Browse Source

Added config options for Rupture and updated the Swords command

nossr50 4 years ago
parent
commit
affecfeeeb

+ 17 - 2
Changelog.txt

@@ -1,11 +1,26 @@
 Version 2.1.186
     Rupture has been reworked to solve a few outstanding issues (see notes)
-    Removed 'Skills.Swords.Rupture.MaxTicks' from advanced.yml
-    Removed 'Skills.Swords.Rupture.BaseTicks' from advanced.yml
     Gore no longer applies Rupture
     Gore no longer sends a message to the Wolf owner when it triggers
     Gore no longer sends a message to players that are hit by it
     Rupture no longer sends a message telling you that your target is bleeding
+    Updated locale string 'Swords.SubSkill.Rupture.Description'
+    Updated locale string 'Swords.SubSkill.Rupture.Stat.Extra'
+    Updated locale string 'Swords.Combat.Rupture.Note'
+    Added 'Skills.Swords.Rupture.Rupture_Mechanics.Chance_To_Apply_On_Hit' to advanced.yml
+    Added 'Skills.Swords.Rupture.Rupture_Mechanics.Duration_In_Seconds.Against_Players' to advanced.yml
+    Added 'Skills.Swords.Rupture.Rupture_Mechanics.Duration_In_Seconds.Against_Mobs' to advanced.yml
+    Added 'Skills.Swords.Rupture.Rupture_Mechanics.Tick_Interval_Damage.Against_Players' to advanced.yml
+    Added 'Skills.Swords.Rupture.Rupture_Mechanics.Tick_Interval_Damage.Against_Mobs' to advanced.yml
+    Added 'Skills.Swords.Rupture.Rupture_Mechanics.Explosion_Damage.Against_Players' to advanced.yml
+    Added 'Skills.Swords.Rupture.Rupture_Mechanics.Explosion_Damage.Against_Mobs' to advanced.yml
+    Removed 'Skills.Swords.Rupture.ChanceMax' from advanced.yml
+    Removed 'Skills.Swords.Rupture.MaxBonusLevel.Standard' from advanced.yml
+    Removed 'Skills.Swords.Rupture.MaxBonusLevel.RetroMode' from advanced.yml
+    Removed 'Skills.Swords.Rupture.MaxTicks' from advanced.yml
+    Removed 'Skills.Swords.Rupture.BaseTicks' from advanced.yml
+    Removed 'Skills.Swords.Rupture.DamagePlayer' from advanced.yml
+    Removed 'Skills.Swords.Rupture.DamageMobs' from advanced.yml
 
     NOTES:
     The old Rupture would constantly interfere with your ability to do a Sweep Attack/Swipe with swords, the new one solves this problem

+ 28 - 20
src/main/java/com/gmail/nossr50/commands/skills/SwordsCommand.java

@@ -1,6 +1,7 @@
 package com.gmail.nossr50.commands.skills;
 
 import com.gmail.nossr50.config.AdvancedConfig;
