From 1f04a13f67b0a7cb71d3c4008afa2295980c96f2 Mon Sep 17 00:00:00 2001 From: Kamron Batman <3953314+kamronbatman@users.noreply.github.com> Date: Sat, 4 Nov 2023 12:32:54 -0700 Subject: [PATCH] fix: Fixes poison field duration, cleans up skill calculations and poison calculations (#1582) ### Summary - [X] Fixes poison field duration - [X] Adds SA+ poison spell calculations - [X] Cleans up skill calculations - [X] Adjusts poison level thresholds to properly reflect OSI --- .../UOContent/Engines/Craft/Core/Enhance.cs | 2 +- .../Skill Items/Magical/Potions/BasePotion.cs | 2 +- .../Weapons/Abilities/InfectiousStrike.cs | 2 +- .../Items/Weapons/Abilities/SerpentArrow.cs | 11 ++- Projects/UOContent/Misc/RegenRates.cs | 2 +- Projects/UOContent/Spells/Base/SpellHelper.cs | 4 +- .../UOContent/Spells/Bushido/Confidence.cs | 7 +- .../UOContent/Spells/Chivalry/PaladinSpell.cs | 2 +- .../UOContent/Spells/Fifth/PoisonField.cs | 18 ++--- .../UOContent/Spells/Fifth/SummonCreature.cs | 2 +- Projects/UOContent/Spells/First/Heal.cs | 8 +- .../UOContent/Spells/Ninjitsu/DeathStrike.cs | 2 +- .../UOContent/Spells/Second/Protection.cs | 8 +- .../UOContent/Spells/Seventh/EnergyField.cs | 2 +- .../UOContent/Spells/Sixth/Invisibility.cs | 2 +- Projects/UOContent/Spells/Third/Poison.cs | 75 ++++++++----------- 16 files changed, 68 insertions(+), 81 deletions(-) diff --git a/Projects/UOContent/Engines/Craft/Core/Enhance.cs b/Projects/UOContent/Engines/Craft/Core/Enhance.cs index acde73673..99a70464f 100644 --- a/Projects/UOContent/Engines/Craft/Core/Enhance.cs +++ b/Projects/UOContent/Engines/Craft/Core/Enhance.cs @@ -182,7 +182,7 @@ namespace Server.Engines.Craft dincBonus = false; } - var skill = from.Skills[craftSystem.MainSkill].Fixed / 10; + var skill = (int)from.Skills[craftSystem.MainSkill].Value; if (skill >= 100) { diff --git a/Projects/UOContent/Items/Skill Items/Magical/Potions/BasePotion.cs b/Projects/UOContent/Items/Skill Items/Magical/Potions/BasePotion.cs index 9aba4ab72..927c76fa2 100644 --- a/Projects/UOContent/Items/Skill Items/Magical/Potions/BasePotion.cs +++ b/Projects/UOContent/Items/Skill Items/Magical/Potions/BasePotion.cs @@ -195,7 +195,7 @@ public abstract partial class BasePotion : Item, ICraftable, ICommodity public static int EnhancePotions(Mobile m) { var EP = AosAttributes.GetValue(m, AosAttribute.EnhancePotions); - var skillBonus = m.Skills.Alchemy.Fixed / 330 * 10; + var skillBonus = (int)(m.Skills.Alchemy.Value * 10 / 33); if (Core.ML && EP > 50 && m.AccessLevel <= AccessLevel.Player) { diff --git a/Projects/UOContent/Items/Weapons/Abilities/InfectiousStrike.cs b/Projects/UOContent/Items/Weapons/Abilities/InfectiousStrike.cs index 9939e2a14..92936d0f9 100644 --- a/Projects/UOContent/Items/Weapons/Abilities/InfectiousStrike.cs +++ b/Projects/UOContent/Items/Weapons/Abilities/InfectiousStrike.cs @@ -47,7 +47,7 @@ namespace Server.Items --weapon.PoisonCharges; // Infectious strike special move now uses poisoning skill to help determine potency - var maxLevel = Math.Max(attacker.Skills.Poisoning.Fixed / 200, 0); + var maxLevel = Math.Max((int)(attacker.Skills.Poisoning.Value / 20), 0); if (p.Level > maxLevel) { p = Poison.GetPoison(maxLevel); diff --git a/Projects/UOContent/Items/Weapons/Abilities/SerpentArrow.cs b/Projects/UOContent/Items/Weapons/Abilities/SerpentArrow.cs index 138dc25bf..fd3ba4afa 100644 --- a/Projects/UOContent/Items/Weapons/Abilities/SerpentArrow.cs +++ b/Projects/UOContent/Items/Weapons/Abilities/SerpentArrow.cs @@ -18,17 +18,15 @@ namespace Server.Items ClearCurrentAbility(attacker); - defender.SendLocalizedMessage(1112369); // You have been poisoned by a lethal arrow! - int level; if (attacker.InRange(defender, 2)) { - level = attacker.Skills.Poisoning.Fixed / 2 switch + level = (attacker.Skills.Archery.Value + attacker.Skills.Poisoning.Value) switch { - >= 1000 => 3, - > 850 => 2, - > 650 => 1, + > 199.8 => 3, + > 170.2 => 2, + > 130.2 => 1, _ => 0 }; } @@ -37,6 +35,7 @@ namespace Server.Items level = 0; } + defender.SendLocalizedMessage(1112369); // You have been poisoned by a lethal arrow! defender.ApplyPoison(attacker, Poison.GetPoison(level)); defender.FixedParticles(0x374A, 10, 15, 5021, EffectLayer.Waist); diff --git a/Projects/UOContent/Misc/RegenRates.cs b/Projects/UOContent/Misc/RegenRates.cs index 0d675474d..02ffc1e46 100644 --- a/Projects/UOContent/Misc/RegenRates.cs +++ b/Projects/UOContent/Misc/RegenRates.cs @@ -79,7 +79,7 @@ namespace Server.Misc if (AnimalForm.UnderTransformation(from, typeof(Dog)) || AnimalForm.UnderTransformation(from, typeof(Cat))) { - points += from.Skills.Ninjitsu.Fixed / 30; + points += (int)(from.Skills.Ninjitsu.Value / 3); } return TimeSpan.FromSeconds(10.0 / (1 + points)); diff --git a/Projects/UOContent/Spells/Base/SpellHelper.cs b/Projects/UOContent/Spells/Base/SpellHelper.cs index e94edbdcc..998114717 100644 --- a/Projects/UOContent/Spells/Base/SpellHelper.cs +++ b/Projects/UOContent/Spells/Base/SpellHelper.cs @@ -359,11 +359,11 @@ namespace Server.Spells if (curse) { - percent = 8 + caster.Skills.EvalInt.Fixed / 100 - target.Skills.MagicResist.Fixed / 100; + percent = 8 + (caster.Skills.EvalInt.Value - target.Skills.MagicResist.Value) / 10; } else { - percent = 1 + caster.Skills.EvalInt.Fixed / 100; + percent = 1 + caster.Skills.EvalInt.Value / 10; } percent *= 0.01; diff --git a/Projects/UOContent/Spells/Bushido/Confidence.cs b/Projects/UOContent/Spells/Bushido/Confidence.cs index 46db09174..fb9757904 100644 --- a/Projects/UOContent/Spells/Bushido/Confidence.cs +++ b/Projects/UOContent/Spells/Bushido/Confidence.cs @@ -108,9 +108,6 @@ public class Confidence : SamuraiSpell { StopRegenerating(m); - // RunUO says this goes for 5 seconds, but UOGuide says 4 seconds during normal regeneration - var hits = (15 + m.Skills.Bushido.Fixed * m.Skills.Bushido.Fixed / 57600) / 4; - TimerExecutionToken timerToken = default; Timer.StartTimer(TimeSpan.FromSeconds(1.0), TimeSpan.FromSeconds(1.0), 4, () => @@ -121,6 +118,10 @@ public class Confidence : SamuraiSpell StopRegenerating(m); } + // RunUO says this goes for 5 seconds, but UOGuide says 4 seconds during normal regeneration + // Divide by 4 because this is per second. + var hits = (int)((15 + m.Skills.Bushido.Value * m.Skills.Bushido.Value / 576) / 4); + m.Hits += hits; }, out timerToken diff --git a/Projects/UOContent/Spells/Chivalry/PaladinSpell.cs b/Projects/UOContent/Spells/Chivalry/PaladinSpell.cs index 04a2204a6..bd341fc46 100644 --- a/Projects/UOContent/Spells/Chivalry/PaladinSpell.cs +++ b/Projects/UOContent/Spells/Chivalry/PaladinSpell.cs @@ -140,7 +140,7 @@ namespace Server.Spells.Chivalry return 0; } - var v = (int)Math.Sqrt(from.Karma + 20000 + from.Skills.Chivalry.Fixed * 10); + var v = (int)Math.Sqrt(from.Karma + 20000 + from.Skills.Chivalry.Value * 100); return v / div; } diff --git a/Projects/UOContent/Spells/Fifth/PoisonField.cs b/Projects/UOContent/Spells/Fifth/PoisonField.cs index a0bcd55a7..e5b2fbdf5 100644 --- a/Projects/UOContent/Spells/Fifth/PoisonField.cs +++ b/Projects/UOContent/Spells/Fifth/PoisonField.cs @@ -42,7 +42,7 @@ namespace Server.Spells.Fifth { Expansion.None => TimeSpan.FromSeconds(20), < Expansion.LBR => TimeSpan.FromSeconds(15 + Caster.Skills.Magery.Value * 0.4), - _ => TimeSpan.FromSeconds(3 + Caster.Skills.Magery.Fixed * 0.4) + _ => TimeSpan.FromSeconds(3 + Caster.Skills.Magery.Value * 0.4) }; for (var i = -2; i <= 2; ++i) @@ -142,24 +142,24 @@ namespace Server.Spells.Fifth return; } - Poison p; + int level; if (Core.AOS) { - p = ((m_Caster.Skills.Magery.Fixed + m_Caster.Skills.Poisoning.Fixed) / 2) switch + level = (m_Caster.Skills.Magery.Value + m_Caster.Skills.Poisoning.Value) switch { - >= 1000 => Poison.Deadly, - > 850 => Poison.Greater, - > 650 => Poison.Regular, - _ => Poison.Lesser + > 199.8 => 3, + > 170.2 => 2, + > 130.2 => 1, + _ => 0 }; } else { - p = Poison.Regular; + level = 1; } - if (m.ApplyPoison(m_Caster, p) == ApplyPoisonResult.Poisoned) + if (m.ApplyPoison(m_Caster, Poison.GetPoison(level)) is ApplyPoisonResult.Poisoned or ApplyPoisonResult.HigherPoisonActive) { if (SpellHelper.CanRevealCaster(m)) { diff --git a/Projects/UOContent/Spells/Fifth/SummonCreature.cs b/Projects/UOContent/Spells/Fifth/SummonCreature.cs index c4896a763..6d01eefda 100644 --- a/Projects/UOContent/Spells/Fifth/SummonCreature.cs +++ b/Projects/UOContent/Spells/Fifth/SummonCreature.cs @@ -75,7 +75,7 @@ namespace Server.Spells.Fifth var duration = Core.Expansion switch { Expansion.None => TimeSpan.FromSeconds(Caster.Skills.Magery.Value), - _ => TimeSpan.FromSeconds(2 * Caster.Skills.Magery.Fixed / 5.0) + _ => TimeSpan.FromSeconds((int)Caster.Skills.Magery.Value * 4) }; SpellHelper.Summon(creature, Caster, 0x215, duration, false, false); diff --git a/Projects/UOContent/Spells/First/Heal.cs b/Projects/UOContent/Spells/First/Heal.cs index 293f2df7d..b591a280e 100644 --- a/Projects/UOContent/Spells/First/Heal.cs +++ b/Projects/UOContent/Spells/First/Heal.cs @@ -45,16 +45,16 @@ namespace Server.Spells.First { SpellHelper.Turn(Caster, m); - int toHeal; + double toHeal; if (Core.AOS) { - toHeal = Caster.Skills.Magery.Fixed / 120; + toHeal = Caster.Skills.Magery.Value / 12; toHeal += Utility.RandomMinMax(1, 4); if (Core.SE && Caster != m) { - toHeal = (int)(toHeal * 1.5); + toHeal *= 1.5; } } else @@ -64,7 +64,7 @@ namespace Server.Spells.First } // m.Heal( toHeal, Caster ); - SpellHelper.Heal(toHeal, m, Caster); + SpellHelper.Heal((int)toHeal, m, Caster); m.FixedParticles(0x376A, 9, 32, 5005, EffectLayer.Waist); m.PlaySound(0x1F2); diff --git a/Projects/UOContent/Spells/Ninjitsu/DeathStrike.cs b/Projects/UOContent/Spells/Ninjitsu/DeathStrike.cs index c645722bd..de2dd5a14 100644 --- a/Projects/UOContent/Spells/Ninjitsu/DeathStrike.cs +++ b/Projects/UOContent/Spells/Ninjitsu/DeathStrike.cs @@ -53,7 +53,7 @@ namespace Server.Spells.Ninjitsu if (timer.Steps > 0) { - damageBonus = attacker.Skills.Ninjitsu.Fixed / 150; + damageBonus = (int)(attacker.Skills.Ninjitsu.Value / 15); } timer.Stop(); diff --git a/Projects/UOContent/Spells/Second/Protection.cs b/Projects/UOContent/Spells/Second/Protection.cs index 35fd04b97..3c6661118 100644 --- a/Projects/UOContent/Spells/Second/Protection.cs +++ b/Projects/UOContent/Spells/Second/Protection.cs @@ -133,11 +133,11 @@ namespace Server.Spells.Second { if (Caster.BeginAction()) { - int value = (Caster.Skills.EvalInt.Fixed + - Caster.Skills.Meditation.Fixed + - Caster.Skills.Inscribe.Fixed) / 4; + double value = (Caster.Skills.EvalInt.Value + + Caster.Skills.Meditation.Value + + Caster.Skills.Inscribe.Value) * 10 / 4; - Registry.Add(Caster, Math.Clamp(value, 0, 750)); // 75.0% protection from disruption + Registry.Add(Caster, Math.Clamp((int)value, 0, 750)); // 75.0% protection from disruption new InternalTimer(Caster).Start(); Caster.FixedParticles(0x375A, 9, 20, 5016, EffectLayer.Waist); diff --git a/Projects/UOContent/Spells/Seventh/EnergyField.cs b/Projects/UOContent/Spells/Seventh/EnergyField.cs index 5c5900a08..988d19fb1 100644 --- a/Projects/UOContent/Spells/Seventh/EnergyField.cs +++ b/Projects/UOContent/Spells/Seventh/EnergyField.cs @@ -39,7 +39,7 @@ namespace Server.Spells.Seventh Effects.PlaySound(loc, Caster.Map, 0x20B); TimeSpan duration = Core.AOS - ? TimeSpan.FromSeconds((15 + Caster.Skills.Magery.Fixed / 5) / 7.0) + ? TimeSpan.FromSeconds((15 + Caster.Skills.Magery.Value * 2) / 7.0) : TimeSpan.FromSeconds(Caster.Skills.Magery.Value * 0.28 + 2.0); var itemID = eastToWest ? 0x3946 : 0x3956; diff --git a/Projects/UOContent/Spells/Sixth/Invisibility.cs b/Projects/UOContent/Spells/Sixth/Invisibility.cs index f7d545538..c40b4eac1 100644 --- a/Projects/UOContent/Spells/Sixth/Invisibility.cs +++ b/Projects/UOContent/Spells/Sixth/Invisibility.cs @@ -51,7 +51,7 @@ namespace Server.Spells.Sixth StopTimer(m); - var duration = TimeSpan.FromSeconds(1.2 * Caster.Skills.Magery.Fixed / 10); + var duration = TimeSpan.FromSeconds(1.2 * Caster.Skills.Magery.Value); BuffInfo.RemoveBuff(m, BuffIcon.HidingAndOrStealth); BuffInfo.AddBuff(m, new BuffInfo(BuffIcon.Invisibility, 1075825, duration, m)); // Invisibility/Invisible diff --git a/Projects/UOContent/Spells/Third/Poison.cs b/Projects/UOContent/Spells/Third/Poison.cs index 168413f25..79fa35f7f 100644 --- a/Projects/UOContent/Spells/Third/Poison.cs +++ b/Projects/UOContent/Spells/Third/Poison.cs @@ -1,3 +1,4 @@ +using System; using Server.Mobiles; using Server.Targeting; @@ -37,70 +38,56 @@ namespace Server.Spells.Third } else { - int level; + var total = Caster.Skills.Magery.Value; - if (Core.AOS) + if (Caster is PlayerMobile pm) { - if (Caster.InRange(m, 2)) + if (pm.DuelContext?.Started != true || pm.DuelContext.Finished || + pm.DuelContext.Ruleset.GetOption("Skills", "Poisoning")) { - level = ((Caster.Skills.Magery.Fixed + Caster.Skills.Poisoning.Fixed) / 2) switch - { - >= 1000 => 3, - > 850 => 2, - > 650 => 1, - _ => 0 - }; - } - else - { - level = 0; + total += pm.Skills.Poisoning.Value; } } else { - // double total = Caster.Skills.Magery.Value + Caster.Skills.Poisoning.Value; + total += Caster.Skills.Poisoning.Value; + } - var total = Caster.Skills.Magery.Value; + var dist = Caster.GetDistanceToSqrt(m); + int level; - if (Caster is PlayerMobile pm) - { - if (pm.DuelContext?.Started != true || pm.DuelContext.Finished || - pm.DuelContext.Ruleset.GetOption("Skills", "Poisoning")) - { - total += pm.Skills.Poisoning.Value; - } - } - else - { - total += Caster.Skills.Poisoning.Value; - } - - var dist = Caster.GetDistanceToSqrt(m); - - if (dist >= 3.0) + if (Core.AOS && dist >= 3) + { + level = 0; + } + else + { + if (!Core.AOS && dist >= 3.0) { total -= (dist - 3.0) * 10.0; } - if (total >= 200.0 && Utility.Random(10) < 1) + if (Core.SA && dist >= 2.0) { - level = 3; + total -= (dist - 2) * 31; // 240 - } - else if (total > (Core.AOS ? 170.1 : 170.0)) + + level = total switch { - level = 2; - } - else if (total > (Core.AOS ? 130.1 : 130.0)) + > 200.0 when Core.SA && dist <= 2.0 => Utility.Random(10) == 0 ? 4 : 3, + > 199.8 => Core.AOS || Utility.Random(10) == 0 ? 3 : 2, + > 170.2 => 2, + > 130.2 => 1, + _ => 0 + }; + + if (Core.SA && dist > 2.0) { - level = 1; - } - else - { - level = 0; + level -= (int)dist / 3; } } - m.ApplyPoison(Caster, Poison.GetPoison(level)); + m.ApplyPoison(Caster, Poison.GetPoison(Math.Max(level, 0))); } m.FixedParticles(0x374A, 10, 15, 5021, EffectLayer.Waist);