فهرست منبع

Merge branch 'configurable' of github.com:mcMMO-Dev/mcmmo into nbt

nossr50 5 سال پیش
والد
کامیت
ab0fc06dc2
93فایلهای تغییر یافته به همراه2020 افزوده شده و 975 حذف شده
  1. 12 0
      .github/FUNDING.yml
  2. 1 0
      .gitignore
  3. 11 0
      1
  4. 50 0
      Changelog.txt
  5. 2 2
      build.gradle.kts
  6. 4 2
      mcmmo-core/src/main/java/com/gmail/nossr50/commands/party/PartyItemShareCommand.java
  7. 17 0
      mcmmo-core/src/main/java/com/gmail/nossr50/commands/party/teleport/PtpCommand.java
  8. 4 3
      mcmmo-core/src/main/java/com/gmail/nossr50/commands/skills/SkillCommand.java
  9. 0 13
      mcmmo-core/src/main/java/com/gmail/nossr50/config/ConfigManager.java
  10. 0 1
      mcmmo-core/src/main/java/com/gmail/nossr50/config/General.java
  11. 3 1
      mcmmo-core/src/main/java/com/gmail/nossr50/config/HOCONUtil.java
  12. 3 1
      mcmmo-core/src/main/java/com/gmail/nossr50/config/SkillConfigFactory.java
  13. 4 0
      mcmmo-core/src/main/java/com/gmail/nossr50/config/antiexploit/ConfigExploitPrevention.java
  14. 17 0
      mcmmo-core/src/main/java/com/gmail/nossr50/config/antiexploit/ConfigSectionExploitExcavation.java
  15. 7 0
      mcmmo-core/src/main/java/com/gmail/nossr50/config/antiexploit/ConfigSectionExploitSkills.java
  16. 2 1
      mcmmo-core/src/main/java/com/gmail/nossr50/config/experience/ConfigExperienceCombat.java
  17. 2 1
      mcmmo-core/src/main/java/com/gmail/nossr50/config/experience/ConfigExperienceHerbalism.java
  18. 2 1
      mcmmo-core/src/main/java/com/gmail/nossr50/config/experience/ConfigExperienceTaming.java
  19. 4 4
      mcmmo-core/src/main/java/com/gmail/nossr50/config/playerleveling/ConfigLeveling.java
  20. 8 11
      mcmmo-core/src/main/java/com/gmail/nossr50/config/playerleveling/ConfigSectionLevelScaling.java
  21. 6 10
      mcmmo-core/src/main/java/com/gmail/nossr50/config/playerleveling/ConfigSectionLevelingGeneral.java
  22. 0 33
      mcmmo-core/src/main/java/com/gmail/nossr50/config/serializers/MaxBonusLevelSerializer.java
  23. 4 10
      mcmmo-core/src/main/java/com/gmail/nossr50/config/serializers/SkillRankPropertySerializer.java
  24. 2 4
      mcmmo-core/src/main/java/com/gmail/nossr50/config/skills/ConfigMaxLevel.java
  25. 3 19
      mcmmo-core/src/main/java/com/gmail/nossr50/config/skills/acrobatics/dodge/ConfigDodge.java
  26. 3 22
      mcmmo-core/src/main/java/com/gmail/nossr50/config/skills/acrobatics/roll/ConfigRoll.java
  27. 0 9
      mcmmo-core/src/main/java/com/gmail/nossr50/config/skills/archery/ConfigArcheryArrowRetrieval.java
  28. 0 9
      mcmmo-core/src/main/java/com/gmail/nossr50/config/skills/archery/ConfigArcheryDaze.java
  29. 3 8
      mcmmo-core/src/main/java/com/gmail/nossr50/config/skills/axes/ConfigAxesCriticalStrikes.java
  30. 0 6
      mcmmo-core/src/main/java/com/gmail/nossr50/config/skills/herbalism/ConfigHerbalismDoubleDrops.java
  31. 0 6
      mcmmo-core/src/main/java/com/gmail/nossr50/config/skills/herbalism/ConfigHerbalismGreenThumb.java
  32. 0 6
      mcmmo-core/src/main/java/com/gmail/nossr50/config/skills/herbalism/ConfigHerbalismHylianLuck.java
  33. 0 5
      mcmmo-core/src/main/java/com/gmail/nossr50/config/skills/herbalism/ConfigHerbalismShroomThumb.java
  34. 0 5
      mcmmo-core/src/main/java/com/gmail/nossr50/config/skills/mining/ConfigMiningDoubleDrops.java
  35. 30 58
      mcmmo-core/src/main/java/com/gmail/nossr50/config/skills/ranks/SkillRankProperty.java
  36. 2 14
      mcmmo-core/src/main/java/com/gmail/nossr50/config/skills/repair/ConfigRepairSuperRepair.java
  37. 0 9
      mcmmo-core/src/main/java/com/gmail/nossr50/config/skills/repair/repairmastery/ConfigRepairRepairMastery.java
  38. 1 6
      mcmmo-core/src/main/java/com/gmail/nossr50/config/skills/smelting/ConfigSmelting.java
  39. 0 9
      mcmmo-core/src/main/java/com/gmail/nossr50/config/skills/smelting/ConfigSmeltingSecondSmelt.java
  40. 0 5
      mcmmo-core/src/main/java/com/gmail/nossr50/config/skills/smelting/ConfigSmeltingSubSkills.java
  41. 0 9
      mcmmo-core/src/main/java/com/gmail/nossr50/config/skills/swords/ConfigSwords.java
  42. 0 9
      mcmmo-core/src/main/java/com/gmail/nossr50/config/skills/swords/ConfigSwordsCounterAttack.java
  43. 0 9
      mcmmo-core/src/main/java/com/gmail/nossr50/config/skills/swords/ConfigSwordsRupture.java
  44. 0 9
      mcmmo-core/src/main/java/com/gmail/nossr50/config/skills/swords/ConfigSwordsSubSkills.java
  45. 0 9
      mcmmo-core/src/main/java/com/gmail/nossr50/config/skills/taming/ConfigTamingGore.java
  46. 0 9
      mcmmo-core/src/main/java/com/gmail/nossr50/config/skills/woodcutting/ConfigWoodcuttingHarvest.java
  47. 1 0
      mcmmo-core/src/main/java/com/gmail/nossr50/config/sound/ConfigSound.java
  48. 50 2
      mcmmo-core/src/main/java/com/gmail/nossr50/core/MaterialMapStore.java
  49. 5 10
      mcmmo-core/src/main/java/com/gmail/nossr50/core/SkillPropertiesManager.java
  50. 0 9
      mcmmo-core/src/main/java/com/gmail/nossr50/database/FlatFileDatabaseManager.java
  51. 10 10
      mcmmo-core/src/main/java/com/gmail/nossr50/database/SQLDatabaseManager.java
  52. 0 11
      mcmmo-core/src/main/java/com/gmail/nossr50/datatypes/player/PlayerProfile.java
  53. 3 1
      mcmmo-core/src/main/java/com/gmail/nossr50/datatypes/skills/SubSkillType.java
  54. 2 2
      mcmmo-core/src/main/java/com/gmail/nossr50/datatypes/skills/behaviours/ArcheryBehaviour.java
  55. 0 35
      mcmmo-core/src/main/java/com/gmail/nossr50/datatypes/skills/properties/AbstractMaxBonusLevel.java
  56. 0 19
      mcmmo-core/src/main/java/com/gmail/nossr50/datatypes/skills/properties/AbstractScalingProperty.java
  57. 0 17
      mcmmo-core/src/main/java/com/gmail/nossr50/datatypes/skills/properties/MaxBonusLevel.java
  58. 0 10
      mcmmo-core/src/main/java/com/gmail/nossr50/datatypes/skills/properties/ScalingProperty.java
  59. 4 2
      mcmmo-core/src/main/java/com/gmail/nossr50/datatypes/skills/subskills/acrobatics/Roll.java
  60. 1 1
      mcmmo-core/src/main/java/com/gmail/nossr50/dumpster/PotionGenerator.java
  61. 84 16
      mcmmo-core/src/main/java/com/gmail/nossr50/listeners/BlockListener.java
  62. 5 21
      mcmmo-core/src/main/java/com/gmail/nossr50/listeners/EntityListener.java
  63. 3 2
      mcmmo-core/src/main/java/com/gmail/nossr50/listeners/InteractionManager.java
  64. 5 3
      mcmmo-core/src/main/java/com/gmail/nossr50/listeners/PlayerListener.java
  65. 15 18
      mcmmo-core/src/main/java/com/gmail/nossr50/mcMMO.java
  66. 7 11
      mcmmo-core/src/main/java/com/gmail/nossr50/runnables/MobHealthDisplayUpdaterTask.java
  67. 18 0
      mcmmo-core/src/main/java/com/gmail/nossr50/runnables/items/TeleportationWarmup.java
  68. 2 1
      mcmmo-core/src/main/java/com/gmail/nossr50/skills/mining/MiningManager.java
  69. 1 0
      mcmmo-core/src/main/java/com/gmail/nossr50/skills/unarmed/UnarmedManager.java
  70. 2 1
      mcmmo-core/src/main/java/com/gmail/nossr50/util/MiscTools.java
  71. 6 0
      mcmmo-core/src/main/java/com/gmail/nossr50/util/MobHealthBarManager.java
  72. 24 22
      mcmmo-core/src/main/java/com/gmail/nossr50/util/PermissionTools.java
  73. 3 1
      mcmmo-core/src/main/java/com/gmail/nossr50/util/StringUtils.java
  74. 2 1
      mcmmo-core/src/main/java/com/gmail/nossr50/util/TextComponentFactory.java
  75. 3 2
      mcmmo-core/src/main/java/com/gmail/nossr50/util/commands/CommandRegistrationManager.java
  76. 3 2
      mcmmo-core/src/main/java/com/gmail/nossr50/util/commands/CommandTools.java
  77. 14 27
      mcmmo-core/src/main/java/com/gmail/nossr50/util/experience/FormulaManager.java
  78. 4 4
      mcmmo-core/src/main/java/com/gmail/nossr50/util/player/NotificationManager.java
  79. 3 5
      mcmmo-core/src/main/java/com/gmail/nossr50/util/random/RandomChanceTools.java
  80. 1 1
      mcmmo-core/src/main/java/com/gmail/nossr50/util/scoreboards/ScoreboardWrapper.java
  81. 39 1
      mcmmo-core/src/main/java/com/gmail/nossr50/util/skills/CombatTools.java
  82. 1 1
      mcmmo-core/src/main/java/com/gmail/nossr50/util/skills/RankTools.java
  83. 2 0
      mcmmo-core/src/main/java/com/gmail/nossr50/util/sounds/SoundManager.java
  84. 1 0
      mcmmo-core/src/main/java/com/gmail/nossr50/util/sounds/SoundType.java
  85. 29 29
      mcmmo-core/src/main/java/com/gmail/nossr50/worldguard/WorldGuardUtils.java
  86. 9 0
      mcmmo-core/src/main/resources/com/gmail/nossr50/locale/doTranslation.sh
  87. 303 303
      mcmmo-core/src/main/resources/com/gmail/nossr50/locale/locale_it.properties
  88. 23 23
      mcmmo-core/src/main/resources/com/gmail/nossr50/locale/locale_ja_JP.properties
  89. 1110 0
      mcmmo-core/src/main/resources/com/gmail/nossr50/locale/locale_lt_LT.properties
  90. 2 1
      mcmmo-core/src/main/resources/config.yml
  91. 5 1
      mcmmo-core/src/main/resources/experience.yml
  92. 4 1
      mcmmo-core/src/main/resources/fishing_treasures.yml
  93. 4 0
      mcmmo-core/src/main/resources/sounds.yml

+ 12 - 0
.github/FUNDING.yml

@@ -0,0 +1,12 @@
+# These are supported funding model platforms
+
+github: [nossr50] # Replace with up to 4 GitHub Sponsors-enabled usernames e.g., [user1, user2]
+patreon: nossr50 # Replace with a single Patreon username
+open_collective: # Replace with a single Open Collective username
+ko_fi: # Replace with a single Ko-fi username
+tidelift: # Replace with a single Tidelift platform-name/package-name e.g., npm/babel
+community_bridge: # Replace with a single Community Bridge project-name e.g., cloud-foundry
+liberapay: # Replace with a single Liberapay username
+issuehunt: # Replace with a single IssueHunt username
+otechie: # Replace with a single Otechie username
+custom: https://paypal.me/nossr50 # Replace with up to 4 custom sponsorship URLs e.g., ['link1', 'link2']

+ 1 - 0
.gitignore

@@ -11,6 +11,7 @@ nbdist/
 
 
 ### Bash Scripts
 ### Bash Scripts
 *.sh
 *.sh
+!mcmmo-core/src/main/resources/com/gmail/nossr50/locale/doTranslation.sh
 
 
 ### JetBrains template
 ### JetBrains template
 # Covers JetBrains IDEs: IntelliJ, RubyMine, PhpStorm, AppCode, PyCharm, CLion, Android Studio and WebStorm
 # Covers JetBrains IDEs: IntelliJ, RubyMine, PhpStorm, AppCode, PyCharm, CLion, Android Studio and WebStorm

+ 11 - 0
1

@@ -0,0 +1,11 @@
+SkillShot tweaks
+# Please enter the commit message for your changes. Lines starting
+# with '#' will be ignored, and an empty message aborts the commit.
+#
+# On branch master
+# Your branch is up to date with 'origin/master'.
+#
+# Changes to be committed:
+#	modified:   src/main/java/com/gmail/nossr50/skills/archery/Archery.java
+#	modified:   src/main/java/com/gmail/nossr50/util/skills/CombatUtils.java
+#

+ 50 - 0
Changelog.txt

@@ -5,6 +5,8 @@ Version 2.2.0
     !!!!!!!!!!!!!!!!!!!!!!!!
     !!!!!!!!!!!!!!!!!!!!!!!!
     !!!!!!!!!!!!!!!!!!!!!!!!
     !!!!!!!!!!!!!!!!!!!!!!!!
     mcMMO's config system has been rewritten
     mcMMO's config system has been rewritten
+    Retro and Standard mode have been removed, now levels are based around 1-1000 and are changed based on a new setting
+    Added Cosmetic Level Scaling setting to the leveling config, you can use this to for example, make the max level 100 instead of 1000
     mcMMO build management is now handled by Gradle (KTS) instead of Maven
     mcMMO build management is now handled by Gradle (KTS) instead of Maven
     Nearly every config setting has been renamed and most have brand new comments
     Nearly every config setting has been renamed and most have brand new comments
     You can now add an unlimited number of custom XP perks with custom defined XP boosts
     You can now add an unlimited number of custom XP perks with custom defined XP boosts
@@ -200,8 +202,56 @@ Version 2.2.0
     Added API method to grab the level cap of a skill by its PrimarySkillType ENUM definition
     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 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
     Added 'UndefinedSkillBehaviour' for trying to use a method that has no behaviour defined for the provided skill
+
+Version 2.1.114
+    Fix some more locale usages, should aim to further prevent issues with oddball locales
+    Fixed a bug where newer versions of MySQL did not like our rank command
+    Added a new setting to turn off the Snow Golem Exploit prevention to experience.yml next to the other exploit fixes
+    Fixed a bug which stopped the optional Endermite XP exploit fix from working
+
+Version 2.1.113
+    Activating Berserk on a soft block (glass, snow, dirts) will break that material right away instead of only breaking subsequent blocks hit by the player
+    Berserk will now break glass and glass pane blocks
+    Hitting glass with berserk readied will activate it
+    Added GLASS settings to sounds.yml for Berserk
+    Fixed bug where BlockCracker didn't work on infested_stone_bricks
+    Fixed a bug where beacons could be duplicated
+    Check player's PTP world permissions before executing a party teleport
+    Improved how mcMMO handles randomness
+
+Version 2.1.112
+    Correct locale usage for enum access, now enforces using the english locale to prevent issues with oddball locales for configs/commands
+    Fixed a NPE that can occur if a player engages in combat with specific skills before their profile is loaded
+    mcMMO is now more compatible with certain mob stacking plugins
+    Improved behaviour for mob health bars
+    Archery's Skill Shot bonus damage is now multiplicative instead of additive (nerfing early game skill shot ranks)
+    Sweet Berry Bush's default Herbalism XP is now 50 instead of 300 (Update your experience.yml or delete it to generate a new one)
+
+Version 2.1.111
+    mcMMO is compatible with the following versions of MC: 1.15 / 1.14.4 / 1.14.3 / 1.14.2 / 1.14.1 / 1.14 / 1.13.2
+    Further prevent nesting of bleed damage calls
+    Warn about reparable/salvage configs with missing sections
+    Added Bee combat experience modifier to experience.yml (Update your experience.yml file, see notes)
+    Breaking a Bee Nest will result in Herbalism XP (Update your experience.yml file, see notes)
+    Breeding bees will now result in Taming XP (Update your experience.yml file, see notes)
+
+    NOTES:
+        You will need to update your experience.yml by hand or delete it to get XP from new things in 1.15
+        The default version of mcMMO's experience.yml looks like this: https://paste.gg/p/anonymous/15c34df6e60d45d9a3508b379a5e6514
+        You'll want to add Bee to combat XP section, and Bee_Nest to Herbalism XP, and Bee to Taming XP section.
+
+Version 2.1.110
+    Fixed a dupe bug
+    Actually fixed Block Cracker
+    You can now crack Infested Stone Bricks with Block Cracker
+    Added Lithuanian locale (thanks Vyciokazz)
+
 Version 2.1.109
 Version 2.1.109
+    Block Cracker will now correctly crack stone_bricks during Berserk again
+    Added Lily_Of_The_Valley to the Bonus Drops list in config.yml (you'll probably want to add this manually) which enables it to double drop
     Added missing 1.14 blocks to ability/tool activation blacklists
     Added missing 1.14 blocks to ability/tool activation blacklists
+    Fixed spamming of incompatible worldguard version message
+    Updated Italian locale (thanks Fabrimat)
 
 
 Version 2.1.108
 Version 2.1.108
     Fixed an amusing exploit for easy leveling in Acrobatics
     Fixed an amusing exploit for easy leveling in Acrobatics

+ 2 - 2
build.gradle.kts

@@ -7,7 +7,7 @@ subprojects {
         mavenLocal()
         mavenLocal()
         mavenCentral()
         mavenCentral()
         maven("https://repo.spongepowered.org/maven")
         maven("https://repo.spongepowered.org/maven")
-        maven("https://hub.spigotmc.org/nexus/content/repositories/snapshoits")
+        maven("https://hub.spigotmc.org/nexus/content/repositories/snapshots")
         maven("https://repo.codemc.org/repository/maven-public")
         maven("https://repo.codemc.org/repository/maven-public")
         maven("https://maven.sk89q.com/repo")
         maven("https://maven.sk89q.com/repo")
         maven("https://mvnrepository.com/artifact/org.jetbrains/annotations")
         maven("https://mvnrepository.com/artifact/org.jetbrains/annotations")
@@ -24,4 +24,4 @@ subprojects {
         sourceCompatibility = JavaVersion.VERSION_1_8
         sourceCompatibility = JavaVersion.VERSION_1_8
     }
     }
 
 
-}
+}

+ 4 - 2
mcmmo-core/src/main/java/com/gmail/nossr50/commands/party/PartyItemShareCommand.java

@@ -11,6 +11,8 @@ import org.bukkit.command.CommandExecutor;
 import org.bukkit.command.CommandSender;
 import org.bukkit.command.CommandSender;
 import org.bukkit.entity.Player;
 import org.bukkit.entity.Player;
 
 
+import java.util.Locale;
+
 public class PartyItemShareCommand implements CommandExecutor {
 public class PartyItemShareCommand implements CommandExecutor {
 
 
     private final mcMMO pluginRef;
     private final mcMMO pluginRef;
@@ -35,7 +37,7 @@ public class PartyItemShareCommand implements CommandExecutor {
 
 
         switch (args.length) {
         switch (args.length) {
             case 2:
             case 2:
-                ShareMode mode = ShareMode.getShareMode(args[1].toUpperCase());
+                ShareMode mode = ShareMode.getShareMode(args[1].toUpperCase(Locale.ENGLISH));
 
 
                 if (mode == null) {
                 if (mode == null) {
                     sender.sendMessage(pluginRef.getLocaleManager().getString("Commands.Usage.2", "party", "itemshare", "<NONE | EQUAL | RANDOM>"));
                     sender.sendMessage(pluginRef.getLocaleManager().getString("Commands.Usage.2", "party", "itemshare", "<NONE | EQUAL | RANDOM>"));
@@ -58,7 +60,7 @@ public class PartyItemShareCommand implements CommandExecutor {
                 }
                 }
 
 
                 try {
                 try {
-                    handleToggleItemShareCategory(party, ItemShareType.valueOf(args[1].toUpperCase()), toggle);
+                    handleToggleItemShareCategory(party, ItemShareType.valueOf(args[1].toUpperCase(Locale.ENGLISH)), toggle);
                 } catch (IllegalArgumentException ex) {
                 } catch (IllegalArgumentException ex) {
                     sender.sendMessage(pluginRef.getLocaleManager().getString("Commands.Usage.2", "party", "itemshare", "<loot | mining | herbalism | woodcutting | misc> <true | false>"));
                     sender.sendMessage(pluginRef.getLocaleManager().getString("Commands.Usage.2", "party", "itemshare", "<loot | mining | herbalism | woodcutting | misc> <true | false>"));
                 }
                 }

+ 17 - 0
mcmmo-core/src/main/java/com/gmail/nossr50/commands/party/teleport/PtpCommand.java

@@ -7,6 +7,7 @@ import com.gmail.nossr50.datatypes.party.PartyTeleportRecord;
 import com.gmail.nossr50.datatypes.player.McMMOPlayer;
 import com.gmail.nossr50.datatypes.player.McMMOPlayer;
 import com.gmail.nossr50.mcMMO;
 import com.gmail.nossr50.mcMMO;
 import com.google.common.collect.ImmutableList;
 import com.google.common.collect.ImmutableList;
+import org.bukkit.World;
 import org.bukkit.command.Command;
 import org.bukkit.command.Command;
 import org.bukkit.command.CommandExecutor;
 import org.bukkit.command.CommandExecutor;
 import org.bukkit.command.CommandSender;
 import org.bukkit.command.CommandSender;
@@ -159,6 +160,22 @@ public class PtpCommand implements TabExecutor {
         McMMOPlayer mcMMOTarget = pluginRef.getUserManager().getPlayer(targetName);
         McMMOPlayer mcMMOTarget = pluginRef.getUserManager().getPlayer(targetName);
         Player target = mcMMOTarget.getPlayer();
         Player target = mcMMOTarget.getPlayer();
 
 
+        if (pluginRef.getConfigManager().getConfigParty().getPTP().isPtpWorldBasedPermissions()) {
+            World targetWorld = target.getWorld();
+            World playerWorld = player.getWorld();
+
+            if (!pluginRef.getPermissionTools().partyTeleportAllWorlds(player)) {
+                if (!pluginRef.getPermissionTools().partyTeleportWorld(target, targetWorld)) {
+                    player.sendMessage(pluginRef.getLocaleManager().formatString("Commands.ptp.NoWorldPermissions", targetWorld.getName()));
+                    return;
+                }
+                else if (targetWorld != playerWorld && !pluginRef.getPermissionTools().partyTeleportWorld(player, targetWorld)) {
+                    player.sendMessage(pluginRef.getLocaleManager().formatString("Commands.ptp.NoWorldPermissions", targetWorld.getName()));
+                    return;
+                }
+            }
+        }
+
         PartyTeleportRecord ptpRecord = mcMMOTarget.getPartyTeleportRecord();
         PartyTeleportRecord ptpRecord = mcMMOTarget.getPartyTeleportRecord();
 
 
         if (!ptpRecord.isConfirmRequired()) {
         if (!ptpRecord.isConfirmRequired()) {

+ 4 - 3
mcmmo-core/src/main/java/com/gmail/nossr50/commands/skills/SkillCommand.java

@@ -19,6 +19,7 @@ import org.bukkit.entity.Player;
 import java.text.DecimalFormat;
 import java.text.DecimalFormat;
 import java.util.ArrayList;
 import java.util.ArrayList;
 import java.util.List;
 import java.util.List;
+import java.util.Locale;
 import java.util.Set;
 import java.util.Set;
 
 
 public abstract class SkillCommand implements TabExecutor {
 public abstract class SkillCommand implements TabExecutor {
@@ -131,7 +132,7 @@ public abstract class SkillCommand implements TabExecutor {
             }
             }
         }
         }
 
 
-        player.sendMessage(pluginRef.getLocaleManager().getString("Guides.Available", skillName, skillName.toLowerCase()));
+        player.sendMessage(pluginRef.getLocaleManager().getString("Guides.Available", skillName, skillName.toLowerCase(Locale.ENGLISH)));
     }
     }
 
 
     private void sendSkillCommandHeader(Player player, McMMOPlayer mcMMOPlayer, int skillValue) {
     private void sendSkillCommandHeader(Player player, McMMOPlayer mcMMOPlayer, int skillValue) {
@@ -223,10 +224,10 @@ public abstract class SkillCommand implements TabExecutor {
         String statDescriptionKey = !isExtra ? subSkillType.getLocaleKeyStatDescription(pluginRef) : subSkillType.getLocaleKeyStatExtraDescription(pluginRef);
         String statDescriptionKey = !isExtra ? subSkillType.getLocaleKeyStatDescription(pluginRef) : subSkillType.getLocaleKeyStatExtraDescription(pluginRef);
 
 
         if (isCustom)
         if (isCustom)
-            return pluginRef.getLocaleManager().getString(templateKey, pluginRef.getLocaleManager().getString(statDescriptionKey, vars));
+            return pluginRef.getLocaleManager().getString(templateKey, pluginRef.getLocaleManager().getString(statDescriptionKey, (Object[]) vars));
         else {
         else {
             String[] mergedList = pluginRef.getNotificationManager().addItemToFirstPositionOfArray(pluginRef.getLocaleManager().getString(statDescriptionKey), vars);
             String[] mergedList = pluginRef.getNotificationManager().addItemToFirstPositionOfArray(pluginRef.getLocaleManager().getString(statDescriptionKey), vars);
-            return pluginRef.getLocaleManager().getString(templateKey, mergedList);
+            return pluginRef.getLocaleManager().getString(templateKey, (Object[]) mergedList);
         }
         }
     }
     }
 
 

+ 0 - 13
mcmmo-core/src/main/java/com/gmail/nossr50/config/ConfigManager.java

@@ -51,7 +51,6 @@ import com.gmail.nossr50.datatypes.experience.FormulaType;
 import com.gmail.nossr50.datatypes.party.PartyFeature;
 import com.gmail.nossr50.datatypes.party.PartyFeature;
 import com.gmail.nossr50.datatypes.skills.PrimarySkillType;
 import com.gmail.nossr50.datatypes.skills.PrimarySkillType;
 import com.gmail.nossr50.datatypes.skills.properties.DamageProperty;
 import com.gmail.nossr50.datatypes.skills.properties.DamageProperty;
-import com.gmail.nossr50.datatypes.skills.properties.MaxBonusLevel;
 import com.gmail.nossr50.datatypes.skills.subskills.taming.CallOfTheWildType;
 import com.gmail.nossr50.datatypes.skills.subskills.taming.CallOfTheWildType;
 import com.gmail.nossr50.datatypes.skills.subskills.taming.TamingSummon;
 import com.gmail.nossr50.datatypes.skills.subskills.taming.TamingSummon;
 import com.gmail.nossr50.mcMMO;
 import com.gmail.nossr50.mcMMO;
@@ -266,7 +265,6 @@ public final class ConfigManager {
         customSerializers.registerType(TypeToken.of(CustomXPPerk.class), new CustomXPPerkSerializer());
         customSerializers.registerType(TypeToken.of(CustomXPPerk.class), new CustomXPPerkSerializer());
         customSerializers.registerType(TypeToken.of(DamageProperty.class), new DamagePropertySerializer());
         customSerializers.registerType(TypeToken.of(DamageProperty.class), new DamagePropertySerializer());
         customSerializers.registerType(TypeToken.of(SkillRankProperty.class), new SkillRankPropertySerializer());
         customSerializers.registerType(TypeToken.of(SkillRankProperty.class), new SkillRankPropertySerializer());
-        customSerializers.registerType(TypeToken.of(MaxBonusLevel.class), new MaxBonusLevelSerializer());
         customSerializers.registerType(TypeToken.of(PlayerNotificationSettings.class), new PlayerNotificationSerializer());
         customSerializers.registerType(TypeToken.of(PlayerNotificationSettings.class), new PlayerNotificationSerializer());
         customSerializers.registerType(TypeToken.of(SoundSetting.class), new SoundSettingSerializer());
         customSerializers.registerType(TypeToken.of(SoundSetting.class), new SoundSettingSerializer());
 //        customSerializers.registerType(TypeToken.of(ItemWildcards.class), new ItemWildcardSerializer());
 //        customSerializers.registerType(TypeToken.of(ItemWildcards.class), new ItemWildcardSerializer());
@@ -483,17 +481,6 @@ public final class ConfigManager {
         return configRanks.getRootNode();
         return configRanks.getRootNode();
     }
     }
 
 
-    /**
-     * Checks if this plugin is using retro mode
-     * Retro mode is a 0-1000 skill system
-     * Standard mode is scaled for 1-100
-     *
-     * @return true if retro mode is enabled
-     */
-    public boolean isRetroMode() {
-        return getConfigLeveling().getConfigSectionLevelingGeneral().getConfigSectionLevelScaling().isRetroModeEnabled();
-    }
-
     public ConfigExperience getConfigExperience() {
     public ConfigExperience getConfigExperience() {
         return configExperience.getConfig();
         return configExperience.getConfig();
     }
     }

+ 0 - 1
mcmmo-core/src/main/java/com/gmail/nossr50/config/General.java

@@ -5,5 +5,4 @@ import ninja.leaping.configurate.objectmapping.serialize.ConfigSerializable;
 @ConfigSerializable
 @ConfigSerializable
 public class General {
 public class General {
 
 
-
 }
 }

+ 3 - 1
mcmmo-core/src/main/java/com/gmail/nossr50/config/HOCONUtil.java

@@ -2,6 +2,8 @@ package com.gmail.nossr50.config;
 
 
 import com.gmail.nossr50.util.StringUtils;
 import com.gmail.nossr50.util.StringUtils;
 
 
+import java.util.Locale;
+
 public final class HOCONUtil {
 public final class HOCONUtil {
 
 
     public static String serializeENUMName(String hyphenedString) {
     public static String serializeENUMName(String hyphenedString) {
@@ -24,7 +26,7 @@ public final class HOCONUtil {
 
 
         for (int x = 0; x < split.length; x++) {
         for (int x = 0; x < split.length; x++) {
             if (x + 1 >= split.length)
             if (x + 1 >= split.length)
-                formattedString.append(split[x].toUpperCase());
+                formattedString.append(split[x].toUpperCase(Locale.ENGLISH));
             else
             else
                 formattedString.append(split[x]).append('_');
                 formattedString.append(split[x]).append('_');
         }
         }

+ 3 - 1
mcmmo-core/src/main/java/com/gmail/nossr50/config/SkillConfigFactory.java

@@ -4,11 +4,13 @@ import com.gmail.nossr50.datatypes.skills.PrimarySkillType;
 import com.gmail.nossr50.mcMMO;
 import com.gmail.nossr50.mcMMO;
 import com.gmail.nossr50.util.StringUtils;
 import com.gmail.nossr50.util.StringUtils;
 
 
+import java.util.Locale;
+
 public class SkillConfigFactory {
 public class SkillConfigFactory {
 
 
     protected static SerializedConfigLoader initSkillConfig(mcMMO pluginRef, PrimarySkillType primarySkillType, Class<?> clazz) {
     protected static SerializedConfigLoader initSkillConfig(mcMMO pluginRef, PrimarySkillType primarySkillType, Class<?> clazz) {
         return new SerializedConfigLoader(pluginRef, clazz,
         return new SerializedConfigLoader(pluginRef, clazz,
-                primarySkillType.toString().toLowerCase() + ".conf",
+                primarySkillType.toString().toLowerCase(Locale.ENGLISH) + ".conf",
                 StringUtils.getCapitalized(primarySkillType.toString()),
                 StringUtils.getCapitalized(primarySkillType.toString()),
                 null);
                 null);
     }
     }

+ 4 - 0
mcmmo-core/src/main/java/com/gmail/nossr50/config/antiexploit/ConfigExploitPrevention.java

@@ -119,4 +119,8 @@ public class ConfigExploitPrevention {
     public ConfigSectionExploitTaming getConfigSectionExploitTaming() {
     public ConfigSectionExploitTaming getConfigSectionExploitTaming() {
         return configSectionExploitSkills.getConfigSectionExploitTaming();
         return configSectionExploitSkills.getConfigSectionExploitTaming();
     }
     }
+
+    public boolean isSnowGolemExploitPrevented() {
+        return configSectionExploitSkills.isSnowGolemExploitPrevented();
+    }
 }
 }

+ 17 - 0
mcmmo-core/src/main/java/com/gmail/nossr50/config/antiexploit/ConfigSectionExploitExcavation.java

@@ -0,0 +1,17 @@
+package com.gmail.nossr50.config.antiexploit;
+
+import ninja.leaping.configurate.objectmapping.Setting;
+import ninja.leaping.configurate.objectmapping.serialize.ConfigSerializable;
+
+@ConfigSerializable
+public class ConfigSectionExploitExcavation {
+
+    public static final boolean DEFAULT_SNOW_GOLEM = true;
+    @Setting(value = "Snow-Golem-Exploit", comment = "If set to true, the snow made by snow golems will not reward XP." +
+            "\nDefault value: "+DEFAULT_SNOW_GOLEM)
+    private boolean snowGolemExploit = DEFAULT_SNOW_GOLEM;
+
+    public boolean isSnowGolemExploitPrevented() {
+        return snowGolemExploit;
+    }
+}

+ 7 - 0
mcmmo-core/src/main/java/com/gmail/nossr50/config/antiexploit/ConfigSectionExploitSkills.java

@@ -26,6 +26,9 @@ public class ConfigSectionExploitSkills {
     @Setting(value = "Taming", comment = "Exploit settings related to Taming")
     @Setting(value = "Taming", comment = "Exploit settings related to Taming")
     private ConfigSectionExploitTaming configSectionExploitTaming = new ConfigSectionExploitTaming();
     private ConfigSectionExploitTaming configSectionExploitTaming = new ConfigSectionExploitTaming();
 
 
+    @Setting(value = "Excavation", comment = "Exploit settings related to Excavation.")
+    private ConfigSectionExploitExcavation configSectionExploitExcavation = new ConfigSectionExploitExcavation();
+
     public ConfigSectionExploitAcrobatics getConfigSectionExploitAcrobatics() {
     public ConfigSectionExploitAcrobatics getConfigSectionExploitAcrobatics() {
         return configSectionExploitAcrobatics;
         return configSectionExploitAcrobatics;
     }
     }
@@ -46,6 +49,10 @@ public class ConfigSectionExploitSkills {
         return configSectionExploitMining.isPreventCobblestoneStoneGeneratorXP();
         return configSectionExploitMining.isPreventCobblestoneStoneGeneratorXP();
     }
     }
 
 
+    public boolean isSnowGolemExploitPrevented() {
+        return configSectionExploitExcavation.isSnowGolemExploitPrevented();
+    }
+
     public boolean areSummonsBreedable() {
     public boolean areSummonsBreedable() {
         return configSectionExploitTaming.areSummonsBreedable();
         return configSectionExploitTaming.areSummonsBreedable();
     }
     }

+ 2 - 1
mcmmo-core/src/main/java/com/gmail/nossr50/config/experience/ConfigExperienceCombat.java

@@ -15,7 +15,7 @@ public class ConfigExperienceCombat {
 
 
     static {
     static {
         COMBAT_EXPERIENCE_DEFAULT = new HashMap<>();
         COMBAT_EXPERIENCE_DEFAULT = new HashMap<>();
-
+        // TODO: namespace
         COMBAT_EXPERIENCE_DEFAULT.put("creeper", 4.0);
         COMBAT_EXPERIENCE_DEFAULT.put("creeper", 4.0);
         COMBAT_EXPERIENCE_DEFAULT.put("cat", 1.0);
         COMBAT_EXPERIENCE_DEFAULT.put("cat", 1.0);
         COMBAT_EXPERIENCE_DEFAULT.put("fox", 1.0);
         COMBAT_EXPERIENCE_DEFAULT.put("fox", 1.0);
@@ -74,6 +74,7 @@ public class ConfigExperienceCombat {
         COMBAT_EXPERIENCE_DEFAULT.put("dolphin", 1.0);
         COMBAT_EXPERIENCE_DEFAULT.put("dolphin", 1.0);
         COMBAT_EXPERIENCE_DEFAULT.put("phantom", 4.0);
         COMBAT_EXPERIENCE_DEFAULT.put("phantom", 4.0);
         COMBAT_EXPERIENCE_DEFAULT.put("wandering_trader", 1.0);
         COMBAT_EXPERIENCE_DEFAULT.put("wandering_trader", 1.0);
+        COMBAT_EXPERIENCE_DEFAULT.put("bee", 1.5);
 
 
         //SPECIAL
         //SPECIAL
         SPECIAL_COMBAT_EXPERIENCE_DEFAULT = new HashMap<>();
         SPECIAL_COMBAT_EXPERIENCE_DEFAULT = new HashMap<>();

+ 2 - 1
mcmmo-core/src/main/java/com/gmail/nossr50/config/experience/ConfigExperienceHerbalism.java

@@ -84,8 +84,9 @@ public class ConfigExperienceHerbalism {
         HERBALISM_EXPERIENCE_DEFAULT.put("minecraft:dead_bush", 30);
         HERBALISM_EXPERIENCE_DEFAULT.put("minecraft:dead_bush", 30);
 
 
         /* MISC */
         /* MISC */
+        HERBALISM_EXPERIENCE_DEFAULT.put("minecraft:bee_nest", 200);
         HERBALISM_EXPERIENCE_DEFAULT.put("minecraft:lily_pad", 100);
         HERBALISM_EXPERIENCE_DEFAULT.put("minecraft:lily_pad", 100);
-        HERBALISM_EXPERIENCE_DEFAULT.put("minecraft:sweet_berry_bush", 300);
+        HERBALISM_EXPERIENCE_DEFAULT.put("minecraft:sweet_berry_bush", 50);
 
 
         /* MUSHROOMS */
         /* MUSHROOMS */
         HERBALISM_EXPERIENCE_DEFAULT.put("minecraft:red_mushroom", 150);
         HERBALISM_EXPERIENCE_DEFAULT.put("minecraft:red_mushroom", 150);

+ 2 - 1
mcmmo-core/src/main/java/com/gmail/nossr50/config/experience/ConfigExperienceTaming.java

@@ -12,7 +12,7 @@ public class ConfigExperienceTaming {
 
 
     static {
     static {
         TAMING_EXPERIENCE_DEFAULT = new HashMap<>();
         TAMING_EXPERIENCE_DEFAULT = new HashMap<>();
-
+        // TODO: namespace
         TAMING_EXPERIENCE_DEFAULT.put("wolf", 250);
         TAMING_EXPERIENCE_DEFAULT.put("wolf", 250);
         TAMING_EXPERIENCE_DEFAULT.put("ocelot", 500);
         TAMING_EXPERIENCE_DEFAULT.put("ocelot", 500);
         TAMING_EXPERIENCE_DEFAULT.put("cat", 500);
         TAMING_EXPERIENCE_DEFAULT.put("cat", 500);
@@ -25,6 +25,7 @@ public class ConfigExperienceTaming {
         TAMING_EXPERIENCE_DEFAULT.put("parrot", 1100);
         TAMING_EXPERIENCE_DEFAULT.put("parrot", 1100);
         TAMING_EXPERIENCE_DEFAULT.put("fox", 1000);
         TAMING_EXPERIENCE_DEFAULT.put("fox", 1000);
         TAMING_EXPERIENCE_DEFAULT.put("panda", 1000);
         TAMING_EXPERIENCE_DEFAULT.put("panda", 1000);
+        TAMING_EXPERIENCE_DEFAULT.put("bee", 100);
     }
     }
 
 
     @Setting(value = "Taming-XP-Values")
     @Setting(value = "Taming-XP-Values")

+ 4 - 4
mcmmo-core/src/main/java/com/gmail/nossr50/config/playerleveling/ConfigLeveling.java

@@ -129,6 +129,10 @@ public class ConfigLeveling {
         return configSectionLevelCaps;
         return configSectionLevelCaps;
     }
     }
 
 
+    public int getCosmeticLevelScaleModifier() {
+        return configSectionLevelingGeneral.getCosmeticLevelScaleModifier();
+    }
+
     public ConfigSectionSkillLevelCap getPowerLevelSettings() {
     public ConfigSectionSkillLevelCap getPowerLevelSettings() {
         return configSectionLevelCaps.getPowerLevelSettings();
         return configSectionLevelCaps.getPowerLevelSettings();
     }
     }
@@ -161,10 +165,6 @@ public class ConfigLeveling {
         return configExperienceFormula.getFormulaType();
         return configExperienceFormula.getFormulaType();
     }
     }
 
 
-    public boolean isRetroModeEnabled() {
-        return getConfigSectionLevelScaling().isRetroModeEnabled();
-    }
-
     public ConfigExperienceFormulaLinear getConfigExperienceFormulaLinear() {
     public ConfigExperienceFormulaLinear getConfigExperienceFormulaLinear() {
         return configExperienceFormula.getConfigExperienceFormulaLinear();
         return configExperienceFormula.getConfigExperienceFormulaLinear();
     }
     }

+ 8 - 11
mcmmo-core/src/main/java/com/gmail/nossr50/config/playerleveling/ConfigSectionLevelScaling.java

@@ -7,22 +7,19 @@ import ninja.leaping.configurate.objectmapping.serialize.ConfigSerializable;
 public class ConfigSectionLevelScaling {
 public class ConfigSectionLevelScaling {
 
 
     /* DEFAULT VALUES */
     /* DEFAULT VALUES */
-    public static final boolean USE_RETRO_MODE_DEFAULT = true;
+    public static final int LEVEL_SCALE_MODIFIER_DEFAULT = 1;
 
 
     /*
     /*
      * CONFIG NODES
      * CONFIG NODES
      */
      */
 
 
-    @Setting(value = "Use-Retro-Mode",
-            comment = "Enables 1-1000 Level Scaling" +
-                    "\nIf set to false, Standard Scaling is used instead (1-100 Level Scaling)")
-    private boolean useRetroMode = USE_RETRO_MODE_DEFAULT;
+    @Setting(value = "Cosmetic-Level-Scaling",
+            comment = "Changes the max number of levels and adjusts settings appropriately" +
+                    "\nThe default value will make level 1000 the max level, settings in the configs are based around that and are mutated based on this setting." +
+                    "\nLeave this setting at a value of 1 if you do not wish to change the cosmetic amount of levels")
+    private int cosmeticLevelScaleModifier = LEVEL_SCALE_MODIFIER_DEFAULT;
 
 
-    /*
-     * GETTER BOILERPLATE
-     */
-
-    public boolean isRetroModeEnabled() {
-        return useRetroMode;
+    public int getCosmeticLevelScaleModifier() {
+        return cosmeticLevelScaleModifier;
     }
     }
 }
 }

+ 6 - 10
mcmmo-core/src/main/java/com/gmail/nossr50/config/playerleveling/ConfigSectionLevelingGeneral.java

@@ -15,16 +15,8 @@ public class ConfigSectionLevelingGeneral {
 
 
     @Setting(value = "Player-Level-Scaling",
     @Setting(value = "Player-Level-Scaling",
             comment = "Level Scaling is a new feature of mcMMO." +
             comment = "Level Scaling is a new feature of mcMMO." +
-                    "\nServer admins can choose between two level scaling modes." +
-                    "\nEach mode is meant to be identical to each other in terms of the speed of progression." +
-                    "\nIn Retro player skills and levels scale the way they always have, on a 1-1000 scale." +
-                    "\nIn Standard player skills scale instead from 1-100." +
-                    "\nAs an example, reaching level 10 in Standard will take the same amount of time as reaching level 100 in Retro" +
-                    "\n\nTo make upgrading mcMMO easier for the vast majority of existing servers, RetroMode will be turned on by default in the following circumstances" +
-                    "\n1) That your server has a config.yml file that does not yet have a RetroMode setting (this means your server has not yet updated from the old system which did not have two level scaling options)" +
-                    "\n2) You are already using RetroMode in your old YAML config files" +
-                    "\n\nIf either of these is true, RetroMode will be turned on by default. If for some reason you had wiped your config files, you will need to come in here and turn RetroMode back on." +
-                    "\nNOTE: RetroMode and Standard use the EXACT same DB, it does not alter any information within that DB. It is not dangerous to switch between Standard and Retro.")
+                    "\nServer admins can adjust level scaling modifiers to tweak a bunch of settings related to progression at once." +
+                    "\nIt is not recommended to change this away from defaults unless you know what you are doing.")
     private ConfigSectionLevelScaling configSectionLevelScaling = new ConfigSectionLevelScaling();
     private ConfigSectionLevelScaling configSectionLevelScaling = new ConfigSectionLevelScaling();
 
 
     @Setting(value = "Player-Starting-Level",
     @Setting(value = "Player-Starting-Level",
@@ -44,4 +36,8 @@ public class ConfigSectionLevelingGeneral {
     public ConfigSectionLevelScaling getConfigSectionLevelScaling() {
     public ConfigSectionLevelScaling getConfigSectionLevelScaling() {
         return configSectionLevelScaling;
         return configSectionLevelScaling;
     }
     }
+
+    public int getCosmeticLevelScaleModifier() {
+        return configSectionLevelScaling.getCosmeticLevelScaleModifier();
+    }
 }
 }

+ 0 - 33
mcmmo-core/src/main/java/com/gmail/nossr50/config/serializers/MaxBonusLevelSerializer.java

@@ -1,33 +0,0 @@
-package com.gmail.nossr50.config.serializers;
-
-import com.gmail.nossr50.datatypes.skills.properties.AbstractMaxBonusLevel;
-import com.gmail.nossr50.datatypes.skills.properties.MaxBonusLevel;
-import com.google.common.reflect.TypeToken;
-import ninja.leaping.configurate.ConfigurationNode;
-import ninja.leaping.configurate.objectmapping.ObjectMappingException;
-import ninja.leaping.configurate.objectmapping.serialize.TypeSerializer;
-import org.checkerframework.checker.nullness.qual.NonNull;
-import org.checkerframework.checker.nullness.qual.Nullable;
-
-public class MaxBonusLevelSerializer implements TypeSerializer<MaxBonusLevel> {
-
-    public static final String STANDARD_NODE = "Standard-Max-Bonus-Level";
-    public static final String RETRO_NODE = "Retro-Max-Bonus-Level";
-
-    @Nullable
-    @Override
-    public MaxBonusLevel deserialize(@NonNull TypeToken<?> type, @NonNull ConfigurationNode value) throws ObjectMappingException {
-        int standard = value.getNode(STANDARD_NODE).getValue(TypeToken.of(Integer.class));
-        int retro = value.getNode(RETRO_NODE).getValue(TypeToken.of(Integer.class));
-
-        AbstractMaxBonusLevel maxBonusLevel = new AbstractMaxBonusLevel(standard, retro);
-        return maxBonusLevel;
-    }
-
-    @Override
-    public void serialize(@NonNull TypeToken<?> type, @Nullable MaxBonusLevel obj, @NonNull ConfigurationNode value) throws ObjectMappingException {
-        value.getNode(STANDARD_NODE).setValue(obj.getStandardScaleValue());
-        value.getNode(RETRO_NODE).setValue(obj.getRetroScaleValue());
-    }
-
-}

+ 4 - 10
mcmmo-core/src/main/java/com/gmail/nossr50/config/serializers/SkillRankPropertySerializer.java

@@ -13,21 +13,17 @@ import java.util.Map;
 
 
 public class SkillRankPropertySerializer implements TypeSerializer<SkillRankProperty> {
 public class SkillRankPropertySerializer implements TypeSerializer<SkillRankProperty> {
 
 
-    private static final String STANDARD_RANK_UNLOCK_LEVEL_REQUIREMENTS = "Standard-Rank-Unlock-Level-Requirements";
-    private static final String RETRO_RANK_UNLOCK_LEVEL_REQUIREMENTS = "Retro-Rank-Unlock-Level-Requirements";
+    private static final String RANK_UNLOCK_LEVEL_REQUIREMENTS = "Standard-Rank-Unlock-Level-Requirements";
 
 
     @Nullable
     @Nullable
     @Override
     @Override
     public SkillRankProperty deserialize(@NonNull TypeToken<?> type, @NonNull ConfigurationNode value) throws ObjectMappingException {
     public SkillRankProperty deserialize(@NonNull TypeToken<?> type, @NonNull ConfigurationNode value) throws ObjectMappingException {
         HashMap<Integer, Integer> standardHashMap;
         HashMap<Integer, Integer> standardHashMap;
-        HashMap<Integer, Integer> retroHashMap;
 
 
         try {
         try {
-            Map<? extends Integer, ? extends Integer> standardMap = value.getNode(STANDARD_RANK_UNLOCK_LEVEL_REQUIREMENTS).getValue(new TypeToken<Map<? extends Integer, ? extends Integer>>() {});
-            Map<? extends Integer, ? extends Integer> retroMap = value.getNode(RETRO_RANK_UNLOCK_LEVEL_REQUIREMENTS).getValue(new TypeToken<Map<? extends Integer, ? extends Integer>>() {});
+            Map<? extends Integer, ? extends Integer> standardMap = value.getNode(RANK_UNLOCK_LEVEL_REQUIREMENTS).getValue(new TypeToken<Map<? extends Integer, ? extends Integer>>() {});
 
 
             standardHashMap = new HashMap<>(standardMap);
             standardHashMap = new HashMap<>(standardMap);
-            retroHashMap = new HashMap<>(retroMap);
 
 
         } catch (ObjectMappingException e) {
         } catch (ObjectMappingException e) {
             System.out.println("[mcMMO Deserializer Debug] Unable to deserialize rank property information from the config, make sure the ranks are correctly set in the config. You can delete the rank config to generate a new one if problems persist.");
             System.out.println("[mcMMO Deserializer Debug] Unable to deserialize rank property information from the config, make sure the ranks are correctly set in the config. You can delete the rank config to generate a new one if problems persist.");
@@ -35,15 +31,13 @@ public class SkillRankPropertySerializer implements TypeSerializer<SkillRankProp
         }
         }
 
 
         SkillRankProperty skillRankProperty = new SkillRankProperty();
         SkillRankProperty skillRankProperty = new SkillRankProperty();
-        skillRankProperty.setStandardRanks(standardHashMap);
-        skillRankProperty.setRetroRanks(retroHashMap);
+        skillRankProperty.setRanks(standardHashMap);
 
 
         return skillRankProperty;
         return skillRankProperty;
     }
     }
 
 
     @Override
     @Override
     public void serialize(@NonNull TypeToken<?> type, @Nullable SkillRankProperty obj, @NonNull ConfigurationNode value) throws ObjectMappingException {
     public void serialize(@NonNull TypeToken<?> type, @Nullable SkillRankProperty obj, @NonNull ConfigurationNode value) throws ObjectMappingException {
-        value.getNode(STANDARD_RANK_UNLOCK_LEVEL_REQUIREMENTS).setValue(obj.getStandardRanks());
-        value.getNode(RETRO_RANK_UNLOCK_LEVEL_REQUIREMENTS).setValue(obj.getRetroRanks());
+        value.getNode(RANK_UNLOCK_LEVEL_REQUIREMENTS).setValue(obj.getRanks());
     }
     }
 }
 }

+ 2 - 4
mcmmo-core/src/main/java/com/gmail/nossr50/config/skills/ConfigMaxLevel.java

@@ -1,8 +1,6 @@
 package com.gmail.nossr50.config.skills;
 package com.gmail.nossr50.config.skills;
 
 
 import com.gmail.nossr50.config.ConfigConstants;
 import com.gmail.nossr50.config.ConfigConstants;
-import com.gmail.nossr50.datatypes.skills.properties.AbstractMaxBonusLevel;
-import com.gmail.nossr50.datatypes.skills.properties.MaxBonusLevel;
 import ninja.leaping.configurate.objectmapping.Setting;
 import ninja.leaping.configurate.objectmapping.Setting;
 import ninja.leaping.configurate.objectmapping.serialize.ConfigSerializable;
 import ninja.leaping.configurate.objectmapping.serialize.ConfigSerializable;
 
 
@@ -11,9 +9,9 @@ public class ConfigMaxLevel {
     @Setting(value = ConfigConstants.MAX_BONUS_LEVEL_FIELD_NAME, comment = "Max bonus level is the level a player needs to reach in this skill to receive maximum benefits, such as better RNG odds or otherwise." +
     @Setting(value = ConfigConstants.MAX_BONUS_LEVEL_FIELD_NAME, comment = "Max bonus level is the level a player needs to reach in this skill to receive maximum benefits, such as better RNG odds or otherwise." +
             "\nSkills dynamically adjust their rewards to match the max bonus level, you can think of it as a curve that calculates what bonuses " +
             "\nSkills dynamically adjust their rewards to match the max bonus level, you can think of it as a curve that calculates what bonuses " +
             "\n a player should have based on how far they are from the max bonus level value, and the other parameters used for the scaling of the sub-skill.")
             "\n a player should have based on how far they are from the max bonus level value, and the other parameters used for the scaling of the sub-skill.")
-    private MaxBonusLevel maxBonusLevel = new AbstractMaxBonusLevel(100);
+    private int maxBonusLevel = 1000;
 
 
-    public MaxBonusLevel getMaxBonusLevel() {
+    public int getMaxBonusLevel() {
         return maxBonusLevel;
         return maxBonusLevel;
     }
     }
 }
 }

+ 3 - 19
mcmmo-core/src/main/java/com/gmail/nossr50/config/skills/acrobatics/dodge/ConfigDodge.java

@@ -1,8 +1,6 @@
 package com.gmail.nossr50.config.skills.acrobatics.dodge;
 package com.gmail.nossr50.config.skills.acrobatics.dodge;
 
 
 import com.gmail.nossr50.config.ConfigConstants;
 import com.gmail.nossr50.config.ConfigConstants;
-import com.gmail.nossr50.datatypes.skills.properties.AbstractMaxBonusLevel;
-import com.gmail.nossr50.datatypes.skills.properties.MaxBonusLevel;
 import ninja.leaping.configurate.objectmapping.Setting;
 import ninja.leaping.configurate.objectmapping.Setting;
 import ninja.leaping.configurate.objectmapping.serialize.ConfigSerializable;
 import ninja.leaping.configurate.objectmapping.serialize.ConfigSerializable;
 
 
@@ -22,25 +20,11 @@ public class ConfigDodge {
             "\nDefault value: " + DAMAGE_REDUCTION_DIVISOR_DEFAULT)
             "\nDefault value: " + DAMAGE_REDUCTION_DIVISOR_DEFAULT)
     private double damageReductionDivisor = DAMAGE_REDUCTION_DIVISOR_DEFAULT;
     private double damageReductionDivisor = DAMAGE_REDUCTION_DIVISOR_DEFAULT;
 
 
-    @Setting(value = ConfigConstants.MAX_BONUS_LEVEL_FIELD_NAME, comment = "Max bonus level is the level a player needs to reach in this skill to receive maximum benefits, such as better RNG odds or otherwise." +
-            "\nSkills dynamically adjust their rewards to match the max bonus level, you can think of it as a curve that calculates what bonuses " +
-            "\n a player should have based on how far they are from the max bonus level value, and the other parameters used for the scaling of the sub-skill.")
-    private MaxBonusLevel maxBonusLevel = new AbstractMaxBonusLevel(100);
-
-    @Setting(value = ConfigConstants.MAX_CHANCE_FIELD_NAME, comment = "The maximum success chance for this Sub-Skill." +
-            "\nA value of 100.0 would be equivalent to 100% chance of success." +
-            "\nPlayers only have Max-Success-Chance when their skill level has reached the maximum bonus level." +
-            "\nMax skill chance is dynamically adjusted based on the players level difference from the \"Max-Bonus-Level\", you can think of it as a curve where reaching \"Max-Bonus-Level\" is the peak." +
-            "\nAs an example, imagine \""+ConfigConstants.MAX_CHANCE_FIELD_NAME+"\" was set to " + FIFTY_PERCENT_EXAMPLE + " and the \""+ConfigConstants.MAX_BONUS_LEVEL_FIELD_NAME+"\" was " + MAX_BONUS_LEVEL_EXAMPLE + "," +
-            "\n and the player was level " + FIFTY_PERCENT_EXAMPLE + " for this skill, that would give the player " + ODDS_PERCENTAGE_EXAMPLE + " odds to succeed with this skill.")
-    private double chanceAtMaxSkill = CHANCE_AT_MAX_SKILL_DEFAULT;
-
-    public MaxBonusLevel getMaxBonusLevel() {
-        return maxBonusLevel;
-    }
+    @Setting(value = ConfigConstants.MAX_CHANCE_FIELD_NAME, comment = ConfigConstants.MAX_CHANCE_FIELD_DESCRIPTION)
+    private double maxChance = 100.0;
 
 
     public double getChanceAtMaxSkill() {
     public double getChanceAtMaxSkill() {
-        return chanceAtMaxSkill;
+        return maxChance;
     }
     }
 
 
     public double getDamageReductionDivisor() {
     public double getDamageReductionDivisor() {

+ 3 - 22
mcmmo-core/src/main/java/com/gmail/nossr50/config/skills/acrobatics/roll/ConfigRoll.java

@@ -1,8 +1,6 @@
 package com.gmail.nossr50.config.skills.acrobatics.roll;
 package com.gmail.nossr50.config.skills.acrobatics.roll;
 
 
 import com.gmail.nossr50.config.ConfigConstants;
 import com.gmail.nossr50.config.ConfigConstants;
-import com.gmail.nossr50.datatypes.skills.properties.AbstractMaxBonusLevel;
-import com.gmail.nossr50.datatypes.skills.properties.MaxBonusLevel;
 import ninja.leaping.configurate.objectmapping.Setting;
 import ninja.leaping.configurate.objectmapping.Setting;
 import ninja.leaping.configurate.objectmapping.serialize.ConfigSerializable;
 import ninja.leaping.configurate.objectmapping.serialize.ConfigSerializable;
 
 
@@ -10,9 +8,6 @@ import ninja.leaping.configurate.objectmapping.serialize.ConfigSerializable;
 public class ConfigRoll {
 public class ConfigRoll {
 
 
     public static final double ROLL_DAMAGE_THRESHOLD_DEFAULT = 7.0D;
     public static final double ROLL_DAMAGE_THRESHOLD_DEFAULT = 7.0D;
-    public static final String FIFTY_PERCENT_EXAMPLE = "50";
-    public static final String MAX_BONUS_LEVEL_EXAMPLE = "100";
-    public static final String ODDS_PERCENTAGE_EXAMPLE = "25%";
     public static final double CHANCE_AT_MAX_SKILL_DEFAULT = 100.0D;
     public static final double CHANCE_AT_MAX_SKILL_DEFAULT = 100.0D;
 
 
     @Setting(value = "Damage-Threshold", comment = "Rolling will reduce up to this much damage." +
     @Setting(value = "Damage-Threshold", comment = "Rolling will reduce up to this much damage." +
@@ -24,24 +19,10 @@ public class ConfigRoll {
         return damageTheshold;
         return damageTheshold;
     }
     }
 
 
-    @Setting(value = ConfigConstants.MAX_BONUS_LEVEL_FIELD_NAME, comment = "Max bonus level is the level a player needs to reach in this skill to receive maximum benefits, such as better RNG odds or otherwise." +
-            "\nSkills dynamically adjust their rewards to match the max bonus level, you can think of it as a curve that calculates what bonuses " +
-            "\n a player should have based on how far they are from the max bonus level value, and the other parameters used for the scaling of the sub-skill.")
-    private MaxBonusLevel maxBonusLevel = new AbstractMaxBonusLevel(100);
-
-    @Setting(value = ConfigConstants.MAX_CHANCE_FIELD_NAME, comment = "The maximum success chance for this Sub-Skill." +
-            "\nA value of 100.0 would be equivalent to 100% chance of success." +
-            "\nPlayers only have Max-Success-Chance when their skill level has reached the maximum bonus level." +
-            "\nMax skill chance is dynamically adjusted based on the players level difference from the \"Max-Bonus-Level\", you can think of it as a curve where reaching \"Max-Bonus-Level\" is the peak." +
-            "\nAs an example, imagine \""+ConfigConstants.MAX_CHANCE_FIELD_NAME+"\" was set to " + FIFTY_PERCENT_EXAMPLE + " and the \""+ConfigConstants.MAX_BONUS_LEVEL_FIELD_NAME+"\" was " + MAX_BONUS_LEVEL_EXAMPLE + "," +
-            "\n and the player was level " + FIFTY_PERCENT_EXAMPLE + " for this skill, that would give the player " + ODDS_PERCENTAGE_EXAMPLE + " odds to succeed with this skill.")
-    private double chanceAtMaxSkill = CHANCE_AT_MAX_SKILL_DEFAULT;
-
-    public MaxBonusLevel getMaxBonusLevel() {
-        return maxBonusLevel;
-    }
+    @Setting(value = ConfigConstants.MAX_CHANCE_FIELD_NAME, comment = ConfigConstants.MAX_CHANCE_FIELD_DESCRIPTION)
+    private double maxChance = 100.0D;
 
 
     public double getChanceAtMaxSkill() {
     public double getChanceAtMaxSkill() {
-        return chanceAtMaxSkill;
+        return maxChance;
     }
     }
 }
 }

+ 0 - 9
mcmmo-core/src/main/java/com/gmail/nossr50/config/skills/archery/ConfigArcheryArrowRetrieval.java

@@ -1,8 +1,6 @@
 package com.gmail.nossr50.config.skills.archery;
 package com.gmail.nossr50.config.skills.archery;
 
 
 import com.gmail.nossr50.config.ConfigConstants;
 import com.gmail.nossr50.config.ConfigConstants;
-import com.gmail.nossr50.datatypes.skills.properties.AbstractMaxBonusLevel;
-import com.gmail.nossr50.datatypes.skills.properties.MaxBonusLevel;
 import ninja.leaping.configurate.objectmapping.Setting;
 import ninja.leaping.configurate.objectmapping.Setting;
 import ninja.leaping.configurate.objectmapping.serialize.ConfigSerializable;
 import ninja.leaping.configurate.objectmapping.serialize.ConfigSerializable;
 
 
@@ -12,14 +10,7 @@ public class ConfigArcheryArrowRetrieval {
     @Setting(value = ConfigConstants.MAX_CHANCE_FIELD_NAME, comment = ConfigConstants.MAX_CHANCE_FIELD_DESCRIPTION)
     @Setting(value = ConfigConstants.MAX_CHANCE_FIELD_NAME, comment = ConfigConstants.MAX_CHANCE_FIELD_DESCRIPTION)
     private double maxChance = 100.0D;
     private double maxChance = 100.0D;
 
 
-    @Setting(value = ConfigConstants.MAX_BONUS_LEVEL_FIELD_NAME)
-    private MaxBonusLevel maxBonusLevel = new AbstractMaxBonusLevel(100);
-
     public double getMaxChance() {
     public double getMaxChance() {
         return maxChance;
         return maxChance;
     }
     }
-
-    public MaxBonusLevel getMaxBonusLevel() {
-        return maxBonusLevel;
-    }
 }
 }

+ 0 - 9
mcmmo-core/src/main/java/com/gmail/nossr50/config/skills/archery/ConfigArcheryDaze.java

@@ -1,8 +1,6 @@
 package com.gmail.nossr50.config.skills.archery;
 package com.gmail.nossr50.config.skills.archery;
 
 
 import com.gmail.nossr50.config.ConfigConstants;
 import com.gmail.nossr50.config.ConfigConstants;
-import com.gmail.nossr50.datatypes.skills.properties.AbstractMaxBonusLevel;
-import com.gmail.nossr50.datatypes.skills.properties.MaxBonusLevel;
 import ninja.leaping.configurate.objectmapping.Setting;
 import ninja.leaping.configurate.objectmapping.Setting;
 import ninja.leaping.configurate.objectmapping.serialize.ConfigSerializable;
 import ninja.leaping.configurate.objectmapping.serialize.ConfigSerializable;
 
 
@@ -15,9 +13,6 @@ public class ConfigArcheryDaze {
         + "\nDefault value: "+DAZE_MAX_CHANCE_DEFAULT)
         + "\nDefault value: "+DAZE_MAX_CHANCE_DEFAULT)
     private double maxChance = DAZE_MAX_CHANCE_DEFAULT;
     private double maxChance = DAZE_MAX_CHANCE_DEFAULT;
 
 
-    @Setting(value = ConfigConstants.MAX_BONUS_LEVEL_FIELD_NAME)
-    private MaxBonusLevel maxBonusLevel = new AbstractMaxBonusLevel(100);
-
     @Setting(value = "Bonus-Damage", comment = "How much bonus damage is applied when daze is applied to a target." +
     @Setting(value = "Bonus-Damage", comment = "How much bonus damage is applied when daze is applied to a target." +
             "\nDefault value: "+DAZE_BONUS_DMG_DEFAULT)
             "\nDefault value: "+DAZE_BONUS_DMG_DEFAULT)
     private double bonusDamage = DAZE_BONUS_DMG_DEFAULT;
     private double bonusDamage = DAZE_BONUS_DMG_DEFAULT;
@@ -26,10 +21,6 @@ public class ConfigArcheryDaze {
         return maxChance;
         return maxChance;
     }
     }
 
 
-    public MaxBonusLevel getMaxBonusLevel() {
-        return maxBonusLevel;
-    }
-
     public double getDazeBonusDamage() {
     public double getDazeBonusDamage() {
         return bonusDamage;
         return bonusDamage;
     }
     }

+ 3 - 8
mcmmo-core/src/main/java/com/gmail/nossr50/config/skills/axes/ConfigAxesCriticalStrikes.java

@@ -2,7 +2,6 @@ package com.gmail.nossr50.config.skills.axes;
 
 
 import com.gmail.nossr50.config.ConfigConstants;
 import com.gmail.nossr50.config.ConfigConstants;
 import com.gmail.nossr50.datatypes.skills.properties.AbstractDamageProperty;
 import com.gmail.nossr50.datatypes.skills.properties.AbstractDamageProperty;
-import com.gmail.nossr50.datatypes.skills.properties.AbstractMaxBonusLevel;
 import com.gmail.nossr50.datatypes.skills.properties.DamageProperty;
 import com.gmail.nossr50.datatypes.skills.properties.DamageProperty;
 import ninja.leaping.configurate.objectmapping.Setting;
 import ninja.leaping.configurate.objectmapping.Setting;
 import ninja.leaping.configurate.objectmapping.serialize.ConfigSerializable;
 import ninja.leaping.configurate.objectmapping.serialize.ConfigSerializable;
@@ -12,18 +11,14 @@ public class ConfigAxesCriticalStrikes {
 
 
     private static final double MAX_ACTIVATION_CHANCE_DEFAULT = 37.50D;
     private static final double MAX_ACTIVATION_CHANCE_DEFAULT = 37.50D;
 
 
-    @Setting(value = ConfigConstants.MAX_CHANCE_FIELD_NAME, comment = "This is max percentage chance that is used to determine whether or not the ability is successful." +
-            "\nA value of 50.0 would mean at most the ability can only have a 50% chance to work at max skill level.")
-    private double maxActivationChance = MAX_ACTIVATION_CHANCE_DEFAULT;
-
-    @Setting(value = ConfigConstants.MAX_BONUS_LEVEL_FIELD_NAME, comment = ConfigConstants.MAX_BONUS_LEVEL_DESCRIPTION)
-    private AbstractMaxBonusLevel maximumProgressionLevel = new AbstractMaxBonusLevel(100);
+    @Setting(value = ConfigConstants.MAX_CHANCE_FIELD_NAME, comment = ConfigConstants.MAX_CHANCE_FIELD_DESCRIPTION)
+    private double maxChance = MAX_ACTIVATION_CHANCE_DEFAULT;
 
 
     @Setting(value = "Damage-Modifiers", comment = "Damage dealt is multiplied by these values when this skill is successfully activated.")
     @Setting(value = "Damage-Modifiers", comment = "Damage dealt is multiplied by these values when this skill is successfully activated.")
     private DamageProperty damageProperty = new AbstractDamageProperty(1.5, 2.0);
     private DamageProperty damageProperty = new AbstractDamageProperty(1.5, 2.0);
 
 
     public double getMaxActivationChance() {
     public double getMaxActivationChance() {
-        return maxActivationChance;
+        return maxChance;
     }
     }
 
 
     public DamageProperty getDamageProperty() {
     public DamageProperty getDamageProperty() {

+ 0 - 6
mcmmo-core/src/main/java/com/gmail/nossr50/config/skills/herbalism/ConfigHerbalismDoubleDrops.java

@@ -1,8 +1,6 @@
 package com.gmail.nossr50.config.skills.herbalism;
 package com.gmail.nossr50.config.skills.herbalism;
 
 
 import com.gmail.nossr50.config.ConfigConstants;
 import com.gmail.nossr50.config.ConfigConstants;
-import com.gmail.nossr50.datatypes.skills.properties.AbstractMaxBonusLevel;
-import com.gmail.nossr50.datatypes.skills.properties.MaxBonusLevel;
 import ninja.leaping.configurate.objectmapping.Setting;
 import ninja.leaping.configurate.objectmapping.Setting;
 import ninja.leaping.configurate.objectmapping.serialize.ConfigSerializable;
 import ninja.leaping.configurate.objectmapping.serialize.ConfigSerializable;
 
 
@@ -11,8 +9,4 @@ public class ConfigHerbalismDoubleDrops {
 
 
     @Setting(value = ConfigConstants.MAX_CHANCE_FIELD_NAME, comment = ConfigConstants.MAX_CHANCE_FIELD_DESCRIPTION)
     @Setting(value = ConfigConstants.MAX_CHANCE_FIELD_NAME, comment = ConfigConstants.MAX_CHANCE_FIELD_DESCRIPTION)
     private double maxChance = 100.0;
     private double maxChance = 100.0;
-
-    @Setting(value = ConfigConstants.MAX_BONUS_LEVEL_FIELD_NAME)
-    private MaxBonusLevel maxBonusLevel = new AbstractMaxBonusLevel(100);
-
 }
 }

+ 0 - 6
mcmmo-core/src/main/java/com/gmail/nossr50/config/skills/herbalism/ConfigHerbalismGreenThumb.java

@@ -1,8 +1,6 @@
 package com.gmail.nossr50.config.skills.herbalism;
 package com.gmail.nossr50.config.skills.herbalism;
 
 
 import com.gmail.nossr50.config.ConfigConstants;
 import com.gmail.nossr50.config.ConfigConstants;
-import com.gmail.nossr50.datatypes.skills.properties.AbstractMaxBonusLevel;
-import com.gmail.nossr50.datatypes.skills.properties.MaxBonusLevel;
 import ninja.leaping.configurate.objectmapping.Setting;
 import ninja.leaping.configurate.objectmapping.Setting;
 import ninja.leaping.configurate.objectmapping.serialize.ConfigSerializable;
 import ninja.leaping.configurate.objectmapping.serialize.ConfigSerializable;
 
 
@@ -11,8 +9,4 @@ public class ConfigHerbalismGreenThumb {
 
 
     @Setting(value = ConfigConstants.MAX_CHANCE_FIELD_NAME, comment = ConfigConstants.MAX_CHANCE_FIELD_DESCRIPTION)
     @Setting(value = ConfigConstants.MAX_CHANCE_FIELD_NAME, comment = ConfigConstants.MAX_CHANCE_FIELD_DESCRIPTION)
     private double maxChance = 100.0;
     private double maxChance = 100.0;
-
-    @Setting(value = ConfigConstants.MAX_BONUS_LEVEL_FIELD_NAME)
-    private MaxBonusLevel maxBonusLevel = new AbstractMaxBonusLevel(100);
-
 }
 }

+ 0 - 6
mcmmo-core/src/main/java/com/gmail/nossr50/config/skills/herbalism/ConfigHerbalismHylianLuck.java

@@ -1,8 +1,6 @@
 package com.gmail.nossr50.config.skills.herbalism;
 package com.gmail.nossr50.config.skills.herbalism;
 
 
 import com.gmail.nossr50.config.ConfigConstants;
 import com.gmail.nossr50.config.ConfigConstants;
-import com.gmail.nossr50.datatypes.skills.properties.AbstractMaxBonusLevel;
-import com.gmail.nossr50.datatypes.skills.properties.MaxBonusLevel;
 import ninja.leaping.configurate.objectmapping.Setting;
 import ninja.leaping.configurate.objectmapping.Setting;
 import ninja.leaping.configurate.objectmapping.serialize.ConfigSerializable;
 import ninja.leaping.configurate.objectmapping.serialize.ConfigSerializable;
 
 
@@ -11,8 +9,4 @@ public class ConfigHerbalismHylianLuck {
 
 
     @Setting(value = ConfigConstants.MAX_CHANCE_FIELD_NAME, comment = ConfigConstants.MAX_CHANCE_FIELD_DESCRIPTION)
     @Setting(value = ConfigConstants.MAX_CHANCE_FIELD_NAME, comment = ConfigConstants.MAX_CHANCE_FIELD_DESCRIPTION)
     private double maxChance = 10.0;
     private double maxChance = 10.0;
-
-    @Setting(value = ConfigConstants.MAX_BONUS_LEVEL_FIELD_NAME)
-    private MaxBonusLevel maxBonusLevel = new AbstractMaxBonusLevel(100);
-
 }
 }

+ 0 - 5
mcmmo-core/src/main/java/com/gmail/nossr50/config/skills/herbalism/ConfigHerbalismShroomThumb.java

@@ -1,8 +1,6 @@
 package com.gmail.nossr50.config.skills.herbalism;
 package com.gmail.nossr50.config.skills.herbalism;
 
 
 import com.gmail.nossr50.config.ConfigConstants;
 import com.gmail.nossr50.config.ConfigConstants;
-import com.gmail.nossr50.datatypes.skills.properties.AbstractMaxBonusLevel;
-import com.gmail.nossr50.datatypes.skills.properties.MaxBonusLevel;
 import ninja.leaping.configurate.objectmapping.Setting;
 import ninja.leaping.configurate.objectmapping.Setting;
 import ninja.leaping.configurate.objectmapping.serialize.ConfigSerializable;
 import ninja.leaping.configurate.objectmapping.serialize.ConfigSerializable;
 
 
@@ -12,7 +10,4 @@ public class ConfigHerbalismShroomThumb {
     @Setting(value = ConfigConstants.MAX_CHANCE_FIELD_NAME, comment = ConfigConstants.MAX_CHANCE_FIELD_DESCRIPTION)
     @Setting(value = ConfigConstants.MAX_CHANCE_FIELD_NAME, comment = ConfigConstants.MAX_CHANCE_FIELD_DESCRIPTION)
     private double maxChance = 50.0;
     private double maxChance = 50.0;
 
 
-    @Setting(value = ConfigConstants.MAX_BONUS_LEVEL_FIELD_NAME)
-    private MaxBonusLevel maxBonusLevel = new AbstractMaxBonusLevel(100);
-
 }
 }

+ 0 - 5
mcmmo-core/src/main/java/com/gmail/nossr50/config/skills/mining/ConfigMiningDoubleDrops.java

@@ -1,8 +1,6 @@
 package com.gmail.nossr50.config.skills.mining;
 package com.gmail.nossr50.config.skills.mining;
 
 
 import com.gmail.nossr50.config.ConfigConstants;
 import com.gmail.nossr50.config.ConfigConstants;
-import com.gmail.nossr50.datatypes.skills.properties.AbstractMaxBonusLevel;
-import com.gmail.nossr50.datatypes.skills.properties.MaxBonusLevel;
 import ninja.leaping.configurate.objectmapping.Setting;
 import ninja.leaping.configurate.objectmapping.Setting;
 import ninja.leaping.configurate.objectmapping.serialize.ConfigSerializable;
 import ninja.leaping.configurate.objectmapping.serialize.ConfigSerializable;
 
 
@@ -11,9 +9,6 @@ public class ConfigMiningDoubleDrops {
     @Setting(value = ConfigConstants.MAX_CHANCE_FIELD_NAME, comment = ConfigConstants.MAX_CHANCE_FIELD_DESCRIPTION)
     @Setting(value = ConfigConstants.MAX_CHANCE_FIELD_NAME, comment = ConfigConstants.MAX_CHANCE_FIELD_DESCRIPTION)
     private double maxChance = 100.0;
     private double maxChance = 100.0;
 
 
-    @Setting(value = ConfigConstants.MAX_BONUS_LEVEL_FIELD_NAME)
-    private MaxBonusLevel maxBonusLevel = new AbstractMaxBonusLevel(100);
-
     @Setting(value = "Silk-Touch-Double-Drops", comment = "Allow silk touch to benefit from double drops.")
     @Setting(value = "Silk-Touch-Double-Drops", comment = "Allow silk touch to benefit from double drops.")
     private boolean allowSilkTouchDoubleDrops = true;
     private boolean allowSilkTouchDoubleDrops = true;
 
 

+ 30 - 58
mcmmo-core/src/main/java/com/gmail/nossr50/config/skills/ranks/SkillRankProperty.java

@@ -2,13 +2,14 @@ package com.gmail.nossr50.config.skills.ranks;
 
 
 import com.gmail.nossr50.api.exceptions.MissingSkillPropertyDefinition;
 import com.gmail.nossr50.api.exceptions.MissingSkillPropertyDefinition;
 import com.gmail.nossr50.datatypes.skills.properties.SkillProperty;
 import com.gmail.nossr50.datatypes.skills.properties.SkillProperty;
+import com.gmail.nossr50.mcMMO;
+import org.apache.logging.log4j.Level;
 
 
 import java.util.HashMap;
 import java.util.HashMap;
 
 
 public class SkillRankProperty implements SkillProperty {
 public class SkillRankProperty implements SkillProperty {
 
 
-    private HashMap<Integer, Integer> standardRanks;
-    private HashMap<Integer, Integer> retroRanks;
+    private HashMap<Integer, Integer> ranks;
 
 
     public SkillRankProperty(Integer... rankDefinitions) {
     public SkillRankProperty(Integer... rankDefinitions) {
         initRankMaps();
         initRankMaps();
@@ -16,88 +17,59 @@ public class SkillRankProperty implements SkillProperty {
         for(int x = 0; x < rankDefinitions.length; x++) {
         for(int x = 0; x < rankDefinitions.length; x++) {
             int curRank = x+1;
             int curRank = x+1;
 
 
-            addStandardAndRetroRank(curRank, rankDefinitions[x]);
+            addRank(curRank, rankDefinitions[x]);
         }
         }
     }
     }
 
 
-    public SkillRankProperty(HashMap<Integer, Integer> standardRanks, HashMap<Integer, Integer> retroRanks) {
-        this.standardRanks = standardRanks;
-        this.retroRanks = retroRanks;
+    public SkillRankProperty(HashMap<Integer, Integer> ranks) {
+        this.ranks = ranks;
     }
     }
 
 
     /**
     /**
-     * Convenience method to add Standard and Retro at the same time for default initialization of values
-     * Only requires standard values be passed
+     * Fill in the rank map and mutate it by the cosmetic modifier
      * @param curRank the rank to fill in the value for
      * @param curRank the rank to fill in the value for
-     * @param standardValue the value of the rank in Standard
+     * @param rankValue the value of the rank in Standard
      */
      */
-    private void addStandardAndRetroRank(int curRank, int standardValue) {
-        //Retro will be equal to standards rank requirement multiplied by 10 unless that value is 1, in which case it will also be 1
-        int retroValue = standardValue == 1 ? 1 : standardValue * 10;
-
+    private void addRank(int curRank, int rankValue) {
         //Avoid negative numbers
         //Avoid negative numbers
-        if(standardValue < 0) {
-            standardRanks.put(curRank, 0);
-            retroRanks.put(curRank, 0);
-        } else {
-            standardRanks.put(curRank, standardValue);
-            retroRanks.put(curRank, retroValue);
-        }
-    }
+        rankValue = Math.max(0, rankValue);
 
 
-    /**
-     * Convenience method to add Standard and Retro at the same time
-     * @param curRank the rank to fill in the value for
-     * @param standardValue the value of the rank in Standard
-     * @param retroValue the value of the rank in Retro
-     */
-    private void addStandardAndRetroRank(int curRank, int standardValue, int retroValue) {
-        //Avoid negative numbers
-        standardValue = Math.max(0, standardValue);
-        retroValue = Math.max(0, retroValue);
-
-        standardRanks.put(curRank, standardValue);
-        retroRanks.put(curRank, retroValue);
+        ranks.put(curRank, rankValue);
     }
     }
 
 
     private void initRankMaps() {
     private void initRankMaps() {
-        standardRanks = new HashMap<>();
-        retroRanks = new HashMap<>();
+        ranks = new HashMap<>();
     }
     }
 
 
     /**
     /**
      * Gets the unlock level for this skill as defined by this SkillRankProperty
      * Gets the unlock level for this skill as defined by this SkillRankProperty
-     * @param retroMode whether or not mcMMO is using RetroMode, true for if it is
      * @param targetRank the rank to get the unlock level for
      * @param targetRank the rank to get the unlock level for
      * @return the unlock level for target rank
      * @return the unlock level for target rank
      */
      */
-    public int getUnlockLevel(boolean retroMode, int targetRank) throws MissingSkillPropertyDefinition {
-        if(retroMode) {
-            if(retroRanks.get(targetRank) == null) {
-                throw new MissingSkillPropertyDefinition("No definition found for rank:"+targetRank+" using Retro scaling");
-            }
-            return retroRanks.get(targetRank);
-        } else {
-            if(standardRanks.get(targetRank) == null) {
-                throw new MissingSkillPropertyDefinition("No definition found for rank:"+targetRank+" using Standard scaling");
-            }
-            return standardRanks.get(targetRank);
+    public int getUnlockLevel(mcMMO pluginRef, int targetRank) throws MissingSkillPropertyDefinition {
+        if(ranks.get(targetRank) == null) {
+            throw new MissingSkillPropertyDefinition("No definition found for rank:"+targetRank+" using Standard scaling");
         }
         }
-    }
 
 
-    public void setStandardRanks(HashMap<Integer, Integer> standardRanks) {
-        this.standardRanks = standardRanks;
-    }
+        //Avoid zero or lower
+        int cosmeticModifier = Math.max(1, pluginRef.getPlayerLevelingSettings().getCosmeticLevelScaleModifier());
 
 
-    public void setRetroRanks(HashMap<Integer, Integer> retroRanks) {
-        this.retroRanks = retroRanks;
+        if(cosmeticModifier == 1)
+            return ranks.get(targetRank);
+
+        //Mutate rank
+        int rankValue = ranks.get(targetRank);
+        rankValue = rankValue / cosmeticModifier;
+
+        return rankValue;
     }
     }
 
 
-    public HashMap<Integer, Integer> getStandardRanks() {
-        return standardRanks;
+    public void setRanks(HashMap<Integer, Integer> ranks) {
+        this.ranks = ranks;
     }
     }
 
 
-    public HashMap<Integer, Integer> getRetroRanks() {
-        return retroRanks;
+    public HashMap<Integer, Integer> getRanks() {
+        return ranks;
     }
     }
+
 }
 }

+ 2 - 14
mcmmo-core/src/main/java/com/gmail/nossr50/config/skills/repair/ConfigRepairSuperRepair.java

@@ -1,8 +1,6 @@
 package com.gmail.nossr50.config.skills.repair;
 package com.gmail.nossr50.config.skills.repair;
 
 
 import com.gmail.nossr50.config.ConfigConstants;
 import com.gmail.nossr50.config.ConfigConstants;
-import com.gmail.nossr50.datatypes.skills.properties.AbstractMaxBonusLevel;
-import com.gmail.nossr50.datatypes.skills.properties.MaxBonusLevel;
 import ninja.leaping.configurate.objectmapping.Setting;
 import ninja.leaping.configurate.objectmapping.Setting;
 import ninja.leaping.configurate.objectmapping.serialize.ConfigSerializable;
 import ninja.leaping.configurate.objectmapping.serialize.ConfigSerializable;
 
 
@@ -14,17 +12,7 @@ public class ConfigRepairSuperRepair {
     private static final String ODDS_PERCENTAGE_EXAMPLE = "25%";
     private static final String ODDS_PERCENTAGE_EXAMPLE = "25%";
     private static final double CHANCE_AT_MAX_SKILL_DEFAULT = 100.0D;
     private static final double CHANCE_AT_MAX_SKILL_DEFAULT = 100.0D;
 
 
-    @Setting(value = ConfigConstants.MAX_BONUS_LEVEL_FIELD_NAME, comment = "Max bonus level is the level a player needs to reach in this skill to receive maximum benefits, such as better RNG odds or otherwise." +
-            "\nSkills dynamically adjust their rewards to match the max bonus level, you can think of it as a curve that calculates what bonuses " +
-            "\n a player should have based on how far they are from the max bonus level value, and the other parameters used for the scaling of the sub-skill.")
-    private MaxBonusLevel maxBonusLevel = new AbstractMaxBonusLevel(100);
-
-    @Setting(value = ConfigConstants.MAX_CHANCE_FIELD_NAME, comment = "The maximum success chance for this Sub-Skill." +
-            "\nA value of 100.0 would be equivalent to 100% chance of success." +
-            "\nPlayers only have Max-Success-Chance when their skill level has reached the maximum bonus level." +
-            "\nMax skill chance is dynamically adjusted based on the players level difference from the \"Max-Bonus-Level\", you can think of it as a curve where reaching \"Max-Bonus-Level\" is the peak." +
-            "\nAs an example, imagine \""+ConfigConstants.MAX_CHANCE_FIELD_NAME+"\" was set to " + FIFTY_PERCENT_EXAMPLE + " and the \""+ConfigConstants.MAX_BONUS_LEVEL_FIELD_NAME+"\" was " + MAX_BONUS_LEVEL_EXAMPLE + "," +
-            "\n and the player was level " + FIFTY_PERCENT_EXAMPLE + " for this skill, that would give the player " + ODDS_PERCENTAGE_EXAMPLE + " odds to succeed with this skill.")
-    private double chanceAtMaxSkill = CHANCE_AT_MAX_SKILL_DEFAULT;
+    @Setting(value = ConfigConstants.MAX_CHANCE_FIELD_NAME, comment = ConfigConstants.MAX_CHANCE_FIELD_DESCRIPTION)
+    private double maxChance = 100.0;
 
 
 }
 }

+ 0 - 9
mcmmo-core/src/main/java/com/gmail/nossr50/config/skills/repair/repairmastery/ConfigRepairRepairMastery.java

@@ -1,8 +1,6 @@
 package com.gmail.nossr50.config.skills.repair.repairmastery;
 package com.gmail.nossr50.config.skills.repair.repairmastery;
 
 
 import com.gmail.nossr50.config.ConfigConstants;
 import com.gmail.nossr50.config.ConfigConstants;
-import com.gmail.nossr50.datatypes.skills.properties.AbstractMaxBonusLevel;
-import com.gmail.nossr50.datatypes.skills.properties.MaxBonusLevel;
 import ninja.leaping.configurate.objectmapping.Setting;
 import ninja.leaping.configurate.objectmapping.Setting;
 import ninja.leaping.configurate.objectmapping.serialize.ConfigSerializable;
 import ninja.leaping.configurate.objectmapping.serialize.ConfigSerializable;
 
 
@@ -12,14 +10,7 @@ public class ConfigRepairRepairMastery {
     @Setting(value = ConfigConstants.MAX_BONUS_PERCENTAGE_FIELD_NAME)
     @Setting(value = ConfigConstants.MAX_BONUS_PERCENTAGE_FIELD_NAME)
     private double maxBonusPercentage = 200.0D;
     private double maxBonusPercentage = 200.0D;
 
 
-    @Setting(value = ConfigConstants.MAX_BONUS_LEVEL_FIELD_NAME, comment = ConfigConstants.MAX_BONUS_LEVEL_DESCRIPTION)
-    private MaxBonusLevel maxBonusLevel = new AbstractMaxBonusLevel(100);
-
     public double getMaxBonusPercentage() {
     public double getMaxBonusPercentage() {
         return maxBonusPercentage;
         return maxBonusPercentage;
     }
     }
-
-    public MaxBonusLevel getMaxBonusLevel() {
-        return maxBonusLevel;
-    }
 }
 }

+ 1 - 6
mcmmo-core/src/main/java/com/gmail/nossr50/config/skills/smelting/ConfigSmelting.java

@@ -1,7 +1,6 @@
 package com.gmail.nossr50.config.skills.smelting;
 package com.gmail.nossr50.config.skills.smelting;
 
 
 import com.gmail.nossr50.config.ConfigConstants;
 import com.gmail.nossr50.config.ConfigConstants;
-import com.gmail.nossr50.datatypes.skills.properties.MaxBonusLevel;
 import ninja.leaping.configurate.objectmapping.Setting;
 import ninja.leaping.configurate.objectmapping.Setting;
 import ninja.leaping.configurate.objectmapping.serialize.ConfigSerializable;
 import ninja.leaping.configurate.objectmapping.serialize.ConfigSerializable;
 
 
@@ -13,7 +12,7 @@ public class ConfigSmelting {
     @Setting(value = ConfigConstants.SUB_SKILL_NODE)
     @Setting(value = ConfigConstants.SUB_SKILL_NODE)
     private ConfigSmeltingSubSkills subskills = new ConfigSmeltingSubSkills();
     private ConfigSmeltingSubSkills subskills = new ConfigSmeltingSubSkills();
 
 
-    public ConfigSmeltingSubSkills getSubskills() {
+    public ConfigSmeltingSubSkills getSubSkills() {
         return subskills;
         return subskills;
     }
     }
 
 
@@ -26,10 +25,6 @@ public class ConfigSmelting {
         return subskills.getMaxChance();
         return subskills.getMaxChance();
     }
     }
 
 
-    public MaxBonusLevel getMaxBonusLevel() {
-        return subskills.getMaxBonusLevel();
-    }
-
     public HashMap<Integer, Integer> getXpMultiplierTable() {
     public HashMap<Integer, Integer> getXpMultiplierTable() {
         return subskills.getXpMultiplierTable();
         return subskills.getXpMultiplierTable();
     }
     }

+ 0 - 9
mcmmo-core/src/main/java/com/gmail/nossr50/config/skills/smelting/ConfigSmeltingSecondSmelt.java

@@ -1,8 +1,6 @@
 package com.gmail.nossr50.config.skills.smelting;
 package com.gmail.nossr50.config.skills.smelting;
 
 
 import com.gmail.nossr50.config.ConfigConstants;
 import com.gmail.nossr50.config.ConfigConstants;
-import com.gmail.nossr50.datatypes.skills.properties.AbstractMaxBonusLevel;
-import com.gmail.nossr50.datatypes.skills.properties.MaxBonusLevel;
 import ninja.leaping.configurate.objectmapping.Setting;
 import ninja.leaping.configurate.objectmapping.Setting;
 import ninja.leaping.configurate.objectmapping.serialize.ConfigSerializable;
 import ninja.leaping.configurate.objectmapping.serialize.ConfigSerializable;
 
 
@@ -28,17 +26,10 @@ public class ConfigSmeltingSecondSmelt {
     @Setting(value = ConfigConstants.MAX_CHANCE_FIELD_NAME, comment = ConfigConstants.MAX_CHANCE_FIELD_DESCRIPTION)
     @Setting(value = ConfigConstants.MAX_CHANCE_FIELD_NAME, comment = ConfigConstants.MAX_CHANCE_FIELD_DESCRIPTION)
     private double maxChance = 50.0;
     private double maxChance = 50.0;
 
 
-    @Setting(value = ConfigConstants.MAX_BONUS_LEVEL_FIELD_NAME, comment = ConfigConstants.MAX_BONUS_LEVEL_DESCRIPTION)
-    private MaxBonusLevel maxBonusLevel = new AbstractMaxBonusLevel(100);
-
     public double getMaxChance() {
     public double getMaxChance() {
         return maxChance;
         return maxChance;
     }
     }
 
 
-    public MaxBonusLevel getMaxBonusLevel() {
-        return maxBonusLevel;
-    }
-
     @Setting(value = "XP-Multiplier-Per-Rank")
     @Setting(value = "XP-Multiplier-Per-Rank")
     private HashMap<Integer, Integer> xpMultiplierTable = XP_MULT_MAP_DEFAULT;
     private HashMap<Integer, Integer> xpMultiplierTable = XP_MULT_MAP_DEFAULT;
 
 

+ 0 - 5
mcmmo-core/src/main/java/com/gmail/nossr50/config/skills/smelting/ConfigSmeltingSubSkills.java

@@ -1,6 +1,5 @@
 package com.gmail.nossr50.config.skills.smelting;
 package com.gmail.nossr50.config.skills.smelting;
 
 
-import com.gmail.nossr50.datatypes.skills.properties.MaxBonusLevel;
 import ninja.leaping.configurate.objectmapping.Setting;
 import ninja.leaping.configurate.objectmapping.Setting;
 import ninja.leaping.configurate.objectmapping.serialize.ConfigSerializable;
 import ninja.leaping.configurate.objectmapping.serialize.ConfigSerializable;
 
 
@@ -20,10 +19,6 @@ public class ConfigSmeltingSubSkills {
         return smeltingSecondSmelt.getMaxChance();
         return smeltingSecondSmelt.getMaxChance();
     }
     }
 
 
-    public MaxBonusLevel getMaxBonusLevel() {
-        return smeltingSecondSmelt.getMaxBonusLevel();
-    }
-
     public HashMap<Integer, Integer> getXpMultiplierTable() {
     public HashMap<Integer, Integer> getXpMultiplierTable() {
         return smeltingSecondSmelt.getXpMultiplierTable();
         return smeltingSecondSmelt.getXpMultiplierTable();
     }
     }

+ 0 - 9
mcmmo-core/src/main/java/com/gmail/nossr50/config/skills/swords/ConfigSwords.java

@@ -1,7 +1,6 @@
 package com.gmail.nossr50.config.skills.swords;
 package com.gmail.nossr50.config.skills.swords;
 
 
 import com.gmail.nossr50.config.ConfigConstants;
 import com.gmail.nossr50.config.ConfigConstants;
-import com.gmail.nossr50.datatypes.skills.properties.MaxBonusLevel;
 import ninja.leaping.configurate.objectmapping.Setting;
 import ninja.leaping.configurate.objectmapping.Setting;
 import ninja.leaping.configurate.objectmapping.serialize.ConfigSerializable;
 import ninja.leaping.configurate.objectmapping.serialize.ConfigSerializable;
 
 
@@ -31,10 +30,6 @@ public class ConfigSwords {
         return subSkills.getCounterAttackMaxChance();
         return subSkills.getCounterAttackMaxChance();
     }
     }
 
 
-    public MaxBonusLevel getCounterAttackMaxBonusLevel() {
-        return subSkills.getCounterAttackMaxBonusLevel();
-    }
-
     public double getCounterAttackDamageModifier() {
     public double getCounterAttackDamageModifier() {
         return subSkills.getCounterAttackDamageModifier();
         return subSkills.getCounterAttackDamageModifier();
     }
     }
@@ -47,10 +42,6 @@ public class ConfigSwords {
         return subSkills.getRuptureMaxChance();
         return subSkills.getRuptureMaxChance();
     }
     }
 
 
-    public MaxBonusLevel getRuptureMaxBonusLevel() {
-        return subSkills.getRuptureMaxBonusLevel();
-    }
-
     public double getRuptureDamagePlayer() {
     public double getRuptureDamagePlayer() {
         return subSkills.getRuptureDamagePlayer();
         return subSkills.getRuptureDamagePlayer();
     }
     }

+ 0 - 9
mcmmo-core/src/main/java/com/gmail/nossr50/config/skills/swords/ConfigSwordsCounterAttack.java

@@ -1,8 +1,6 @@
 package com.gmail.nossr50.config.skills.swords;
 package com.gmail.nossr50.config.skills.swords;
 
 
 import com.gmail.nossr50.config.ConfigConstants;
 import com.gmail.nossr50.config.ConfigConstants;
-import com.gmail.nossr50.datatypes.skills.properties.AbstractMaxBonusLevel;
-import com.gmail.nossr50.datatypes.skills.properties.MaxBonusLevel;
 import ninja.leaping.configurate.objectmapping.Setting;
 import ninja.leaping.configurate.objectmapping.Setting;
 import ninja.leaping.configurate.objectmapping.serialize.ConfigSerializable;
 import ninja.leaping.configurate.objectmapping.serialize.ConfigSerializable;
 
 
@@ -14,9 +12,6 @@ public class ConfigSwordsCounterAttack {
     @Setting(value = ConfigConstants.MAX_CHANCE_FIELD_NAME, comment = ConfigConstants.MAX_CHANCE_FIELD_DESCRIPTION)
     @Setting(value = ConfigConstants.MAX_CHANCE_FIELD_NAME, comment = ConfigConstants.MAX_CHANCE_FIELD_DESCRIPTION)
     private double maxChance = 30.0;
     private double maxChance = 30.0;
 
 
-    @Setting(value = ConfigConstants.MAX_BONUS_LEVEL_FIELD_NAME, comment = ConfigConstants.MAX_BONUS_LEVEL_DESCRIPTION)
-    private MaxBonusLevel maxBonusLevel = new AbstractMaxBonusLevel(100);
-
     @Setting(value = "Damage-Modifier", comment = "The damage returned from Counter-Attack will be equal to the damage dealt divided by this number." +
     @Setting(value = "Damage-Modifier", comment = "The damage returned from Counter-Attack will be equal to the damage dealt divided by this number." +
             "\nDefault value: "+DAMAGE_MODIFIER_DEFAULT)
             "\nDefault value: "+DAMAGE_MODIFIER_DEFAULT)
     private double damageModifier = DAMAGE_MODIFIER_DEFAULT;
     private double damageModifier = DAMAGE_MODIFIER_DEFAULT;
@@ -25,10 +20,6 @@ public class ConfigSwordsCounterAttack {
         return maxChance;
         return maxChance;
     }
     }
 
 
-    public MaxBonusLevel getCounterAttackMaxBonusLevel() {
-        return maxBonusLevel;
-    }
-
     public double getCounterAttackDamageModifier() {
     public double getCounterAttackDamageModifier() {
         return damageModifier;
         return damageModifier;
     }
     }

+ 0 - 9
mcmmo-core/src/main/java/com/gmail/nossr50/config/skills/swords/ConfigSwordsRupture.java

@@ -1,8 +1,6 @@
 package com.gmail.nossr50.config.skills.swords;
 package com.gmail.nossr50.config.skills.swords;
 
 
 import com.gmail.nossr50.config.ConfigConstants;
 import com.gmail.nossr50.config.ConfigConstants;
-import com.gmail.nossr50.datatypes.skills.properties.AbstractMaxBonusLevel;
-import com.gmail.nossr50.datatypes.skills.properties.MaxBonusLevel;
 import ninja.leaping.configurate.objectmapping.Setting;
 import ninja.leaping.configurate.objectmapping.Setting;
 import ninja.leaping.configurate.objectmapping.serialize.ConfigSerializable;
 import ninja.leaping.configurate.objectmapping.serialize.ConfigSerializable;
 
 
@@ -17,9 +15,6 @@ public class ConfigSwordsRupture {
     @Setting(value = ConfigConstants.MAX_CHANCE_FIELD_NAME, comment = ConfigConstants.MAX_CHANCE_FIELD_DESCRIPTION)
     @Setting(value = ConfigConstants.MAX_CHANCE_FIELD_NAME, comment = ConfigConstants.MAX_CHANCE_FIELD_DESCRIPTION)
     private double maxChance = MAX_CHANCE_DEFAULT;
     private double maxChance = MAX_CHANCE_DEFAULT;
 
 
-    @Setting(value = ConfigConstants.MAX_BONUS_LEVEL_FIELD_NAME)
-    private MaxBonusLevel maxBonusLevel = new AbstractMaxBonusLevel(100);
-
     @Setting(value = "Damage-Per-Tick-PVP")
     @Setting(value = "Damage-Per-Tick-PVP")
     private double damagePlayer = DAMAGE_PVP_DEFAULT;
     private double damagePlayer = DAMAGE_PVP_DEFAULT;
 
 
@@ -35,10 +30,6 @@ public class ConfigSwordsRupture {
         return maxChance;
         return maxChance;
     }
     }
 
 
-    public MaxBonusLevel getRuptureMaxBonusLevel() {
-        return maxBonusLevel;
-    }
-
     public double getRuptureDamagePlayer() {
     public double getRuptureDamagePlayer() {
         return damagePlayer;
         return damagePlayer;
     }
     }

+ 0 - 9
mcmmo-core/src/main/java/com/gmail/nossr50/config/skills/swords/ConfigSwordsSubSkills.java

@@ -1,6 +1,5 @@
 package com.gmail.nossr50.config.skills.swords;
 package com.gmail.nossr50.config.skills.swords;
 
 
-import com.gmail.nossr50.datatypes.skills.properties.MaxBonusLevel;
 import ninja.leaping.configurate.objectmapping.Setting;
 import ninja.leaping.configurate.objectmapping.Setting;
 import ninja.leaping.configurate.objectmapping.serialize.ConfigSerializable;
 import ninja.leaping.configurate.objectmapping.serialize.ConfigSerializable;
 
 
@@ -35,10 +34,6 @@ public class ConfigSwordsSubSkills {
         return counterAttack.getCounterAttackMaxChance();
         return counterAttack.getCounterAttackMaxChance();
     }
     }
 
 
-    public MaxBonusLevel getCounterAttackMaxBonusLevel() {
-        return counterAttack.getCounterAttackMaxBonusLevel();
-    }
-
     public double getCounterAttackDamageModifier() {
     public double getCounterAttackDamageModifier() {
         return counterAttack.getCounterAttackDamageModifier();
         return counterAttack.getCounterAttackDamageModifier();
     }
     }
@@ -51,10 +46,6 @@ public class ConfigSwordsSubSkills {
         return rupture.getRuptureMaxChance();
         return rupture.getRuptureMaxChance();
     }
     }
 
 
-    public MaxBonusLevel getRuptureMaxBonusLevel() {
-        return rupture.getRuptureMaxBonusLevel();
-    }
-
     public double getRuptureDamagePlayer() {
     public double getRuptureDamagePlayer() {
         return rupture.getRuptureDamagePlayer();
         return rupture.getRuptureDamagePlayer();
     }
     }

+ 0 - 9
mcmmo-core/src/main/java/com/gmail/nossr50/config/skills/taming/ConfigTamingGore.java

@@ -1,8 +1,6 @@
 package com.gmail.nossr50.config.skills.taming;
 package com.gmail.nossr50.config.skills.taming;
 
 
 import com.gmail.nossr50.config.ConfigConstants;
 import com.gmail.nossr50.config.ConfigConstants;
-import com.gmail.nossr50.datatypes.skills.properties.AbstractMaxBonusLevel;
-import com.gmail.nossr50.datatypes.skills.properties.MaxBonusLevel;
 import ninja.leaping.configurate.objectmapping.Setting;
 import ninja.leaping.configurate.objectmapping.Setting;
 import ninja.leaping.configurate.objectmapping.serialize.ConfigSerializable;
 import ninja.leaping.configurate.objectmapping.serialize.ConfigSerializable;
 
 
@@ -15,9 +13,6 @@ public class ConfigTamingGore {
     @Setting(value = "Gore-Bleed-Tick-Length", comment = "How many times to apply the bleed DOT from gore before it wears off.")
     @Setting(value = "Gore-Bleed-Tick-Length", comment = "How many times to apply the bleed DOT from gore before it wears off.")
     private int goreBleedTicks = 2;
     private int goreBleedTicks = 2;
 
 
-    @Setting(value = ConfigConstants.MAX_BONUS_LEVEL_FIELD_NAME, comment = ConfigConstants.MAX_BONUS_LEVEL_DESCRIPTION)
-    private MaxBonusLevel maxBonusLevel = new AbstractMaxBonusLevel(100);
-
     @Setting(value = "Gore-Damage-Modifier")
     @Setting(value = "Gore-Damage-Modifier")
     private double goreMofifier = 2.0;
     private double goreMofifier = 2.0;
 
 
@@ -25,10 +20,6 @@ public class ConfigTamingGore {
         return maxChance;
         return maxChance;
     }
     }
 
 
-    public MaxBonusLevel getMaxBonusLevel() {
-        return maxBonusLevel;
-    }
-
     public double getGoreMofifier() {
     public double getGoreMofifier() {
         return goreMofifier;
         return goreMofifier;
     }
     }

+ 0 - 9
mcmmo-core/src/main/java/com/gmail/nossr50/config/skills/woodcutting/ConfigWoodcuttingHarvest.java

@@ -1,8 +1,6 @@
 package com.gmail.nossr50.config.skills.woodcutting;
 package com.gmail.nossr50.config.skills.woodcutting;
 
 
 import com.gmail.nossr50.config.ConfigConstants;
 import com.gmail.nossr50.config.ConfigConstants;
-import com.gmail.nossr50.datatypes.skills.properties.AbstractMaxBonusLevel;
-import com.gmail.nossr50.datatypes.skills.properties.MaxBonusLevel;
 import ninja.leaping.configurate.objectmapping.Setting;
 import ninja.leaping.configurate.objectmapping.Setting;
 import ninja.leaping.configurate.objectmapping.serialize.ConfigSerializable;
 import ninja.leaping.configurate.objectmapping.serialize.ConfigSerializable;
 
 
@@ -14,15 +12,8 @@ public class ConfigWoodcuttingHarvest {
     @Setting(value = ConfigConstants.MAX_CHANCE_FIELD_NAME, comment = ConfigConstants.MAX_CHANCE_FIELD_DESCRIPTION)
     @Setting(value = ConfigConstants.MAX_CHANCE_FIELD_NAME, comment = ConfigConstants.MAX_CHANCE_FIELD_DESCRIPTION)
     private double maxChance = MAX_CHANCE_DEFAULT;
     private double maxChance = MAX_CHANCE_DEFAULT;
 
 
-    @Setting(value = ConfigConstants.MAX_BONUS_LEVEL_FIELD_NAME)
-    private MaxBonusLevel maxBonusLevel = new AbstractMaxBonusLevel(100);
-
     public double getMaxChance() {
     public double getMaxChance() {
         return maxChance;
         return maxChance;
     }
     }
 
 
-    public MaxBonusLevel getMaxBonusLevel() {
-        return maxBonusLevel;
-    }
-
 }
 }

+ 1 - 0
mcmmo-core/src/main/java/com/gmail/nossr50/config/sound/ConfigSound.java

@@ -29,6 +29,7 @@ public class ConfigSound {
         SOUND_SETTINGS_MAP_DEFAULT.put(SoundType.ABILITY_ACTIVATED_BERSERK, new SoundSetting(0.5, 1.7));
         SOUND_SETTINGS_MAP_DEFAULT.put(SoundType.ABILITY_ACTIVATED_BERSERK, new SoundSetting(0.5, 1.7));
         SOUND_SETTINGS_MAP_DEFAULT.put(SoundType.TIRED, new SoundSetting(1.0, 1.7));
         SOUND_SETTINGS_MAP_DEFAULT.put(SoundType.TIRED, new SoundSetting(1.0, 1.7));
         SOUND_SETTINGS_MAP_DEFAULT.put(SoundType.BLEED, new SoundSetting(2.0, 2.0));
         SOUND_SETTINGS_MAP_DEFAULT.put(SoundType.BLEED, new SoundSetting(2.0, 2.0));
+        SOUND_SETTINGS_MAP_DEFAULT.put(SoundType.GLASS, new SoundSetting(1.0, 1.0));
     }
     }
 
 
     @Setting(value = "Sound-Settings", comment = "Adjust sound settings for various mcMMO sounds here." +
     @Setting(value = "Sound-Settings", comment = "Adjust sound settings for various mcMMO sounds here." +

+ 50 - 2
mcmmo-core/src/main/java/com/gmail/nossr50/core/MaterialMapStore.java

@@ -3,6 +3,7 @@ package com.gmail.nossr50.core;
 import org.bukkit.Material;
 import org.bukkit.Material;
 
 
 import java.util.HashSet;
 import java.util.HashSet;
+import java.util.Locale;
 
 
 /**
 /**
  * Stores hash tables for item and block names
  * Stores hash tables for item and block names
@@ -21,6 +22,7 @@ public class MaterialMapStore {
     private HashSet<String> canMakeShroomyWhiteList;
     private HashSet<String> canMakeShroomyWhiteList;
     private HashSet<String> multiBlockPlant;
     private HashSet<String> multiBlockPlant;
     private HashSet<String> foodItemWhiteList;
     private HashSet<String> foodItemWhiteList;
+    private HashSet<String> glassBlocks;
 
 
     public MaterialMapStore() {
     public MaterialMapStore() {
         abilityBlackList = new HashSet<>();
         abilityBlackList = new HashSet<>();
@@ -32,6 +34,7 @@ public class MaterialMapStore {
         canMakeShroomyWhiteList = new HashSet<>();
         canMakeShroomyWhiteList = new HashSet<>();
         multiBlockPlant = new HashSet<>();
         multiBlockPlant = new HashSet<>();
         foodItemWhiteList = new HashSet<>();
         foodItemWhiteList = new HashSet<>();
+        glassBlocks = new HashSet<>();
 
 
         fillHardcodedHashSets();
         fillHardcodedHashSets();
     }
     }
@@ -79,6 +82,44 @@ public class MaterialMapStore {
         fillShroomyWhiteList();
         fillShroomyWhiteList();
         fillMultiBlockEntitiesList();
         fillMultiBlockEntitiesList();
         fillFoodWhiteList();
         fillFoodWhiteList();
+        fillGlassBlockWhiteList();
+    }
+
+    private void fillGlassBlockWhiteList() {
+        glassBlocks.add("glass");
+        glassBlocks.add("glass_pane");
+        glassBlocks.add("black_stained_glass");
+        glassBlocks.add("black_stained_glass_pane");
+        glassBlocks.add("blue_stained_glass");
+        glassBlocks.add("blue_stained_glass_pane");
+        glassBlocks.add("brown_stained_glass");
+        glassBlocks.add("brown_stained_glass_pane");
+        glassBlocks.add("cyan_stained_glass");
+        glassBlocks.add("cyan_stained_glass_pane");
+        glassBlocks.add("gray_stained_glass");
+        glassBlocks.add("gray_stained_glass_pane");
+        glassBlocks.add("green_stained_glass");
+        glassBlocks.add("green_stained_glass_pane");
+        glassBlocks.add("light_blue_stained_glass");
+        glassBlocks.add("light_blue_stained_glass_pane");
+        glassBlocks.add("light_gray_stained_glass");
+        glassBlocks.add("light_gray_stained_glass_pane");
+        glassBlocks.add("lime_stained_glass");
+        glassBlocks.add("lime_stained_glass_pane");
+        glassBlocks.add("magenta_stained_glass");
+        glassBlocks.add("magenta_stained_glass_pane");
+        glassBlocks.add("orange_stained_glass");
+        glassBlocks.add("orange_stained_glass_pane");
+        glassBlocks.add("pink_stained_glass");
+        glassBlocks.add("pink_stained_glass_pane");
+        glassBlocks.add("purple_stained_glass");
+        glassBlocks.add("purple_stained_glass_pane");
+        glassBlocks.add("red_stained_glass");
+        glassBlocks.add("red_stained_glass_pane");
+        glassBlocks.add("white_stained_glass");
+        glassBlocks.add("white_stained_glass_pane");
+        glassBlocks.add("yellow_stained_glass");
+        glassBlocks.add("yellow_stained_glass_pane");
     }
     }
 
 
     private void fillFoodWhiteList() {
     private void fillFoodWhiteList() {
@@ -120,6 +161,10 @@ public class MaterialMapStore {
         foodItemWhiteList.add("tropical_fish");
         foodItemWhiteList.add("tropical_fish");
     }
     }
 
 
+    public boolean isGlass(Material material) {
+        return glassBlocks.contains(material.getKey().getKey());
+    }
+
     public boolean isFood(Material material) {
     public boolean isFood(Material material) {
         return foodItemWhiteList.contains(material.getKey().getKey());
         return foodItemWhiteList.contains(material.getKey().getKey());
     }
     }
@@ -146,6 +191,8 @@ public class MaterialMapStore {
 
 
     private void fillBlockCrackerWhiteList() {
     private void fillBlockCrackerWhiteList() {
         blockCrackerWhiteList.add("stone_bricks");
         blockCrackerWhiteList.add("stone_bricks");
+        blockCrackerWhiteList.add("infested_stone_bricks");
+
     }
     }
 
 
     private void fillHerbalismAbilityBlackList() {
     private void fillHerbalismAbilityBlackList() {
@@ -426,7 +473,8 @@ public class MaterialMapStore {
         toolBlackList.add("stonecutter");
         toolBlackList.add("stonecutter");
     }
     }
 
 
-    private void addToHashSet(String string, HashSet<String> stringHashSet) {
-        stringHashSet.add(string.toLowerCase());
+    private void addToHashSet(String string, HashSet<String> stringHashSet)
+    {
+        stringHashSet.add(string.toLowerCase(Locale.ENGLISH));
     }
     }
 }
 }

+ 5 - 10
mcmmo-core/src/main/java/com/gmail/nossr50/core/SkillPropertiesManager.java

@@ -3,7 +3,6 @@ package com.gmail.nossr50.core;
 import com.gmail.nossr50.config.ConfigConstants;
 import com.gmail.nossr50.config.ConfigConstants;
 import com.gmail.nossr50.datatypes.skills.PrimarySkillType;
 import com.gmail.nossr50.datatypes.skills.PrimarySkillType;
 import com.gmail.nossr50.datatypes.skills.SubSkillType;
 import com.gmail.nossr50.datatypes.skills.SubSkillType;
-import com.gmail.nossr50.datatypes.skills.properties.MaxBonusLevel;
 import com.gmail.nossr50.mcMMO;
 import com.gmail.nossr50.mcMMO;
 import com.gmail.nossr50.util.random.InvalidStaticChance;
 import com.gmail.nossr50.util.random.InvalidStaticChance;
 import com.google.common.reflect.TypeToken;
 import com.google.common.reflect.TypeToken;
@@ -31,8 +30,8 @@ public class SkillPropertiesManager {
         staticActivationChanceMap = new HashMap<>();
         staticActivationChanceMap = new HashMap<>();
     }
     }
 
 
-    public void registerMaxBonusLevel(SubSkillType subSkillType, MaxBonusLevel maxBonusLevel) {
-        maxBonusLevelMap.put(subSkillType, pluginRef.isRetroModeEnabled() ? maxBonusLevel.getRetroScaleValue() : maxBonusLevel.getStandardScaleValue());
+    public void registerMaxBonusLevel(SubSkillType subSkillType, int maxBonusLevel) {
+        maxBonusLevelMap.put(subSkillType, maxBonusLevel);
     }
     }
 
 
     public void registerMaxBonus(SubSkillType subSkillType, double maxBonus) {
     public void registerMaxBonus(SubSkillType subSkillType, double maxBonus) {
@@ -133,13 +132,9 @@ public class SkillPropertiesManager {
     }
     }
 
 
     private void attemptRegisterMaxBonusLevel(SubSkillType subSkillType, CommentedConfigurationNode childNode) {
     private void attemptRegisterMaxBonusLevel(SubSkillType subSkillType, CommentedConfigurationNode childNode) {
-        try {
-            pluginRef.getLogger().info("Registering MaxBonusLevel for "+subSkillType.toString());
-            MaxBonusLevel maxBonusLevel = childNode.getValue(TypeToken.of(MaxBonusLevel.class));
-            registerMaxBonusLevel(subSkillType, maxBonusLevel);
-        } catch (ObjectMappingException e) {
-            //This time a silent exception is fine
-        }
+        pluginRef.getLogger().info("Registering MaxBonusLevel for "+subSkillType.toString());
+        int maxBonusLevel = childNode.getInt();
+        registerMaxBonusLevel(subSkillType, maxBonusLevel);
     }
     }
 
 
     private void attemptRegisterMaxChance(SubSkillType subSkillType, CommentedConfigurationNode childNode) {
     private void attemptRegisterMaxChance(SubSkillType subSkillType, CommentedConfigurationNode childNode) {

+ 0 - 9
mcmmo-core/src/main/java/com/gmail/nossr50/database/FlatFileDatabaseManager.java

@@ -530,11 +530,6 @@ public final class FlatFileDatabaseManager implements DatabaseManager {
 
 
                 // Didn't find the player, create a new one
                 // Didn't find the player, create a new one
                 if (create) {
                 if (create) {
-                    if (uuid == null) {
-                        newUser(playerName, uuid);
-                        return new PlayerProfile(pluginRef, playerName, true);
-                    }
-
                     newUser(playerName, uuid);
                     newUser(playerName, uuid);
                     return new PlayerProfile(pluginRef, playerName, uuid, true);
                     return new PlayerProfile(pluginRef, playerName, uuid, true);
                 }
                 }
@@ -554,10 +549,6 @@ public final class FlatFileDatabaseManager implements DatabaseManager {
         }
         }
 
 
         // Return unloaded profile
         // Return unloaded profile
-        if (uuid == null) {
-            return new PlayerProfile(pluginRef, playerName);
-        }
-
         return new PlayerProfile(pluginRef, playerName, uuid);
         return new PlayerProfile(pluginRef, playerName, uuid);
     }
     }
 
 

+ 10 - 10
mcmmo-core/src/main/java/com/gmail/nossr50/database/SQLDatabaseManager.java

@@ -361,7 +361,7 @@ public final class SQLDatabaseManager implements DatabaseManager {
     public List<PlayerStat> readLeaderboard(PrimarySkillType skill, int pageNumber, int statsPerPage) {
     public List<PlayerStat> readLeaderboard(PrimarySkillType skill, int pageNumber, int statsPerPage) {
         List<PlayerStat> stats = new ArrayList<>();
         List<PlayerStat> stats = new ArrayList<>();
 
 
-        String query = skill == null ? ALL_QUERY_VERSION : skill.name().toLowerCase();
+        String query = skill == null ? ALL_QUERY_VERSION : skill.name().toLowerCase(Locale.ENGLISH);
         ResultSet resultSet = null;
         ResultSet resultSet = null;
         PreparedStatement statement = null;
         PreparedStatement statement = null;
         Connection connection = null;
         Connection connection = null;
@@ -403,9 +403,9 @@ public final class SQLDatabaseManager implements DatabaseManager {
         try {
         try {
             connection = getConnection(PoolIdentifier.MISC);
             connection = getConnection(PoolIdentifier.MISC);
             for (PrimarySkillType primarySkillType : pluginRef.getSkillTools().NON_CHILD_SKILLS) {
             for (PrimarySkillType primarySkillType : pluginRef.getSkillTools().NON_CHILD_SKILLS) {
-                String skillName = primarySkillType.name().toLowerCase();
+                String skillName = primarySkillType.name().toLowerCase(Locale.ENGLISH);
                 // Get count of all users with higher skill level than player
                 // Get count of all users with higher skill level than player
-                String sql = "SELECT COUNT(*) AS rank FROM " + tablePrefix + "users JOIN " + tablePrefix + "skills ON user_id = id WHERE " + skillName + " > 0 " +
+                String sql = "SELECT COUNT(*) AS 'rank' FROM " + tablePrefix + "users JOIN " + tablePrefix + "skills ON user_id = id WHERE " + skillName + " > 0 " +
                         "AND " + skillName + " > (SELECT " + skillName + " FROM " + tablePrefix + "users JOIN " + tablePrefix + "skills ON user_id = id " +
                         "AND " + skillName + " > (SELECT " + skillName + " FROM " + tablePrefix + "users JOIN " + tablePrefix + "skills ON user_id = id " +
                         "WHERE user = ?)";
                         "WHERE user = ?)";
 
 
@@ -439,7 +439,7 @@ public final class SQLDatabaseManager implements DatabaseManager {
                 statement.close();
                 statement.close();
             }
             }
 
 
-            String sql = "SELECT COUNT(*) AS rank FROM " + tablePrefix + "users JOIN " + tablePrefix + "skills ON user_id = id " +
+            String sql = "SELECT COUNT(*) AS 'rank' FROM " + tablePrefix + "users JOIN " + tablePrefix + "skills ON user_id = id " +
                     "WHERE " + ALL_QUERY_VERSION + " > 0 " +
                     "WHERE " + ALL_QUERY_VERSION + " > 0 " +
                     "AND " + ALL_QUERY_VERSION + " > " +
                     "AND " + ALL_QUERY_VERSION + " > " +
                     "(SELECT " + ALL_QUERY_VERSION + " " +
                     "(SELECT " + ALL_QUERY_VERSION + " " +
@@ -564,10 +564,10 @@ public final class SQLDatabaseManager implements DatabaseManager {
                     id = newUser(connection, playerName, uuid);
                     id = newUser(connection, playerName, uuid);
                     create = false;
                     create = false;
                     if (id == -1) {
                     if (id == -1) {
-                        return new PlayerProfile(pluginRef, playerName, false);
+                        return new PlayerProfile(pluginRef, playerName, uuid, false);
                     }
                     }
                 } else {
                 } else {
-                    return new PlayerProfile(pluginRef, playerName, false);
+                    return new PlayerProfile(pluginRef, playerName, uuid,false);
                 }
                 }
             }
             }
             // There is such a user
             // There is such a user
@@ -634,7 +634,7 @@ public final class SQLDatabaseManager implements DatabaseManager {
 
 
         // return unloaded profile
         // return unloaded profile
         if (!retry) {
         if (!retry) {
-            return new PlayerProfile(pluginRef, playerName, false);
+            return new PlayerProfile(pluginRef, playerName, uuid, false);
         }
         }
 
 
         // Retry, and abort on re-failure
         // Retry, and abort on re-failure
@@ -914,7 +914,7 @@ public final class SQLDatabaseManager implements DatabaseManager {
 
 
                     //Shrink skills above the cap
                     //Shrink skills above the cap
                     int cap = pluginRef.getPlayerLevelingSettings().getSkillLevelCap(skill);
                     int cap = pluginRef.getPlayerLevelingSettings().getSkillLevelCap(skill);
-                    statement = connection.prepareStatement("UPDATE `" + tablePrefix + "skills` SET `" + skill.name().toLowerCase() + "` = " + cap + " WHERE `" + skill.name().toLowerCase() + "` > " + cap);
+                    statement = connection.prepareStatement("UPDATE `" + tablePrefix + "skills` SET `" + skill.name().toLowerCase(Locale.ENGLISH) + "` = " + cap + " WHERE `" + skill.name().toLowerCase(Locale.ENGLISH) + "` > " + cap);
                     statement.executeUpdate();
                     statement.executeUpdate();
                     tryClose(statement);
                     tryClose(statement);
                 }
                 }
@@ -951,7 +951,7 @@ public final class SQLDatabaseManager implements DatabaseManager {
                 break;
                 break;
         }
         }
         if (connection == null) {
         if (connection == null) {
-            throw new RuntimeException("getConnection() for " + identifier.name().toLowerCase() + " pool timed out.  Increase max connections settings.");
+            throw new RuntimeException("getConnection() for " + identifier.name().toLowerCase(Locale.ENGLISH) + " pool timed out.  Increase max connections settings.");
         }
         }
         return connection;
         return connection;
     }
     }
@@ -1249,7 +1249,7 @@ public final class SQLDatabaseManager implements DatabaseManager {
                 pluginRef.getLogger().info("Indexing tables, this may take a while on larger databases");
                 pluginRef.getLogger().info("Indexing tables, this may take a while on larger databases");
 
 
                 for (PrimarySkillType skill : pluginRef.getSkillTools().NON_CHILD_SKILLS) {
                 for (PrimarySkillType skill : pluginRef.getSkillTools().NON_CHILD_SKILLS) {
-                    String skill_name = skill.name().toLowerCase();
+                    String skill_name = skill.name().toLowerCase(Locale.ENGLISH);
 
 
                     try {
                     try {
                         statement.executeUpdate("ALTER TABLE `" + tablePrefix + "skills` ADD INDEX `idx_" + skill_name + "` (`" + skill_name + "`) USING BTREE");
                         statement.executeUpdate("ALTER TABLE `" + tablePrefix + "skills` ADD INDEX `idx_" + skill_name + "` (`" + skill_name + "`) USING BTREE");

+ 0 - 11
mcmmo-core/src/main/java/com/gmail/nossr50/datatypes/player/PlayerProfile.java

@@ -34,11 +34,6 @@ public class PlayerProfile {
     private HashMap<PrimarySkillType, Double> rollingSkillsXp = new HashMap<PrimarySkillType, Double>();
     private HashMap<PrimarySkillType, Double> rollingSkillsXp = new HashMap<PrimarySkillType, Double>();
     private final mcMMO pluginRef;
     private final mcMMO pluginRef;
 
 
-    @Deprecated
-    public PlayerProfile(mcMMO pluginRef, String playerName) {
-        this(pluginRef, playerName, null);
-    }
-
     public PlayerProfile(mcMMO pluginRef, String playerName, UUID uuid) {
     public PlayerProfile(mcMMO pluginRef, String playerName, UUID uuid) {
         this.pluginRef = pluginRef;
         this.pluginRef = pluginRef;
         this.uuid = uuid;
         this.uuid = uuid;
@@ -60,12 +55,6 @@ public class PlayerProfile {
         uniquePlayerData.put(UniqueDataType.CHIMAERA_WING_DATS, 0); //Chimaera wing
         uniquePlayerData.put(UniqueDataType.CHIMAERA_WING_DATS, 0); //Chimaera wing
     }
     }
 
 
-    @Deprecated
-    public PlayerProfile(mcMMO pluginRef, String playerName, boolean isLoaded) {
-        this(pluginRef, playerName);
-        this.loaded = isLoaded;
-    }
-
     public PlayerProfile(mcMMO pluginRef, String playerName, UUID uuid, boolean isLoaded) {
     public PlayerProfile(mcMMO pluginRef, String playerName, UUID uuid, boolean isLoaded) {
         this(pluginRef, playerName, uuid);
         this(pluginRef, playerName, uuid);
         this.loaded = isLoaded;
         this.loaded = isLoaded;

+ 3 - 1
mcmmo-core/src/main/java/com/gmail/nossr50/datatypes/skills/SubSkillType.java

@@ -4,6 +4,8 @@ import com.gmail.nossr50.config.HOCONUtil;
 import com.gmail.nossr50.mcMMO;
 import com.gmail.nossr50.mcMMO;
 import com.gmail.nossr50.util.StringUtils;
 import com.gmail.nossr50.util.StringUtils;
 
 
+import java.util.Locale;
+
 public enum SubSkillType {
 public enum SubSkillType {
     /* !! Warning -- Do not let subskills share a name with any existing PrimarySkillType as it will clash with the static import !! */
     /* !! Warning -- Do not let subskills share a name with any existing PrimarySkillType as it will clash with the static import !! */
 
 
@@ -142,7 +144,7 @@ public enum SubSkillType {
      */
      */
     public String getPermissionNodeAddress(mcMMO pluginRef) {
     public String getPermissionNodeAddress(mcMMO pluginRef) {
         //TODO: This could be optimized
         //TODO: This could be optimized
-        return "mcmmo.ability." + getParentSkill(pluginRef).toString().toLowerCase() + "." + getConfigName(toString()).toLowerCase();
+        return "mcmmo.ability." + getParentSkill(pluginRef).toString().toLowerCase(Locale.ENGLISH) + "." + getConfigName(toString()).toLowerCase(Locale.ENGLISH);
     }
     }
 
 
     /**
     /**

+ 2 - 2
mcmmo-core/src/main/java/com/gmail/nossr50/datatypes/skills/behaviours/ArcheryBehaviour.java

@@ -48,11 +48,11 @@ public class ArcheryBehaviour {
     public double getSkillShotBonusDamage(Player player, double oldDamage) {
     public double getSkillShotBonusDamage(Player player, double oldDamage) {
         double damageBonusPercent = getSkillShotDamageBonusPercent(player);
         double damageBonusPercent = getSkillShotDamageBonusPercent(player);
         double newDamage = oldDamage + (oldDamage * damageBonusPercent);
         double newDamage = oldDamage + (oldDamage * damageBonusPercent);
-        return Math.min(newDamage, getSkillShotDamageCap());
+        return Math.min(newDamage, (oldDamage + getSkillShotDamageCap()));
     }
     }
 
 
     public double getSkillShotDamageBonusPercent(Player player) {
     public double getSkillShotDamageBonusPercent(Player player) {
-        return ((pluginRef.getRankTools().getRank(player, SubSkillType.ARCHERY_SKILL_SHOT)) * pluginRef.getConfigManager().getConfigArchery().getSkillShotDamageMultiplier()) / 100.0D;
+        return ((pluginRef.getRankTools().getRank(player, SubSkillType.ARCHERY_SKILL_SHOT)) * (pluginRef.getConfigManager().getConfigArchery().getSkillShotDamageMultiplier()) / 100.0D);
     }
     }
 
 
     public double getSkillShotDamageCap() {
     public double getSkillShotDamageCap() {

+ 0 - 35
mcmmo-core/src/main/java/com/gmail/nossr50/datatypes/skills/properties/AbstractMaxBonusLevel.java

@@ -1,35 +0,0 @@
-package com.gmail.nossr50.datatypes.skills.properties;
-
-public class AbstractMaxBonusLevel implements MaxBonusLevel {
-
-    private int retro;
-    private int standard;
-
-    public AbstractMaxBonusLevel(int standard, int retro) {
-        this.standard = standard;
-        this.retro = retro;
-    }
-
-    public AbstractMaxBonusLevel(int standard) {
-        this.standard = standard;
-        this.retro = standard * 10;
-    }
-
-    @Override
-    public int getRetroScaleValue() {
-        return retro;
-    }
-
-    @Override
-    public int getStandardScaleValue() {
-        return standard;
-    }
-
-    public void setRetro(int retro) {
-        this.retro = retro;
-    }
-
-    public void setStandard(int standard) {
-        this.standard = standard;
-    }
-}

+ 0 - 19
mcmmo-core/src/main/java/com/gmail/nossr50/datatypes/skills/properties/AbstractScalingProperty.java

@@ -1,19 +0,0 @@
-package com.gmail.nossr50.datatypes.skills.properties;
-
-import com.gmail.nossr50.datatypes.skills.SubSkillType;
-
-public abstract class AbstractScalingProperty implements ScalingProperty {
-    public SubSkillType subSkillType;
-
-    public AbstractScalingProperty(SubSkillType subSkillType) {
-        super();
-        this.subSkillType = subSkillType;
-    }
-
-    @Override
-    public String toString() {
-        return "AbstractScalingProperty{" +
-                "subSkillType=" + subSkillType +
-                '}';
-    }
-}

+ 0 - 17
mcmmo-core/src/main/java/com/gmail/nossr50/datatypes/skills/properties/MaxBonusLevel.java

@@ -1,17 +0,0 @@
-package com.gmail.nossr50.datatypes.skills.properties;
-
-public interface MaxBonusLevel {
-
-    /**
-     * Get the max level for this skill for Retro scaling
-     * @return Retro Mode max bonus level
-     */
-    int getRetroScaleValue();
-
-    /**
-     * Get the max level for this skill for Standard scaling
-     * @return Standard Mode max bonus level
-     */
-    int getStandardScaleValue();
-
-}

+ 0 - 10
mcmmo-core/src/main/java/com/gmail/nossr50/datatypes/skills/properties/ScalingProperty.java

@@ -1,10 +0,0 @@
-package com.gmail.nossr50.datatypes.skills.properties;
-
-public interface ScalingProperty extends SkillProperty {
-    /**
-     * Returns the appropriate value for this scaling property whether it is Standard or Retro
-     *
-     * @return the value used in scaling calculations for this ScalingProperty
-     */
-    double getValue();
-}

+ 4 - 2
mcmmo-core/src/main/java/com/gmail/nossr50/datatypes/skills/subskills/acrobatics/Roll.java

@@ -20,6 +20,8 @@ import org.bukkit.event.EventPriority;
 import org.bukkit.event.entity.EntityDamageEvent;
 import org.bukkit.event.entity.EntityDamageEvent;
 import org.bukkit.inventory.ItemStack;
 import org.bukkit.inventory.ItemStack;
 
 
+import java.util.Locale;
+
 public class Roll extends AcrobaticsSubSkill {
 public class Roll extends AcrobaticsSubSkill {
 
 
     private final mcMMO pluginRef;
     private final mcMMO pluginRef;
@@ -95,7 +97,7 @@ public class Roll extends AcrobaticsSubSkill {
      */
      */
     @Override
     @Override
     public String getPermissionNode() {
     public String getPermissionNode() {
-        return ("mcmmo.ability." + getPrimaryKeyName() + "." + getConfigKeyName()).toLowerCase();
+        return ("mcmmo.ability." + getPrimaryKeyName() + "." + getConfigKeyName()).toLowerCase(Locale.ENGLISH);
     }
     }
 
 
     /**
     /**
@@ -370,7 +372,7 @@ public class Roll extends AcrobaticsSubSkill {
 
 
         //Chance to roll at half max skill
         //Chance to roll at half max skill
         RandomChanceSkill rollHalfMaxSkill = new RandomChanceSkill(pluginRef, null, subSkillType);
         RandomChanceSkill rollHalfMaxSkill = new RandomChanceSkill(pluginRef, null, subSkillType);
-        int halfMaxSkillValue = pluginRef.isRetroModeEnabled() ? 500 : 50;
+        int halfMaxSkillValue = (int) pluginRef.getDynamicSettingsManager().getSkillMaxBonusLevel(subSkillType) / 2;
         rollHalfMaxSkill.setSkillLevel(halfMaxSkillValue);
         rollHalfMaxSkill.setSkillLevel(halfMaxSkillValue);
 
 
         //Chance to graceful roll at full skill
         //Chance to graceful roll at full skill

+ 1 - 1
mcmmo-core/src/main/java/com/gmail/nossr50/dumpster/PotionGenerator.java

@@ -253,7 +253,7 @@
 //        if (target.equals("II")) { // hacks
 //        if (target.equals("II")) { // hacks
 //            return target;
 //            return target;
 //        }
 //        }
-//        return target.substring(0, 1).toUpperCase() + target.substring(1).toLowerCase();
+//        return target.substring(0, 1).toUpperCase() + target.substring(1).toLowerCase(Locale.ENGLISH);
 //    }
 //    }
 //
 //
 //    private static String getName(PotionEffectType type) {
 //    private static String getName(PotionEffectType type) {

+ 84 - 16
mcmmo-core/src/main/java/com/gmail/nossr50/listeners/BlockListener.java

@@ -31,6 +31,7 @@ import org.bukkit.event.block.*;
 import org.bukkit.inventory.ItemStack;
 import org.bukkit.inventory.ItemStack;
 import org.bukkit.metadata.MetadataValue;
 import org.bukkit.metadata.MetadataValue;
 
 
+import java.util.HashSet;
 import java.util.List;
 import java.util.List;
 
 
 public class BlockListener implements Listener {
 public class BlockListener implements Listener {
@@ -42,21 +43,51 @@ public class BlockListener implements Listener {
 
 
     @EventHandler(priority = EventPriority.HIGHEST, ignoreCancelled = true)
     @EventHandler(priority = EventPriority.HIGHEST, ignoreCancelled = true)
     public void onBlockDropItemEvent(BlockDropItemEvent event) {
     public void onBlockDropItemEvent(BlockDropItemEvent event) {
-        for (Item item : event.getItems()) {
-            ItemStack is = new ItemStack(item.getItemStack());
+        //Track how many "things" are being dropped
+        HashSet<Material> uniqueMaterials = new HashSet<>();
+        boolean dontRewardTE = false; //If we suspect TEs are mixed in with other things don't reward bonus drops for anything that isn't a block
+        int blockCount = 0;
 
 
-            if (is.getAmount() <= 0)
-                continue;
+        for(Item item : event.getItems()) {
+            //Track unique materials
+            uniqueMaterials.add(item.getItemStack().getType());
 
 
-            if (!pluginRef.getDynamicSettingsManager().getBonusDropManager().isBonusDropWhitelisted(is.getType()))
-                continue;
+            //Count blocks as a second failsafe
+            if(item.getItemStack().getType().isBlock())
+                blockCount++;
+        }
+
+        if(uniqueMaterials.size() > 1) {
+            //Too many things are dropping, assume tile entities might be duped
+            //Technically this would also prevent something like coal from being bonus dropped if you placed a TE above a coal ore when mining it but that's pretty edge case and this is a good solution for now
+            dontRewardTE = true;
+        }
+
+        //If there are more than one block in the item list we can't really trust it and will back out of rewarding bonus drops
+        if (blockCount <= 1){
+            for (Item item : event.getItems()) {
+                ItemStack is = new ItemStack(item.getItemStack());
+
+                if (is.getAmount() <= 0)
+                    continue;
 
 
-            if (event.getBlock().getMetadata(MetadataConstants.BONUS_DROPS_METAKEY).size() > 0) {
-                BonusDropMeta bonusDropMeta = (BonusDropMeta) event.getBlock().getMetadata(MetadataConstants.BONUS_DROPS_METAKEY).get(0);
-                int bonusCount = bonusDropMeta.asInt();
+                if (!pluginRef.getDynamicSettingsManager().getBonusDropManager().isBonusDropWhitelisted(is.getType()))
+                    continue;
 
 
-                for (int i = 0; i < bonusCount; i++) {
-                    event.getBlock().getWorld().dropItemNaturally(event.getBlockState().getLocation(), is);
+                //If we suspect TEs might be duped only reward block
+                if (dontRewardTE) {
+                    if (!is.getType().isBlock()) {
+                        continue;
+                    }
+                }
+
+                if (event.getBlock().getMetadata(MetadataConstants.BONUS_DROPS_METAKEY).size() > 0) {
+                    BonusDropMeta bonusDropMeta = (BonusDropMeta) event.getBlock().getMetadata(MetadataConstants.BONUS_DROPS_METAKEY).get(0);
+                    int bonusCount = bonusDropMeta.asInt();
+
+                    for (int i = 0; i < bonusCount; i++) {
+                        event.getBlock().getWorld().dropItemNaturally(event.getBlockState().getLocation(), is);
+                    }
                 }
                 }
             }
             }
         }
         }
@@ -129,7 +160,7 @@ public class BlockListener implements Listener {
         if (pluginRef.getDynamicSettingsManager().isWorldBlacklisted(event.getBlock().getWorld().getName()))
         if (pluginRef.getDynamicSettingsManager().isWorldBlacklisted(event.getBlock().getWorld().getName()))
             return;
             return;
 
 
-        if (pluginRef.getBlockTools().shouldBeWatched(event.getNewState())) {
+        if (pluginRef.getConfigManager().getConfigExploitPrevention().isSnowGolemExploitPrevented() && pluginRef.getBlockTools().shouldBeWatched(event.getNewState())) {
             pluginRef.getPlaceStore().setTrue(event.getNewState().getBlock());
             pluginRef.getPlaceStore().setTrue(event.getNewState().getBlock());
         }
         }
     }
     }
@@ -450,8 +481,27 @@ public class BlockListener implements Listener {
                 mcMMOPlayer.checkAbilityActivation(PrimarySkillType.MINING);
                 mcMMOPlayer.checkAbilityActivation(PrimarySkillType.MINING);
             } else if (mcMMOPlayer.getToolPreparationMode(ToolType.SHOVEL) && pluginRef.getItemTools().isShovel(heldItem) && pluginRef.getBlockTools().affectedByGigaDrillBreaker(blockState) && pluginRef.getPermissionTools().gigaDrillBreaker(player)) {
             } else if (mcMMOPlayer.getToolPreparationMode(ToolType.SHOVEL) && pluginRef.getItemTools().isShovel(heldItem) && pluginRef.getBlockTools().affectedByGigaDrillBreaker(blockState) && pluginRef.getPermissionTools().gigaDrillBreaker(player)) {
                 mcMMOPlayer.checkAbilityActivation(PrimarySkillType.EXCAVATION);
                 mcMMOPlayer.checkAbilityActivation(PrimarySkillType.EXCAVATION);
-            } else if (mcMMOPlayer.getToolPreparationMode(ToolType.FISTS) && heldItem.getType() == Material.AIR && (pluginRef.getBlockTools().affectedByGigaDrillBreaker(blockState) || blockState.getType() == Material.SNOW || pluginRef.getBlockTools().affectedByBlockCracker(blockState) && pluginRef.getPermissionTools().berserk(player))) {
+            } else if (mcMMOPlayer.getToolPreparationMode(ToolType.FISTS)
+                    && heldItem.getType() == Material.AIR
+                    && ((pluginRef.getBlockTools().affectedByGigaDrillBreaker(blockState)
+                        || blockState.getType() == Material.SNOW
+                        || pluginRef.getBlockTools().affectedByBlockCracker(blockState)
+                        || pluginRef.getMaterialMapStore().isGlass(blockState.getType()))
+                    && pluginRef.getPermissionTools().berserk(player))) {
                 mcMMOPlayer.checkAbilityActivation(PrimarySkillType.UNARMED);
                 mcMMOPlayer.checkAbilityActivation(PrimarySkillType.UNARMED);
+
+                if(mcMMOPlayer.getSuperAbilityMode(SuperAbilityType.BERSERK)) {
+                    if (pluginRef.getSkillTools().superAbilityBlockCheck(SuperAbilityType.BERSERK, blockState)
+                            && pluginRef.getEventManager().simulateBlockBreak(blockState.getBlock(), player, true)) {
+                        event.setInstaBreak(true);
+
+                        if(blockState.getType().getKey().getKey().contains("glass")) {
+                            pluginRef.getSoundManager().worldSendSound(player.getWorld(), blockState.getLocation(), SoundType.GLASS);
+                        } else {
+                            pluginRef.getSoundManager().sendSound(player, blockState.getLocation(), SoundType.POP);
+                        }
+                    }
+                }
             }
             }
         }
         }
 
 
@@ -520,17 +570,35 @@ public class BlockListener implements Listener {
             if (mcMMOPlayer.getHerbalismManager().processGreenTerraBlockConversion(blockState)) {
             if (mcMMOPlayer.getHerbalismManager().processGreenTerraBlockConversion(blockState)) {
                 blockState.update(true);
                 blockState.update(true);
             }
             }
-        } else if (mcMMOPlayer.getSuperAbilityMode(SuperAbilityType.BERSERK) && heldItem.getType() == Material.AIR) {
+        } else if (mcMMOPlayer.getSuperAbilityMode(SuperAbilityType.BERSERK) && (heldItem.getType() == Material.AIR || pluginRef.getConfigManager().getConfigUnarmed().doItemsCountAsUnarmed())) {
             if (pluginRef.getSkillTools().superAbilityBlockCheck(SuperAbilityType.BERSERK, block.getState())
             if (pluginRef.getSkillTools().superAbilityBlockCheck(SuperAbilityType.BERSERK, block.getState())
                     && pluginRef.getEventManager().simulateBlockBreak(block, player, true)) {
                     && pluginRef.getEventManager().simulateBlockBreak(block, player, true)) {
                 event.setInstaBreak(true);
                 event.setInstaBreak(true);
                 pluginRef.getSoundManager().sendSound(player, block.getLocation(), SoundType.POP);
                 pluginRef.getSoundManager().sendSound(player, block.getLocation(), SoundType.POP);
-            } else if (mcMMOPlayer.getUnarmedManager().canUseBlockCracker() && pluginRef.getBlockTools().affectedByBlockCracker(blockState) && pluginRef.getEventManager().simulateBlockBreak(block, player, true)) {
+            } else if (mcMMOPlayer.getUnarmedManager().canUseBlockCracker()
+                    && pluginRef.getBlockTools().affectedByBlockCracker(blockState)
+                    && pluginRef.getEventManager().simulateBlockBreak(block, player, true)) {
                 if (mcMMOPlayer.getUnarmedManager().blockCrackerCheck(blockState)) {
                 if (mcMMOPlayer.getUnarmedManager().blockCrackerCheck(blockState)) {
                     blockState.update();
                     blockState.update();
                 }
                 }
             }
             }
-        } else if (mcMMOPlayer.getWoodcuttingManager().canUseLeafBlower(heldItem) && pluginRef.getBlockTools().isLeaves(blockState) && pluginRef.getEventManager().simulateBlockBreak(block, player, true)) {
+            //Only run if insta-break isn't on, this is because we turn it on in another event of this same type but different priority under certain conditions
+            else if (!event.getInstaBreak()
+                    && pluginRef.getBlockTools().canActivateAbilities(blockState)
+                    && pluginRef.getEventManager().simulateBlockBreak(block, player, true)) {
+                event.setInstaBreak(true);
+
+                //Break Glass
+                if(blockState.getType().getKey().getKey().contains("glass")) {
+                    pluginRef.getSoundManager().worldSendSound(player.getWorld(), block.getLocation(), SoundType.GLASS);
+                } else {
+                    pluginRef.getSoundManager().sendSound(player, block.getLocation(), SoundType.POP);
+                }
+            }
+        }
+        else if (mcMMOPlayer.getWoodcuttingManager().canUseLeafBlower(heldItem)
+                && pluginRef.getBlockTools().isLeaves(blockState)
+                && pluginRef.getEventManager().simulateBlockBreak(block, player, true)) {
             event.setInstaBreak(true);
             event.setInstaBreak(true);
             pluginRef.getSoundManager().sendSound(player, block.getLocation(), SoundType.POP);
             pluginRef.getSoundManager().sendSound(player, block.getLocation(), SoundType.POP);
         }
         }

+ 5 - 21
mcmmo-core/src/main/java/com/gmail/nossr50/listeners/EntityListener.java

@@ -60,7 +60,7 @@ public class EntityListener implements Listener {
 
 
         //Prevent entities from giving XP if they target endermite
         //Prevent entities from giving XP if they target endermite
         if (event.getTarget() instanceof Endermite) {
         if (event.getTarget() instanceof Endermite) {
-            if (event.getEntity().hasMetadata(MetadataConstants.UNNATURAL_MOB_METAKEY))
+            if (!event.getEntity().hasMetadata(MetadataConstants.UNNATURAL_MOB_METAKEY))
                 event.getEntity().setMetadata(MetadataConstants.UNNATURAL_MOB_METAKEY, MetadataConstants.metadataValue);
                 event.getEntity().setMetadata(MetadataConstants.UNNATURAL_MOB_METAKEY, MetadataConstants.metadataValue);
         }
         }
     }
     }
@@ -291,6 +291,10 @@ public class EntityListener implements Listener {
             return;
             return;
         }
         }
 
 
+        if (pluginRef.getCombatTools().isProcessingNoInvulnDamage()) {
+            return;
+        }
+
         if (event.getEntity() instanceof ArmorStand) {
         if (event.getEntity() instanceof ArmorStand) {
             return;
             return;
         }
         }
@@ -789,26 +793,6 @@ public class EntityListener implements Listener {
         }
         }
     }
     }
 
 
-    /**
-     * Handle EntityExplode events that involve modifying the event.
-     *
-     * @param event The event to modify
-     */
-    @EventHandler(priority = EventPriority.LOWEST, ignoreCancelled = true)
-    public void onEntityExplodeMonitor(EntityExplodeEvent event) {
-        /* WORLD BLACKLIST CHECK */
-        if (pluginRef.getDynamicSettingsManager().isWorldBlacklisted(event.getEntity().getWorld().getName()))
-            return;
-
-        Entity entity = event.getEntity();
-
-        if (!(entity instanceof TNTPrimed) || !entity.hasMetadata(MetadataConstants.SAFE_TNT_METAKEY)) {
-            return;
-        }
-
-        event.blockList().clear();
-    }
-
     /**
     /**
      * Handle FoodLevelChange events that involve modifying the event.
      * Handle FoodLevelChange events that involve modifying the event.
      *
      *

+ 3 - 2
mcmmo-core/src/main/java/com/gmail/nossr50/listeners/InteractionManager.java

@@ -9,6 +9,7 @@ import org.bukkit.event.Event;
 
 
 import java.util.ArrayList;
 import java.util.ArrayList;
 import java.util.HashMap;
 import java.util.HashMap;
+import java.util.Locale;
 
 
 public class InteractionManager {
 public class InteractionManager {
     private static HashMap<InteractType, ArrayList<Interaction>> interactRegister;
     private static HashMap<InteractType, ArrayList<Interaction>> interactRegister;
@@ -46,7 +47,7 @@ public class InteractionManager {
         //Register skill
         //Register skill
         arrayRef.add(abstractSubSkill);
         arrayRef.add(abstractSubSkill);
 
 
-        String lowerCaseName = abstractSubSkill.getConfigKeyName().toLowerCase();
+        String lowerCaseName = abstractSubSkill.getConfigKeyName().toLowerCase(Locale.ENGLISH);
 
 
         //Register in name map
         //Register in name map
         subSkillNameMap.putIfAbsent(lowerCaseName, abstractSubSkill);
         subSkillNameMap.putIfAbsent(lowerCaseName, abstractSubSkill);
@@ -62,7 +63,7 @@ public class InteractionManager {
      * @return null if the subskill is not registered
      * @return null if the subskill is not registered
      */
      */
     public static AbstractSubSkill getAbstractByName(String name) {
     public static AbstractSubSkill getAbstractByName(String name) {
-        return subSkillNameMap.get(name.toLowerCase());
+        return subSkillNameMap.get(name.toLowerCase(Locale.ENGLISH));
     }
     }
 
 
     /**
     /**

+ 5 - 3
mcmmo-core/src/main/java/com/gmail/nossr50/listeners/PlayerListener.java

@@ -34,6 +34,8 @@ import org.bukkit.event.player.*;
 import org.bukkit.inventory.EquipmentSlot;
 import org.bukkit.inventory.EquipmentSlot;
 import org.bukkit.inventory.ItemStack;
 import org.bukkit.inventory.ItemStack;
 
 
+import java.util.Locale;
+
 public class PlayerListener implements Listener {
 public class PlayerListener implements Listener {
     private final mcMMO pluginRef;
     private final mcMMO pluginRef;
 
 
@@ -880,12 +882,12 @@ public class PlayerListener implements Listener {
         if (!pluginRef.getConfigManager().getConfigLanguage().getTargetLanguage().equalsIgnoreCase("en_US")) {
         if (!pluginRef.getConfigManager().getConfigLanguage().getTargetLanguage().equalsIgnoreCase("en_US")) {
             String message = event.getMessage();
             String message = event.getMessage();
             String command = message.substring(1).split(" ")[0];
             String command = message.substring(1).split(" ")[0];
-            String lowerCaseCommand = command.toLowerCase();
+            String lowerCaseCommand = command.toLowerCase(Locale.ENGLISH);
 
 
             // Do these ACTUALLY have to be lower case to work properly?
             // Do these ACTUALLY have to be lower case to work properly?
             for (PrimarySkillType primarySkillType : PrimarySkillType.values()) {
             for (PrimarySkillType primarySkillType : PrimarySkillType.values()) {
-                String skillName = primarySkillType.toString().toLowerCase();
-                String localizedName = pluginRef.getSkillTools().getLocalizedSkillName(primarySkillType).toLowerCase();
+                String skillName = primarySkillType.toString().toLowerCase(Locale.ENGLISH);
+                String localizedName = pluginRef.getSkillTools().getLocalizedSkillName(primarySkillType).toLowerCase(Locale.ENGLISH);
 
 
                 if (command.equalsIgnoreCase(localizedName)) {
                 if (command.equalsIgnoreCase(localizedName)) {
                     event.setMessage(message.replace(command, skillName));
                     event.setMessage(message.replace(command, skillName));

+ 15 - 18
mcmmo-core/src/main/java/com/gmail/nossr50/mcMMO.java

@@ -67,6 +67,7 @@ import java.io.File;
 import java.io.IOException;
 import java.io.IOException;
 import java.util.ArrayList;
 import java.util.ArrayList;
 import java.util.List;
 import java.util.List;
+import java.util.Locale;
 
 
 public class mcMMO extends JavaPlugin {
 public class mcMMO extends JavaPlugin {
     /* Managers */
     /* Managers */
@@ -88,6 +89,7 @@ public class mcMMO extends JavaPlugin {
     private SoundManager soundManager;
     private SoundManager soundManager;
     private HardcoreManager hardcoreManager;
     private HardcoreManager hardcoreManager;
     private PlatformManager platformManager;
     private PlatformManager platformManager;
+    private WorldGuardManager worldGuardManager;
 
 
     /* Not-Managers but my naming scheme sucks */
     /* Not-Managers but my naming scheme sucks */
     private DatabaseManagerFactory databaseManagerFactory;
     private DatabaseManagerFactory databaseManagerFactory;
@@ -241,10 +243,14 @@ public class mcMMO extends JavaPlugin {
                 metrics = new Metrics(this);
                 metrics = new Metrics(this);
                 metrics.addCustomChart(new Metrics.SimplePie("version", () -> getDescription().getVersion()));
                 metrics.addCustomChart(new Metrics.SimplePie("version", () -> getDescription().getVersion()));
 
 
-                if (!configManager.getConfigLeveling().getConfigSectionLevelingGeneral().getConfigSectionLevelScaling().isRetroModeEnabled())
+                int levelScaleModifier = configManager.getConfigLeveling().getConfigSectionLevelingGeneral().getConfigSectionLevelScaling().getCosmeticLevelScaleModifier();
+
+                if (levelScaleModifier == 10)
                     metrics.addCustomChart(new Metrics.SimplePie("scaling", () -> "Standard"));
                     metrics.addCustomChart(new Metrics.SimplePie("scaling", () -> "Standard"));
-                else
+                else if (levelScaleModifier == 1)
                     metrics.addCustomChart(new Metrics.SimplePie("scaling", () -> "Retro"));
                     metrics.addCustomChart(new Metrics.SimplePie("scaling", () -> "Retro"));
+                else
+                    metrics.addCustomChart(new Metrics.SimplePie("scaling", () -> "Custom"));
             }
             }
         } catch (Throwable t) {
         } catch (Throwable t) {
             getLogger().severe("There was an error while enabling mcMMO!");
             getLogger().severe("There was an error while enabling mcMMO!");
@@ -308,13 +314,15 @@ public class mcMMO extends JavaPlugin {
     @Override
     @Override
     public void onLoad()
     public void onLoad()
     {
     {
+        worldGuardUtils = new WorldGuardUtils(this); //Init WGU
+
         if(getServer().getPluginManager().getPlugin("WorldGuard") != null) {
         if(getServer().getPluginManager().getPlugin("WorldGuard") != null) {
-            worldGuardUtils = new WorldGuardUtils(); //Init WGU
 
 
             if(worldGuardUtils.isWorldGuardLoaded()) {
             if(worldGuardUtils.isWorldGuardLoaded()) {
                 //Register flags
                 //Register flags
                 System.out.println("[mcMMO - Registering World Guard Flags...]");
                 System.out.println("[mcMMO - Registering World Guard Flags...]");
-                worldGuardUtils.getWorldGuardManager().registerFlags();
+                worldGuardManager = new WorldGuardManager();
+                worldGuardManager.registerFlags();
             }
             }
         }
         }
     }
     }
@@ -384,9 +392,9 @@ public class mcMMO extends JavaPlugin {
      * @return the ServerSoftwareType which likely matches the server
      * @return the ServerSoftwareType which likely matches the server
      */
      */
     private ServerSoftwareType getServerSoftware() {
     private ServerSoftwareType getServerSoftware() {
-        if (Bukkit.getVersion().toLowerCase().contains("paper"))
+        if (Bukkit.getVersion().toLowerCase(Locale.ENGLISH).contains("paper"))
             return ServerSoftwareType.PAPER;
             return ServerSoftwareType.PAPER;
-        else if (Bukkit.getVersion().toLowerCase().contains("spigot"))
+        else if (Bukkit.getVersion().toLowerCase(Locale.ENGLISH).contains("spigot"))
             return ServerSoftwareType.SPIGOT;
             return ServerSoftwareType.SPIGOT;
         else
         else
             return ServerSoftwareType.CRAFTBUKKIT;
             return ServerSoftwareType.CRAFTBUKKIT;
@@ -515,17 +523,6 @@ public class mcMMO extends JavaPlugin {
         return healthBarPluginEnabled;
         return healthBarPluginEnabled;
     }
     }
 
 
-    /**
-     * Checks if this plugin is using retro mode
-     * Retro mode is a 0-1000 skill system
-     * Standard mode is scaled for 1-100
-     *
-     * @return true if retro mode is enabled
-     */
-    public boolean isRetroModeEnabled() {
-        return configManager.isRetroMode();
-    }
-
     public ConfigManager getConfigManager() {
     public ConfigManager getConfigManager() {
         return configManager;
         return configManager;
     }
     }
@@ -761,7 +758,7 @@ public class mcMMO extends JavaPlugin {
     }
     }
 
 
     public WorldGuardManager getWorldGuardManager() {
     public WorldGuardManager getWorldGuardManager() {
-        return worldGuardUtils.getWorldGuardManager();
+        return worldGuardManager;
     }
     }
 
 
     public PartyManager getPartyManager() {
     public PartyManager getPartyManager() {

+ 7 - 11
mcmmo-core/src/main/java/com/gmail/nossr50/runnables/MobHealthDisplayUpdaterTask.java

@@ -8,25 +8,21 @@ import org.bukkit.scheduler.BukkitRunnable;
 public class MobHealthDisplayUpdaterTask extends BukkitRunnable {
 public class MobHealthDisplayUpdaterTask extends BukkitRunnable {
     private final mcMMO pluginRef;
     private final mcMMO pluginRef;
     private LivingEntity target;
     private LivingEntity target;
-    private String oldName;
-    private boolean oldNameVisible;
 
 
     public MobHealthDisplayUpdaterTask(mcMMO pluginRef, LivingEntity target) {
     public MobHealthDisplayUpdaterTask(mcMMO pluginRef, LivingEntity target) {
         this.pluginRef = pluginRef;
         this.pluginRef = pluginRef;
-
-        if (target.isValid()) {
-            this.target = target;
-            this.oldName = target.getMetadata(MetadataConstants.CUSTOM_NAME_METAKEY).get(0).asString();
-            this.oldNameVisible = target.getMetadata(MetadataConstants.NAME_VISIBILITY_METAKEY).get(0).asBoolean();
-        }
+        this.target = target;
     }
     }
 
 
     @Override
     @Override
     public void run() {
     public void run() {
-        if (target != null && target.isValid()) {
-            target.setCustomNameVisible(oldNameVisible);
-            target.setCustomName(oldName);
+        if (target.hasMetadata(MetadataConstants.CUSTOM_NAME_METAKEY)) {
+            target.setCustomName(target.getMetadata(MetadataConstants.CUSTOM_NAME_METAKEY).get(0).asString());
             target.removeMetadata(MetadataConstants.CUSTOM_NAME_METAKEY, pluginRef);
             target.removeMetadata(MetadataConstants.CUSTOM_NAME_METAKEY, pluginRef);
+        }
+
+        if (target.hasMetadata(MetadataConstants.NAME_VISIBILITY_METAKEY)) {
+            target.setCustomNameVisible(target.getMetadata(MetadataConstants.NAME_VISIBILITY_METAKEY).get(0).asBoolean());
             target.removeMetadata(MetadataConstants.NAME_VISIBILITY_METAKEY, pluginRef);
             target.removeMetadata(MetadataConstants.NAME_VISIBILITY_METAKEY, pluginRef);
         }
         }
     }
     }

+ 18 - 0
mcmmo-core/src/main/java/com/gmail/nossr50/runnables/items/TeleportationWarmup.java

@@ -3,6 +3,7 @@ package com.gmail.nossr50.runnables.items;
 import com.gmail.nossr50.datatypes.player.McMMOPlayer;
 import com.gmail.nossr50.datatypes.player.McMMOPlayer;
 import com.gmail.nossr50.mcMMO;
 import com.gmail.nossr50.mcMMO;
 import org.bukkit.Location;
 import org.bukkit.Location;
+import org.bukkit.World;
 import org.bukkit.entity.Player;
 import org.bukkit.entity.Player;
 import org.bukkit.scheduler.BukkitRunnable;
 import org.bukkit.scheduler.BukkitRunnable;
 
 
@@ -48,6 +49,23 @@ public class TeleportationWarmup extends BukkitRunnable {
             }
             }
         }
         }
 
 
+        if (pluginRef.getConfigManager().getConfigParty().getPTP().isPtpWorldBasedPermissions()) {
+            World targetWorld = targetPlayer.getWorld();
+            World playerWorld = teleportingPlayer.getWorld();
+
+            if (!pluginRef.getPermissionTools().partyTeleportAllWorlds(teleportingPlayer)) {
+                if (!pluginRef.getPermissionTools().partyTeleportWorld(targetPlayer, targetWorld)) {
+                    teleportingPlayer.sendMessage(pluginRef.getLocaleManager().formatString("Commands.ptp.NoWorldPermissions", targetWorld.getName()));
+                    return;
+                }
+                else if (targetWorld != playerWorld && !pluginRef.getPermissionTools().partyTeleportWorld(teleportingPlayer, targetWorld)) {
+                    teleportingPlayer.sendMessage(pluginRef.getLocaleManager().formatString("Commands.ptp.NoWorldPermissions", targetWorld.getName()));
+                    return;
+                }
+            }
+        }
+
+
         pluginRef.getEventManager().handlePartyTeleportEvent(teleportingPlayer, targetPlayer);
         pluginRef.getEventManager().handlePartyTeleportEvent(teleportingPlayer, targetPlayer);
     }
     }
 }
 }

+ 2 - 1
mcmmo-core/src/main/java/com/gmail/nossr50/skills/mining/MiningManager.java

@@ -155,7 +155,8 @@ public class MiningManager extends SkillManager {
 
 
             if (pluginRef.getBlockTools().isOre(blockState)) {
             if (pluginRef.getBlockTools().isOre(blockState)) {
                 ores.add(blockState);
                 ores.add(blockState);
-            } else {
+            //A bug where beacons can drop when yield is set to 0 on explosion events is prevented here
+            } else if(blockState.getType() != Material.BEACON) {
                 debris.add(blockState);
                 debris.add(blockState);
             }
             }
         }
         }

+ 1 - 0
mcmmo-core/src/main/java/com/gmail/nossr50/skills/unarmed/UnarmedManager.java

@@ -80,6 +80,7 @@ public class UnarmedManager extends SkillManager {
 
 
         switch (blockState.getType()) {
         switch (blockState.getType()) {
             case STONE_BRICKS:
             case STONE_BRICKS:
+                // TODO: REREF? https://github.com/mcMMO-Dev/mcMMO/blame/421a394f68fc714899f167dc3faf53114b8469ce/src/main/java/com/gmail/nossr50/skills/unarmed/UnarmedManager.java#L95
                 /*if (!Unarmed.blockCrackerSmoothBrick) {
                 /*if (!Unarmed.blockCrackerSmoothBrick) {
                     return false;
                     return false;
                 }*/
                 }*/

+ 2 - 1
mcmmo-core/src/main/java/com/gmail/nossr50/util/MiscTools.java

@@ -12,6 +12,7 @@ import org.bukkit.inventory.ItemStack;
 import org.bukkit.util.Vector;
 import org.bukkit.util.Vector;
 
 
 import java.util.Collection;
 import java.util.Collection;
+import java.util.Locale;
 import java.util.Random;
 import java.util.Random;
 import java.util.Set;
 import java.util.Set;
 
 
@@ -208,7 +209,7 @@ public final class MiscTools {
         String[] materialSplit = materialName.split("_");
         String[] materialSplit = materialName.split("_");
 
 
         if (materialSplit.length > 1) {
         if (materialSplit.length > 1) {
-            return materialSplit[0].toLowerCase();
+            return materialSplit[0].toLowerCase(Locale.ENGLISH);
         }
         }
 
 
         return "UnknownMods";
         return "UnknownMods";

+ 6 - 0
mcmmo-core/src/main/java/com/gmail/nossr50/util/MobHealthBarManager.java

@@ -48,6 +48,11 @@ public final class MobHealthBarManager {
             return;
             return;
         }
         }
 
 
+        // Don't mangle invalid entities, they're not going to be rendered anyways
+        if (!target.isValid()) {
+            return;
+        }
+
         String originalName = target.getName();
         String originalName = target.getName();
         String oldName = target.getCustomName();
         String oldName = target.getCustomName();
 
 
@@ -61,6 +66,7 @@ public final class MobHealthBarManager {
             oldName = "";
             oldName = "";
         }
         }
 
 
+
         boolean oldNameVisible = target.isCustomNameVisible();
         boolean oldNameVisible = target.isCustomNameVisible();
         String newName = createHealthDisplay(pluginRef.getConfigManager().getConfigMobs().getCombat().getHealthBars().getDisplayBarType(), target, damage);
         String newName = createHealthDisplay(pluginRef.getConfigManager().getConfigMobs().getCombat().getHealthBars().getDisplayBarType(), target, damage);
 
 

+ 24 - 22
mcmmo-core/src/main/java/com/gmail/nossr50/util/PermissionTools.java

@@ -18,6 +18,8 @@ import org.bukkit.permissions.PermissionDefault;
 import org.bukkit.plugin.PluginManager;
 import org.bukkit.plugin.PluginManager;
 import org.bukkit.plugin.SimplePluginManager;
 import org.bukkit.plugin.SimplePluginManager;
 
 
+import java.util.Locale;
+
 public final class PermissionTools {
 public final class PermissionTools {
     private final mcMMO pluginRef;
     private final mcMMO pluginRef;
 
 
@@ -175,7 +177,7 @@ public final class PermissionTools {
     }
     }
 
 
     public boolean mctop(Permissible permissible, PrimarySkillType skill) {
     public boolean mctop(Permissible permissible, PrimarySkillType skill) {
-        return permissible.hasPermission("mcmmo.commands.mctop." + skill.toString().toLowerCase());
+        return permissible.hasPermission("mcmmo.commands.mctop." + skill.toString().toLowerCase(Locale.ENGLISH));
     }
     }
 
 
     public boolean mmoedit(Permissible permissible) {
     public boolean mmoedit(Permissible permissible) {
@@ -195,7 +197,7 @@ public final class PermissionTools {
     }
     }
 
 
     public boolean skillreset(Permissible permissible, PrimarySkillType skill) {
     public boolean skillreset(Permissible permissible, PrimarySkillType skill) {
-        return permissible.hasPermission("mcmmo.commands.skillreset." + skill.toString().toLowerCase());
+        return permissible.hasPermission("mcmmo.commands.skillreset." + skill.toString().toLowerCase(Locale.ENGLISH));
     }
     }
 
 
     public boolean skillresetOthers(Permissible permissible) {
     public boolean skillresetOthers(Permissible permissible) {
@@ -203,11 +205,11 @@ public final class PermissionTools {
     }
     }
 
 
     public boolean skillresetOthers(Permissible permissible, PrimarySkillType skill) {
     public boolean skillresetOthers(Permissible permissible, PrimarySkillType skill) {
-        return permissible.hasPermission("mcmmo.commands.skillreset.others." + skill.toString().toLowerCase());
+        return permissible.hasPermission("mcmmo.commands.skillreset.others." + skill.toString().toLowerCase(Locale.ENGLISH));
     }
     }
 
 
     public boolean xplock(Permissible permissible, PrimarySkillType skill) {
     public boolean xplock(Permissible permissible, PrimarySkillType skill) {
-        return permissible.hasPermission("mcmmo.commands.xplock." + skill.toString().toLowerCase());
+        return permissible.hasPermission("mcmmo.commands.xplock." + skill.toString().toLowerCase(Locale.ENGLISH));
     }
     }
 
 
     public boolean xprateSet(Permissible permissible) {
     public boolean xprateSet(Permissible permissible) {
@@ -257,32 +259,32 @@ public final class PermissionTools {
     }
     }
 
 
     public boolean lucky(Permissible permissible, PrimarySkillType skill) {
     public boolean lucky(Permissible permissible, PrimarySkillType skill) {
-        return permissible.hasPermission("mcmmo.perks.lucky." + skill.toString().toLowerCase());
+        return permissible.hasPermission("mcmmo.perks.lucky." + skill.toString().toLowerCase(Locale.ENGLISH));
     }
     }
 
 
     /* XP PERKS */
     /* XP PERKS */
     public boolean quadrupleXp(Permissible permissible, PrimarySkillType skill) {
     public boolean quadrupleXp(Permissible permissible, PrimarySkillType skill) {
-        return permissible.hasPermission("mcmmo.perks.xp.quadruple." + skill.toString().toLowerCase());
+        return permissible.hasPermission("mcmmo.perks.xp.quadruple." + skill.toString().toLowerCase(Locale.ENGLISH));
     }
     }
 
 
     public boolean tripleXp(Permissible permissible, PrimarySkillType skill) {
     public boolean tripleXp(Permissible permissible, PrimarySkillType skill) {
-        return permissible.hasPermission("mcmmo.perks.xp.triple." + skill.toString().toLowerCase());
+        return permissible.hasPermission("mcmmo.perks.xp.triple." + skill.toString().toLowerCase(Locale.ENGLISH));
     }
     }
 
 
     public boolean doubleAndOneHalfXp(Permissible permissible, PrimarySkillType skill) {
     public boolean doubleAndOneHalfXp(Permissible permissible, PrimarySkillType skill) {
-        return permissible.hasPermission("mcmmo.perks.xp.150percentboost." + skill.toString().toLowerCase());
+        return permissible.hasPermission("mcmmo.perks.xp.150percentboost." + skill.toString().toLowerCase(Locale.ENGLISH));
     }
     }
 
 
     public boolean doubleXp(Permissible permissible, PrimarySkillType skill) {
     public boolean doubleXp(Permissible permissible, PrimarySkillType skill) {
-        return permissible.hasPermission("mcmmo.perks.xp.double." + skill.toString().toLowerCase());
+        return permissible.hasPermission("mcmmo.perks.xp.double." + skill.toString().toLowerCase(Locale.ENGLISH));
     }
     }
 
 
     public boolean oneAndOneHalfXp(Permissible permissible, PrimarySkillType skill) {
     public boolean oneAndOneHalfXp(Permissible permissible, PrimarySkillType skill) {
-        return permissible.hasPermission("mcmmo.perks.xp.50percentboost." + skill.toString().toLowerCase());
+        return permissible.hasPermission("mcmmo.perks.xp.50percentboost." + skill.toString().toLowerCase(Locale.ENGLISH));
     }
     }
 
 
     public boolean oneAndOneTenthXp(Permissible permissible, PrimarySkillType skill) {
     public boolean oneAndOneTenthXp(Permissible permissible, PrimarySkillType skill) {
-        return permissible.hasPermission("mcmmo.perks.xp.10percentboost." + skill.toString().toLowerCase());
+        return permissible.hasPermission("mcmmo.perks.xp.10percentboost." + skill.toString().toLowerCase(Locale.ENGLISH));
     }
     }
 
 
     public boolean hasCustomXPPerk(Permissible permissible, CustomXPPerk customXPPerk) {
     public boolean hasCustomXPPerk(Permissible permissible, CustomXPPerk customXPPerk) {
@@ -320,11 +322,11 @@ public final class PermissionTools {
      */
      */
 
 
     public boolean skillEnabled(Permissible permissible, PrimarySkillType skill) {
     public boolean skillEnabled(Permissible permissible, PrimarySkillType skill) {
-        return permissible.hasPermission("mcmmo.skills." + skill.toString().toLowerCase());
+        return permissible.hasPermission("mcmmo.skills." + skill.toString().toLowerCase(Locale.ENGLISH));
     }
     }
 
 
     public boolean vanillaXpBoost(Permissible permissible, PrimarySkillType skill) {
     public boolean vanillaXpBoost(Permissible permissible, PrimarySkillType skill) {
-        return permissible.hasPermission("mcmmo.ability." + skill.toString().toLowerCase() + ".vanillaxpboost");
+        return permissible.hasPermission("mcmmo.ability." + skill.toString().toLowerCase(Locale.ENGLISH) + ".vanillaxpboost");
     }
     }
 
 
     public boolean isSubSkillEnabled(Permissible permissible, SubSkillType subSkillType) {
     public boolean isSubSkillEnabled(Permissible permissible, SubSkillType subSkillType) {
@@ -336,7 +338,7 @@ public final class PermissionTools {
     }
     }
 
 
     public boolean bonusDamage(Permissible permissible, PrimarySkillType skill) {
     public boolean bonusDamage(Permissible permissible, PrimarySkillType skill) {
-        return permissible.hasPermission("mcmmo.ability." + skill.toString().toLowerCase() + ".bonusdamage");
+        return permissible.hasPermission("mcmmo.ability." + skill.toString().toLowerCase(Locale.ENGLISH) + ".bonusdamage");
     }
     }
 
 
     /* ACROBATICS */
     /* ACROBATICS */
@@ -386,11 +388,11 @@ public final class PermissionTools {
     }
     }
 
 
     public boolean greenThumbBlock(Permissible permissible, Material material) {
     public boolean greenThumbBlock(Permissible permissible, Material material) {
-        return permissible.hasPermission("mcmmo.ability.herbalism.greenthumb.blocks." + material.toString().replace("_", "").toLowerCase());
+        return permissible.hasPermission("mcmmo.ability.herbalism.greenthumb.blocks." + material.toString().replace("_", "").toLowerCase(Locale.ENGLISH));
     }
     }
 
 
     public boolean greenThumbPlant(Permissible permissible, Material material) {
     public boolean greenThumbPlant(Permissible permissible, Material material) {
-        return permissible.hasPermission("mcmmo.ability.herbalism.greenthumb.plants." + material.toString().replace("_", "").toLowerCase());
+        return permissible.hasPermission("mcmmo.ability.herbalism.greenthumb.plants." + material.toString().replace("_", "").toLowerCase(Locale.ENGLISH));
     }
     }
 
 
     /* MINING */
     /* MINING */
@@ -412,11 +414,11 @@ public final class PermissionTools {
 
 
     /* REPAIR */
     /* REPAIR */
     public boolean repairItemType(Permissible permissible, ItemType repairItemType) {
     public boolean repairItemType(Permissible permissible, ItemType repairItemType) {
-        return permissible.hasPermission("mcmmo.ability.repair." + repairItemType.toString().toLowerCase() + "repair");
+        return permissible.hasPermission("mcmmo.ability.repair." + repairItemType.toString().toLowerCase(Locale.ENGLISH) + "repair");
     }
     }
 
 
     public boolean repairMaterialType(Permissible permissible, ItemMaterialCategory repairItemMaterialCategory) {
     public boolean repairMaterialType(Permissible permissible, ItemMaterialCategory repairItemMaterialCategory) {
-        return permissible.hasPermission("mcmmo.ability.repair." + repairItemMaterialCategory.toString().toLowerCase() + "repair");
+        return permissible.hasPermission("mcmmo.ability.repair." + repairItemMaterialCategory.toString().toLowerCase(Locale.ENGLISH) + "repair");
     }
     }
 
 
     /* SALVAGE */
     /* SALVAGE */
@@ -429,11 +431,11 @@ public final class PermissionTools {
     }
     }
 
 
     public boolean salvageItemType(Permissible permissible, ItemType salvageItemType) {
     public boolean salvageItemType(Permissible permissible, ItemType salvageItemType) {
-        return permissible.hasPermission("mcmmo.ability.salvage." + salvageItemType.toString().toLowerCase() + "salvage");
+        return permissible.hasPermission("mcmmo.ability.salvage." + salvageItemType.toString().toLowerCase(Locale.ENGLISH) + "salvage");
     }
     }
 
 
     public boolean salvageMaterialType(Permissible permissible, ItemMaterialCategory salvageItemMaterialCategory) {
     public boolean salvageMaterialType(Permissible permissible, ItemMaterialCategory salvageItemMaterialCategory) {
-        return permissible.hasPermission("mcmmo.ability.salvage." + salvageItemMaterialCategory.toString().toLowerCase() + "salvage");
+        return permissible.hasPermission("mcmmo.ability.salvage." + salvageItemMaterialCategory.toString().toLowerCase(Locale.ENGLISH) + "salvage");
     }
     }
 
 
     /* SMELTING */
     /* SMELTING */
@@ -452,7 +454,7 @@ public final class PermissionTools {
 
 
     /* TAMING */
     /* TAMING */
     public boolean callOfTheWild(Permissible permissible, EntityType type) {
     public boolean callOfTheWild(Permissible permissible, EntityType type) {
-        return permissible.hasPermission("mcmmo.ability.taming.callofthewild." + type.toString().toLowerCase());
+        return permissible.hasPermission("mcmmo.ability.taming.callofthewild." + type.toString().toLowerCase(Locale.ENGLISH));
     }
     }
 
 
     /* UNARMED */
     /* UNARMED */
@@ -477,7 +479,7 @@ public final class PermissionTools {
     }
     }
 
 
     public boolean partySubcommand(Permissible permissible, PartySubcommandType subcommand) {
     public boolean partySubcommand(Permissible permissible, PartySubcommandType subcommand) {
-        return permissible.hasPermission("mcmmo.commands.party." + subcommand.toString().toLowerCase());
+        return permissible.hasPermission("mcmmo.commands.party." + subcommand.toString().toLowerCase(Locale.ENGLISH));
     }
     }
 
 
     public boolean friendlyFire(Permissible permissible) {
     public boolean friendlyFire(Permissible permissible) {

+ 3 - 1
mcmmo-core/src/main/java/com/gmail/nossr50/util/StringUtils.java

@@ -7,6 +7,8 @@ import org.bukkit.block.data.Ageable;
 import org.bukkit.block.data.BlockData;
 import org.bukkit.block.data.BlockData;
 import org.bukkit.entity.EntityType;
 import org.bukkit.entity.EntityType;
 
 
+import java.util.Locale;
+
 public class StringUtils {
 public class StringUtils {
 
 
     /**
     /**
@@ -16,7 +18,7 @@ public class StringUtils {
      * @return the capitalized string
      * @return the capitalized string
      */
      */
     public static String getCapitalized(String target) {
     public static String getCapitalized(String target) {
-        return target.substring(0, 1).toUpperCase() + target.substring(1).toLowerCase();
+        return target.substring(0, 1).toUpperCase() + target.substring(1).toLowerCase(Locale.ENGLISH);
     }
     }
 
 
     /**
     /**

+ 2 - 1
mcmmo-core/src/main/java/com/gmail/nossr50/util/TextComponentFactory.java

@@ -14,6 +14,7 @@ import org.bukkit.entity.Player;
 
 
 import java.util.ArrayList;
 import java.util.ArrayList;
 import java.util.List;
 import java.util.List;
+import java.util.Locale;
 
 
 /**
 /**
  * This class handles many of the JSON components that mcMMO makes and uses
  * This class handles many of the JSON components that mcMMO makes and uses
@@ -537,7 +538,7 @@ public class TextComponentFactory {
         TextComponent unlockMessage = new TextComponent("");
         TextComponent unlockMessage = new TextComponent("");
         unlockMessage.setText(pluginRef.getLocaleManager().getString("JSON.SkillUnlockMessage", subSkillType.getLocaleName(pluginRef), pluginRef.getRankTools().getRank(player, subSkillType)));
         unlockMessage.setText(pluginRef.getLocaleManager().getString("JSON.SkillUnlockMessage", subSkillType.getLocaleName(pluginRef), pluginRef.getRankTools().getRank(player, subSkillType)));
         unlockMessage.setHoverEvent(new HoverEvent(HoverEvent.Action.SHOW_TEXT, getSubSkillHoverComponent(player, subSkillType)));
         unlockMessage.setHoverEvent(new HoverEvent(HoverEvent.Action.SHOW_TEXT, getSubSkillHoverComponent(player, subSkillType)));
-        unlockMessage.setClickEvent(new ClickEvent(ClickEvent.Action.RUN_COMMAND, "/" + pluginRef.getSkillTools().getPrimarySkillBySubSkill(subSkillType).toString().toLowerCase()));
+        unlockMessage.setClickEvent(new ClickEvent(ClickEvent.Action.RUN_COMMAND, "/" + pluginRef.getSkillTools().getPrimarySkillBySubSkill(subSkillType).toString().toLowerCase(Locale.ENGLISH)));
         return unlockMessage;
         return unlockMessage;
     }
     }
 }
 }

+ 3 - 2
mcmmo-core/src/main/java/com/gmail/nossr50/util/commands/CommandRegistrationManager.java

@@ -25,6 +25,7 @@ import org.bukkit.command.PluginCommand;
 
 
 import java.util.ArrayList;
 import java.util.ArrayList;
 import java.util.List;
 import java.util.List;
+import java.util.Locale;
 
 
 public final class CommandRegistrationManager {
 public final class CommandRegistrationManager {
     private final mcMMO pluginRef;
     private final mcMMO pluginRef;
@@ -37,8 +38,8 @@ public final class CommandRegistrationManager {
 
 
     private void registerSkillCommands() {
     private void registerSkillCommands() {
         for (PrimarySkillType primarySkillType : PrimarySkillType.values()) {
         for (PrimarySkillType primarySkillType : PrimarySkillType.values()) {
-            String commandName = primarySkillType.toString().toLowerCase();
-            String localizedName = pluginRef.getSkillTools().getLocalizedSkillName(primarySkillType).toLowerCase();
+            String commandName = primarySkillType.toString().toLowerCase(Locale.ENGLISH);
+            String localizedName = pluginRef.getSkillTools().getLocalizedSkillName(primarySkillType).toLowerCase(Locale.ENGLISH);
 
 
             PluginCommand command;
             PluginCommand command;
 
 

+ 3 - 2
mcmmo-core/src/main/java/com/gmail/nossr50/util/commands/CommandTools.java

@@ -12,6 +12,7 @@ import org.bukkit.entity.Player;
 
 
 import java.util.ArrayList;
 import java.util.ArrayList;
 import java.util.List;
 import java.util.List;
+import java.util.Locale;
 
 
 public final class CommandTools {
 public final class CommandTools {
     private final mcMMO pluginRef;
     private final mcMMO pluginRef;
@@ -75,7 +76,7 @@ public final class CommandTools {
             return true;
             return true;
         }
         }
 
 
-        PlayerProfile profile = new PlayerProfile(pluginRef, playerName, false);
+        PlayerProfile profile = new PlayerProfile(pluginRef, playerName, null, false);
 
 
         if (unloadedProfile(sender, profile)) {
         if (unloadedProfile(sender, profile)) {
             return false;
             return false;
@@ -288,7 +289,7 @@ public final class CommandTools {
                 break;
                 break;
             }
             }
 
 
-            if (playerName.toLowerCase().contains(partialName.toLowerCase())) {
+            if (playerName.toLowerCase(Locale.ENGLISH).contains(partialName.toLowerCase(Locale.ENGLISH))) {
                 // Partial match
                 // Partial match
                 matchedPlayers.add(playerName);
                 matchedPlayers.add(playerName);
             }
             }

+ 14 - 27
mcmmo-core/src/main/java/com/gmail/nossr50/util/experience/FormulaManager.java

@@ -9,10 +9,10 @@ import java.util.Map;
 
 
 public class FormulaManager {
 public class FormulaManager {
     // Experience needed to reach a level, cached values for speed
     // Experience needed to reach a level, cached values for speed
-    private Map<Integer, Integer> experienceNeededRetroLinear;
-    private Map<Integer, Integer> experienceNeededStandardLinear;
-    private Map<Integer, Integer> experienceNeededRetroExponential;
-    private Map<Integer, Integer> experienceNeededStandardExponential;
+    private Map<Integer, Integer> experienceNeededCosmeticLinear;
+    private Map<Integer, Integer> experienceNeededLinear;
+    private Map<Integer, Integer> experienceNeededCosmeticExponential;
+    private Map<Integer, Integer> experienceNeededExponential;
 
 
     private FormulaType currentFormula;
     private FormulaType currentFormula;
     private final mcMMO pluginRef;
     private final mcMMO pluginRef;
@@ -27,10 +27,10 @@ public class FormulaManager {
      * Initialize maps used for XP to next level
      * Initialize maps used for XP to next level
      */
      */
     private void initExperienceNeededMaps() {
     private void initExperienceNeededMaps() {
-        experienceNeededRetroLinear = new HashMap<>();
-        experienceNeededRetroExponential = new HashMap<>();
-        experienceNeededStandardLinear = new HashMap<>();
-        experienceNeededStandardExponential = new HashMap<>();
+        experienceNeededCosmeticLinear = new HashMap<>();
+        experienceNeededCosmeticExponential = new HashMap<>();
+        experienceNeededLinear = new HashMap<>();
+        experienceNeededExponential = new HashMap<>();
     }
     }
 
 
     /**
     /**
@@ -120,34 +120,21 @@ public class FormulaManager {
         return processXPToNextLevel(level, currentFormula);
         return processXPToNextLevel(level, currentFormula);
     }
     }
 
 
-    /**
-     * Gets the value of XP needed for the next level based on the level Scaling, the level, and the formula type
-     * @param level target level
-     * @param formulaType target formulaType
-     */
-    private int processXPToNextLevel(int level, FormulaType formulaType) {
-        if(pluginRef.isRetroModeEnabled())
-        {
-            return processXPRetroToNextLevel(level, formulaType);
-        } else {
-            return processStandardXPToNextLevel(level, formulaType);
-        }
-    }
-
     /**
     /**
      * Calculate the XP needed for the next level for the linear formula for Standard scaling (1-100)
      * Calculate the XP needed for the next level for the linear formula for Standard scaling (1-100)
      * @param level target level
      * @param level target level
      * @return raw xp needed to reach the next level
      * @return raw xp needed to reach the next level
      */
      */
-    private int processStandardXPToNextLevel(int level, FormulaType formulaType) {
-        Map<Integer, Integer> experienceMapRef = formulaType == FormulaType.LINEAR ? experienceNeededStandardLinear : experienceNeededStandardExponential;
+    private int processXPToNextLevel(int level, FormulaType formulaType) {
+        Map<Integer, Integer> experienceMapRef = formulaType == FormulaType.LINEAR ? experienceNeededLinear : experienceNeededExponential;
 
 
         if(!experienceMapRef.containsKey(level)) {
         if(!experienceMapRef.containsKey(level)) {
+            int cosmeticScaleMod = pluginRef.getPlayerLevelingSettings().getCosmeticLevelScaleModifier();
             int experienceSum = 0;
             int experienceSum = 0;
-            int retroIndex = (level * 10) + 1;
+            int cosmeticIndex = (level * cosmeticScaleMod) + 1;
 
 
             //Sum the range of levels in Retro that this Standard level would represent
             //Sum the range of levels in Retro that this Standard level would represent
-            for(int x = retroIndex; x < (retroIndex + 10); x++) {
+            for(int x = cosmeticIndex; x < (cosmeticIndex + cosmeticScaleMod); x++) {
                 //calculateXPNeeded doesn't cache results so we use that instead of invoking the Retro XP methods to avoid memory bloat
                 //calculateXPNeeded doesn't cache results so we use that instead of invoking the Retro XP methods to avoid memory bloat
                 experienceSum += calculateXPNeeded(x, formulaType);
                 experienceSum += calculateXPNeeded(x, formulaType);
             }
             }
@@ -166,7 +153,7 @@ public class FormulaManager {
      * @return raw xp needed to reach the next level based on formula type
      * @return raw xp needed to reach the next level based on formula type
      */
      */
     private int processXPRetroToNextLevel(int level, FormulaType formulaType) {
     private int processXPRetroToNextLevel(int level, FormulaType formulaType) {
-        Map<Integer, Integer> experienceMapRef = formulaType == FormulaType.LINEAR ? experienceNeededRetroLinear : experienceNeededRetroExponential;
+        Map<Integer, Integer> experienceMapRef = formulaType == FormulaType.LINEAR ? experienceNeededCosmeticLinear : experienceNeededCosmeticExponential;
 
 
         if (!experienceMapRef.containsKey(level)) {
         if (!experienceMapRef.containsKey(level)) {
             int experience = calculateXPNeeded(level, formulaType);
             int experience = calculateXPNeeded(level, formulaType);

+ 4 - 4
mcmmo-core/src/main/java/com/gmail/nossr50/util/player/NotificationManager.java

@@ -214,12 +214,12 @@ public class NotificationManager {
         //Send the notification
         //Send the notification
         switch (sensitiveCommandType) {
         switch (sensitiveCommandType) {
             case XPRATE_MODIFY:
             case XPRATE_MODIFY:
-                sendAdminNotification(pluginRef.getLocaleManager().getString("Notifications.Admin.XPRate.Start.Others", addItemToFirstPositionOfArray(senderName, args)));
-                sendAdminCommandConfirmation(commandSender, pluginRef.getLocaleManager().getString("Notifications.Admin.XPRate.Start.Self", args));
+                sendAdminNotification(pluginRef.getLocaleManager().getString("Notifications.Admin.XPRate.Start.Others", (Object[]) addItemToFirstPositionOfArray(senderName, args)));
+                sendAdminCommandConfirmation(commandSender, pluginRef.getLocaleManager().getString("Notifications.Admin.XPRate.Start.Self", (Object[]) args));
                 break;
                 break;
             case XPRATE_END:
             case XPRATE_END:
-                sendAdminNotification(pluginRef.getLocaleManager().getString("Notifications.Admin.XPRate.End.Others", addItemToFirstPositionOfArray(senderName, args)));
-                sendAdminCommandConfirmation(commandSender, pluginRef.getLocaleManager().getString("Notifications.Admin.XPRate.End.Self", args));
+                sendAdminNotification(pluginRef.getLocaleManager().getString("Notifications.Admin.XPRate.End.Others", (Object[]) addItemToFirstPositionOfArray(senderName, args)));
+                sendAdminCommandConfirmation(commandSender, pluginRef.getLocaleManager().getString("Notifications.Admin.XPRate.End.Self", (Object[]) args));
                 break;
                 break;
         }
         }
     }
     }

+ 3 - 5
mcmmo-core/src/main/java/com/gmail/nossr50/util/random/RandomChanceTools.java

@@ -10,7 +10,7 @@ import com.gmail.nossr50.util.skills.SkillActivationType;
 import org.bukkit.entity.Player;
 import org.bukkit.entity.Player;
 
 
 import java.text.DecimalFormat;
 import java.text.DecimalFormat;
-import java.util.Random;
+import java.util.concurrent.ThreadLocalRandom;
 
 
 public class RandomChanceTools {
 public class RandomChanceTools {
     
     
@@ -79,10 +79,8 @@ public class RandomChanceTools {
         return rollDice(chance, 10000);
         return rollDice(chance, 10000);
     }
     }
 
 
-    public boolean rollDice(double chanceOfSuccess, int bound) {
-        Random random = new Random();
-
-        return chanceOfSuccess > random.nextInt(bound);
+    public static boolean rollDice(double chanceOfSuccess, int bound) {
+        return chanceOfSuccess > ThreadLocalRandom.current().nextInt(bound);
     }
     }
 
 
     /**
     /**

+ 1 - 1
mcmmo-core/src/main/java/com/gmail/nossr50/util/scoreboards/ScoreboardWrapper.java

@@ -163,7 +163,7 @@ public class ScoreboardWrapper {
         revertTask = new ScoreboardChangeTask().runTaskLater(pluginRef, ticks);
         revertTask = new ScoreboardChangeTask().runTaskLater(pluginRef, ticks);
 
 
         // TODO is there any way to do the time that looks acceptable?
         // TODO is there any way to do the time that looks acceptable?
-        // player.sendMessage(pluginRef.getLocaleManager().getString("Commands.ConfigScoreboard.Timer", StringUtils.capitalize(sidebarType.toString().toLowerCase()), ticks / 20F));
+        // player.sendMessage(LocaleLoader.getString("Commands.Scoreboard.Timer", StringUtils.capitalize(sidebarType.toString().toLowerCase(Locale.ENGLISH)), ticks / 20F));
 
 
         if (pluginRef.getUserManager().getPlayer(playerName) == null)
         if (pluginRef.getUserManager().getPlayer(playerName) == null)
             return;
             return;

+ 39 - 1
mcmmo-core/src/main/java/com/gmail/nossr50/util/skills/CombatTools.java

@@ -48,6 +48,12 @@ public final class CombatTools {
         }
         }
 
 
         McMMOPlayer mcMMOPlayer = pluginRef.getUserManager().getPlayer(player);
         McMMOPlayer mcMMOPlayer = pluginRef.getUserManager().getPlayer(player);
+
+        //Make sure the profiles been loaded
+        if(mcMMOPlayer == null) {
+            return;
+        }
+
         SwordsManager swordsManager = mcMMOPlayer.getSwordsManager();
         SwordsManager swordsManager = mcMMOPlayer.getSwordsManager();
         double initialDamage = event.getDamage();
         double initialDamage = event.getDamage();
         double finalDamage = initialDamage;
         double finalDamage = initialDamage;
@@ -92,6 +98,12 @@ public final class CombatTools {
         Map<DamageModifier, Double> modifiers = getModifiers(event);
         Map<DamageModifier, Double> modifiers = getModifiers(event);
 
 
         McMMOPlayer mcMMOPlayer = pluginRef.getUserManager().getPlayer(player);
         McMMOPlayer mcMMOPlayer = pluginRef.getUserManager().getPlayer(player);
+
+        //Make sure the profiles been loaded
+        if(mcMMOPlayer == null) {
+            return;
+        }
+
         AxesManager axesManager = mcMMOPlayer.getAxesManager();
         AxesManager axesManager = mcMMOPlayer.getAxesManager();
 
 
         if (axesManager.canActivateAbility()) {
         if (axesManager.canActivateAbility()) {
@@ -134,6 +146,12 @@ public final class CombatTools {
         double finalDamage = initialDamage;
         double finalDamage = initialDamage;
 
 
         McMMOPlayer mcMMOPlayer = pluginRef.getUserManager().getPlayer(player);
         McMMOPlayer mcMMOPlayer = pluginRef.getUserManager().getPlayer(player);
+
+        //Make sure the profiles been loaded
+        if(mcMMOPlayer == null) {
+            return;
+        }
+
         UnarmedManager unarmedManager = mcMMOPlayer.getUnarmedManager();
         UnarmedManager unarmedManager = mcMMOPlayer.getUnarmedManager();
 
 
         if (unarmedManager.canActivateAbility()) {
         if (unarmedManager.canActivateAbility()) {
@@ -208,6 +226,12 @@ public final class CombatTools {
         double initialDamage = event.getDamage();
         double initialDamage = event.getDamage();
 
 
         McMMOPlayer mcMMOPlayer = pluginRef.getUserManager().getPlayer(player);
         McMMOPlayer mcMMOPlayer = pluginRef.getUserManager().getPlayer(player);
+
+        //Make sure the profiles been loaded
+        if(mcMMOPlayer == null) {
+            return;
+        }
+
         ArcheryManager archeryManager = mcMMOPlayer.getArcheryManager();
         ArcheryManager archeryManager = mcMMOPlayer.getArcheryManager();
 
 
         double finalDamage = event.getDamage();
         double finalDamage = event.getDamage();
@@ -226,7 +250,8 @@ public final class CombatTools {
         }
         }
 
 
         if (archeryManager.canSkillShot()) {
         if (archeryManager.canSkillShot()) {
-            finalDamage += archeryManager.skillShot(initialDamage);
+            //Not Additive
+            finalDamage = archeryManager.skillShot(initialDamage);
         }
         }
 
 
         if (archeryManager.canDaze(target)) {
         if (archeryManager.canDaze(target)) {
@@ -578,6 +603,12 @@ public final class CombatTools {
             target.damage(damage);
             target.damage(damage);
     }
     }
 
 
+
+    private boolean processingNoInvulnDamage;
+    public boolean isProcessingNoInvulnDamage() {
+        return processingNoInvulnDamage;
+    }
+
     public void dealNoInvulnerabilityTickDamage(LivingEntity target, double damage, Entity attacker) {
     public void dealNoInvulnerabilityTickDamage(LivingEntity target, double damage, Entity attacker) {
         if (target.isDead()) {
         if (target.isDead()) {
             return;
             return;
@@ -588,14 +619,21 @@ public final class CombatTools {
         // potentially mis-attributing the death cause; calling a fake event would partially fix this, but this and setting the last damage
         // potentially mis-attributing the death cause; calling a fake event would partially fix this, but this and setting the last damage
         // cause do have issues around plugin observability. This is not a perfect solution, but it appears to be the best one here
         // cause do have issues around plugin observability. This is not a perfect solution, but it appears to be the best one here
         // We also set no damage ticks to 0, to ensure that damage is applied for this case, and reset it back to the original value
         // We also set no damage ticks to 0, to ensure that damage is applied for this case, and reset it back to the original value
+        // Snapshot current state so we can pop up properly
         boolean wasMetaSet = target.getMetadata(MetadataConstants.CUSTOM_DAMAGE_METAKEY).size() != 0;
         boolean wasMetaSet = target.getMetadata(MetadataConstants.CUSTOM_DAMAGE_METAKEY).size() != 0;
         target.setMetadata(MetadataConstants.CUSTOM_DAMAGE_METAKEY, MetadataConstants.metadataValue);
         target.setMetadata(MetadataConstants.CUSTOM_DAMAGE_METAKEY, MetadataConstants.metadataValue);
+        boolean wasProcessing = processingNoInvulnDamage;
+        // set markers
+        processingNoInvulnDamage = true;
+        target.setMetadata(MetadataConstants.CUSTOM_DAMAGE_METAKEY, MetadataConstants.metadataValue);
         int noDamageTicks = target.getNoDamageTicks();
         int noDamageTicks = target.getNoDamageTicks();
         target.setNoDamageTicks(0);
         target.setNoDamageTicks(0);
         target.damage(damage, attacker);
         target.damage(damage, attacker);
         target.setNoDamageTicks(noDamageTicks);
         target.setNoDamageTicks(noDamageTicks);
         if (!wasMetaSet)
         if (!wasMetaSet)
             target.removeMetadata(MetadataConstants.CUSTOM_DAMAGE_METAKEY, pluginRef);
             target.removeMetadata(MetadataConstants.CUSTOM_DAMAGE_METAKEY, pluginRef);
+        if (!wasProcessing)
+            processingNoInvulnDamage = false;
     }
     }
 
 
     public void dealNoInvulnerabilityTickDamageRupture(LivingEntity target, double damage, Entity attacker, int toolTier) {
     public void dealNoInvulnerabilityTickDamageRupture(LivingEntity target, double damage, Entity attacker, int toolTier) {

+ 1 - 1
mcmmo-core/src/main/java/com/gmail/nossr50/util/skills/RankTools.java

@@ -392,7 +392,7 @@ public class RankTools {
                     .getNode(subSkillType.getHoconFriendlyConfigName())
                     .getNode(subSkillType.getHoconFriendlyConfigName())
                     .getValue(TypeToken.of(SkillRankProperty.class));
                     .getValue(TypeToken.of(SkillRankProperty.class));
 
 
-            int unlockLevel = skillRankProperty.getUnlockLevel(pluginRef.isRetroModeEnabled(), rank);
+            int unlockLevel = skillRankProperty.getUnlockLevel(pluginRef, rank);
             return unlockLevel;
             return unlockLevel;
 
 
         } catch (ObjectMappingException | MissingSkillPropertyDefinition | NullPointerException e) {
         } catch (ObjectMappingException | MissingSkillPropertyDefinition | NullPointerException e) {

+ 2 - 0
mcmmo-core/src/main/java/com/gmail/nossr50/util/sounds/SoundManager.java

@@ -93,6 +93,8 @@ public class SoundManager {
             case DEFLECT_ARROWS:
             case DEFLECT_ARROWS:
             case BLEED:
             case BLEED:
                 return Sound.ENTITY_ENDER_EYE_DEATH;
                 return Sound.ENTITY_ENDER_EYE_DEATH;
+            case GLASS:
+                return Sound.BLOCK_GLASS_BREAK;
             default:
             default:
                 return null;
                 return null;
         }
         }

+ 1 - 0
mcmmo-core/src/main/java/com/gmail/nossr50/util/sounds/SoundType.java

@@ -14,6 +14,7 @@ public enum SoundType {
     ABILITY_ACTIVATED_GENERIC,
     ABILITY_ACTIVATED_GENERIC,
     ABILITY_ACTIVATED_BERSERK,
     ABILITY_ACTIVATED_BERSERK,
     BLEED,
     BLEED,
+    GLASS,
     TIRED;
     TIRED;
 
 
     public boolean usesCustomPitch() {
     public boolean usesCustomPitch() {

+ 29 - 29
mcmmo-core/src/main/java/com/gmail/nossr50/worldguard/WorldGuardUtils.java

@@ -1,6 +1,9 @@
 package com.gmail.nossr50.worldguard;
 package com.gmail.nossr50.worldguard;
 
 
+import com.gmail.nossr50.mcMMO;
+import com.sk89q.worldguard.WorldGuard;
 import com.sk89q.worldguard.bukkit.WorldGuardPlugin;
 import com.sk89q.worldguard.bukkit.WorldGuardPlugin;
+import com.sk89q.worldguard.protection.flags.registry.SimpleFlagRegistry;
 import org.bukkit.plugin.Plugin;
 import org.bukkit.plugin.Plugin;
 
 
 import java.util.ArrayList;
 import java.util.ArrayList;
@@ -12,10 +15,7 @@ public class WorldGuardUtils {
     private boolean isLoaded = false;
     private boolean isLoaded = false;
     private boolean detectedIncompatibleWG = false;
     private boolean detectedIncompatibleWG = false;
     private static final ArrayList<String> WGClassList;
     private static final ArrayList<String> WGClassList;
-    private WorldGuardManager worldGuardManager;
-
-    public WorldGuardUtils() {
-    }
+    protected final mcMMO pluginRef;
 
 
     static {
     static {
         /*
         /*
@@ -41,6 +41,10 @@ public class WorldGuardUtils {
         WGClassList.add("com.sk89q.worldguard.protection.regions.RegionQuery");
         WGClassList.add("com.sk89q.worldguard.protection.regions.RegionQuery");
     }
     }
 
 
+    public WorldGuardUtils(mcMMO pluginRef) {
+        this.pluginRef = pluginRef;
+    }
+
     public boolean isWorldGuardLoaded()
     public boolean isWorldGuardLoaded()
     {
     {
         if(detectedIncompatibleWG)
         if(detectedIncompatibleWG)
@@ -68,7 +72,7 @@ public class WorldGuardUtils {
         if(plugin == null) {
         if(plugin == null) {
             //WG is not present
             //WG is not present
             detectedIncompatibleWG = true;
             detectedIncompatibleWG = true;
-            System.out.println("[mcMMO WorldGuardUtils Debug] WorldGuard was not detected.");
+            pluginRef.getLogger().info("WorldGuard was not detected.");
         } else {
         } else {
             //Check that its actually of class WorldGuardPlugin
             //Check that its actually of class WorldGuardPlugin
             if(plugin instanceof WorldGuardPlugin)
             if(plugin instanceof WorldGuardPlugin)
@@ -77,9 +81,6 @@ public class WorldGuardUtils {
                 {
                 {
                     worldGuardPluginRef = (WorldGuardPlugin) plugin;
                     worldGuardPluginRef = (WorldGuardPlugin) plugin;
                     isLoaded = true;
                     isLoaded = true;
-
-                    //Init WG Manager
-                    worldGuardManager = new WorldGuardManager();
                 }
                 }
             } else {
             } else {
                 //Plugin is not of the expected type
                 //Plugin is not of the expected type
@@ -87,6 +88,7 @@ public class WorldGuardUtils {
             }
             }
         }
         }
 
 
+
         return worldGuardPluginRef;
         return worldGuardPluginRef;
     }
     }
 
 
@@ -98,7 +100,10 @@ public class WorldGuardUtils {
      */
      */
     private boolean isCompatibleVersion(Plugin plugin) {
     private boolean isCompatibleVersion(Plugin plugin) {
         //Check that the version of WG is at least version 7.xx
         //Check that the version of WG is at least version 7.xx
-//        boolean allClassesFound = true;
+        boolean allClassesFound = true;
+        if (detectedIncompatibleWG) {
+            return false;
+        }
 
 
         if (!plugin.getDescription().getVersion().startsWith("7")) {
         if (!plugin.getDescription().getVersion().startsWith("7")) {
             markWGIncompatible();
             markWGIncompatible();
@@ -107,10 +112,9 @@ public class WorldGuardUtils {
             for(String classString : WGClassList) {
             for(String classString : WGClassList) {
                 try {
                 try {
                     Class<?> checkForClass = Class.forName(classString);
                     Class<?> checkForClass = Class.forName(classString);
-                    detectedIncompatibleWG = false; //In case this was set to true previously
                 } catch (ClassNotFoundException | NoClassDefFoundError e) {
                 } catch (ClassNotFoundException | NoClassDefFoundError e) {
-//                    allClassesFound = false;
-                    System.out.println("[mcMMO WorldGuardUtils Debug] Missing WorldGuard class - "+classString);
+                    allClassesFound = false;
+                    pluginRef.getLogger().severe("Missing WorldGuard class - "+classString);
                     markWGIncompatible();
                     markWGIncompatible();
                 }
                 }
             }
             }
@@ -118,17 +122,17 @@ public class WorldGuardUtils {
             /*
             /*
              * If WG appears to have all of its classes we can then check to see if its been initialized properly
              * If WG appears to have all of its classes we can then check to see if its been initialized properly
              */
              */
-//            try {
-//                if(allClassesFound) {
-//                    if(!((SimpleFlagRegistry) WorldGuard.getInstance().getFlagRegistry()).isInitialized()) {
-//                        markWGIncompatible();
-//                        System.out.println("[mcMMO WorldGuardUtils Debug] WG did not initialize properly, this can cause errors with mcMMO so mcMMO is disabling certain features.");
-//                    }
-//                }
-//            } catch (Exception e) {
-//                markWGIncompatible();
-//                e.printStackTrace();
-//            }
+            try {
+                if(allClassesFound) {
+                    if(!((SimpleFlagRegistry) WorldGuard.getInstance().getFlagRegistry()).isInitialized()) {
+                        markWGIncompatible();
+                        pluginRef.getLogger().severe("WG did not initialize properly, this can cause errors with mcMMO so mcMMO is disabling certain features.");
+                    }
+                }
+            } catch (Exception e) {
+                markWGIncompatible();
+                e.printStackTrace();
+            }
         }
         }
 
 
         return !detectedIncompatibleWG;
         return !detectedIncompatibleWG;
@@ -138,14 +142,10 @@ public class WorldGuardUtils {
      * Mark WG as being incompatible to avoid unnecessary operations
      * Mark WG as being incompatible to avoid unnecessary operations
      */
      */
     private void markWGIncompatible() {
     private void markWGIncompatible() {
-        System.out.println("[mcMMO WorldGuardUtils Debug] You are using a version of WG that is not compatible with mcMMO, " +
+        pluginRef.getLogger().severe("You are using a version of WG that is not compatible with mcMMO, " +
                 "WG features for mcMMO will be disabled. mcMMO requires you to be using a new version of WG7 " +
                 "WG features for mcMMO will be disabled. mcMMO requires you to be using a new version of WG7 " +
                 "in order for it to use WG features. Not all versions of WG7 are compatible.");
                 "in order for it to use WG features. Not all versions of WG7 are compatible.");
-        System.out.println("[mcMMO WorldGuardUtils Debug] mcMMO will continue to function normally, but if you wish to use WG support you must use a compatible version.");
+        pluginRef.getLogger().severe("mcMMO will continue to function normally, but if you wish to use WG support you must use a compatible version.");
         detectedIncompatibleWG = true;
         detectedIncompatibleWG = true;
     }
     }
-
-    public WorldGuardManager getWorldGuardManager() {
-        return worldGuardManager;
-    }
 }
 }

+ 9 - 0
mcmmo-core/src/main/resources/com/gmail/nossr50/locale/doTranslation.sh

@@ -0,0 +1,9 @@
+
+sed -i s/Axes.Skills.SS/SuperAbility.SkullSplitter/g *.properties
+sed -i s/Excavation.Skills.GigaDrillBreaker/SuperAbility.GigaDrillBreaker/g *.properties
+sed -i s/Herbalism.Skills.GTe/SuperAbility.GreenTerra/g *.properties
+sed -i s/Mining.Skills.SuperBreaker/SuperAbility.SuperBreaker/g *.properties
+sed -i s/Mining.Blast/SuperAbility.BlastMining/g *.properties
+sed -i s/Swords.Skills.SS/SuperAbility.SerratedStrikes/g *.properties
+sed -i s/Unarmed.Skills.Berserk/SuperAbility.Berserk/g *.properties
+sed -i s/Woodcutting.Skills.TreeFeller/SuperAbility.TreeFeller/g *.properties

تفاوت فایلی نمایش داده نمی شود زیرا این فایل بسیار بزرگ است
+ 303 - 303
mcmmo-core/src/main/resources/com/gmail/nossr50/locale/locale_it.properties


+ 23 - 23
mcmmo-core/src/main/resources/com/gmail/nossr50/locale/locale_ja_JP.properties

@@ -118,14 +118,14 @@ XPBar.Complex.Template={0} [[DARK_AQUA]] {4}[[WHITE]]% [[DARK_AQUA]]([[WHITE]]{1
 # ACROBATICS
 # ACROBATICS
 Acrobatics.Ability.Proc=[[GREEN]]**\u512a\u96c5\u306b\u7740\u5730\u3057\u305f**
 Acrobatics.Ability.Proc=[[GREEN]]**\u512a\u96c5\u306b\u7740\u5730\u3057\u305f**
 Acrobatics.Combat.Proc=[[GREEN]]**\u8eb1\u3057\u305f**
 Acrobatics.Combat.Proc=[[GREEN]]**\u8eb1\u3057\u305f**
-Acrobatics.SubSkill.Roll.Stats=[[GOLD]]\u53d7\u3051\u8eab \u78ba\u7387 [[YELLOW]]{0}%[[GOLD]] \u4e0a\u4f4d\u53d7\u3051\u8eab \u78ba\u7387[[YELLOW]] {1}%
+Acrobatics.SubSkill.Roll.Stats=[[GOLD]]\u53d7\u3051\u8eab \u78ba\u7387 [[YELLOW]]{0}%[[GOLD]] \u512a\u96c5\u306a\u53d7\u3051\u8eab \u78ba\u7387[[YELLOW]] {1}%
 Acrobatics.SubSkill.Roll.Stat=\u53d7\u3051\u8eab \u78ba\u7387
 Acrobatics.SubSkill.Roll.Stat=\u53d7\u3051\u8eab \u78ba\u7387
-Acrobatics.SubSkill.Roll.Stat.Extra=\u4e0a\u4f4d\u53d7\u3051\u8eab \u78ba\u7387
+Acrobatics.SubSkill.Roll.Stat.Extra=\u512a\u96c5\u306a\u53d7\u3051\u8eab \u78ba\u7387
 Acrobatics.SubSkill.Roll.Name=\u53d7\u3051\u8eab
 Acrobatics.SubSkill.Roll.Name=\u53d7\u3051\u8eab
 Acrobatics.SubSkill.Roll.Description=\u30c0\u30e1\u30fc\u30b8\u3092\u907f\u3051\u308b\u70ba\u306b\u843d\u4e0b\u6642\u306b\u53d7\u3051\u8eab\u3059\u308b\u3002
 Acrobatics.SubSkill.Roll.Description=\u30c0\u30e1\u30fc\u30b8\u3092\u907f\u3051\u308b\u70ba\u306b\u843d\u4e0b\u6642\u306b\u53d7\u3051\u8eab\u3059\u308b\u3002
 Acrobatics.SubSkill.Roll.Chance=\u53d7\u3051\u8eab \u78ba\u7387: [[YELLOW]]{0}
 Acrobatics.SubSkill.Roll.Chance=\u53d7\u3051\u8eab \u78ba\u7387: [[YELLOW]]{0}
-Acrobatics.SubSkill.Roll.GraceChance=\u4e0a\u4f4d\u53d7\u3051\u8eab \u78ba\u7387: [[YELLOW]]{0}
-Acrobatics.SubSkill.GracefulRoll.Name=\u4e0a\u4f4d\u53d7\u3051\u8eab
+Acrobatics.SubSkill.Roll.GraceChance=\u512a\u96c5\u306a\u53d7\u3051\u8eab \u78ba\u7387: [[YELLOW]]{0}
+Acrobatics.SubSkill.GracefulRoll.Name=\u512a\u96c5\u306a\u53d7\u3051\u8eab
 Acrobatics.SubSkill.GracefulRoll.Description=\u53d7\u3051\u8eab\u306e\u4e8c\u500d\u306e\u52b9\u679c\u3092\u767a\u63ee\u3059\u308b\u3002
 Acrobatics.SubSkill.GracefulRoll.Description=\u53d7\u3051\u8eab\u306e\u4e8c\u500d\u306e\u52b9\u679c\u3092\u767a\u63ee\u3059\u308b\u3002
 Acrobatics.SubSkill.Dodge.Name=\u8eb1\u3059
 Acrobatics.SubSkill.Dodge.Name=\u8eb1\u3059
 Acrobatics.SubSkill.Dodge.Description=\u653b\u6483\u3067\u53d7\u3051\u308b\u30c0\u30e1\u30fc\u30b8\u3092\u534a\u6e1b\u3059\u308b\u3002
 Acrobatics.SubSkill.Dodge.Description=\u653b\u6483\u3067\u53d7\u3051\u308b\u30c0\u30e1\u30fc\u30b8\u3092\u534a\u6e1b\u3059\u308b\u3002
@@ -193,10 +193,10 @@ Axes.SubSkill.GreaterImpact.Name=\u30b0\u30ec\u30fc\u30bf\u30fc\u30a4\u30f3\u30d
 Axes.SubSkill.GreaterImpact.Description=\u9632\u5177\u306e\u306a\u3044\u6575\u306b\u8ffd\u52a0\u30c0\u30e1\u30fc\u30b8\u3092\u4e0e\u3048\u308b\u3002
 Axes.SubSkill.GreaterImpact.Description=\u9632\u5177\u306e\u306a\u3044\u6575\u306b\u8ffd\u52a0\u30c0\u30e1\u30fc\u30b8\u3092\u4e0e\u3048\u308b\u3002
 Axes.Listener=\u65a7:
 Axes.Listener=\u65a7:
 Axes.SkillName=\u65a7
 Axes.SkillName=\u65a7
-SuperAbility.SkullSplitter.Off=**\u30b9\u30ab\u30eb\u30b9\u30d7\u30ea\u30c3\u30bf\u30fc \u3092\u6469\u640d\u3057\u305f**
+SuperAbility.SkullSplitter.Off=**\u30b9\u30ab\u30eb\u30b9\u30d7\u30ea\u30c3\u30bf\u30fc \u3092\u6d88\u8017\u3057\u305f**
 SuperAbility.SkullSplitter.On=[[GREEN]]**\u30b9\u30ab\u30eb\u30b9\u30d7\u30ea\u30c3\u30bf\u30fc \u30a2\u30af\u30c6\u30a3\u30d9\u30fc\u30c8**
 SuperAbility.SkullSplitter.On=[[GREEN]]**\u30b9\u30ab\u30eb\u30b9\u30d7\u30ea\u30c3\u30bf\u30fc \u30a2\u30af\u30c6\u30a3\u30d9\u30fc\u30c8**
 SuperAbility.SkullSplitter.Refresh=[[YELLOW]]\u30b9\u30ab\u30eb\u30b9\u30d7\u30ea\u30c3\u30bf\u30fc [[GREEN]]\u30a2\u30d3\u30ea\u30c6\u30a3\u304c\u56de\u5fa9\u3057\u307e\u3057\u305f\uff01
 SuperAbility.SkullSplitter.Refresh=[[YELLOW]]\u30b9\u30ab\u30eb\u30b9\u30d7\u30ea\u30c3\u30bf\u30fc [[GREEN]]\u30a2\u30d3\u30ea\u30c6\u30a3\u304c\u56de\u5fa9\u3057\u307e\u3057\u305f\uff01
-SuperAbility.SkullSplitter.Other.Off=[[YELLOW]]{0}\u304c [[WHITE]]\u30b9\u30ab\u30eb\u30b9\u30d7\u30ea\u30c3\u30bf\u30fc [[GREEN]]\u3092\u6469\u640d\u3057\u305f
+SuperAbility.SkullSplitter.Other.Off=[[YELLOW]]{0}\u304c [[WHITE]]\u30b9\u30ab\u30eb\u30b9\u30d7\u30ea\u30c3\u30bf\u30fc [[GREEN]]\u3092\u6d88\u8017\u3057\u305f
 SuperAbility.SkullSplitter.Other.On=[[GREEN]]{0}[[DARK_GREEN]]\u304c [[RED]]\u30b9\u30ab\u30eb\u30b9\u30d7\u30ea\u30c3\u30bf\u30fc [[DARK_GREEN]]\u3092\u4f7f\u3063\u305f\uff01
 SuperAbility.SkullSplitter.Other.On=[[GREEN]]{0}[[DARK_GREEN]]\u304c [[RED]]\u30b9\u30ab\u30eb\u30b9\u30d7\u30ea\u30c3\u30bf\u30fc [[DARK_GREEN]]\u3092\u4f7f\u3063\u305f\uff01
 
 
 # EXCAVATION
 # EXCAVATION
@@ -212,10 +212,10 @@ Excavation.SubSkill.Archaeology.Stat.Extra=\u8003\u53e4\u5b66 \u7d4c\u9a13\u5024
 
 
 Excavation.Listener=\u6398\u524a:
 Excavation.Listener=\u6398\u524a:
 Excavation.SkillName=\u6398\u524a
 Excavation.SkillName=\u6398\u524a
-SuperAbility.GigaDrillBreaker.Off=**\u30ae\u30ac\u30c9\u30ea\u30eb\u30d6\u30ec\u30fc\u30ab\u30fc \u3092\u6469\u640d\u3057\u305f**
+SuperAbility.GigaDrillBreaker.Off=**\u30ae\u30ac\u30c9\u30ea\u30eb\u30d6\u30ec\u30fc\u30ab\u30fc \u3092\u6d88\u8017\u3057\u305f**
 SuperAbility.GigaDrillBreaker.On=[[GREEN]]**\u30ae\u30ac\u30c9\u30ea\u30eb\u30d6\u30ec\u30fc\u30ab\u30fc \u30a2\u30af\u30c6\u30a3\u30d9\u30fc\u30c8**
 SuperAbility.GigaDrillBreaker.On=[[GREEN]]**\u30ae\u30ac\u30c9\u30ea\u30eb\u30d6\u30ec\u30fc\u30ab\u30fc \u30a2\u30af\u30c6\u30a3\u30d9\u30fc\u30c8**
 SuperAbility.GigaDrillBreaker.Refresh=[[YELLOW]]\u30ae\u30ac\u30c9\u30ea\u30eb\u30d6\u30ec\u30fc\u30ab\u30fc [[GREEN]]\u30a2\u30d3\u30ea\u30c6\u30a3\u304c\u56de\u5fa9\u3057\u307e\u3057\u305f\uff01
 SuperAbility.GigaDrillBreaker.Refresh=[[YELLOW]]\u30ae\u30ac\u30c9\u30ea\u30eb\u30d6\u30ec\u30fc\u30ab\u30fc [[GREEN]]\u30a2\u30d3\u30ea\u30c6\u30a3\u304c\u56de\u5fa9\u3057\u307e\u3057\u305f\uff01
-SuperAbility.GigaDrillBreaker.Other.Off=[[YELLOW]]{0}\u304c [[WHITE]]\u30ae\u30ac\u30c9\u30ea\u30eb\u30d6\u30ec\u30fc\u30ab\u30fc [[GREEN]]\u3092\u6469\u640d\u3057\u305f
+SuperAbility.GigaDrillBreaker.Other.Off=[[YELLOW]]{0}\u304c [[WHITE]]\u30ae\u30ac\u30c9\u30ea\u30eb\u30d6\u30ec\u30fc\u30ab\u30fc [[GREEN]]\u3092\u6d88\u8017\u3057\u305f
 SuperAbility.GigaDrillBreaker.Other.On=[[GREEN]]{0}[[DARK_GREEN]]\u304c [[RED]]\u30ae\u30ac\u30c9\u30ea\u30eb\u30d6\u30ec\u30fc\u30ab\u30fc [[DARK_GREEN]]\u3092\u4f7f\u3063\u305f\uff01
 SuperAbility.GigaDrillBreaker.Other.On=[[GREEN]]{0}[[DARK_GREEN]]\u304c [[RED]]\u30ae\u30ac\u30c9\u30ea\u30eb\u30d6\u30ec\u30fc\u30ab\u30fc [[DARK_GREEN]]\u3092\u4f7f\u3063\u305f\uff01
 
 
 # FISHING
 # FISHING
@@ -284,10 +284,10 @@ Herbalism.SubSkill.ShroomThumb.Stat=\u30ad\u30ce\u30b3\u306e\u89aa\u6307 \u78ba\
 Herbalism.HylianLuck=[[GREEN]]\u30cf\u30a4\u30e9\u30eb\u306e\u904b\u306f\u4eca\u65e5\u306e\u3042\u306a\u305f\u306b\u3064\u3044\u3066\u3044\u307e\u3059\uff01
 Herbalism.HylianLuck=[[GREEN]]\u30cf\u30a4\u30e9\u30eb\u306e\u904b\u306f\u4eca\u65e5\u306e\u3042\u306a\u305f\u306b\u3064\u3044\u3066\u3044\u307e\u3059\uff01
 Herbalism.Listener=\u8fb2\u696d:
 Herbalism.Listener=\u8fb2\u696d:
 Herbalism.SkillName=\u8fb2\u696d
 Herbalism.SkillName=\u8fb2\u696d
-SuperAbility.GreenTerra.Off=**\u304c\u3059\u308a\u6e1b\u3063\u305f \u3092\u6469\u640d\u3057\u305f**
-SuperAbility.GreenTerra.On=[[GREEN]]**\u304c\u3059\u308a\u6e1b\u3063\u305f \u30a2\u30af\u30c6\u30a3\u30d9\u30fc\u30c8**
-SuperAbility.GreenTerra.Refresh=[[YELLOW]]\u304c\u3059\u308a\u6e1b\u3063\u305f [[GREEN]]\u30a2\u30d3\u30ea\u30c6\u30a3\u304c\u56de\u5fa9\u3057\u307e\u3057\u305f\uff01
-SuperAbility.GreenTerra.Other.Off=[[YELLOW]]{0}\u304c [[WHITE]]\u304c\u3059\u308a\u6e1b\u3063\u305f [[GREEN]]\u3092\u6469\u640d\u3057\u305f
+SuperAbility.GreenTerra.Off=**\u30b0\u30ea\u30fc\u30f3\u30c6\u30e9 \u3092\u6d88\u8017\u3057\u305f**
+SuperAbility.GreenTerra.On=[[GREEN]]**\u30b0\u30ea\u30fc\u30f3\u30c6\u30e9 \u30a2\u30af\u30c6\u30a3\u30d9\u30fc\u30c8**
+SuperAbility.GreenTerra.Refresh=[[YELLOW]]\u30b0\u30ea\u30fc\u30f3\u30c6\u30e9 [[GREEN]]\u30a2\u30d3\u30ea\u30c6\u30a3\u304c\u56de\u5fa9\u3057\u307e\u3057\u305f\uff01
+SuperAbility.GreenTerra.Other.Off=[[YELLOW]]{0}\u304c [[WHITE]]\u30b0\u30ea\u30fc\u30f3\u30c6\u30e9 [[GREEN]]\u3092\u6d88\u8017\u3057\u305f
 SuperAbility.GreenTerra.Other.On=[[GREEN]]{0}[[DARK_GREEN]]\u304c [[RED]]\u30b0\u30ea\u30fc\u30f3\u30c6\u30e9 [[DARK_GREEN]]\u3092\u4f7f\u3063\u305f\uff01
 SuperAbility.GreenTerra.Other.On=[[GREEN]]{0}[[DARK_GREEN]]\u304c [[RED]]\u30b0\u30ea\u30fc\u30f3\u30c6\u30e9 [[DARK_GREEN]]\u3092\u4f7f\u3063\u305f\uff01
 
 
 # MINING
 # MINING
@@ -313,10 +313,10 @@ Mining.SubSkill.DemolitionsExpertise.Description=TNT\u306b\u3088\u308b\u30c0\u30
 Mining.SubSkill.DemolitionsExpertise.Stat=\u89e3\u4f53\u30a8\u30ad\u30b9\u30d1\u30fc\u30c8\u306e\u30c0\u30e1\u30fc\u30b8\u8efd\u6e1b
 Mining.SubSkill.DemolitionsExpertise.Stat=\u89e3\u4f53\u30a8\u30ad\u30b9\u30d1\u30fc\u30c8\u306e\u30c0\u30e1\u30fc\u30b8\u8efd\u6e1b
 Mining.Listener=\u63a1\u6398:
 Mining.Listener=\u63a1\u6398:
 Mining.SkillName=\u63a1\u6398
 Mining.SkillName=\u63a1\u6398
-SuperAbility.SuperBreaker.Off=**\u30b9\u30fc\u30d1\u30fc\u30d6\u30ec\u30fc\u30ab\u30fc \u3092\u6469\u640d\u3057\u305f**
+SuperAbility.SuperBreaker.Off=**\u30b9\u30fc\u30d1\u30fc\u30d6\u30ec\u30fc\u30ab\u30fc \u3092\u6d88\u8017\u3057\u305f**
 SuperAbility.SuperBreaker.On=[[GREEN]]**\u30b9\u30fc\u30d1\u30fc\u30d6\u30ec\u30fc\u30ab\u30fc \u30a2\u30af\u30c6\u30a3\u30d9\u30fc\u30c8**
 SuperAbility.SuperBreaker.On=[[GREEN]]**\u30b9\u30fc\u30d1\u30fc\u30d6\u30ec\u30fc\u30ab\u30fc \u30a2\u30af\u30c6\u30a3\u30d9\u30fc\u30c8**
 SuperAbility.SuperBreaker.Refresh=[[YELLOW]]\u30b9\u30fc\u30d1\u30fc\u30d6\u30ec\u30fc\u30ab\u30fc [[GREEN]]\u30a2\u30d3\u30ea\u30c6\u30a3\u304c\u56de\u5fa9\u3057\u307e\u3057\u305f\uff01
 SuperAbility.SuperBreaker.Refresh=[[YELLOW]]\u30b9\u30fc\u30d1\u30fc\u30d6\u30ec\u30fc\u30ab\u30fc [[GREEN]]\u30a2\u30d3\u30ea\u30c6\u30a3\u304c\u56de\u5fa9\u3057\u307e\u3057\u305f\uff01
-SuperAbility.SuperBreaker.Other.Off=[[YELLOW]]{0}\u304c [[WHITE]]\u30b9\u30fc\u30d1\u30fc\u30d6\u30ec\u30fc\u30ab\u30fc [[GREEN]]\u3092\u6469\u640d\u3057\u305f
+SuperAbility.SuperBreaker.Other.Off=[[YELLOW]]{0}\u304c [[WHITE]]\u30b9\u30fc\u30d1\u30fc\u30d6\u30ec\u30fc\u30ab\u30fc [[GREEN]]\u3092\u6d88\u8017\u3057\u305f
 SuperAbility.SuperBreaker.Other.On=[[GREEN]]{0}[[DARK_GREEN]]\u304c [[RED]]\u30b9\u30fc\u30d1\u30fc\u30d6\u30ec\u30fc\u30ab\u30fc [[DARK_GREEN]]\u3092\u4f7f\u3063\u305f\uff01
 SuperAbility.SuperBreaker.Other.On=[[GREEN]]{0}[[DARK_GREEN]]\u304c [[RED]]\u30b9\u30fc\u30d1\u30fc\u30d6\u30ec\u30fc\u30ab\u30fc [[DARK_GREEN]]\u3092\u4f7f\u3063\u305f\uff01
 
 
 # Blast Mining
 # Blast Mining
@@ -428,10 +428,10 @@ Swords.Effect.4=\u92f8\u6b6f\u72b6\u306e\u653b\u6483\u306e\u7834\u88c2+
 Swords.Effect.5={0} Tick \u7834\u88c2
 Swords.Effect.5={0} Tick \u7834\u88c2
 Swords.Listener=\u5263:
 Swords.Listener=\u5263:
 Swords.SkillName=\u5263
 Swords.SkillName=\u5263
-SuperAbility.SerratedStrikes.Off=**\u92f8\u6b6f\u72b6\u306e\u653b\u6483 \u3092\u6469\u640d\u3057\u305f**
+SuperAbility.SerratedStrikes.Off=**\u92f8\u6b6f\u72b6\u306e\u653b\u6483 \u3092\u6d88\u8017\u3057\u305f**
 SuperAbility.SerratedStrikes.On=[[GREEN]]**\u92f8\u6b6f\u72b6\u306e\u653b\u6483 \u30a2\u30af\u30c6\u30a3\u30d9\u30fc\u30c8**
 SuperAbility.SerratedStrikes.On=[[GREEN]]**\u92f8\u6b6f\u72b6\u306e\u653b\u6483 \u30a2\u30af\u30c6\u30a3\u30d9\u30fc\u30c8**
 SuperAbility.SerratedStrikes.Refresh=[[YELLOW]]\u92f8\u6b6f\u72b6\u306e\u653b\u6483 [[GREEN]]\u30a2\u30d3\u30ea\u30c6\u30a3\u304c\u56de\u5fa9\u3057\u307e\u3057\u305f\uff01
 SuperAbility.SerratedStrikes.Refresh=[[YELLOW]]\u92f8\u6b6f\u72b6\u306e\u653b\u6483 [[GREEN]]\u30a2\u30d3\u30ea\u30c6\u30a3\u304c\u56de\u5fa9\u3057\u307e\u3057\u305f\uff01
-SuperAbility.SerratedStrikes.Other.Off=[[YELLOW]]{0}\u304c [[WHITE]]\u92f8\u6b6f\u72b6\u306e\u653b\u6483 [[GREEN]]\u3092\u6469\u640d\u3057\u305f
+SuperAbility.SerratedStrikes.Other.Off=[[YELLOW]]{0}\u304c [[WHITE]]\u92f8\u6b6f\u72b6\u306e\u653b\u6483 [[GREEN]]\u3092\u6d88\u8017\u3057\u305f
 SuperAbility.SerratedStrikes.Other.On=[[GREEN]]{0}[[DARK_GREEN]] \u304c [[RED]]\u92f8\u6b6f\u72b6\u306e\u653b\u6483 [[DARK_GREEN]]\u3092\u4f7f\u3063\u305f\uff01
 SuperAbility.SerratedStrikes.Other.On=[[GREEN]]{0}[[DARK_GREEN]] \u304c [[RED]]\u92f8\u6b6f\u72b6\u306e\u653b\u6483 [[DARK_GREEN]]\u3092\u4f7f\u3063\u305f\uff01
 
 
 # TAMING
 # TAMING
@@ -515,10 +515,10 @@ Unarmed.SubSkill.BlockCracker.Name=\u30d6\u30ed\u30c3\u30af\u30af\u30e9\u30c3\u3
 Unarmed.SubSkill.BlockCracker.Description=\u62f3\u3067\u5ca9\u3092\u7834\u58ca\u3059\u308b\u3002
 Unarmed.SubSkill.BlockCracker.Description=\u62f3\u3067\u5ca9\u3092\u7834\u58ca\u3059\u308b\u3002
 Unarmed.Listener=\u7d20\u624b:
 Unarmed.Listener=\u7d20\u624b:
 Unarmed.SkillName=\u7d20\u624b
 Unarmed.SkillName=\u7d20\u624b
-SuperAbility.Berserk.Off=**\u30d0\u30fc\u30b5\u30fc\u30ab\u30fc \u3092\u6469\u640d\u3057\u305f**
+SuperAbility.Berserk.Off=**\u30d0\u30fc\u30b5\u30fc\u30ab\u30fc \u3092\u6d88\u8017\u3057\u305f**
 SuperAbility.Berserk.On=[[GREEN]]**\u30d0\u30fc\u30b5\u30fc\u30ab\u30fc \u30a2\u30af\u30c6\u30a3\u30d9\u30fc\u30c8**
 SuperAbility.Berserk.On=[[GREEN]]**\u30d0\u30fc\u30b5\u30fc\u30ab\u30fc \u30a2\u30af\u30c6\u30a3\u30d9\u30fc\u30c8**
 SuperAbility.Berserk.Refresh=[[YELLOW]]\u30d0\u30fc\u30b5\u30fc\u30ab\u30fc [[GREEN]]\u30a2\u30d3\u30ea\u30c6\u30a3\u304c\u56de\u5fa9\u3057\u307e\u3057\u305f\uff01
 SuperAbility.Berserk.Refresh=[[YELLOW]]\u30d0\u30fc\u30b5\u30fc\u30ab\u30fc [[GREEN]]\u30a2\u30d3\u30ea\u30c6\u30a3\u304c\u56de\u5fa9\u3057\u307e\u3057\u305f\uff01
-SuperAbility.Berserk.Other.Off=[[YELLOW]]{0}\u304c [[WHITE]]\u30d0\u30fc\u30b5\u30fc\u30ab\u30fc [[GREEN]]\u3092\u6469\u640d\u3057\u305f
+SuperAbility.Berserk.Other.Off=[[YELLOW]]{0}\u304c [[WHITE]]\u30d0\u30fc\u30b5\u30fc\u30ab\u30fc [[GREEN]]\u3092\u6d88\u8017\u3057\u305f
 SuperAbility.Berserk.Other.On=[[GREEN]]{0}[[DARK_GREEN]]\u304c [[RED]]\u30d0\u30fc\u30b5\u30fc\u30ab\u30fc [[DARK_GREEN]]\u3092\u4f7f\u3063\u305f\uff01
 SuperAbility.Berserk.Other.On=[[GREEN]]{0}[[DARK_GREEN]]\u304c [[RED]]\u30d0\u30fc\u30b5\u30fc\u30ab\u30fc [[DARK_GREEN]]\u3092\u4f7f\u3063\u305f\uff01
 
 
 # WOODCUTTING
 # WOODCUTTING
@@ -541,10 +541,10 @@ Woodcutting.SubSkill.NaturesBounty.Name=\u81ea\u7136\u306e\u6075\u307f
 Woodcutting.SubSkill.NaturesBounty.Description=\u81ea\u7136\u304b\u3089\u7d4c\u9a13\u5024\u3092\u96c6\u3081\u308b\u3002
 Woodcutting.SubSkill.NaturesBounty.Description=\u81ea\u7136\u304b\u3089\u7d4c\u9a13\u5024\u3092\u96c6\u3081\u308b\u3002
 Woodcutting.Listener=\u6728\u3053\u308a:
 Woodcutting.Listener=\u6728\u3053\u308a:
 Woodcutting.SkillName=\u6728\u3053\u308a
 Woodcutting.SkillName=\u6728\u3053\u308a
-SuperAbility.TreeFeller.Off=**\u30c4\u30ea\u30fc\u30d5\u30a7\u30e9\u30fc \u3092\u6469\u640d\u3057\u305f**
+SuperAbility.TreeFeller.Off=**\u30c4\u30ea\u30fc\u30d5\u30a7\u30e9\u30fc \u3092\u6d88\u8017\u3057\u305f**
 SuperAbility.TreeFeller.On=[[GREEN]]**\u30c4\u30ea\u30fc\u30d5\u30a7\u30e9\u30fc \u30a2\u30af\u30c6\u30a3\u30d9\u30fc\u30c8**
 SuperAbility.TreeFeller.On=[[GREEN]]**\u30c4\u30ea\u30fc\u30d5\u30a7\u30e9\u30fc \u30a2\u30af\u30c6\u30a3\u30d9\u30fc\u30c8**
 SuperAbility.TreeFeller.Refresh=[[YELLOW]]\u30c4\u30ea\u30fc\u30d5\u30a7\u30e9\u30fc [[GREEN]]\u30a2\u30d3\u30ea\u30c6\u30a3\u304c\u56de\u5fa9\u3057\u307e\u3057\u305f\uff01
 SuperAbility.TreeFeller.Refresh=[[YELLOW]]\u30c4\u30ea\u30fc\u30d5\u30a7\u30e9\u30fc [[GREEN]]\u30a2\u30d3\u30ea\u30c6\u30a3\u304c\u56de\u5fa9\u3057\u307e\u3057\u305f\uff01
-SuperAbility.TreeFeller.Other.Off=[[YELLOW]]{0}\u304c [[WHITE]]\u30c4\u30ea\u30fc\u30d5\u30a7\u30e9\u30fc [[GREEN]]\u3092\u6469\u640d\u3057\u305f
+SuperAbility.TreeFeller.Other.Off=[[YELLOW]]{0}\u304c [[WHITE]]\u30c4\u30ea\u30fc\u30d5\u30a7\u30e9\u30fc [[GREEN]]\u3092\u6d88\u8017\u3057\u305f
 SuperAbility.TreeFeller.Other.On=[[GREEN]]{0}[[DARK_GREEN]]\u304c [[RED]]\u30c4\u30ea\u30fc\u30d5\u30a7\u30e9\u30fc [[DARK_GREEN]]\u3092\u4f7f\u3063\u305f\uff01
 SuperAbility.TreeFeller.Other.On=[[GREEN]]{0}[[DARK_GREEN]]\u304c [[RED]]\u30c4\u30ea\u30fc\u30d5\u30a7\u30e9\u30fc [[DARK_GREEN]]\u3092\u4f7f\u3063\u305f\uff01
 SuperAbility.TreeFeller.Splinter=\u65a7\u306f\u4f55\u5341\u3082\u306e\u7834\u7247\u306b\u7815\u3051\u305f\uff01
 SuperAbility.TreeFeller.Splinter=\u65a7\u306f\u4f55\u5341\u3082\u306e\u7834\u7247\u306b\u7815\u3051\u305f\uff01
 SuperAbility.TreeFeller.Threshold=\u6728\u304c\u5927\u304d\u3059\u304e\u308b\uff01
 SuperAbility.TreeFeller.Threshold=\u6728\u304c\u5927\u304d\u3059\u304e\u308b\uff01
@@ -988,19 +988,19 @@ Skills.Parents= PARENTS
 Skills.Stats={0}[[GREEN]]{1}[[DARK_AQUA]] XP([[GRAY]]{2}[[DARK_AQUA]]/[[GRAY]]{3}[[DARK_AQUA]])
 Skills.Stats={0}[[GREEN]]{1}[[DARK_AQUA]] XP([[GRAY]]{2}[[DARK_AQUA]]/[[GRAY]]{3}[[DARK_AQUA]])
 Skills.ChildStats={0}[[GREEN]]{1}
 Skills.ChildStats={0}[[GREEN]]{1}
 Skills.MaxXP=\u6700\u5927
 Skills.MaxXP=\u6700\u5927
-Skills.TooTired=\u305d\u306e\u30a2\u30d3\u30ea\u30c6\u30a3\u3092\u518d\u3073\u4f7f\u3046\u306e\u306b\u306f\u98fd\u304d\u904e\u304e\u3066\u3044\u307e\u3059\u3002 [[YELLOW]]({0}\u79d2)
+Skills.TooTired=\u305d\u306e\u30a2\u30d3\u30ea\u30c6\u30a3\u3092\u518d\u3073\u4f7f\u3046\u306e\u306b\u306f\u75b2\u308c\u904e\u304e\u3066\u3044\u307e\u3059\u3002 [[YELLOW]]({0}\u79d2)
 Skills.Cancelled=[[GOLD]]{0} [[RED]]\u30ad\u30e3\u30f3\u30bb\u30eb\uff01
 Skills.Cancelled=[[GOLD]]{0} [[RED]]\u30ad\u30e3\u30f3\u30bb\u30eb\uff01
 Skills.ConfirmOrCancel=[[GREEN]]\u3082\u3046\u4e00\u5ea6\u53f3\u30af\u30ea\u30c3\u30af\u3057\u3066[[GOLD]]{0}[[GREEN]]\u3092\u78ba\u8a8d\u3057\u3066\u304f\u3060\u3055\u3044\u3002 \u30ad\u30e3\u30f3\u30bb\u30eb\u3059\u308b\u306b\u306f\u5de6\u30af\u30ea\u30c3\u30af\u3057\u3066\u304f\u3060\u3055\u3044\u3002
 Skills.ConfirmOrCancel=[[GREEN]]\u3082\u3046\u4e00\u5ea6\u53f3\u30af\u30ea\u30c3\u30af\u3057\u3066[[GOLD]]{0}[[GREEN]]\u3092\u78ba\u8a8d\u3057\u3066\u304f\u3060\u3055\u3044\u3002 \u30ad\u30e3\u30f3\u30bb\u30eb\u3059\u308b\u306b\u306f\u5de6\u30af\u30ea\u30c3\u30af\u3057\u3066\u304f\u3060\u3055\u3044\u3002
 Skills.AbilityGateRequirementFail=[[GRAY]]\u3053\u306e\u30a2\u30d3\u30ea\u30c6\u30a3\u3092\u4f7f\u3046\u305f\u3081\u306b\u306f[[YELLOW]]{0}[[GRAY]]\u30ec\u30d9\u30eb\u306e[[DARK_AQUA]]{1}[[GRAY]]\u304c\u5fc5\u8981\u3067\u3059\u3002
 Skills.AbilityGateRequirementFail=[[GRAY]]\u3053\u306e\u30a2\u30d3\u30ea\u30c6\u30a3\u3092\u4f7f\u3046\u305f\u3081\u306b\u306f[[YELLOW]]{0}[[GRAY]]\u30ec\u30d9\u30eb\u306e[[DARK_AQUA]]{1}[[GRAY]]\u304c\u5fc5\u8981\u3067\u3059\u3002
 
 
 # STATISTICS
 # STATISTICS
-Stats.Header.Combat=[[GOLD]]-=\u30b3\u30f3\u30d0\u30c3\u30c8\u30b9\u30ad\u30eb=-
+Stats.Header.Combat=[[GOLD]]-=\u6226\u95d8\u30b9\u30ad\u30eb=-
 Stats.Header.Gathering=[[GOLD]]-=\u53ce\u96c6\u30b9\u30ad\u30eb=-
 Stats.Header.Gathering=[[GOLD]]-=\u53ce\u96c6\u30b9\u30ad\u30eb=-
 Stats.Header.Misc=[[GOLD]]-=\u305d\u306e\u4ed6\u306e\u30b9\u30ad\u30eb=-
 Stats.Header.Misc=[[GOLD]]-=\u305d\u306e\u4ed6\u306e\u30b9\u30ad\u30eb=-
 Stats.Own.Stats=[[GREEN]][mcMMO] \u7d71\u8a08
 Stats.Own.Stats=[[GREEN]][mcMMO] \u7d71\u8a08
 
 
 # PERKS
 # PERKS
-Perks.XP.Name=\u7d4c\u9a13
+Perks.XP.Name=\u7d4c\u9a13\u5024
 Perks.XP.Desc=\u7279\u5b9a\u306e\u30b9\u30ad\u30eb\u306e\u30d6\u30fc\u30b9\u30c8XP\u3092\u53d7\u3051\u53d6\u308b\u3002
 Perks.XP.Desc=\u7279\u5b9a\u306e\u30b9\u30ad\u30eb\u306e\u30d6\u30fc\u30b9\u30c8XP\u3092\u53d7\u3051\u53d6\u308b\u3002
 Perks.Lucky.Name=\u30e9\u30c3\u30ad\u30fc
 Perks.Lucky.Name=\u30e9\u30c3\u30ad\u30fc
 Perks.Lucky.Desc={0}\u306e\u30b9\u30ad\u30eb\u3068\u80fd\u529b\u306b\u300133.3\uff05\u306e\u30a2\u30af\u30c6\u30a3\u30d9\u30fc\u30c8\u306e\u78ba\u7387\u3092\u4e0e\u3048\u307e\u3059\u3002
 Perks.Lucky.Desc={0}\u306e\u30b9\u30ad\u30eb\u3068\u80fd\u529b\u306b\u300133.3\uff05\u306e\u30a2\u30af\u30c6\u30a3\u30d9\u30fc\u30c8\u306e\u78ba\u7387\u3092\u4e0e\u3048\u307e\u3059\u3002

+ 1110 - 0
mcmmo-core/src/main/resources/com/gmail/nossr50/locale/locale_lt_LT.properties

@@ -0,0 +1,1110 @@
+#I'm going to try to normalize our locale file, forgive the mess for now.
+
+#DO NOT USE COLOR CODES IN THE JSON KEYS
+#COLORS ARE DEFINED IN advanced.yml IF YOU WISH TO CHANGE THEM
+JSON.Rank=Rankas
+JSON.DescriptionHeader=Aprašymas
+JSON.JWrapper.Header=Informacija
+JSON.Type.Passive=Neaktyvuota
+JSON.Type.Active=Aktyvuota
+JSON.Type.SuperAbility=Super Ability
+JSON.Locked=-=[UŽRAKINTA]=-
+JSON.LevelRequirement=Įgūdžių lygių reikalavimai
+JSON.JWrapper.Target.Type=Pasirinktas tipas:
+JSON.JWrapper.Target.Block=Blokas
+JSON.JWrapper.Target.Player=Žaidėjas
+JSON.JWrapper.Perks.Header=[[GOLD]]Lucky Perks
+JSON.JWrapper.Perks.Lucky={0}% Better Odds
+JSON.Hover.Tips=Svarbu
+JSON.Acrobatics=Acrobatika
+JSON.Alchemy=Alchemija
+JSON.Archery=Lanko valdymas
+JSON.Axes=Kirvio valdymas
+JSON.Excavation=Kasimas
+JSON.Fishing=Žvejyba
+JSON.Herbalism=Žolininkystė
+JSON.Mining=Akmens skaldymas
+JSON.Repair=Taisymas
+JSON.Salvage=Kepimas
+JSON.Swords=Kardo valdymas
+JSON.Taming=Prijaukinimas
+JSON.Unarmed=Beginkė kova
+JSON.Woodcutting=Medžio kirtimas
+JSON.URL.Website=Oficialus mcMMO Projekto tinklalapis!
+JSON.URL.Discord=Oficialus mcMMO Discord serveris pagalbai!
+JSON.URL.Patreon=Pagalbą teikia: nossr50 prisidėti prie mcMMO galite paremdami: Patreon!
+JSON.URL.Spigot=Oficialus mcMMO Spigot tiekėjas!
+JSON.URL.Translation=Vertimai mcMMO kitomis kalbomis!
+JSON.URL.Wiki=Oficiali mcMMO Pagalba!
+JSON.SkillUnlockMessage=[[GOLD]][ mcMMO[[YELLOW]] @[[DARK_AQUA]]{0} [[GOLD]]Įgūdžių Rankas [[DARK_AQUA]]{1}[[GOLD]] Atrakintas! ]
+JSON.Hover.Rank=&e&lRankas:&r &f{0}
+JSON.Hover.NextRank=&7&oKitas ranko pakėlimas už {0} LvL.
+# for JSON.Hover.Mystery you can add {0} to insert the level required into the name, I don't like how that looks so I'm not doing that atm
+JSON.Hover.Mystery=[[GRAY]]???
+JSON.Hover.Mystery2=[[YELLOW]][[[DARK_GRAY]]{0}[[YELLOW]]][[DARK_GRAY]]???&r
+JSON.Hover.SkillName=[[DARK_AQUA]]{0}&r
+JSON.Hover.SuperAbility=[[DARK_PURPLE]]{0}&r
+JSON.Hover.MaxRankSkillName=[[GOLD]]{0}&r
+JSON.Hover.AtSymbolSkills=[[YELLOW]]@
+JSON.Hover.AtSymbolURL=[[YELLOW]]@
+
+#This is the message sent to players when an ability is activated
+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
+
+mcMMO.Template.Prefix=[[GOLD]]([[GREEN]]mcMMO[[GOLD]]) [[GRAY]]{0}
+# BEGIN STYLING
+Ability.Generic.Refresh=[[GREEN]]**ABILITIES REFRESHED!**
+Ability.Generic.Template.Lock=[[GRAY]]{0}
+# Skill Command Styling
+Ability.Generic.Template=[[DARK_AQUA]]{0}: [[GREEN]]{1}
+Ability.Generic.Template.Custom=[[DARK_AQUA]]{0}
+Skills.Overhaul.Header=[[RED]][]=====[][[GREEN]] {0} [[RED]][]=====[]
+Effects.Effects=EFFECTS
+Effects.SubSkills.Overhaul=Sub-Skills
+Effects.Child.Overhaul=[[DARK_AQUA]]Buvęs LvL.[[YELLOW]] {0}[[DARK_AQUA]]: {1}
+Effects.Child.ParentList=[[GREEN]]{0}[[GOLD]]([[DARK_AQUA]]LvL.[[YELLOW]]{1}[[GOLD]])
+Effects.Level.Overhaul=[[GOLD]]LvL: [[YELLOW]]{0} [[DARK_AQUA]]XP[[YELLOW]]([[GOLD]]{1}[[YELLOW]]/[[GOLD]]{2}[[YELLOW]])
+Effects.Parent=[[GOLD]]{0} -
+Effects.Template=[[DARK_AQUA]]{0}: [[GREEN]]{1}
+Commands.Stats.Self.Overhaul=Stats
+Commands.XPGain.Overhaul=[[GOLD]]Įgavote patirties eXP: [[DARK_AQUA]]{0}
+MOTD.Version.Overhaul=[[GOLD]][mcMMO] [[DARK_AQUA]]Overhaul Era[[GOLD]] - [[DARK_AQUA]]{0}
+Overhaul.mcMMO.Header=[[RED]][]=====[][[GREEN]] mcMMO - Overhaul Era [[RED]][]=====[]
+Overhaul.mcMMO.Url.Wrap.Prefix=[[RED]][|
+Overhaul.mcMMO.Url.Wrap.Suffix=[[RED]]|]
+Overhaul.mcMMO.MmoInfo.Wiki=[[YELLOW]][[[WHITE]]View this skill on the wiki![[YELLOW]]]
+# Overhaul.Levelup can take {0} - Skill Name defined in Overhaul.Name {1} - Amount of levels gained {2} - Level in skill
+Overhaul.Levelup=[[BOLD]]{0} [[GOLD]]LvL. [[DARK_AQUA]]pakilo iki: [[RESET]][[GREEN]][[BOLD]]{2}[[RESET]][[WHITE]].
+Overhaul.Name.Acrobatics=Akrobatinių įgūdžių
+Overhaul.Name.Alchemy=Alchemiko įgūdžių
+Overhaul.Name.Archery=Lankininko įgūdžių
+Overhaul.Name.Axes=Kirvio valdymo įgūdžių
+Overhaul.Name.Excavation=Kasinėjimosi įgūdžių
+Overhaul.Name.Fishing=Žvejybos įgūdžių
+Overhaul.Name.Herbalism=Žolininko įgūdžių
+Overhaul.Name.Mining=Akmens skaldytojo įgūdžių
+Overhaul.Name.Repair=Taisymo įgūdžių
+Overhaul.Name.Salvage=Gelbėjimo įgūdžių
+Overhaul.Name.Smelting=Kepimo įgūdžių
+Overhaul.Name.Swords=Kardo valdymo įgūdžių
+Overhaul.Name.Taming=Prijaukinimo įgūdžių
+Overhaul.Name.Unarmed=Beginklės kovos įgūdžių
+Overhaul.Name.Woodcutting=Medkirčio įgūdžių
+# /mcMMO Command Style Stuff
+Commands.mcc.Header=[[RED]]---[][[GREEN]]mcMMO Commands[[RED]][]---
+Commands.Other=[[RED]]---[][[GREEN]]SPECIAL COMMANDS[[RED]][]---
+Commands.Party.Header=[[RED]]-----[][[GREEN]]PARTY[[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]]Įgyjami nauji įgūdžiai...
+XPBar.Acrobatics=Akrobatinių įgūdžių LvL.[[GOLD]]{0}
+XPBar.Alchemy=Alchemiko įgūdžių LvL.[[GOLD]]{0}
+XPBar.Archery=Lankininko įgūdžių LvL.[[GOLD]]{0}
+XPBar.Axes=Kirvio valdymo įgūdžių LvL.[[GOLD]]{0}
+XPBar.Excavation=Kasinėjimosi įgūdžių LvL.[[GOLD]]{0}
+XPBar.Fishing=Žvejybos įgūdžių LvL.[[GOLD]]{0}
+XPBar.Herbalism=Žolininko įgūdžių LvL.[[GOLD]]{0}
+XPBar.Mining=Akmens skaldytojo įgūdžių LvL.[[GOLD]]{0}
+XPBar.Repair=Taisymo įgūdžių LvL.[[GOLD]]{0}
+XPBar.Salvage=Gelbėjimo įgūdžių LvL.[[GOLD]]{0}
+XPBar.Smelting=Kepimo įgūdžių LvL.[[GOLD]]{0}
+XPBar.Swords=Kardo valdymo įgūdžių LvL.[[GOLD]]{0}
+XPBar.Taming=Prijaukinimo įgūdžių LvL.[[GOLD]]{0}
+XPBar.Unarmed=Beginklės kovos įgūdžių LvL.[[GOLD]]{0}
+XPBar.Woodcutting=Medkirčio įgūdžių LvL.[[GOLD]]{0}
+#This is just a preset template that gets used if the 'ExtraDetails' setting is turned on in experience.yml (off by default), you can ignore this template and just edit the strings above
+XPBar.Complex.Template={0} [[DARK_AQUA]] {4}[[WHITE]]% [[DARK_AQUA]]([[WHITE]]{1}[[DARK_AQUA]]/[[WHITE]]{2}[[DARK_AQUA]])
+# 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!
+# END STYLING
+
+#ACROBATICS
+Acrobatics.Ability.Proc=[[GREEN]]**Graceful Landing**
+Acrobatics.Combat.Proc=[[GREEN]]**Dodged**
+Acrobatics.SubSkill.Roll.Stats=[[GOLD]]Roll Chance [[YELLOW]]{0}%[[GOLD]] Graceful Roll Chance[[YELLOW]] {1}%
+Acrobatics.SubSkill.Roll.Stat=Roll Chance
+Acrobatics.SubSkill.Roll.Stat.Extra=Graceful Roll Chance
+Acrobatics.SubSkill.Roll.Name=Roll
+Acrobatics.SubSkill.Roll.Description=Land strategically to avoid damage.
+Acrobatics.SubSkill.Roll.Chance=Roll Chance: [[YELLOW]]{0}
+Acrobatics.SubSkill.Roll.GraceChance=Graceful Roll Chance: [[YELLOW]]{0}
+Acrobatics.SubSkill.Roll.Mechanics=[[GRAY]]Rolling is an active Sub-Skill with a passive component.\nWhenever you take fall damage you have a chance to completely negate the damage based on your skill level, at level 50 you have a [[YELLOW]]{0}%[[GRAY]] chance to prevent damage, and [[YELLOW]]{1}%[[GRAY]] if you activate Graceful Roll.\nThe chance for success is scaled against your skill level in a linear curve until level [[YELLOW]]{2}[[GRAY]] where it maxes out, every level in Acrobatics gives you a [[YELLOW]]{3}%[[GRAY]] chance to succeed.\nBy holding the sneak button you can double your odds to avoid fall damage and avoid up to twice the fall damage! Holding sneak will transform a normal roll into a Graceful Roll.\nRolling will only prevent up to [[RED]]{4}[[GRAY]] damage. Graceful Rolls will prevent up to [[GREEN]]{5}[[GRAY]] damage.
+Acrobatics.SubSkill.GracefulRoll.Name=Graceful Roll
+Acrobatics.SubSkill.GracefulRoll.Description=Twice as effective as a normal Roll
+Acrobatics.SubSkill.Dodge.Name=Dodge
+Acrobatics.SubSkill.Dodge.Description=Reduce attack damage by half
+Acrobatics.SubSkill.Dodge.Stat=Dodge Chance
+Acrobatics.Listener=Acrobatics:
+Acrobatics.Roll.Text=[[ITALIC]]**Rolled**
+Acrobatics.SkillName=ACROBATICS
+#ALCHEMY
+Alchemy.SubSkill.Catalysis.Name=Catalysis
+Alchemy.SubSkill.Catalysis.Description=Increases potion brewing speed
+Alchemy.SubSkill.Catalysis.Stat=Brewing Speed
+Alchemy.SubSkill.Concoctions.Name=Concoctions
+Alchemy.SubSkill.Concoctions.Description=Brew potions with more ingredients
+Alchemy.SubSkill.Concoctions.Stat=Concoctions Rank: [[GREEN]]{0}[[DARK_AQUA]]/[[GREEN]]{1}
+Alchemy.SubSkill.Concoctions.Stat.Extra=Ingredients [[[GREEN]]{0}[[DARK_AQUA]]]: [[GREEN]]{1}
+Alchemy.Listener=Alchemy:
+Alchemy.Ability.Locked.0=LOCKED UNTIL {0}+ SKILL (CATALYSIS)
+Alchemy.SkillName=ALCHEMY
+#ARCHERY
+
+
+Archery.SubSkill.SkillShot.Name=Skill Shot
+Archery.SubSkill.SkillShot.Description=Increases damage done with bows
+Archery.SubSkill.SkillShot.Stat=Skill Shot Bonus Damage
+Archery.SubSkill.Daze.Name=Daze
+Archery.SubSkill.Daze.Description=Disorients foes and deals extra DMG
+Archery.SubSkill.Daze.Stat=Daze Chance
+Archery.SubSkill.ArrowRetrieval.Name=Arrow Retrieval
+Archery.SubSkill.ArrowRetrieval.Description=Chance to retrieve arrows from corpses
+Archery.SubSkill.ArrowRetrieval.Stat=Arrow Recovery Chance
+Archery.SubSkill.ArcheryLimitBreak.Name=Archery Limit Break
+Archery.SubSkill.ArcheryLimitBreak.Description=Breaking your limits. Increased damage against tough opponents. Intended for PVP, up to server settings for whether or not it will boost damage in PVE.
+Archery.SubSkill.ArcheryLimitBreak.Stat=Limit Break Max DMG
+Archery.Listener=Archery:
+Archery.SkillName=ARCHERY
+#AXES
+Axes.Ability.Bonus.0=Kirvio meistras
+Axes.Ability.Bonus.1=Pridės {0} žalos
+Axes.Ability.Bonus.2=Armor Impact
+Axes.Ability.Bonus.3=Deal {0} Bonus DMG to armor
+Axes.Ability.Bonus.4=Greater Impact
+Axes.Ability.Bonus.5=Deal {0} Bonus DMG to unarmored foes
+Axes.Ability.Lower=[[GRAY]]You lower your Axe.
+Axes.Ability.Ready=[[DARK_AQUA]]You [[GOLD]]ready[[DARK_AQUA]] your Axe.
+Axes.Combat.CritStruck=[[DARK_RED]]You were CRITICALLY hit!
+Axes.Combat.CriticalHit=CRITICAL HIT!
+Axes.Combat.GI.Proc=[[GREEN]]**STRUCK WITH GREAT FORCE**
+Axes.Combat.GI.Struck=**HIT BY GREATER IMPACT**
+Axes.Combat.SS.Struck=[[DARK_RED]]Struck by SKULL SPLITTER!
+Axes.SubSkill.SkullSplitter.Name=Kaukolių skaldytojas
+Axes.SubSkill.SkullSplitter.Description=Deal AoE Damage
+Axes.SubSkill.SkullSplitter.Stat=Skull Splitter Duration
+Axes.SubSkill.CriticalStrikes.Name=Critical Strikes
+Axes.SubSkill.CriticalStrikes.Description=Double Damage
+Axes.SubSkill.CriticalStrikes.Stat=Critical Strike Chance
+Axes.SubSkill.AxeMastery.Name=Axe Mastery
+Axes.SubSkill.AxeMastery.Description=Adds bonus DMG
+Axes.SubSkill.AxesLimitBreak.Name=Axes Limit Break
+Axes.SubSkill.AxesLimitBreak.Description=Breaking your limits. Increased damage against tough opponents. Intended for PVP, up to server settings for whether or not it will boost damage in PVE.
+Axes.SubSkill.AxesLimitBreak.Stat=Limit Break Max DMG
+Axes.SubSkill.ArmorImpact.Name=Armor Impact
+Axes.SubSkill.ArmorImpact.Description=Strike with enough force to shatter armor
+Axes.SubSkill.GreaterImpact.Name=Greater Impact
+Axes.SubSkill.GreaterImpact.Description=Deal bonus damage to unarmored foes
+Axes.Listener=Axes:
+Axes.SkillName=AXES
+SuperAbility.SkullSplitter.Off=**Skull Splitter has worn off**
+SuperAbility.SkullSplitter.On=[[GREEN]]**Skull Splitter ACTIVATED**
+SuperAbility.SkullSplitter.Refresh=[[GREEN]]Your [[YELLOW]]Skull Splitter [[GREEN]]ability is refreshed!
+SuperAbility.SkullSplitter.Other.Off=Skull Splitter[[GREEN]] has worn off for [[YELLOW]]{0}
+SuperAbility.SkullSplitter.Other.On=[[GREEN]]{0}[[DARK_GREEN]] has used [[RED]]Skull Splitter!
+#EXCAVATION
+Excavation.Ability.Lower=[[GRAY]]You lower your shovel.
+Excavation.Ability.Ready=[[DARK_AQUA]]You [[GOLD]]ready[[DARK_AQUA]] your Shovel.
+Excavation.SubSkill.GigaDrillBreaker.Name=Giga Drill Breaker
+Excavation.SubSkill.GigaDrillBreaker.Description=3x Drop Rate, 3x EXP, +Speed
+Excavation.SubSkill.GigaDrillBreaker.Stat=Giga Drill Breaker Duration
+Excavation.SubSkill.Archaeology.Name=Archeologas
+Excavation.SubSkill.Archaeology.Description=Unearth the secrets of the land! High skill levels increase your odds of finding experience orbs when you find treasure!
+Excavation.SubSkill.Archaeology.Stat=Archaeology Experience Orb Chance
+Excavation.SubSkill.Archaeology.Stat.Extra=Archaeology Experience Orb Amount
+Excavation.Listener=Excavation:
+Excavation.SkillName=EXCAVATION
+SuperAbility.GigaDrillBreaker.Off=**Giga Drill Breaker has worn off**
+SuperAbility.GigaDrillBreaker.On=[[GREEN]]**GIGA DRILL BREAKER ACTIVATED**
+SuperAbility.GigaDrillBreaker.Refresh=[[GREEN]]Your [[YELLOW]]Giga Drill Breaker [[GREEN]]ability is refreshed!
+SuperAbility.GigaDrillBreaker.Other.Off=Giga Drill Breaker[[GREEN]] has worn off for [[YELLOW]]{0}
+SuperAbility.GigaDrillBreaker.Other.On=[[GREEN]]{0}[[DARK_GREEN]] has used [[RED]]Giga Drill Breaker!
+#FISHING
+Fishing.ScarcityTip=[[YELLOW]]&oŠioje zonoje nebeliko ką žvejoti, todėl prašome Jūsų žvejoti kitoje vietoje persikeliant: {0} blokus į bet kurįą pusę!
+Fishing.Scared=[[GRAY]]&oGreitai judėdami išgasdinsite žuvis!
+Fishing.Exhausting=[[RED]]&oNaudodami meškerę ne pagal paskirtį ją sulaužysite!
+Fishing.LowResourcesTip=[[GRAY]]Šioje zonoje nebeliko ką žvejoti, todėl prašome Jūsų žvejoti kitoje vietoje persikeliant: {0} blokus į bet kurįą pusę!
+Fishing.Ability.Info=Magiškas žvejys: [[GRAY]] **Kitas rankas: Lobių ieškotojas**
+Fishing.Ability.Locked.0=LOCKED UNTIL {0}+ SKILL (SHAKE)
+Fishing.Ability.Locked.1=LOCKED UNTIL {0}+ SKILL (ICE FISHING)
+Fishing.Ability.Locked.2=LOCKED UNTIL {0}+ SKILL (MASTER ANGLER)
+Fishing.SubSkill.TreasureHunter.Name=Lobių ieškotojas
+Fishing.SubSkill.TreasureHunter.Description=Fish up misc. objects
+Fishing.SubSkill.TreasureHunter.Stat=Lobių ieškotojo rankas: [[GREEN]]{0}[[DARK_AQUA]]/[[GREEN]]{1}
+Fishing.SubSkill.TreasureHunter.Stat.Extra=Drop Rate: [[GRAY]]Common: [[YELLOW]]{0} [[GREEN]]Uncommon: [[YELLOW]]{1}\n[[BLUE]]Rare: [[YELLOW]]{2} [[LIGHT_PURPLE]]Epic: [[YELLOW]]{3} [[GOLD]]Legendary: [[YELLOW]]{4} [[AQUA]]Record: [[YELLOW]]{5}
+Fishing.SubSkill.MagicHunter.Name=Magiškas žvejys
+Fishing.SubSkill.MagicHunter.Description=Find Enchanted Items
+Fishing.SubSkill.MagicHunter.Stat=Magic Hunter Chance
+Fishing.SubSkill.Shake.Name=Shake
+Fishing.SubSkill.Shake.Description=Shake items off of mobs or players w/ fishing pole
+Fishing.SubSkill.Shake.Stat=Shake Chance
+Fishing.SubSkill.FishermansDiet.Name=Fisherman's Diet
+Fishing.SubSkill.FishermansDiet.Description=Improves hunger restored from fished foods
+Fishing.SubSkill.FishermansDiet.Stat=Fisherman's Diet:[[GREEN]] Rank {0}
+Fishing.SubSkill.MasterAngler.Name=Master Angler
+Fishing.SubSkill.MasterAngler.Description=Improves chance of getting a bite while fishing
+Fishing.SubSkill.MasterAngler.Stat=Added Bite Chance at your current location: [[GREEN]]+{0}
+Fishing.SubSkill.IceFishing.Name=Ice Fishing
+Fishing.SubSkill.IceFishing.Description=Allows you to fish in icy biomes
+Fishing.SubSkill.IceFishing.Stat=Ice Fishing
+Fishing.Chance.Raining=[[BLUE]] Rain Bonus
+Fishing.Listener=Fishing:
+Fishing.Ability.TH.MagicFound=[[GRAY]]You feel a touch of magic with this catch...
+Fishing.Ability.TH.Boom=[[GRAY]]BOOM TIME!!!
+Fishing.Ability.TH.Poison=[[GRAY]]Something doesn't smell quite right...
+Fishing.SkillName=FISHING
+#HERBALISM
+Herbalism.Ability.GTe.NeedMore=You need more seeds to spread Green Terra.
+Herbalism.Ability.GTh.Fail=**GREEN THUMB FAIL**
+Herbalism.Ability.GTh=[[GREEN]]**GREEN THUMB**
+Herbalism.Ability.Lower=[[GRAY]]You lower your Hoe.
+Herbalism.Ability.Ready=[[DARK_AQUA]]You [[GOLD]]ready[[DARK_AQUA]] your Hoe.
+Herbalism.Ability.ShroomThumb.Fail=**SHROOM THUMB FAIL**
+Herbalism.SubSkill.GreenTerra.Name=Green Terra
+Herbalism.SubSkill.GreenTerra.Description=Spread the Terra, 3x Drops
+Herbalism.SubSkill.GreenTerra.Stat=Green Terra Duration
+Herbalism.SubSkill.GreenThumb.Name=Green Thumb
+Herbalism.SubSkill.GreenThumb.Description=Auto-Plants crops when harvesting
+Herbalism.SubSkill.GreenThumb.Stat=Green Thumb Chance
+Herbalism.SubSkill.GreenThumb.Stat.Extra=Green Thumb Stage: [[GREEN]] Crops grow in stage {0}
+Herbalism.Effect.4=Green Thumb (Blocks)
+Herbalism.SubSkill.GreenThumb.Description.2=Make bricks mossy, or make grass grow
+Herbalism.SubSkill.FarmersDiet.Name=Farmer's Diet
+Herbalism.SubSkill.FarmersDiet.Description=Improves hunger restored from farmed foods
+Herbalism.SubSkill.FarmersDiet.Stat=Farmer's Diet: [[GREEN]]Rank {0}
+Herbalism.SubSkill.DoubleDrops.Name=Double Drops
+Herbalism.SubSkill.DoubleDrops.Description=Double the normal loot
+Herbalism.SubSkill.DoubleDrops.Stat=Double Drop Chance
+Herbalism.SubSkill.HylianLuck.Name=Hylian Luck
+Herbalism.SubSkill.HylianLuck.Description=Gives a small chance of finding rare items
+Herbalism.SubSkill.HylianLuck.Stat=Hylian Luck Chance
+Herbalism.SubSkill.ShroomThumb.Name=Shroom Thumb
+Herbalism.SubSkill.ShroomThumb.Description=Spread mycelium to dirt & grass
+Herbalism.SubSkill.ShroomThumb.Stat=Shroom Thumb Chance
+Herbalism.HylianLuck=[[GREEN]]The luck of Hyrule is with you today!
+Herbalism.Listener=Herbalism:
+Herbalism.SkillName=HERBALISM
+SuperAbility.GreenTerra.Off=**Green Terra has worn off**
+SuperAbility.GreenTerra.On=[[GREEN]]**GREEN TERRA ACTIVATED**
+SuperAbility.GreenTerra.Refresh=[[GREEN]]Your [[YELLOW]]Green Terra [[GREEN]]ability is refreshed!
+SuperAbility.GreenTerra.Other.Off=Green Terra[[GREEN]] has worn off for [[YELLOW]]{0}
+SuperAbility.GreenTerra.Other.On=[[GREEN]]{0}[[DARK_GREEN]] has used [[RED]]Green Terra!
+#MINING
+Mining.Ability.Locked.0=LOCKED UNTIL {0}+ SKILL (BLAST MINING)
+Mining.Ability.Locked.1=LOCKED UNTIL {0}+ SKILL (BIGGER BOMBS)
+Mining.Ability.Locked.2=LOCKED UNTIL {0}+ SKILL (DEMOLITIONS EXPERTISE)
+Mining.Ability.Lower=[[GRAY]]You lower your Pickaxe.
+Mining.Ability.Ready=[[DARK_AQUA]]You [[GOLD]]ready[[DARK_AQUA]] your pickaxe.
+Mining.SubSkill.SuperBreaker.Name=Super Breaker
+Mining.SubSkill.SuperBreaker.Description=Speed+, Triple Drop Chance
+Mining.SubSkill.SuperBreaker.Stat=Super Breaker Length
+Mining.SubSkill.DoubleDrops.Name=Double Drops
+Mining.SubSkill.DoubleDrops.Description=Double the normal loot
+Mining.SubSkill.DoubleDrops.Stat=Double Drop Chance
+Mining.SubSkill.BlastMining.Name=Blast Mining
+Mining.SubSkill.BlastMining.Description=Bonuses to mining with TNT
+Mining.SubSkill.BlastMining.Stat=Blast Mining:[[GREEN]] Rank {0}/{1} [[GRAY]]({2})
+Mining.SubSkill.BlastMining.Stat.Extra=Blast Radius Increase: [[GREEN]]+{0}
+Mining.SubSkill.BiggerBombs.Name=Bigger Bombs
+Mining.SubSkill.BiggerBombs.Description=Increases TNT explosion radius
+Mining.SubSkill.DemolitionsExpertise.Name=Demolitions Expertise
+Mining.SubSkill.DemolitionsExpertise.Description=Decreases damage from TNT explosions
+Mining.SubSkill.DemolitionsExpertise.Stat=Demolitions Expert Damage Decrease
+
+Mining.Listener=Mining:
+Mining.SkillName=MINING
+SuperAbility.SuperBreaker.Off=**Super Breaker has worn off**
+SuperAbility.SuperBreaker.On=[[GREEN]]**SUPER BREAKER ACTIVATED**
+SuperAbility.SuperBreaker.Other.Off=Super Breaker[[GREEN]] has worn off for [[YELLOW]]{0}
+SuperAbility.SuperBreaker.Other.On=[[GREEN]]{0}[[DARK_GREEN]] has used [[RED]]Super Breaker!
+SuperAbility.SuperBreaker.Refresh=[[GREEN]]Your [[YELLOW]]Super Breaker [[GREEN]]ability is refreshed!
+#Blast Mining
+SuperAbility.BlastMining.Boom=[[GRAY]]**BOOM**
+SuperAbility.BlastMining.Cooldown=
+SuperAbility.BlastMining.Effect=+{0} ore yield, -{1} debris yield, {2}x drops
+SuperAbility.BlastMining.Other.On=[[GREEN]]{0}[[DARK_GREEN]] has used [[RED]]Blast Mining!
+SuperAbility.BlastMining.Refresh=[[GREEN]]Your [[YELLOW]]Blast Mining [[GREEN]]ability is refreshed!
+#REPAIR
+Repair.SubSkill.Repair.Name=Repair
+Repair.SubSkill.Repair.Description=Repair Tools & Armor
+Repair.SubSkill.GoldRepair.Name=Gold Repair ({0}+ SKILL)
+Repair.SubSkill.GoldRepair.Description=Repair Gold Tools & Armor
+Repair.SubSkill.IronRepair.Name=Iron Repair ({0}+ SKILL)
+Repair.SubSkill.IronRepair.Description=Repair Iron Tools & Armor
+Repair.SubSkill.StoneRepair.Name=Stone Repair ({0}+ SKILL)
+Repair.SubSkill.StoneRepair.Description=Repair Stone Tools
+Repair.SubSkill.RepairMastery.Name=Repair Mastery
+Repair.SubSkill.RepairMastery.Description=Increased repair amount
+Repair.SubSkill.RepairMastery.Stat=Repair Mastery: [[GREEN]]Extra {0} durability restored
+Repair.SubSkill.SuperRepair.Name=Super Repair
+Repair.SubSkill.SuperRepair.Description=Double effectiveness
+Repair.SubSkill.SuperRepair.Stat=Super Repair Chance
+Repair.SubSkill.DiamondRepair.Name=Diamond Repair ({0}+ SKILL)
+Repair.SubSkill.DiamondRepair.Description=Repair Diamond Tools & Armor
+Repair.SubSkill.ArcaneForging.Name=Arcane Forging
+Repair.SubSkill.ArcaneForging.Description=Repair magic items
+Repair.SubSkill.ArcaneForging.Stat=Arcane Forging: [[YELLOW]]Rank {0}/{1}
+Repair.SubSkill.ArcaneForging.Stat.Extra=[[DARK_AQUA]]Arcane Forging Odds:[[GRAY]] Success [[GREEN]]{0}[[GRAY]]%, Failure [[RED]]{1}[[GRAY]]%
+Repair.Error=[[DARK_RED]]mcMMO encountered an error attempting to repair this item!
+Repair.Listener.Anvil=[[DARK_RED]]You have placed an anvil, anvils can repair tools and armor.
+Repair.Listener=Repair:
+Repair.SkillName=REPAIR
+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.
+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.StackedItems=[[DARK_RED]]You can't repair stacked items.
+Repair.Pretty.Name=Repair
+#Arcane Forging
+Repair.Arcane.Downgrade=Arcane power has decreased for this item.
+Repair.Arcane.Fail=Arcane power has permanently left the item.
+Repair.Arcane.Lost=You were not skilled enough to keep any enchantments.
+Repair.Arcane.Perfect=[[GREEN]]You have sustained the arcane energies in this item.
+#SALVAGE
+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.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.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!
+Salvage.Skills.Adept.Damaged=[[DARK_RED]]You aren't skilled enough to salvage damaged items.
+Salvage.Skills.Adept.Level=You must be level [[YELLOW]]{0}[[RED]] to salvage [[YELLOW]]{1}
+Salvage.Skills.TooDamaged=[[DARK_RED]]This item is too damaged to be salvaged.
+Salvage.Skills.ArcaneFailed=[[RED]]You were unable to extract the knowledge contained within this item.
+Salvage.Skills.ArcanePartial=[[RED]]You were only able to extract some of the knowledge contained within this item.
+Salvage.Skills.ArcaneSuccess=[[GREEN]]You able to extract all of the knowledge contained within this item!
+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 [[DARK_AQUA]]{0}[[GOLD]] materials from [[YELLOW]]{1}[[GOLD]].
+Salvage.Skills.Lottery.Perfect=[[GREEN]][[BOLD]]Perfect![[RESET]][[GOLD]] You salvaged [[DARK_AQUA]]{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
+Swords.Ability.Lower=[[GRAY]]You lower your sword.
+Swords.Ability.Ready=[[DARK_AQUA]]You [[GOLD]]ready[[DARK_AQUA]] your Sword.
+Swords.Combat.Rupture.Note=[[GRAY]]NOTE: [[YELLOW]]1 Tick happens every 0.5 seconds!
+Swords.Combat.Bleeding.Started=[[DARK_RED]] You're bleeding!
+Swords.Combat.Bleeding.Stopped=[[GRAY]]The bleeding has [[GREEN]]stopped[[GRAY]]!
+Swords.Combat.Bleeding=[[GREEN]]**ENEMY BLEEDING**
+Swords.Combat.Counter.Hit=[[DARK_RED]]Hit with a counter-attack!
+Swords.Combat.Countered=[[GREEN]]**COUNTER-ATTACKED**
+Swords.Combat.SS.Struck=[[DARK_RED]]Struck by SERRATED STRIKES!
+Swords.SubSkill.CounterAttack.Name=Counter Attack
+Swords.SubSkill.CounterAttack.Description=Reflect a portion of damage when attacked!
+Swords.SubSkill.CounterAttack.Stat=Counter Attack Chance
+Swords.SubSkill.SerratedStrikes.Name=Serrated Strikes
+Swords.SubSkill.SerratedStrikes.Description=Deal partial damage in an AOE with a chance to apply Rupture!
+Swords.SubSkill.SerratedStrikes.Stat=Serrated Strikes Length
+Swords.SubSkill.Rupture.Name=Rupture
+Swords.SubSkill.Rupture.Description=Apply a powerful bleed DoT
+Swords.SubSkill.Stab.Name=Stab
+Swords.SubSkill.Stab.Description=Adds bonus damage to your attacks.
+Swords.SubSkill.Stab.Stat=Stab Damage
+Swords.SubSkill.SwordsLimitBreak.Name=Swords Limit Break
+Swords.SubSkill.SwordsLimitBreak.Description=Breaking your limits. Increased damage against tough opponents. Intended for PVP, up to server settings for whether or not it will boost damage in PVE.
+Swords.SubSkill.SwordsLimitBreak.Stat=Limit Break Max DMG
+Swords.SubSkill.Rupture.Stat=Rupture Chance
+Swords.SubSkill.Rupture.Stat.Extra=Rupture: [[GREEN]]{0} ticks [{1} DMG vs Player] [{2} DMG vs Mobs]
+Swords.Effect.4=Serrated Strikes Rupture+
+Swords.Effect.5={0} Tick Rupture
+Swords.Listener=Swords:
+Swords.SkillName=SWORDS
+SuperAbility.SerratedStrikes.Off=**Serrated Strikes has worn off**
+SuperAbility.SerratedStrikes.On=[[GREEN]]**SERRATED STRIKES ACTIVATED**
+SuperAbility.SerratedStrikes.Refresh=[[GREEN]]Your [[YELLOW]]Serrated Strikes [[GREEN]]ability is refreshed!
+SuperAbility.SerratedStrikes.Other.Off=Serrated Strikes[[GREEN]] has worn off for [[YELLOW]]{0}
+SuperAbility.SerratedStrikes.Other.On=[[GREEN]]{0}[[DARK_GREEN]] has used [[RED]]Serrated Strikes!
+#TAMING
+Taming.Ability.Bonus.0=Environmentally Aware
+Taming.Ability.Bonus.1=Wolves avoid danger
+Taming.Ability.Bonus.2=Thick Fur
+Taming.Ability.Bonus.3=1/{0} Damage, Fire Resistance
+Taming.Ability.Bonus.4=Shock Proof
+Taming.Ability.Bonus.5=Explosives do 1/{0} normal damage
+Taming.Ability.Bonus.6=Sharpened Claws
+Taming.Ability.Bonus.7=+{0} Damage
+Taming.Ability.Bonus.8=Fast Food Service
+Taming.Ability.Bonus.9={0} Chance for heal on attack
+Taming.Ability.Bonus.10=Holy Hound
+Taming.Ability.Bonus.11=Regain health when damaged by magic or poison
+Taming.Ability.Locked.0=LOCKED UNTIL {0}+ SKILL (ENVIRONMENTALLY AWARE)
+Taming.Ability.Locked.1=LOCKED UNTIL {0}+ SKILL (THICK FUR)
+Taming.Ability.Locked.2=LOCKED UNTIL {0}+ SKILL (SHOCK PROOF)
+Taming.Ability.Locked.3=LOCKED UNTIL {0}+ SKILL (SHARPENED CLAWS)
+Taming.Ability.Locked.4=LOCKED UNTIL {0}+ SKILL (FAST FOOD SERVICE)
+Taming.Ability.Locked.5=LOCKED UNTIL {0}+ SKILL (HOLY HOUND)
+Taming.Combat.Chance.Gore=Gore Chance
+Taming.SubSkill.BeastLore.Name=Beast Lore
+Taming.SubSkill.BeastLore.Description=Bone-whacking inspects wolves & ocelots
+Taming.SubSkill.ShockProof.Name=Shock Proof
+Taming.SubSkill.ShockProof.Description=Explosive Damage Reduction
+Taming.SubSkill.CallOfTheWild.Name=Call of the Wild
+Taming.SubSkill.CallOfTheWild.Description=Summon an animal to your side
+Taming.SubSkill.CallOfTheWild.Description.2=[[GRAY]]COTW: Crouch and left-click with\n  {0} {1} (Ocelot), {2} {3} (Wolf), {4} {5} (Horse)
+Taming.SubSkill.FastFoodService.Name=Fast Food Service
+Taming.SubSkill.FastFoodService.Description=Chance for wolves to heal on attack
+Taming.SubSkill.HolyHound.Name=Holy Hound
+Taming.SubSkill.HolyHound.Description=Healed by Magic & Poison
+Taming.SubSkill.Gore.Name=Gore
+Taming.SubSkill.Gore.Description=Critical Strike that applies Rupture
+Taming.SubSkill.SharpenedClaws.Name=Sharpened Claws
+Taming.SubSkill.SharpenedClaws.Description=Damage Bonus
+Taming.SubSkill.EnvironmentallyAware.Name=Environmentally Aware
+Taming.SubSkill.EnvironmentallyAware.Description=Cactus/Lava Phobia, Fall DMG Immune
+Taming.SubSkill.ThickFur.Name=Thick Fur
+Taming.SubSkill.ThickFur.Description=DMG Reduction, Fire Resistance
+Taming.SubSkill.Pummel.Name=Pummel
+Taming.SubSkill.Pummel.Description=Your Wolves have a chance of knocking back foes
+Taming.SubSkill.Pummel.TargetMessage=You've been knocked back by a wolf!
+Taming.Listener.Wolf=[[DARK_GRAY]]Your wolf scurries back to you...
+Taming.Listener=Taming:
+Taming.SkillName=TAMING
+Taming.Summon.COTW.Success.WithoutLifespan=[[GREEN]](Call Of The Wild) [[GRAY]]You have summoned a [[GOLD]]{0}[[GRAY]]
+Taming.Summon.COTW.Success.WithLifespan=[[GREEN]](Call Of The Wild) [[GRAY]]You have summoned a [[GOLD]]{0}[[GRAY]] and it has a duration of [[GOLD]]{1}[[GRAY]] seconds.
+Taming.Summon.COTW.Limit=[[GREEN]](Call Of The Wild) [[GRAY]]You can only have [[RED]]{0} [[GRAY]]summoned [[GRAY]]{1} pets at the same time.
+Taming.Summon.COTW.TimeExpired=[[GREEN]](Call Of The Wild) [[GRAY]]Time is up, your [[GOLD]]{0}[[GRAY]] departs.
+Taming.Summon.COTW.BreedingDisallowed=[[GREEN]](Call Of The Wild) [[RED]]You cannot breed a summoned animal.
+Taming.Summon.COTW.NeedMoreItems=[[GREEN]](Call Of The Wild) [[GRAY]]You need [[YELLOW]]{0}[[GRAY]] more [[DARK_AQUA]]{1}[[GRAY]](s)
+Taming.Summon.Name.Format=[[GOLD]](COTW) [[WHITE]]{0}'s {1}
+#UNARMED
+Unarmed.Ability.Bonus.0=Iron Arm Style
+Unarmed.Ability.Bonus.1=+{0} DMG Upgrade
+Unarmed.Ability.IronGrip.Attacker=Your opponent has an iron grip!
+Unarmed.Ability.IronGrip.Defender=[[GREEN]]Your iron grip kept you from being disarmed!
+Unarmed.Ability.Lower=[[GRAY]]You lower your fists.
+Unarmed.Ability.Ready=[[DARK_AQUA]]You [[GOLD]]ready[[DARK_AQUA]] your Fists.
+Unarmed.SubSkill.Berserk.Name=Berserk
+Unarmed.SubSkill.Berserk.Description=+50% DMG, Breaks weak materials
+Unarmed.SubSkill.Berserk.Stat=Berserk Length
+Unarmed.SubSkill.Disarm.Name=Disarm
+Unarmed.SubSkill.Disarm.Description=Drops the foes item held in hand
+Unarmed.SubSkill.Disarm.Stat=Disarm Chance
+Unarmed.SubSkill.UnarmedLimitBreak.Name=Unarmed Limit Break
+Unarmed.SubSkill.UnarmedLimitBreak.Description=Breaking your limits. Increased damage against tough opponents. Intended for PVP, up to server settings for whether or not it will boost damage in PVE.
+Unarmed.SubSkill.UnarmedLimitBreak.Stat=Limit Break Max DMG
+Unarmed.SubSkill.IronArmStyle.Name=Iron Arm Style
+Unarmed.SubSkill.IronArmStyle.Description=Hardens your arm over time
+Unarmed.SubSkill.ArrowDeflect.Name=Arrow Deflect
+Unarmed.SubSkill.ArrowDeflect.Description=Deflect arrows
+Unarmed.SubSkill.ArrowDeflect.Stat=Arrow Deflect Chance
+Unarmed.SubSkill.IronGrip.Name=Iron Grip
+Unarmed.SubSkill.IronGrip.Description=Prevents you from being disarmed
+Unarmed.SubSkill.IronGrip.Stat=Iron Grip Chance
+Unarmed.SubSkill.BlockCracker.Name=Block Cracker
+Unarmed.SubSkill.BlockCracker.Description=Break rock with your fists
+Unarmed.Listener=Unarmed:
+Unarmed.SkillName=UNARMED
+SuperAbility.Berserk.Off=**Berserk has worn off**
+SuperAbility.Berserk.On=[[GREEN]]**BERSERK ACTIVATED**
+SuperAbility.Berserk.Other.Off=Berserk[[GREEN]] has worn off for [[YELLOW]]{0}
+SuperAbility.Berserk.Other.On=[[GREEN]]{0}[[DARK_GREEN]] has used [[RED]]Berserk!
+SuperAbility.Berserk.Refresh=[[GREEN]]Your [[YELLOW]]Berserk [[GREEN]]ability is refreshed!
+#WOODCUTTING
+Woodcutting.Ability.0=Leaf Blower
+Woodcutting.Ability.1=Blow away leaves
+Woodcutting.Ability.Locked.0=LOCKED UNTIL {0}+ SKILL (LEAF BLOWER)
+Woodcutting.SubSkill.TreeFeller.Name=Tree Feller
+Woodcutting.SubSkill.TreeFeller.Description=Make trees explode
+Woodcutting.SubSkill.TreeFeller.Stat=Tree Feller Length
+Woodcutting.SubSkill.LeafBlower.Name=Leaf Blower
+Woodcutting.SubSkill.LeafBlower.Description=Blow Away Leaves
+Woodcutting.SubSkill.HarvestLumber.Name=Harvest Lumber
+Woodcutting.SubSkill.HarvestLumber.Description=Skillfully extract more Lumber
+Woodcutting.SubSkill.HarvestLumber.Stat=Double Drop Chance
+Woodcutting.SubSkill.Splinter.Name=Splinter
+Woodcutting.SubSkill.Splinter.Description=Cut down trees more efficiently.
+Woodcutting.SubSkill.BarkSurgeon.Name=Bark Surgeon
+Woodcutting.SubSkill.BarkSurgeon.Description=Extract useful materials when stripping trees.
+Woodcutting.SubSkill.NaturesBounty.Name=Nature's Bounty
+Woodcutting.SubSkill.NaturesBounty.Description=Gather experience from nature.
+Woodcutting.Listener=Woodcutting:
+Woodcutting.SkillName=WOODCUTTING
+SuperAbility.TreeFeller.Off=**Tree Feller has worn off**
+SuperAbility.TreeFeller.On=[[GREEN]]**TREE FELLER ACTIVATED**
+SuperAbility.TreeFeller.Refresh=[[GREEN]]Your [[YELLOW]]Tree Feller [[GREEN]]ability is refreshed!
+SuperAbility.TreeFeller.Other.Off=Tree Feller[[GREEN]] has worn off for [[YELLOW]]{0}
+SuperAbility.TreeFeller.Other.On=[[GREEN]]{0}[[DARK_GREEN]] has used [[RED]]Tree Feller!
+SuperAbility.TreeFeller.Splinter=YOUR AXE SPLINTERS INTO DOZENS OF PIECES!
+SuperAbility.TreeFeller.Threshold=That tree is too large!
+#ABILITIY
+
+#COMBAT
+Combat.ArrowDeflect=[[WHITE]]**ARROW DEFLECT**
+Combat.BeastLore=[[GREEN]]**BEAST LORE**
+Combat.BeastLoreHealth=[[DARK_AQUA]]Būklė ([[GREEN]]{0}[[DARK_AQUA]]/{1})
+Combat.BeastLoreOwner=[[DARK_AQUA]]Savininkas ([[RED]]{0}[[DARK_AQUA]])
+Combat.BeastLoreHorseSpeed=[[DARK_AQUA]]Horse Movement Speed ([[GREEN]]{0} blocks/s[[DARK_AQUA]])
+Combat.BeastLoreHorseJumpStrength=[[DARK_AQUA]]Horse Jump Strength ([[GREEN]]Max {0} blocks[[DARK_AQUA]])
+Combat.Gore=[[GREEN]]**GORED**
+Combat.StruckByGore=**YOU HAVE BEEN GORED**
+Combat.TargetDazed=Target was [[DARK_RED]]Dazed
+Combat.TouchedFuzzy=[[DARK_RED]]Touched Fuzzy. Felt Dizzy.
+#COMMANDS
+##generic
+mcMMO.Description=[[DARK_AQUA]]Visa informacija apie: [[YELLOW]]mcMMO[[DARK_AQUA]] Projektas:,[[GOLD]]mcMMO yra [[RED]]atvirojo kodo[[GOLD]] RPG modifikacija sukurta 2011 metų Vasario mėn.,[[GOLD]]projekto autorius: [[BLUE]]nossr50[[GOLD]]. Pagrindinė idėja buvo apjungti RPG įgūdžius.,[[DARK_AQUA]]Svarbu:,[[GOLD]] - [[GREEN]]Naudokite [[RED]]/mcmmo help[[GREEN]] norėdami peržiūrėti komandoms,[[GOLD]] - [[GREEN]]Naudokite [[RED]]/SKILLNAME[[GREEN]] norėdami peržiūrėti įgūdžių informaciją,[[DARK_AQUA]]Autoriai:,[[GOLD]] - [[GREEN]]nossr50 [[BLUE]](Creator & Project Lead),[[GOLD]] - [[GREEN]]electronicboy [[BLUE]](Dev),[[GOLD]] - [[GREEN]]kashike [[BLUE]](Dev),[[GOLD]] - [[GREEN]]t00thpick1 [[BLUE]](Classic versijos plėtotojas)
+mcMMO.Description.FormerDevs=[[DARK_AQUA]]Pagrindiniai plėtotojai: [[GREEN]]GJ, NuclearW, bm01, TfT_02, Glitchfinder
+Commands.addlevels.AwardAll.1=[[GREEN]]You were awarded {0} levels in all skills!
+Commands.addlevels.AwardAll.2=All skills have been modified for {0}.
+Commands.addlevels.AwardSkill.1=[[GREEN]]You were awarded {0} levels in {1}!
+Commands.addlevels.AwardSkill.2={0} has been modified for {1}.
+Commands.addxp.AwardAll=[[GREEN]]You were awarded {0} experience in all skills!
+Commands.addxp.AwardSkill=[[GREEN]]You were awarded {0} experience in {1}!
+Commands.Ability.Off=Ability use toggled [[RED]]off
+Commands.Ability.On=Ability use toggled [[GREEN]]on
+Commands.Ability.Toggle=Ability use has been toggled for [[YELLOW]]{0}
+Commands.AdminChat.Off=Admin Chat only [[RED]]Off
+Commands.AdminChat.On=Admin Chat only [[GREEN]]On
+Commands.AdminToggle=[[GREEN]]- Toggle admin chat
+Commands.Chat.Console=*Console*
+Commands.Cooldowns.Header=[[GOLD]]--= [[GREEN]]mcMMO Ability Cooldowns[[GOLD]] =--
+Commands.Cooldowns.Row.N=\  [[RED]]{0}[[WHITE]] - [[GOLD]]{1} seconds left
+Commands.Cooldowns.Row.Y=\  [[AQUA]]{0}[[WHITE]] - [[DARK_GREEN]]Ready!
+Commands.Database.CooldownMS=You must wait {0} milliseconds before using this command again.
+Commands.Database.Processing=Your previous command is still being processed. Please wait.
+Commands.Disabled=Apgailestaujame, tačiau ši komanda yra išjungta!
+Commands.DoesNotExist= [[RED]]Apgailestaujame, tačiau tokio žaidėjų serverio duomenų bazėje nėra!
+Commands.GodMode.Disabled=mcMMO Nemirtingumas Išjungtas
+Commands.GodMode.Enabled=mcMMO Nemirtingumas Įjungtas
+Commands.AdminChatSpy.Enabled=mcMMO Party Chat Spy Enabled
+Commands.AdminChatSpy.Disabled=mcMMO Party Chat Spy Disabled
+Commands.AdminChatSpy.Toggle=mcMMO Party Chat has been toggled for [[YELLOW]]{0}
+Commands.AdminChatSpy.Chat=[[GOLD]][SPY: [[GREEN]]{0}[[GOLD]]] [[WHITE]]{1}
+Commands.GodMode.Forbidden=[mcMMO] God Mode not permitted on this world (See Permissions)
+Commands.GodMode.Toggle=Nemirtingumo rėžimas nustatytas: [[YELLOW]]{0}
+Commands.Healthbars.Changed.HEARTS=[mcMMO] Your healthbar display type was changed to [[RED]]Hearts[[WHITE]].
+Commands.Healthbars.Changed.BAR=[mcMMO] Your healthbar display type was changed to [[YELLOW]]Boxes[[WHITE]].
+Commands.Healthbars.Changed.DISABLED=[mcMMO] Your mob healthbars have been [[GRAY]]disabled[[WHITE]].
+Commands.Healthbars.Invalid=Invalid healthbar type!
+Commands.Inspect=<player> [[GREEN]]- Peržiūrėti detalią žaidėjo informaciją
+Commands.Invite.Success=[[GREEN]]Pakvietimas sėkmingai išsiustas.
+Commands.Leaderboards=<skill> <page> [[GREEN]]- Leaderboards
+Commands.mcgod=[[GREEN]]- Nemirtingumo valdymas
+Commands.mchud.Invalid=That is not a valid HUD type.
+Commands.mcpurge.Success=[[GREEN]]The database was successfully purged!
+Commands.mcrank.Heading=[[GOLD]]-=ASMENINIAI ĮGŪDŽIAI=-
+Commands.mcrank.Overall=Overall[[GREEN]] - [[GOLD]]Rank [[WHITE]]#[[GREEN]]{0}
+Commands.mcrank.Player=[[YELLOW]]Žaidėjo įgūdžių rankas: [[WHITE]]{0}
+Commands.mcrank.Skill=[[YELLOW]]{0}[[GREEN]] - [[GOLD]]Įgūdžių Rankas [[WHITE]]#[[GREEN]]{1}
+Commands.mcrank.Unranked=[[WHITE]]Neturintis įgūdžių ranko!
+Commands.mcrefresh.Success={0}''s cooldowns have been refreshed.
+Commands.mcremove.Success=[[GREEN]]{0} was successfully removed from the database!
+Commands.mctop.Tip=[[GOLD]]Tip: Use [[RED]]/mcrank[[GOLD]] to view all of your personal rankings!
+Commands.mmoedit=[player] <skill> <newvalue> [[GREEN]] - Modify target
+Commands.mmoedit.AllSkills.1=[[GREEN]]Your level in all skills was set to {0}!
+Commands.mmoedit.Modified.1=[[GREEN]]Your level in {0} was set to {1}!
+Commands.mmoedit.Modified.2={0} has been modified for {1}.
+Commands.mcconvert.Database.Same=You are already using the {0} database!
+Commands.mcconvert.Database.InvalidType={0} nustatytas netinkamas duomenų tipas.
+Commands.mcconvert.Database.Start=[[GRAY]]Starting conversion from {0} to {1}...
+Commands.mcconvert.Database.Finish=[[GRAY]]Database migration complete; the {1} database now has all data from the {0} database.
+Commands.mmoshowdb=The currently used database is [[GREEN]]{0}
+Commands.mcconvert.Experience.Invalid=Nežinomas formulės tipas! Galimi tipai yra: [[GREEN]]LINEAR [[RED]]and [[GREEN]]EXPONENTIAL.
+Commands.mcconvert.Experience.Same=Already using formula type {0}
+Commands.mcconvert.Experience.Start=[[GRAY]]Starting conversion from {0} to {1} curve
+Commands.mcconvert.Experience.Finish=[[GRAY]]Formula conversion complete; now using {0} XP curve.
+Commands.ModDescription=[[GREEN]]- Read brief mod description
+Commands.NoConsole=Ši komanda negali būti naudojama konsolės rėžime!
+Commands.Notifications.Off=Ability notifications toggled [[RED]]off
+Commands.Notifications.On=Ability notifications toggled [[GREEN]]on
+Commands.Offline=This command does not work for offline players.
+Commands.NotLoaded=Žaidėjo profilis dar nepakrautas!
+Commands.Party.Status=[[DARK_GRAY]]NAME: [[WHITE]]{0} {1} [[DARK_GRAY]]LEVEL: [[DARK_AQUA]]{2}
+Commands.Party.Status.Alliance=[[DARK_GRAY]]ALLY: [[WHITE]]{0}
+Commands.Party.UnlockedFeatures=[[DARK_GRAY]]Unlocked Features: [[GRAY]][[ITALIC]]{0}
+Commands.Party.ShareMode=[[DARK_GRAY]]SHARE MODE:
+Commands.Party.ItemShare=[[GRAY]]ITEM [[DARK_AQUA]]({0})
+Commands.Party.ExpShare=[[GRAY]]EXP [[DARK_AQUA]]({0})
+Commands.Party.ItemShareCategories=[[DARK_GRAY]]Sharing Items: [[GRAY]][[ITALIC]]{0}
+Commands.Party.MembersNear=[[DARK_GRAY]]NEAR YOU [[DARK_AQUA]]{0}[[DARK_GRAY]]/[[DARK_AQUA]]{1}
+Commands.Party.Accept=[[GREEN]]- Accept party invite
+Commands.Party.Chat.Off=Party Chat only [[RED]]Off
+Commands.Party.Chat.On=Party Chat only [[GREEN]]On
+Commands.Party.Commands=[[RED]]---[][[GREEN]]PARTY COMMANDS[[RED]][]---
+Commands.Party.Invite.0=[[RED]]ALERT: [[GREEN]]You have received a party invite for {0} from {1}
+Commands.Party.Invite.1=[[YELLOW]]Type [[GREEN]]/party accept[[YELLOW]] to accept the invite
+Commands.Party.Invite=[[GREEN]]- Send party invite
+Commands.Party.Invite.Accepted=[[GREEN]]Invite Accepted. You have joined party {0}
+Commands.Party.Join=[[GRAY]]Joined Party: {0}
+Commands.Party.PartyFull=[[GOLD]]{0}[[RED]] is full!
+Commands.Party.PartyFull.Invite=You cannot invite [[YELLOW]]{0}[[RED]] to [[GREEN]]{1}[[RED]] because it already has [[DARK_AQUA]]{2}[[RED]] players in it!
+Commands.Party.PartyFull.InviteAccept=You cannot join [[GREEN]]{0}[[RED]] because it already has [[DARK_AQUA]]{1}[[RED]] players in it!
+Commands.Party.Create=[[GRAY]]Created Party: {0}
+Commands.Party.Rename=[[GRAY]]Party name changed to: [[WHITE]]{0}
+Commands.Party.SetSharing=[[GRAY]]Party {0} sharing set to: [[DARK_AQUA]]{1}
+Commands.Party.ToggleShareCategory=[[GRAY]]Party item sharing for [[GOLD]]{0} [[GRAY]]has been [[DARK_AQUA]]{1}
+Commands.Party.AlreadyExists=[[DARK_RED]]Party {0} already exists!
+Commands.Party.Kick=[[RED]]You were kicked from party [[GREEN]]{0}[[RED]]!
+Commands.Party.Leave=[[YELLOW]]You have left that party
+Commands.Party.Members.Header=[[RED]]-----[][[GREEN]]MEMBERS[[RED]][]-----
+Commands.Party.None=[[RED]]You are not in a party.
+Commands.Party.Quit=[[GREEN]]- Leave your current party
+Commands.Party.Teleport=[[GREEN]]- Teleport to party member
+Commands.Party.Toggle=[[GREEN]]- Toggle Party Chat
+Commands.Party1=[[GREEN]]- Create a new party
+Commands.Party2=[[GREEN]]- Join a players party
+Commands.Party.Alliance.Header=[[RED]]-----[][[GREEN]]PARTY ALLIANCE[[RED]][]-----
+Commands.Party.Alliance.Ally=[[WHITE]]{0} [[DARK_GRAY]]IS ALLIED WITH: [[WHITE]]{1}
+Commands.Party.Alliance.Members.Header=[[RED]]-----[][[GREEN]]ALLIANCE MEMBERS[[RED]][]-----
+Commands.Party.Alliance.Invite.0=ALERT: [[GREEN]]You have received a party alliance invite for {0} from {1}
+Commands.Party.Alliance.Invite.1=Type [[GREEN]]/party alliance accept[[YELLOW]] to accept the invite
+Commands.Party.Alliance.Invite.Accepted=[[GREEN]]Alliance invite Accepted.
+Commands.Party.Alliance.None=[[RED]]Your party does not have an ally.
+Commands.Party.Alliance.AlreadyAllies=[[RED]]Your party already has an ally. Disband with [[DARK_AQUA]]/party alliance disband
+Commands.Party.Alliance.Help.0=[[RED]]This party hasn't formed an alliance. Invite a party leader
+Commands.Party.Alliance.Help.1=[[RED]] to an alliance with [[DARK_AQUA]]/party alliance invite <player>[[RED]].
+Commands.ptp.Enabled=Party teleporting [[GREEN]]enabled
+Commands.ptp.Disabled=Party teleporting [[RED]]disabled
+Commands.ptp.NoRequests=[[RED]]You have no teleport requests at this time
+Commands.ptp.NoWorldPermissions=[[RED]][mcMMO] You do not have permission to teleport to the world {0}.
+Commands.ptp.Request1=[[YELLOW]]{0} [[GREEN]]has requested to teleport to you.
+Commands.ptp.Request2=[[GREEN]]To teleport, type [[YELLOW]]/ptp accept[[GREEN]]. Request expires in [[RED]]{0} [[GREEN]]seconds.
+Commands.ptp.AcceptAny.Enabled=Party teleport request confirmation [[GREEN]]enabled
+Commands.ptp.AcceptAny.Disabled=Party teleport request confirmation [[RED]]disabled
+Commands.ptp.RequestExpired=[[RED]]Party teleport request has expired!
+Commands.PowerLevel.Leaderboard=[[YELLOW]]--mcMMO[[BLUE]] Power Level [[YELLOW]]Leaderboard--
+Commands.PowerLevel.Capped=[[DARK_RED]]POWER LEVEL: [[GREEN]]{0} [[DARK_RED]]MAX LEVEL: [[YELLOW]]{1}
+Commands.PowerLevel=[[DARK_RED]]POWER LEVEL: [[GREEN]]{0}
+Commands.Reset.All=[[GREEN]]All of your skill levels have been reset successfully.
+Commands.Reset.Single=[[GREEN]]Your {0} skill level has been reset successfully.
+Commands.Reset=[[GREEN]]- Reset a skill's level to 0
+Commands.Scoreboard.Clear=[[DARK_AQUA]]mcMMO scoreboard cleared.
+Commands.Scoreboard.NoBoard=[[RED]]The mcMMO scoreboard is not active.
+Commands.Scoreboard.Keep=[[DARK_AQUA]]The mcMMO scoreboard will stay up until you use [[GREEN]]/mcscoreboard clear[[DARK_AQUA]].
+Commands.Scoreboard.Timer=[[DARK_AQUA]]The mcMMO scoreboard will clear [[GOLD]]{0}[[DARK_AQUA]] seconds from now.
+Commands.Scoreboard.Help.0=[[GOLD]] == [[GREEN]]Help for [[RED]]/mcscoreboard[[GOLD]] ==
+Commands.Scoreboard.Help.1=[[DARK_AQUA]]/mcscoreboard[[AQUA]] clear [[WHITE]] - clear the McMMO scoreboard
+Commands.Scoreboard.Help.2=[[DARK_AQUA]]/mcscoreboard[[AQUA]] keep [[WHITE]] - keep the mcMMO scoreboard up
+Commands.Scoreboard.Help.3=[[DARK_AQUA]]/mcscoreboard[[AQUA]] time [n] [[WHITE]] - clear the McMMO scoreboard after [[LIGHT_PURPLE]]n[[WHITE]] seconds
+Commands.Scoreboard.Tip.Keep=[[GOLD]]Tip: Use [[RED]]/mcscoreboard keep[[GOLD]] while the scoreboard is shown to keep it from going away.
+Commands.Scoreboard.Tip.Clear=[[GOLD]]Tip: Use [[RED]]/mcscoreboard clear[[GOLD]] to get rid of the scoreboard.
+Commands.Skill.Invalid=That is not a valid skillname!
+Commands.Skill.ChildSkill=Child skills are not valid for this command!
+Commands.Skill.Leaderboard=--mcMMO [[BLUE]]{0}[[YELLOW]] Lyderiai--
+Commands.SkillInfo=[[GREEN]]- Peržiūrėsite detalią informaciją apie įgūdžius
+Commands.Stats=[[GREEN]]- Peržiūrėti mcMMO Informaciją
+Commands.ToggleAbility=[[GREEN]]- Toggle ability activation with right click
+Commands.Usage.0=[[RED]]Teisingas naudojimas: /{0}
+Commands.Usage.1=[[RED]]Teisingas naudojimas: /{0} {1}
+Commands.Usage.2=[[RED]]Teisingas naudojimas: /{0} {1} {2}
+Commands.Usage.3=[[RED]]Teisingas naudojimas: /{0} {1} {2} {3}
+Commands.Usage.FullClassName=classname
+Commands.Usage.Level=level
+Commands.Usage.Message=message
+Commands.Usage.Page=page
+Commands.Usage.PartyName=name
+Commands.Usage.Password=password
+Commands.Usage.Player=player
+Commands.Usage.Rate=rate
+Commands.Usage.Skill=skill
+Commands.Usage.SubSkill=subskill
+Commands.Usage.XP=xp
+Commands.Description.mmoinfo=Read details about a skill or mechanic.
+Commands.MmoInfo.Mystery=[[GRAY]]You haven't unlocked this skill yet, but when you do you will be able to read details about it here!
+Commands.MmoInfo.NoMatch=That subskill doesn't exist!
+Commands.MmoInfo.Header=[[DARK_AQUA]]-=[]=====[][[GOLD]] MMO Info [[DARK_AQUA]][]=====[]=-
+Commands.MmoInfo.SubSkillHeader=[[GOLD]]Name:[[YELLOW]] {0}
+Commands.MmoInfo.DetailsHeader=[[DARK_AQUA]]-=[]=====[][[GREEN]] Details [[DARK_AQUA]][]=====[]=-
+Commands.MmoInfo.OldSkill=[[GRAY]]mcMMO skills are being converted into an improved modular skill system, unfortunately this skill has not been converted yet and lacks detailed stats. The new system will allow for faster release times for new mcMMO skills and greater flexibility with existing skills.
+Commands.MmoInfo.Mechanics=[[DARK_AQUA]]-=[]=====[][[GOLD]] Mechanics [[DARK_AQUA]][]=====[]=-
+Commands.MmoInfo.Stats=INFORMACIJA: {0}
+Commands.Mmodebug.Toggle=mcMMO Debug Mode is now [[GOLD]]{0}[[GRAY]], use this command again to toggle. With debug mode true, you can punch blocks to print useful information used for support.
+mcMMO.NoInvites=[[RED]]Šiuo metu Jūs neturite jokio pakvietimo!
+mcMMO.NoPermission=[[DARK_RED]]Apgailestaujame, tačiau tam Jūs neturite atitinkamų leidimų!
+mcMMO.NoSkillNote=[[DARK_GRAY]]If you don't have access to a skill it will not be shown here.
+##party
+Party.Forbidden=[mcMMO] Parties not permitted on this world (See Permissions)
+Party.Help.0=[[RED]]Teisingas naudojimas: [[DARK_AQUA]]{0} <player> [password].
+Party.Help.1=[[RED]]To create a party, use [[DARK_AQUA]]{0} <name> [password].
+Party.Help.2=[[RED]]Consult [[DARK_AQUA]]{0} [[RED]]for more information
+Party.Help.3=[[RED]]Use [[DARK_AQUA]]{0} <player> [password] [[RED]]to join or [[DARK_AQUA]]{1} [[RED]]to quit
+Party.Help.4=[[RED]]To lock or unlock your party, use [[DARK_AQUA]]{0}
+Party.Help.5=[[RED]]To password protect your party, use [[DARK_AQUA]]{0} <password>
+Party.Help.6=[[RED]]To kick a player from your party, use [[DARK_AQUA]]{0} <player>
+Party.Help.7=[[RED]]To transfer ownership of your party, use [[DARK_AQUA]]{0} <player>
+Party.Help.8=[[RED]]To disband your party, use [[DARK_AQUA]]{0}
+Party.Help.9=[[RED]]Use [[DARK_AQUA]]{0} [[RED]]to share items with party members
+Party.Help.10=[[RED]]Use [[DARK_AQUA]]{0} [[RED]]to enable XP sharing with party members
+Party.InformedOnJoin={0} [[GREEN]]has joined your party
+Party.InformedOnQuit={0} [[GREEN]]has left your party
+Party.InformedOnNameChange=[[GOLD]]{0} [[GREEN]]has set the party name to [[WHITE]]{1}
+Party.InvalidName=[[DARK_RED]]That is not a valid party name.
+Party.Invite.Self=[[RED]]You can't invite yourself!
+Party.IsLocked=[[RED]]This party is already locked!
+Party.IsntLocked=[[RED]]This party is not locked!
+Party.Locked=[[RED]]Party is locked, only party leader may invite.
+Party.NotInYourParty=[[DARK_RED]]{0} is not in your party
+Party.NotOwner=[[DARK_RED]]You are not the party leader.
+Party.Target.NotOwner=[[DARK_RED]]{0} is not the party leader.
+Party.Owner.New=[[GREEN]]{0} is the new party leader.
+Party.Owner.NotLeader=[[DARK_RED]]You are no longer the party leader.
+Party.Owner.Player =[[GREEN]]You are now the party leader.
+Party.Password.None=[[RED]]This party is password protected. Please provide a password to join.
+Party.Password.Incorrect=[[RED]]Party password is incorrect.
+Party.Password.Set=[[GREEN]]Party password set to {0}
+Party.Password.Removed=[[GREEN]]Party password has been cleared.
+Party.Player.Invalid=[[RED]]That is not a valid player.
+Party.NotOnline=[[DARK_RED]]{0} is not online!
+Party.Player.InSameParty=[[RED]]{0} already is in your party!
+Party.PlayerNotInParty=[[DARK_RED]]{0} is not in a party
+Party.Specify=[[RED]]You must specify a party.
+Party.Teleport.Dead=[[RED]]You can't teleport to a dead player.
+Party.Teleport.Hurt=[[RED]]You have been hurt in the last {0} seconds and cannot teleport.
+Party.Teleport.Player=[[GREEN]]You have teleported to {0}.
+Party.Teleport.Self=[[RED]]You can't teleport to yourself!
+Party.Teleport.Target=[[GREEN]]{0} has teleported to you.
+Party.Teleport.Disabled=[[RED]]{0} doesn't allow party teleportation.
+Party.Rename.Same=[[RED]]That is already the name of your party!
+Party.Join.Self=[[RED]]You can't join yourself!
+Party.Unlocked=[[GRAY]]Party is unlocked
+Party.Disband=[[GRAY]]The party has been disbanded
+Party.Alliance.Formed=[[GRAY]]Your party is now allies with [[GREEN]]{0}
+Party.Alliance.Disband=[[GRAY]]Your party is no longer allies with [[RED]]{0}
+Party.Status.Locked=[[DARK_RED]](INVITE-ONLY)
+Party.Status.Unlocked=[[DARK_GREEN]](OPEN)
+Party.LevelUp=[[YELLOW]]Party level increased by {0}. Total ({1})
+Party.Feature.Chat=Party Chat
+Party.Feature.Teleport=Party Teleport
+Party.Feature.Alliance=Alliances
+Party.Feature.ItemShare=Item Sharing
+Party.Feature.XpShare=XP Sharing
+Party.Feature.Locked.Chat=LOCKED UNTIL {0}+ (PARTY CHAT)
+Party.Feature.Locked.Teleport=LOCKED UNTIL {0}+ (PARTY TELEPORT)
+Party.Feature.Locked.Alliance=LOCKED UNTIL {0}+ (ALLIANCES)
+Party.Feature.Locked.ItemShare=LOCKED UNTIL {0}+ (ITEM SHARING)
+Party.Feature.Locked.XpShare=LOCKED UNTIL {0}+ (XP SHARING)
+Party.Feature.Disabled.1=[[RED]]Party chat is not unlocked yet.
+Party.Feature.Disabled.2=[[RED]]Party teleport is not unlocked yet.
+Party.Feature.Disabled.3=[[RED]]Party alliances are not unlocked yet.
+Party.Feature.Disabled.4=[[RED]]Party item sharing is not unlocked yet.
+Party.Feature.Disabled.5=[[RED]]Party XP sharing is not unlocked yet.
+Party.ShareType.Xp=XP
+Party.ShareType.Item=ITEM
+Party.ShareMode.None=NONE
+Party.ShareMode.Equal=EQUAL
+Party.ShareMode.Random=RANDOM
+Party.ItemShare.Category.Loot=Loot
+Party.ItemShare.Category.Mining=Mining
+Party.ItemShare.Category.Herbalism=Herbalism
+Party.ItemShare.Category.Woodcutting=Woodcutting
+Party.ItemShare.Category.Misc=Misc
+##xp
+Commands.XPGain.Acrobatics=Falling
+Commands.XPGain.Alchemy=Brewing Potions
+Commands.XPGain.Archery=Attacking Monsters
+Commands.XPGain.Axes=Attacking Monsters
+Commands.XPGain.Child=Gains levels from Parent Skills
+Commands.XPGain.Excavation=Digging and finding treasures
+Commands.XPGain.Fishing=Fishing (Go figure!)
+Commands.XPGain.Herbalism=Harvesting Herbs
+Commands.XPGain.Mining=Mining Stone & Ore
+Commands.XPGain.Repair=Repairing
+Commands.XPGain.Swords=Attacking Monsters
+Commands.XPGain.Taming=Animal Taming, or combat w/ your wolves
+Commands.XPGain.Unarmed=Attacking Monsters
+Commands.XPGain.Woodcutting=Chopping down trees
+Commands.XPGain=[[DARK_GRAY]]XP GAIN: [[WHITE]]{0}
+Commands.xplock.locked=[[GOLD]]Your XP BAR is now locked to {0}!
+Commands.xplock.unlocked=[[GOLD]]Your XP BAR is now [[GREEN]]UNLOCKED[[GOLD]]!
+Commands.xprate.modified=[[RED]]The XP RATE was modified to {0}
+Commands.xprate.over=[[RED]]mcMMO XP Rate Event is OVER!!
+Commands.xprate.proper.0=[[RED]]Proper usage to change the XP rate is /xprate <integer> <true/false>
+Commands.xprate.proper.1=[[RED]]Proper usage to restore the XP rate to default is /xprate reset
+Commands.xprate.proper.2=[[RED]]Please specify true or false to indicate if this is an xp event or not
+Commands.NegativeNumberWarn=Don't use negative numbers!
+Commands.Event.Start=[[GREEN]]mcMMO[[GOLD]] Event!
+Commands.Event.Stop=[[GREEN]]mcMMO[[DARK_AQUA]] Event Over!
+Commands.Event.Stop.Subtitle=[[GREEN]]I hope you had fun!
+Commands.Event.XP=[[DARK_AQUA]]XP Rate is now [[GOLD]]{0}[[DARK_AQUA]]x
+Commands.xprate.started.0=[[GOLD]]XP EVENT FOR mcMMO HAS STARTED!
+Commands.xprate.started.1=[[GOLD]]mcMMO XP RATE IS NOW {0}x!
+
+# Admin Notifications
+Server.ConsoleName=[[YELLOW]][Server]
+Notifications.Admin.XPRate.Start.Self=[[GRAY]]You have set the global XP rate multiplier to [[GOLD]]{0}x
+Notifications.Admin.XPRate.End.Self=[[GRAY]]You ended the XP rate event.
+Notifications.Admin.XPRate.End.Others={0} [[GRAY]]has ended the XP rate event
+Notifications.Admin.XPRate.Start.Others={0} [[GRAY]]has started or modified an XP rate event with global multiplier {1}x
+Notifications.Admin.Format.Others=[[GOLD]]([[GREEN]]mcMMO [[DARK_AQUA]]Admin[[GOLD]]) [[GRAY]]{0}
+Notifications.Admin.Format.Self=[[GOLD]]([[GREEN]]mcMMO[[GOLD]]) [[GRAY]]{0}
+
+# Event
+XPRate.Event=[[GOLD]]mcMMO is currently in an XP rate event! XP rate is {0}x!
+
+#GUIDES
+Guides.Available=[[GRAY]]Guide for {0} available - type /{1} ? [page]
+Guides.Header=[[GOLD]]-=[[GREEN]]{0} Guide[[GOLD]]=-
+Guides.Page.Invalid=Not a valid page number!
+Guides.Page.OutOfRange=That page does not exist, there are only {0} total pages.
+Guides.Usage= Usage is /{0} ? [page]
+##Acrobatics
+Guides.Acrobatics.Section.0=[[DARK_AQUA]]About Acrobatics:\n[[YELLOW]]Acrobatics is the art of moving Gracefuly in mcMMO.\n[[YELLOW]]It provides combat bonuses and environment damage bonuses.\n\n[[DARK_AQUA]]XP GAIN:\n[[YELLOW]]To gain XP in this skill you need to perform a dodge\n[[YELLOW]]in combat or survive falls from heights that damage you.
+Guides.Acrobatics.Section.1=[[DARK_AQUA]]How does Rolling work?\n[[YELLOW]]You have a passive chance when you take fall damage\n[[YELLOW]]to negate the damage done. You can hold the sneak button to\n[[YELLOW]]double your chances during the fall.\n[[YELLOW]]This triggers a Graceful Roll instead of a standard one.\n[[YELLOW]]Graceful Rolls are like regular rolls but are twice as likely to\n[[YELLOW]]occur and provide more damage safety than regular rolls.\n[[YELLOW]]Rolling chance is tied to your skill level
+Guides.Acrobatics.Section.2=[[DARK_AQUA]]How does Dodge work?\n[[YELLOW]]Dodge is a passive chance when you are\n[[YELLOW]]injured in combat to halve the damage taken.\n[[YELLOW]]It is tied to your skill level.
+##Alchemy
+Guides.Alchemy.Section.0=[[DARK_AQUA]]About Alchemy:\n[[YELLOW]]Alchemy is about brewing potions.\n[[YELLOW]]It provides a speed increase in the potion brew time, as well\n[[YELLOW]]as the addition of new (previously) unobtainable potions.\n\n\n[[DARK_AQUA]]XP GAIN:\n[[YELLOW]]To gain XP in this skill you need to brew potions.
+Guides.Alchemy.Section.1=[[DARK_AQUA]]How does Catalysis work?\n[[YELLOW]]Catalysis speeds of the brewing process, with a\n[[YELLOW]]max speed of 4x at level 1000.\n[[YELLOW]]This ability is unlocked at level 100 by default.
+Guides.Alchemy.Section.2=[[DARK_AQUA]]How does Concoctions work?\n[[YELLOW]]Concoctions allows brewing of more potions with custom ingredients.\n[[YELLOW]]Which special ingredients are unlocked is determined\n[[YELLOW]]by your Rank. There are 8 ranks to unlock.
+Guides.Alchemy.Section.3=[[DARK_AQUA]]Concoctions tier 1 ingredients:\n[[YELLOW]]Blaze Powder, Fermented Spider Eye, Ghast Tear, Redstone,\n[[YELLOW]]Glowstone Dust, Sugar, Glistering Melon, Golden Carrot,\n[[YELLOW]]Magma Cream, Nether Wart, Spider Eye, Suplhur, Water Lily,\n[[YELLOW]]Pufferfish\n[[YELLOW]](Vanilla Potions)
+Guides.Alchemy.Section.4=[[DARK_AQUA]]Concoctions tier 2 ingredients:\n[[YELLOW]]Carrot (Potion of Haste)\n[[YELLOW]]Slimeball (Potion of Dullness)\n\n[[DARK_AQUA]]Concoctions tier 3 ingredients:\n[[YELLOW]]Quartz (Potion of Absorption)\n[[YELLOW]]Red Mushroom (Potion of Leaping)
+Guides.Alchemy.Section.5=[[DARK_AQUA]]Concoctions tier 4 ingredients:\n[[YELLOW]]Apple (Potion of Health Boost)\n[[YELLOW]]Rotten Flesh (Potion of Hunger)\n\n[[DARK_AQUA]]Concoctions tier 5 ingredients:\n[[YELLOW]]Brown Mushroom (Potion of Nausea)\n[[YELLOW]]Ink Sack (Potion of Blindness)
+Guides.Alchemy.Section.6=[[DARK_AQUA]]Concoctions tier 6 ingredients:\n[[YELLOW]]Fern (Potion of Saturation)\n\n[[DARK_AQUA]]Concoctions tier 7 ingredients:\n[[YELLOW]]Poisonous Potato (Potion of Decay)\n\n[[DARK_AQUA]]Concoctions tier 8 ingredients:\n[[YELLOW]]Regular Golden Apple (Potion of Resistance)
+##Archery
+Guides.Archery.Section.0=[[DARK_AQUA]]About Archery:\n[[YELLOW]]Archery is about shooting with your bow and arrow.\n[[YELLOW]]It provides various combat bonuses, such as a damage boost\n[[YELLOW]]that scales with your level and the ability to daze your\n[[YELLOW]]opponents in PvP. In addition to this, you can retrieve\n[[YELLOW]]some of your spent arrows from the corpses of your foes.\n\n\n[[DARK_AQUA]]XP GAIN:\n[[YELLOW]]To gain XP in this skill you need to shoot mobs or\n[[YELLOW]]other players.
+Guides.Archery.Section.1=[[DARK_AQUA]]How does Skill Shot work?\n[[YELLOW]]Skill Shot provides additional damage to your shots.\n[[YELLOW]]The bonus damage from Skill Shot increases as you\n[[YELLOW]]level in Archery.\n[[YELLOW]]With the default settings, your archery damage increases 10%\n[[YELLOW]]every 50 levels, to a maximum of 200% bonus damage.
+Guides.Archery.Section.2=[[DARK_AQUA]]How does Daze work?\n[[YELLOW]]You have a passive chance to daze other players when\n[[YELLOW]]you shoot them. When Daze triggers it forces your opponents\n[[YELLOW]]to look straight up for a short duration.\n[[YELLOW]]A Daze shot also deals an additional 4 damage (2 hearts).
+Guides.Archery.Section.3=[[DARK_AQUA]]How does Arrow Retrieval work?\n[[YELLOW]]You have a passive chance to retrieve some of your arrows\n[[YELLOW]]when you kill a mob with your bow.\n[[YELLOW]]This chance increases as you level in Archery.\n[[YELLOW]]By default, this ability increases by 0.1% per level, up to 100%\n[[YELLOW]]at level 1000.
+##Axes
+Guides.Axes.Section.0=[[DARK_AQUA]]About Axes:\n[[YELLOW]]With the Axes skill you can use your axe for much more then\n[[YELLOW]]just deforesting! You can hack and chop away at mobs\n[[YELLOW]]and players to gain XP, hitting mobs with the effect of\n[[YELLOW]]knockback and inflicting DEADLY criticals on mobs and players.\n[[YELLOW]]Your axe also becomes a hand-held woodchipper,\n[[YELLOW]]breaking down the enemy's armor with ease as your level\n[[YELLOW]]increases.\n[[DARK_AQUA]]XP GAIN:\n[[YELLOW]]To gain XP in this skill you need hit other mobs or players\n[[YELLOW]]with an Axe.
+Guides.Axes.Section.1=[[DARK_AQUA]]How does Skull Splitter work?\n[[YELLOW]]This ability allows you to deal an AoE (Area of Effect) hit.\n[[YELLOW]]This AoE hit will deal half as much damage as you did to the\n[[YELLOW]]main target, so it's great for clearing out large piles of mobs.
+Guides.Axes.Section.2=[[DARK_AQUA]]How does Critical Strikes work?\n[[YELLOW]]Critical Strikes is a passive ability which gives players a\n[[YELLOW]]chance to deal additional damage.\n[[YELLOW]]With the default settings, every 2 skill levels in Axes awards a\n[[YELLOW]]0.1% chance to deal a Critical Strike, causing 2.0 times damage\n[[YELLOW]]to mobs or 1.5 times damage against other players.
+Guides.Axes.Section.3=[[DARK_AQUA]]How does Axe Mastery work?\n[[YELLOW]]Axe Mastery is a passive ability that will add additional damage\n[[YELLOW]]to your hits when using Axes.\n[[YELLOW]]By default, the bonus damage increases by 1 every 50 levels,\n[[YELLOW]]up to a cap of 4 extra damage at level 200.
+Guides.Axes.Section.4=[[DARK_AQUA]]How does Armor Impact work?\n[[YELLOW]]Strike with enough force to shatter armor!\n[[YELLOW]]Armor Impact has a passive chance to damage your\n[[YELLOW]]opponent's armor. This damage increases as you level in Axes.
+Guides.Axes.Section.5=[[DARK_AQUA]]How does Greater Impact work?\n[[YELLOW]]You have a passive chance to achieve a greater impact when\n[[YELLOW]]hitting mobs or players with your axe.\n[[YELLOW]]By default this chance is 25%. This passive ability has an\n[[YELLOW]]extreme knockback effect, similar to the Knockback II\n[[YELLOW]]enchantment. In addition, it deals bonus damage to the target.
+##Excavation
+Guides.Excavation.Section.0=[[DARK_AQUA]]About Excavation:\n[[YELLOW]]Excavation is the act of digging up dirt to find treasures.\n[[YELLOW]]By excavating the land you will find treasures.\n[[YELLOW]]The more you do this the more treasures you can find.\n\n[[DARK_AQUA]]XP GAIN:\n[[YELLOW]]To gain XP in this skill you must dig with a shovel in hand.\n[[YELLOW]]Only certain materials can be dug up for treasures and XP.
+Guides.Excavation.Section.1=[[DARK_AQUA]]Compatible Materials:\n[[YELLOW]]Grass, Dirt, Sand, Clay, Gravel, Mycelium, Soul Sand, Snow
+Guides.Excavation.Section.2=[[DARK_AQUA]]How to use Giga Drill Breaker:\n[[YELLOW]]With a shovel in hand right click to ready your tool.\n[[YELLOW]]Once in this state you have about 4 seconds to make\n[[YELLOW]]contact with Excavation compatible materials this will\n[[YELLOW]]activate Giga Drill Breaker.
+Guides.Excavation.Section.3=[[DARK_AQUA]]What is Giga Drill Breaker?\n[[YELLOW]]Giga Drill Breaker is an ability with a cooldown\n[[YELLOW]]tied to Excavation skill. It triples your chance\n[[YELLOW]]of finding treasures and enables instant break\n[[YELLOW]]on Excavation materials.
+Guides.Excavation.Section.4=[[DARK_AQUA]]How does Archaeology work?\n[[YELLOW]]Every possible treasure for Excavation has its own\n[[YELLOW]]skill level requirement for it to drop, as a result it's\n[[YELLOW]]difficult to say how much it is helping you.\n[[YELLOW]]Just keep in mind that the higher your Excavation skill\n[[YELLOW]]is, the more treasures that can be found.\n[[YELLOW]]And also keep in mind that each type of Excavation\n[[YELLOW]]compatible material has its own unique list of treasures.\n[[YELLOW]]In other words you will find different treasures in Dirt\n[[YELLOW]]than you would in Gravel.
+Guides.Excavation.Section.5=[[DARK_AQUA]]Notes about Excavation:\n[[YELLOW]]Excavation drops are completely customizeable\n[[YELLOW]]So results vary server to server.
+##Fishing
+Guides.Fishing.Section.0=[[DARK_AQUA]]About Fishing:\n[[YELLOW]]With the Fishing skill, Fishing is exciting again!\n[[YELLOW]]Find hidden treasures, and shake items off mobs.\n\n[[DARK_AQUA]]XP GAIN:\n[[YELLOW]]Catch fish.
+Guides.Fishing.Section.1=[[DARK_AQUA]]How does Treasure Hunter work?\n[[YELLOW]]This ability allows you to find treasure from fishing \n[[YELLOW]]with a small chance of the items being enchanted.\n[[YELLOW]]Every possible treasure for Fishing has a chance\n[[YELLOW]]to drop on any level. It depends however\n[[YELLOW]]what the rarity of the item is how often it will drop.\n[[YELLOW]]The higher your Fishing skill is, the better\n[[YELLOW]]your chances are to find better treasures.
+Guides.Fishing.Section.2=[[DARK_AQUA]]How does Ice Fishing work?\n[[YELLOW]]This passive skill allows you to fish in ice lakes!\n[[YELLOW]]Cast your fishing rod in an ice lake and the ability will\n[[YELLOW]]create a small hole in the ice to fish in.
+Guides.Fishing.Section.3=[[DARK_AQUA]]How does Master Angler work?\n[[YELLOW]]This passive skill increases the bite chance while fishing.\n[[YELLOW]]When you've unlocked this ability, fishing while in\n[[YELLOW]]a boat or when an ocean biome doubles the bite chance.
+Guides.Fishing.Section.4=[[DARK_AQUA]]How does Shake work?\n[[YELLOW]]This active ability allows you to shake items loose from mobs\n[[YELLOW]]by hooking them with the fishing rod. \n[[YELLOW]]Mobs will drop items they would normally drop on death.\n[[YELLOW]]It is also possible to acquire mob skulls, which are normally \n[[YELLOW]]unobtainable in survival mode.
+Guides.Fishing.Section.5=[[DARK_AQUA]]How does Fisherman's Diet work?\n[[YELLOW]]This passive skill increases the amount of hunger restored \n[[YELLOW]]from eating fish.
+Guides.Fishing.Section.6=[[DARK_AQUA]]Notes about Fishing:\n[[YELLOW]]Fishing drops are completely customizable,\n[[YELLOW]]so results vary server to server.
+##Herbalism
+Guides.Herbalism.Section.0=[[DARK_AQUA]]About Herbalism:\n[[YELLOW]]Herbalism is about collecting herbs and plants.\n\n\n[[DARK_AQUA]]XP GAIN:\n[[YELLOW]]Collect plants and herbs.
+Guides.Herbalism.Section.1=[[DARK_AQUA]]Compatible Blocks\n[[YELLOW]]Wheat, Potatoes, Carrots, Melons, \n[[YELLOW]]Pumpkins, Sugar Canes, Cocoa Beans, Flowers, Cacti, Mushrooms,\n[[YELLOW]]Nether Wart, Lily Pads, and Vines.
+Guides.Herbalism.Section.2=[[DARK_AQUA]]How does Green Terra work?\n[[YELLOW]]Green Terra is an active ability, you can right-click\n[[YELLOW]]while holding a hoe to activate Green Terra.\n[[YELLOW]]Green Terra grants players a chance to get 3x drops from\n[[YELLOW]]harvesting plants. It also gives players the ability to\n[[YELLOW]]spread life into blocks and transform them using seeds\n[[YELLOW]]from your inventory.
+Guides.Herbalism.Section.3=[[DARK_AQUA]]How does Green Thumb (Crops) work?\n[[YELLOW]]This passive ability will automatically replant crops when\n[[YELLOW]]harvesting.\n[[YELLOW]]Your chance of success depends on your Herbalism skill.
+Guides.Herbalism.Section.4=[[DARK_AQUA]]How does Green Thumb (Cobble/Stone Brick/Dirt) work?\n[[YELLOW]]This active ability allows you to turn blocks into their\n[[YELLOW]]"plant-related" counterparts. You can do this by right-clicking\n[[YELLOW]]a block, while holding seeds. This will consume 1 seed.
+Guides.Herbalism.Section.5=[[DARK_AQUA]]How does Farmer's Diet work?\n[[YELLOW]]This passive skill increases the amount of hunger restored \n[[YELLOW]]when eating Bread, Cookies, Melons, Mushroom Soup, Carrots,\n[[YELLOW]]and Potatoes.
+Guides.Herbalism.Section.6=[[DARK_AQUA]]How does Hylian Luck work?\n[[YELLOW]]This passive ability gives you a chance to find rare items\n[[YELLOW]]when certain blocks are broken with a sword.
+Guides.Herbalism.Section.7=[[DARK_AQUA]]How do Double Drops work?\n[[YELLOW]]This passive ability gives players more yield from their\n[[YELLOW]]harvests.
+##Mining
+Guides.Mining.Section.0=[[DARK_AQUA]]About Mining:\n[[YELLOW]]Mining consists of mining stone and ores. It provides bonuses\n[[YELLOW]]to the amount of materials dropped while mining.\n\n[[DARK_AQUA]]XP GAIN:\n[[YELLOW]]To gain XP in this skill, you must mine with a pickaxe in hand.\n[[YELLOW]]Only certain blocks award XP.
+Guides.Mining.Section.1=[[DARK_AQUA]]Compatible Materials:\n[[YELLOW]]Stone, Coal Ore, Iron Ore, Gold Ore, Diamond Ore, Redstone Ore,\n[[YELLOW]]Lapis Ore, Obsidian, Mossy Cobblestone, Ender Stone,\n[[YELLOW]]Glowstone, and Netherrack.
+Guides.Mining.Section.2=[[DARK_AQUA]]How to use Super Breaker:\n[[YELLOW]]With a pickaxe in your hand, right click to ready your tool.\n[[YELLOW]]Once in this state, you have about 4 seconds to make contact\n[[YELLOW]]with Mining compatible materials, which will activate Super\n[[YELLOW]]Breaker.
+Guides.Mining.Section.3=[[DARK_AQUA]]What is Super Breaker?\n[[YELLOW]]Super Breaker is an ability with a cooldown tied to the Mining\n[[YELLOW]]skill. It triples your chance of extra items dropping and\n[[YELLOW]]enables instant break on Mining materials.
+Guides.Mining.Section.4=[[DARK_AQUA]]How to use Blast Mining:\n[[YELLOW]]With a pickaxe in hand,\n[[YELLOW]]crouch and right-click on TNT from a distance. This will cause the TNT\n[[YELLOW]]to instantly explode.
+Guides.Mining.Section.5=[[DARK_AQUA]]How does Blast Mining work?\n[[YELLOW]]Blast Mining is an ability with a cooldown tied to the Mining\n[[YELLOW]]skill. It gives bonuses when mining with TNT and allows you\n[[YELLOW]]to remote detonate TNT. There are three parts to Blast Mining.\n[[YELLOW]]The first part is Bigger Bombs, which increases blast radius.\n[[YELLOW]]The second is Demolitions Expert, which decreases damage\n[[YELLOW]]from TNT explosions. The third part simply increases the\n[[YELLOW]]amount of ores dropped from TNT and decreases the\n[[YELLOW]]debris dropped.
+##Repair
+Guides.Repair.Section.0=[[DARK_AQUA]]About Repair:\n[[YELLOW]]Repair allows you to use an iron block to repair armor and\n[[YELLOW]]tools.\n\n[[DARK_AQUA]]XP GAIN:\n[[YELLOW]]Repair tools or armor using the mcMMO Anvil. This is an\n[[YELLOW]]iron block by default and should not be confused with\n[[YELLOW]]the Vanilla Minecraft Anvil.
+Guides.Repair.Section.1=[[DARK_AQUA]]How can I use Repair?\n[[YELLOW]]Place down a mcMMO Anvil and right-click to repair the item \n[[YELLOW]]you're currently holding. This consumes 1 item on every use.
+Guides.Repair.Section.2=[[DARK_AQUA]]How does Repair Mastery work?\n[[YELLOW]]Repair Mastery increases the repair amount. The extra amount\n[[YELLOW]]repaired is influenced by your Repair skill level.
+Guides.Repair.Section.3=[[DARK_AQUA]]How does Super Repair work?\n[[YELLOW]]Super Repair is a passive ability. When repairing an item,\n[[YELLOW]]it grants players a chance to repair an item with\n[[YELLOW]]double effectiveness.
+Guides.Repair.Section.4=[[DARK_AQUA]]How does Arcane Forging work?\n[[YELLOW]]This passive ability allows you to repair items with a certain\n[[YELLOW]]chance of maintaining its enchantments. The enchants may be\n[[YELLOW]]kept at their existing levels, downgraded to a lower level,\n[[YELLOW]]or lost entirely.
+##Salvage
+Guides.Salvage.Section.0=[[DARK_AQUA]]About Salvage:\n[[YELLOW]]Salvage allows you to use a gold block to salvage armor and\n[[YELLOW]]tools.\n\n[[DARK_AQUA]]XP GAIN:\n[[YELLOW]]Salvage is a child skill of Repair and Fishing, your Salvage\n[[YELLOW]]skill level is based on your Fishing and Repair skill levels.
+Guides.Salvage.Section.1=[[DARK_AQUA]]How can I use Salvage?\n[[YELLOW]]Place down a mcMMO Salvage Anvil and right-click to salvage\n[[YELLOW]]the item you're currently holding. This will break apart the item,\n[[YELLOW]]and give back materials used to craft the item.\n\n[[YELLOW]]For example, salvaging an iron pickaxe will give you iron bars.
+Guides.Salvage.Section.2=[[DARK_AQUA]]How does Advanced Salvage work?\n[[YELLOW]]When unlocked, this ability allows you to salvage damaged items.\n[[YELLOW]]The yield percentage increases as you level up. A higher yield\n[[YELLOW]]means that you can get more materials back.\n[[YELLOW]]With advanced salvage you will always get 1 material back,\n[[YELLOW]]unless the item is too damaged. So you don't have to worry\n[[YELLOW]]about destroying items without getting anything in return.
+Guides.Salvage.Section.3=[[DARK_AQUA]]To illustrate how this works, here's an example:\n[[YELLOW]]Let's say we salvage a gold pickaxe which is damaged for 20%,\n[[YELLOW]]this means that the maximum amount you could get is only 2\n[[YELLOW]](because the pick is crafted with 3 ingots - each worth\n[[YELLOW]]33,33% durability) which is equal to 66%. If your yield\n[[YELLOW]]percentage is below 66% you are not able to get 2 ingots.\n[[YELLOW]]If it is above this value you are able to gain the "full amount",\n[[YELLOW]]which means that you will get 2 ingots.
+Guides.Salvage.Section.4=[[DARK_AQUA]]How does Arcane Salvage work?\n[[YELLOW]]This ability allows you to get enchanted books when salvaging\n[[YELLOW]]enchanted items. Depending on your level the chance of\n[[YELLOW]]successfully extracting a full or partial enchantment varies.\n\n[[YELLOW]]When an enchantment is partially extracted, the enchantment\n[[YELLOW]]book will have a lower level enchantment compared to what\n[[YELLOW]]it was on the item.
+##Smelting
+Guides.Smelting.Section.0=Coming soon...
+##Swords
+Guides.Swords.Section.0=[[DARK_AQUA]]About Swords:\n[[YELLOW]]This skill awards combat bonuses to anyone fighting with a\n[[YELLOW]]sword.\n\n[[DARK_AQUA]]XP GAIN:\n[[YELLOW]]XP is gained based on the amount of damage dealt to mobs or \n[[YELLOW]]other players when wielding a sword.
+Guides.Swords.Section.1=[[DARK_AQUA]]How does Serrated Strikes work?\n[[YELLOW]]Serrated Strikes is an active ability, you can activate it by\n[[YELLOW]]right-clicking with a sword. This ability allows you to deal \n[[YELLOW]]an AoE (Area of Effect) hit. This AoE will do a bonus 25%\n[[YELLOW]]damage and will inflict a bleed effect that lasts for 5 ticks.
+Guides.Swords.Section.2=[[DARK_AQUA]]How does Counter Attack work?\n[[YELLOW]]Counter Attack is an active ability. When blocking and taking\n[[YELLOW]]hits from mobs, you will have a chance to reflect 50% of \n[[YELLOW]]the damage that was taken.
+Guides.Swords.Section.3=[[DARK_AQUA]]How does Rupture work?\n[[YELLOW]]Rupture causes enemies to take damage every two seconds. The \n[[YELLOW]]target will bleed until the effect wears off, or death, \n[[YELLOW]]whichever comes first.\n[[YELLOW]]The duration of the bleed is increased by your sword skill.
+##Taming
+Guides.Taming.Section.0=[[DARK_AQUA]]About Taming:\n[[YELLOW]]Taming will give players various combat bonuses when using\n[[YELLOW]]tamed wolves.\n\n[[DARK_AQUA]]XP GAIN:\n[[YELLOW]]To gain XP in this skill, you need to tame wolves/ocelots or\n[[YELLOW]]get into combat with your wolves.
+Guides.Taming.Section.1=[[DARK_AQUA]]How does Call of the Wild work?\n[[YELLOW]]Call of the Wild is an active ability that will allow you to summon\n[[YELLOW]]a wolf or an ocelot by your side. You can do this by\n[[YELLOW]]sneaking + left-clicking while holding bones or fish.
+Guides.Taming.Section.2=[[DARK_AQUA]]How does Beast Lore work?\n[[YELLOW]]Beast Lore allows players to inspect pets and to check the\n[[YELLOW]]stats of wolves and ocelots. Left-click a wolf or ocelot to use\n[[YELLOW]]Beast Lore.
+Guides.Taming.Section.3=[[DARK_AQUA]]How does Gore work?\n[[YELLOW]]Gore is a passive ability that has a chance of inflicting a\n[[YELLOW]]bleeding effect on your wolves' targets.
+Guides.Taming.Section.4=[[DARK_AQUA]]How does Sharpened Claws work?\n[[YELLOW]]Sharpened Claws provides a damage bonus to damage dealt\n[[YELLOW]]by wolves. The damage bonus depends on your Taming level.
+Guides.Taming.Section.5=[[DARK_AQUA]]How does Environmentally Aware work?\n[[YELLOW]]This passive ability will allow wolves to teleport to you when\n[[YELLOW]]they get near hazards, such as Cacti/Lava. It will also give\n[[YELLOW]]wolves fall damage immunity.
+Guides.Taming.Section.6=[[DARK_AQUA]]How does Thick Fur work?\n[[YELLOW]]This passive ability will reduce damage and make wolves\n[[YELLOW]]fire resistant.
+Guides.Taming.Section.7=[[DARK_AQUA]]How does Shock Proof work?\n[[YELLOW]]This passive ability reduces damage done to wolves\n[[YELLOW]]from explosions.
+Guides.Taming.Section.8=[[DARK_AQUA]]How does Fast Food Service work?\n[[YELLOW]]This passive ability gives wolves a chance to heal whenever\n[[YELLOW]]they perform an attack.
+##Unarmed
+Guides.Unarmed.Section.0=[[DARK_AQUA]]About Unarmed:\n[[YELLOW]]Unarmed will give players various combat bonuses when using\n[[YELLOW]]your fists as a weapon. \n\n[[DARK_AQUA]]XP GAIN:\n[[YELLOW]]XP is gained based on the amount of damage dealt to mobs \n[[YELLOW]]or other players when unarmed.
+Guides.Unarmed.Section.1=[[DARK_AQUA]]How does Berserk work?\n[[YELLOW]]Beserk is an active ability that is activated by\n[[YELLOW]]right-clicking. While in Beserk mode, you deal 50% more\n[[YELLOW]]damage and you can break weak materials instantly, such as\n[[YELLOW]]Dirt and Grass.
+Guides.Unarmed.Section.2=[[DARK_AQUA]]How does Iron Arm work?\n[[YELLOW]]Iron Arm increases the damage dealt when hitting mobs or\n[[YELLOW]]players with your fists.
+Guides.Unarmed.Section.3=[[DARK_AQUA]]How does Arrow Deflect work?\n[[YELLOW]]Arrow Deflect is a passive ability that gives you a chance\n[[YELLOW]]to deflect arrows shot by Skeletons or other players.\n[[YELLOW]]The arrow will fall harmlessly to the ground.
+Guides.Unarmed.Section.4=[[DARK_AQUA]]How does Iron Grip work?\n[[YELLOW]]Iron Grip is a passive ability that counters disarm. As your\n[[YELLOW]]unarmed level increases, the chance of preventing a disarm increases.
+Guides.Unarmed.Section.5=[[DARK_AQUA]]How does Disarm work?\n[[YELLOW]]This passive ability allows players to disarm other players,\n[[YELLOW]]causing the target's equipped item to fall to the ground.
+##Woodcutting
+Guides.Woodcutting.Section.0=[[DARK_AQUA]]About Woodcutting:\n[[YELLOW]]Woodcutting is all about chopping down trees.\n\n[[DARK_AQUA]]XP GAIN:\n[[YELLOW]]XP is gained whenever you break log blocks.
+Guides.Woodcutting.Section.1=[[DARK_AQUA]]How does Tree Feller work?\n[[YELLOW]]Tree Feller is an active ability, you can right-click\n[[YELLOW]]while holding an ax to activate Tree Feller. This will\n[[YELLOW]]cause the entire tree to break instantly, dropping all\n[[YELLOW]]of its logs at once.
+Guides.Woodcutting.Section.2=[[DARK_AQUA]]How does Leaf Blower work?\n[[YELLOW]]Leaf Blower is a passive ability that will cause leaf\n[[YELLOW]]blocks to break instantly when hit with an axe. By default,\n[[YELLOW]]this ability unlocks at level 100.
+Guides.Woodcutting.Section.3=[[DARK_AQUA]]How do Double Drops work?\n[[YELLOW]]This passive ability gives you a chance to obtain an extra\n[[YELLOW]]block for every log you chop.
+#INSPECT
+Inspect.Offline= [[RED]]Apgailestaujame, tačiau atsijungusių žaidėjų patikrinimui neturi atitinkamo leidimo!
+Inspect.OfflineStats=mcMMO Atsijungusių žaidėjų Įgūdžių Informacija [[YELLOW]]{0}
+Inspect.Stats=[[GREEN]]mcMMO Įgūdžių Informacija: [[YELLOW]]{0}
+Inspect.TooFar=Atrodo, jog esate per toli nuo, Jūsų tikrinamo žaidėjo!
+#ITEMS
+Item.ChimaeraWing.Fail=[[RED]]**CHIMAERA WING FAILED!**
+Item.ChimaeraWing.Pass=**CHIMAERA WING**
+Item.ChimaeraWing.Name=Chimaera Wing
+Item.ChimaeraWing.Lore=[[GRAY]]Teleports you to your bed.
+Item.ChimaeraWing.NotEnough=You need [[YELLOW]]{0}[[RED]] more [[GOLD]]{1}[[RED]]!
+Item.NotEnough=You need [[YELLOW]]{0}[[RED]] more [[GOLD]]{1}[[RED]]!
+Item.Generic.Wait=You need to wait before you can use this again! [[YELLOW]]({0}s)
+Item.Injured.Wait=You were injured recently and must wait to use this. [[YELLOW]]({0}s)
+Item.FluxPickaxe.Name=Flux Pickaxe
+Item.FluxPickaxe.Lore.1=[[GRAY]]Has a chance of instantly smelting ores.
+Item.FluxPickaxe.Lore.2=[[GRAY]]Requires Smelting level {0}+
+#TELEPORTATION
+Teleport.Commencing=[[GRAY]]Perkėlimas už: [[GOLD]]({0}) [[GRAY]]s., prašome nejudėti...
+Teleport.Cancelled=[[DARK_RED]]Perkėlimas atmestas!
+#SKILLS
+Skills.Child=[[GOLD]](CHILD SKILL)
+Skills.Disarmed=[[DARK_RED]]You have been disarmed!
+Skills.Header=-----[] [[GREEN]]{0}[[RED]] []-----
+Skills.NeedMore=[[DARK_RED]]You need more [[GRAY]]{0}
+Skills.NeedMore.Extra=[[DARK_RED]]You need more [[GRAY]]{0}{1}
+Skills.Parents= PARENTS
+Skills.Stats={0}[[GREEN]]{1}[[DARK_AQUA]] XP([[GRAY]]{2}[[DARK_AQUA]]/[[GRAY]]{3}[[DARK_AQUA]])
+Skills.ChildStats={0}[[GREEN]]{1}
+Skills.MaxXP=Max
+Skills.TooTired=You are too tired to use that ability again. [[YELLOW]]({0}s)
+Skills.Cancelled=[[GOLD]]{0} [[RED]]cancelled!
+Skills.ConfirmOrCancel=[[GREEN]]Right-click again to confirm [[GOLD]]{0}[[GREEN]]. Left-click to cancel.
+Skills.AbilityGateRequirementFail=[[GRAY]]You require [[YELLOW]]{0}[[GRAY]] more levels of [[DARK_AQUA]]{1}[[GRAY]] to use this super ability.
+#STATISTICS
+Stats.Header.Combat=[[GOLD]]-=KOVOS ĮGŪDŽIAI=-
+Stats.Header.Gathering=[[GOLD]]-=GATHERING SKILLS=-
+Stats.Header.Misc=[[GOLD]]-=ĮVAIRŪS ĮGŪDŽIAI=-
+Stats.Own.Stats=[[GREEN]][mcMMO] Informacija
+#PERKS
+Perks.XP.Name=Experience
+Perks.XP.Desc=Receive boosted XP in certain skills.
+Perks.Lucky.Name=Luck
+Perks.Lucky.Desc=Gives {0} skills and abilities a 33.3% better chance to activate.
+Perks.Lucky.Desc.Login=Gives certain skills and abilities a 33.3% better chance to activate.
+Perks.Lucky.Bonus=[[GOLD]] ({0} with Lucky Perk)
+Perks.Cooldowns.Name=Fast Recovery
+Perks.Cooldowns.Desc=Cuts cooldown duration by {0}.
+Perks.ActivationTime.Name=Endurance
+Perks.ActivationTime.Desc=Increases ability activation time by {0} seconds.
+Perks.ActivationTime.Bonus=[[GOLD]] ({0}s with Endurance Perk)
+#HARDCORE
+Hardcore.Mode.Disabled=[[GOLD]][mcMMO] Hardcore mode {0} disabled for {1}.
+Hardcore.Mode.Enabled=[[GOLD]][mcMMO] Hardcore mode {0} enabled for {1}.
+Hardcore.DeathStatLoss.Name=Skill Death Penalty
+Hardcore.DeathStatLoss.PlayerDeath=[[GOLD]][mcMMO] [[DARK_RED]]You have lost [[BLUE]]{0}[[DARK_RED]] levels from death.
+Hardcore.DeathStatLoss.PercentageChanged=[[GOLD]][mcMMO] The stat loss percentage was changed to {0}.
+Hardcore.Vampirism.Name=Vampirism
+Hardcore.Vampirism.Killer.Failure=[[GOLD]][mcMMO] [[YELLOW]]{0}[[GRAY]] was too unskilled to grant you any knowledge.
+Hardcore.Vampirism.Killer.Success=[[GOLD]][mcMMO] [[DARK_AQUA]]You have stolen [[BLUE]]{0}[[DARK_AQUA]] levels from [[YELLOW]]{1}.
+Hardcore.Vampirism.Victim.Failure=[[GOLD]][mcMMO] [[YELLOW]]{0}[[GRAY]] was unable to steal knowledge from you!
+Hardcore.Vampirism.Victim.Success=[[GOLD]][mcMMO] [[YELLOW]]{0}[[DARK_RED]] has stolen [[BLUE]]{1}[[DARK_RED]] levels from you!
+Hardcore.Vampirism.PercentageChanged=[[GOLD]][mcMMO] The stat leech percentage was changed to {0}.
+#MOTD
+MOTD.Donate=[[DARK_AQUA]]Donation Info:
+MOTD.Hardcore.Enabled=[[GOLD]][mcMMO] [[DARK_AQUA]]Sunkusis rėžimas aktyvuotas: [[DARK_RED]]{0}
+MOTD.Hardcore.DeathStatLoss.Stats=[[GOLD]][mcMMO] [[DARK_AQUA]]Skill Death Penalty: [[DARK_RED]]{0}%
+MOTD.Hardcore.Vampirism.Stats=[[GOLD]][mcMMO] [[DARK_AQUA]]Vampirism Stat Leech: [[DARK_RED]]{0}%
+MOTD.PerksPrefix=[[GOLD]][mcMMO Perks]
+MOTD.Version=[[GOLD]][mcMMO] Naudojama sisteminė versija [[DARK_AQUA]]{0}
+MOTD.Website=[[GOLD]][mcMMO] [[GREEN]]{0}[[YELLOW]] - mcMMO projekto tinklalapis
+#SMELTING
+Smelting.SubSkill.UnderstandingTheArt.Name=Understanding The Art
+Smelting.SubSkill.UnderstandingTheArt.Description=Maybe you're spending a bit too much time smelting in the caves.\nPowers up various properties of Smelting.
+Smelting.SubSkill.UnderstandingTheArt.Stat=Vanilla XP Multiplier: [[YELLOW]]{0}x
+Smelting.Ability.Locked.0=LOCKED UNTIL {0}+ SKILL (VANILLA XP BOOST)
+Smelting.Ability.Locked.1=LOCKED UNTIL {0}+ SKILL (FLUX MINING)
+Smelting.SubSkill.FuelEfficiency.Name=Fuel Efficiency
+Smelting.SubSkill.FuelEfficiency.Description=Increase the burn time of fuel used in furnaces when smelting
+Smelting.SubSkill.FuelEfficiency.Stat=Fuel Efficiency Multiplier: [[YELLOW]]{0}x
+Smelting.SubSkill.SecondSmelt.Name=Second Smelt
+Smelting.SubSkill.SecondSmelt.Description=Double the resources gained from smelting
+Smelting.SubSkill.SecondSmelt.Stat=Second Smelt Chance
+Smelting.Effect.4=Vanilla XP Boost
+Smelting.Effect.5=Increase vanilla XP gained while smelting
+Smelting.SubSkill.FluxMining.Name=Flux Mining
+Smelting.SubSkill.FluxMining.Description=Chance for ores to be instantly smelted while mining
+Smelting.SubSkill.FluxMining.Stat=Flux Mining Chance
+Smelting.Listener=Smelting:
+Smelting.SkillName=SMELTING
+#COMMAND DESCRIPTIONS
+Commands.Description.addlevels=Add mcMMO levels to a user
+Commands.Description.adminchat=Toggle mcMMO admin chat on/off or send admin chat messages
+Commands.Description.addxp=Add mcMMO XP to a user
+Commands.Description.hardcore=Modify the mcMMO hardcore percentage or toggle hardcore mode on/off
+Commands.Description.inspect=View detailed mcMMO info on another player
+Commands.Description.mcability=Toggle mcMMO abilities being readied on right-click on/off
+Commands.Description.mccooldown=View all of the mcMMO ability cooldowns
+Commands.Description.mcchatspy=Toggle mcMMO party chat spying on or off
+Commands.Description.mcgod=Toggle mcMMO god-mode on/off
+Commands.Description.mchud=Change your mcMMO HUD style
+Commands.Description.mcmmo=Show a brief description of mcMMO
+Commands.Description.mcnotify=Toggle mcMMO abilities chat display notifications on/off
+Commands.Description.mcpurge=Purge users with no mcMMO levels and users who have not connected in over {0} months from the mcMMO database.
+Commands.Description.mcrank=Show mcMMO ranking for a player
+Commands.Description.mcrefresh=Refresh all cooldowns for mcMMO
+Commands.Description.mcremove=Remove a user from the mcMMO database
+Commands.Description.mcscoreboard=Manage your mcMMO Scoreboard
+Commands.Description.mcstats=Show your mcMMO levels and XP
+Commands.Description.mctop=Show mcMMO leader boards
+Commands.Description.mmoedit=Edit mcMMO levels for a user
+Commands.Description.mmodebug=Toggle a debug mode which prints useful information when you hit blocks
+Commands.Description.mmoupdate=Migrate mcMMO database from an old database into the current one
+Commands.Description.mcconvert=Converts database types or experience formula types
+Commands.Description.mmoshowdb=Show the name of the current database type (for later use with /mmoupdate)
+Commands.Description.party=Control various mcMMO party settings
+Commands.Description.partychat=Toggle mcMMO party chat on/off or send party chat messages
+Commands.Description.ptp=Teleport to an mcMMO party member
+Commands.Description.Skill=Display detailed mcMMO skill info for {0}
+Commands.Description.skillreset=Reset mcMMO levels for a user
+Commands.Description.vampirism=Modify the mcMMO vampirism percentage or toggle vampirism mode on/off
+Commands.Description.xplock=Lock your mcMMO XP bar to a specific mcMMO skill
+Commands.Description.xprate=Modify the mcMMO XP rate or start an mcMMO XP event
+#UPDATE CHECKER
+UpdateChecker.Outdated=Nustatyta, jog šis serveris naudoja pasenusią mcMMO versiją!
+UpdateChecker.NewAvailable=Atnaujinimą galima parsisiūsti iš: spigotmc.org.
+#SCOREBOARD HEADERS
+Scoreboard.Header.PlayerStats=[[YELLOW]]mcMMO Informacija
+Scoreboard.Header.PlayerCooldowns=[[YELLOW]]mcMMO Cooldowns
+Scoreboard.Header.PlayerRank=[[YELLOW]]mcMMO Rankinimas
+Scoreboard.Header.PlayerInspect=[[YELLOW]]mcMMO Informacija: {0}
+Scoreboard.Header.PowerLevel=[[RED]]Jėgos įgūdžių lygis
+Scoreboard.Misc.PowerLevel=[[GOLD]]Jėgos įgūdžių lygis
+Scoreboard.Misc.Level=[[DARK_AQUA]]Įgūdžių lygis
+Scoreboard.Misc.CurrentXP=[[GREEN]]Įgūdžių patirties XP
+Scoreboard.Misc.RemainingXP=[[YELLOW]]Reikiamas XP
+Scoreboard.Misc.Cooldown=[[LIGHT_PURPLE]]Cooldown
+Scoreboard.Misc.Overall=[[GOLD]]Overall
+Scoreboard.Misc.Ability=Ability
+#DATABASE RECOVERY
+Profile.PendingLoad=[[RED]]Your mcMMO player data has not yet been loaded.
+Profile.Loading.Success=[[GREEN]]Your mcMMO profile has been loaded.
+Profile.Loading.FailurePlayer=[[RED]]mcMMO is having trouble loading your data, we have attempted to load it [[GREEN]]{0}[[RED]] times.[[RED]] You may want to contact the server admins about this issue. mcMMO will attempt to load your data until you disconnect, you will not gain XP or be able to use skills while the data is not loaded.
+Profile.Loading.FailureNotice=[[DARK_RED]][A][[RED]] mcMMO was unable to load the player data for [[YELLOW]]{0}[[RED]]. [[LIGHT_PURPLE]]Please inspect your database setup. Attempts made so far {1}.
+#Holiday
+Holiday.AprilFools.Levelup=[[GOLD]]{0} dabartinis įgūdžių lygis [[GREEN]]{1}[[GREEN]]LvL[[GOLD]]!
+Holiday.Anniversary=[[BLUE]]Happy {0} Year Anniversary!\n[[BLUE]]In honor of all of nossr50's work and all the devs, here's a firework show!
+#Reminder Messages
+Reminder.Squelched=[[GRAY]]Reminder: You are currently not receiving notifications from mcMMO, to enable notifications please run the /mcnotify command again. This is an automated hourly reminder.
+#Locale
+Locale.Reloaded=[[GREEN]]Kalbos nustatymai atnaujinti!
+#Player Leveling Stuff
+LevelCap.PowerLevel=[[GOLD]]([[GREEN]]mcMMO[[GOLD]]) [[YELLOW]]You have reached the power level cap of [[RED]]{0}[[YELLOW]]. You will cease to level in skills from this point on.
+LevelCap.Skill=[[GOLD]]([[GREEN]]mcMMO[[GOLD]]) [[YELLOW]]You have reached the level cap of [[RED]]{0}[[YELLOW]] for [[GOLD]]{1}[[YELLOW]]. You will cease to level in this skill from this point on.

+ 2 - 1
mcmmo-core/src/main/resources/config.yml

@@ -436,7 +436,7 @@ Bonus_Drops:
         Melon_Slice: true
         Melon_Slice: true
         Nether_Wart: true
         Nether_Wart: true
         Potatoes: true
         Potatoes: true
-        Potatoe: true
+        Potato: true
         Pumpkin: true
         Pumpkin: true
         Red_Mushroom: true
         Red_Mushroom: true
         Sugar_Cane: true
         Sugar_Cane: true
@@ -456,6 +456,7 @@ Bonus_Drops:
         Lilac: true
         Lilac: true
         Rose_Bush: true
         Rose_Bush: true
         Peony: true
         Peony: true
+        Lily_Of_The_Valley: true
     Mining:
     Mining:
         Andesite: true
         Andesite: true
         Diorite: true
         Diorite: true

+ 5 - 1
mcmmo-core/src/main/resources/experience.yml

@@ -33,6 +33,7 @@ ExploitFix:
     LavaStoneAndCobbleFarming: true
     LavaStoneAndCobbleFarming: true
     TreeFellerReducedXP: true
     TreeFellerReducedXP: true
     PistonCheating: true
     PistonCheating: true
+    SnowGolemExcavation: true
 Experience_Bars:
 Experience_Bars:
     # Turn this to false if you wanna disable XP bars
     # Turn this to false if you wanna disable XP bars
     Enable: true
     Enable: true
@@ -274,7 +275,8 @@ Experience_Values:
         Brown_Mushroom_Block: 70
         Brown_Mushroom_Block: 70
         Mushroom_Stem: 80
         Mushroom_Stem: 80
     Herbalism:
     Herbalism:
-        Sweet_Berry_Bush: 300
+        Bee_Nest: 200
+        Sweet_Berry_Bush: 50
         Seagrass: 10
         Seagrass: 10
         Tall_Seagrass: 10
         Tall_Seagrass: 10
         Kelp: 3
         Kelp: 3
@@ -440,6 +442,7 @@ Experience_Values:
             Cat: 500
             Cat: 500
             Fox: 1000
             Fox: 1000
             Panda: 1000
             Panda: 1000
+            Bee: 100
     Combat:
     Combat:
         Multiplier:
         Multiplier:
             Animals: 1.0
             Animals: 1.0
@@ -501,4 +504,5 @@ Experience_Values:
             Ravager: 4.0
             Ravager: 4.0
             Trader_Llama: 1.0
             Trader_Llama: 1.0
             Wandering_trader: 1.0
             Wandering_trader: 1.0
+            Bee: 1.5
 
 

+ 4 - 1
mcmmo-core/src/main/resources/fishing_treasures.yml

@@ -561,6 +561,7 @@ Enchantment_Drop_Rates:
         LEGENDARY: 0.75
         LEGENDARY: 0.75
 #
 #
 #  Settings for Excavation's Archaeology
 #  Settings for Excavation's Archaeology
+#  If you are in retro mode, Drop_Level is multiplied by 10.
 ###
 ###
 Excavation:
 Excavation:
     CAKE:
     CAKE:
@@ -691,6 +692,7 @@ Excavation:
         Drops_From: [Dirt, Coarse_Dirt, Podzol, Grass_Block, Sand, Red_Sand, Gravel, Clay, Mycelium, Soul_Sand]
         Drops_From: [Dirt, Coarse_Dirt, Podzol, Grass_Block, Sand, Red_Sand, Gravel, Clay, Mycelium, Soul_Sand]
 #
 #
 #  Settings for Hylian Luck
 #  Settings for Hylian Luck
+#  If you are in retro mode, Drop_Level is multiplied by 10.
 ###
 ###
 Hylian_Luck:
 Hylian_Luck:
     MELON_SEEDS:
     MELON_SEEDS:
@@ -748,7 +750,8 @@ Hylian_Luck:
         Drop_Level: 0
         Drop_Level: 0
         Drops_From: [Pots]
         Drops_From: [Pots]
 #
 #
-#	Settings for Shake
+#  Settings for Shake
+#  If you are in retro mode, Drop_Level is multiplied by 10.
 ###
 ###
 Shake:
 Shake:
     BLAZE:
     BLAZE:

+ 4 - 0
mcmmo-core/src/main/resources/sounds.yml

@@ -4,6 +4,10 @@ Sounds:
     # 1.0 = Max volume
     # 1.0 = Max volume
     # 0.0 = No Volume
     # 0.0 = No Volume
     MasterVolume: 1.0
     MasterVolume: 1.0
+    GLASS:
+        Enable: true
+        Volume: 1.0
+        Pitch: 1.0
     ANVIL:
     ANVIL:
         Enable: true
         Enable: true
         Volume: 1.0
         Volume: 1.0

برخی فایل ها در این مقایسه diff نمایش داده نمی شوند زیرا تعداد فایل ها بسیار زیاد است