+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.locale.LocaleLoader;
@@ -19,15 +20,16 @@ import java.util.List;
 public class SwordsCommand extends SkillCommand {
     private String counterChance;
     private String counterChanceLucky;
-    private int bleedLength;
-    private String bleedChance;
-    private String bleedChanceLucky;
     private String serratedStrikesLength;
     private String serratedStrikesLengthEndurance;
 
+    private String rupturePureTickDamageAgainstPlayers, rupturePureTickDamageAgainstMobs,
+            ruptureExplosionDamageAgainstPlayers, ruptureExplosionDamageAgainstMobs,
+            ruptureLengthSecondsAgainstPlayers, ruptureLengthSecondsAgainstMobs, ruptureChanceToApply, ruptureChanceToApplyLucky;
+
     private boolean canCounter;
     private boolean canSerratedStrike;
-    private boolean canBleed;
+    private boolean canRupture;
 
     public SwordsCommand() {
         super(PrimarySkillType.SWORDS);
@@ -43,12 +45,19 @@ public class SwordsCommand extends SkillCommand {
         }
 
         // SWORDS_RUPTURE
-        if (canBleed) {
-            bleedLength = UserManager.getPlayer(player).getSwordsManager().getRuptureBleedTicks();
+        if (canRupture) {
+            int ruptureRank = RankUtils.getRank(player, SubSkillType.SWORDS_RUPTURE);
+            ruptureLengthSecondsAgainstPlayers = String.valueOf(AdvancedConfig.getInstance().getRuptureDurationSeconds(true));
+            ruptureLengthSecondsAgainstMobs = String.valueOf(AdvancedConfig.getInstance().getRuptureDurationSeconds(false));
+
+            rupturePureTickDamageAgainstPlayers = String.valueOf(AdvancedConfig.getInstance().getRuptureTickDamage(true, ruptureRank));
+            rupturePureTickDamageAgainstMobs = String.valueOf(AdvancedConfig.getInstance().getRuptureTickDamage(false, ruptureRank));
 
-            String[] bleedStrings = getAbilityDisplayValues(SkillActivationType.RANDOM_LINEAR_100_SCALE_WITH_CAP, player, SubSkillType.SWORDS_RUPTURE);
-            bleedChance = bleedStrings[0];
-            bleedChanceLucky = bleedStrings[1];
+            ruptureExplosionDamageAgainstPlayers = String.valueOf(AdvancedConfig.getInstance().getRuptureExplosionDamage(true, ruptureRank));
+            ruptureExplosionDamageAgainstMobs = String.valueOf(AdvancedConfig.getInstance().getRuptureExplosionDamage(false, ruptureRank));
+
+            ruptureChanceToApply = String.valueOf(AdvancedConfig.getInstance().getRuptureChanceToApplyOnHit(ruptureRank));
+            ruptureChanceToApplyLucky = String.valueOf(AdvancedConfig.getInstance().getRuptureChanceToApplyOnHit(ruptureRank) * 1.33);
         }
         
         // SERRATED STRIKES
@@ -61,7 +70,7 @@ public class SwordsCommand extends SkillCommand {
 
     @Override
     protected void permissionsCheck(Player player) {
-        canBleed = canUseSubskill(player, SubSkillType.SWORDS_RUPTURE);
+        canRupture = canUseSubskill(player, SubSkillType.SWORDS_RUPTURE);
         canCounter = canUseSubskill(player, SubSkillType.SWORDS_COUNTER_ATTACK);
         canSerratedStrike = RankUtils.hasUnlockedSubskill(player, SubSkillType.SWORDS_SERRATED_STRIKES) && Permissions.serratedStrikes(player);
     }
@@ -70,22 +79,21 @@ public class SwordsCommand extends SkillCommand {
     protected List<String> statsDisplay(Player player, float skillValue, boolean hasEndurance, boolean isLucky) {
         List<String> messages = new ArrayList<>();
 
-        int ruptureTicks = UserManager.getPlayer(player).getSwordsManager().getRuptureBleedTicks();
-        double ruptureDamagePlayers =  RankUtils.getRank(player, SubSkillType.SWORDS_RUPTURE) >= 3 ? AdvancedConfig.getInstance().getRuptureDamagePlayer() * 1.5D : AdvancedConfig.getInstance().getRuptureDamagePlayer();
-        double ruptureDamageMobs =  RankUtils.getRank(player, SubSkillType.SWORDS_RUPTURE) >= 3 ? AdvancedConfig.getInstance().getRuptureDamageMobs() * 1.5D : AdvancedConfig.getInstance().getRuptureDamageMobs();
-
         if (canCounter) {
             messages.add(getStatMessage(SubSkillType.SWORDS_COUNTER_ATTACK, counterChance)
                     + (isLucky ? LocaleLoader.getString("Perks.Lucky.Bonus", counterChanceLucky) : ""));
         }
 
-        if (canBleed) {
-            messages.add(getStatMessage(SubSkillType.SWORDS_RUPTURE, bleedChance)
-                    + (isLucky ? LocaleLoader.getString("Perks.Lucky.Bonus", bleedChanceLucky) : ""));
+        if (canRupture) {
+            messages.add(getStatMessage(SubSkillType.SWORDS_RUPTURE, ruptureChanceToApply)
+                    + (isLucky ? LocaleLoader.getString("Perks.Lucky.Bonus", ruptureChanceToApplyLucky) : ""));
             messages.add(getStatMessage(true, true, SubSkillType.SWORDS_RUPTURE,
-                    String.valueOf(ruptureTicks),
-                    String.valueOf(ruptureDamagePlayers),
-                    String.valueOf(ruptureDamageMobs)));
+                    ruptureLengthSecondsAgainstPlayers,
+                    ruptureLengthSecondsAgainstMobs,
+                    rupturePureTickDamageAgainstPlayers,
+                    rupturePureTickDamageAgainstMobs,
+                    ruptureExplosionDamageAgainstPlayers,
+                    ruptureExplosionDamageAgainstMobs));
 
             messages.add(LocaleLoader.getString("Swords.Combat.Rupture.Note"));
         }

+ 27 - 49
src/main/java/com/gmail/nossr50/config/AdvancedConfig.java

@@ -5,6 +5,9 @@ import com.gmail.nossr50.datatypes.skills.SubSkillType;
 import com.gmail.nossr50.datatypes.skills.subskills.AbstractSubSkill;
 import com.gmail.nossr50.mcMMO;
 import net.md_5.bungee.api.ChatColor;
+import org.bukkit.entity.LivingEntity;
+import org.bukkit.entity.Player;
+import org.jetbrains.annotations.NotNull;
 
 import java.util.ArrayList;
 import java.util.List;
@@ -310,25 +313,6 @@ public class AdvancedConfig extends AutoUpdateConfigLoader {
         }
 
         /* SWORDS */
-        if (getMaximumProbability(SubSkillType.SWORDS_RUPTURE) < 1) {
-            reason.add("Skills.Swords.Rupture.ChanceMax should be at least 1!");
-        }
-
-        if (getMaxBonusLevel(SubSkillType.SWORDS_RUPTURE) < 1) {
-            reason.add("Skills.Swords.Rupture.MaxBonusLevel should be at least 1!");
-        }
-
-        if (getRuptureMaxTicks() < 1) {
-            reason.add("Skills.Swords.Rupture.MaxTicks should be at least 1!");
-        }
-
-        if (getRuptureMaxTicks() < getRuptureBaseTicks()) {
-            reason.add("Skills.Swords.Rupture.MaxTicks should be at least Skills.Swords.Rupture.BaseTicks!");
-        }
-
-        if (getRuptureBaseTicks() < 1) {
-            reason.add("Skills.Swords.Rupture.BaseTicks should be at least 1!");
-        }
 
         if (getMaximumProbability(SubSkillType.SWORDS_COUNTER_ATTACK) < 1) {
             reason.add("Skills.Swords.CounterAttack.ChanceMax should be at least 1!");
@@ -665,13 +649,11 @@ public class AdvancedConfig extends AutoUpdateConfigLoader {
     public double getGracefulRollDamageThreshold() { return config.getDouble("Skills.Acrobatics.GracefulRoll.DamageThreshold", 14.0D); }
 
     /* ALCHEMY */
-    /*public int getCatalysisUnlockLevel() { return config.getInt("Skills.Alchemy.Catalysis.UnlockLevel", 100); }*/
     public int getCatalysisMaxBonusLevel() { return config.getInt("Skills.Alchemy.Catalysis.MaxBonusLevel", 1000); }
 
     public double getCatalysisMinSpeed() { return config.getDouble("Skills.Alchemy.Catalysis.MinSpeed", 1.0D); }
     public double getCatalysisMaxSpeed() { return config.getDouble("Skills.Alchemy.Catalysis.MaxSpeed", 4.0D); }
 
-    //public int getConcoctionsTierLevel(Alchemy.Tier tier) { return config.getInt("Skills.Alchemy.Rank_Levels.Rank_" + rank); }
 
     /* ARCHERY */
     public double getSkillShotRankDamageMultiplier() { return config.getDouble("Skills.Archery.SkillShot.RankDamageMultiplier", 10.0D); }
@@ -700,7 +682,6 @@ public class AdvancedConfig extends AutoUpdateConfigLoader {
     //Nothing to configure, everything is already configurable in config.yml
 
     /* FISHING */
-    //public int getFishingTierLevel(int rank) { return config.getInt("Skills.Fishing.Rank_Levels.Rank_" + rank); }
     public double getShakeChance(int rank) { return config.getDouble("Skills.Fishing.ShakeChance.Rank_" + rank); }
     public int getFishingVanillaXPModifier(int rank) { return config.getInt("Skills.Fishing.VanillaXPMultiplier.Rank_" + rank); }
 
@@ -712,9 +693,7 @@ public class AdvancedConfig extends AutoUpdateConfigLoader {
     public int getFishingReductionMaxWaitCap() { return config.getInt("Skills.Fishing.MasterAngler.Tick_Reduction_Caps.Max_Wait", 100);}
     public int getFishermanDietRankChange() { return config.getInt("Skills.Fishing.FishermansDiet.RankChange", 200); }
 
-    /*public int getIceFishingUnlockLevel() { return config.getInt("Skills.Fishing.IceFishing.UnlockLevel", 50); }
 
-    public int getMasterAnglerUnlockLevel() {return config.getInt("Skills.Fishing.MasterAngler.UnlockLevel", 125); }*/
     public double getMasterAnglerBoatModifier() {return config.getDouble("Skills.Fishing.MasterAngler.BoatModifier", 2.0); }
     public double getMasterAnglerBiomeModifier() {return config.getDouble("Skills.Fishing.MasterAngler.BiomeModifier", 2.0); }
 
@@ -737,23 +716,15 @@ public class AdvancedConfig extends AutoUpdateConfigLoader {
     public double getRepairMasteryMaxBonus() { return config.getDouble("Skills.Repair.RepairMastery.MaxBonusPercentage", 200.0D); }
     public int getRepairMasteryMaxLevel() { return config.getInt("Skills.Repair.RepairMastery.MaxBonusLevel", 100); }
 
-    /* Arcane Forging */
-    //public int getArcaneForgingRankLevel(int rank) { return config.getInt("Skills.Repair.ArcaneForging.Rank_Levels.Rank_" + rank); }
-
     public boolean getArcaneForgingEnchantLossEnabled() { return config.getBoolean("Skills.Repair.ArcaneForging.May_Lose_Enchants", true); }
     public double getArcaneForgingKeepEnchantsChance(int rank) { return config.getDouble("Skills.Repair.ArcaneForging.Keep_Enchants_Chance.Rank_" + rank); }
 
     public boolean getArcaneForgingDowngradeEnabled() { return config.getBoolean("Skills.Repair.ArcaneForging.Downgrades_Enabled", true); }
     public double getArcaneForgingDowngradeChance(int rank) { return config.getDouble("Skills.Repair.ArcaneForging.Downgrades_Chance.Rank_" + rank); }
 
-    /* SALVAGE */
-    //public double getSalvageMaxPercentage() { return config.getDouble("Skills.Salvage.MaxPercentage", 100.0D); }
-    //public int getSalvageMaxPercentageLevel() { return config.getInt("Skills.Salvage.MaxPercentageLevel", 1000); }
-
     public boolean getArcaneSalvageEnchantDowngradeEnabled() { return config.getBoolean("Skills.Salvage.ArcaneSalvage.EnchantDowngradeEnabled", true); }
     public boolean getArcaneSalvageEnchantLossEnabled() { return config.getBoolean("Skills.Salvage.ArcaneSalvage.EnchantLossEnabled", true); }
 
-    //public int getArcaneSalvageRankLevel(int rank) { return config.getInt("Skills.Salvage.ArcaneSalvage.Rank_Levels.Rank_" + rank); }
     public double getArcaneSalvageExtractFullEnchantsChance(int rank) { return config.getDouble("Skills.Salvage.ArcaneSalvage.ExtractFullEnchant.Rank_" + rank); }
     public double getArcaneSalvageExtractPartialEnchantsChance(int rank) { return config.getDouble("Skills.Salvage.ArcaneSalvage.ExtractPartialEnchant.Rank_" + rank); }
 
@@ -765,19 +736,35 @@ public class AdvancedConfig extends AutoUpdateConfigLoader {
             return config.getInt("Skills.Smelting.FuelEfficiency.Standard.MaxBonusLevel", 100);
     }
 
-    /*public int getFluxMiningUnlockLevel() { return config.getInt("Skills.Smelting.FluxMining.UnlockLevel", 250); }*/
     public double getFluxMiningChance() { return config.getDouble("Skills.Smelting.FluxMining.Chance", 33.0D); }
 
-    public int getSmeltingRankLevel(int rank) { return config.getInt("Skills.Smelting.Rank_Levels.Rank_" + rank); }
+    /* SWORDS */
+    public double getRuptureTickDamage(boolean isTargetPlayer, int rank) {
+        String root = "Skills.Swords.Rupture.Rupture_Mechanics.Tick_Interval_Damage.Against_";
+        String targetType = isTargetPlayer ? "Players" : "Mobs";
+        String key = root + targetType + ".Rank_" + rank;
 
-    public int getSmeltingVanillaXPBoostMultiplier(int rank) { return config.getInt("Skills.Smelting.VanillaXPMultiplier.Rank_" + rank); }
+        return config.getDouble(key, 1.0D);
+    }
 
-    /* SWORDS */
-    public double getRuptureDamagePlayer() { return config.getDouble("Skills.Swords.Rupture.DamagePlayer", 1.0); }
-    public double getRuptureDamageMobs() { return config.getDouble("Skills.Swords.Rupture.DamageMobs", 2.0); }
+    public int getRuptureDurationSeconds(boolean isTargetPlayer) {
+        String root = "Skills.Swords.Rupture.Rupture_Mechanics.Duration_In_Seconds.Against_";
+        String targetType = isTargetPlayer ? "Players" : "Mobs";
+        return config.getInt(root + targetType, 5);
+    }
+
+    public double getRuptureExplosionDamage(boolean isTargetPlayer, int rank) {
+        String root = "Skills.Swords.Rupture.Rupture_Mechanics.Explosion_Damage.Against_";
+        String targetType = isTargetPlayer ? "Players" : "Mobs";
+        String key = root + targetType + ".Rank_" + rank;
 
-    public int getRuptureMaxTicks() { return config.getInt("Skills.Swords.Rupture.MaxTicks", 8); }
-    public int getRuptureBaseTicks() { return config.getInt("Skills.Swords.Rupture.BaseTicks", 2); }
+        return config.getDouble(key, 40.0D);
+    }
+
+    public double getRuptureChanceToApplyOnHit(int rank) {
+        String root = "Skills.Swords.Rupture.Rupture_Mechanics.Chance_To_Apply_On_Hit.Rank_";
+        return config.getDouble(root + rank, 33);
+    }
 
     public double getCounterModifier() { return config.getDouble("Skills.Swords.CounterAttack.DamageModifier", 2.0D); }
 
@@ -785,24 +772,15 @@ public class AdvancedConfig extends AutoUpdateConfigLoader {
     public int getSerratedStrikesTicks() { return config.getInt("Skills.Swords.SerratedStrikes.RuptureTicks", 5); }
 
     /* TAMING */
-    //public int getGoreRuptureTicks() { return config.getInt("Skills.Taming.Gore.RuptureTicks", 2); }
     public double getGoreModifier() { return config.getDouble("Skills.Taming.Gore.Modifier", 2.0D); }
 
-    /*public int getFastFoodUnlock() { return config.getInt("Skills.Taming.FastFood.UnlockLevel", 50); }*/
     public double getFastFoodChance() { return config.getDouble("Skills.Taming.FastFoodService.Chance", 50.0D); }
     public double getPummelChance() { return config.getDouble("Skills.Taming.Pummel.Chance", 10.0D); }
 
-    //public int getEnviromentallyAwareUnlock() { return config.getInt("Skills.Taming.EnvironmentallyAware.UnlockLevel", 100); }
-
-    /*public int getThickFurUnlock() { return config.getInt("Skills.Taming.ThickFur.UnlockLevel", 250); }*/
     public double getThickFurModifier() { return config.getDouble("Skills.Taming.ThickFur.Modifier", 2.0D); }
 
-    /*public int getHolyHoundUnlock() {return config.getInt("Skills.Taming.HolyHound.UnlockLevel", 375); }*/
-
-    /*public int getShockProofUnlock() { return config.getInt("Skills.Taming.ShockProof.UnlockLevel", 500); }*/
     public double getShockProofModifier() { return config.getDouble("Skills.Taming.ShockProof.Modifier", 6.0D); }
 
-    /*public int getSharpenedClawsUnlock() { return config.getInt("Skills.Taming.SharpenedClaws.UnlockLevel", 750); }*/
     public double getSharpenedClawsBonus() { return config.getDouble("Skills.Taming.SharpenedClaws.Bonus", 2.0D); }
 
     public double getMinHorseJumpStrength() { return config.getDouble("Skills.Taming.CallOfTheWild.MinHorseJumpStrength", 0.7D); }

+ 33 - 32
src/main/java/com/gmail/nossr50/runnables/skills/RuptureTask.java

@@ -1,37 +1,38 @@
 package com.gmail.nossr50.runnables.skills;
 
+import com.gmail.nossr50.config.AdvancedConfig;
 import com.gmail.nossr50.datatypes.player.McMMOPlayer;
 import com.gmail.nossr50.mcMMO;
 import com.gmail.nossr50.util.MobHealthbarUtils;
 import com.gmail.nossr50.util.skills.ParticleEffectUtils;
 import com.google.common.base.Objects;
 import org.bukkit.entity.LivingEntity;
+import org.bukkit.entity.Player;
 import org.bukkit.scheduler.BukkitRunnable;
 import org.jetbrains.annotations.NotNull;
 
 public class RuptureTask extends BukkitRunnable {
 
-    public static final int FIVE_SECOND_DURATION = 20 * 5;
     public static final int DAMAGE_TICK_INTERVAL = 10;
 
     private final @NotNull McMMOPlayer ruptureSource;
     private final @NotNull LivingEntity targetEntity;
-    private final int ruptureRank;
     private final int expireTick;
 
     private int ruptureTick;
     private int damageTickTracker;
-    private final double damageValue; //TODO: Make configurable
+    private final double pureTickDamage; //TODO: Make configurable
+    private final double explosionDamage; //TODO: Make configurable
 
-    public RuptureTask(@NotNull McMMOPlayer ruptureSource, @NotNull LivingEntity targetEntity, int ruptureRank, double damageValue) {
+    public RuptureTask(@NotNull McMMOPlayer ruptureSource, @NotNull LivingEntity targetEntity, double pureTickDamage, double explosionDamage) {
         this.ruptureSource = ruptureSource;
         this.targetEntity = targetEntity;
-        this.ruptureRank = ruptureRank;
-        this.expireTick = FIVE_SECOND_DURATION;
-        this.damageValue = damageValue;
+        this.expireTick = AdvancedConfig.getInstance().getRuptureDurationSeconds(targetEntity instanceof Player);
 
         this.ruptureTick = 0;
         this.damageTickTracker = 0;
+        this.pureTickDamage = pureTickDamage;
+        this.explosionDamage = explosionDamage;
     }
 
     @Override
@@ -48,10 +49,11 @@ public class RuptureTask extends BukkitRunnable {
                 if(damageTickTracker >= DAMAGE_TICK_INTERVAL) {
                     damageTickTracker = 0; //Reset
                     ParticleEffectUtils.playBleedEffect(targetEntity); //Animate
+                    double finalDamage = 0; //Used for mob health bars and setting last damage
 
                     if(targetEntity.getHealth() > 0.01) {
                         double healthBeforeRuptureIsApplied = targetEntity.getHealth();
-                        double damagedHealth = healthBeforeRuptureIsApplied - getTickDamage();
+                        double damagedHealth = healthBeforeRuptureIsApplied - calculateAdjustedTickDamage();
 
                         if(damagedHealth <= 0) {
                             mcMMO.p.getLogger().severe("DEBUG: Miscalculating Rupture tick damage");
@@ -59,10 +61,7 @@ public class RuptureTask extends BukkitRunnable {
                             targetEntity.setHealth(damagedHealth); //Hurt entity without the unwanted side effects of damage()
 
                             //TODO: Do we need to set last damage? Double check
-                            double finalDamage = healthBeforeRuptureIsApplied - targetEntity.getHealth();
-
-                            //Update health bars
-                            MobHealthbarUtils.handleMobHealthbars(targetEntity, finalDamage, mcMMO.p);
+                            finalDamage = healthBeforeRuptureIsApplied - targetEntity.getHealth();
 
                             if(finalDamage <= 0) {
                                 mcMMO.p.getLogger().severe("DEBUG: Miscalculating final damage for Rupture");
@@ -72,6 +71,9 @@ public class RuptureTask extends BukkitRunnable {
                             }
                         }
                     }
+
+                    //Update Health bars
+                    MobHealthbarUtils.handleMobHealthbars(targetEntity, finalDamage, mcMMO.p);
                 }
             } else {
                 explode();
@@ -95,8 +97,8 @@ public class RuptureTask extends BukkitRunnable {
         this.cancel(); //Task no longer needed
     }
 
-    private double getTickDamage() {
-        double tickDamage = damageValue;
+    private double calculateAdjustedTickDamage() {
+        double tickDamage = pureTickDamage;
 
         if(targetEntity.getHealth() <= tickDamage) {
             tickDamage = targetEntity.getHealth() - 0.01;
@@ -109,9 +111,21 @@ public class RuptureTask extends BukkitRunnable {
         return tickDamage;
     }
 
-    private int getExplosionDamage() {
-        //TODO: Balance pass
-        return ruptureRank * 10;
+    private double getExplosionDamage() {
+        return explosionDamage;
+    }
+
+    @Override
+    public String toString() {
+        return "RuptureTask{" +
+                "ruptureSource=" + ruptureSource +
+                ", targetEntity=" + targetEntity +
+                ", expireTick=" + expireTick +
+                ", ruptureTick=" + ruptureTick +
+                ", damageTickTracker=" + damageTickTracker +
+                ", pureTickDamage=" + pureTickDamage +
+                ", explosionDamage=" + explosionDamage +
+                '}';
     }
 
     @Override
@@ -119,24 +133,11 @@ public class RuptureTask extends BukkitRunnable {
         if (this == o) return true;
         if (o == null || getClass() != o.getClass()) return false;
         RuptureTask that = (RuptureTask) o;
-        return ruptureRank == that.ruptureRank && expireTick == that.expireTick && ruptureTick == that.ruptureTick && damageTickTracker == that.damageTickTracker && Double.compare(that.damageValue, damageValue) == 0 && Objects.equal(ruptureSource, that.ruptureSource) && Objects.equal(targetEntity, that.targetEntity);
+        return expireTick == that.expireTick && ruptureTick == that.ruptureTick && damageTickTracker == that.damageTickTracker && Double.compare(that.pureTickDamage, pureTickDamage) == 0 && Double.compare(that.explosionDamage, explosionDamage) == 0 && Objects.equal(ruptureSource, that.ruptureSource) && Objects.equal(targetEntity, that.targetEntity);
     }
 
     @Override
     public int hashCode() {
-        return Objects.hashCode(ruptureSource, targetEntity, ruptureRank, expireTick, ruptureTick, damageTickTracker, damageValue);
-    }
-
-    @Override
-    public String toString() {
-        return "RuptureTimerTask{" +
-                "ruptureSource=" + ruptureSource +
-                ", targetEntity=" + targetEntity +
-                ", ruptureRank=" + ruptureRank +
-                ", expireTick=" + expireTick +
-                ", ruptureTick=" + ruptureTick +
-                ", damageTickTracker=" + damageTickTracker +
-                ", damageValue=" + damageValue +
-                '}';
+        return Objects.hashCode(ruptureSource, targetEntity, expireTick, ruptureTick, damageTickTracker, pureTickDamage, explosionDamage);
     }
 }

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

@@ -3,8 +3,6 @@ package com.gmail.nossr50.skills.swords;
 import com.gmail.nossr50.config.AdvancedConfig;
 
 public class Swords {
-    public static int    bleedMaxTicks      = AdvancedConfig.getInstance().getRuptureMaxTicks();
-
     public static double  counterAttackModifier      = AdvancedConfig.getInstance().getCounterModifier();
 
     public static double serratedStrikesModifier   = AdvancedConfig.getInstance().getSerratedStrikesModifier();

+ 5 - 4
src/main/java/com/gmail/nossr50/skills/swords/SwordsManager.java

@@ -89,9 +89,10 @@ public class SwordsManager extends SkillManager {
                 }
             }
 
-            double tickDamageValue = target instanceof Player ? AdvancedConfig.getInstance().getRuptureDamagePlayer() : AdvancedConfig.getInstance().getRuptureDamageMobs();
+            RuptureTask ruptureTask = new RuptureTask(mmoPlayer, target,
+                    AdvancedConfig.getInstance().getRuptureTickDamage(target instanceof Player, getRuptureRank()),
+                    AdvancedConfig.getInstance().getRuptureExplosionDamage(target instanceof Player, getRuptureRank()));
 
-            RuptureTask ruptureTask = new RuptureTask(mmoPlayer, target, RankUtils.getRank(mmoPlayer.getPlayer(), SubSkillType.SWORDS_RUPTURE), tickDamageValue);
             RuptureTaskMeta ruptureTaskMeta = new RuptureTaskMeta(mcMMO.p, ruptureTask);
 
             ruptureTask.runTaskTimer(mcMMO.p, 0, 1);
@@ -133,8 +134,8 @@ public class SwordsManager extends SkillManager {
             return 1;
     }
 
-    public int getRuptureBleedTicks() {
-        return RuptureTask.FIVE_SECOND_DURATION / RuptureTask.DAMAGE_TICK_INTERVAL;
+    public int getRuptureBleedTicks(boolean isTargetPlayer) {
+        return AdvancedConfig.getInstance().getRuptureDurationSeconds(isTargetPlayer) / RuptureTask.DAMAGE_TICK_INTERVAL;
     }
 
     /**

+ 35 - 11
src/main/resources/advanced.yml

@@ -454,17 +454,41 @@ Skills:
     ###
     Swords:
         Rupture:
-            # ChanceMax: Maximum chance of triggering bleeding
-            # MaxBonusLevel: On this level, the chance to cause Bleeding will be <ChanceMax>
-            ChanceMax: 33.0
-            MaxBonusLevel:
-                Standard: 100
-                RetroMode: 1000
-
-            # DamagePlayer: Bleeding damage dealt to players
-            # DamageMobs: Bleeding damage dealt to mobs
-            DamagePlayer: 2.0
-            DamageMobs: 3.0
+            Rupture_Mechanics:
+                # This is % chance, 15 would mean 15% percent of the time
+                Chance_To_Apply_On_Hit:
+                    Rank_1: 15
+                    Rank_2: 33
+                    Rank_3: 40
+                    Rank_4: 66
+                Duration_In_Seconds:
+                    Against_Players: 5
+                    Against_Mobs: 5
+                # Tick interval damage is applied twice a second during rupture, it is "pure" and does not get lowered from armor or absorption etc
+                Tick_Interval_Damage:
+                    Against_Players:
+                        Rank_1: 0.1
+                        Rank_2: 0.15
+                        Rank_3: 0.2
+                        Rank_4: 0.3
+                    Against_Mobs:
+                        Rank_1: 0.5
+                        Rank_2: 0.75
+                        Rank_3: 0.9
+                        Rank_4: 1
+                # If Rupture runs for 5 seconds without being reapplied, it explodes
+                # this damage is **NOT** pure and is reduced dramatically vs armor/absorption/etc
+                Explosion_Damage:
+                    Against_Players:
+                        Rank_1: 10
+                        Rank_2: 20
+                        Rank_3: 30
+                        Rank_4: 40
+                    Against_Mobs:
+                        Rank_1: 10
+                        Rank_2: 20
+                        Rank_3: 30
+                        Rank_4: 40
         CounterAttack:
             # ChanceMax: Maximum chance of triggering a counter attack
             # MaxBonusLevel: On this level, the chance to Counter will be <ChanceMax>

+ 3 - 3
src/main/resources/locale/locale_en_US.properties

@@ -406,7 +406,7 @@ Anvil.Unbreakable=This item is unbreakable!
 #SWORDS
 Swords.Ability.Lower=&7You lower your sword.
 Swords.Ability.Ready=&3You &6ready&3 your Sword.
-Swords.Combat.Rupture.Note=&7NOTE: &e1 Tick happens every 0.5 seconds!
+Swords.Combat.Rupture.Note=&7NOTE: Pure tick damage is dealt twice a second during Rupture and bypasses resistances but IS never lethal, an explosion goes off after 5 seconds with is reduced by armor and other resistances.
 Swords.Combat.Bleeding.Started=&4 You're bleeding!
 Swords.Combat.Bleeding.Stopped=&7The bleeding has &astopped&7!
 Swords.Combat.Bleeding=&a**ENEMY BLEEDING**
@@ -420,7 +420,7 @@ 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.Rupture.Description=A damage over time effect that ends explosively
 Swords.SubSkill.Stab.Name=Stab
 Swords.SubSkill.Stab.Description=Adds bonus damage to your attacks.
 Swords.SubSkill.Stab.Stat=Stab Damage
@@ -428,7 +428,7 @@ 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: &a{0} ticks [{1} DMG vs Player] [{2} DMG vs Mobs]
+Swords.SubSkill.Rupture.Stat.Extra=Rupture: Duration in seconds: &a{0} vs Players, {1} vs Mobs. Pure Tick Damage: {2} vs Players, {3} vs Mobs. Explosion Damage: {4} vs Players, {5} vs Mobs
 Swords.Effect.4=Serrated Strikes Rupture+
 Swords.Effect.5={0} Tick Rupture
 Swords.Listener=Swords: