diff --git a/src/main/java/com/gmail/nossr50/config/AdvancedConfig.java b/src/main/java/com/gmail/nossr50/config/AdvancedConfig.java index 87bfb4496..f6d0f130b 100644 --- a/src/main/java/com/gmail/nossr50/config/AdvancedConfig.java +++ b/src/main/java/com/gmail/nossr50/config/AdvancedConfig.java @@ -65,6 +65,7 @@ public class AdvancedConfig extends AutoUpdateConfigLoader { public int getGreaterImpactBonusDamage() { return config.getInt("Skills.Axes.GreaterImpact_BonusDamage", 2); } public int getArmorImpactIncreaseLevel() { return config.getInt("Skills.Axes.ArmorImpact_IncreaseLevel", 50); } + public double getImpactChance() { return config.getDouble("Skills.Axes.ArmorImpact_Chance", 25.0D); } public double getArmorImpactMaxDurabilityDamage() { return config.getDouble("Skills.Axes.ArmorImpact_MaxPercentageDurabilityDamage", 20.0D); } public int getSkullSplitterModifier() { return config.getInt("Skills.Axes.SkullSplitter_DamagerModifier", 2); } diff --git a/src/main/java/com/gmail/nossr50/skills/axes/AxeBonusDamageEventHandler.java b/src/main/java/com/gmail/nossr50/skills/axes/AxeBonusDamageEventHandler.java deleted file mode 100644 index 2caf3edc1..000000000 --- a/src/main/java/com/gmail/nossr50/skills/axes/AxeBonusDamageEventHandler.java +++ /dev/null @@ -1,31 +0,0 @@ -package com.gmail.nossr50.skills.axes; - -import org.bukkit.event.entity.EntityDamageByEntityEvent; - -public class AxeBonusDamageEventHandler { - private int skillLevel; - private EntityDamageByEntityEvent event; - private int damageBonus; - - public AxeBonusDamageEventHandler(AxeManager manager, EntityDamageByEntityEvent event) { - this.skillLevel = manager.getSkillLevel(); - this.event = event; - } - - protected void calculateDamageBonus() { - int increaseLevel = Axes.bonusDamageMaxBonusLevel / Axes.bonusDamageMaxBonus; - - /* Add 1 DMG for every 50 skill levels (default value) */ - damageBonus = skillLevel / increaseLevel; - - if (damageBonus > Axes.bonusDamageMaxBonus) { - damageBonus = Axes.bonusDamageMaxBonus; - } - } - - protected void modifyEventDamage() { - int damage = event.getDamage(); - - event.setDamage(damage + damageBonus); - } -} \ No newline at end of file diff --git a/src/main/java/com/gmail/nossr50/skills/axes/AxeManager.java b/src/main/java/com/gmail/nossr50/skills/axes/AxeManager.java index d3bcf5f71..fc720f869 100644 --- a/src/main/java/com/gmail/nossr50/skills/axes/AxeManager.java +++ b/src/main/java/com/gmail/nossr50/skills/axes/AxeManager.java @@ -1,67 +1,148 @@ package com.gmail.nossr50.skills.axes; +import org.bukkit.enchantments.Enchantment; import org.bukkit.entity.LivingEntity; -import org.bukkit.event.entity.EntityDamageByEntityEvent; +import org.bukkit.entity.Player; +import org.bukkit.inventory.ItemStack; import com.gmail.nossr50.datatypes.McMMOPlayer; +import com.gmail.nossr50.locale.LocaleLoader; +import com.gmail.nossr50.mods.ModChecks; import com.gmail.nossr50.skills.SkillManager; +import com.gmail.nossr50.skills.utilities.AbilityType; +import com.gmail.nossr50.skills.utilities.CombatTools; +import com.gmail.nossr50.skills.utilities.SkillTools; import com.gmail.nossr50.skills.utilities.SkillType; -import com.gmail.nossr50.util.Misc; +import com.gmail.nossr50.skills.utilities.ToolType; +import com.gmail.nossr50.util.ItemChecks; +import com.gmail.nossr50.util.ParticleEffectUtils; +import com.gmail.nossr50.util.Permissions; +import com.gmail.nossr50.util.Users; public class AxeManager extends SkillManager { public AxeManager(McMMOPlayer mcMMOPlayer) { super(mcMMOPlayer, SkillType.AXES); } - /** - * Apply bonus to damage done by axes. - * - * @param event The event to modify - */ - public void bonusDamage(EntityDamageByEntityEvent event) { - AxeBonusDamageEventHandler eventHandler = new AxeBonusDamageEventHandler(this, event); + public boolean canUseAxeMastery() { + return Permissions.bonusDamage(getPlayer(), skill); + } - eventHandler.calculateDamageBonus(); - eventHandler.modifyEventDamage(); + public boolean canCriticalHit(LivingEntity target) { + return target.isValid() && Permissions.criticalStrikes(getPlayer()); + } + + public boolean canImpact(LivingEntity target) { + return target.isValid() && Permissions.armorImpact(getPlayer()) && Axes.hasArmor(target); + } + + public boolean canGreaterImpact(LivingEntity target) { + return target.isValid() && Permissions.greaterImpact(getPlayer()) && !Axes.hasArmor(target); + } + + public boolean canUseSkullSplitter(LivingEntity target) { + return target.isValid() && getProfile().getAbilityMode(AbilityType.SKULL_SPLITTER) && Permissions.skullSplitter(getPlayer()); + } + + public boolean canActivateAbility() { + return getProfile().getToolPreparationMode(ToolType.AXE) && Permissions.skullSplitter(getPlayer()); } /** - * Check for critical chances on axe damage. + * Handle the effects of the Axe Mastery ability * - * @param event The event to modify + * @param damage The amount of damage initially dealt by the event + * @return the modified event damage */ - public void criticalHitCheck(EntityDamageByEntityEvent event, LivingEntity target) { - CriticalHitEventHandler eventHandler = new CriticalHitEventHandler(this, event, target); + public int axeMasteryCheck(int damage) { + int axeBonus = Math.min(getSkillLevel() / (Axes.bonusDamageMaxBonusLevel / Axes.bonusDamageMaxBonus), Axes.bonusDamageMaxBonus); - double chance = (Axes.criticalHitMaxChance / Axes.criticalHitMaxBonusLevel) * eventHandler.skillModifier; + return damage + axeBonus; + } - if (chance > Misc.getRandom().nextInt(activationChance)) { - eventHandler.modifyEventDamage(); - eventHandler.sendAbilityMessages(); + /** + * Handle the effects of the Critical Hit ability + * + * @param target The {@link LivingEntity} being affected by the ability + * @param damage The amount of damage initially dealt by the event + * @return the modified event damage if the ability was successful, the original event damage otherwise + */ + public int criticalHitCheck(LivingEntity target, int damage) { + Player player = getPlayer(); + + if (SkillTools.activationSuccessful(player, skill, Axes.criticalHitMaxChance, Axes.criticalHitMaxBonusLevel)) { + player.sendMessage(LocaleLoader.getString("Axes.Combat.CriticalHit")); + + if (target instanceof Player) { + ((Player) target).sendMessage(LocaleLoader.getString("Axes.Combat.CritStruck")); + + return (int) (damage * Axes.criticalHitPVPModifier); + } + + return (int) (damage * Axes.criticalHitPVEModifier); + } + + return damage; + } + + /** + * Handle the effects of the Impact ability + * + * @param target The {@link LivingEntity} being affected by Impact + */ + public void impactCheck(LivingEntity target) { + int durabilityDamage = 1 + (getSkillLevel() / Axes.impactIncreaseLevel); + + for (ItemStack armor : target.getEquipment().getArmorContents()) { + if (ItemChecks.isArmor(armor) && SkillTools.activationSuccessful(getPlayer(), skill, Axes.impactChance)) { + double durabilityModifier = 1 / (armor.getEnchantmentLevel(Enchantment.DURABILITY) + 1); // Modifier to simulate the durability enchantment behavior + double modifiedDurabilityDamage = durabilityDamage * durabilityModifier; + double maxDurabilityDamage = (ModChecks.isCustomArmor(armor) ? ModChecks.getArmorFromItemStack(armor).getDurability() : armor.getType().getMaxDurability()) * Axes.impactMaxDurabilityDamageModifier; + + armor.setDurability((short) (Math.min(modifiedDurabilityDamage, maxDurabilityDamage) + armor.getDurability())); + } } } /** - * Check for Impact ability. + * Handle the effects of the Greater Impact ability * - * @param event The event to modify + * @param target The {@link LivingEntity} being affected by the ability + * @param damage The amount of damage initially dealt by the event + * @return the modified event damage if the ability was successful, the original event damage otherwise */ - public void impact(EntityDamageByEntityEvent event, LivingEntity target) { - ImpactEventHandler eventHandler = new ImpactEventHandler(this, event, target); + public int greaterImpactCheck(LivingEntity target, int damage) { + Player player = getPlayer(); - if (!eventHandler.applyImpact()) { - eventHandler.applyGreaterImpact(); + if (SkillTools.activationSuccessful(player, skill, Axes.greaterImpactChance)) { + ParticleEffectUtils.playGreaterImpactEffect(target); + target.setVelocity(player.getLocation().getDirection().normalize().multiply(Axes.greaterImpactKnockbackMultiplier)); + + if (getProfile().useChatNotifications()) { + player.sendMessage(LocaleLoader.getString("Axes.Combat.GI.Proc")); + } + + if (target instanceof Player) { + Player defender = (Player) target; + + if (Users.getPlayer(defender).getProfile().useChatNotifications()) { + defender.sendMessage(LocaleLoader.getString("Axes.Combat.GI.Struck")); + } + } + + return damage + Axes.greaterImpactBonusDamage; } + + return damage; } /** - * Check for Skull Splitter ability. + * Handle the effects of the Skull Splitter ability * - * @param target The entity hit by Skull Splitter - * @param damage The base damage to deal + * @param target The {@link LivingEntity} being affected by the ability + * @param damage The amount of damage initially dealt by the event */ - public void skullSplitter(LivingEntity target, int damage) { - SkullSplitterEventHandler eventHandler = new SkullSplitterEventHandler(mcMMOPlayer.getPlayer(), damage, target); - eventHandler.applyAbilityEffects(); + public void skullSplitterCheck(LivingEntity target, int damage) { + CombatTools.applyAbilityAoE(getPlayer(), target, damage / Axes.skullSplitterModifier, skill); } } diff --git a/src/main/java/com/gmail/nossr50/skills/axes/Axes.java b/src/main/java/com/gmail/nossr50/skills/axes/Axes.java index 0fd7d60a5..6beb94881 100644 --- a/src/main/java/com/gmail/nossr50/skills/axes/Axes.java +++ b/src/main/java/com/gmail/nossr50/skills/axes/Axes.java @@ -1,6 +1,10 @@ package com.gmail.nossr50.skills.axes; +import org.bukkit.entity.LivingEntity; +import org.bukkit.inventory.ItemStack; + import com.gmail.nossr50.config.AdvancedConfig; +import com.gmail.nossr50.util.ItemChecks; public class Axes { public static int bonusDamageMaxBonus = AdvancedConfig.getInstance().getBonusDamageAxesBonusMax(); @@ -12,6 +16,7 @@ public class Axes { public static double criticalHitPVEModifier = AdvancedConfig.getInstance().getAxesCriticalPVEModifier(); public static int impactIncreaseLevel = AdvancedConfig.getInstance().getArmorImpactIncreaseLevel(); + public static double impactChance = AdvancedConfig.getInstance().getImpactChance(); public static double impactMaxDurabilityDamageModifier = AdvancedConfig.getInstance().getArmorImpactMaxDurabilityDamage() / 100D; public static double greaterImpactChance = AdvancedConfig.getInstance().getGreaterImpactChance(); @@ -19,4 +24,14 @@ public class Axes { public static int greaterImpactBonusDamage = AdvancedConfig.getInstance().getGreaterImpactBonusDamage(); public static int skullSplitterModifier = AdvancedConfig.getInstance().getSkullSplitterModifier(); + + protected static boolean hasArmor(LivingEntity target) { + for (ItemStack itemStack : target.getEquipment().getArmorContents()) { + if (ItemChecks.isArmor(itemStack)) { + return true; + } + } + + return false; + } } diff --git a/src/main/java/com/gmail/nossr50/skills/axes/CriticalHitEventHandler.java b/src/main/java/com/gmail/nossr50/skills/axes/CriticalHitEventHandler.java deleted file mode 100644 index 4b8d3d875..000000000 --- a/src/main/java/com/gmail/nossr50/skills/axes/CriticalHitEventHandler.java +++ /dev/null @@ -1,61 +0,0 @@ -package com.gmail.nossr50.skills.axes; - -import org.bukkit.Effect; -import org.bukkit.entity.LivingEntity; -import org.bukkit.entity.Player; -import org.bukkit.event.entity.EntityDamageByEntityEvent; - -import com.gmail.nossr50.datatypes.McMMOPlayer; -import com.gmail.nossr50.locale.LocaleLoader; -import com.gmail.nossr50.skills.utilities.SkillTools; -import com.gmail.nossr50.util.Users; - -public class CriticalHitEventHandler { - private AxeManager manager; - private EntityDamageByEntityEvent event; - private int damage; - - protected LivingEntity defender; - protected int skillModifier; - - public CriticalHitEventHandler(AxeManager manager, EntityDamageByEntityEvent event, LivingEntity defender) { - this.manager = manager; - this.event = event; - this.defender = defender; - this.damage = event.getDamage(); - - calculateSkillModifier(); - } - - protected void modifyEventDamage() { - if (defender instanceof Player) { - event.setDamage((int) (damage * Axes.criticalHitPVPModifier)); - } - else { - event.setDamage((int) (damage * Axes.criticalHitPVEModifier)); - } - } - - protected void sendAbilityMessages() { - McMMOPlayer mcMMOPlayer = manager.getMcMMOPlayer(); - Player attacker = mcMMOPlayer.getPlayer(); - - attacker.playEffect(defender.getEyeLocation(), Effect.MOBSPAWNER_FLAMES, 0); - - if (mcMMOPlayer.getProfile().useChatNotifications()) { - attacker.sendMessage(LocaleLoader.getString("Axes.Combat.CriticalHit")); - } - - if (defender instanceof Player) { - Player defendingPlayer = (Player) defender; - - if (Users.getPlayer(defendingPlayer).getProfile().useChatNotifications()) { - defendingPlayer.sendMessage(LocaleLoader.getString("Axes.Combat.CritStruck")); - } - } - } - - private void calculateSkillModifier() { - this.skillModifier = SkillTools.skillCheck(manager.getSkillLevel(), Axes.criticalHitMaxBonusLevel); - } -} diff --git a/src/main/java/com/gmail/nossr50/skills/axes/ImpactEventHandler.java b/src/main/java/com/gmail/nossr50/skills/axes/ImpactEventHandler.java deleted file mode 100644 index daa081487..000000000 --- a/src/main/java/com/gmail/nossr50/skills/axes/ImpactEventHandler.java +++ /dev/null @@ -1,104 +0,0 @@ -package com.gmail.nossr50.skills.axes; - -import org.bukkit.enchantments.Enchantment; -import org.bukkit.entity.LivingEntity; -import org.bukkit.entity.Player; -import org.bukkit.event.entity.EntityDamageByEntityEvent; -import org.bukkit.inventory.EntityEquipment; -import org.bukkit.inventory.ItemStack; - -import com.gmail.nossr50.locale.LocaleLoader; -import com.gmail.nossr50.mods.ModChecks; -import com.gmail.nossr50.util.ItemChecks; -import com.gmail.nossr50.util.Misc; -import com.gmail.nossr50.util.ParticleEffectUtils; -import com.gmail.nossr50.util.Permissions; -import com.gmail.nossr50.util.Users; - -public class ImpactEventHandler { - private AxeManager manager; - private Player player; - private EntityDamageByEntityEvent event; - private short durabilityDamage = 1; - private EntityEquipment entityEquipment; - protected LivingEntity defender; - boolean impactApplied; - - public ImpactEventHandler(AxeManager manager, EntityDamageByEntityEvent event, LivingEntity defender) { - this.manager = manager; - this.player = manager.getMcMMOPlayer().getPlayer(); - this.event = event; - this.defender = defender; - this.entityEquipment = defender.getEquipment(); - } - - protected boolean applyImpact() { - // Every 50 Skill Levels you gain 1 durability damage (default values) - durabilityDamage += (short) (manager.getSkillLevel() / Axes.impactIncreaseLevel); - // getArmorContents.length can't be used because it's always equal to 4 (no armor = air block) - boolean hasArmor = false; - - for (ItemStack itemStack : entityEquipment.getArmorContents()) { - if (ItemChecks.isArmor(itemStack)) { - hasArmor = true; - - if (Misc.getRandom().nextInt(100) < 25) { - damageArmor(itemStack); - } - } - } - - return hasArmor; - } - - private void damageArmor(ItemStack armor) { - // Modifier simulate the durability enchantment behavior - float modifier = 1; - - if (armor.containsEnchantment(Enchantment.DURABILITY)) { - modifier /= armor.getEnchantmentLevel(Enchantment.DURABILITY) + 1; - } - - float modifiedDurabilityDamage = durabilityDamage * modifier; - short maxDurabilityDamage = ModChecks.isCustomArmor(armor) ? ModChecks.getArmorFromItemStack(armor).getDurability() : armor.getType().getMaxDurability(); - maxDurabilityDamage *= Axes.impactMaxDurabilityDamageModifier; - - if (modifiedDurabilityDamage > maxDurabilityDamage) { - modifiedDurabilityDamage = maxDurabilityDamage; - } - - armor.setDurability((short) (modifiedDurabilityDamage + armor.getDurability())); - } - - protected void applyGreaterImpact() { - if (!Permissions.greaterImpact(player)) { - return; - } - - if (Misc.getRandom().nextInt(manager.getActivationChance()) <= Axes.greaterImpactChance) { - handleGreaterImpactEffect(); - sendAbilityMessge(); - } - } - - private void handleGreaterImpactEffect() { - event.setDamage(event.getDamage() + Axes.greaterImpactBonusDamage); - - ParticleEffectUtils.playGreaterImpactEffect(defender); - defender.setVelocity(player.getLocation().getDirection().normalize().multiply(Axes.greaterImpactKnockbackMultiplier)); - } - - private void sendAbilityMessge() { - if (manager.getMcMMOPlayer().getProfile().useChatNotifications()) { - player.sendMessage(LocaleLoader.getString("Axes.Combat.GI.Proc")); - } - - if (defender instanceof Player) { - Player defendingPlayer = (Player) defender; - - if (Users.getPlayer(defendingPlayer).getProfile().useChatNotifications()) { - defendingPlayer.sendMessage(LocaleLoader.getString("Axes.Combat.GI.Struck")); - } - } - } -} diff --git a/src/main/java/com/gmail/nossr50/skills/axes/SkullSplitterEventHandler.java b/src/main/java/com/gmail/nossr50/skills/axes/SkullSplitterEventHandler.java deleted file mode 100644 index d4f8ef05f..000000000 --- a/src/main/java/com/gmail/nossr50/skills/axes/SkullSplitterEventHandler.java +++ /dev/null @@ -1,23 +0,0 @@ -package com.gmail.nossr50.skills.axes; - -import org.bukkit.entity.LivingEntity; -import org.bukkit.entity.Player; - -import com.gmail.nossr50.skills.utilities.CombatTools; -import com.gmail.nossr50.skills.utilities.SkillType; - -public class SkullSplitterEventHandler { - private Player player; - private LivingEntity target; - private int damage; - - protected SkullSplitterEventHandler(Player player, int damage, LivingEntity target) { - this.player = player; - this.target = target; - this.damage = damage; - } - - protected void applyAbilityEffects() { - CombatTools.applyAbilityAoE(player, target, damage / Axes.skullSplitterModifier, SkillType.AXES); - } -} diff --git a/src/main/java/com/gmail/nossr50/skills/utilities/CombatTools.java b/src/main/java/com/gmail/nossr50/skills/utilities/CombatTools.java index 1e0671b9b..566859c6c 100644 --- a/src/main/java/com/gmail/nossr50/skills/utilities/CombatTools.java +++ b/src/main/java/com/gmail/nossr50/skills/utilities/CombatTools.java @@ -28,6 +28,7 @@ import com.gmail.nossr50.locale.LocaleLoader; import com.gmail.nossr50.mods.ModChecks; import com.gmail.nossr50.party.PartyManager; import com.gmail.nossr50.skills.SkillManagerStore; +import com.gmail.nossr50.skills.axes.AxeManager; import com.gmail.nossr50.skills.runnables.BleedTimer; import com.gmail.nossr50.skills.runnables.CombatXpGiver; import com.gmail.nossr50.skills.swords.Swords; @@ -106,32 +107,32 @@ public final class CombatTools { } if (Permissions.skillEnabled(player, SkillType.AXES)) { - McMMOPlayer mcMMOPlayer = Users.getPlayer(player); - PlayerProfile profile = mcMMOPlayer.getProfile(); - String playerName = player.getName(); + AxeManager axeManager = SkillManagerStore.getInstance().getAxeManager(player.getName()); - boolean canSkullSplit = Permissions.skullSplitter(player); //So we don't have to check the same permission twice - if (profile.getToolPreparationMode(ToolType.AXE) && canSkullSplit) { + if (axeManager.canActivateAbility()) { SkillTools.abilityCheck(player, SkillType.AXES); } - if (Permissions.bonusDamage(player, SkillType.AXES)) { - SkillManagerStore.getInstance().getAxeManager(playerName).bonusDamage(event); + if (axeManager.canUseAxeMastery()) { + event.setDamage(axeManager.axeMasteryCheck(event.getDamage())); } - if (!target.isDead() && Permissions.criticalStrikes(player)) { - SkillManagerStore.getInstance().getAxeManager(playerName).criticalHitCheck(event, target); + if (axeManager.canCriticalHit(target)) { + event.setDamage(axeManager.criticalHitCheck(target, event.getDamage())); } - if (!target.isDead() && Permissions.armorImpact(player)) { - SkillManagerStore.getInstance().getAxeManager(playerName).impact(event, target); + if (axeManager.canImpact(target)) { + axeManager.impactCheck(target); + } + else if (axeManager.canGreaterImpact(target)){ + event.setDamage(axeManager.greaterImpactCheck(target, event.getDamage())); } - if (!target.isDead() && profile.getAbilityMode(AbilityType.SKULL_SPLITTER) && canSkullSplit) { - SkillManagerStore.getInstance().getAxeManager(playerName).skullSplitter(target, event.getDamage()); + if (axeManager.canUseSkullSplitter(target)) { + axeManager.skullSplitterCheck(target, event.getDamage()); } - startGainXp(mcMMOPlayer, target, SkillType.AXES); + startGainXp(axeManager.getMcMMOPlayer(), target, SkillType.AXES); } } else if (heldItemType == Material.AIR) { diff --git a/src/main/resources/advanced.yml b/src/main/resources/advanced.yml index 0d60c90b6..e9a028b85 100644 --- a/src/main/resources/advanced.yml +++ b/src/main/resources/advanced.yml @@ -95,8 +95,10 @@ Skills: GreaterImpact_BonusDamage: 2 # ArmorImpact_IncreaseLevel: Every "IncreaseLevel" the durability damage goes up with 1 + # ArmorImpact_Chance: Chance of hitting with ArmorImpact # ArmorImpact_MaxPercentageDurabilityDamage: Durability damage cap for ArmorImpact, 20% means that you can never destroy a piece of armor in less than 5 hits ArmorImpact_IncreaseLevel: 50 + ArmorImpact_Chance: 25.0 ArmorImpact_MaxPercentageDurabilityDamage: 20.0 # SkullSplitter_DamageModifier: Damage will get divided by this modifier