浏览代码

Merge remote-tracking branch 'upstream/master'

OverCrave 6 年之前
父节点
当前提交
610e1a6bf4

+ 31 - 1
Changelog.txt

@@ -7,12 +7,42 @@ Key:
   ! Change
   - Removal
 
+Version 2.1.27
+    Fixed an exploit that allowed players to duplicate torches, and rails
+
+Version 2.1.26
+    Added new scaling damage buffs to all existing Combat Skills
+    Added a new subskill named Stab to Swords
+    Fixed a bug where Berserk was not adding 50% damage to attacks
+    Changed how Iron Arm damage is calculated (Rank 1 now effectively gives twice the damage bonus it used to, higher ranks have more damage)
+
+    NOTE: Combat skills will be completely configurable in the upcoming 2.2 update, be patient <3
+
+    New Permissions
+            - mcmmo.ability.unarmed.unarmedlimitbreak
+            - mcmmo.ability.axes.axeslimitbreak
+            - mcmmo.ability.archery.archerylimitbreak
+            - mcmmo.ability.swords.swordslimitbreak
+            - mcmmo.ability.swords.stab
+
+    Notes:
+    The new Limit Break subskills are intended to make Prot IV players less tanky and for you to feel more powerful for having high skill level.
+    Limit Break has 10 ranks, each rank gives 1 extra RAW damage, this is damage before reductions from armor and enchantments. The net result is you deal about 50% more damage with an end game skill compared to before.
+    With these new changes, most skills can 2 shot normal diamond armor, and it takes about 5 hits to kill someone in Prot IV Diamond Armor.
+    I'm not sure everyone will like these changes, the net result is players are a lot easier to kill now, whereas before you could take quite a beating before getting killed.
+    I collected several sets of data before making these changes, including damage to player with and without prot 4 diamond armor, damage to those players with and without enchanted weapons, damage with and without leveling your skills, and combinations of the previously mentioned things.
+
+Version 2.1.25
+    Shake now has an upper limit of damage (10) - Will be configurable in 2.2 which is coming in the near future
+    Rank 1 of Catalysis & Concoctions are now available at level 0 by default (update skillranks.yml or delete it to regen a new one)
+    NOTE: The change to shake was to make mcMMO more compatible with plugins that spawn entities with large amounts of HP
+
 Version 2.1.24
     Fixed an exploit where you could clone inventories
 
 Version 2.1.23
     Fixed a bug with Double Drops for Mining (Update your configs instructions below)
-    Fixed a 7 year old bug where damage in mcMMO from Skills was potentially getting reduced by damage reduction TWICE
+    Fixed a 7 year old bug where damage in mcMMO from SkillBs was potentially getting reduced by damage reduction TWICE
     Fixed a bug where killing entities with Rupture would not properly credit you as the killer
     Fixed a bug where Serrated Strikes was applying Rupture twice
     Players will now be ejected from Minecarts if they cast their fishing rod (anti-afk)

+ 1 - 1
pom.xml

@@ -2,7 +2,7 @@
     <modelVersion>4.0.0</modelVersion>
     <groupId>com.gmail.nossr50.mcMMO</groupId>
     <artifactId>mcMMO</artifactId>
-    <version>2.1.24</version>
+    <version>2.1.27</version>
     <name>mcMMO</name>
     <url>https://github.com/mcMMO-Dev/mcMMO</url>
     <scm>

+ 6 - 0
src/main/java/com/gmail/nossr50/commands/skills/ArcheryCommand.java

@@ -5,6 +5,7 @@ import com.gmail.nossr50.datatypes.skills.SubSkillType;
 import com.gmail.nossr50.locale.LocaleLoader;
 import com.gmail.nossr50.skills.archery.Archery;
 import com.gmail.nossr50.util.TextComponentFactory;
+import com.gmail.nossr50.util.skills.CombatUtils;
 import com.gmail.nossr50.util.skills.SkillActivationType;
 import net.md_5.bungee.api.chat.TextComponent;
 import org.bukkit.entity.Player;
@@ -74,6 +75,11 @@ public class ArcheryCommand extends SkillCommand {
             messages.add(getStatMessage(SubSkillType.ARCHERY_SKILL_SHOT, skillShotBonus));
         }
 
+        if(canUseSubskill(player, SubSkillType.ARCHERY_ARCHERY_LIMIT_BREAK)) {
+            messages.add(getStatMessage(SubSkillType.ARCHERY_ARCHERY_LIMIT_BREAK,
+                    String.valueOf(CombatUtils.getLimitBreakDamage(player, SubSkillType.ARCHERY_ARCHERY_LIMIT_BREAK))));
+        }
+
         return messages;
     }
 

+ 6 - 0
src/main/java/com/gmail/nossr50/commands/skills/AxesCommand.java

@@ -7,6 +7,7 @@ import com.gmail.nossr50.skills.axes.Axes;
 import com.gmail.nossr50.util.Permissions;
 import com.gmail.nossr50.util.TextComponentFactory;
 import com.gmail.nossr50.util.player.UserManager;
+import com.gmail.nossr50.util.skills.CombatUtils;
 import com.gmail.nossr50.util.skills.RankUtils;
 import com.gmail.nossr50.util.skills.SkillActivationType;
 import net.md_5.bungee.api.chat.TextComponent;
@@ -95,6 +96,11 @@ public class AxesCommand extends SkillCommand {
                     + (hasEndurance ? LocaleLoader.getString("Perks.ActivationTime.Bonus", skullSplitterLengthEndurance) : ""));
         }
 
+        if(canUseSubskill(player, SubSkillType.AXES_AXES_LIMIT_BREAK)) {
+            messages.add(getStatMessage(SubSkillType.AXES_AXES_LIMIT_BREAK,
+                    String.valueOf(CombatUtils.getLimitBreakDamage(player, SubSkillType.AXES_AXES_LIMIT_BREAK))));
+        }
+
         return messages;
     }
 

+ 12 - 0
src/main/java/com/gmail/nossr50/commands/skills/SwordsCommand.java

@@ -7,6 +7,7 @@ import com.gmail.nossr50.locale.LocaleLoader;
 import com.gmail.nossr50.util.Permissions;
 import com.gmail.nossr50.util.TextComponentFactory;
 import com.gmail.nossr50.util.player.UserManager;
+import com.gmail.nossr50.util.skills.CombatUtils;
 import com.gmail.nossr50.util.skills.RankUtils;
 import com.gmail.nossr50.util.skills.SkillActivationType;
 import net.md_5.bungee.api.chat.TextComponent;
@@ -94,6 +95,17 @@ public class SwordsCommand extends SkillCommand {
                     + (hasEndurance ? LocaleLoader.getString("Perks.ActivationTime.Bonus", serratedStrikesLengthEndurance) : ""));
         }
 
+        if(canUseSubskill(player, SubSkillType.SWORDS_STAB))
+        {
+            messages.add(getStatMessage(SubSkillType.SWORDS_STAB,
+                    String.valueOf(UserManager.getPlayer(player).getSwordsManager().getStabDamage())));
+        }
+
+        if(canUseSubskill(player, SubSkillType.SWORDS_SWORDS_LIMIT_BREAK)) {
+            messages.add(getStatMessage(SubSkillType.SWORDS_SWORDS_LIMIT_BREAK,
+                    String.valueOf(CombatUtils.getLimitBreakDamage(player, SubSkillType.SWORDS_SWORDS_LIMIT_BREAK))));
+        }
+
         return messages;
     }
 

+ 6 - 0
src/main/java/com/gmail/nossr50/commands/skills/UnarmedCommand.java

@@ -6,6 +6,7 @@ import com.gmail.nossr50.locale.LocaleLoader;
 import com.gmail.nossr50.util.Permissions;
 import com.gmail.nossr50.util.TextComponentFactory;
 import com.gmail.nossr50.util.player.UserManager;
+import com.gmail.nossr50.util.skills.CombatUtils;
 import com.gmail.nossr50.util.skills.RankUtils;
 import com.gmail.nossr50.util.skills.SkillActivationType;
 import net.md_5.bungee.api.chat.TextComponent;
@@ -113,6 +114,11 @@ public class UnarmedCommand extends SkillCommand {
             //messages.add(LocaleLoader.getString("Unarmed.Ability.Chance.IronGrip", ironGripChance) + (isLucky ? LocaleLoader.getString("Perks.Lucky.Bonus", ironGripChanceLucky) : ""));
         }
 
+        if(canUseSubskill(player, SubSkillType.UNARMED_UNARMED_LIMIT_BREAK)) {
+            messages.add(getStatMessage(SubSkillType.UNARMED_UNARMED_LIMIT_BREAK,
+                    String.valueOf(CombatUtils.getLimitBreakDamage(player, SubSkillType.UNARMED_UNARMED_LIMIT_BREAK))));
+        }
+
         return messages;
     }
 

+ 30 - 15
src/main/java/com/gmail/nossr50/datatypes/skills/PrimarySkillType.java

@@ -35,21 +35,36 @@ import java.util.Collections;
 import java.util.List;
 
 public enum PrimarySkillType {
-    ACROBATICS(AcrobaticsManager.class, Color.WHITE, ImmutableList.of(SubSkillType.ACROBATICS_DODGE, SubSkillType.ACROBATICS_ROLL)),
-    ALCHEMY(AlchemyManager.class, Color.FUCHSIA, ImmutableList.of(SubSkillType.ALCHEMY_CATALYSIS, SubSkillType.ALCHEMY_CONCOCTIONS)),
-    ARCHERY(ArcheryManager.class, Color.MAROON, ImmutableList.of(SubSkillType.ARCHERY_DAZE, SubSkillType.ARCHERY_ARROW_RETRIEVAL, SubSkillType.ARCHERY_SKILL_SHOT)),
-    AXES(AxesManager.class, Color.AQUA, SuperAbilityType.SKULL_SPLITTER, ToolType.AXE, ImmutableList.of(SubSkillType.AXES_SKULL_SPLITTER, SubSkillType.AXES_ARMOR_IMPACT, SubSkillType.AXES_AXE_MASTERY, SubSkillType.AXES_CRITICAL_STRIKES, SubSkillType.AXES_GREATER_IMPACT)),
-    EXCAVATION(ExcavationManager.class, Color.fromRGB(139, 69, 19), SuperAbilityType.GIGA_DRILL_BREAKER, ToolType.SHOVEL, ImmutableList.of(SubSkillType.EXCAVATION_GIGA_DRILL_BREAKER, SubSkillType.EXCAVATION_ARCHAEOLOGY)),
-    FISHING(FishingManager.class, Color.NAVY, ImmutableList.of(SubSkillType.FISHING_FISHERMANS_DIET, SubSkillType.FISHING_TREASURE_HUNTER, SubSkillType.FISHING_ICE_FISHING, SubSkillType.FISHING_MAGIC_HUNTER, SubSkillType.FISHING_MASTER_ANGLER, SubSkillType.FISHING_SHAKE)),
-    HERBALISM(HerbalismManager.class, Color.GREEN, SuperAbilityType.GREEN_TERRA, ToolType.HOE, ImmutableList.of(SubSkillType.HERBALISM_GREEN_TERRA, SubSkillType.HERBALISM_FARMERS_DIET, SubSkillType.HERBALISM_GREEN_THUMB, SubSkillType.HERBALISM_DOUBLE_DROPS, SubSkillType.HERBALISM_HYLIAN_LUCK, SubSkillType.HERBALISM_SHROOM_THUMB)),
-    MINING(MiningManager.class, Color.GRAY, SuperAbilityType.SUPER_BREAKER, ToolType.PICKAXE, ImmutableList.of(SubSkillType.MINING_SUPER_BREAKER, SubSkillType.MINING_DEMOLITIONS_EXPERTISE, SubSkillType.MINING_BIGGER_BOMBS, SubSkillType.MINING_BLAST_MINING, SubSkillType.MINING_DOUBLE_DROPS)),
-    REPAIR(RepairManager.class, Color.SILVER, ImmutableList.of(SubSkillType.REPAIR_ARCANE_FORGING, SubSkillType.REPAIR_REPAIR_MASTERY, SubSkillType.REPAIR_SUPER_REPAIR)),
-    SALVAGE(SalvageManager.class, Color.ORANGE, ImmutableList.of(SubSkillType.SALVAGE_ADVANCED_SALVAGE, SubSkillType.SALVAGE_ARCANE_SALVAGE)),
-    SMELTING(SmeltingManager.class, Color.YELLOW, ImmutableList.of(SubSkillType.SMELTING_UNDERSTANDING_THE_ART, /*SubSkillType.SMELTING_FLUX_MINING,*/ SubSkillType.SMELTING_FUEL_EFFICIENCY, SubSkillType.SMELTING_SECOND_SMELT)),
-    SWORDS(SwordsManager.class, Color.fromRGB(178, 34, 34), SuperAbilityType.SERRATED_STRIKES, ToolType.SWORD, ImmutableList.of(SubSkillType.SWORDS_SERRATED_STRIKES, SubSkillType.SWORDS_RUPTURE, SubSkillType.SWORDS_COUNTER_ATTACK)),
-    TAMING(TamingManager.class, Color.PURPLE, ImmutableList.of(SubSkillType.TAMING_BEAST_LORE, SubSkillType.TAMING_CALL_OF_THE_WILD, SubSkillType.TAMING_ENVIRONMENTALLY_AWARE, SubSkillType.TAMING_FAST_FOOD_SERVICE, SubSkillType.TAMING_GORE, SubSkillType.TAMING_HOLY_HOUND, SubSkillType.TAMING_SHARPENED_CLAWS, SubSkillType.TAMING_SHOCK_PROOF, SubSkillType.TAMING_THICK_FUR, SubSkillType.TAMING_PUMMEL)),
-    UNARMED(UnarmedManager.class, Color.BLACK, SuperAbilityType.BERSERK, ToolType.FISTS, ImmutableList.of(SubSkillType.UNARMED_BERSERK, SubSkillType.UNARMED_BLOCK_CRACKER, SubSkillType.UNARMED_ARROW_DEFLECT, SubSkillType.UNARMED_DISARM, SubSkillType.UNARMED_IRON_ARM_STYLE, SubSkillType.UNARMED_IRON_GRIP)),
-    WOODCUTTING(WoodcuttingManager.class, Color.OLIVE, SuperAbilityType.TREE_FELLER, ToolType.AXE, ImmutableList.of(SubSkillType.WOODCUTTING_LEAF_BLOWER, SubSkillType.WOODCUTTING_TREE_FELLER, SubSkillType.WOODCUTTING_HARVEST_LUMBER));
+    ACROBATICS(AcrobaticsManager.class, Color.WHITE,
+            ImmutableList.of(SubSkillType.ACROBATICS_DODGE, SubSkillType.ACROBATICS_ROLL)),
+    ALCHEMY(AlchemyManager.class, Color.FUCHSIA,
+            ImmutableList.of(SubSkillType.ALCHEMY_CATALYSIS, SubSkillType.ALCHEMY_CONCOCTIONS)),
+    ARCHERY(ArcheryManager.class, Color.MAROON,
+            ImmutableList.of(SubSkillType.ARCHERY_DAZE, SubSkillType.ARCHERY_ARCHERY_LIMIT_BREAK, SubSkillType.ARCHERY_ARROW_RETRIEVAL, SubSkillType.ARCHERY_SKILL_SHOT)),
+    AXES(AxesManager.class, Color.AQUA, SuperAbilityType.SKULL_SPLITTER, ToolType.AXE,
+            ImmutableList.of(SubSkillType.AXES_SKULL_SPLITTER, SubSkillType.AXES_AXES_LIMIT_BREAK, SubSkillType.AXES_ARMOR_IMPACT, SubSkillType.AXES_AXE_MASTERY, SubSkillType.AXES_CRITICAL_STRIKES, SubSkillType.AXES_GREATER_IMPACT)),
+    EXCAVATION(ExcavationManager.class, Color.fromRGB(139, 69, 19), SuperAbilityType.GIGA_DRILL_BREAKER, ToolType.SHOVEL,
+            ImmutableList.of(SubSkillType.EXCAVATION_GIGA_DRILL_BREAKER, SubSkillType.EXCAVATION_ARCHAEOLOGY)),
+    FISHING(FishingManager.class, Color.NAVY,
+            ImmutableList.of(SubSkillType.FISHING_FISHERMANS_DIET, SubSkillType.FISHING_TREASURE_HUNTER, SubSkillType.FISHING_ICE_FISHING, SubSkillType.FISHING_MAGIC_HUNTER, SubSkillType.FISHING_MASTER_ANGLER, SubSkillType.FISHING_SHAKE)),
+    HERBALISM(HerbalismManager.class, Color.GREEN, SuperAbilityType.GREEN_TERRA, ToolType.HOE,
+            ImmutableList.of(SubSkillType.HERBALISM_GREEN_TERRA, SubSkillType.HERBALISM_FARMERS_DIET, SubSkillType.HERBALISM_GREEN_THUMB, SubSkillType.HERBALISM_DOUBLE_DROPS, SubSkillType.HERBALISM_HYLIAN_LUCK, SubSkillType.HERBALISM_SHROOM_THUMB)),
+    MINING(MiningManager.class, Color.GRAY, SuperAbilityType.SUPER_BREAKER, ToolType.PICKAXE,
+            ImmutableList.of(SubSkillType.MINING_SUPER_BREAKER, SubSkillType.MINING_DEMOLITIONS_EXPERTISE, SubSkillType.MINING_BIGGER_BOMBS, SubSkillType.MINING_BLAST_MINING, SubSkillType.MINING_DOUBLE_DROPS)),
+    REPAIR(RepairManager.class, Color.SILVER,
+            ImmutableList.of(SubSkillType.REPAIR_ARCANE_FORGING, SubSkillType.REPAIR_REPAIR_MASTERY, SubSkillType.REPAIR_SUPER_REPAIR)),
+    SALVAGE(SalvageManager.class, Color.ORANGE,
+            ImmutableList.of(SubSkillType.SALVAGE_ADVANCED_SALVAGE, SubSkillType.SALVAGE_ARCANE_SALVAGE)),
+    SMELTING(SmeltingManager.class, Color.YELLOW,
+            ImmutableList.of(SubSkillType.SMELTING_UNDERSTANDING_THE_ART, /*SubSkillType.SMELTING_FLUX_MINING,*/ SubSkillType.SMELTING_FUEL_EFFICIENCY, SubSkillType.SMELTING_SECOND_SMELT)),
+    SWORDS(SwordsManager.class, Color.fromRGB(178, 34, 34), SuperAbilityType.SERRATED_STRIKES, ToolType.SWORD,
+            ImmutableList.of(SubSkillType.SWORDS_SERRATED_STRIKES, SubSkillType.SWORDS_SWORDS_LIMIT_BREAK, SubSkillType.SWORDS_STAB, SubSkillType.SWORDS_RUPTURE, SubSkillType.SWORDS_COUNTER_ATTACK)),
+    TAMING(TamingManager.class, Color.PURPLE,
+            ImmutableList.of(SubSkillType.TAMING_BEAST_LORE, SubSkillType.TAMING_CALL_OF_THE_WILD, SubSkillType.TAMING_ENVIRONMENTALLY_AWARE, SubSkillType.TAMING_FAST_FOOD_SERVICE, SubSkillType.TAMING_GORE, SubSkillType.TAMING_HOLY_HOUND, SubSkillType.TAMING_SHARPENED_CLAWS, SubSkillType.TAMING_SHOCK_PROOF, SubSkillType.TAMING_THICK_FUR, SubSkillType.TAMING_PUMMEL)),
+    UNARMED(UnarmedManager.class, Color.BLACK, SuperAbilityType.BERSERK, ToolType.FISTS,
+            ImmutableList.of(SubSkillType.UNARMED_BERSERK, SubSkillType.UNARMED_UNARMED_LIMIT_BREAK, SubSkillType.UNARMED_BLOCK_CRACKER, SubSkillType.UNARMED_ARROW_DEFLECT, SubSkillType.UNARMED_DISARM, SubSkillType.UNARMED_IRON_ARM_STYLE, SubSkillType.UNARMED_IRON_GRIP)),
+    WOODCUTTING(WoodcuttingManager.class, Color.OLIVE, SuperAbilityType.TREE_FELLER, ToolType.AXE,
+            ImmutableList.of(SubSkillType.WOODCUTTING_LEAF_BLOWER, SubSkillType.WOODCUTTING_TREE_FELLER, SubSkillType.WOODCUTTING_HARVEST_LUMBER));
 
     private Class<? extends SkillManager> managerClass;
     private Color runescapeColor;

+ 5 - 0
src/main/java/com/gmail/nossr50/datatypes/skills/SubSkillType.java

@@ -18,10 +18,12 @@ public enum SubSkillType {
     ARCHERY_ARROW_RETRIEVAL(1),
     ARCHERY_DAZE,
     ARCHERY_SKILL_SHOT(20),
+    ARCHERY_ARCHERY_LIMIT_BREAK(10),
 
     /* Axes */
     AXES_ARMOR_IMPACT(20),
     AXES_AXE_MASTERY(4),
+    AXES_AXES_LIMIT_BREAK(10),
     AXES_CRITICAL_STRIKES(1),
     AXES_GREATER_IMPACT(1),
     AXES_SKULL_SPLITTER(1),
@@ -71,6 +73,8 @@ public enum SubSkillType {
     SWORDS_COUNTER_ATTACK(1),
     SWORDS_RUPTURE(4),
     SWORDS_SERRATED_STRIKES(1),
+    SWORDS_STAB(2),
+    SWORDS_SWORDS_LIMIT_BREAK(10),
 
     /* Taming */
     TAMING_BEAST_LORE(1),
@@ -91,6 +95,7 @@ public enum SubSkillType {
     UNARMED_DISARM(1),
     UNARMED_IRON_ARM_STYLE(5),
     UNARMED_IRON_GRIP(1),
+    UNARMED_UNARMED_LIMIT_BREAK(10),
 
     /* Woodcutting */
 /*    WOODCUTTING_BARK_SURGEON(3),*/

+ 10 - 4
src/main/java/com/gmail/nossr50/listeners/BlockListener.java

@@ -62,21 +62,27 @@ public class BlockListener implements Listener {
         {
             ItemStack is = new ItemStack(item.getItemStack());
 
-            if(is.getAmount() <= 0)
+            if(!event.getBlock().getDrops().contains(is))
                 continue;
 
-            //Extra Protection
-            if(event.getBlock().getState() instanceof Container)
-                return;
+            if(is.getAmount() <= 0)
+                continue;
 
             if(event.getBlock().getState().getMetadata(mcMMO.doubleDropKey).size() > 0)
             {
+                //Extra Protection
+                if(event.getBlock().getState() instanceof Container)
+                    return;
+
                 event.getBlock().getState().removeMetadata(mcMMO.doubleDropKey, plugin);
                 event.getBlock().getState().getWorld().dropItemNaturally(event.getBlockState().getLocation(), is);
             }
 
             else if(event.getBlock().getState().getMetadata(mcMMO.tripleDropKey).size() > 0)
             {
+                //Extra Protection
+                if(event.getBlock().getState() instanceof Container)
+                    return;
                 event.getBlock().getState().removeMetadata(mcMMO.tripleDropKey, plugin);
                 event.getBlock().getState().getWorld().dropItemNaturally(event.getBlockState().getLocation(), is);
                 event.getBlock().getState().getWorld().dropItemNaturally(event.getBlockState().getLocation(), is);

+ 27 - 3
src/main/java/com/gmail/nossr50/listeners/EntityListener.java

@@ -187,7 +187,7 @@ public class EntityListener implements Listener {
         }
     }
 
-/*    @EventHandler(priority = EventPriority.LOWEST, ignoreCancelled = true)
+    /*@EventHandler(priority = EventPriority.LOWEST, ignoreCancelled = true)
     public void onEntityDamageDebugLowest(EntityDamageEvent event)
     {
         if(event instanceof FakeEntityDamageByEntityEvent)
@@ -196,7 +196,8 @@ public class EntityListener implements Listener {
         if(event instanceof FakeEntityDamageEvent)
             return;
 
-        Bukkit.broadcastMessage(ChatColor.GOLD+"DMG Before Events: "+ChatColor.RESET+event.getDamage());
+        Bukkit.broadcastMessage(ChatColor.DARK_AQUA+"DMG Before Events: "
+                +ChatColor.RESET+event.getDamage());
     }
 
     @EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true)
@@ -208,9 +209,30 @@ public class EntityListener implements Listener {
         if(event instanceof FakeEntityDamageEvent)
             return;
 
+        if(!(event.getEntity() instanceof LivingEntity))
+            return;
+
+        LivingEntity entity = (LivingEntity) event.getEntity();
+
         double rawDamage = event.getDamage();
         double dmgAfterReduction = event.getFinalDamage();
-        Bukkit.broadcastMessage(ChatColor.GOLD+"DEBUG: " + event.getEntity().getName()+ChatColor.RESET+"RawDMG["+rawDamage+"], "+"FinalDMG=["+dmgAfterReduction+"]");
+
+        Bukkit.broadcastMessage(ChatColor.GOLD+"DMG After Events: "
+                + event.getEntity().getName()+ChatColor.RESET
+                +"RawDMG["+rawDamage+"], "
+                +"FinalDMG=["+dmgAfterReduction+"]");
+
+        Bukkit.broadcastMessage(
+                event.getEntity().getName()
+                +ChatColor.GREEN
+                +" HP "
+                +ChatColor.RESET
+                +entity.getHealth()
+                +ChatColor.YELLOW
+                +" -> "
+                +ChatColor.RESET
+                +(entity.getHealth()-event.getFinalDamage()));
+
         Bukkit.broadcastMessage("");
     }*/
 
@@ -381,6 +403,8 @@ public class EntityListener implements Listener {
                 }
             }
         }
+
+
     }
 
     /**

+ 1 - 1
src/main/java/com/gmail/nossr50/skills/fishing/FishingManager.java

@@ -420,7 +420,7 @@ public class FishingManager extends SkillManager {
             }
 
             Misc.dropItem(target.getLocation(), drop);
-            CombatUtils.dealDamage(target, Math.max(target.getMaxHealth() / 4, 1), EntityDamageEvent.DamageCause.CUSTOM, getPlayer()); // Make it so you can shake a mob no more than 4 times.
+            CombatUtils.dealDamage(target, Math.min(Math.max(target.getMaxHealth() / 4, 1), 10), EntityDamageEvent.DamageCause.CUSTOM, getPlayer()); // Make it so you can shake a mob no more than 4 times.
             applyXpGain(ExperienceConfig.getInstance().getFishingShakeXP(), XPGainReason.PVE);
         }
     }

+ 0 - 2
src/main/java/com/gmail/nossr50/skills/swords/Swords.java

@@ -4,10 +4,8 @@ import com.gmail.nossr50.config.AdvancedConfig;
 
 public class Swords {
     public static int    bleedMaxTicks      = AdvancedConfig.getInstance().getRuptureMaxTicks();
-    public static int    bleedBaseTicks     = AdvancedConfig.getInstance().getRuptureBaseTicks();
 
     public static double  counterAttackModifier      = AdvancedConfig.getInstance().getCounterModifier();
 
     public static double serratedStrikesModifier   = AdvancedConfig.getInstance().getSerratedStrikesModifier();
-    public static int    serratedStrikesBleedTicks = AdvancedConfig.getInstance().getSerratedStrikesTicks();
 }

+ 17 - 0
src/main/java/com/gmail/nossr50/skills/swords/SwordsManager.java

@@ -33,6 +33,10 @@ public class SwordsManager extends SkillManager {
         return mcMMOPlayer.getToolPreparationMode(ToolType.SWORD) && Permissions.serratedStrikes(getPlayer());
     }
 
+    public boolean canUseStab() {
+        return Permissions.isSubSkillEnabled(getPlayer(), SubSkillType.SWORDS_STAB) && RankUtils.hasUnlockedSubskill(getPlayer(), SubSkillType.SWORDS_STAB);
+    }
+
     public boolean canUseRupture() {
         return Permissions.isSubSkillEnabled(getPlayer(), SubSkillType.SWORDS_RUPTURE) && RankUtils.hasUnlockedSubskill(getPlayer(), SubSkillType.SWORDS_RUPTURE);
     }
@@ -80,6 +84,19 @@ public class SwordsManager extends SkillManager {
         }
     }
 
+    public double getStabDamage()
+    {
+        int rank = RankUtils.getRank(getPlayer(), SubSkillType.SWORDS_STAB);
+
+        if(rank > 0)
+        {
+            double stabDamage = 1.0D + (rank * 1.5);
+            return stabDamage;
+        }
+
+        return 0;
+    }
+
     public int getToolTier(ItemStack itemStack)
     {
         if(ItemUtils.isDiamondTool(itemStack))

+ 8 - 1
src/main/java/com/gmail/nossr50/skills/unarmed/UnarmedManager.java

@@ -151,7 +151,14 @@ public class UnarmedManager extends SkillManager {
     }
 
     public double getIronArmDamage() {
-        return RankUtils.getRank(getPlayer(), SubSkillType.UNARMED_IRON_ARM_STYLE) * 2;
+        int rank = RankUtils.getRank(getPlayer(), SubSkillType.UNARMED_IRON_ARM_STYLE);
+
+        if(rank == 1)
+        {
+            return 4;
+        } else {
+            return 3 + (rank * 2);
+        }
     }
 
     /**

+ 64 - 23
src/main/java/com/gmail/nossr50/util/skills/CombatUtils.java

@@ -5,6 +5,7 @@ import com.gmail.nossr50.datatypes.experience.XPGainReason;
 import com.gmail.nossr50.datatypes.interactions.NotificationType;
 import com.gmail.nossr50.datatypes.player.McMMOPlayer;
 import com.gmail.nossr50.datatypes.skills.PrimarySkillType;
+import com.gmail.nossr50.datatypes.skills.SubSkillType;
 import com.gmail.nossr50.events.fake.FakeEntityDamageByEntityEvent;
 import com.gmail.nossr50.events.fake.FakeEntityDamageEvent;
 import com.gmail.nossr50.mcMMO;
@@ -21,7 +22,6 @@ import com.gmail.nossr50.util.*;
 import com.gmail.nossr50.util.player.NotificationManager;
 import com.gmail.nossr50.util.player.UserManager;
 import com.google.common.collect.ImmutableMap;
-import org.bukkit.Bukkit;
 import org.bukkit.GameMode;
 import org.bukkit.Material;
 import org.bukkit.entity.*;
@@ -47,6 +47,7 @@ public final class CombatUtils {
         McMMOPlayer mcMMOPlayer = UserManager.getPlayer(player);
         SwordsManager swordsManager = mcMMOPlayer.getSwordsManager();
         double initialDamage = event.getDamage();
+        double finalDamage = initialDamage;
 
         Map<DamageModifier, Double> modifiers = getModifiers(event);
 
@@ -61,10 +62,22 @@ public final class CombatUtils {
             }
         }
 
+        //Add Stab Damage
+        if(swordsManager.canUseStab())
+        {
+            finalDamage+=swordsManager.getStabDamage();
+        }
+
         if (swordsManager.canUseSerratedStrike()) {
             swordsManager.serratedStrikes(target, initialDamage, modifiers);
         }
 
+        if(canUseLimitBreak(player, SubSkillType.SWORDS_SWORDS_LIMIT_BREAK))
+        {
+            finalDamage+=getLimitBreakDamage(player, SubSkillType.SWORDS_SWORDS_LIMIT_BREAK);
+        }
+
+        applyScaledModifiers(initialDamage, finalDamage, event);
         startGainXp(mcMMOPlayer, target, PrimarySkillType.SWORDS);
     }
 
@@ -85,24 +98,29 @@ public final class CombatUtils {
         }
 
         if (axesManager.canUseAxeMastery()) {
-            finalDamage += axesManager.axeMastery();
-        }
-
-        if (axesManager.canCriticalHit(target)) {
-            finalDamage += axesManager.criticalHit(target, initialDamage);
+            finalDamage+=axesManager.axeMastery();
         }
 
         if (axesManager.canImpact(target)) {
             axesManager.impactCheck(target);
         }
         else if (axesManager.canGreaterImpact(target)) {
-            finalDamage += axesManager.greaterImpact(target);
+            finalDamage+=axesManager.greaterImpact(target);
         }
 
         if (axesManager.canUseSkullSplitter(target)) {
             axesManager.skullSplitterCheck(target, initialDamage, modifiers);
         }
 
+        if (axesManager.canCriticalHit(target)) {
+            finalDamage+=axesManager.criticalHit(target, finalDamage);
+        }
+
+        if(canUseLimitBreak(player, SubSkillType.AXES_AXES_LIMIT_BREAK))
+        {
+            finalDamage+=getLimitBreakDamage(player, SubSkillType.AXES_AXES_LIMIT_BREAK);
+        }
+
         applyScaledModifiers(initialDamage, finalDamage, event);
         startGainXp(mcMMOPlayer, target, PrimarySkillType.AXES);
     }
@@ -111,7 +129,7 @@ public final class CombatUtils {
         if (event.getCause() == DamageCause.THORNS) {
             return;
         }
-        
+
         double initialDamage = event.getDamage();
         double finalDamage = initialDamage;
 
@@ -122,25 +140,29 @@ public final class CombatUtils {
             mcMMOPlayer.checkAbilityActivation(PrimarySkillType.UNARMED);
         }
 
-        //Only execute bonuses if the player is not spamming
         if(unarmedManager.isPunchingCooldownOver())
         {
+            //Only execute bonuses if the player is not spamming
             if (unarmedManager.canUseIronArm()) {
-                finalDamage += unarmedManager.ironArm();
+                finalDamage+=unarmedManager.ironArm();
             }
 
             if (unarmedManager.canUseBerserk()) {
-                finalDamage += unarmedManager.berserkDamage(initialDamage);
+                finalDamage+=unarmedManager.berserkDamage(finalDamage);
             }
 
             if (unarmedManager.canDisarm(target)) {
                 unarmedManager.disarmCheck((Player) target);
             }
+
+            if(canUseLimitBreak(player, SubSkillType.UNARMED_UNARMED_LIMIT_BREAK))
+            {
+                finalDamage+=getLimitBreakDamage(player, SubSkillType.UNARMED_UNARMED_LIMIT_BREAK);
+            }
         }
 
         applyScaledModifiers(initialDamage, finalDamage, event);
         startGainXp(mcMMOPlayer, target, PrimarySkillType.UNARMED);
-
         Unarmed.lastAttacked = System.currentTimeMillis(); //Track how often the player is punching
     }
 
@@ -158,11 +180,11 @@ public final class CombatUtils {
         tamingManager.pummel(target, wolf);
 
         if (tamingManager.canUseSharpenedClaws()) {
-            finalDamage += tamingManager.sharpenedClaws();
+            finalDamage+=tamingManager.sharpenedClaws();
         }
 
         if (tamingManager.canUseGore()) {
-            finalDamage += tamingManager.gore(target, initialDamage);
+            finalDamage+=tamingManager.gore(target, initialDamage);
         }
 
         applyScaledModifiers(initialDamage, finalDamage, event);
@@ -171,10 +193,11 @@ public final class CombatUtils {
 
     private static void processArcheryCombat(LivingEntity target, Player player, EntityDamageByEntityEvent event, Arrow arrow) {
         double initialDamage = event.getDamage();
-        double finalDamage = initialDamage;
 
         McMMOPlayer mcMMOPlayer = UserManager.getPlayer(player);
         ArcheryManager archeryManager = mcMMOPlayer.getArcheryManager();
+        
+        double finalDamage = event.getDamage();
 
         if (target instanceof Player && PrimarySkillType.UNARMED.getPVPEnabled()) {
             UnarmedManager unarmedManager = UserManager.getPlayer((Player) target).getUnarmedManager();
@@ -189,17 +212,22 @@ public final class CombatUtils {
         }
 
         if (archeryManager.canSkillShot()) {
-            finalDamage += archeryManager.skillShot(initialDamage);
+            finalDamage+=archeryManager.skillShot(initialDamage);
         }
 
         if (archeryManager.canDaze(target)) {
-            finalDamage += archeryManager.daze((Player) target);
+            finalDamage+=archeryManager.daze((Player) target);
         }
 
         if (!arrow.hasMetadata(mcMMO.infiniteArrowKey) && archeryManager.canRetrieveArrows()) {
             archeryManager.retrieveArrows(target);
         }
 
+        if(canUseLimitBreak(player, SubSkillType.ARCHERY_ARCHERY_LIMIT_BREAK))
+        {
+            finalDamage+=getLimitBreakDamage(player, SubSkillType.ARCHERY_ARCHERY_LIMIT_BREAK);
+        }
+
         double distanceMultiplier = archeryManager.distanceXpBonusMultiplier(target, arrow);
 
         applyScaledModifiers(initialDamage, finalDamage, event);
@@ -212,8 +240,7 @@ public final class CombatUtils {
      * @param event The event to run the combat checks on.
      */
     public static void processCombatAttack(EntityDamageByEntityEvent event, Entity attacker, LivingEntity target) {
-        Entity damager = event.getDamager();
-        EntityType entityType = damager.getType();
+        EntityType entityType = attacker.getType();
 
         if (attacker instanceof Player && entityType == EntityType.PLAYER) {
             Player player = (Player) attacker;
@@ -270,7 +297,7 @@ public final class CombatUtils {
         }
 
         else if (entityType == EntityType.WOLF) {
-            Wolf wolf = (Wolf) damager;
+            Wolf wolf = (Wolf) attacker;
             AnimalTamer tamer = wolf.getOwner();
 
             if (tamer != null && tamer instanceof Player && PrimarySkillType.TAMING.shouldProcess(target)) {
@@ -282,7 +309,7 @@ public final class CombatUtils {
             }
         }
         else if (entityType == EntityType.ARROW) {
-            Arrow arrow = (Arrow) damager;
+            Arrow arrow = (Arrow) attacker;
             ProjectileSource projectileSource = arrow.getShooter();
 
             if (projectileSource != null && projectileSource instanceof Player && PrimarySkillType.ARCHERY.shouldProcess(target)) {
@@ -323,13 +350,27 @@ public final class CombatUtils {
 
                 SwordsManager swordsManager = mcMMOPlayer.getSwordsManager();
 
-                if (swordsManager.canUseCounterAttack(damager)) {
-                    swordsManager.counterAttackChecks((LivingEntity) damager, event.getDamage());
+                if (swordsManager.canUseCounterAttack(attacker)) {
+                    swordsManager.counterAttackChecks((LivingEntity) attacker, event.getDamage());
                 }
             }
         }
     }
 
+    public static int getLimitBreakDamage(Player player, SubSkillType subSkillType) {
+        return RankUtils.getRank(player, subSkillType);
+    }
+
+    /**
+     * Checks if player has access to their weapons limit break
+     * @param player target player
+     * @return true if the player has access to the limit break
+     */
+    public static boolean canUseLimitBreak(Player player, SubSkillType subSkillType) {
+        return RankUtils.hasUnlockedSubskill(player, subSkillType)
+                && Permissions.isSubSkillEnabled(player, subSkillType);
+    }
+
     /**
      * Attempt to damage target for value dmg with reason CUSTOM
      *

+ 15 - 0
src/main/resources/plugin.yml

@@ -248,6 +248,9 @@ permissions:
             mcmmo.ability.archery.skillshot: true
             mcmmo.ability.archery.daze: true
             mcmmo.ability.archery.arrowretrieval: true
+            mcmmo.ability.archery.archerylimitbreak: true
+    mcmmo.ability.archery.archerylimitbreak:
+        description: Adds damage to bows and crossbows
     mcmmo.ability.archery.skillshot:
         description: Allows bonus damage from the Archery SkillShot ability
     mcmmo.ability.archery.daze:
@@ -267,6 +270,9 @@ permissions:
             mcmmo.ability.axes.greaterimpact: true
             mcmmo.ability.axes.armorimpact: true
             mcmmo.ability.axes.skullsplitter: true
+            mcmmo.ability.axes.axeslimitbreak: true
+    mcmmo.ability.axes.axeslimitbreak:
+        description: Adds damage to axes
     mcmmo.ability.axes.axemastery:
         description: Allows bonus damage from Axes
     mcmmo.ability.axes.criticalhit:
@@ -561,8 +567,14 @@ permissions:
         description: Allows access to all Swords abilities
         children:
             mcmmo.ability.swords.rupture: true
+            mcmmo.ability.swords.stab: true
             mcmmo.ability.swords.counterattack: true
             mcmmo.ability.swords.serratedstrikes: true
+            mcmmo.ability.swords.swordslimitbreak: true
+    mcmmo.ability.swords.stab:
+        description: Adds damage to swords
+    mcmmo.ability.swords.swordslimitbreak:
+        description: Adds damagee to swords
     mcmmo.ability.swords.rupture:
         description: Allows access to the Bleed ability
     mcmmo.ability.swords.counterattack:
@@ -639,6 +651,9 @@ permissions:
             mcmmo.ability.unarmed.arrowdeflect: true
             mcmmo.ability.unarmed.disarm: true
             mcmmo.ability.unarmed.irongrip: true
+            mcmmo.ability.unarmed.unarmedlimitbreak: true
+    mcmmo.ability.unarmed.unarmedlimitbreak:
+        description: Adds damage to unarmed attacks
     mcmmo.ability.unarmed.berserk:
         description: Allows access to the Berserker ability
     mcmmo.ability.unarmed.blockcracker:

+ 103 - 4
src/main/resources/skillranks.yml

@@ -8,12 +8,12 @@
 Alchemy:
     Catalysis:
         Standard:
-            Rank_1: 10
+            Rank_1: 0
         RetroMode:
-            Rank_1: 100
+            Rank_1: 0
     Concoctions:
         Standard:
-            Rank_1: 10
+            Rank_1: 0
             Rank_2: 25
             Rank_3: 35
             Rank_4: 50
@@ -22,7 +22,7 @@ Alchemy:
             Rank_7: 85
             Rank_8: 100
         RetroMode:
-            Rank_1: 100
+            Rank_1: 0
             Rank_2: 250
             Rank_3: 350
             Rank_4: 500
@@ -31,6 +31,29 @@ Alchemy:
             Rank_7: 850
             Rank_8: 1000
 Archery:
+    ArcheryLimitBreak:
+        Standard:
+            Rank_1: 10
+            Rank_2: 20
+            Rank_3: 30
+            Rank_4: 40
+            Rank_5: 50
+            Rank_6: 60
+            Rank_7: 70
+            Rank_8: 80
+            Rank_9: 90
+            Rank_10: 100
+        RetroMode:
+            Rank_1: 100
+            Rank_2: 200
+            Rank_3: 300
+            Rank_4: 400
+            Rank_5: 500
+            Rank_6: 600
+            Rank_7: 700
+            Rank_8: 800
+            Rank_9: 900
+            Rank_10: 1000
     ArrowRetrieval:
         Standard:
             Rank_1: 2
@@ -86,6 +109,29 @@ Acrobatics:
         RetroMode:
             Rank_1: 20
 Axes:
+    AxesLimitBreak:
+        Standard:
+            Rank_1: 10
+            Rank_2: 20
+            Rank_3: 30
+            Rank_4: 40
+            Rank_5: 50
+            Rank_6: 60
+            Rank_7: 70
+            Rank_8: 80
+            Rank_9: 90
+            Rank_10: 100
+        RetroMode:
+            Rank_1: 100
+            Rank_2: 200
+            Rank_3: 300
+            Rank_4: 400
+            Rank_5: 500
+            Rank_6: 600
+            Rank_7: 700
+            Rank_8: 800
+            Rank_9: 900
+            Rank_10: 1000
     SkullSplitter:
         Standard:
             Rank_1: 5
@@ -381,6 +427,36 @@ Fishing:
             Rank_7: 850
             Rank_8: 1000
 Swords:
+    SwordsLimitBreak:
+        Standard:
+            Rank_1: 10
+            Rank_2: 20
+            Rank_3: 30
+            Rank_4: 40
+            Rank_5: 50
+            Rank_6: 60
+            Rank_7: 70
+            Rank_8: 80
+            Rank_9: 90
+            Rank_10: 100
+        RetroMode:
+            Rank_1: 100
+            Rank_2: 200
+            Rank_3: 300
+            Rank_4: 400
+            Rank_5: 500
+            Rank_6: 600
+            Rank_7: 700
+            Rank_8: 800
+            Rank_9: 900
+            Rank_10: 1000
+    Stab:
+        Standard:
+            Rank_1: 75
+            Rank_2: 100
+        RetroMode:
+            Rank_1: 750
+            Rank_2: 1000
     CounterAttack:
         Standard:
             Rank_1: 20
@@ -403,6 +479,29 @@ Swords:
         RetroMode:
             Rank_1: 100
 Unarmed:
+    UnarmedLimitBreak:
+        Standard:
+            Rank_1: 10
+            Rank_2: 20
+            Rank_3: 30
+            Rank_4: 40
+            Rank_5: 50
+            Rank_6: 60
+            Rank_7: 70
+            Rank_8: 80
+            Rank_9: 90
+            Rank_10: 100
+        RetroMode:
+            Rank_1: 100
+            Rank_2: 200
+            Rank_3: 300
+            Rank_4: 400
+            Rank_5: 500
+            Rank_6: 600
+            Rank_7: 700
+            Rank_8: 800
+            Rank_9: 900
+            Rank_10: 1000
     Berserk:
         Standard:
             Rank_1: 10