fix: Fixes curses and spell effects (#1112)
* * Fix statmod naming mismatch: everything in code searches for "[Magic] {type} Offset" but stat reductions are being added as "[Magic] {type} Curse"
* Clarifies and cleans up curses
* Fixes blood oath
* * NobleSacrifice remove all curses in one go
* Dont need a method
* Fix extra parentheses
Co-authored-by: Kamron Batman <3953314+kamronbatman@users.noreply.github.com>
This commit is contained in:
parent
ad0e1702a3
commit
bd4e6fc30e
10 changed files with 126 additions and 126 deletions
|
|
@ -1817,12 +1817,18 @@ namespace Server.Engines.ConPVP
|
|||
|
||||
public static void Debuff(Mobile mob)
|
||||
{
|
||||
mob.RemoveStatMod("[Magic] Str Offset");
|
||||
mob.RemoveStatMod("[Magic] Dex Offset");
|
||||
mob.RemoveStatMod("[Magic] Int Offset");
|
||||
mob.RemoveStatMod("[Magic] Str Buff");
|
||||
mob.RemoveStatMod("[Magic] Dex Buff");
|
||||
mob.RemoveStatMod("[Magic] Int Buff");
|
||||
mob.RemoveStatMod("[Magic] Str Curse");
|
||||
mob.RemoveStatMod("[Magic] Dex Curse");
|
||||
mob.RemoveStatMod("[Magic] Int Curse");
|
||||
mob.RemoveStatMod("Concussion");
|
||||
mob.RemoveStatMod("blood-rose");
|
||||
mob.RemoveStatMod("clarity-potion");
|
||||
mob.RemoveStatMod("RoseOfTrinsicPetal");
|
||||
mob.RemoveStatMod("Holy Bless");
|
||||
mob.RemoveStatMod("Holy Curse");
|
||||
|
||||
OrangePetals.RemoveContext(mob);
|
||||
|
||||
|
|
|
|||
|
|
@ -209,17 +209,8 @@ namespace Server.Factions
|
|||
return true;
|
||||
}
|
||||
|
||||
public int GetStatMod(Mobile mob, StatType type)
|
||||
{
|
||||
var mod = mob.GetStatMod($"[Magic] {type} Offset");
|
||||
|
||||
if (mod == null)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
return mod.Offset;
|
||||
}
|
||||
public static int GetStatMod(Mobile mob, StatType type) =>
|
||||
mob.GetStatMod($"[Magic] {type} Curse")?.Offset ?? 0;
|
||||
|
||||
public Spell RandomOffenseSpell()
|
||||
{
|
||||
|
|
|
|||
|
|
@ -1238,24 +1238,22 @@ namespace Server.Items
|
|||
0x100
|
||||
);
|
||||
|
||||
StatMod mod;
|
||||
|
||||
mod = target.GetStatMod("[Magic] Str Offset");
|
||||
var mod = target.GetStatMod("[Magic] Str Curse");
|
||||
if (mod?.Offset < 0)
|
||||
{
|
||||
target.RemoveStatMod("[Magic] Str Offset");
|
||||
target.RemoveStatMod("[Magic] Str Curse");
|
||||
}
|
||||
|
||||
mod = target.GetStatMod("[Magic] Dex Offset");
|
||||
mod = target.GetStatMod("[Magic] Dex Curse");
|
||||
if (mod?.Offset < 0)
|
||||
{
|
||||
target.RemoveStatMod("[Magic] Dex Offset");
|
||||
target.RemoveStatMod("[Magic] Dex Curse");
|
||||
}
|
||||
|
||||
mod = target.GetStatMod("[Magic] Int Offset");
|
||||
mod = target.GetStatMod("[Magic] Int Curse");
|
||||
if (mod?.Offset < 0)
|
||||
{
|
||||
target.RemoveStatMod("[Magic] Int Offset");
|
||||
target.RemoveStatMod("[Magic] Int Curse");
|
||||
}
|
||||
|
||||
target.Paralyzed = false;
|
||||
|
|
|
|||
|
|
@ -41,12 +41,15 @@ namespace Server.Items
|
|||
|
||||
public static bool IsWounded(Mobile m) => _table.ContainsKey(m);
|
||||
|
||||
private static void StopTimer(Mobile m)
|
||||
private static bool StopTimer(Mobile m)
|
||||
{
|
||||
if (_table.Remove(m, out var timerToken))
|
||||
{
|
||||
timerToken.Cancel();
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public static void BeginWound(Mobile m, TimeSpan duration)
|
||||
|
|
@ -58,11 +61,16 @@ namespace Server.Items
|
|||
m.YellowHealthbar = true;
|
||||
}
|
||||
|
||||
public static void EndWound(Mobile m)
|
||||
public static bool EndWound(Mobile m)
|
||||
{
|
||||
StopTimer(m);
|
||||
m.YellowHealthbar = false;
|
||||
m.SendLocalizedMessage(1060208); // You are no longer mortally wounded.
|
||||
if (StopTimer(m))
|
||||
{
|
||||
m.YellowHealthbar = false;
|
||||
m.SendLocalizedMessage(1060208); // You are no longer mortally wounded.
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -303,7 +303,7 @@ namespace Server.Spells
|
|||
public static bool AddStatBonus(Mobile caster, Mobile target, StatType type, int bonus, TimeSpan duration)
|
||||
{
|
||||
var offset = bonus;
|
||||
var name = $"[Magic] {type} Offset";
|
||||
var name = $"[Magic] {type} Buff";
|
||||
|
||||
var mod = target.GetStatMod(name);
|
||||
|
||||
|
|
|
|||
|
|
@ -1,7 +1,10 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using Server.Gumps;
|
||||
using Server.Items;
|
||||
using Server.Mobiles;
|
||||
using Server.Spells.Fourth;
|
||||
using Server.Spells.Mysticism;
|
||||
using Server.Spells.Necromancy;
|
||||
|
||||
namespace Server.Spells.Chivalry
|
||||
|
|
@ -83,7 +86,7 @@ namespace Server.Spells.Chivalry
|
|||
}
|
||||
else
|
||||
{
|
||||
var sendEffect = false;
|
||||
bool sendEffect = false;
|
||||
|
||||
if (m.Poisoned && m.CurePoison(Caster))
|
||||
{
|
||||
|
|
@ -108,26 +111,24 @@ namespace Server.Spells.Chivalry
|
|||
sendEffect = true;
|
||||
}
|
||||
|
||||
StatMod mod;
|
||||
|
||||
mod = m.GetStatMod("[Magic] Str Offset");
|
||||
var mod = m.GetStatMod("[Magic] Str Curse");
|
||||
if (mod?.Offset < 0)
|
||||
{
|
||||
m.RemoveStatMod("[Magic] Str Offset");
|
||||
m.RemoveStatMod("[Magic] Str Curse");
|
||||
sendEffect = true;
|
||||
}
|
||||
|
||||
mod = m.GetStatMod("[Magic] Dex Offset");
|
||||
mod = m.GetStatMod("[Magic] Dex Curse");
|
||||
if (mod?.Offset < 0)
|
||||
{
|
||||
m.RemoveStatMod("[Magic] Dex Offset");
|
||||
m.RemoveStatMod("[Magic] Dex Curse");
|
||||
sendEffect = true;
|
||||
}
|
||||
|
||||
mod = m.GetStatMod("[Magic] Int Offset");
|
||||
mod = m.GetStatMod("[Magic] Int Curse");
|
||||
if (mod?.Offset < 0)
|
||||
{
|
||||
m.RemoveStatMod("[Magic] Int Offset");
|
||||
m.RemoveStatMod("[Magic] Int Curse");
|
||||
sendEffect = true;
|
||||
}
|
||||
|
||||
|
|
@ -137,22 +138,24 @@ namespace Server.Spells.Chivalry
|
|||
sendEffect = true;
|
||||
}
|
||||
|
||||
if (EvilOmenSpell.TryEndEffect(m))
|
||||
{
|
||||
sendEffect = true;
|
||||
}
|
||||
sendEffect = EvilOmenSpell.TryEndEffect(m) || sendEffect;
|
||||
sendEffect = StrangleSpell.RemoveCurse(m) || sendEffect;
|
||||
sendEffect = CorpseSkinSpell.RemoveCurse(m) || sendEffect;
|
||||
sendEffect = CurseSpell.RemoveEffect(m) || sendEffect;
|
||||
sendEffect = MortalStrike.EndWound(m) || sendEffect;
|
||||
sendEffect = MindRotSpell.ClearMindRotScalar(m) || sendEffect;
|
||||
sendEffect = BloodOathSpell.RemoveCurse(m) || sendEffect;
|
||||
sendEffect = SpellPlagueSpell.RemoveEffect(m) || sendEffect;
|
||||
|
||||
if (StrangleSpell.RemoveCurse(m))
|
||||
{
|
||||
sendEffect = true;
|
||||
}
|
||||
|
||||
if (CorpseSkinSpell.RemoveCurse(m))
|
||||
{
|
||||
sendEffect = true;
|
||||
}
|
||||
|
||||
// TODO: Should this remove blood oath? Pain spike?
|
||||
// TODO: Move these into their respective end effect methods
|
||||
BuffInfo.RemoveBuff(m, BuffIcon.Clumsy);
|
||||
BuffInfo.RemoveBuff(m, BuffIcon.FeebleMind);
|
||||
BuffInfo.RemoveBuff(m, BuffIcon.Weaken);
|
||||
BuffInfo.RemoveBuff(m, BuffIcon.Curse);
|
||||
BuffInfo.RemoveBuff(m, BuffIcon.MassCurse);
|
||||
BuffInfo.RemoveBuff(m, BuffIcon.MortalStrike);
|
||||
BuffInfo.RemoveBuff(m, BuffIcon.Strangle);
|
||||
BuffInfo.RemoveBuff(m, BuffIcon.EvilOmen);
|
||||
|
||||
if (sendEffect)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -2,6 +2,7 @@ using System;
|
|||
using Server.Engines.ConPVP;
|
||||
using Server.Items;
|
||||
using Server.Spells.Fourth;
|
||||
using Server.Spells.Mysticism;
|
||||
using Server.Spells.Necromancy;
|
||||
using Server.Targeting;
|
||||
|
||||
|
|
@ -44,24 +45,13 @@ namespace Server.Spells.Chivalry
|
|||
* Chance of removing curse is affected by Caster's Karma.
|
||||
*/
|
||||
|
||||
int chance;
|
||||
|
||||
if (Caster.Karma < -5000)
|
||||
int chance = Caster.Karma switch
|
||||
{
|
||||
chance = 0;
|
||||
}
|
||||
else if (Caster.Karma < 0)
|
||||
{
|
||||
chance = (int)Math.Sqrt(20000 + Caster.Karma) - 122;
|
||||
}
|
||||
else if (Caster.Karma < 5625)
|
||||
{
|
||||
chance = (int)Math.Sqrt(Caster.Karma) + 25;
|
||||
}
|
||||
else
|
||||
{
|
||||
chance = 100;
|
||||
}
|
||||
< -5000 => 0,
|
||||
< 0 => (int)Math.Sqrt(20000 + Caster.Karma) - 122,
|
||||
< 5625 => (int)Math.Sqrt(Caster.Karma) + 25,
|
||||
_ => 100
|
||||
};
|
||||
|
||||
if (chance > Utility.Random(100))
|
||||
{
|
||||
|
|
@ -88,22 +78,22 @@ namespace Server.Spells.Chivalry
|
|||
0x100
|
||||
);
|
||||
|
||||
var mod = m.GetStatMod("[Magic] Str Offset");
|
||||
var mod = m.GetStatMod("[Magic] Str Curse");
|
||||
if (mod?.Offset < 0)
|
||||
{
|
||||
m.RemoveStatMod("[Magic] Str Offset");
|
||||
m.RemoveStatMod("[Magic] Str Curse");
|
||||
}
|
||||
|
||||
mod = m.GetStatMod("[Magic] Dex Offset");
|
||||
mod = m.GetStatMod("[Magic] Dex Curse");
|
||||
if (mod?.Offset < 0)
|
||||
{
|
||||
m.RemoveStatMod("[Magic] Dex Offset");
|
||||
m.RemoveStatMod("[Magic] Dex Curse");
|
||||
}
|
||||
|
||||
mod = m.GetStatMod("[Magic] Int Offset");
|
||||
mod = m.GetStatMod("[Magic] Int Curse");
|
||||
if (mod?.Offset < 0)
|
||||
{
|
||||
m.RemoveStatMod("[Magic] Int Offset");
|
||||
m.RemoveStatMod("[Magic] Int Curse");
|
||||
}
|
||||
|
||||
m.Paralyzed = false;
|
||||
|
|
@ -113,22 +103,19 @@ namespace Server.Spells.Chivalry
|
|||
CorpseSkinSpell.RemoveCurse(m);
|
||||
CurseSpell.RemoveEffect(m);
|
||||
MortalStrike.EndWound(m);
|
||||
if (Core.ML)
|
||||
{
|
||||
BloodOathSpell.RemoveCurse(m);
|
||||
}
|
||||
|
||||
MindRotSpell.ClearMindRotScalar(m);
|
||||
BloodOathSpell.RemoveCurse(m);
|
||||
SpellPlagueSpell.RemoveEffect(m);
|
||||
|
||||
// TODO: Move these into their respective end effect methods
|
||||
BuffInfo.RemoveBuff(m, BuffIcon.Clumsy);
|
||||
BuffInfo.RemoveBuff(m, BuffIcon.FeebleMind);
|
||||
BuffInfo.RemoveBuff(m, BuffIcon.Weaken);
|
||||
BuffInfo.RemoveBuff(m, BuffIcon.Curse);
|
||||
BuffInfo.RemoveBuff(m, BuffIcon.MassCurse);
|
||||
BuffInfo.RemoveBuff(m, BuffIcon.MortalStrike);
|
||||
BuffInfo.RemoveBuff(m, BuffIcon.Mindrot);
|
||||
|
||||
// TODO: Should this remove blood oath? Pain spike?
|
||||
BuffInfo.RemoveBuff(m, BuffIcon.Strangle);
|
||||
BuffInfo.RemoveBuff(m, BuffIcon.EvilOmen);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
|
|||
|
|
@ -80,12 +80,16 @@ namespace Server.Spells.Mysticism
|
|||
|
||||
public static bool UnderEffect(Mobile m) => _table.ContainsKey(m);
|
||||
|
||||
public static void RemoveEffect(Mobile m)
|
||||
public static bool RemoveEffect(Mobile m)
|
||||
{
|
||||
if (_table.TryGetValue(m, out var context))
|
||||
if (_table.Remove(m, out var context))
|
||||
{
|
||||
context.EndPlague(false);
|
||||
context.Stop();
|
||||
BuffInfo.RemoveBuff(m, BuffIcon.SpellPlague);
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public static void CheckPlague(Mobile m)
|
||||
|
|
@ -179,9 +183,9 @@ namespace Server.Spells.Mysticism
|
|||
}
|
||||
}
|
||||
|
||||
public void EndPlague(bool restart = true)
|
||||
public void EndPlague()
|
||||
{
|
||||
if (restart && m_Next != null)
|
||||
if (m_Next != null)
|
||||
{
|
||||
_table[m_Target] = m_Next;
|
||||
m_Next.StartPlague();
|
||||
|
|
@ -191,6 +195,8 @@ namespace Server.Spells.Mysticism
|
|||
_table.Remove(m_Target);
|
||||
BuffInfo.RemoveBuff(m_Target, BuffIcon.SpellPlague);
|
||||
}
|
||||
|
||||
Stop();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -65,8 +65,7 @@ namespace Server.Spells.Necromancy
|
|||
* ((ss-rm)/8)+8
|
||||
*/
|
||||
|
||||
_table.TryGetValue(m, out var timer);
|
||||
timer?.DoExpire();
|
||||
RemoveCurse(m);
|
||||
|
||||
m_OathTable[Caster] = Caster;
|
||||
m_OathTable[m] = Caster;
|
||||
|
|
@ -84,7 +83,7 @@ namespace Server.Spells.Necromancy
|
|||
var duration = TimeSpan.FromSeconds((GetDamageSkill(Caster) - GetResistSkill(m)) / 8 + 8);
|
||||
m.CheckSkill(SkillName.MagicResist, 0.0, 120.0); // Skill check for gain
|
||||
|
||||
timer = new ExpireTimer(Caster, m, duration);
|
||||
var timer = new ExpireTimer(Caster, m, duration);
|
||||
timer.Start();
|
||||
|
||||
BuffInfo.AddBuff(Caster, new BuffInfo(BuffIcon.BloodOathCaster, 1075659, duration, Caster, m.Name));
|
||||
|
|
@ -102,10 +101,30 @@ namespace Server.Spells.Necromancy
|
|||
Caster.Target = new SpellTargetMobile(this, TargetFlags.Harmful, Core.ML ? 10 : 12);
|
||||
}
|
||||
|
||||
public static void RemoveCurse(Mobile m)
|
||||
public static bool RemoveCurse(Mobile target)
|
||||
{
|
||||
_table.TryGetValue(m, out var t);
|
||||
t?.DoExpire();
|
||||
if (_table.Remove(target, out var timer))
|
||||
{
|
||||
var caster = timer.Caster;
|
||||
if (m_OathTable.Remove(caster))
|
||||
{
|
||||
caster.SendLocalizedMessage(1061620); // Your Blood Oath has been broken.
|
||||
}
|
||||
|
||||
if (m_OathTable.Remove(target))
|
||||
{
|
||||
target.SendLocalizedMessage(1061620); // Your Blood Oath has been broken.
|
||||
}
|
||||
|
||||
timer.Stop();
|
||||
|
||||
BuffInfo.RemoveBuff(caster, BuffIcon.BloodOathCaster);
|
||||
BuffInfo.RemoveBuff(target, BuffIcon.BloodOathCurse);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public static Mobile GetBloodOath(Mobile m) =>
|
||||
|
|
@ -113,48 +132,29 @@ namespace Server.Spells.Necromancy
|
|||
|
||||
private class ExpireTimer : Timer
|
||||
{
|
||||
private readonly Mobile m_Caster;
|
||||
private readonly DateTime m_End;
|
||||
private readonly Mobile m_Target;
|
||||
private Mobile _target;
|
||||
private DateTime _end;
|
||||
|
||||
public Mobile Caster { get; }
|
||||
|
||||
public ExpireTimer(Mobile caster, Mobile target, TimeSpan delay) : base(
|
||||
TimeSpan.FromSeconds(1.0),
|
||||
TimeSpan.FromSeconds(1.0)
|
||||
)
|
||||
{
|
||||
m_Caster = caster;
|
||||
m_Target = target;
|
||||
m_End = Core.Now + delay;
|
||||
Caster = caster;
|
||||
_target = target;
|
||||
_end = Core.Now + delay;
|
||||
}
|
||||
|
||||
protected override void OnTick()
|
||||
{
|
||||
if (m_Caster.Deleted || m_Target.Deleted || !m_Caster.Alive || !m_Target.Alive ||
|
||||
Core.Now >= m_End)
|
||||
if (Caster.Deleted || _target.Deleted || !Caster.Alive || !_target.Alive ||
|
||||
Core.Now >= _end)
|
||||
{
|
||||
DoExpire();
|
||||
RemoveCurse(_target);
|
||||
}
|
||||
}
|
||||
|
||||
public void DoExpire()
|
||||
{
|
||||
if (m_OathTable.Remove(m_Caster))
|
||||
{
|
||||
m_Caster.SendLocalizedMessage(1061620); // Your Blood Oath has been broken.
|
||||
}
|
||||
|
||||
if (m_OathTable.Remove(m_Target))
|
||||
{
|
||||
m_Target.SendLocalizedMessage(1061620); // Your Blood Oath has been broken.
|
||||
}
|
||||
|
||||
Stop();
|
||||
|
||||
BuffInfo.RemoveBuff(m_Caster, BuffIcon.BloodOathCaster);
|
||||
BuffInfo.RemoveBuff(m_Target, BuffIcon.BloodOathCurse);
|
||||
|
||||
_table.Remove(m_Caster);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -71,15 +71,17 @@ namespace Server.Spells.Necromancy
|
|||
Caster.Target = new SpellTargetMobile(this, TargetFlags.Harmful, Core.ML ? 10 : 12);
|
||||
}
|
||||
|
||||
public static void ClearMindRotScalar(Mobile m)
|
||||
public static bool ClearMindRotScalar(Mobile m)
|
||||
{
|
||||
if (_table.Remove(m, out var tmpB))
|
||||
{
|
||||
tmpB.m_MRExpireTimer.Stop();
|
||||
m.SendLocalizedMessage(1060872); // Your mind feels normal again.
|
||||
BuffInfo.RemoveBuff(m, BuffIcon.Mindrot);
|
||||
return true;
|
||||
}
|
||||
|
||||
BuffInfo.RemoveBuff(m, BuffIcon.Mindrot);
|
||||
return false;
|
||||
}
|
||||
|
||||
public static bool HasMindRotScalar(Mobile m) => _table.ContainsKey(m);
|
||||
|
|
@ -127,7 +129,6 @@ namespace Server.Spells.Necromancy
|
|||
if (m_Target.Deleted || !m_Target.Alive || Core.Now >= m_End)
|
||||
{
|
||||
MindRotSpell.ClearMindRotScalar(m_Target);
|
||||
Stop();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue