fix: Adds name support for all mods (#1128)
This commit is contained in:
parent
b1cf95f810
commit
ffdc08259f
33 changed files with 404 additions and 343 deletions
|
|
@ -1,4 +1,14 @@
|
|||
{
|
||||
"version": 0,
|
||||
"type": "Server.MobileMod"
|
||||
"type": "Server.MobileMod",
|
||||
"properties": [
|
||||
{
|
||||
"name": "Name",
|
||||
"type": "string",
|
||||
"rule": "PrimitiveTypeMigrationRule",
|
||||
"ruleArguments": [
|
||||
""
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
|
|
@ -20,14 +20,6 @@
|
|||
"type": "Server.StatType",
|
||||
"rule": "EnumMigrationRule"
|
||||
},
|
||||
{
|
||||
"name": "Name",
|
||||
"type": "string",
|
||||
"rule": "PrimitiveTypeMigrationRule",
|
||||
"ruleArguments": [
|
||||
""
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "Offset",
|
||||
"type": "int",
|
||||
|
|
|
|||
|
|
@ -331,6 +331,9 @@ public class Mobile : IHued, IComparable<Mobile>, ISpawnable, IObjectPropertyLis
|
|||
private IWeapon m_Weapon;
|
||||
|
||||
private bool m_YellowHealthbar;
|
||||
private List<StatMod> _statMods;
|
||||
private List<ResistanceMod> _resistanceMods;
|
||||
private List<SkillMod> _skillMods;
|
||||
|
||||
public Mobile()
|
||||
{
|
||||
|
|
@ -402,8 +405,6 @@ public class Mobile : IHued, IComparable<Mobile>, ISpawnable, IObjectPropertyLis
|
|||
[CommandProperty(AccessLevel.Counselor)]
|
||||
public virtual int EnergyResistance => GetResistance(ResistanceType.Energy);
|
||||
|
||||
public List<ResistanceMod> ResistanceMods { get; set; }
|
||||
|
||||
public static int MaxPlayerResistance { get; set; } = 70;
|
||||
|
||||
public virtual bool NewGuildDisplay => false;
|
||||
|
|
@ -415,7 +416,9 @@ public class Mobile : IHued, IComparable<Mobile>, ISpawnable, IObjectPropertyLis
|
|||
|
||||
public object Party { get; set; }
|
||||
|
||||
public HashSet<SkillMod> SkillMods { get; private set; }
|
||||
public List<SkillMod> SkillMods => _skillMods;
|
||||
public List<StatMod> StatMods => _statMods;
|
||||
public List<ResistanceMod> ResistanceMods => _resistanceMods;
|
||||
|
||||
[CommandProperty(AccessLevel.GameMaster)]
|
||||
public int VirtualArmorMod
|
||||
|
|
@ -1783,11 +1786,6 @@ public class Mobile : IHued, IComparable<Mobile>, ISpawnable, IObjectPropertyLis
|
|||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets a list of all <see cref="StatMod">StatMod's</see> currently active for the Mobile.
|
||||
/// </summary>
|
||||
public HashSet<StatMod> StatMods { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the base, unmodified, strength of the Mobile. Ranges from 1 to 65000, inclusive.
|
||||
/// <seealso cref="Str" />
|
||||
|
|
@ -1839,7 +1837,7 @@ public class Mobile : IHued, IComparable<Mobile>, ISpawnable, IObjectPropertyLis
|
|||
get => Math.Clamp(m_Str + GetStatOffset(StatType.Str), 1, 65000);
|
||||
set
|
||||
{
|
||||
if (StatMods.Count == 0)
|
||||
if (_statMods.Count == 0)
|
||||
{
|
||||
RawStr = value;
|
||||
}
|
||||
|
|
@ -1897,7 +1895,7 @@ public class Mobile : IHued, IComparable<Mobile>, ISpawnable, IObjectPropertyLis
|
|||
get => Math.Clamp(m_Dex + GetStatOffset(StatType.Dex), 0, 65000);
|
||||
set
|
||||
{
|
||||
if (StatMods.Count == 0)
|
||||
if (_statMods.Count == 0)
|
||||
{
|
||||
RawDex = value;
|
||||
}
|
||||
|
|
@ -1955,7 +1953,7 @@ public class Mobile : IHued, IComparable<Mobile>, ISpawnable, IObjectPropertyLis
|
|||
get => Math.Clamp(m_Int + GetStatOffset(StatType.Int), 0, 65000);
|
||||
set
|
||||
{
|
||||
if (StatMods.Count == 0)
|
||||
if (_statMods.Count == 0)
|
||||
{
|
||||
RawInt = value;
|
||||
}
|
||||
|
|
@ -3090,26 +3088,76 @@ public class Mobile : IHued, IComparable<Mobile>, ISpawnable, IObjectPropertyLis
|
|||
return res;
|
||||
}
|
||||
|
||||
public virtual void AddResistanceMod(ResistanceMod toAdd)
|
||||
public virtual void AddResistanceMod(ResistanceMod mod)
|
||||
{
|
||||
ResistanceMods ??= new List<ResistanceMod>();
|
||||
if (mod == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
_resistanceMods ??= new List<ResistanceMod>();
|
||||
_resistanceMods.Add(mod);
|
||||
|
||||
ResistanceMods.Add(toAdd);
|
||||
UpdateResistances();
|
||||
}
|
||||
|
||||
public virtual void RemoveResistanceMod(ResistanceMod toRemove)
|
||||
public virtual ResistanceMod GetResistanceMod(string name)
|
||||
{
|
||||
if (ResistanceMods != null)
|
||||
if (_resistanceMods == null || name == null)
|
||||
{
|
||||
ResistanceMods.Remove(toRemove);
|
||||
return null;
|
||||
}
|
||||
|
||||
if (ResistanceMods.Count == 0)
|
||||
for (var i = 0; i < _resistanceMods.Count; i++)
|
||||
{
|
||||
var mod = _resistanceMods[i];
|
||||
if (mod.Name == name)
|
||||
{
|
||||
ResistanceMods = null;
|
||||
return mod;
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public virtual void RemoveResistanceMod(string name)
|
||||
{
|
||||
if (_resistanceMods == null || name == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
for (var i = _resistanceMods.Count - 1; i >= 0; i--)
|
||||
{
|
||||
var mod = _resistanceMods[i];
|
||||
if (mod.Name == name)
|
||||
{
|
||||
_resistanceMods.RemoveAt(i);
|
||||
}
|
||||
}
|
||||
|
||||
if (_resistanceMods.Count == 0)
|
||||
{
|
||||
_resistanceMods = null;
|
||||
}
|
||||
|
||||
UpdateResistances();
|
||||
}
|
||||
|
||||
public virtual void RemoveResistanceMod(ResistanceMod mod)
|
||||
{
|
||||
if (_resistanceMods == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
_resistanceMods.Remove(mod);
|
||||
|
||||
if (_resistanceMods.Count == 0)
|
||||
{
|
||||
_resistanceMods = null;
|
||||
}
|
||||
|
||||
UpdateResistances();
|
||||
}
|
||||
|
||||
|
|
@ -3128,9 +3176,9 @@ public class Mobile : IHued, IComparable<Mobile>, ISpawnable, IObjectPropertyLis
|
|||
Resistances[3] += BasePoisonResistance;
|
||||
Resistances[4] += BaseEnergyResistance;
|
||||
|
||||
for (var i = 0; i < ResistanceMods?.Count; ++i)
|
||||
for (var i = 0; i < _resistanceMods.Count; i++)
|
||||
{
|
||||
var mod = ResistanceMods[i];
|
||||
var mod = _resistanceMods[i];
|
||||
var v = (int)mod.Type;
|
||||
|
||||
if (v >= 0 && v < Resistances.Length)
|
||||
|
|
@ -3362,32 +3410,25 @@ public class Mobile : IHued, IComparable<Mobile>, ISpawnable, IObjectPropertyLis
|
|||
{
|
||||
}
|
||||
|
||||
public virtual void UpdateSkillMods()
|
||||
{
|
||||
ValidateSkillMods();
|
||||
|
||||
foreach (var mod in SkillMods)
|
||||
{
|
||||
var sk = Skills[mod.Skill];
|
||||
sk?.Update();
|
||||
}
|
||||
}
|
||||
|
||||
public virtual void ValidateSkillMods()
|
||||
{
|
||||
using var queue = PooledRefQueue<SkillMod>.Create(8);
|
||||
foreach (var mod in SkillMods)
|
||||
if (_skillMods == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
for (var i = _skillMods.Count - 1; i >= 0; i--)
|
||||
{
|
||||
var mod = _skillMods[i];
|
||||
|
||||
if (!mod.CheckCondition())
|
||||
{
|
||||
queue.Enqueue(mod);
|
||||
_skillMods.RemoveAt(i);
|
||||
mod.Owner = null;
|
||||
Skills[mod.Skill]?.Update();
|
||||
}
|
||||
}
|
||||
|
||||
while (queue.Count > 0)
|
||||
{
|
||||
InternalRemoveSkillMod(queue.Dequeue());
|
||||
}
|
||||
}
|
||||
|
||||
public virtual void AddSkillMod(SkillMod mod)
|
||||
|
|
@ -3398,35 +3439,77 @@ public class Mobile : IHued, IComparable<Mobile>, ISpawnable, IObjectPropertyLis
|
|||
}
|
||||
|
||||
ValidateSkillMods();
|
||||
_skillMods ??= new List<SkillMod>();
|
||||
_skillMods.Add(mod);
|
||||
mod.Owner = this;
|
||||
Skills[mod.Skill]?.Update();
|
||||
}
|
||||
|
||||
if (SkillMods.Add(mod))
|
||||
public virtual SkillMod GetSkillMod(string name)
|
||||
{
|
||||
if (_skillMods == null || name == null)
|
||||
{
|
||||
mod.Owner = this;
|
||||
return null;
|
||||
}
|
||||
|
||||
var sk = Skills[mod.Skill];
|
||||
sk?.Update();
|
||||
ValidateSkillMods();
|
||||
|
||||
for (var i = 0; i < _skillMods.Count; i++)
|
||||
{
|
||||
var mod = _skillMods[i];
|
||||
if (mod.Name == name)
|
||||
{
|
||||
return mod;
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public virtual void RemoveSkillMod(string name)
|
||||
{
|
||||
if (_skillMods == null || name == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
for (var i = _skillMods.Count - 1; i >= 0; i--)
|
||||
{
|
||||
var mod = _skillMods[i];
|
||||
if (mod.Name == name)
|
||||
{
|
||||
mod.Owner = null;
|
||||
Skills[mod.Skill]?.Update();
|
||||
_skillMods.RemoveAt(i);
|
||||
}
|
||||
}
|
||||
|
||||
ValidateSkillMods();
|
||||
|
||||
if (_skillMods.Count == 0)
|
||||
{
|
||||
_skillMods = null;
|
||||
}
|
||||
}
|
||||
|
||||
public virtual void RemoveSkillMod(SkillMod mod)
|
||||
{
|
||||
if (mod == null)
|
||||
if (_skillMods == null || mod == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
InternalRemoveSkillMod(mod);
|
||||
ValidateSkillMods();
|
||||
}
|
||||
|
||||
private void InternalRemoveSkillMod(SkillMod mod)
|
||||
{
|
||||
if (SkillMods.Remove(mod))
|
||||
if (_skillMods.Remove(mod))
|
||||
{
|
||||
mod.Owner = null;
|
||||
Skills[mod.Skill]?.Update();
|
||||
}
|
||||
|
||||
var sk = Skills[mod.Skill];
|
||||
sk?.Update();
|
||||
ValidateSkillMods();
|
||||
|
||||
if (_skillMods.Count == 0)
|
||||
{
|
||||
_skillMods = null;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -6259,8 +6342,8 @@ public class Mobile : IHued, IComparable<Mobile>, ISpawnable, IObjectPropertyLis
|
|||
m_DexLock = (StatLockType)reader.ReadByte();
|
||||
m_IntLock = (StatLockType)reader.ReadByte();
|
||||
|
||||
StatMods = new HashSet<StatMod>();
|
||||
SkillMods = new HashSet<SkillMod>();
|
||||
_statMods = new List<StatMod>();
|
||||
_skillMods = new List<SkillMod>();
|
||||
|
||||
if (version < 32)
|
||||
{
|
||||
|
|
@ -7608,8 +7691,8 @@ public class Mobile : IHued, IComparable<Mobile>, ISpawnable, IObjectPropertyLis
|
|||
m_FollowersMax = 5;
|
||||
Skills = new Skills(this);
|
||||
Items = new List<Item>();
|
||||
StatMods = new HashSet<StatMod>();
|
||||
SkillMods = new HashSet<SkillMod>();
|
||||
_statMods = new List<StatMod>();
|
||||
_skillMods = new List<SkillMod>();
|
||||
Map = Map.Internal;
|
||||
AutoPageNotify = true;
|
||||
Aggressors = new List<AggressorInfo>();
|
||||
|
|
@ -8293,43 +8376,58 @@ public class Mobile : IHued, IComparable<Mobile>, ISpawnable, IObjectPropertyLis
|
|||
return false;
|
||||
}
|
||||
|
||||
public bool RemoveStatMod(string name)
|
||||
public virtual void RemoveStatMod(string name)
|
||||
{
|
||||
StatMods ??= new HashSet<StatMod>();
|
||||
|
||||
StatMod mod = GetStatMod(name);
|
||||
|
||||
if (mod != null)
|
||||
if (_statMods == null || name == null)
|
||||
{
|
||||
StatMods.Remove(mod);
|
||||
CheckStatTimers();
|
||||
Delta(MobileDelta.Stat | GetStatDelta(mod.Type));
|
||||
return true;
|
||||
return;
|
||||
}
|
||||
|
||||
return false;
|
||||
for (var i = _statMods.Count - 1; i >= 0; i--)
|
||||
{
|
||||
var mod = _statMods[i];
|
||||
if (mod.Name == name)
|
||||
{
|
||||
_statMods.RemoveAt(i);
|
||||
CheckStatTimers();
|
||||
Delta(MobileDelta.Stat | GetStatDelta(mod.Type));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (_statMods.Count == 0)
|
||||
{
|
||||
_statMods = null;
|
||||
}
|
||||
}
|
||||
|
||||
public StatMod GetStatMod(string name)
|
||||
public virtual StatMod GetStatMod(string name)
|
||||
{
|
||||
StatMods ??= new HashSet<StatMod>();
|
||||
|
||||
foreach (var check in StatMods)
|
||||
if (_statMods == null || name == null)
|
||||
{
|
||||
if (check.Name == name)
|
||||
return null;
|
||||
}
|
||||
|
||||
for (var i = 0; i < _statMods.Count; i++)
|
||||
{
|
||||
var mod = _statMods[i];
|
||||
if (mod.Name == name)
|
||||
{
|
||||
return check;
|
||||
return mod;
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public void AddStatMod(StatMod mod)
|
||||
public virtual void AddStatMod(StatMod mod)
|
||||
{
|
||||
RemoveStatMod(mod.Name);
|
||||
if (mod == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
StatMods.Add(mod);
|
||||
_statMods.Add(mod);
|
||||
Delta(MobileDelta.Stat | GetStatDelta(mod.Type));
|
||||
CheckStatTimers();
|
||||
}
|
||||
|
|
@ -8361,32 +8459,35 @@ public class Mobile : IHued, IComparable<Mobile>, ISpawnable, IObjectPropertyLis
|
|||
/// </summary>
|
||||
public int GetStatOffset(StatType type)
|
||||
{
|
||||
_statMods ??= new List<StatMod>();
|
||||
|
||||
if (_statMods.Count <= 0)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
var offset = 0;
|
||||
|
||||
StatMods ??= new HashSet<StatMod>();
|
||||
|
||||
if (StatMods.Count > 0)
|
||||
using var queue = PooledRefQueue<StatMod>.Create(8);
|
||||
for (var i = 0; i < _statMods.Count; i++)
|
||||
{
|
||||
using var queue = PooledRefQueue<StatMod>.Create(8);
|
||||
foreach (var mod in StatMods)
|
||||
var mod = _statMods[i];
|
||||
if (mod.HasElapsed())
|
||||
{
|
||||
if (mod.HasElapsed())
|
||||
{
|
||||
queue.Enqueue(mod);
|
||||
}
|
||||
else if ((mod.Type & type) != 0)
|
||||
{
|
||||
offset += mod.Offset;
|
||||
}
|
||||
queue.Enqueue(mod);
|
||||
}
|
||||
else if ((mod.Type & type) != 0)
|
||||
{
|
||||
offset += mod.Offset;
|
||||
}
|
||||
}
|
||||
|
||||
while (queue.Count > 0)
|
||||
{
|
||||
var mod = queue.Dequeue();
|
||||
StatMods.Remove(mod);
|
||||
Delta(MobileDelta.Stat | GetStatDelta(mod.Type));
|
||||
CheckStatTimers();
|
||||
}
|
||||
while (queue.Count > 0)
|
||||
{
|
||||
var mod = queue.Dequeue();
|
||||
_statMods.Remove(mod);
|
||||
Delta(MobileDelta.Stat | GetStatDelta(mod.Type));
|
||||
CheckStatTimers();
|
||||
}
|
||||
|
||||
return offset;
|
||||
|
|
|
|||
|
|
@ -24,7 +24,7 @@ public partial class DefaultSkillMod : SkillMod
|
|||
{
|
||||
}
|
||||
|
||||
public DefaultSkillMod(SkillName skill, bool relative, double value) : base(skill, relative, value)
|
||||
public DefaultSkillMod(SkillName skill, string name, bool relative, double value) : base(skill, name, relative, value)
|
||||
{
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -27,8 +27,8 @@ public partial class EquippedSkillMod : SkillMod
|
|||
{
|
||||
}
|
||||
|
||||
public EquippedSkillMod(SkillName skill, bool relative, double value, Item item, Mobile mobile)
|
||||
: base(skill, relative, value, mobile) => _item = item;
|
||||
public EquippedSkillMod(SkillName skill, string name, bool relative, double value, Item item, Mobile owner)
|
||||
: base(skill, name, relative, value, owner) => _item = item;
|
||||
|
||||
public override bool CheckCondition() => !_item.Deleted && Owner?.Deleted == false && _item.Parent == Owner;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -23,5 +23,14 @@ public partial class MobileMod
|
|||
[DirtyTrackingEntity]
|
||||
public Mobile Owner { get; set; }
|
||||
|
||||
[SerializableField(0)]
|
||||
private string _name;
|
||||
|
||||
public MobileMod(Mobile owner) => Owner = owner;
|
||||
|
||||
public MobileMod(Mobile owner, string name)
|
||||
{
|
||||
Owner = owner;
|
||||
Name = name;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -24,7 +24,7 @@ public partial class ResistanceMod : MobileMod
|
|||
{
|
||||
}
|
||||
|
||||
public ResistanceMod(ResistanceType type, int offset, Mobile owner = null) : base(owner)
|
||||
public ResistanceMod(ResistanceType type, string name, int offset, Mobile owner = null) : base(owner, name)
|
||||
{
|
||||
_type = type;
|
||||
_offset = offset;
|
||||
|
|
|
|||
|
|
@ -25,7 +25,7 @@ public abstract partial class SkillMod : MobileMod
|
|||
{
|
||||
}
|
||||
|
||||
public SkillMod(SkillName skill, bool relative, double value, Mobile owner = null) : base(owner)
|
||||
public SkillMod(SkillName skill, string name, bool relative, double value, Mobile owner = null) : base(owner, name)
|
||||
{
|
||||
_skill = skill;
|
||||
_relative = relative;
|
||||
|
|
|
|||
|
|
@ -31,19 +31,15 @@ public partial class StatMod : MobileMod
|
|||
private StatType _type;
|
||||
|
||||
[SerializableField(3, setter: "private")]
|
||||
private string _name;
|
||||
|
||||
[SerializableField(4, setter: "private")]
|
||||
private int _offset;
|
||||
|
||||
public StatMod(Mobile owner) : base(owner)
|
||||
{
|
||||
}
|
||||
|
||||
public StatMod(StatType type, string name, int offset, TimeSpan duration, Mobile owner = null) : base(owner)
|
||||
public StatMod(StatType type, string name, int offset, TimeSpan duration, Mobile owner = null) : base(owner, name)
|
||||
{
|
||||
_type = type;
|
||||
_name = name;
|
||||
_offset = offset;
|
||||
_duration = duration;
|
||||
_added = Core.Now;
|
||||
|
|
|
|||
|
|
@ -28,13 +28,13 @@ public partial class TimedSkillMod : SkillMod
|
|||
{
|
||||
}
|
||||
|
||||
public TimedSkillMod(SkillName skill, bool relative, double value, TimeSpan delay)
|
||||
: this(skill, relative, value, Core.Now + delay)
|
||||
public TimedSkillMod(SkillName skill, string name, bool relative, double value, TimeSpan delay)
|
||||
: this(skill, name, relative, value, Core.Now + delay)
|
||||
{
|
||||
}
|
||||
|
||||
public TimedSkillMod(SkillName skill, bool relative, double value, DateTime expire)
|
||||
: base(skill, relative, value) => _expire = expire;
|
||||
public TimedSkillMod(SkillName skill, string name, bool relative, double value, DateTime expire)
|
||||
: base(skill, name, relative, value) => _expire = expire;
|
||||
|
||||
public override bool CheckCondition() => Core.Now < _expire;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1329,7 +1329,12 @@ namespace Server.Factions
|
|||
|
||||
if (baseValue > 0)
|
||||
{
|
||||
SkillMod mod = new DefaultSkillMod(sk.SkillName, true, -(baseValue * SkillLossFactor));
|
||||
SkillMod mod = new DefaultSkillMod(
|
||||
sk.SkillName,
|
||||
$"{sk.Name}FactionSkillLoss",
|
||||
true,
|
||||
-(baseValue * SkillLossFactor)
|
||||
);
|
||||
|
||||
mods.Add(mod);
|
||||
mob.AddSkillMod(mod);
|
||||
|
|
|
|||
|
|
@ -38,7 +38,7 @@ namespace Server.Items
|
|||
}
|
||||
else if (m_SkillMod == null && Parent is Mobile mobile)
|
||||
{
|
||||
m_SkillMod = new DefaultSkillMod(SkillName.Blacksmith, true, m_Bonus);
|
||||
m_SkillMod = new DefaultSkillMod(SkillName.Blacksmith, "AncientSmithyHammer", true, m_Bonus);
|
||||
mobile.AddSkillMod(m_SkillMod);
|
||||
}
|
||||
else if (m_SkillMod != null)
|
||||
|
|
@ -59,7 +59,7 @@ namespace Server.Items
|
|||
{
|
||||
m_SkillMod?.Remove();
|
||||
|
||||
m_SkillMod = new DefaultSkillMod(SkillName.Blacksmith, true, m_Bonus);
|
||||
m_SkillMod = new DefaultSkillMod(SkillName.Blacksmith, "AncientSmithyHammer", true, m_Bonus);
|
||||
mobile.AddSkillMod(m_SkillMod);
|
||||
}
|
||||
}
|
||||
|
|
@ -111,7 +111,7 @@ namespace Server.Items
|
|||
{
|
||||
m_SkillMod?.Remove();
|
||||
|
||||
m_SkillMod = new DefaultSkillMod(SkillName.Blacksmith, true, m_Bonus);
|
||||
m_SkillMod = new DefaultSkillMod(SkillName.Blacksmith, "AncientSmithyHammer", true, m_Bonus);
|
||||
mobile.AddSkillMod(m_SkillMod);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -164,7 +164,7 @@ namespace Server.Items
|
|||
}
|
||||
else if (m_SkillMod == null && Parent is Mobile mobile)
|
||||
{
|
||||
m_SkillMod = new DefaultSkillMod(SkillName.Mining, true, m_Bonus);
|
||||
m_SkillMod = new DefaultSkillMod(SkillName.Mining, "MiningGloves", true, m_Bonus);
|
||||
mobile.AddSkillMod(m_SkillMod);
|
||||
}
|
||||
else if (m_SkillMod != null)
|
||||
|
|
@ -182,7 +182,7 @@ namespace Server.Items
|
|||
{
|
||||
m_SkillMod?.Remove();
|
||||
|
||||
m_SkillMod = new DefaultSkillMod(SkillName.Mining, true, m_Bonus);
|
||||
m_SkillMod = new DefaultSkillMod(SkillName.Mining, "MiningGloves", true, m_Bonus);
|
||||
mobile.AddSkillMod(m_SkillMod);
|
||||
}
|
||||
}
|
||||
|
|
@ -234,7 +234,7 @@ namespace Server.Items
|
|||
{
|
||||
m_SkillMod?.Remove();
|
||||
|
||||
m_SkillMod = new DefaultSkillMod(SkillName.Mining, true, m_Bonus);
|
||||
m_SkillMod = new DefaultSkillMod(SkillName.Mining, "MiningGloves", true, m_Bonus);
|
||||
mobile.AddSkillMod(m_SkillMod);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -36,7 +36,7 @@ namespace Server.Items
|
|||
EndDefense(info);
|
||||
}
|
||||
|
||||
var mod = new ResistanceMod(ResistanceType.Physical, 50 + modifier);
|
||||
var mod = new ResistanceMod(ResistanceType.Physical, "PhysicalResistDefenseMastery", 50 + modifier);
|
||||
attacker.AddResistanceMod(mod);
|
||||
|
||||
info = new DefenseMasteryInfo(attacker, 80 - modifier, mod);
|
||||
|
|
|
|||
|
|
@ -439,7 +439,7 @@ namespace Server.Items
|
|||
}
|
||||
else if (m_SkillMod == null && Parent is Mobile mobile)
|
||||
{
|
||||
m_SkillMod = new DefaultSkillMod(AccuracySkill, true, (int)m_AccuracyLevel * 5);
|
||||
m_SkillMod = new DefaultSkillMod(AccuracySkill, "WeaponAccuracy", true, (int)m_AccuracyLevel * 5);
|
||||
mobile.AddSkillMod(m_SkillMod);
|
||||
}
|
||||
else if (m_SkillMod != null)
|
||||
|
|
@ -966,7 +966,7 @@ namespace Server.Items
|
|||
{
|
||||
m_SkillMod?.Remove();
|
||||
|
||||
m_SkillMod = new DefaultSkillMod(AccuracySkill, true, (int)m_AccuracyLevel * 5);
|
||||
m_SkillMod = new DefaultSkillMod(AccuracySkill, "WeaponAccuracy", true, (int)m_AccuracyLevel * 5);
|
||||
from.AddSkillMod(m_SkillMod);
|
||||
}
|
||||
|
||||
|
|
@ -974,7 +974,7 @@ namespace Server.Items
|
|||
{
|
||||
m_MageMod?.Remove();
|
||||
|
||||
m_MageMod = new DefaultSkillMod(SkillName.Magery, true, -30 + WeaponAttributes.MageWeapon);
|
||||
m_MageMod = new DefaultSkillMod(SkillName.Magery, "MageWeapon", true, -30 + WeaponAttributes.MageWeapon);
|
||||
from.AddSkillMod(m_MageMod);
|
||||
}
|
||||
|
||||
|
|
@ -3944,7 +3944,7 @@ namespace Server.Items
|
|||
|
||||
if (UseSkillMod && m_AccuracyLevel != WeaponAccuracyLevel.Regular && parentMobile != null)
|
||||
{
|
||||
m_SkillMod = new DefaultSkillMod(AccuracySkill, true, (int)m_AccuracyLevel * 5);
|
||||
m_SkillMod = new DefaultSkillMod(AccuracySkill, "WeaponAccuracy", true, (int)m_AccuracyLevel * 5);
|
||||
parentMobile.AddSkillMod(m_SkillMod);
|
||||
}
|
||||
|
||||
|
|
@ -3956,7 +3956,7 @@ namespace Server.Items
|
|||
if (Core.AOS && WeaponAttributes.MageWeapon != 0 && WeaponAttributes.MageWeapon != 30 &&
|
||||
parentMobile != null)
|
||||
{
|
||||
m_MageMod = new DefaultSkillMod(SkillName.Magery, true, -30 + WeaponAttributes.MageWeapon);
|
||||
m_MageMod = new DefaultSkillMod(SkillName.Magery, "MageWeapon", true, -30 + WeaponAttributes.MageWeapon);
|
||||
parentMobile.AddSkillMod(m_MageMod);
|
||||
}
|
||||
|
||||
|
|
@ -4111,7 +4111,7 @@ namespace Server.Items
|
|||
|
||||
if (UseSkillMod && m_AccuracyLevel != WeaponAccuracyLevel.Regular && parentMobile != null)
|
||||
{
|
||||
m_SkillMod = new DefaultSkillMod(AccuracySkill, true, (int)m_AccuracyLevel * 5);
|
||||
m_SkillMod = new DefaultSkillMod(AccuracySkill, "WeaponAccuracy", true, (int)m_AccuracyLevel * 5);
|
||||
parentMobile.AddSkillMod(m_SkillMod);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -590,21 +590,20 @@ namespace Server
|
|||
|
||||
if (strBonus != 0 || dexBonus != 0 || intBonus != 0)
|
||||
{
|
||||
var serial = Owner.Serial;
|
||||
|
||||
var hashCode = GetHashCode();
|
||||
if (strBonus != 0)
|
||||
{
|
||||
to.AddStatMod(new StatMod(StatType.Str, $"{serial}Str", strBonus, TimeSpan.Zero));
|
||||
to.AddStatMod(new StatMod(StatType.Str, $"{hashCode}Str", strBonus, TimeSpan.Zero));
|
||||
}
|
||||
|
||||
if (dexBonus != 0)
|
||||
{
|
||||
to.AddStatMod(new StatMod(StatType.Dex, $"{serial}Dex", dexBonus, TimeSpan.Zero));
|
||||
to.AddStatMod(new StatMod(StatType.Dex, $"{hashCode}Dex", dexBonus, TimeSpan.Zero));
|
||||
}
|
||||
|
||||
if (intBonus != 0)
|
||||
{
|
||||
to.AddStatMod(new StatMod(StatType.Int, $"{serial}Int", intBonus, TimeSpan.Zero));
|
||||
to.AddStatMod(new StatMod(StatType.Int, $"{hashCode}Int", intBonus, TimeSpan.Zero));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -1094,7 +1093,7 @@ namespace Server
|
|||
|
||||
m_Mods ??= new HashSet<SkillMod>();
|
||||
|
||||
SkillMod sk = new DefaultSkillMod(skill, true, bonus);
|
||||
SkillMod sk = new DefaultSkillMod(skill, $"{GetHashCode()}{skill}", true, bonus);
|
||||
sk.ObeyCap = true;
|
||||
m.AddSkillMod(sk);
|
||||
m_Mods.Add(sk);
|
||||
|
|
@ -1346,10 +1345,10 @@ namespace Server
|
|||
|
||||
public bool IsEmpty => _names == 0;
|
||||
|
||||
private Item _owner;
|
||||
private IEntity _owner;
|
||||
|
||||
[DirtyTrackingEntity]
|
||||
public Item Owner => _owner;
|
||||
public IEntity Owner => _owner;
|
||||
|
||||
public int GetValue(int bitmask)
|
||||
{
|
||||
|
|
@ -1483,23 +1482,30 @@ namespace Server
|
|||
}
|
||||
}
|
||||
|
||||
if (Owner?.Parent is Mobile m)
|
||||
if (Owner is Item item)
|
||||
{
|
||||
m.CheckStatTimers();
|
||||
m.UpdateResistances();
|
||||
m.Delta(
|
||||
MobileDelta.Stat | MobileDelta.WeaponDamage | MobileDelta.Hits | MobileDelta.Stam |
|
||||
MobileDelta.Mana
|
||||
);
|
||||
|
||||
if (this is AosSkillBonuses)
|
||||
if (item.Parent is Mobile m)
|
||||
{
|
||||
((AosSkillBonuses)this).Remove();
|
||||
((AosSkillBonuses)this).AddTo(m);
|
||||
}
|
||||
}
|
||||
m.CheckStatTimers();
|
||||
m.UpdateResistances();
|
||||
m.Delta(
|
||||
MobileDelta.Stat | MobileDelta.WeaponDamage | MobileDelta.Hits | MobileDelta.Stam |
|
||||
MobileDelta.Mana
|
||||
);
|
||||
|
||||
Owner?.InvalidateProperties();
|
||||
if (this is AosSkillBonuses skillBonuses)
|
||||
{
|
||||
skillBonuses.Remove();
|
||||
skillBonuses.AddTo(m);
|
||||
}
|
||||
}
|
||||
|
||||
item.InvalidateProperties();
|
||||
}
|
||||
else if (Owner is Mobile mob)
|
||||
{
|
||||
mob.InvalidateProperties();
|
||||
}
|
||||
}
|
||||
|
||||
private int GetIndex(uint mask)
|
||||
|
|
|
|||
|
|
@ -44,7 +44,7 @@ public class GraspingClaw : MonsterAbility
|
|||
*/
|
||||
var effect = -(target.PhysicalResistance * 15 / 100);
|
||||
|
||||
var mod = new ResistanceMod(ResistanceType.Physical, effect);
|
||||
var mod = new ResistanceMod(ResistanceType.Physical, "GraspingClaw", effect);
|
||||
|
||||
target.FixedEffect(0x37B9, 10, 5);
|
||||
target.AddResistanceMod(mod);
|
||||
|
|
|
|||
|
|
@ -78,18 +78,17 @@ namespace Server.Mobiles
|
|||
return;
|
||||
}
|
||||
|
||||
if (m_Table.TryGetValue(defender, out var timer))
|
||||
if (m_Table.Remove(defender, out var timer))
|
||||
{
|
||||
timer.DoExpire();
|
||||
}
|
||||
|
||||
defender.FixedParticles(0x3709, 10, 30, 5052, EffectLayer.LeftFoot);
|
||||
defender.PlaySound(0x208);
|
||||
defender.SendLocalizedMessage(
|
||||
1070833
|
||||
); // The creature fans you with fire, reducing your resistance to fire attacks.
|
||||
// The creature fans you with fire, reducing your resistance to fire attacks.
|
||||
defender.SendLocalizedMessage(1070833);
|
||||
|
||||
var mod = new ResistanceMod(ResistanceType.Fire, -10);
|
||||
var mod = new ResistanceMod(ResistanceType.Fire, "FireResistFanningFire", -10);
|
||||
defender.AddResistanceMod(mod);
|
||||
|
||||
m_Table[defender] = timer = new ExpireTimer(defender, mod);
|
||||
|
|
@ -127,13 +126,13 @@ namespace Server.Mobiles
|
|||
m_Mobile.RemoveResistanceMod(m_Mod);
|
||||
|
||||
Stop();
|
||||
m_Table.Remove(m_Mobile);
|
||||
}
|
||||
|
||||
protected override void OnTick()
|
||||
{
|
||||
m_Mobile.SendLocalizedMessage(1070834); // Your resistance to fire attacks has returned.
|
||||
DoExpire();
|
||||
m_Table.Remove(m_Mobile);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -126,7 +126,7 @@ namespace Server.Mobiles
|
|||
{
|
||||
var s = target.Skills[i];
|
||||
|
||||
target.AddSkillMod(new TimedSkillMod(s.SkillName, true, s.Base * -0.28, delay));
|
||||
target.AddSkillMod(new TimedSkillMod(s.SkillName, $"{s.Name}Satyr", true, s.Base * -0.28, delay));
|
||||
}
|
||||
|
||||
var count = (int)Math.Round(delay.TotalSeconds / 1.25);
|
||||
|
|
|
|||
|
|
@ -105,21 +105,20 @@ namespace Server.Mobiles
|
|||
return;
|
||||
}
|
||||
|
||||
if (m_Table.TryGetValue(defender, out var timer))
|
||||
if (m_Table.Remove(defender, out var timer))
|
||||
{
|
||||
timer.DoExpire();
|
||||
defender.SendLocalizedMessage(1070837); // The creature lands another blow in your weakened state.
|
||||
}
|
||||
else
|
||||
{
|
||||
defender.SendLocalizedMessage(
|
||||
1070836
|
||||
); // The blow from the creature's claws has made you more susceptible to physical attacks.
|
||||
// The blow from the creature's claws has made you more susceptible to physical attacks.
|
||||
defender.SendLocalizedMessage(1070836);
|
||||
}
|
||||
|
||||
var effect = -(defender.PhysicalResistance * 15 / 100);
|
||||
|
||||
var mod = new ResistanceMod(ResistanceType.Physical, effect);
|
||||
var mod = new ResistanceMod(ResistanceType.Physical, "PhysicalResistGraspingClaw", effect);
|
||||
|
||||
defender.FixedEffect(0x37B9, 10, 5);
|
||||
defender.AddResistanceMod(mod);
|
||||
|
|
@ -159,13 +158,13 @@ namespace Server.Mobiles
|
|||
{
|
||||
m_Mobile.RemoveResistanceMod(m_Mod);
|
||||
Stop();
|
||||
m_Table.Remove(m_Mobile);
|
||||
}
|
||||
|
||||
protected override void OnTick()
|
||||
{
|
||||
m_Mobile.SendLocalizedMessage(1070838); // Your resistance to physical attacks has returned.
|
||||
DoExpire();
|
||||
m_Table.Remove(m_Mobile);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -114,7 +114,7 @@ namespace Server.Mobiles
|
|||
{
|
||||
base.OnGaveMeleeAttack(defender, damage);
|
||||
|
||||
if (!IsFanned(defender) && Utility.RandomDouble() < 0.05)
|
||||
if (m_Table.Add(defender) && Utility.RandomDouble() < 0.05)
|
||||
{
|
||||
/* Fanning Fire
|
||||
* Graphic: Type: "3" From: "0x57D4F5B" To: "0x0" ItemId: "0x3709" ItemIdName: "fire column" FromLocation: "(994 325, 16)" ToLocation: "(994 325, 16)" Speed: "10" Duration: "30" FixedDirection: "True" Explode: "False" Hue: "0x0" RenderMode: "0x0" Effect: "0x34" ExplodeEffect: "0x1" ExplodeSound: "0x0" Serial: "0x57D4F5B" Layer: "5" Unknown: "0x0"
|
||||
|
|
@ -131,7 +131,7 @@ namespace Server.Mobiles
|
|||
|
||||
var effect = -(defender.FireResistance / 10);
|
||||
|
||||
var mod = new ResistanceMod(ResistanceType.Fire, effect);
|
||||
var mod = new ResistanceMod(ResistanceType.Fire, "FireResistFanningFire", effect);
|
||||
|
||||
defender.FixedParticles(0x37B9, 10, 30, 0x34, EffectLayer.RightFoot);
|
||||
defender.PlaySound(0x208);
|
||||
|
|
@ -143,11 +143,10 @@ namespace Server.Mobiles
|
|||
|
||||
var timer = new ExpireTimer(defender, mod, TimeSpan.FromSeconds(10.0));
|
||||
timer.Start();
|
||||
m_Table.Add(defender);
|
||||
}
|
||||
}
|
||||
|
||||
public bool IsFanned(Mobile m) => m_Table.Contains(m);
|
||||
public static bool IsFanned(Mobile m) => m_Table.Contains(m);
|
||||
|
||||
public override void Serialize(IGenericWriter writer)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -72,21 +72,20 @@ namespace Server.Mobiles
|
|||
* Effect: Type: "3" From: "0x57D4F5B" To: "0x0" ItemId: "0x37B9" ItemIdName: "glow" FromLocation: "(1048 779, 6)" ToLocation: "(1048 779, 6)" Speed: "10" Duration: "5" FixedDirection: "True" Explode: "False"
|
||||
*/
|
||||
|
||||
if (m_FlurryOfTwigsTable.TryGetValue(defender, out var timer))
|
||||
if (m_FlurryOfTwigsTable.Remove(defender, out var timer))
|
||||
{
|
||||
timer.DoExpire();
|
||||
defender.SendLocalizedMessage(1070851); // The creature lands another blow in your weakened state.
|
||||
}
|
||||
else
|
||||
{
|
||||
defender.SendLocalizedMessage(
|
||||
1070850
|
||||
); // The creature's flurry of twigs has made you more susceptible to physical attacks!
|
||||
// The creature's flurry of twigs has made you more susceptible to physical attacks!
|
||||
defender.SendLocalizedMessage(1070850);
|
||||
}
|
||||
|
||||
var effect = -(defender.PhysicalResistance * 15 / 100);
|
||||
|
||||
var mod = new ResistanceMod(ResistanceType.Physical, effect);
|
||||
var mod = new ResistanceMod(ResistanceType.Physical, "PhysicalResistFlurryOfTwigs", effect);
|
||||
|
||||
defender.FixedEffect(0x37B9, 10, 5);
|
||||
defender.AddResistanceMod(mod);
|
||||
|
|
@ -99,7 +98,7 @@ namespace Server.Mobiles
|
|||
|
||||
if (Utility.RandomDouble() < 0.05)
|
||||
{
|
||||
/* Chlorophyl Blast
|
||||
/* Chlorophyll Blast
|
||||
* Start cliloc: 1070827
|
||||
* Effect: Energy resistance -50% for 10 seconds
|
||||
* End cliloc: 1070829
|
||||
|
|
@ -113,14 +112,13 @@ namespace Server.Mobiles
|
|||
}
|
||||
else
|
||||
{
|
||||
defender.SendLocalizedMessage(
|
||||
1070827
|
||||
); // The creature's attack has made you more susceptible to energy attacks!
|
||||
// The creature's attack has made you more susceptible to energy attacks!
|
||||
defender.SendLocalizedMessage(1070827);
|
||||
}
|
||||
|
||||
var effect = -(defender.EnergyResistance / 2);
|
||||
|
||||
var mod = new ResistanceMod(ResistanceType.Energy, effect);
|
||||
var mod = new ResistanceMod(ResistanceType.Energy, "EnergyResistChlorophyllBlast", effect);
|
||||
|
||||
defender.FixedEffect(0x37B9, 10, 5);
|
||||
defender.AddResistanceMod(mod);
|
||||
|
|
@ -161,7 +159,6 @@ namespace Server.Mobiles
|
|||
{
|
||||
m_Mobile.RemoveResistanceMod(m_Mod);
|
||||
Stop();
|
||||
m_Table.Remove(m_Mobile);
|
||||
}
|
||||
|
||||
protected override void OnTick()
|
||||
|
|
@ -176,6 +173,7 @@ namespace Server.Mobiles
|
|||
}
|
||||
|
||||
DoExpire();
|
||||
m_Table.Remove(m_Mobile);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -110,7 +110,7 @@ namespace Server.Mobiles
|
|||
* End ASCII: "The corruption of your armor has worn off"
|
||||
*/
|
||||
|
||||
if (m_Table.TryGetValue(defender, out var timer))
|
||||
if (m_Table.Remove(defender, out var timer))
|
||||
{
|
||||
timer.DoExpire();
|
||||
defender.SendLocalizedMessage(1070845); // The creature continues to corrupt your armor!
|
||||
|
|
@ -120,42 +120,59 @@ namespace Server.Mobiles
|
|||
defender.SendLocalizedMessage(1070846); // The creature magically corrupts your armor!
|
||||
}
|
||||
|
||||
var mods = new List<ResistanceMod>();
|
||||
|
||||
if (Core.ML)
|
||||
{
|
||||
if (defender.PhysicalResistance > 0)
|
||||
{
|
||||
mods.Add(new ResistanceMod(ResistanceType.Physical, -(defender.PhysicalResistance / 2)));
|
||||
defender.AddResistanceMod(
|
||||
new ResistanceMod(
|
||||
ResistanceType.Physical,
|
||||
"RuneCorruption",
|
||||
-(defender.PhysicalResistance / 2)
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
if (defender.FireResistance > 0)
|
||||
{
|
||||
mods.Add(new ResistanceMod(ResistanceType.Fire, -(defender.FireResistance / 2)));
|
||||
defender.AddResistanceMod(new ResistanceMod(ResistanceType.Fire, "RuneCorruption", -(defender.FireResistance / 2)));
|
||||
}
|
||||
|
||||
if (defender.ColdResistance > 0)
|
||||
{
|
||||
mods.Add(new ResistanceMod(ResistanceType.Cold, -(defender.ColdResistance / 2)));
|
||||
defender.AddResistanceMod(new ResistanceMod(ResistanceType.Cold, "RuneCorruption", -(defender.ColdResistance / 2)));
|
||||
}
|
||||
|
||||
if (defender.PoisonResistance > 0)
|
||||
{
|
||||
mods.Add(new ResistanceMod(ResistanceType.Poison, -(defender.PoisonResistance / 2)));
|
||||
defender.AddResistanceMod(
|
||||
new ResistanceMod(
|
||||
ResistanceType.Poison,
|
||||
"RuneCorruption",
|
||||
-(defender.PoisonResistance / 2)
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
if (defender.EnergyResistance > 0)
|
||||
{
|
||||
mods.Add(new ResistanceMod(ResistanceType.Energy, -(defender.EnergyResistance / 2)));
|
||||
defender.AddResistanceMod(
|
||||
new ResistanceMod(
|
||||
ResistanceType.Energy,
|
||||
"RuneCorruption",
|
||||
-(defender.EnergyResistance / 2)
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (defender.PhysicalResistance > 0)
|
||||
{
|
||||
mods.Add(
|
||||
defender.AddResistanceMod(
|
||||
new ResistanceMod(
|
||||
ResistanceType.Physical,
|
||||
"RuneCorruption",
|
||||
defender.PhysicalResistance > 70 ? -70 : -defender.PhysicalResistance
|
||||
)
|
||||
);
|
||||
|
|
@ -163,9 +180,10 @@ namespace Server.Mobiles
|
|||
|
||||
if (defender.FireResistance > 0)
|
||||
{
|
||||
mods.Add(
|
||||
defender.AddResistanceMod(
|
||||
new ResistanceMod(
|
||||
ResistanceType.Fire,
|
||||
"RuneCorruption",
|
||||
defender.FireResistance > 70 ? -70 : -defender.FireResistance
|
||||
)
|
||||
);
|
||||
|
|
@ -173,9 +191,10 @@ namespace Server.Mobiles
|
|||
|
||||
if (defender.ColdResistance > 0)
|
||||
{
|
||||
mods.Add(
|
||||
defender.AddResistanceMod(
|
||||
new ResistanceMod(
|
||||
ResistanceType.Cold,
|
||||
"RuneCorruption",
|
||||
defender.ColdResistance > 70 ? -70 : -defender.ColdResistance
|
||||
)
|
||||
);
|
||||
|
|
@ -183,9 +202,10 @@ namespace Server.Mobiles
|
|||
|
||||
if (defender.PoisonResistance > 0)
|
||||
{
|
||||
mods.Add(
|
||||
defender.AddResistanceMod(
|
||||
new ResistanceMod(
|
||||
ResistanceType.Poison,
|
||||
"RuneCorruption",
|
||||
defender.PoisonResistance > 70 ? -70 : -defender.PoisonResistance
|
||||
)
|
||||
);
|
||||
|
|
@ -193,23 +213,19 @@ namespace Server.Mobiles
|
|||
|
||||
if (defender.EnergyResistance > 0)
|
||||
{
|
||||
mods.Add(
|
||||
defender.AddResistanceMod(
|
||||
new ResistanceMod(
|
||||
ResistanceType.Energy,
|
||||
"RuneCorruption",
|
||||
defender.EnergyResistance > 70 ? -70 : -defender.EnergyResistance
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
for (var i = 0; i < mods.Count; ++i)
|
||||
{
|
||||
defender.AddResistanceMod(mods[i]);
|
||||
}
|
||||
|
||||
defender.FixedEffect(0x37B9, 10, 5);
|
||||
|
||||
timer = new ExpireTimer(defender, mods, TimeSpan.FromSeconds(5.0));
|
||||
timer = new ExpireTimer(defender, TimeSpan.FromSeconds(5.0));
|
||||
timer.Start();
|
||||
m_Table[defender] = timer;
|
||||
}
|
||||
|
|
@ -229,11 +245,12 @@ namespace Server.Mobiles
|
|||
{
|
||||
for (var i = 0; i < Skills.Length; ++i)
|
||||
{
|
||||
Skills[i].Cap = Math.Max(100.0, Skills[i].Cap * 0.9);
|
||||
var skill = Skills[i];
|
||||
skill.Cap = Math.Max(100.0, skill.Cap * 0.9);
|
||||
|
||||
if (Skills[i].Base > Skills[i].Cap)
|
||||
if (skill.Base > skill.Cap)
|
||||
{
|
||||
Skills[i].Base = Skills[i].Cap;
|
||||
skill.Base = skill.Cap;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -242,29 +259,20 @@ namespace Server.Mobiles
|
|||
private class ExpireTimer : Timer
|
||||
{
|
||||
private readonly Mobile m_Mobile;
|
||||
private readonly List<ResistanceMod> m_Mods;
|
||||
|
||||
public ExpireTimer(Mobile m, List<ResistanceMod> mods, TimeSpan delay) : base(delay)
|
||||
{
|
||||
m_Mobile = m;
|
||||
m_Mods = mods;
|
||||
}
|
||||
public ExpireTimer(Mobile m, TimeSpan delay) : base(delay) => m_Mobile = m;
|
||||
|
||||
public void DoExpire()
|
||||
{
|
||||
for (var i = 0; i < m_Mods.Count; ++i)
|
||||
{
|
||||
m_Mobile.RemoveResistanceMod(m_Mods[i]);
|
||||
}
|
||||
|
||||
m_Mobile.RemoveResistanceMod("RuneCorruption");
|
||||
Stop();
|
||||
m_Table.Remove(m_Mobile);
|
||||
}
|
||||
|
||||
protected override void OnTick()
|
||||
{
|
||||
m_Mobile.SendMessage("The corruption of your armor has worn off");
|
||||
DoExpire();
|
||||
m_Table.Remove(m_Mobile);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -95,63 +95,24 @@ namespace Server.SkillHandlers
|
|||
public readonly Mobile m_Creature;
|
||||
public readonly int m_Effect;
|
||||
public readonly Mobile m_From;
|
||||
public readonly List<object> m_Mods;
|
||||
public bool m_Ending;
|
||||
public DateTime m_EndTime;
|
||||
public TimerExecutionToken _timerToken;
|
||||
|
||||
public DiscordanceInfo(Mobile from, Mobile creature, int effect, List<object> mods)
|
||||
public DiscordanceInfo(Mobile from, Mobile creature, int effect)
|
||||
{
|
||||
m_From = from;
|
||||
m_Creature = creature;
|
||||
m_EndTime = Core.Now;
|
||||
m_Ending = false;
|
||||
m_Effect = effect;
|
||||
m_Mods = mods;
|
||||
|
||||
Apply();
|
||||
}
|
||||
|
||||
public void Apply()
|
||||
{
|
||||
for (var i = 0; i < m_Mods.Count; ++i)
|
||||
{
|
||||
var mod = m_Mods[i];
|
||||
|
||||
if (mod is ResistanceMod resistanceMod)
|
||||
{
|
||||
m_Creature.AddResistanceMod(resistanceMod);
|
||||
}
|
||||
else if (mod is StatMod statMod)
|
||||
{
|
||||
m_Creature.AddStatMod(statMod);
|
||||
}
|
||||
else if (mod is SkillMod skillMod)
|
||||
{
|
||||
m_Creature.AddSkillMod(skillMod);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void Clear()
|
||||
{
|
||||
for (var i = 0; i < m_Mods.Count; ++i)
|
||||
{
|
||||
var mod = m_Mods[i];
|
||||
|
||||
if (mod is ResistanceMod resistanceMod)
|
||||
{
|
||||
m_Creature.RemoveResistanceMod(resistanceMod);
|
||||
}
|
||||
else if (mod is StatMod statMod)
|
||||
{
|
||||
m_Creature.RemoveStatMod(statMod.Name);
|
||||
}
|
||||
else if (mod is SkillMod skillMod)
|
||||
{
|
||||
m_Creature.RemoveSkillMod(skillMod);
|
||||
}
|
||||
}
|
||||
m_Creature.RemoveResistanceMod("Discordance");
|
||||
m_Creature.RemoveStatMod("Discordance");
|
||||
m_Creature.RemoveSkillMod("Discordance");
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -163,8 +124,7 @@ namespace Server.SkillHandlers
|
|||
BaseInstrument.GetBardRange(from, SkillName.Discordance),
|
||||
false,
|
||||
TargetFlags.None
|
||||
) =>
|
||||
m_Instrument = inst;
|
||||
) => m_Instrument = inst;
|
||||
|
||||
protected override void OnTarget(Mobile from, object target)
|
||||
{
|
||||
|
|
@ -211,7 +171,6 @@ namespace Server.SkillHandlers
|
|||
m_Instrument.PlayInstrumentWell(from);
|
||||
m_Instrument.ConsumeUse(from);
|
||||
|
||||
var mods = new List<object>();
|
||||
int effect;
|
||||
double scalar;
|
||||
|
||||
|
|
@ -235,60 +194,53 @@ namespace Server.SkillHandlers
|
|||
|
||||
scalar = effect * 0.01;
|
||||
|
||||
mods.Add(new ResistanceMod(ResistanceType.Physical, effect));
|
||||
mods.Add(new ResistanceMod(ResistanceType.Fire, effect));
|
||||
mods.Add(new ResistanceMod(ResistanceType.Cold, effect));
|
||||
mods.Add(new ResistanceMod(ResistanceType.Poison, effect));
|
||||
mods.Add(new ResistanceMod(ResistanceType.Energy, effect));
|
||||
|
||||
for (var i = 0; i < targ.Skills.Length; ++i)
|
||||
{
|
||||
if (targ.Skills[i].Value > 0)
|
||||
{
|
||||
mods.Add(new DefaultSkillMod((SkillName)i, true, targ.Skills[i].Value * scalar));
|
||||
}
|
||||
}
|
||||
targ.AddResistanceMod(new ResistanceMod(ResistanceType.Physical, "Discordance", effect));
|
||||
targ.AddResistanceMod(new ResistanceMod(ResistanceType.Fire, "Discordance", effect));
|
||||
targ.AddResistanceMod(new ResistanceMod(ResistanceType.Cold, "Discordance", effect));
|
||||
targ.AddResistanceMod(new ResistanceMod(ResistanceType.Poison, "Discordance", effect));
|
||||
targ.AddResistanceMod(new ResistanceMod(ResistanceType.Energy, "Discordance", effect));
|
||||
}
|
||||
else
|
||||
{
|
||||
effect = (int)(from.Skills.Discordance.Value / -5.0);
|
||||
scalar = effect * 0.01;
|
||||
|
||||
mods.Add(
|
||||
targ.AddStatMod(
|
||||
new StatMod(
|
||||
StatType.Str,
|
||||
"DiscordanceStr",
|
||||
"Discordance",
|
||||
(int)(targ.RawStr * scalar),
|
||||
TimeSpan.Zero
|
||||
)
|
||||
);
|
||||
mods.Add(
|
||||
targ.AddStatMod(
|
||||
new StatMod(
|
||||
StatType.Int,
|
||||
"DiscordanceInt",
|
||||
"Discordance",
|
||||
(int)(targ.RawInt * scalar),
|
||||
TimeSpan.Zero
|
||||
)
|
||||
);
|
||||
mods.Add(
|
||||
targ.AddStatMod(
|
||||
new StatMod(
|
||||
StatType.Dex,
|
||||
"DiscordanceDex",
|
||||
"Discordance",
|
||||
(int)(targ.RawDex * scalar),
|
||||
TimeSpan.Zero
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
for (var i = 0; i < targ.Skills.Length; ++i)
|
||||
for (var i = 0; i < targ.Skills.Length; ++i)
|
||||
{
|
||||
var skill = targ.Skills[i];
|
||||
if (skill.Value > 0)
|
||||
{
|
||||
if (targ.Skills[i].Value > 0)
|
||||
{
|
||||
mods.Add(new DefaultSkillMod((SkillName)i, true, targ.Skills[i].Value * scalar));
|
||||
}
|
||||
targ.AddSkillMod(new DefaultSkillMod(skill.SkillName, "Discordance", true, skill.Value * scalar));
|
||||
}
|
||||
}
|
||||
|
||||
var info = new DiscordanceInfo(from, targ, effect.Abs(), mods);
|
||||
var info = new DiscordanceInfo(from, targ, effect.Abs());
|
||||
Timer.StartTimer(
|
||||
TimeSpan.Zero,
|
||||
TimeSpan.FromSeconds(1.25),
|
||||
|
|
|
|||
|
|
@ -1242,31 +1242,29 @@ namespace Server.Spells
|
|||
|
||||
if (!ourTransform)
|
||||
{
|
||||
var mods = new List<ResistanceMod>();
|
||||
|
||||
if (transformSpell.PhysResistOffset != 0)
|
||||
{
|
||||
mods.Add(new ResistanceMod(ResistanceType.Physical, transformSpell.PhysResistOffset));
|
||||
caster.AddResistanceMod(new ResistanceMod(ResistanceType.Physical, "TransformSpell", transformSpell.PhysResistOffset));
|
||||
}
|
||||
|
||||
if (transformSpell.FireResistOffset != 0)
|
||||
{
|
||||
mods.Add(new ResistanceMod(ResistanceType.Fire, transformSpell.FireResistOffset));
|
||||
caster.AddResistanceMod(new ResistanceMod(ResistanceType.Fire, "TransformSpell", transformSpell.FireResistOffset));
|
||||
}
|
||||
|
||||
if (transformSpell.ColdResistOffset != 0)
|
||||
{
|
||||
mods.Add(new ResistanceMod(ResistanceType.Cold, transformSpell.ColdResistOffset));
|
||||
caster.AddResistanceMod(new ResistanceMod(ResistanceType.Cold, "TransformSpell", transformSpell.ColdResistOffset));
|
||||
}
|
||||
|
||||
if (transformSpell.PoisResistOffset != 0)
|
||||
{
|
||||
mods.Add(new ResistanceMod(ResistanceType.Poison, transformSpell.PoisResistOffset));
|
||||
caster.AddResistanceMod(new ResistanceMod(ResistanceType.Poison, "TransformSpell", transformSpell.PoisResistOffset));
|
||||
}
|
||||
|
||||
if (transformSpell.NrgyResistOffset != 0)
|
||||
{
|
||||
mods.Add(new ResistanceMod(ResistanceType.Energy, transformSpell.NrgyResistOffset));
|
||||
caster.AddResistanceMod(new ResistanceMod(ResistanceType.Energy, "TransformSpell", transformSpell.NrgyResistOffset));
|
||||
}
|
||||
|
||||
if (!((Body)transformSpell.Body).IsHuman)
|
||||
|
|
@ -1282,17 +1280,12 @@ namespace Server.Spells
|
|||
caster.BodyMod = transformSpell.Body;
|
||||
caster.HueMod = transformSpell.Hue;
|
||||
|
||||
for (var i = 0; i < mods.Count; ++i)
|
||||
{
|
||||
caster.AddResistanceMod(mods[i]);
|
||||
}
|
||||
|
||||
transformSpell.DoEffect(caster);
|
||||
|
||||
Timer timer = new TransformTimer(caster, transformSpell);
|
||||
timer.Start();
|
||||
|
||||
AddContext(caster, new TransformContext(timer, mods, ourType, transformSpell));
|
||||
AddContext(caster, new TransformContext(timer, ourType, transformSpell));
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
|
@ -1322,12 +1315,7 @@ namespace Server.Spells
|
|||
return;
|
||||
}
|
||||
|
||||
var mods = context.Mods;
|
||||
|
||||
for (var i = 0; i < mods.Count; ++i)
|
||||
{
|
||||
m.RemoveResistanceMod(mods[i]);
|
||||
}
|
||||
m.RemoveResistanceMod("TransformSpell");
|
||||
|
||||
if (resetGraphics)
|
||||
{
|
||||
|
|
@ -1371,18 +1359,15 @@ namespace Server.Spells
|
|||
|
||||
public class TransformContext
|
||||
{
|
||||
public TransformContext(Timer timer, List<ResistanceMod> mods, Type type, ITransformationSpell spell)
|
||||
public TransformContext(Timer timer, Type type, ITransformationSpell spell)
|
||||
{
|
||||
Timer = timer;
|
||||
Mods = mods;
|
||||
Type = type;
|
||||
Spell = spell;
|
||||
}
|
||||
|
||||
public Timer Timer { get; }
|
||||
|
||||
public List<ResistanceMod> Mods { get; }
|
||||
|
||||
public Type Type { get; }
|
||||
|
||||
public ITransformationSpell Spell { get; }
|
||||
|
|
|
|||
|
|
@ -46,18 +46,18 @@ namespace Server.Spells.Bushido
|
|||
{
|
||||
var mods = new List<object>
|
||||
{
|
||||
new ResistanceMod(ResistanceType.Physical, -40),
|
||||
new ResistanceMod(ResistanceType.Fire, -40),
|
||||
new ResistanceMod(ResistanceType.Cold, -40),
|
||||
new ResistanceMod(ResistanceType.Poison, -40),
|
||||
new ResistanceMod(ResistanceType.Energy, -40)
|
||||
new ResistanceMod(ResistanceType.Physical, "PhysicalResistHonorableExecution", -40),
|
||||
new ResistanceMod(ResistanceType.Fire, "FireResistHonorableExecution", -40),
|
||||
new ResistanceMod(ResistanceType.Cold, "ColdResistHonorableExecution", -40),
|
||||
new ResistanceMod(ResistanceType.Poison, "PoisonResistHonorableExecution", -40),
|
||||
new ResistanceMod(ResistanceType.Energy, "EnergyResistHonorableExecution", -40)
|
||||
};
|
||||
|
||||
var resSpells = attacker.Skills.MagicResist.Value;
|
||||
|
||||
if (resSpells > 0.0)
|
||||
{
|
||||
mods.Add(new DefaultSkillMod(SkillName.MagicResist, true, -resSpells));
|
||||
mods.Add(new DefaultSkillMod(SkillName.MagicResist, "MagicResistHonorableExecution", true, -resSpells));
|
||||
}
|
||||
|
||||
timer = new HonorableExecutionTimer(attacker, mods);
|
||||
|
|
|
|||
|
|
@ -78,15 +78,15 @@ namespace Server.Spells.Fifth
|
|||
targ.FixedParticles(0x375A, 10, 15, 5037, EffectLayer.Waist);
|
||||
|
||||
var physiMod = -25 + (int)(targ.Skills.Inscribe.Value / 20);
|
||||
var otherMod = 10;
|
||||
const int otherMod = 10;
|
||||
|
||||
mods = new[]
|
||||
{
|
||||
new ResistanceMod(ResistanceType.Physical, physiMod),
|
||||
new ResistanceMod(ResistanceType.Fire, otherMod),
|
||||
new ResistanceMod(ResistanceType.Cold, otherMod),
|
||||
new ResistanceMod(ResistanceType.Poison, otherMod),
|
||||
new ResistanceMod(ResistanceType.Energy, otherMod)
|
||||
new ResistanceMod(ResistanceType.Physical, "PhysicalResistMagicResist", physiMod),
|
||||
new ResistanceMod(ResistanceType.Fire, "FireResistMagicResist", otherMod),
|
||||
new ResistanceMod(ResistanceType.Cold, "ColdResistMagicResist", otherMod),
|
||||
new ResistanceMod(ResistanceType.Poison, "PoisonResistMagicResist", otherMod),
|
||||
new ResistanceMod(ResistanceType.Energy, "EnergyResistMagicResist", otherMod)
|
||||
};
|
||||
|
||||
_table[targ] = mods;
|
||||
|
|
|
|||
|
|
@ -83,12 +83,13 @@ namespace Server.Spells.First
|
|||
{
|
||||
new ResistanceMod(
|
||||
ResistanceType.Physical,
|
||||
"PhysicalResistReactiveArmorSpell",
|
||||
15 + (int)(targ.Skills.Inscribe.Value / 20)
|
||||
),
|
||||
new ResistanceMod(ResistanceType.Fire, -5),
|
||||
new ResistanceMod(ResistanceType.Cold, -5),
|
||||
new ResistanceMod(ResistanceType.Poison, -5),
|
||||
new ResistanceMod(ResistanceType.Energy, -5)
|
||||
new ResistanceMod(ResistanceType.Fire, "FireResistReactiveArmorSpell", -5),
|
||||
new ResistanceMod(ResistanceType.Cold, "ColdResistReactiveArmorSpell", -5),
|
||||
new ResistanceMod(ResistanceType.Poison, "PoisonResistReactiveArmorSpell", -5),
|
||||
new ResistanceMod(ResistanceType.Energy, "EnergyResistReactiveArmorSpell", -5)
|
||||
};
|
||||
|
||||
_table[targ] = mods;
|
||||
|
|
|
|||
|
|
@ -101,11 +101,11 @@ namespace Server.Spells.Mysticism
|
|||
|
||||
ResistanceMod[] mods =
|
||||
{
|
||||
new(ResistanceType.Physical, offset),
|
||||
new(ResistanceType.Fire, offset),
|
||||
new(ResistanceType.Cold, offset),
|
||||
new(ResistanceType.Poison, offset),
|
||||
new(ResistanceType.Energy, offset)
|
||||
new(ResistanceType.Physical, "PhysicalResistStoneFormSpell", offset),
|
||||
new(ResistanceType.Fire, "FireResistStoneFormSpell", offset),
|
||||
new(ResistanceType.Cold, "ColdResistStoneFormSpell", offset),
|
||||
new(ResistanceType.Poison, "PoisonResistStoneFormSpell", offset),
|
||||
new(ResistanceType.Energy, "EnergyResistStoneFormSpell", offset)
|
||||
};
|
||||
|
||||
for (var i = 0; i < mods.Length; ++i)
|
||||
|
|
|
|||
|
|
@ -71,10 +71,10 @@ namespace Server.Spells.Necromancy
|
|||
|
||||
ResistanceMod[] mods =
|
||||
{
|
||||
new(ResistanceType.Fire, -15),
|
||||
new(ResistanceType.Poison, -15),
|
||||
new(ResistanceType.Cold, +10),
|
||||
new(ResistanceType.Physical, +10)
|
||||
new(ResistanceType.Fire, "FireResistCorpseSkinSpell", -15),
|
||||
new(ResistanceType.Poison, "PoisonResistCorpseSkinSpell", -15),
|
||||
new(ResistanceType.Cold, "ColdResistCorpseSkinSpell", +10),
|
||||
new(ResistanceType.Physical, "PhysicalResistCorpseSkinSpell", +10)
|
||||
};
|
||||
|
||||
timer = new ExpireTimer(m, mods, duration);
|
||||
|
|
|
|||
|
|
@ -53,7 +53,7 @@ namespace Server.Spells.Necromancy
|
|||
|
||||
if (!_table.ContainsKey(m))
|
||||
{
|
||||
var mod = new DefaultSkillMod(SkillName.MagicResist, false, m.Skills.MagicResist.Value / 2);
|
||||
var mod = new DefaultSkillMod(SkillName.MagicResist, "EvilOmen", false, m.Skills.MagicResist.Value / 2);
|
||||
m.AddSkillMod(mod);
|
||||
_table[m] = mod;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -237,11 +237,12 @@ namespace Server.Spells.Ninjitsu
|
|||
m.NetState.SendSpeedControl(SpeedControlSetting.Mount);
|
||||
}
|
||||
|
||||
// TODO: Determine if transform spell skill mods to a generic location like stat mods
|
||||
SkillMod mod = null;
|
||||
|
||||
if (entry.StealthBonus)
|
||||
{
|
||||
mod = new DefaultSkillMod(SkillName.Stealth, true, 20.0) { ObeyCap = true };
|
||||
mod = new DefaultSkillMod(SkillName.Stealth, "StealthAnimalForm", true, 20.0) { ObeyCap = true };
|
||||
m.AddSkillMod(mod);
|
||||
}
|
||||
|
||||
|
|
@ -249,7 +250,7 @@ namespace Server.Spells.Ninjitsu
|
|||
|
||||
if (entry.StealingBonus)
|
||||
{
|
||||
stealingMod = new DefaultSkillMod(SkillName.Stealing, true, 10.0) { ObeyCap = true };
|
||||
stealingMod = new DefaultSkillMod(SkillName.Stealing, "StealingAnimalForm", true, 10.0) { ObeyCap = true };
|
||||
m.AddSkillMod(stealingMod);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -79,8 +79,8 @@ namespace Server.Spells.Second
|
|||
|
||||
var physLoss = -15 + (int)(caster.Skills.Inscribe.Value / 20);
|
||||
var resistLoss = -35 + (int)(caster.Skills.Inscribe.Value / 20);
|
||||
var physMod = new ResistanceMod(ResistanceType.Physical, physLoss);
|
||||
var resistMod = new DefaultSkillMod(SkillName.MagicResist, true, resistLoss);
|
||||
var physMod = new ResistanceMod(ResistanceType.Physical, "PhysicalResistProtectionSpell", physLoss);
|
||||
var resistMod = new DefaultSkillMod(SkillName.MagicResist, "MagicResistProtectionSpell", true, resistLoss);
|
||||
|
||||
_table[target] = Tuple.Create(physMod, resistMod);
|
||||
Registry[target] = 1000; // 100.0% protection from disruption
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue