diff --git a/Server/src/main/content/global/handlers/item/equipment/special/AncientMaceSpecialHandler.java b/Server/src/main/content/global/handlers/item/equipment/special/AncientMaceSpecialHandler.java index 330523540..9c04d990f 100644 --- a/Server/src/main/content/global/handlers/item/equipment/special/AncientMaceSpecialHandler.java +++ b/Server/src/main/content/global/handlers/item/equipment/special/AncientMaceSpecialHandler.java @@ -57,7 +57,7 @@ public final class AncientMaceSpecialHandler extends MeleeSwingHandler implement state.setStyle(CombatStyle.MELEE); int hit = 0; if (isAccurateImpact(entity, victim, CombatStyle.MELEE, 1.1, 0.98)) { - hit = RandomFunction.random(calculateHit(entity, victim, 1)); + hit = RandomFunction.random(calculateHit(entity, victim, 1) + 1); if (entity.getSkills().getPrayerPoints() < entity.getSkills().getStaticLevel(5)) { entity.getSkills().setPrayerPoints(entity.getSkills().getPrayerPoints() + hit); } diff --git a/Server/src/main/content/global/handlers/item/equipment/special/BackstabSpecialHandler.java b/Server/src/main/content/global/handlers/item/equipment/special/BackstabSpecialHandler.java index bb243ad37..2baaab97e 100644 --- a/Server/src/main/content/global/handlers/item/equipment/special/BackstabSpecialHandler.java +++ b/Server/src/main/content/global/handlers/item/equipment/special/BackstabSpecialHandler.java @@ -59,13 +59,10 @@ public final class BackstabSpecialHandler extends MeleeSwingHandler implements P } state.setStyle(CombatStyle.MELEE); int hit = 0; - double accuracy = 1.0; - if (!victim.getProperties().getCombatPulse().isAttacking()) { - accuracy = 1.75; - } - if (isAccurateImpact(entity, victim, CombatStyle.MELEE, accuracy, 0.98)) { - hit = RandomFunction.random(calculateHit(entity, victim, 1.0)); - victim.getSkills().updateLevel(Skills.DEFENCE, -hit / 10, 0); + if (!victim.getProperties().getCombatPulse().isAttacking() || isAccurateImpact(entity, victim, CombatStyle.MELEE)) { + hit = RandomFunction.random(calculateHit(entity, victim, 1.0) + 1); + if (victim.getSkills().getStaticLevel(Skills.DEFENCE) >= victim.getSkills().getDynamicLevels()[Skills.DEFENCE]) + victim.getSkills().updateLevel(Skills.DEFENCE, -hit, 0); } state.setEstimatedHit(hit); return 1; diff --git a/Server/src/main/content/global/handlers/item/equipment/special/ChainhitSpecialHandler.java b/Server/src/main/content/global/handlers/item/equipment/special/ChainhitSpecialHandler.java index a4682149f..b3e276dcd 100644 --- a/Server/src/main/content/global/handlers/item/equipment/special/ChainhitSpecialHandler.java +++ b/Server/src/main/content/global/handlers/item/equipment/special/ChainhitSpecialHandler.java @@ -1,9 +1,7 @@ package content.global.handlers.item.equipment.special; import core.game.node.entity.Entity; -import core.game.node.entity.combat.BattleState; -import core.game.node.entity.combat.CombatStyle; -import core.game.node.entity.combat.DeathTask; +import core.game.node.entity.combat.*; import core.game.node.entity.combat.ImpactHandler.HitsplatType; import core.game.node.entity.impl.Animator.Priority; import core.game.node.entity.impl.Projectile; @@ -17,7 +15,6 @@ import core.game.world.update.flag.context.Graphics; import core.plugin.Initializable; import core.plugin.Plugin; import core.tools.RandomFunction; -import core.game.node.entity.combat.RangeSwingHandler; import core.game.world.GameWorld; import core.game.world.repository.Repository; import org.rs09.consts.Sounds; @@ -34,6 +31,13 @@ import static core.api.ContentAPIKt.playGlobalAudio; @Initializable public final class ChainhitSpecialHandler extends RangeSwingHandler implements Plugin { + /** + * Constructs a new {@code ChainhitSpecialHandler} {@code Object}. + */ + public ChainhitSpecialHandler() { + super(SwingHandlerFlag.IGNORE_PRAYER_BOOSTS_DAMAGE); + } + /** * The sp::ecial energy required. */ @@ -159,7 +163,7 @@ public final class ChainhitSpecialHandler extends RangeSwingHandler implements P public boolean pulse() { BattleState bs = new BattleState(entity, e); bs.setMaximumHit(calculateHit(player, e, 1.0)); - bs.setEstimatedHit(RandomFunction.RANDOM.nextInt(bs.getMaximumHit())); + bs.setEstimatedHit(RandomFunction.random(bs.getMaximumHit() + 1)); handleHit(victim, e, player, bs); ChainhitSpecialHandler.super.visualizeImpact(player, e, bs); return true; diff --git a/Server/src/main/content/global/handlers/item/equipment/special/ChinchompaSwingHandler.java b/Server/src/main/content/global/handlers/item/equipment/special/ChinchompaSwingHandler.java index fea739a85..0bd2e6d33 100644 --- a/Server/src/main/content/global/handlers/item/equipment/special/ChinchompaSwingHandler.java +++ b/Server/src/main/content/global/handlers/item/equipment/special/ChinchompaSwingHandler.java @@ -31,13 +31,6 @@ public final class ChinchompaSwingHandler extends RangeSwingHandler { */ private static final Graphics END_GRAPHIC = new Graphics(157, 96); - /** - * Constructs a new {@code ChinchompaSwingHandler} {@code Object}. - */ - public ChinchompaSwingHandler() { - super(SwingHandlerFlag.IGNORE_STAT_BOOSTS_DAMAGE); - } - @Override public int swing(Entity entity, Entity victim, BattleState state) { boolean multi = entity.getProperties().isMultiZone() && victim.getProperties().isMultiZone(); @@ -72,7 +65,7 @@ public final class ChinchompaSwingHandler extends RangeSwingHandler { s.setStyle(CombatStyle.RANGE); int hit = 0; if (isAccurateImpact(entity, e, CombatStyle.RANGE)) { - hit = RandomFunction.random(calculateHit(entity, e, 1.0)); + hit = RandomFunction.random(calculateHit(entity, e, 1.0) + 1); } s.setEstimatedHit(hit); } diff --git a/Server/src/main/content/global/handlers/item/equipment/special/CleaveSpecialHandler.java b/Server/src/main/content/global/handlers/item/equipment/special/CleaveSpecialHandler.java index dd669c168..f728dbaf2 100644 --- a/Server/src/main/content/global/handlers/item/equipment/special/CleaveSpecialHandler.java +++ b/Server/src/main/content/global/handlers/item/equipment/special/CleaveSpecialHandler.java @@ -57,8 +57,8 @@ public final class CleaveSpecialHandler extends MeleeSwingHandler implements Plu } state.setStyle(CombatStyle.MELEE); int hit = 0; - if (isAccurateImpact(entity, victim, CombatStyle.MELEE, 1.18, 1.0)) { - hit = RandomFunction.random(calculateHit(entity, victim, 1.2203)); + if (isAccurateImpact(entity, victim, CombatStyle.MELEE)) { + hit = RandomFunction.random(calculateHit(entity, victim, 1.25) + 1); } state.setEstimatedHit(hit); return 1; diff --git a/Server/src/main/content/global/handlers/item/equipment/special/DescentOfDarknessSpecialHandler.java b/Server/src/main/content/global/handlers/item/equipment/special/DescentOfDarknessSpecialHandler.java index 519f9462a..75ae1f8a8 100644 --- a/Server/src/main/content/global/handlers/item/equipment/special/DescentOfDarknessSpecialHandler.java +++ b/Server/src/main/content/global/handlers/item/equipment/special/DescentOfDarknessSpecialHandler.java @@ -30,7 +30,7 @@ public final class DescentOfDarknessSpecialHandler extends RangeSwingHandler imp /** * The special energy required. */ - private static final int SPECIAL_ENERGY = 65; + private static final int SPECIAL_ENERGY = 55; /** * The descent of dragons projectile. @@ -102,13 +102,13 @@ public final class DescentOfDarknessSpecialHandler extends RangeSwingHandler imp state.setMaximumHit(max); int hit = minDamage; if (isAccurateImpact(entity, victim, CombatStyle.RANGE, 1.15, 1.0)) { - hit += RandomFunction.random(max - minDamage); + hit += RandomFunction.random(max - minDamage + 1); } state.setEstimatedHit(hit); if (w.getType() == WeaponType.DOUBLE_SHOT) { hit = minDamage; if (isAccurateImpact(entity, victim, CombatStyle.RANGE, 1.15, 1.0)) { - hit += RandomFunction.random(max - minDamage); + hit += RandomFunction.random(max - minDamage + 1); } state.setSecondaryHit(hit); } diff --git a/Server/src/main/content/global/handlers/item/equipment/special/EnergyDrainSpecialHandler.java b/Server/src/main/content/global/handlers/item/equipment/special/EnergyDrainSpecialHandler.java index c7b6dec41..4686eb2b8 100644 --- a/Server/src/main/content/global/handlers/item/equipment/special/EnergyDrainSpecialHandler.java +++ b/Server/src/main/content/global/handlers/item/equipment/special/EnergyDrainSpecialHandler.java @@ -57,8 +57,8 @@ public final class EnergyDrainSpecialHandler extends MeleeSwingHandler implement } state.setStyle(CombatStyle.MELEE); int hit = 0; - if (isAccurateImpact(entity, victim, CombatStyle.MELEE, 1.2, 1.0)) { - hit = RandomFunction.random(calculateHit(entity, victim, 1)); + if (isAccurateImpact(entity, victim, CombatStyle.MELEE, 1.25, 1.0)) { + hit = RandomFunction.random(calculateHit(entity, victim, 1) + 1); } if (victim instanceof Player) { ((Player) victim).getSettings().updateRunEnergy(10); diff --git a/Server/src/main/content/global/handlers/item/equipment/special/FeintSpecialHandler.java b/Server/src/main/content/global/handlers/item/equipment/special/FeintSpecialHandler.java index a22ba8c10..b85962790 100644 --- a/Server/src/main/content/global/handlers/item/equipment/special/FeintSpecialHandler.java +++ b/Server/src/main/content/global/handlers/item/equipment/special/FeintSpecialHandler.java @@ -52,8 +52,9 @@ public final class FeintSpecialHandler extends MeleeSwingHandler implements Plug } state.setStyle(CombatStyle.MELEE); int hit = 0; - if (isAccurateImpact(entity, victim, CombatStyle.MELEE, 1.0, 1.0)) { - hit = RandomFunction.random(calculateHit(entity, victim, RandomFunction.random(1.0, 1.2))); + if (isAccurateImpact(entity, victim, CombatStyle.MELEE, 1.0, 0.25)) { + int minDamage = calculateHit(entity, victim, 0.2); + hit = minDamage + RandomFunction.random(calculateHit(entity, victim, 1.0) + 1); } state.setEstimatedHit(hit); return 1; diff --git a/Server/src/main/content/global/handlers/item/equipment/special/HamstringSpecialHandler.java b/Server/src/main/content/global/handlers/item/equipment/special/HamstringSpecialHandler.java index fefffaabd..6a89af4fc 100644 --- a/Server/src/main/content/global/handlers/item/equipment/special/HamstringSpecialHandler.java +++ b/Server/src/main/content/global/handlers/item/equipment/special/HamstringSpecialHandler.java @@ -46,7 +46,8 @@ public final class HamstringSpecialHandler extends RangeSwingHandler implements state.setMaximumHit(max); int hit = 0; if (isAccurateImpact(entity, victim)) { - hit = RandomFunction.random(max); + int minDamage = calculateHit(entity, victim, 0.2); + hit = minDamage + RandomFunction.random(calculateHit(entity, victim, 1.0) + 1); } state.setEstimatedHit(hit); Companion.useAmmo(entity, state, victim.getLocation()); diff --git a/Server/src/main/content/global/handlers/item/equipment/special/HealingBladeSpecialHandler.java b/Server/src/main/content/global/handlers/item/equipment/special/HealingBladeSpecialHandler.java index 76780908b..5589c48c0 100644 --- a/Server/src/main/content/global/handlers/item/equipment/special/HealingBladeSpecialHandler.java +++ b/Server/src/main/content/global/handlers/item/equipment/special/HealingBladeSpecialHandler.java @@ -57,20 +57,20 @@ public final class HealingBladeSpecialHandler extends MeleeSwingHandler implemen } state.setStyle(CombatStyle.MELEE); int hit = 0; - if (isAccurateImpact(entity, victim, CombatStyle.MELEE, 1.12, 0.98)) { - hit = RandomFunction.random(calculateHit(entity, victim, 1.005)); + if (isAccurateImpact(entity, victim, CombatStyle.MELEE, 2.0, 1.0)) { + hit = RandomFunction.random(calculateHit(entity, victim, 1.1) + 1); + int healthRestore = hit / 2; + double prayerRestore = hit * 0.25; + if (healthRestore < 10) { + healthRestore = 10; + } + if (prayerRestore < 5) { + prayerRestore = 5; + } + entity.getSkills().heal(healthRestore); + entity.getSkills().incrementPrayerPoints(prayerRestore); } state.setEstimatedHit(hit); - int healthRestore = hit / 2; - double prayerRestore = hit * 0.25; - if (healthRestore < 10) { - healthRestore = 10; - } - if (prayerRestore < 5) { - prayerRestore = 5; - } - entity.getSkills().heal(healthRestore); - entity.getSkills().incrementPrayerPoints(prayerRestore); return 1; } diff --git a/Server/src/main/content/global/handlers/item/equipment/special/IceCleaveSpecialHandler.java b/Server/src/main/content/global/handlers/item/equipment/special/IceCleaveSpecialHandler.java index 42053679b..83c1e4a50 100644 --- a/Server/src/main/content/global/handlers/item/equipment/special/IceCleaveSpecialHandler.java +++ b/Server/src/main/content/global/handlers/item/equipment/special/IceCleaveSpecialHandler.java @@ -57,8 +57,8 @@ public final class IceCleaveSpecialHandler extends MeleeSwingHandler implements } state.setStyle(CombatStyle.MELEE); int hit = 0; - if (isAccurateImpact(entity, victim, CombatStyle.MELEE, 1.075, 0.98)) { - hit = RandomFunction.random(calculateHit(entity, victim, 1.005)); + if (isAccurateImpact(entity, victim, CombatStyle.MELEE, 2.0, 1.0)) { + hit = RandomFunction.random(calculateHit(entity, victim, 1.1) + 1); } state.setEstimatedHit(hit); return 1; diff --git a/Server/src/main/content/global/handlers/item/equipment/special/ImpaleSpecialHandler.java b/Server/src/main/content/global/handlers/item/equipment/special/ImpaleSpecialHandler.java index 11ddbd9f9..2e0ff5aa4 100644 --- a/Server/src/main/content/global/handlers/item/equipment/special/ImpaleSpecialHandler.java +++ b/Server/src/main/content/global/handlers/item/equipment/special/ImpaleSpecialHandler.java @@ -59,7 +59,7 @@ public final class ImpaleSpecialHandler extends MeleeSwingHandler implements Plu state.setStyle(CombatStyle.MELEE); int hit = 0; if (isAccurateImpact(entity, victim, CombatStyle.MELEE, 1.1, 0.98)) { - hit = RandomFunction.random(calculateHit(entity, victim, 1.1)); + hit = RandomFunction.random(calculateHit(entity, victim, 1.1) + 1); } state.setEstimatedHit(hit); return 1; diff --git a/Server/src/main/content/global/handlers/item/equipment/special/JudgementSpecialHandler.java b/Server/src/main/content/global/handlers/item/equipment/special/JudgementSpecialHandler.java index 0fb647924..abdb00cc5 100644 --- a/Server/src/main/content/global/handlers/item/equipment/special/JudgementSpecialHandler.java +++ b/Server/src/main/content/global/handlers/item/equipment/special/JudgementSpecialHandler.java @@ -57,8 +57,8 @@ public final class JudgementSpecialHandler extends MeleeSwingHandler implements } state.setStyle(CombatStyle.MELEE); int hit = 0; - if (isAccurateImpact(entity, victim, CombatStyle.MELEE, 1.25, 0.98)) { - hit = RandomFunction.random(calculateHit(entity, victim, 1.25)); + if (isAccurateImpact(entity, victim, CombatStyle.MELEE, 2.0, 1.0)) { + hit = RandomFunction.random((int) (calculateHit(entity, victim, 1.1) * 1.25) + 1); } state.setEstimatedHit(hit); return 1; diff --git a/Server/src/main/content/global/handlers/item/equipment/special/PhantomStrikeSpecialHandler.java b/Server/src/main/content/global/handlers/item/equipment/special/PhantomStrikeSpecialHandler.java index 18af20d24..82f5b3eb3 100644 --- a/Server/src/main/content/global/handlers/item/equipment/special/PhantomStrikeSpecialHandler.java +++ b/Server/src/main/content/global/handlers/item/equipment/special/PhantomStrikeSpecialHandler.java @@ -49,7 +49,7 @@ public final class PhantomStrikeSpecialHandler extends RangeSwingHandler impleme state.setMaximumHit(max); int hit = 0; if (isAccurateImpact(entity, victim)) { - hit = RandomFunction.random(max); + hit = RandomFunction.random(max + 1); } state.setEstimatedHit(hit); Companion.useAmmo(entity, state, victim.getLocation()); diff --git a/Server/src/main/content/global/handlers/item/equipment/special/PowershotSpecialHandler.java b/Server/src/main/content/global/handlers/item/equipment/special/PowershotSpecialHandler.java index aca1a0070..4fe5e5f90 100644 --- a/Server/src/main/content/global/handlers/item/equipment/special/PowershotSpecialHandler.java +++ b/Server/src/main/content/global/handlers/item/equipment/special/PowershotSpecialHandler.java @@ -56,10 +56,7 @@ public final class PowershotSpecialHandler extends RangeSwingHandler implements return -1; } state.setStyle(CombatStyle.RANGE); - int hit = 0; - if (isAccurateImpact(entity, victim, CombatStyle.RANGE, 1.98, 1.0)) { - hit = RandomFunction.random(calculateHit(entity, victim, 1.0)); - } + int hit = RandomFunction.random(calculateHit(entity, victim, 1.0) + 1); state.setEstimatedHit(hit); Companion.useAmmo(entity, state, victim.getLocation()); return 1 + (int) Math.ceil(entity.getLocation().getDistance(victim.getLocation()) * 0.3); diff --git a/Server/src/main/content/global/handlers/item/equipment/special/PowerstabSpecialHandler.java b/Server/src/main/content/global/handlers/item/equipment/special/PowerstabSpecialHandler.java index 4c7ea7a83..172ca036c 100644 --- a/Server/src/main/content/global/handlers/item/equipment/special/PowerstabSpecialHandler.java +++ b/Server/src/main/content/global/handlers/item/equipment/special/PowerstabSpecialHandler.java @@ -85,7 +85,7 @@ public final class PowerstabSpecialHandler extends MeleeSwingHandler implements BattleState s = targets[count++] = new BattleState(entity, e); int hit = 0; if (isAccurateImpact(entity, e)) { - hit = RandomFunction.random(calculateHit(entity, e, 1.0)); + hit = RandomFunction.random(calculateHit(entity, e, 1.0) + 1); } s.setStyle(CombatStyle.MELEE); s.setEstimatedHit(hit); diff --git a/Server/src/main/content/global/handlers/item/equipment/special/PunctureSpecialHandler.java b/Server/src/main/content/global/handlers/item/equipment/special/PunctureSpecialHandler.java index e489173fc..b5fc3357f 100644 --- a/Server/src/main/content/global/handlers/item/equipment/special/PunctureSpecialHandler.java +++ b/Server/src/main/content/global/handlers/item/equipment/special/PunctureSpecialHandler.java @@ -61,18 +61,13 @@ public final class PunctureSpecialHandler extends MeleeSwingHandler implements P return -1; } state.setStyle(CombatStyle.MELEE); - // First hit - //double accuracyMod, double defenceMod int hit = 0; - // accuracyMod defenceMod - if (isAccurateImpact(entity, victim, CombatStyle.MELEE, 1.05, 1.0)) { - hit = RandomFunction.random(calculateHit(entity, victim, 1.1306)); + if (isAccurateImpact(entity, victim, CombatStyle.MELEE, 1.15, 1.0)) { + hit = RandomFunction.random(calculateHit(entity, victim, 1.15) + 1); } state.setEstimatedHit(hit); - // Second hit - // accuracyMod defenceMod - if (isAccurateImpact(entity, victim, CombatStyle.MELEE, 1.05, 1.0)) { - hit = RandomFunction.random(calculateHit(entity, victim, 1.1306)); + if (isAccurateImpact(entity, victim, CombatStyle.MELEE, 1.15, 1.0)) { + hit = RandomFunction.random(calculateHit(entity, victim, 1.15) + 1); } else { hit = 0; } diff --git a/Server/src/main/content/global/handlers/item/equipment/special/QuickSmashSpecialHandler.java b/Server/src/main/content/global/handlers/item/equipment/special/QuickSmashSpecialHandler.java index cc5e5a557..e1d043c9d 100644 --- a/Server/src/main/content/global/handlers/item/equipment/special/QuickSmashSpecialHandler.java +++ b/Server/src/main/content/global/handlers/item/equipment/special/QuickSmashSpecialHandler.java @@ -3,9 +3,11 @@ package content.global.handlers.item.equipment.special; import core.game.node.entity.Entity; import core.game.node.entity.combat.BattleState; import core.game.node.entity.combat.CombatStyle; +import core.game.node.entity.combat.DeathTask; import core.game.node.entity.combat.MeleeSwingHandler; import core.game.node.entity.impl.Animator.Priority; import core.game.node.entity.player.Player; +import core.game.node.entity.player.link.prayer.PrayerType; import core.game.world.GameWorld; import core.game.world.update.flag.context.Animation; import core.game.world.update.flag.context.Graphics; @@ -65,16 +67,22 @@ public final class QuickSmashSpecialHandler extends MeleeSwingHandler implements return -1; } } + if (DeathTask.isDead(victim)) { + return -1; + } if (!p.getSettings().drainSpecial(SPECIAL_ENERGY)) { return -1; } - // TODO: apply protection prayers/experience manually (since this is bypassing normal BattleState machinery) visualize(entity, victim, null); int hit = 0; if (isAccurateImpact(entity, victim)) { - hit = RandomFunction.random(calculateHit(entity, victim, 1.)); + hit = RandomFunction.random(calculateHit(entity, victim, 1.0) + 1); } - victim.getImpactHandler().handleImpact(entity, hit, CombatStyle.MELEE); + if (victim.hasProtectionPrayer(CombatStyle.MELEE)) + hit *= (victim instanceof Player) ? 0.6 : 0; + BattleState b = new BattleState(); + b.setEstimatedHit(victim.getImpactHandler().handleImpact(entity, hit, CombatStyle.MELEE).getAmount()); + addExperience(entity, victim, b); return 1; } diff --git a/Server/src/main/content/global/handlers/item/equipment/special/RampageSpecialHandler.java b/Server/src/main/content/global/handlers/item/equipment/special/RampageSpecialHandler.java index 0aef9cd2b..2e70ab9ec 100644 --- a/Server/src/main/content/global/handlers/item/equipment/special/RampageSpecialHandler.java +++ b/Server/src/main/content/global/handlers/item/equipment/special/RampageSpecialHandler.java @@ -65,15 +65,15 @@ public final class RampageSpecialHandler extends MeleeSwingHandler implements Pl p.visualize(ANIMATION, GRAPHIC); @SuppressWarnings("unused") int boost = 0; - for (int i = 0; i < 6; i++) { - if (i == 2 || i == 3 || i == 5) { - continue; + for (int i = 0; i < 7; i++) { + if (i == Skills.ATTACK || i == Skills.DEFENCE || i == Skills.RANGE || i == Skills.MAGIC) { + int drain = (int) (p.getSkills().getLevel(i) * 0.1); + boost += drain; + p.getSkills().updateLevel(i, -drain, 0); } - double drain = p.getSkills().getLevel(i) * 0.1; - boost += drain; - p.getSkills().updateLevel(i, (int) -drain, (int) (p.getSkills().getStaticLevel(i) - drain)); } - p.getSkills().updateLevel(Skills.STRENGTH, (int) (p.getSkills().getStaticLevel(Skills.STRENGTH) * 0.20)); + boost = 10 + (boost / 4); + p.getSkills().updateLevel(Skills.STRENGTH, boost, Math.max(p.getSkills().getStaticLevel(Skills.STRENGTH) + boost, p.getSkills().getLevel(Skills.STRENGTH))); return -1; } diff --git a/Server/src/main/content/global/handlers/item/equipment/special/SaradominsLightningHandler.java b/Server/src/main/content/global/handlers/item/equipment/special/SaradominsLightningHandler.java index 3875ba7be..9e672f4db 100644 --- a/Server/src/main/content/global/handlers/item/equipment/special/SaradominsLightningHandler.java +++ b/Server/src/main/content/global/handlers/item/equipment/special/SaradominsLightningHandler.java @@ -52,9 +52,9 @@ public final class SaradominsLightningHandler extends MeleeSwingHandler implemen state.setStyle(CombatStyle.MAGIC); int hit = 0; int secondary = 0; - if (isAccurateImpact(entity, victim, CombatStyle.MELEE, 1.10, 0.98)) { - hit = RandomFunction.random(calculateHit(entity, victim, 1.1)); - secondary = 5 + RandomFunction.RANDOM.nextInt(14); + if (isAccurateImpact(entity, victim, CombatStyle.MELEE, 1.10, 1.0)) { + hit = RandomFunction.random(calculateHit(entity, victim, 1.1) + 1); + secondary = 1 + RandomFunction.random(16); } state.setEstimatedHit(hit); state.setSecondaryHit(secondary); diff --git a/Server/src/main/content/global/handlers/item/equipment/special/SeercullSpecialHandler.java b/Server/src/main/content/global/handlers/item/equipment/special/SeercullSpecialHandler.java index 5d9bc30ef..b4a374d3e 100644 --- a/Server/src/main/content/global/handlers/item/equipment/special/SeercullSpecialHandler.java +++ b/Server/src/main/content/global/handlers/item/equipment/special/SeercullSpecialHandler.java @@ -1,5 +1,6 @@ package content.global.handlers.item.equipment.special; +import core.game.node.entity.combat.SwingHandlerFlag; import core.game.node.entity.skill.Skills; import core.game.node.entity.Entity; import core.game.node.entity.combat.BattleState; @@ -24,6 +25,13 @@ import static core.api.ContentAPIKt.playGlobalAudio; @Initializable public final class SeercullSpecialHandler extends RangeSwingHandler implements Plugin { + /** + * Constructs a new {@code SeercullSpecialHandler} {@code Object}. + */ + public SeercullSpecialHandler() { + super(SwingHandlerFlag.IGNORE_PRAYER_BOOSTS_DAMAGE); + } + /** * The special energy required. */ @@ -57,11 +65,9 @@ public final class SeercullSpecialHandler extends RangeSwingHandler implements P if (!((Player) entity).getSettings().drainSpecial(SPECIAL_ENERGY)) { return -1; } - int hit = 0; - if (isAccurateImpact(entity, victim, CombatStyle.RANGE, 1.05, 1.0)) { - hit = RandomFunction.random(calculateHit(entity, victim, 1.0)); + int hit = RandomFunction.random(calculateHit(entity, victim, 1.0) + 1); + if (victim.getSkills().getLevel(Skills.MAGIC) >= victim.getSkills().getStaticLevel(Skills.MAGIC)) victim.getSkills().updateLevel(Skills.MAGIC, -hit, 0); - } Companion.useAmmo(entity, state, victim.getLocation()); state.setEstimatedHit(hit); return 1; diff --git a/Server/src/main/content/global/handlers/item/equipment/special/SeverSpecialHandler.java b/Server/src/main/content/global/handlers/item/equipment/special/SeverSpecialHandler.java index 116e993d4..eb8419c10 100644 --- a/Server/src/main/content/global/handlers/item/equipment/special/SeverSpecialHandler.java +++ b/Server/src/main/content/global/handlers/item/equipment/special/SeverSpecialHandler.java @@ -56,8 +56,8 @@ public final class SeverSpecialHandler extends MeleeSwingHandler implements Plug return -1; state.setStyle(CombatStyle.MELEE); int hit = 0; - if (isAccurateImpact(entity, victim, CombatStyle.MELEE, 1.124, 1.0)) { - hit = RandomFunction.random(calculateHit(entity, victim, 1.0)); + if (isAccurateImpact(entity, victim, CombatStyle.MELEE, 1.25, 1.0)) { + hit = RandomFunction.random(calculateHit(entity, victim, 1.0) + 1); if (victim instanceof Player) { Player p = (Player) victim; if (p.getPrayer().get(PrayerType.PROTECT_FROM_MAGIC)) { diff --git a/Server/src/main/content/global/handlers/item/equipment/special/ShatterSpecialHandler.java b/Server/src/main/content/global/handlers/item/equipment/special/ShatterSpecialHandler.java index aebbd909f..1b226c390 100644 --- a/Server/src/main/content/global/handlers/item/equipment/special/ShatterSpecialHandler.java +++ b/Server/src/main/content/global/handlers/item/equipment/special/ShatterSpecialHandler.java @@ -56,8 +56,8 @@ public final class ShatterSpecialHandler extends MeleeSwingHandler implements Pl } state.setStyle(CombatStyle.MELEE); int hit = 0; - if (isAccurateImpact(entity, victim, CombatStyle.MELEE, 0.87, 1.0)) { - hit = RandomFunction.random(calculateHit(entity, victim, 1.3546)); + if (isAccurateImpact(entity, victim, CombatStyle.MELEE, 1.25, 1.0)) { + hit = RandomFunction.random(calculateHit(entity, victim, 1.5) + 1); } state.setEstimatedHit(hit); return 1; diff --git a/Server/src/main/content/global/handlers/item/equipment/special/SliceAndDiceSpecialHandler.java b/Server/src/main/content/global/handlers/item/equipment/special/SliceAndDiceSpecialHandler.java index 808cae7a4..9f755280c 100644 --- a/Server/src/main/content/global/handlers/item/equipment/special/SliceAndDiceSpecialHandler.java +++ b/Server/src/main/content/global/handlers/item/equipment/special/SliceAndDiceSpecialHandler.java @@ -56,24 +56,25 @@ public final class SliceAndDiceSpecialHandler extends MeleeSwingHandler implemen return -1; } int maximum = calculateHit(entity, victim, 1.0); - int[] hits = new int[] {0, 1}; - int hit = getHit(entity, victim, maximum); + int[] hits; + int hit = getHit(entity, victim, maximum - 1, maximum / 2); if (hit > 0) { - hits = new int[] {hit, hit / 2, (hit / 2) / 2, (hit / 2) - ((hit / 2) / 2)}; + hits = new int[] {hit, hit / 2, (hit / 2) / 2, (hit / 2) / 2 + 1}; } else { - hit = getHit(entity, victim, maximum); + hit = getHit(entity, victim, maximum * 7 / 8, maximum * 3 / 8); if (hit > 0) { - hits = new int[] {0, hit, hit / 2, hit - (hit / 2)}; + hits = new int[] {0, hit, hit / 2, hit / 2 + 1}; } else { - hit = getHit(entity, victim, maximum); + hit = getHit(entity, victim, maximum * 3 / 4, maximum / 4); if (hit > 0) { - hits = new int[] {0, 0, hit / 2, (hit / 2) + 10}; + hits = new int[] {0, 0, hit, hit + 1}; } else { - hit = getHit(entity, victim, (int) (maximum * 1.5)); + hit = getHit(entity, victim, maximum * 5 / 4, maximum / 4); if (hit > 0) { hits = new int[] {0, 0, 0, hit}; } else { - hits = new int[] {0, RandomFunction.random(2)}; + hit = RandomFunction.random(2); + hits = new int[] {0, 0, hit, hit}; } } } @@ -95,9 +96,9 @@ public final class SliceAndDiceSpecialHandler extends MeleeSwingHandler implemen * @param maximum The maximum hit. * @return The hit. */ - private int getHit(Entity entity, Entity victim, int maximum) { - if (isAccurateImpact(entity, victim, CombatStyle.MELEE, 1.25, 0.98)) { - return RandomFunction.random(maximum); + private int getHit(Entity entity, Entity victim, int maximum, int minimum) { + if (isAccurateImpact(entity, victim, CombatStyle.MELEE)) { + return RandomFunction.random(minimum, maximum + 1); } return 0; } diff --git a/Server/src/main/content/global/handlers/item/equipment/special/SmashSpecialHandler.java b/Server/src/main/content/global/handlers/item/equipment/special/SmashSpecialHandler.java index e4137d26c..ba4989eda 100644 --- a/Server/src/main/content/global/handlers/item/equipment/special/SmashSpecialHandler.java +++ b/Server/src/main/content/global/handlers/item/equipment/special/SmashSpecialHandler.java @@ -59,7 +59,8 @@ public final class SmashSpecialHandler extends MeleeSwingHandler implements Plug state.setStyle(CombatStyle.MELEE); int hit = 0; if (isAccurateImpact(entity, victim, CombatStyle.MELEE, 1.0, 1.0)) { - hit = RandomFunction.random(calculateHit(entity, victim, RandomFunction.random(1.0, 1.5))); + int max = calculateHit(entity, victim, 1.0); + hit = max / 4 + RandomFunction.random(max + 1); int lower = (int) (victim.getSkills().getLevel(Skills.DEFENCE) * 0.30); victim.getSkills().updateLevel(Skills.DEFENCE, -lower, 0); } diff --git a/Server/src/main/content/global/handlers/item/equipment/special/SnapshotSpecialHandler.java b/Server/src/main/content/global/handlers/item/equipment/special/SnapshotSpecialHandler.java index ddd761a21..618a0f4b2 100644 --- a/Server/src/main/content/global/handlers/item/equipment/special/SnapshotSpecialHandler.java +++ b/Server/src/main/content/global/handlers/item/equipment/special/SnapshotSpecialHandler.java @@ -3,6 +3,7 @@ package content.global.handlers.item.equipment.special; import core.game.node.entity.Entity; import core.game.node.entity.combat.BattleState; import core.game.node.entity.combat.CombatStyle; +import core.game.node.entity.combat.SwingHandlerFlag; import core.game.node.entity.impl.Animator.Priority; import core.game.node.entity.impl.Projectile; import core.game.node.entity.player.Player; @@ -25,6 +26,13 @@ import static core.api.ContentAPIKt.playGlobalAudio; @Initializable public final class SnapshotSpecialHandler extends RangeSwingHandler implements Plugin { + /** + * Constructs a new {@code SnapshotSpecialHandler} {@code Object}. + */ + public SnapshotSpecialHandler() { + super(SwingHandlerFlag.IGNORE_PRAYER_BOOSTS_DAMAGE); + } + /** * The special energy required. */ @@ -67,13 +75,13 @@ public final class SnapshotSpecialHandler extends RangeSwingHandler implements P int max = calculateHit(entity, victim, 1.0); state.setMaximumHit(max); int hit = 0; - if (isAccurateImpact(entity, victim, CombatStyle.MELEE, 0.9, 1.0)) { - hit = RandomFunction.random(max); + if (isAccurateImpact(entity, victim, CombatStyle.MELEE, 1.43, 1.0)) { + hit = RandomFunction.random(max + 1); } state.setEstimatedHit(hit); hit = 0; - if (isAccurateImpact(entity, victim, CombatStyle.MELEE, 0.9, 1.0)) { - hit = RandomFunction.random(max); + if (isAccurateImpact(entity, victim, CombatStyle.MELEE, 1.43, 1.0)) { + hit = RandomFunction.random(max + 1); } state.setSecondaryHit(hit); Companion.useAmmo(entity, state, victim.getLocation()); diff --git a/Server/src/main/content/global/handlers/item/equipment/special/SnipeSpecialHandler.java b/Server/src/main/content/global/handlers/item/equipment/special/SnipeSpecialHandler.java index b3941ef7c..4d5b66609 100644 --- a/Server/src/main/content/global/handlers/item/equipment/special/SnipeSpecialHandler.java +++ b/Server/src/main/content/global/handlers/item/equipment/special/SnipeSpecialHandler.java @@ -60,9 +60,10 @@ public final class SnipeSpecialHandler extends RangeSwingHandler implements Plug } state.setStyle(CombatStyle.RANGE); int hit = 0; - if (isAccurateImpact(entity, victim, CombatStyle.RANGE, 1.05, 1.0)) { - hit = RandomFunction.random(calculateHit(entity, victim, 1.0)); - victim.getSkills().updateLevel(Skills.DEFENCE, -hit, 0); + if (!victim.getProperties().getCombatPulse().isAttacking() || isAccurateImpact(entity, victim, CombatStyle.RANGE)) { + hit = RandomFunction.random(calculateHit(entity, victim, 1.0) + 1); + if (victim.getSkills().getStaticLevel(Skills.DEFENCE) >= victim.getSkills().getDynamicLevels()[Skills.DEFENCE]) + victim.getSkills().updateLevel(Skills.DEFENCE, -hit, 0); } Companion.useAmmo(entity, state, victim.getLocation()); state.setEstimatedHit(hit); diff --git a/Server/src/main/content/global/handlers/item/equipment/special/SpearWallSpecialHandler.java b/Server/src/main/content/global/handlers/item/equipment/special/SpearWallSpecialHandler.java index bdbef4ee4..c83d2fd5d 100644 --- a/Server/src/main/content/global/handlers/item/equipment/special/SpearWallSpecialHandler.java +++ b/Server/src/main/content/global/handlers/item/equipment/special/SpearWallSpecialHandler.java @@ -85,7 +85,7 @@ public final class SpearWallSpecialHandler extends MeleeSwingHandler implements if (CombatStyle.RANGE.getSwingHandler().canSwing(entity, e) != InteractionType.NO_INTERACT) { BattleState s = targets[count++] = new BattleState(entity, e); int hit = 0; - hit = RandomFunction.random(calculateHit(entity, e, 1.0)); + hit = RandomFunction.random(calculateHit(entity, e, 1.0) + 1); s.setStyle(CombatStyle.MELEE); s.setEstimatedHit(hit); } diff --git a/Server/src/main/content/global/handlers/item/equipment/special/SweepSpecialHandler.java b/Server/src/main/content/global/handlers/item/equipment/special/SweepSpecialHandler.java index 4b7947736..3ef8ce0f7 100644 --- a/Server/src/main/content/global/handlers/item/equipment/special/SweepSpecialHandler.java +++ b/Server/src/main/content/global/handlers/item/equipment/special/SweepSpecialHandler.java @@ -66,14 +66,14 @@ public final class SweepSpecialHandler extends MeleeSwingHandler implements Plug for (BattleState s : targets) { s.setStyle(CombatStyle.MELEE); int hit = 0; - if (isAccurateImpact(entity, s.getVictim(), CombatStyle.MELEE, 1, 0.94)) { - hit = RandomFunction.random(calculateHit(entity, s.getVictim(), 1.1)); + if (isAccurateImpact(entity, s.getVictim(), CombatStyle.MELEE)) { + hit = RandomFunction.random(calculateHit(entity, s.getVictim(), 1.1) + 1); } s.setEstimatedHit(hit); if (s.getVictim().size() > 1) { hit = 0; - if (isAccurateImpact(entity, s.getVictim(), CombatStyle.MELEE, 1, 0.94)) { - hit = RandomFunction.random(calculateHit(entity, s.getVictim(), 1.1)); + if (isAccurateImpact(entity, s.getVictim(), CombatStyle.MELEE, 0.75, 1.0)) { + hit = RandomFunction.random(calculateHit(entity, s.getVictim(), 1.1) + 1); } s.setSecondaryHit(hit); } diff --git a/Server/src/main/content/global/handlers/item/equipment/special/WarstrikeSpecialHandler.java b/Server/src/main/content/global/handlers/item/equipment/special/WarstrikeSpecialHandler.java index 8982b198b..177769d5d 100644 --- a/Server/src/main/content/global/handlers/item/equipment/special/WarstrikeSpecialHandler.java +++ b/Server/src/main/content/global/handlers/item/equipment/special/WarstrikeSpecialHandler.java @@ -57,8 +57,8 @@ public final class WarstrikeSpecialHandler extends MeleeSwingHandler implements } state.setStyle(CombatStyle.MELEE); int hit = 0; - if (isAccurateImpact(entity, victim, CombatStyle.MELEE, 1.049, 0.98)) { - hit = RandomFunction.random(calculateHit(entity, victim, 1.1)); + if (isAccurateImpact(entity, victim, CombatStyle.MELEE, 2.0, 1.0)) { + hit = RandomFunction.random((int) (calculateHit(entity, victim, 1.1) * 1.1) + 1); } state.setEstimatedHit(hit); if (victim instanceof Player) { @@ -68,10 +68,10 @@ public final class WarstrikeSpecialHandler extends MeleeSwingHandler implements if (left > 0) { left = -victim.getSkills().updateLevel(Skills.STRENGTH, -left, 0); if (left > 0) { - left = -victim.getSkills().updateLevel(Skills.ATTACK, -left, 0); + left = (int) -(victim.getSkills().getPrayerPoints() + left); + victim.getSkills().decrementPrayerPoints(left); if (left > 0) { - left = (int) -(victim.getSkills().getPrayerPoints() + left); - victim.getSkills().decrementPrayerPoints(left); + left = -victim.getSkills().updateLevel(Skills.ATTACK, -left, 0); if (left > 0) { left = -victim.getSkills().updateLevel(Skills.MAGIC, -left, 0); if (left > 0) diff --git a/Server/src/main/content/global/handlers/item/equipment/special/WeakenSpecialHandler.java b/Server/src/main/content/global/handlers/item/equipment/special/WeakenSpecialHandler.java index 0fda16c8c..b8f45d90f 100644 --- a/Server/src/main/content/global/handlers/item/equipment/special/WeakenSpecialHandler.java +++ b/Server/src/main/content/global/handlers/item/equipment/special/WeakenSpecialHandler.java @@ -57,18 +57,19 @@ public final class WeakenSpecialHandler extends MeleeSwingHandler implements Plu state.setStyle(CombatStyle.MELEE); int hit = 0; if (isAccurateImpact(entity, victim, CombatStyle.MELEE, 1.0, 1.0)) { - hit = RandomFunction.random(calculateHit(entity, victim, 1.0)); + hit = RandomFunction.random(calculateHit(entity, victim, 1.0) + 1); + if (victim instanceof Player) { + ((Player) victim).getPacketDispatch().sendMessage("You have been drained."); + } + // TODO 10% drain to demons + int lower = (int) (victim.getSkills().getStaticLevel(Skills.DEFENCE) * 0.05) + 1; + victim.getSkills().updateLevel(Skills.DEFENCE, -lower, 0); + lower = (int) (victim.getSkills().getStaticLevel(Skills.ATTACK) * 0.05) + 1; + victim.getSkills().updateLevel(Skills.ATTACK, -lower, 0); + lower = (int) (victim.getSkills().getStaticLevel(Skills.STRENGTH) * 0.05) + 1; + victim.getSkills().updateLevel(Skills.STRENGTH, -lower, 0); } state.setEstimatedHit(hit); - if (victim instanceof Player) { - ((Player) victim).getPacketDispatch().sendMessage("You have been drained."); - } - int lower = (int) (victim.getSkills().getLevel(Skills.DEFENCE) * 0.05); - victim.getSkills().updateLevel(Skills.DEFENCE, -lower, 0); - int lower2 = (int) (victim.getSkills().getLevel(Skills.ATTACK) * 0.05); - victim.getSkills().updateLevel(Skills.ATTACK, -lower2, 0); - int lower3 = (int) (victim.getSkills().getLevel(Skills.STRENGTH) * 0.05); - victim.getSkills().updateLevel(Skills.STRENGTH, -lower3, 0); return hit; } diff --git a/Server/src/main/content/global/skill/slayer/SlayerEquipmentFlags.kt b/Server/src/main/content/global/skill/slayer/SlayerEquipmentFlags.kt index c953bf9de..e8c5e01e6 100644 --- a/Server/src/main/content/global/skill/slayer/SlayerEquipmentFlags.kt +++ b/Server/src/main/content/global/skill/slayer/SlayerEquipmentFlags.kt @@ -72,7 +72,7 @@ object SlayerEquipmentFlags { val isCape = SlayerManager.getInstance(player).flags.equipmentFlags == 0x3F val hasMask = hasBlackMask(player) - return if(hasMask) 1.15 + return if(hasMask) 1.1667 else if(isCape) 1.075 else 1.0 } diff --git a/Server/src/main/core/game/container/impl/EquipmentContainer.java b/Server/src/main/core/game/container/impl/EquipmentContainer.java index 8ecc54bf5..1e5eba34b 100644 --- a/Server/src/main/core/game/container/impl/EquipmentContainer.java +++ b/Server/src/main/core/game/container/impl/EquipmentContainer.java @@ -323,9 +323,6 @@ public final class EquipmentContainer extends Container { if (item != null) { int[] bonus = item.getDefinition().getConfiguration(ItemConfigParser.BONUS, new int[15]); for (int i = 0; i < bonus.length; i++) { - if (i == 14 && bonuses[i] != 0) { - continue; - } bonuses[i] += bonus[i]; } } diff --git a/Server/src/main/core/game/node/entity/combat/CombatSwingHandler.kt b/Server/src/main/core/game/node/entity/combat/CombatSwingHandler.kt index b5633d588..40df6d765 100644 --- a/Server/src/main/core/game/node/entity/combat/CombatSwingHandler.kt +++ b/Server/src/main/core/game/node/entity/combat/CombatSwingHandler.kt @@ -173,26 +173,21 @@ abstract class CombatSwingHandler(var type: CombatStyle?) { * @return `True` if the hit is accurate. */ fun isAccurateImpact(entity: Entity?, victim: Entity?, style: CombatStyle?, accuracyMod: Double, defenceMod: Double): Boolean { - var mod = 1.33 + var mod = 1.0 if (victim == null || style == null) { return false } if (victim is Player && entity is Familiar && victim.prayer[PrayerType.PROTECT_FROM_SUMMONING]) { mod = 0.0 } - val attack = calculateAccuracy(entity) * accuracyMod * mod * getSetMultiplier(entity, Skills.ATTACK) - val defence = calculateDefence(victim, entity) * defenceMod * getSetMultiplier(victim, Skills.DEFENCE) + val attack = calculateAccuracy(entity) * accuracyMod * mod + val defence = calculateDefence(victim, entity) * defenceMod val chance: Double = if (attack > defence) { - 1 - ((defence + 2) / ((2 * attack) + 1)) + 1 - ((defence + 2) / (2 * (attack + 1))) } else { - attack / ((2 * defence) + 1) + attack / (2 * (defence + 1)) } - val ratio = chance * 100 - val accuracy = floor(ratio) - val block = floor(101 - ratio) - val acc = Math.random() * accuracy - val def = Math.random() * block - return (acc > def).also { if(entity?.username?.toLowerCase() == "test10") log(this::class.java, Log.FINE, "Should hit: $it") } + return Math.random() < chance } /** diff --git a/Server/src/main/core/game/node/entity/combat/MagicSwingHandler.kt b/Server/src/main/core/game/node/entity/combat/MagicSwingHandler.kt index c7d850781..82bf1d5d8 100644 --- a/Server/src/main/core/game/node/entity/combat/MagicSwingHandler.kt +++ b/Server/src/main/core/game/node/entity/combat/MagicSwingHandler.kt @@ -1,5 +1,6 @@ package core.game.node.entity.combat +import content.global.skill.skillcapeperks.SkillcapePerks import core.game.node.entity.Entity import core.game.node.entity.combat.equipment.ArmourSet import core.game.node.entity.combat.spell.SpellType @@ -61,7 +62,7 @@ open class MagicSwingHandler (vararg flags: SwingHandlerFlag) for (s in state.targets) { var hit = -1 s.spell = spell - if (isAccurateImpact(entity, s.victim, CombatStyle.MAGIC, 1.3, 1.0)) { + if (isAccurateImpact(entity, s.victim, CombatStyle.MAGIC)) { s.maximumHit = max hit = RandomFunction.random(max) } @@ -136,31 +137,31 @@ open class MagicSwingHandler (vararg flags: SwingHandlerFlag) } override fun calculateAccuracy(entity: Entity?): Int { - val baseLevel = entity!!.skills.getStaticLevel(Skills.MAGIC) - var spellRequirement = baseLevel - if (entity is Player) { - if (entity.getProperties().spell != null) { - spellRequirement = entity.getProperties().spell.level - } else if (entity.getProperties().autocastSpell != null) { - spellRequirement = entity.getProperties().autocastSpell.level + entity ?: return 0 + + val styleAttackBonus = entity.properties.bonuses[WeaponInterface.BONUS_MAGIC] + 64 + when (entity) { + is Player -> { + var effectiveMagicLevel = entity.skills.getLevel(Skills.MAGIC, true).toDouble() + if(!flags.contains(SwingHandlerFlag.IGNORE_PRAYER_BOOSTS_ACCURACY)) + effectiveMagicLevel = floor(effectiveMagicLevel + (entity.prayer.getSkillBonus(Skills.MAGIC) * effectiveMagicLevel)) + effectiveMagicLevel += 8 + effectiveMagicLevel *= getSetMultiplier(entity, Skills.MAGIC) + effectiveMagicLevel = floor(effectiveMagicLevel) + + if (!flags.contains(SwingHandlerFlag.IGNORE_STAT_BOOSTS_ACCURACY)) + effectiveMagicLevel *= styleAttackBonus + else effectiveMagicLevel *= 64 + + return effectiveMagicLevel.toInt() + } + is NPC -> { + val magicLevel = entity.skills.getLevel(Skills.MAGIC) + 9 + return magicLevel * styleAttackBonus } } - var spellBonus = 0.0 - if (baseLevel > spellRequirement) { - spellBonus = (baseLevel - spellRequirement) * .3 - } - val level = entity.skills.getLevel(Skills.MAGIC, true) - var prayer = 1.0 - if (entity is Player && !flags.contains(SwingHandlerFlag.IGNORE_PRAYER_BOOSTS_ACCURACY)) { - prayer += entity.prayer.getSkillBonus(Skills.MAGIC) - } - val additional = getSetMultiplier(entity, Skills.MAGIC) - val effective = floor(level * prayer * additional + spellBonus) - val bonus = - if (!flags.contains(SwingHandlerFlag.IGNORE_STAT_BOOSTS_ACCURACY)) - entity.properties.bonuses[WeaponInterface.BONUS_MAGIC] - else 0 - return floor((effective + 8) * (bonus + 64) / 10).toInt() + + return 0 } override fun calculateHit(entity: Entity?, victim: Entity?, modifier: Double): Int { @@ -183,14 +184,31 @@ open class MagicSwingHandler (vararg flags: SwingHandlerFlag) } override fun calculateDefence(victim: Entity?, attacker: Entity?): Int { - val level = victim!!.skills.getLevel(Skills.DEFENCE, true) - var prayer = 1.0 - if (victim is Player) { - prayer += victim.prayer.getSkillBonus(Skills.MAGIC) + victim ?: return 0 + attacker ?: return 0 + + val styleDefenceBonus = victim.properties.bonuses[WeaponInterface.BONUS_MAGIC + 5] + 64 + when (victim) { + is Player -> { + var effectiveDefenceLevel = victim.skills.getLevel(Skills.DEFENCE).toDouble() + effectiveDefenceLevel = floor(effectiveDefenceLevel + (victim.prayer.getSkillBonus(Skills.DEFENCE) * effectiveDefenceLevel)) + if (victim.properties.attackStyle.style == WeaponInterface.STYLE_DEFENSIVE || victim.properties.attackStyle.style == WeaponInterface.STYLE_LONG_RANGE) effectiveDefenceLevel += 3 + else if (victim.properties.attackStyle.style == WeaponInterface.STYLE_CONTROLLED) effectiveDefenceLevel += 1 + effectiveDefenceLevel *= getSetMultiplier(victim, Skills.DEFENCE) + + var effectiveMagicLevel = victim.skills.getLevel(Skills.MAGIC).toDouble() + effectiveMagicLevel = floor(effectiveMagicLevel + (victim.prayer.getSkillBonus(Skills.MAGIC) * effectiveMagicLevel)) + + effectiveDefenceLevel = effectiveDefenceLevel * 0.3 + effectiveMagicLevel * 0.7 + 8 + return effectiveDefenceLevel.toInt() * styleDefenceBonus + } + is NPC -> { + val defLevel = victim.skills.getLevel(Skills.MAGIC) + 9 + return defLevel * styleDefenceBonus + } } - val effective = floor(level * prayer * 0.3) + victim.skills.getLevel(Skills.MAGIC, true) * 0.7 - val equipment = victim.properties.bonuses[WeaponInterface.BONUS_MAGIC + 5] - return floor((effective + 8) * (equipment + 64) / 10).toInt() + + return 0 } override fun getSetMultiplier(e: Entity?, skillId: Int): Double { diff --git a/Server/src/main/core/game/node/entity/combat/MeleeSwingHandler.kt b/Server/src/main/core/game/node/entity/combat/MeleeSwingHandler.kt index d755c269d..c32a7567e 100644 --- a/Server/src/main/core/game/node/entity/combat/MeleeSwingHandler.kt +++ b/Server/src/main/core/game/node/entity/combat/MeleeSwingHandler.kt @@ -64,13 +64,16 @@ open class MeleeSwingHandler (vararg flags: SwingHandlerFlag) if (entity is Player) { state.weapon = Weapon(entity.equipment[3]) } - if (entity!!.properties.armourSet === ArmourSet.VERAC && RandomFunction.random(100) < 21) { + if (entity!!.properties.armourSet === ArmourSet.VERAC && RandomFunction.random(100) < 25) { state.armourEffect = ArmourSet.VERAC } if (state.armourEffect === ArmourSet.VERAC || isAccurateImpact(entity, victim, CombatStyle.MELEE)) { - val max = calculateHit(entity, victim, 1.0) + var max = calculateHit(entity, victim, 1.0) + if (victim != null) { + if (entity is NPC && state.armourEffect === ArmourSet.VERAC && victim.hasProtectionPrayer(CombatStyle.MELEE)) max = max * 2 / 3 + } state.maximumHit = max - hit = RandomFunction.random(max + 1) + hit = RandomFunction.random(max + 1) + (if (entity is Player && state.armourEffect === ArmourSet.VERAC) 1 else 0) } state.estimatedHit = hit if(victim != null) { @@ -128,68 +131,79 @@ open class MeleeSwingHandler (vararg flags: SwingHandlerFlag) override fun calculateAccuracy(entity: Entity?): Int { //formula taken from wiki: https://oldschool.runescape.wiki/w/Damage_per_second/Melee#Step_six:_Calculate_the_hit_chance Yes I know it's old school. It's the best resource we have for potentially authentic formulae. entity ?: return 0 - var effectiveAttackLevel = entity.skills.getLevel(Skills.ATTACK).toDouble() - if(entity is Player && !flags.contains(SwingHandlerFlag.IGNORE_PRAYER_BOOSTS_ACCURACY)) - effectiveAttackLevel = floor(effectiveAttackLevel + (entity.prayer.getSkillBonus(Skills.ATTACK) * effectiveAttackLevel)) - if(entity.properties.attackStyle.style == WeaponInterface.STYLE_ACCURATE) effectiveAttackLevel += 3 - else if(entity.properties.attackStyle.style == WeaponInterface.STYLE_CONTROLLED) effectiveAttackLevel += 1 - effectiveAttackLevel += 8 - if(entity is Player && SkillcapePerks.isActive(SkillcapePerks.PRECISION_STRIKES, entity)){ //Attack skillcape perk - effectiveAttackLevel += 6 - } - effectiveAttackLevel *= getSetMultiplier(entity, Skills.ATTACK) - effectiveAttackLevel = floor(effectiveAttackLevel) - if (!flags.contains(SwingHandlerFlag.IGNORE_STAT_BOOSTS_ACCURACY)) - effectiveAttackLevel *= (entity.properties.bonuses[entity.properties.attackStyle.bonusType] + 64) - else effectiveAttackLevel *= 64 + val styleAttackBonus = entity.properties.bonuses[entity.properties.attackStyle.bonusType] + 64 + when (entity) { + is Player -> { + var effectiveAttackLevel = entity.skills.getLevel(Skills.ATTACK).toDouble() + if(!flags.contains(SwingHandlerFlag.IGNORE_PRAYER_BOOSTS_ACCURACY)) + effectiveAttackLevel = floor(effectiveAttackLevel + (entity.prayer.getSkillBonus(Skills.ATTACK) * effectiveAttackLevel)) + if(entity.properties.attackStyle.style == WeaponInterface.STYLE_ACCURATE) effectiveAttackLevel += 3 + else if(entity.properties.attackStyle.style == WeaponInterface.STYLE_CONTROLLED) effectiveAttackLevel += 1 + effectiveAttackLevel += 8 + if(SkillcapePerks.isActive(SkillcapePerks.PRECISION_STRIKES, entity)){ //Attack skillcape perk + effectiveAttackLevel += 6 + } + effectiveAttackLevel *= getSetMultiplier(entity, Skills.ATTACK) + effectiveAttackLevel = floor(effectiveAttackLevel) + if (!flags.contains(SwingHandlerFlag.IGNORE_STAT_BOOSTS_ACCURACY)) + effectiveAttackLevel *= styleAttackBonus + else effectiveAttackLevel *= 64 - val victimName = entity.properties.combatPulse.getVictim()?.name ?: "none" + val victimName = entity.properties.combatPulse.getVictim()?.name ?: "none" - // attack bonus for specialized equipments (salve amulets, slayer equips) - if (entity is Player) { - val amuletId = getItemFromEquipment(entity, EquipmentSlot.NECK)?.id ?: 0 - if ((amuletId == Items.SALVE_AMULET_4081 || amuletId == Items.SALVE_AMULETE_10588) && checkUndead(victimName)) { - effectiveAttackLevel *= if (amuletId == Items.SALVE_AMULET_4081) 1.15 else 1.2 - } else if (getSlayerTask(entity)?.ids?.contains((entity.properties.combatPulse?.getVictim()?.id ?: 0)) == true) { - effectiveAttackLevel *= SlayerEquipmentFlags.getDamAccBonus(entity) //Slayer Helm/ Black Mask/ Slayer cape - if (getSlayerTask(entity)?.dragon == true && inEquipment(entity, Items.DRAGON_SLAYER_GLOVES_12862)) - effectiveAttackLevel *= 1.1 + // attack bonus for specialized equipments (salve amulets, slayer equips) + val amuletId = getItemFromEquipment(entity, EquipmentSlot.NECK)?.id ?: 0 + if ((amuletId == Items.SALVE_AMULET_4081 || amuletId == Items.SALVE_AMULETE_10588) && checkUndead(victimName)) { + effectiveAttackLevel *= if (amuletId == Items.SALVE_AMULET_4081) 1.15 else 1.2 + } else if (getSlayerTask(entity)?.ids?.contains((entity.properties.combatPulse?.getVictim()?.id ?: 0)) == true) { + effectiveAttackLevel *= SlayerEquipmentFlags.getDamAccBonus(entity) //Slayer Helm/ Black Mask/ Slayer cape + if (getSlayerTask(entity)?.dragon == true && inEquipment(entity, Items.DRAGON_SLAYER_GLOVES_12862)) + effectiveAttackLevel *= 1.1 + } + + return effectiveAttackLevel.toInt() + } + is NPC -> { + val attackLevel = entity.skills.getLevel(Skills.ATTACK) + 9 + return attackLevel * styleAttackBonus } } - return floor(effectiveAttackLevel).toInt() + return 0 + + } override fun calculateHit(entity: Entity?, victim: Entity?, modifier: Double): Int { - val level = entity!!.skills.getLevel(Skills.STRENGTH) - var bonus = entity.properties.bonuses[11] - var prayer = 1.0 - if (entity is Player && !flags.contains(SwingHandlerFlag.IGNORE_PRAYER_BOOSTS_DAMAGE)) { - prayer += entity.prayer.getSkillBonus(Skills.STRENGTH) - } - var cumulativeStr = floor(level * prayer) - if (entity.properties.attackStyle.style == WeaponInterface.STYLE_AGGRESSIVE) { - cumulativeStr += 3.0 - } else if (entity.properties.attackStyle.style == WeaponInterface.STYLE_CONTROLLED) { - cumulativeStr += 1.0 + entity ?: return 0 + + var styleStrengthBonus = entity.properties.bonuses[11] + 64 + when (entity) { + is Player -> { + var effectiveStrengthLevel = entity.skills.getLevel(Skills.STRENGTH).toDouble() + if(!flags.contains(SwingHandlerFlag.IGNORE_PRAYER_BOOSTS_DAMAGE)) + effectiveStrengthLevel = floor(effectiveStrengthLevel + (entity.prayer.getSkillBonus(Skills.STRENGTH) * effectiveStrengthLevel)) + if(entity.properties.attackStyle.style == WeaponInterface.STYLE_AGGRESSIVE) effectiveStrengthLevel += 3 + else if (entity.properties.attackStyle.style == WeaponInterface.STYLE_CONTROLLED) effectiveStrengthLevel += 1 + effectiveStrengthLevel += 8 + effectiveStrengthLevel *= getSetMultiplier(entity, Skills.STRENGTH) + effectiveStrengthLevel = floor(effectiveStrengthLevel) + if (!flags.contains(SwingHandlerFlag.IGNORE_STAT_BOOSTS_DAMAGE)) + effectiveStrengthLevel *= styleStrengthBonus + else effectiveStrengthLevel *= 64 + if (getSlayerTask(entity)?.ids?.contains((entity.properties.combatPulse?.getVictim()?.id ?: 0)) == true) + effectiveStrengthLevel *= SlayerEquipmentFlags.getDamAccBonus(entity) //Slayer Helm/ Black Mask/ Slayer cape + + return (floor((0.5 + (effectiveStrengthLevel / 640.0))) * modifier).toInt() + } + is NPC -> { + val strengthLevel = entity.skills.getLevel(Skills.STRENGTH) + 9 + return (floor((0.5 + (strengthLevel * styleStrengthBonus / 640.0))) * modifier).toInt() + } } - //Strength skillcape perk - if(entity is Player && SkillcapePerks.isActive(SkillcapePerks.FINE_ATTUNEMENT, entity) && getItemFromEquipment(entity, EquipmentSlot.WEAPON)?.definition?.getRequirement(Skills.STRENGTH) != 0) - bonus = ceil(bonus * 1.20).toInt() - - if (flags.contains(SwingHandlerFlag.IGNORE_STAT_BOOSTS_DAMAGE)) - bonus = 0 - - cumulativeStr *= getSetMultiplier(entity, Skills.STRENGTH) - - if(entity is Player && getSlayerTask(entity)?.ids?.contains((entity.properties.combatPulse?.getVictim()?.id ?: 0)) == true) - cumulativeStr *= SlayerEquipmentFlags.getDamAccBonus(entity) //Slayer helm/black mask/skillcape - - /*val hit = (16 + cumulativeStr + bonus / 8 + cumulativeStr * bonus * 0.016865) * modifier - return (hit / 10).toInt() + 1*/ - return ((1.3 + (cumulativeStr / 10) + (bonus / 80) + ((cumulativeStr * bonus) / 640)) * modifier).toInt() + return 0 } override fun calculateDefence(victim: Entity?, attacker: Entity?): Int { @@ -197,19 +211,19 @@ open class MeleeSwingHandler (vararg flags: SwingHandlerFlag) victim ?: return 0 attacker ?: return 0 - when(victim){ + val styleDefenceBonus = victim.properties.bonuses[attacker.properties.attackStyle.bonusType + 5] + 64 + when (victim) { is Player -> { var effectiveDefenceLevel = victim.skills.getLevel(Skills.DEFENCE).toDouble() effectiveDefenceLevel = floor(effectiveDefenceLevel + (victim.prayer.getSkillBonus(Skills.DEFENCE) * effectiveDefenceLevel)) - if(victim.properties.attackStyle.style == WeaponInterface.STYLE_DEFENSIVE) effectiveDefenceLevel += 3 - else if(victim.properties.attackStyle.style == WeaponInterface.STYLE_CONTROLLED) effectiveDefenceLevel += 1 + if (victim.properties.attackStyle.style == WeaponInterface.STYLE_DEFENSIVE || victim.properties.attackStyle.style == WeaponInterface.STYLE_LONG_RANGE) effectiveDefenceLevel += 3 + else if (victim.properties.attackStyle.style == WeaponInterface.STYLE_CONTROLLED) effectiveDefenceLevel += 1 effectiveDefenceLevel += 8 - effectiveDefenceLevel = floor(effectiveDefenceLevel) - return floor(effectiveDefenceLevel * (victim.properties.bonuses[attacker.properties.attackStyle.bonusType + 5] + 64)).toInt() + effectiveDefenceLevel *= getSetMultiplier(victim, Skills.DEFENCE) + return effectiveDefenceLevel.toInt() * styleDefenceBonus } is NPC -> { - val defLevel = victim.skills.getLevel(Skills.DEFENCE) - val styleDefenceBonus = victim.properties.bonuses[attacker.properties.attackStyle.bonusType + 5] + 64 + val defLevel = victim.skills.getLevel(Skills.DEFENCE) + 9 return defLevel * styleDefenceBonus } } diff --git a/Server/src/main/core/game/node/entity/combat/RangeSwingHandler.kt b/Server/src/main/core/game/node/entity/combat/RangeSwingHandler.kt index 325dd3f78..c0e20bf67 100644 --- a/Server/src/main/core/game/node/entity/combat/RangeSwingHandler.kt +++ b/Server/src/main/core/game/node/entity/combat/RangeSwingHandler.kt @@ -13,14 +13,14 @@ import core.game.node.entity.skill.Skills import core.game.node.item.GroundItem import core.game.node.item.GroundItemManager import core.game.node.item.Item +import core.game.system.config.ItemConfigParser import core.game.system.task.Pulse +import core.game.world.GameWorld import core.game.world.map.Location import core.game.world.map.RegionManager import core.game.world.update.flag.context.Graphics -import core.tools.RandomFunction -import core.tools.SystemLogger -import core.game.world.GameWorld import core.tools.Log +import core.tools.RandomFunction import java.util.* import kotlin.math.ceil import kotlin.math.floor @@ -83,7 +83,7 @@ open class RangeSwingHandler (vararg flags: SwingHandlerFlag) state.estimatedHit = hit if (state.weapon.type == WeaponType.DOUBLE_SHOT) { if (isAccurateImpact(entity, victim, CombatStyle.RANGE)) { - hit = RandomFunction.random(calculateHit(entity, victim, 1.0)) + hit = RandomFunction.random(calculateHit(entity, victim, 1.0) + 1) } state.secondaryHit = hit } @@ -183,56 +183,92 @@ open class RangeSwingHandler (vararg flags: SwingHandlerFlag) override fun calculateAccuracy(entity: Entity?): Int { entity ?: return 0 - var effectiveRangedLevel = entity.skills.getLevel(Skills.RANGE).toDouble() - if(entity is Player && !flags.contains(SwingHandlerFlag.IGNORE_PRAYER_BOOSTS_ACCURACY)) - effectiveRangedLevel = floor(effectiveRangedLevel + (entity.prayer.getSkillBonus(Skills.RANGE) * effectiveRangedLevel)) - if(entity.properties.attackStyle.style == WeaponInterface.STYLE_RANGE_ACCURATE) effectiveRangedLevel += 3 - effectiveRangedLevel += 8 - effectiveRangedLevel *= getSetMultiplier(entity, Skills.RANGE) - if(entity is Player && SkillcapePerks.isActive(SkillcapePerks.ACCURATE_MARKSMAN,entity)) effectiveRangedLevel *= 1.1 - effectiveRangedLevel = floor(effectiveRangedLevel) - if (!flags.contains(SwingHandlerFlag.IGNORE_STAT_BOOSTS_ACCURACY)) - effectiveRangedLevel *= (entity.properties.bonuses[entity.properties.attackStyle.bonusType] + 64) - else effectiveRangedLevel *= 64 + val styleAttackBonus = entity.properties.bonuses[entity.properties.attackStyle.bonusType] + 64 + when (entity) { + is Player -> { + var effectiveRangedLevel = entity.skills.getLevel(Skills.RANGE).toDouble() + if(!flags.contains(SwingHandlerFlag.IGNORE_PRAYER_BOOSTS_ACCURACY)) + effectiveRangedLevel = floor(effectiveRangedLevel + (entity.prayer.getSkillBonus(Skills.RANGE) * effectiveRangedLevel)) + if(entity.properties.attackStyle.style == WeaponInterface.STYLE_RANGE_ACCURATE) effectiveRangedLevel += 3 + effectiveRangedLevel += 8 + effectiveRangedLevel *= getSetMultiplier(entity, Skills.RANGE) + if(SkillcapePerks.isActive(SkillcapePerks.ACCURATE_MARKSMAN,entity)) effectiveRangedLevel *= 1.1 - return floor(effectiveRangedLevel).toInt() + effectiveRangedLevel = floor(effectiveRangedLevel) + if (!flags.contains(SwingHandlerFlag.IGNORE_STAT_BOOSTS_ACCURACY)) + effectiveRangedLevel *= styleAttackBonus + else effectiveRangedLevel *= 64 + + return effectiveRangedLevel.toInt() + } + is NPC -> { + val rangedLevel = entity.skills.getLevel(Skills.RANGE) + 9 + return rangedLevel * styleAttackBonus + } + } + + return 0 } override fun calculateHit(entity: Entity?, victim: Entity?, modifier: Double): Int { - val level = entity!!.skills.getLevel(Skills.RANGE) - val bonus = entity.properties.bonuses[14] - var prayer = 1.0 - if (entity is Player && !flags.contains(SwingHandlerFlag.IGNORE_PRAYER_BOOSTS_DAMAGE)) { - prayer += entity.prayer.getSkillBonus(Skills.RANGE) - } - var cumulativeStr = floor(level * prayer) - if (entity.properties.attackStyle.style == WeaponInterface.STYLE_RANGE_ACCURATE) { - cumulativeStr += 3.0 - } - cumulativeStr *= getSetMultiplier(entity, Skills.RANGE) + entity ?: return 0 - if (!flags.contains(SwingHandlerFlag.IGNORE_STAT_BOOSTS_DAMAGE)) - cumulativeStr *= (bonus + 64) - else cumulativeStr *= 64 + var styleStrengthBonus = entity.properties.bonuses[14] + 64 + when (entity) { + is Player -> { + if(entity.equipment[EquipmentContainer.SLOT_WEAPON] != null && RangeWeapon.get(entity.equipment[EquipmentContainer.SLOT_WEAPON].id).ammunitionSlot != EquipmentContainer.SLOT_ARROWS && entity.equipment[EquipmentContainer.SLOT_ARROWS] != null) + styleStrengthBonus -= entity.equipment[EquipmentContainer.SLOT_ARROWS].definition.getConfiguration(ItemConfigParser.BONUS)[14] + var effectiveStrengthLevel = entity.skills.getLevel(Skills.RANGE).toDouble() + if(!flags.contains(SwingHandlerFlag.IGNORE_PRAYER_BOOSTS_DAMAGE)) + effectiveStrengthLevel = floor(effectiveStrengthLevel + (entity.prayer.getSkillBonus(Skills.RANGE) * effectiveStrengthLevel)) + if(entity.properties.attackStyle.style == WeaponInterface.STYLE_RANGE_ACCURATE) effectiveStrengthLevel += 3 + effectiveStrengthLevel += 8 + effectiveStrengthLevel *= getSetMultiplier(entity, Skills.RANGE) + effectiveStrengthLevel = floor(effectiveStrengthLevel) + if (!flags.contains(SwingHandlerFlag.IGNORE_STAT_BOOSTS_DAMAGE)) + effectiveStrengthLevel *= styleStrengthBonus + else effectiveStrengthLevel *= 64 - return floor((1.5 + (ceil(cumulativeStr) / 640.0)) * modifier).toInt() - //return ((14 + cumulativeStr + bonus / 8 + cumulativeStr * bonus * 0.016865) * modifier).toInt() / 10 + 1 + return (floor((0.5 + (effectiveStrengthLevel / 640.0))) * modifier).toInt() + } + is NPC -> { + val rangedLevel = entity.skills.getLevel(Skills.RANGE) + 9 + return (floor((0.5 + (rangedLevel * styleStrengthBonus / 640.0))) * modifier).toInt() + } + } + + return 0 } override fun calculateDefence(victim: Entity?, attacker: Entity?): Int { victim ?: return 0 attacker ?: return 0 - val defLevel = victim.skills.getLevel(Skills.DEFENCE) val styleDefenceBonus = victim.properties.bonuses[attacker.properties.attackStyle.bonusType + 5] + 64 - return defLevel * styleDefenceBonus + when (victim) { + is Player -> { + var effectiveDefLevel = victim.skills.getLevel(Skills.DEFENCE).toDouble() + effectiveDefLevel = floor(effectiveDefLevel + (victim.prayer.getSkillBonus(Skills.DEFENCE) * effectiveDefLevel)) + if (victim.properties.attackStyle.style == WeaponInterface.STYLE_DEFENSIVE || victim.properties.attackStyle.style == WeaponInterface.STYLE_LONG_RANGE) effectiveDefLevel += 3 + else if (victim.properties.attackStyle.style == WeaponInterface.STYLE_CONTROLLED) effectiveDefLevel += 1 + effectiveDefLevel += 8 + effectiveDefLevel *= getSetMultiplier(victim, Skills.DEFENCE) + return effectiveDefLevel.toInt() * styleDefenceBonus + } + is NPC -> { + val defLevel = victim.skills.getLevel(Skills.DEFENCE) + 9 + return defLevel * styleDefenceBonus + } + } + + return 0 } override fun getSetMultiplier(e: Entity?, skillId: Int): Double { if(skillId == Skills.RANGE) { if(e is Player && e.isWearingVoid(CombatStyle.RANGE)) { - return 1.1 + return 1.2 } } return 1.0 diff --git a/Server/src/main/core/game/node/entity/combat/equipment/ArmourSet.java b/Server/src/main/core/game/node/entity/combat/equipment/ArmourSet.java index 16097c032..f311b95e6 100644 --- a/Server/src/main/core/game/node/entity/combat/equipment/ArmourSet.java +++ b/Server/src/main/core/game/node/entity/combat/equipment/ArmourSet.java @@ -21,7 +21,7 @@ public enum ArmourSet { AHRIM(new Graphics(401, 96), new int[][] { { 4708, 4856, 4857, 4858, 4859 }, { 4710, 4862, 4863, 4864, 4865 }, { 4712, 4868, 4869, 4870, 4871 }, { 4714, 4874, 4875, 4876, 4877 } }) { @Override public boolean effect(Entity e, Entity victim, BattleState state) { - if (RandomFunction.random(100) < 20) { + if (RandomFunction.random(100) < 25 && state.getEstimatedHit() > -1) { victim.getSkills().updateLevel(Skills.STRENGTH, -5, 0); return true; } @@ -78,8 +78,8 @@ public enum ArmourSet { KARIL(new Graphics(400, 96), new int[][] { { 4732, 4928, 4929, 4930, 4931 }, { 4734, 4934, 4935, 4936, 4937 }, { 4736, 4940, 4941, 4942, 4943 }, { 4738, 4946, 4947, 4948, 4949 } }) { @Override public boolean effect(Entity e, Entity victim, BattleState state) { - if (state.getEstimatedHit() > 9 && RandomFunction.random(100) < 20) { - victim.getSkills().updateLevel(Skills.AGILITY, -(state.getEstimatedHit() / 10), 0); + if (state.getEstimatedHit() > 0 && RandomFunction.random(100) < 25) { + victim.getSkills().updateLevel(Skills.AGILITY, -(victim.getSkills().getDynamicLevels()[Skills.AGILITY] / 5), 0); return true; } return false; @@ -100,7 +100,7 @@ public enum ArmourSet { TORAG(new Graphics(399, 96), new int[][] { { 4745, 4952, 4953, 4954, 4955 }, { 4747, 4958, 4959, 4960, 4961 }, { 4749, 4964, 4965, 4966, 4967 }, { 4751, 4970, 4971, 4972, 4973 } }) { @Override public boolean effect(Entity e, Entity victim, BattleState state) { - if (state.getEstimatedHit() > 0 && RandomFunction.random(100) < 20) { + if (state.getEstimatedHit() > 0 && RandomFunction.random(100) < 25) { if (victim instanceof Player) { ((Player) victim).getSettings().updateRunEnergy(20); } diff --git a/Server/src/main/core/game/system/command/sets/MiscCommandSet.kt b/Server/src/main/core/game/system/command/sets/MiscCommandSet.kt index 9893a25a8..fb7b7b544 100644 --- a/Server/src/main/core/game/system/command/sets/MiscCommandSet.kt +++ b/Server/src/main/core/game/system/command/sets/MiscCommandSet.kt @@ -46,10 +46,11 @@ class MiscCommandSet : CommandSet(Privilege.ADMIN){ player.toggleDebug() } - define("calc_accuracy", Privilege.STANDARD, "::calc_accuracy NPC ID", "Calculates and prints your current chance to hit a given NPC."){ player, args -> + define("calcaccuracy", Privilege.STANDARD, "::calcaccuracy NPC ID", "Calculates and prints your current chance to hit a given NPC."){ player, args -> val handler = player.getSwingHandler(false) player.sendMessage("handler type: ${handler.type}") - player.sendMessage("calculateAccuracy: ${handler.calculateAccuracy(player)}") + val accuracy = handler.calculateAccuracy(player) + player.sendMessage("calculateAccuracy: ${accuracy}") if (args.size > 1) { @@ -57,7 +58,14 @@ class MiscCommandSet : CommandSet(Privilege.ADMIN){ val npc = NPC(npcId) npc.initConfig() player.sendMessage("npc: ${npc.name}. npc defence: ${npc.skills.getLevel(Skills.DEFENCE)}") - player.sendMessage("calculateDefence: ${handler.calculateDefence(npc, player)}") + val defence = handler.calculateDefence(npc, player) + player.sendMessage("calculateDefence: ${defence}") + val chance: Double = if (accuracy > defence) { + 1.0 - ((defence + 2.0) / (2.0 * (accuracy + 1.0))) + } else { + accuracy / (2.0 * (defence + 1.0)) + } + player.sendMessage("chance to hit: ${chance}") } } @@ -107,7 +115,7 @@ class MiscCommandSet : CommandSet(Privilege.ADMIN){ define("calcmaxhit", Privilege.STANDARD, "", "Calculates and shows you your current max hit.") { player, _ -> val swingHandler = player.getSwingHandler(false) val hit = swingHandler.calculateHit(player, player, 1.0) - notify(player, "max hit (${(swingHandler as Object).getClass().getName()}): ${hit}") + notify(player, "max hit: ${hit} (${(swingHandler as Object).getClass().getName()})") } /** diff --git a/Server/src/test/kotlin/content/CombatTests.kt b/Server/src/test/kotlin/content/CombatTests.kt index 55ffc715e..762ed8406 100644 --- a/Server/src/test/kotlin/content/CombatTests.kt +++ b/Server/src/test/kotlin/content/CombatTests.kt @@ -2,6 +2,10 @@ package content import TestUtils import content.global.handlers.item.equipment.special.ChinchompaSwingHandler +import core.api.EquipmentSlot +import core.game.container.impl.EquipmentContainer.updateBonuses +import core.game.interaction.IntType +import core.game.interaction.InteractionListeners import core.game.node.entity.combat.MagicSwingHandler import core.game.node.entity.combat.MeleeSwingHandler import core.game.node.entity.combat.RangeSwingHandler @@ -9,8 +13,10 @@ import core.game.node.entity.combat.SwingHandlerFlag import core.game.node.entity.combat.equipment.WeaponInterface import core.game.node.entity.player.link.prayer.PrayerType import core.game.node.entity.skill.Skills +import core.game.node.item.Item import org.junit.jupiter.api.Assertions import org.junit.jupiter.api.Test +import org.rs09.consts.Items class CombatTests { init { @@ -115,12 +121,17 @@ class CombatTests { } } - @Test fun chinchompaSwingHandlerIgnoresStatsForDamage() { + @Test fun chinchompaSwingHandlerIgnoresAmmoSlotForDamage() { val handler = ChinchompaSwingHandler() TestUtils.getMockPlayer("chinchompaStatTest").use { p -> + p.skills.staticLevels[Skills.RANGE] = 99 + p.skills.dynamicLevels[Skills.RANGE] = 99 + p.equipment.replace(Item(Items.CHINCHOMPA_10033), EquipmentSlot.WEAPON.ordinal) + updateBonuses(p) val damageBaseline = handler.calculateHit(p, p, 1.0) - p.properties.bonuses[14] = 250 + p.equipment.replace(Item(Items.DRAGON_ARROW_11212), EquipmentSlot.AMMO.ordinal) + updateBonuses(p) Assertions.assertEquals(damageBaseline, handler.calculateHit(p, p, 1.0)) } }