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
This commit is contained in:
Kamron Batman 2023-11-04 12:32:54 -07:00 committed by GitHub
parent 54431f05b5
commit 1f04a13f67
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
16 changed files with 68 additions and 81 deletions

View file

@ -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)
{

View file

@ -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)
{

View file

@ -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);

View file

@ -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);

View file

@ -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));

View file

@ -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;

View file

@ -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

View file

@ -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;
}

View file

@ -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))
{

View file

@ -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);

View file

@ -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);

View file

@ -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();

View file

@ -133,11 +133,11 @@ namespace Server.Spells.Second
{
if (Caster.BeginAction<DefensiveSpell>())
{
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);

View file

@ -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;

View file

@ -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

View file

@ -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);