diff --git a/Projects/UOContent/Engines/Ethics/Core/Ethic.cs b/Projects/UOContent/Engines/Ethics/Core/Ethic.cs index 3e54dd974..22bb85c79 100644 --- a/Projects/UOContent/Engines/Ethics/Core/Ethic.cs +++ b/Projects/UOContent/Engines/Ethics/Core/Ethic.cs @@ -1,288 +1,293 @@ +using System.Collections.Generic; +using ModernUO.Serialization; using Server.Ethics.Evil; using Server.Ethics.Hero; using Server.Items; using Server.Mobiles; -namespace Server.Ethics +namespace Server.Ethics; + +[SerializationGenerator(1)] +public abstract partial class Ethic : EthicsEntity { - public abstract class Ethic + public static Ethic Hero { get; private set; } + public static Ethic Evil { get; private set; } + + public static readonly Ethic[] Ethics = { - public static readonly Ethic Hero = new HeroEthic(); - public static readonly Ethic Evil = new EvilEthic(); + Hero, + Evil + }; - public static readonly Ethic[] Ethics = + public static bool RegisterEthic(Ethic ethic) + { + if (ethic is HeroEthic) { - Hero, - Evil - }; - - protected EthicDefinition m_Definition; - - protected PlayerCollection m_Players; - - public Ethic() => m_Players = new PlayerCollection(); - public static bool Enabled { get; private set; } - - public EthicDefinition Definition => m_Definition; - - public PlayerCollection Players => m_Players; - - public static Ethic Find(Item item) - { - if ((item.SavedFlags & 0x100) != 0) - { - if (item.Hue == Hero.Definition.PrimaryHue) - { - return Hero; - } - - item.SavedFlags &= ~0x100; - } - - if ((item.SavedFlags & 0x200) != 0) - { - if (item.Hue == Evil.Definition.PrimaryHue) - { - return Evil; - } - - item.SavedFlags &= ~0x200; - } - - return null; - } - - public static bool CheckTrade(Mobile from, Mobile to, Mobile newOwner, Item item) - { - var itemEthic = Find(item); - - if (itemEthic == null || Find(newOwner) == itemEthic) + if (Hero == null) { + Hero = ethic; return true; } - if (itemEthic == Hero) - { - (from == newOwner ? to : from).SendMessage("Only heros may receive this item."); - } - else if (itemEthic == Evil) - { - (from == newOwner ? to : from).SendMessage("Only the evil may receive this item."); - } - return false; } - public static bool CheckEquip(Mobile from, Item item) + if (ethic is EvilEthic) { - var itemEthic = Find(item); - - if (itemEthic == null || Find(from) == itemEthic) + if (Evil == null) { + Evil = ethic; return true; } - if (itemEthic == Hero) - { - from.SendMessage("Only heros may wear this item."); - } - else if (itemEthic == Evil) - { - from.SendMessage("Only the evil may wear this item."); - } - return false; } - public static bool IsImbued(Item item) => IsImbued(item, false); + return false; + } - public static bool IsImbued(Item item, bool recurse) + public Ethic() => Players = []; + + public static bool Enabled { get; private set; } + + public virtual EthicDefinition Definition { get; } + + public List Players { get; protected set; } + + public static Ethic Find(Item item) + { + if ((item.SavedFlags & 0x100) != 0) { - if (Find(item) != null) + if (item.Hue == Hero.Definition.PrimaryHue) { - return true; + return Hero; } - if (recurse) + item.SavedFlags &= ~0x100; + } + + if ((item.SavedFlags & 0x200) != 0) + { + if (item.Hue == Evil.Definition.PrimaryHue) { - foreach (var child in item.Items) + return Evil; + } + + item.SavedFlags &= ~0x200; + } + + return null; + } + + public static bool CheckTrade(Mobile from, Mobile to, Mobile newOwner, Item item) + { + var itemEthic = Find(item); + + if (itemEthic == null || Find(newOwner) == itemEthic) + { + return true; + } + + if (itemEthic == Hero) + { + (from == newOwner ? to : from).SendMessage("Only heroes may receive this item."); + } + else if (itemEthic == Evil) + { + (from == newOwner ? to : from).SendMessage("Only the evil may receive this item."); + } + + return false; + } + + public static bool CheckEquip(Mobile from, Item item) + { + var itemEthic = Find(item); + + if (itemEthic == null || Find(from) == itemEthic) + { + return true; + } + + if (itemEthic == Hero) + { + from.SendMessage("Only heroes may wear this item."); + } + else if (itemEthic == Evil) + { + from.SendMessage("Only the evil may wear this item."); + } + + return false; + } + + public static bool IsImbued(Item item) => IsImbued(item, false); + + public static bool IsImbued(Item item, bool recurse) + { + if (Find(item) != null) + { + return true; + } + + if (recurse) + { + foreach (var child in item.Items) + { + if (IsImbued(child, true)) { - if (IsImbued(child, true)) + return true; + } + } + } + + return false; + } + + public static void Configure() + { + Enabled = ServerConfiguration.GetOrUpdateSetting("ethics.enable", false); + } + + public static void Initialize() + { + if (Enabled) + { + EventSink.Speech += EventSink_Speech; + } + } + + public static void EventSink_Speech(SpeechEventArgs e) + { + if (e.Blocked || e.Handled) + { + return; + } + + var pl = Player.Find(e.Mobile); + + if (pl == null) + { + for (var i = 0; i < Ethics.Length; ++i) + { + var ethic = Ethics[i]; + + if (!ethic.IsEligible(e.Mobile)) + { + continue; + } + + if (!ethic.Definition.JoinPhrase.String.InsensitiveEquals(e.Speech)) + { + continue; + } + + var found = false; + + foreach (var item in e.Mobile.GetItemsInRange(2)) + { + if (item is AnkhNorth or AnkhWest) { - return true; + found = true; + break; } } - } - return false; - } + if (!found) + { + continue; + } - public static void Configure() - { - Enabled = ServerConfiguration.GetOrUpdateSetting("ethics.enable", false); - } + pl = new Player(ethic, e.Mobile); - public static void Initialize() - { - if (Enabled) - { - EventSink.Speech += EventSink_Speech; + pl.Attach(); + + e.Mobile.FixedEffect(0x373A, 10, 30); + e.Mobile.PlaySound(0x209); + + e.Handled = true; + break; } } - - public static void EventSink_Speech(SpeechEventArgs e) + else { - if (e.Blocked || e.Handled) + if (e.Mobile is PlayerMobile mobile && mobile.DuelContext != null) { return; } - var pl = Player.Find(e.Mobile); + var ethic = pl.Ethic; - if (pl == null) + for (var i = 0; i < ethic.Definition.Powers.Length; ++i) { - for (var i = 0; i < Ethics.Length; ++i) + var power = ethic.Definition.Powers[i]; + + if (!power.Definition.Phrase.String.InsensitiveEquals(e.Speech)) { - var ethic = Ethics[i]; - - if (!ethic.IsEligible(e.Mobile)) - { - continue; - } - - if (!ethic.Definition.JoinPhrase.String.InsensitiveEquals(e.Speech)) - { - continue; - } - - var found = false; - - foreach (var item in e.Mobile.GetItemsInRange(2)) - { - if (item is AnkhNorth or AnkhWest) - { - found = true; - break; - } - } - - if (!found) - { - continue; - } - - pl = new Player(ethic, e.Mobile); - - pl.Attach(); - - e.Mobile.FixedEffect(0x373A, 10, 30); - e.Mobile.PlaySound(0x209); - - e.Handled = true; - break; + continue; } + + if (!power.CheckInvoke(pl)) + { + continue; + } + + power.BeginInvoke(pl); + e.Handled = true; + + break; } - else + } + } + + public static Ethic Find(Mobile mob) => Find(mob, false, false); + + public static Ethic Find(Mobile mob, bool inherit) => Find(mob, inherit, false); + + public static Ethic Find(Mobile mob, bool inherit, bool allegiance) + { + var pl = Player.Find(mob); + + if (pl != null) + { + return pl.Ethic; + } + + if (inherit && mob is BaseCreature bc) + { + if (bc.Controlled) { - if (e.Mobile is PlayerMobile mobile && mobile.DuelContext != null) - { - return; - } + return Find(bc.ControlMaster, false); + } - var ethic = pl.Ethic; + if (bc.Summoned) + { + return Find(bc.SummonMaster, false); + } - for (var i = 0; i < ethic.Definition.Powers.Length; ++i) - { - var power = ethic.Definition.Powers[i]; - - if (!power.Definition.Phrase.String.InsensitiveEquals(e.Speech)) - { - continue; - } - - if (!power.CheckInvoke(pl)) - { - continue; - } - - power.BeginInvoke(pl); - e.Handled = true; - - break; - } + if (allegiance) + { + return bc.EthicAllegiance; } } - public static Ethic Find(Mobile mob) => Find(mob, false, false); + return null; + } - public static Ethic Find(Mobile mob, bool inherit) => Find(mob, inherit, false); + public abstract bool IsEligible(Mobile mob); - public static Ethic Find(Mobile mob, bool inherit, bool allegiance) + private void Deserialize(IGenericReader reader, int version) + { + var playerCount = reader.ReadEncodedInt(); + + for (var i = 0; i < playerCount; ++i) { - var pl = Player.Find(mob); + var pl = new Player(this, null); + pl.Deserialize(reader); - if (pl != null) + if (pl.Mobile != null) { - return pl.Ethic; - } - - if (inherit && mob is BaseCreature bc) - { - if (bc.Controlled) - { - return Find(bc.ControlMaster, false); - } - - if (bc.Summoned) - { - return Find(bc.SummonMaster, false); - } - - if (allegiance) - { - return bc.EthicAllegiance; - } - } - - return null; - } - - public abstract bool IsEligible(Mobile mob); - - public virtual void Deserialize(IGenericReader reader) - { - var version = reader.ReadEncodedInt(); - - switch (version) - { - case 0: - { - var playerCount = reader.ReadEncodedInt(); - - for (var i = 0; i < playerCount; ++i) - { - var pl = new Player(this, reader); - - if (pl.Mobile != null) - { - Timer.StartTimer(pl.CheckAttach); - } - } - - break; - } - } - } - - public virtual void Serialize(IGenericWriter writer) - { - writer.WriteEncodedInt(0); // version - - writer.WriteEncodedInt(m_Players.Count); - - for (var i = 0; i < m_Players.Count; ++i) - { - m_Players[i].Serialize(writer); + Timer.StartTimer(pl.CheckAttach); } } } diff --git a/Projects/UOContent/Engines/Ethics/Core/EthicsEntity.cs b/Projects/UOContent/Engines/Ethics/Core/EthicsEntity.cs new file mode 100644 index 000000000..5ce677cb8 --- /dev/null +++ b/Projects/UOContent/Engines/Ethics/Core/EthicsEntity.cs @@ -0,0 +1,26 @@ +using System; +using ModernUO.Serialization; + +namespace Server.Ethics; + +[SerializationGenerator(0)] +public partial class EthicsEntity : ISerializable +{ + public EthicsEntity() + { + Serial = EthicsSystem.NewProfile; + EthicsSystem.Add(this); + } + + public DateTime Created { get; set; } = Core.Now; + + public Serial Serial { get; } + + public bool Deleted { get; private set; } + + public void Delete() + { + Deleted = true; + EthicsSystem.Remove(this); + } +} diff --git a/Projects/UOContent/Engines/Ethics/Core/EthicsSystem.cs b/Projects/UOContent/Engines/Ethics/Core/EthicsSystem.cs new file mode 100644 index 000000000..be87eb781 --- /dev/null +++ b/Projects/UOContent/Engines/Ethics/Core/EthicsSystem.cs @@ -0,0 +1,59 @@ +using System; +using Server.Ethics.Evil; +using Server.Ethics.Hero; + +namespace Server.Ethics; + +public class EthicsSystem : GenericEntityPersistence +{ + private static EthicsSystem _persistence; + + public static void Configure() + { + _persistence = new EthicsSystem(); + } + + public EthicsSystem() : base("Ethics", 3, 0x1, 0x7FFFFFFF) + { + } + + public static Serial NewProfile => _persistence.NewEntity; + + public static void Add(EthicsEntity entity) => _persistence.AddEntity(entity); + + public static void Remove(EthicsEntity entity) => _persistence.RemoveEntity(entity); + + public static T Find(Serial serial) where T : EthicsEntity => _persistence.FindEntity(serial); +} + +[ManualDirtyChecking] +[TypeAlias("Server.Ethics.EthicsPersistance")] +[Obsolete("Deprecated in favor of the static system. Only used for legacy deserialization")] +public class EthicsPersistence : Item +{ + public EthicsPersistence() + { + Delete(); + } + + public EthicsPersistence(Serial serial) : base(serial) + { + } + + public override void Serialize(IGenericWriter writer) + { + } + + public override void Deserialize(IGenericReader reader) + { + base.Deserialize(reader); + + var heroEthic = new HeroEthic(); + heroEthic.Deserialize(reader); + + var evilEthic = new EvilEthic(); + evilEthic.Deserialize(reader); + + Timer.DelayCall(Delete); + } +} diff --git a/Projects/UOContent/Engines/Ethics/Core/Persistance.cs b/Projects/UOContent/Engines/Ethics/Core/Persistance.cs deleted file mode 100644 index ad5032ba8..000000000 --- a/Projects/UOContent/Engines/Ethics/Core/Persistance.cs +++ /dev/null @@ -1,65 +0,0 @@ -namespace Server.Ethics -{ - public class EthicsPersistance : Item - { - [Constructible] - public EthicsPersistance() - : base(1) - { - Movable = false; - - if (Instance?.Deleted != false) - { - Instance = this; - } - else - { - base.Delete(); - } - } - - public EthicsPersistance(Serial serial) - : base(serial) => - Instance = this; - - public static EthicsPersistance Instance { get; private set; } - - public override string DefaultName => "Ethics Persistance - Internal"; - - public override void Serialize(IGenericWriter writer) - { - base.Serialize(writer); - - writer.Write(0); // version - - for (var i = 0; i < Ethic.Ethics.Length; ++i) - { - Ethic.Ethics[i].Serialize(writer); - } - } - - public override void Deserialize(IGenericReader reader) - { - base.Deserialize(reader); - - var version = reader.ReadInt(); - - switch (version) - { - case 0: - { - for (var i = 0; i < Ethic.Ethics.Length; ++i) - { - Ethic.Ethics[i].Deserialize(reader); - } - - break; - } - } - } - - public override void Delete() - { - } - } -} diff --git a/Projects/UOContent/Engines/Ethics/Core/Player.cs b/Projects/UOContent/Engines/Ethics/Core/Player.cs index 23eee750e..f21fe9eb9 100644 --- a/Projects/UOContent/Engines/Ethics/Core/Player.cs +++ b/Projects/UOContent/Engines/Ethics/Core/Player.cs @@ -1,169 +1,141 @@ using System; -using System.Collections.ObjectModel; +using ModernUO.Serialization; using Server.Mobiles; -namespace Server.Ethics +namespace Server.Ethics; + +[PropertyObject] +[SerializationGenerator(1)] +public partial class Player : EthicsEntity { - public class PlayerCollection : Collection + [SerializableField(0, setter: "private")] + private Mobile _mobile; + + [SerializableField(1)] + [SerializedCommandProperty(AccessLevel.GameMaster, AccessLevel.Administrator)] + private int _power; + + [SerializableField(2)] + [SerializedCommandProperty(AccessLevel.GameMaster, AccessLevel.Administrator)] + private int _history; + + [SerializableField(3)] + [SerializedCommandProperty(AccessLevel.GameMaster, AccessLevel.Administrator)] + private Mobile _steed; + + [SerializableField(4)] + [SerializedCommandProperty(AccessLevel.GameMaster, AccessLevel.Administrator)] + private Mobile _familiar; + + [DeltaDateTime] + [SerializableField(5, setter: "private")] + private DateTime _shield; + + [SerializableField(6, setter: "private")] + private Ethic _ethic; + + public Player(Ethic ethic, Mobile mobile) { + _ethic = ethic; + _mobile = mobile; + + _power = 5; + _history = 5; } - [PropertyObject] - public class Player + private void Deserialize(IGenericReader reader, int version) { - private DateTime m_Shield; + // Don't call the base Deserialize - public Player(Ethic ethic, Mobile mobile) + _mobile = reader.ReadEntity(); + + _power = reader.ReadEncodedInt(); + _history = reader.ReadEncodedInt(); + + _steed = reader.ReadEntity(); + _familiar = reader.ReadEntity(); + + _shield = reader.ReadDeltaTime(); + } + + [CommandProperty(AccessLevel.GameMaster)] + public bool IsShielded + { + get { - Ethic = ethic; - Mobile = mobile; - - Power = 5; - History = 5; - } - - public Player(Ethic ethic, IGenericReader reader) - { - Ethic = ethic; - - var version = reader.ReadEncodedInt(); - - switch (version) + if (_shield == DateTime.MinValue) { - case 0: - { - Mobile = reader.ReadEntity(); - - Power = reader.ReadEncodedInt(); - History = reader.ReadEncodedInt(); - - Steed = reader.ReadEntity(); - Familiar = reader.ReadEntity(); - - m_Shield = reader.ReadDeltaTime(); - - break; - } - } - } - - public Ethic Ethic { get; } - - public Mobile Mobile { get; } - - [CommandProperty(AccessLevel.GameMaster, AccessLevel.Administrator)] - public int Power { get; set; } - - [CommandProperty(AccessLevel.GameMaster, AccessLevel.Administrator)] - public int History { get; set; } - - [CommandProperty(AccessLevel.GameMaster, AccessLevel.Administrator)] - public Mobile Steed { get; set; } - - [CommandProperty(AccessLevel.GameMaster, AccessLevel.Administrator)] - public Mobile Familiar { get; set; } - - [CommandProperty(AccessLevel.GameMaster)] - public bool IsShielded - { - get - { - if (m_Shield == DateTime.MinValue) - { - return false; - } - - if (Core.Now < m_Shield + TimeSpan.FromHours(1.0)) - { - return true; - } - - FinishShield(); return false; } + + if (Core.Now < _shield + TimeSpan.FromHours(1.0)) + { + return true; + } + + FinishShield(); + return false; } + } - public static Player Find(Mobile mob) => Find(mob, false); + public static Player Find(Mobile mob) => Find(mob, false); - public static Player Find(Mobile mob, bool inherit) + public static Player Find(Mobile mob, bool inherit) + { + var pm = mob as PlayerMobile; + + if (pm == null) { - var pm = mob as PlayerMobile; + if (inherit && mob is BaseCreature bc) + { + pm = bc.GetMaster() as PlayerMobile; + } if (pm == null) { - if (inherit && mob is BaseCreature bc) - { - if (bc.Controlled) - { - pm = bc.ControlMaster as PlayerMobile; - } - else if (bc.Summoned) - { - pm = bc.SummonMaster as PlayerMobile; - } - } - - if (pm == null) - { - return null; - } - } - - var pl = pm.EthicPlayer; - - if (pl?.Ethic.IsEligible(pl.Mobile) == false) - { - pm.EthicPlayer = pl = null; - } - - return pl; - } - - public void BeginShield() => m_Shield = Core.Now; - - public void FinishShield() => m_Shield = DateTime.MinValue; - - public void CheckAttach() - { - if (Ethic.IsEligible(Mobile)) - { - Attach(); + return null; } } - public void Attach() - { - if (Mobile is PlayerMobile mobile) - { - mobile.EthicPlayer = this; - } + var pl = pm.EthicPlayer; - Ethic.Players.Add(this); + if (pl?.Ethic.IsEligible(pl.Mobile) == false) + { + pm.EthicPlayer = pl = null; } - public void Detach() + return pl; + } + + public void BeginShield() => _shield = Core.Now; + + public void FinishShield() => _shield = DateTime.MinValue; + + public void CheckAttach() + { + if (Ethic.IsEligible(Mobile)) { - if (Mobile is PlayerMobile mobile) - { - mobile.EthicPlayer = null; - } - - Ethic.Players.Remove(this); - } - - public void Serialize(IGenericWriter writer) - { - writer.WriteEncodedInt(0); // version - - writer.Write(Mobile); - - writer.WriteEncodedInt(Power); - writer.WriteEncodedInt(History); - - writer.Write(Steed); - writer.Write(Familiar); - - writer.WriteDeltaTime(m_Shield); + Attach(); } } + + public void Attach() + { + if (Mobile is PlayerMobile mobile) + { + mobile.EthicPlayer = this; + } + + Ethic.Players.Add(this); + } + + public void Detach() + { + if (Mobile is PlayerMobile mobile) + { + mobile.EthicPlayer = null; + } + + Ethic.Players.Remove(this); + } } diff --git a/Projects/UOContent/Engines/Ethics/Core/Power.cs b/Projects/UOContent/Engines/Ethics/Core/Power.cs index 2c695c4bc..00d045fdc 100644 --- a/Projects/UOContent/Engines/Ethics/Core/Power.cs +++ b/Projects/UOContent/Engines/Ethics/Core/Power.cs @@ -1,37 +1,31 @@ -namespace Server.Ethics +namespace Server.Ethics; + +public abstract class Power { - public abstract class Power + public PowerDefinition Definition { get; protected set; } + + public virtual bool CheckInvoke(Player from) { - protected PowerDefinition m_Definition; - - public PowerDefinition Definition => m_Definition; - - public virtual bool CheckInvoke(Player from) + if (!from.Mobile.CheckAlive()) { - if (!from.Mobile.CheckAlive()) - { - return false; - } - - if (from.Power < m_Definition.Power) - { - from.Mobile.LocalOverheadMessage( - MessageType.Regular, - 0x3B2, - false, - "You lack the power to invoke this ability." - ); - return false; - } - - return true; + return false; } - public abstract void BeginInvoke(Player from); - - public virtual void FinishInvoke(Player from) + if (from.Power < Definition.Power) { - from.Power -= m_Definition.Power; + from.Mobile.LocalOverheadMessage( + MessageType.Regular, + 0x3B2, + false, + "You lack the power to invoke this ability." + ); + return false; } + + return true; } + + public abstract void BeginInvoke(Player from); + + public virtual void FinishInvoke(Player from) => from.Power -= Definition.Power; } diff --git a/Projects/UOContent/Engines/Ethics/Definitions/EthicDefinition.cs b/Projects/UOContent/Engines/Ethics/Definitions/EthicDefinition.cs index ab183cafd..b29f56544 100644 --- a/Projects/UOContent/Engines/Ethics/Definitions/EthicDefinition.cs +++ b/Projects/UOContent/Engines/Ethics/Definitions/EthicDefinition.cs @@ -1,30 +1,29 @@ -namespace Server.Ethics +namespace Server.Ethics; + +public class EthicDefinition { - public class EthicDefinition + public EthicDefinition( + int primaryHue, TextDefinition title, TextDefinition adjunct, TextDefinition joinPhrase, + Power[] powers + ) { - public EthicDefinition( - int primaryHue, TextDefinition title, TextDefinition adjunct, TextDefinition joinPhrase, - Power[] powers - ) - { - PrimaryHue = primaryHue; + PrimaryHue = primaryHue; - Title = title; - Adjunct = adjunct; + Title = title; + Adjunct = adjunct; - JoinPhrase = joinPhrase; + JoinPhrase = joinPhrase; - Powers = powers; - } - - public int PrimaryHue { get; } - - public TextDefinition Title { get; } - - public TextDefinition Adjunct { get; } - - public TextDefinition JoinPhrase { get; } - - public Power[] Powers { get; } + Powers = powers; } + + public int PrimaryHue { get; } + + public TextDefinition Title { get; } + + public TextDefinition Adjunct { get; } + + public TextDefinition JoinPhrase { get; } + + public Power[] Powers { get; } } diff --git a/Projects/UOContent/Engines/Ethics/Definitions/PowerDefinition.cs b/Projects/UOContent/Engines/Ethics/Definitions/PowerDefinition.cs index 81a698d39..13a709e6d 100644 --- a/Projects/UOContent/Engines/Ethics/Definitions/PowerDefinition.cs +++ b/Projects/UOContent/Engines/Ethics/Definitions/PowerDefinition.cs @@ -1,22 +1,21 @@ -namespace Server.Ethics +namespace Server.Ethics; + +public class PowerDefinition { - public class PowerDefinition + public PowerDefinition(int power, TextDefinition name, TextDefinition phrase, TextDefinition description) { - public PowerDefinition(int power, TextDefinition name, TextDefinition phrase, TextDefinition description) - { - Power = power; + Power = power; - Name = name; - Phrase = phrase; - Description = description; - } - - public int Power { get; } - - public TextDefinition Name { get; } - - public TextDefinition Phrase { get; } - - public TextDefinition Description { get; } + Name = name; + Phrase = phrase; + Description = description; } -} + + public int Power { get; } + + public TextDefinition Name { get; } + + public TextDefinition Phrase { get; } + + public TextDefinition Description { get; } +} \ No newline at end of file diff --git a/Projects/UOContent/Engines/Ethics/Evil/Ethic.cs b/Projects/UOContent/Engines/Ethics/Evil/Ethic.cs index 211cfa42a..470844e5a 100644 --- a/Projects/UOContent/Engines/Ethics/Evil/Ethic.cs +++ b/Projects/UOContent/Engines/Ethics/Evil/Ethic.cs @@ -1,35 +1,44 @@ +using ModernUO.Serialization; using Server.Factions; -namespace Server.Ethics.Evil +namespace Server.Ethics.Evil; + +[SerializationGenerator(0, false)] +public sealed partial class EvilEthic : Ethic { - public sealed class EvilEthic : Ethic + public override EthicDefinition Definition => new( + 0x455, + "Evil", + "(Evil)", + "I am evil incarnate", + [ + new UnholySense(), + new UnholyItem(), + new SummonFamiliar(), + new VileBlade(), + new Blight(), + new UnholyShield(), + new UnholySteed(), + new UnholyWord() + ] + ); + + public EvilEthic() { - public EvilEthic() + if (!RegisterEthic(this)) { - m_Definition = new EthicDefinition( - 0x455, - "Evil", - "(Evil)", - "I am evil incarnate", - new Power[] - { - new UnholySense(), - new UnholyItem(), - new SummonFamiliar(), - new VileBlade(), - new Blight(), - new UnholyShield(), - new UnholySteed(), - new UnholyWord() - } - ); + Delete(); } + } - public override bool IsEligible(Mobile mob) + public override bool IsEligible(Mobile mob) => Faction.Find(mob) is Minax or Shadowlords; + + [AfterDeserialization] + private void AfterDeserialization() + { + if (!RegisterEthic(this)) { - var fac = Faction.Find(mob); - - return fac is Minax or Shadowlords; + Delete(); } } } diff --git a/Projects/UOContent/Engines/Ethics/Evil/Mobiles/UnholySteed.cs b/Projects/UOContent/Engines/Ethics/Evil/Mobiles/UnholySteed.cs index cbcfb8130..9c8360e66 100644 --- a/Projects/UOContent/Engines/Ethics/Evil/Mobiles/UnholySteed.cs +++ b/Projects/UOContent/Engines/Ethics/Evil/Mobiles/UnholySteed.cs @@ -1,92 +1,75 @@ +using ModernUO.Serialization; using Server.Ethics; -namespace Server.Mobiles +namespace Server.Mobiles; + +[SerializationGenerator(0, false)] +public partial class UnholySteed : BaseMount { - public class UnholySteed : BaseMount + public override string DefaultName => "a dark steed"; + + [Constructible] + public UnholySteed() : base(0x74, 0x3EA7, AIType.AI_Melee, FightMode.Aggressor) { - public override string DefaultName => "a dark steed"; + SetStr(496, 525); + SetDex(86, 105); + SetInt(86, 125); - [Constructible] - public UnholySteed() : base(0x74, 0x3EA7, AIType.AI_Melee, FightMode.Aggressor) + SetHits(298, 315); + + SetDamage(16, 22); + + SetDamageType(ResistanceType.Physical, 40); + SetDamageType(ResistanceType.Fire, 40); + SetDamageType(ResistanceType.Energy, 20); + + SetResistance(ResistanceType.Physical, 55, 65); + SetResistance(ResistanceType.Fire, 30, 40); + SetResistance(ResistanceType.Cold, 30, 40); + SetResistance(ResistanceType.Poison, 30, 40); + SetResistance(ResistanceType.Energy, 20, 30); + + SetSkill(SkillName.MagicResist, 25.1, 30.0); + SetSkill(SkillName.Tactics, 97.6, 100.0); + SetSkill(SkillName.Wrestling, 80.5, 92.5); + + Fame = 14000; + Karma = -14000; + + VirtualArmor = 60; + + Tamable = false; + ControlSlots = 1; + } + + public override int StepsMax => 6400; + public override string CorpseName => "an unholy corpse"; + public override bool IsDispellable => false; + public override bool IsBondable => false; + public override FoodType FavoriteFood => FoodType.FruitsAndVeggies | FoodType.GrainsAndHay; + + private static MonsterAbility[] _abilities = { MonsterAbilities.FireBreath }; + public override MonsterAbility[] GetMonsterAbilities() => _abilities; + + public override string ApplyNameSuffix(string suffix) + { + if (suffix.Length == 0) { - SetStr(496, 525); - SetDex(86, 105); - SetInt(86, 125); - - SetHits(298, 315); - - SetDamage(16, 22); - - SetDamageType(ResistanceType.Physical, 40); - SetDamageType(ResistanceType.Fire, 40); - SetDamageType(ResistanceType.Energy, 20); - - SetResistance(ResistanceType.Physical, 55, 65); - SetResistance(ResistanceType.Fire, 30, 40); - SetResistance(ResistanceType.Cold, 30, 40); - SetResistance(ResistanceType.Poison, 30, 40); - SetResistance(ResistanceType.Energy, 20, 30); - - SetSkill(SkillName.MagicResist, 25.1, 30.0); - SetSkill(SkillName.Tactics, 97.6, 100.0); - SetSkill(SkillName.Wrestling, 80.5, 92.5); - - Fame = 14000; - Karma = -14000; - - VirtualArmor = 60; - - Tamable = false; - ControlSlots = 1; + return base.ApplyNameSuffix(Ethic.Evil.Definition.Adjunct.String); } - public UnholySteed(Serial serial) : base(serial) + return base.ApplyNameSuffix($"{suffix} {Ethic.Evil.Definition.Adjunct.String}"); + } + + public override void OnDoubleClick(Mobile from) + { + if (Ethic.Find(from) != Ethic.Evil) { + from.SendMessage("You may not ride this steed."); } - - public override int StepsMax => 6400; - public override string CorpseName => "an unholy corpse"; - public override bool IsDispellable => false; - public override bool IsBondable => false; - public override FoodType FavoriteFood => FoodType.FruitsAndVeggies | FoodType.GrainsAndHay; - - private static MonsterAbility[] _abilities = { MonsterAbilities.FireBreath }; - public override MonsterAbility[] GetMonsterAbilities() => _abilities; - - public override string ApplyNameSuffix(string suffix) + else { - if (suffix.Length == 0) - { - return base.ApplyNameSuffix(Ethic.Evil.Definition.Adjunct.String); - } - - return base.ApplyNameSuffix($"{suffix} {Ethic.Evil.Definition.Adjunct.String}"); - } - - public override void OnDoubleClick(Mobile from) - { - if (Ethic.Find(from) != Ethic.Evil) - { - from.SendMessage("You may not ride this steed."); - } - else - { - base.OnDoubleClick(from); - } - } - - public override void Serialize(IGenericWriter writer) - { - base.Serialize(writer); - - writer.Write(0); // version - } - - public override void Deserialize(IGenericReader reader) - { - base.Deserialize(reader); - - var version = reader.ReadInt(); + base.OnDoubleClick(from); } } } diff --git a/Projects/UOContent/Engines/Ethics/Evil/Powers/Blight.cs b/Projects/UOContent/Engines/Ethics/Evil/Powers/Blight.cs index b8b17670e..fa540ebef 100644 --- a/Projects/UOContent/Engines/Ethics/Evil/Powers/Blight.cs +++ b/Projects/UOContent/Engines/Ethics/Evil/Powers/Blight.cs @@ -2,82 +2,81 @@ using System; using Server.Spells; using Server.Targeting; -namespace Server.Ethics.Evil -{ - public sealed class Blight : Power - { - public Blight() => - m_Definition = new PowerDefinition( - 15, - "Blight", - "Velgo Ontawl", - "" - ); +namespace Server.Ethics.Evil; - public override void BeginInvoke(Player from) +public sealed class Blight : Power +{ + public Blight() => + Definition = new PowerDefinition( + 15, + "Blight", + "Velgo Ontawl", + "" + ); + + public override void BeginInvoke(Player from) + { + from.Mobile.BeginTarget(12, true, TargetFlags.None, Power_OnTarget, from); + from.Mobile.SendMessage("Where do you wish to blight?"); + } + + private void Power_OnTarget(Mobile fromMobile, object obj, Player from) + { + if (obj is not IPoint3D p) { - from.Mobile.BeginTarget(12, true, TargetFlags.None, Power_OnTarget, from); - from.Mobile.SendMessage("Where do you wish to blight?"); + return; } - private void Power_OnTarget(Mobile fromMobile, object obj, Player from) + if (!CheckInvoke(from)) { - if (obj is not IPoint3D p) + return; + } + + var powerFunctioned = false; + + SpellHelper.GetSurfaceTop(ref p); + + foreach (var mob in from.Mobile.GetMobilesInRange(6)) + { + if (mob == from.Mobile || !SpellHelper.ValidIndirectTarget(from.Mobile, mob)) { - return; + continue; } - if (!CheckInvoke(from)) + if (mob.GetStatMod("Holy Curse") != null) { - return; + continue; } - var powerFunctioned = false; - - SpellHelper.GetSurfaceTop(ref p); - - foreach (var mob in from.Mobile.GetMobilesInRange(6)) + if (!from.Mobile.CanBeHarmful(mob, false)) { - if (mob == from.Mobile || !SpellHelper.ValidIndirectTarget(from.Mobile, mob)) - { - continue; - } - - if (mob.GetStatMod("Holy Curse") != null) - { - continue; - } - - if (!from.Mobile.CanBeHarmful(mob, false)) - { - continue; - } - - from.Mobile.DoHarmful(mob, true); - - mob.AddStatMod(new StatMod(StatType.All, "Holy Curse", -10, TimeSpan.FromMinutes(30.0))); - - mob.FixedParticles(0x374A, 10, 15, 5028, EffectLayer.Waist); - mob.PlaySound(0x1FB); - - powerFunctioned = true; + continue; } - if (powerFunctioned) - { - SpellHelper.Turn(from.Mobile, p); + from.Mobile.DoHarmful(mob, true); - Effects.PlaySound(new Point3D(p), from.Mobile.Map, 0x1FB); + mob.AddStatMod(new StatMod(StatType.All, "Holy Curse", -10, TimeSpan.FromMinutes(30.0))); - from.Mobile.LocalOverheadMessage(MessageType.Regular, 0x3B2, false, "You curse the area."); + mob.FixedParticles(0x374A, 10, 15, 5028, EffectLayer.Waist); + mob.PlaySound(0x1FB); - FinishInvoke(from); - } - else - { - from.Mobile.FixedEffect(0x3735, 6, 30); - from.Mobile.PlaySound(0x5C); - } + powerFunctioned = true; + } + + if (powerFunctioned) + { + SpellHelper.Turn(from.Mobile, p); + + Effects.PlaySound(new Point3D(p), from.Mobile.Map, 0x1FB); + + from.Mobile.LocalOverheadMessage(MessageType.Regular, 0x3B2, false, "You curse the area."); + + FinishInvoke(from); + } + else + { + from.Mobile.FixedEffect(0x3735, 6, 30); + from.Mobile.PlaySound(0x5C); } } -} +} \ No newline at end of file diff --git a/Projects/UOContent/Engines/Ethics/Evil/Powers/SummonFamiliar.cs b/Projects/UOContent/Engines/Ethics/Evil/Powers/SummonFamiliar.cs index aa6f3ee25..02e25405c 100644 --- a/Projects/UOContent/Engines/Ethics/Evil/Powers/SummonFamiliar.cs +++ b/Projects/UOContent/Engines/Ethics/Evil/Powers/SummonFamiliar.cs @@ -1,45 +1,44 @@ using System; using Server.Mobiles; -namespace Server.Ethics.Evil +namespace Server.Ethics.Evil; + +public sealed class SummonFamiliar : Power { - public sealed class SummonFamiliar : Power + public SummonFamiliar() => + Definition = new PowerDefinition( + 5, + "Summon Familiar", + "Trubechs Vingir", + "" + ); + + public override void BeginInvoke(Player from) { - public SummonFamiliar() => - m_Definition = new PowerDefinition( - 5, - "Summon Familiar", - "Trubechs Vingir", - "" - ); - - public override void BeginInvoke(Player from) + if (from.Familiar?.Deleted == true) { - if (from.Familiar?.Deleted == true) - { - from.Familiar = null; - } + from.Familiar = null; + } - if (from.Familiar != null) - { - from.Mobile.LocalOverheadMessage(MessageType.Regular, 0x3B2, false, "You already have an unholy familiar."); - return; - } + if (from.Familiar != null) + { + from.Mobile.LocalOverheadMessage(MessageType.Regular, 0x3B2, false, "You already have an unholy familiar."); + return; + } - if (from.Mobile.Followers + 1 > from.Mobile.FollowersMax) - { - from.Mobile.SendLocalizedMessage(1049645); // You have too many followers to summon that creature. - return; - } + if (from.Mobile.Followers + 1 > from.Mobile.FollowersMax) + { + from.Mobile.SendLocalizedMessage(1049645); // You have too many followers to summon that creature. + return; + } - var familiar = new UnholyFamiliar(); + var familiar = new UnholyFamiliar(); - if (BaseCreature.Summon(familiar, from.Mobile, from.Mobile.Location, 0x217, TimeSpan.FromHours(1.0))) - { - from.Familiar = familiar; + if (BaseCreature.Summon(familiar, from.Mobile, from.Mobile.Location, 0x217, TimeSpan.FromHours(1.0))) + { + from.Familiar = familiar; - FinishInvoke(from); - } + FinishInvoke(from); } } -} +} \ No newline at end of file diff --git a/Projects/UOContent/Engines/Ethics/Evil/Powers/UnholyItem.cs b/Projects/UOContent/Engines/Ethics/Evil/Powers/UnholyItem.cs index 70e803394..09b399d9d 100644 --- a/Projects/UOContent/Engines/Ethics/Evil/Powers/UnholyItem.cs +++ b/Projects/UOContent/Engines/Ethics/Evil/Powers/UnholyItem.cs @@ -1,71 +1,70 @@ using Server.Items; using Server.Targeting; -namespace Server.Ethics.Evil -{ - public sealed class UnholyItem : Power - { - public UnholyItem() => - m_Definition = new PowerDefinition( - 5, - "Unholy Item", - "Vidda K'balc", - "" - ); +namespace Server.Ethics.Evil; - public override void BeginInvoke(Player from) +public sealed class UnholyItem : Power +{ + public UnholyItem() => + Definition = new PowerDefinition( + 5, + "Unholy Item", + "Vidda K'balc", + "" + ); + + public override void BeginInvoke(Player from) + { + from.Mobile.BeginTarget(12, false, TargetFlags.None, Power_OnTarget, from); + from.Mobile.SendMessage("Which item do you wish to imbue?"); + } + + private void Power_OnTarget(Mobile fromMobile, object obj, Player from) + { + if (obj is not Item item) { - from.Mobile.BeginTarget(12, false, TargetFlags.None, Power_OnTarget, from); - from.Mobile.SendMessage("Which item do you wish to imbue?"); + from.Mobile.LocalOverheadMessage(MessageType.Regular, 0x3B2, false, "You may not imbue that."); + return; } - private void Power_OnTarget(Mobile fromMobile, object obj, Player from) + if (item.Parent != from.Mobile) { - if (obj is not Item item) + from.Mobile.LocalOverheadMessage( + MessageType.Regular, + 0x3B2, + false, + "You may only imbue items you are wearing." + ); + return; + } + + if ((item.SavedFlags & 0x300) != 0) + { + from.Mobile.LocalOverheadMessage(MessageType.Regular, 0x3B2, false, "That has already been imbued."); + return; + } + + var canImbue = item is Spellbook or BaseClothing or BaseArmor or BaseWeapon && + item.Name == null; + + if (canImbue) + { + if (!CheckInvoke(from)) { - from.Mobile.LocalOverheadMessage(MessageType.Regular, 0x3B2, false, "You may not imbue that."); return; } - if (item.Parent != from.Mobile) - { - from.Mobile.LocalOverheadMessage( - MessageType.Regular, - 0x3B2, - false, - "You may only imbue items you are wearing." - ); - return; - } + item.Hue = Ethic.Evil.Definition.PrimaryHue; + item.SavedFlags |= 0x200; - if ((item.SavedFlags & 0x300) != 0) - { - from.Mobile.LocalOverheadMessage(MessageType.Regular, 0x3B2, false, "That has already been imbued."); - return; - } + from.Mobile.FixedEffect(0x375A, 10, 20); + from.Mobile.PlaySound(0x209); - var canImbue = item is Spellbook or BaseClothing or BaseArmor or BaseWeapon && - item.Name == null; - - if (canImbue) - { - if (!CheckInvoke(from)) - { - return; - } - - item.Hue = Ethic.Evil.Definition.PrimaryHue; - item.SavedFlags |= 0x200; - - from.Mobile.FixedEffect(0x375A, 10, 20); - from.Mobile.PlaySound(0x209); - - FinishInvoke(from); - } - else - { - from.Mobile.LocalOverheadMessage(MessageType.Regular, 0x3B2, false, "You may not imbue that."); - } + FinishInvoke(from); + } + else + { + from.Mobile.LocalOverheadMessage(MessageType.Regular, 0x3B2, false, "You may not imbue that."); } } -} +} \ No newline at end of file diff --git a/Projects/UOContent/Engines/Ethics/Evil/Powers/UnholySense.cs b/Projects/UOContent/Engines/Ethics/Evil/Powers/UnholySense.cs index ac884d950..56cfc3f84 100644 --- a/Projects/UOContent/Engines/Ethics/Evil/Powers/UnholySense.cs +++ b/Projects/UOContent/Engines/Ethics/Evil/Powers/UnholySense.cs @@ -1,97 +1,76 @@ using System; using Server.Text; -namespace Server.Ethics.Evil +namespace Server.Ethics.Evil; + +public sealed class UnholySense : Power { - public sealed class UnholySense : Power + public UnholySense() => + Definition = new PowerDefinition( + 0, + "Unholy Sense", + "Drewrok Velgo", + "" + ); + + public override void BeginInvoke(Player from) { - public UnholySense() => - m_Definition = new PowerDefinition( - 0, - "Unholy Sense", - "Drewrok Velgo", - "" - ); + var opposition = Ethic.Hero; - public override void BeginInvoke(Player from) + var enemyCount = 0; + + var maxRange = 18 + from.Power; + + Player primary = null; + + foreach (var pl in opposition.Players) { - var opposition = Ethic.Hero; + var mob = pl.Mobile; - var enemyCount = 0; - - var maxRange = 18 + from.Power; - - Player primary = null; - - foreach (var pl in opposition.Players) + if (mob == null || mob.Map != from.Mobile.Map || !mob.Alive) { - var mob = pl.Mobile; - - if (mob == null || mob.Map != from.Mobile.Map || !mob.Alive) - { - continue; - } - - if (!mob.InRange(from.Mobile, Math.Max(18, maxRange - pl.Power))) - { - continue; - } - - if (primary == null || pl.Power > primary.Power) - { - primary = pl; - } - - ++enemyCount; + continue; } - using var sb = ValueStringBuilder.Create(); - - sb.Append("You sense "); - sb.Append(enemyCount == 0 ? "no" : enemyCount.ToString()); - sb.Append(enemyCount == 1 ? " enemy" : " enemies"); - - if (primary != null) + if (!mob.InRange(from.Mobile, Math.Max(18, maxRange - pl.Power))) { - sb.Append(", and a strong presence"); - - switch (from.Mobile.GetDirectionTo(primary.Mobile)) - { - case Direction.West: - sb.Append(" to the west."); - break; - case Direction.East: - sb.Append(" to the east."); - break; - case Direction.North: - sb.Append(" to the north."); - break; - case Direction.South: - sb.Append(" to the south."); - break; - - case Direction.Up: - sb.Append(" to the north-west."); - break; - case Direction.Down: - sb.Append(" to the south-east."); - break; - case Direction.Left: - sb.Append(" to the south-west."); - break; - case Direction.Right: - sb.Append(" to the north-east."); - break; - } - } - else - { - sb.Append('.'); + continue; } - from.Mobile.LocalOverheadMessage(MessageType.Regular, 0x59, false, sb.ToString()); + if (primary == null || pl.Power > primary.Power) + { + primary = pl; + } - FinishInvoke(from); + ++enemyCount; } + + using var sb = ValueStringBuilder.Create(); + sb.Append($"You sense {(enemyCount == 0 ? "no" : enemyCount.ToString())} {(enemyCount == 1 ? "enemy" : "enemies")}"); + + if (primary != null) + { + var direction = from.Mobile.GetDirectionTo(primary.Mobile) switch + { + Direction.East => "east", + Direction.North => "north", + Direction.South => "south", + Direction.Up => "north-west", + Direction.Down => "south-east", + Direction.Left => "south-west", + Direction.Right => "north-east", + _ => "west" + }; + + sb.Append($", and a strong presence to the {direction}."); + } + else + { + sb.Append('.'); + } + + from.Mobile.LocalOverheadMessage(MessageType.Regular, 0x59, false, sb.ToString()); + + FinishInvoke(from); } } diff --git a/Projects/UOContent/Engines/Ethics/Evil/Powers/UnholyShield.cs b/Projects/UOContent/Engines/Ethics/Evil/Powers/UnholyShield.cs index 7aec50d7d..2ea27bd99 100644 --- a/Projects/UOContent/Engines/Ethics/Evil/Powers/UnholyShield.cs +++ b/Projects/UOContent/Engines/Ethics/Evil/Powers/UnholyShield.cs @@ -1,38 +1,37 @@ -namespace Server.Ethics.Evil +namespace Server.Ethics.Evil; + +public sealed class UnholyShield : Power { - public sealed class UnholyShield : Power + public UnholyShield() => + Definition = new PowerDefinition( + 20, + "Unholy Shield", + "Velgo K'blac", + "" + ); + + public override void BeginInvoke(Player from) { - public UnholyShield() => - m_Definition = new PowerDefinition( - 20, - "Unholy Shield", - "Velgo K'blac", - "" - ); - - public override void BeginInvoke(Player from) + if (from.IsShielded) { - if (from.IsShielded) - { - from.Mobile.LocalOverheadMessage( - MessageType.Regular, - 0x3B2, - false, - "You are already under the protection of an unholy shield." - ); - return; - } - - from.BeginShield(); - from.Mobile.LocalOverheadMessage( MessageType.Regular, 0x3B2, false, - "You are now under the protection of an unholy shield." + "You are already under the protection of an unholy shield." ); - - FinishInvoke(from); + return; } + + from.BeginShield(); + + from.Mobile.LocalOverheadMessage( + MessageType.Regular, + 0x3B2, + false, + "You are now under the protection of an unholy shield." + ); + + FinishInvoke(from); } -} +} \ No newline at end of file diff --git a/Projects/UOContent/Engines/Ethics/Evil/Powers/UnholySteed.cs b/Projects/UOContent/Engines/Ethics/Evil/Powers/UnholySteed.cs index fda8a44dc..9bf4e3e5c 100644 --- a/Projects/UOContent/Engines/Ethics/Evil/Powers/UnholySteed.cs +++ b/Projects/UOContent/Engines/Ethics/Evil/Powers/UnholySteed.cs @@ -1,45 +1,44 @@ using System; using Server.Mobiles; -namespace Server.Ethics.Evil +namespace Server.Ethics.Evil; + +public sealed class UnholySteed : Power { - public sealed class UnholySteed : Power + public UnholySteed() => + Definition = new PowerDefinition( + 30, + "Unholy Steed", + "Trubechs Yeliab", + "" + ); + + public override void BeginInvoke(Player from) { - public UnholySteed() => - m_Definition = new PowerDefinition( - 30, - "Unholy Steed", - "Trubechs Yeliab", - "" - ); - - public override void BeginInvoke(Player from) + if (from.Steed?.Deleted == true) { - if (from.Steed?.Deleted == true) - { - from.Steed = null; - } + from.Steed = null; + } - if (from.Steed != null) - { - from.Mobile.LocalOverheadMessage(MessageType.Regular, 0x3B2, false, "You already have an unholy steed."); - return; - } + if (from.Steed != null) + { + from.Mobile.LocalOverheadMessage(MessageType.Regular, 0x3B2, false, "You already have an unholy steed."); + return; + } - if (from.Mobile.Followers + 1 > from.Mobile.FollowersMax) - { - from.Mobile.SendLocalizedMessage(1049645); // You have too many followers to summon that creature. - return; - } + if (from.Mobile.Followers + 1 > from.Mobile.FollowersMax) + { + from.Mobile.SendLocalizedMessage(1049645); // You have too many followers to summon that creature. + return; + } - var steed = new Mobiles.UnholySteed(); + var steed = new Mobiles.UnholySteed(); - if (BaseCreature.Summon(steed, from.Mobile, from.Mobile.Location, 0x217, TimeSpan.FromHours(1.0))) - { - from.Steed = steed; + if (BaseCreature.Summon(steed, from.Mobile, from.Mobile.Location, 0x217, TimeSpan.FromHours(1.0))) + { + from.Steed = steed; - FinishInvoke(from); - } + FinishInvoke(from); } } -} +} \ No newline at end of file diff --git a/Projects/UOContent/Engines/Ethics/Evil/Powers/UnholyWord.cs b/Projects/UOContent/Engines/Ethics/Evil/Powers/UnholyWord.cs index 881880c48..33539e91f 100644 --- a/Projects/UOContent/Engines/Ethics/Evil/Powers/UnholyWord.cs +++ b/Projects/UOContent/Engines/Ethics/Evil/Powers/UnholyWord.cs @@ -1,17 +1,16 @@ -namespace Server.Ethics.Evil -{ - public sealed class UnholyWord : Power - { - public UnholyWord() => - m_Definition = new PowerDefinition( - 100, - "Unholy Word", - "Velgo Oostrac", - "" - ); +namespace Server.Ethics.Evil; - public override void BeginInvoke(Player from) - { - } +public sealed class UnholyWord : Power +{ + public UnholyWord() => + Definition = new PowerDefinition( + 100, + "Unholy Word", + "Velgo Oostrac", + "" + ); + + public override void BeginInvoke(Player from) + { } -} +} \ No newline at end of file diff --git a/Projects/UOContent/Engines/Ethics/Evil/Powers/VileBlade.cs b/Projects/UOContent/Engines/Ethics/Evil/Powers/VileBlade.cs index fa0a180d2..f7325ffc5 100644 --- a/Projects/UOContent/Engines/Ethics/Evil/Powers/VileBlade.cs +++ b/Projects/UOContent/Engines/Ethics/Evil/Powers/VileBlade.cs @@ -1,17 +1,16 @@ -namespace Server.Ethics.Evil -{ - public sealed class VileBlade : Power - { - public VileBlade() => - m_Definition = new PowerDefinition( - 10, - "Vile Blade", - "Velgo Reyam", - "" - ); +namespace Server.Ethics.Evil; - public override void BeginInvoke(Player from) - { - } +public sealed class VileBlade : Power +{ + public VileBlade() => + Definition = new PowerDefinition( + 10, + "Vile Blade", + "Velgo Reyam", + "" + ); + + public override void BeginInvoke(Player from) + { } -} +} \ No newline at end of file diff --git a/Projects/UOContent/Engines/Ethics/Hero/Ethic.cs b/Projects/UOContent/Engines/Ethics/Hero/Ethic.cs index e473b00d9..df7a8ec8e 100644 --- a/Projects/UOContent/Engines/Ethics/Hero/Ethic.cs +++ b/Projects/UOContent/Engines/Ethics/Hero/Ethic.cs @@ -1,40 +1,44 @@ +using ModernUO.Serialization; using Server.Factions; -namespace Server.Ethics.Hero +namespace Server.Ethics.Hero; + +[SerializationGenerator(0, false)] +public sealed partial class HeroEthic : Ethic { - public sealed class HeroEthic : Ethic + public override EthicDefinition Definition => new( + 0x482, + "Hero", + "(Hero)", + "I will defend the virtues", + [ + new HolySense(), + new HolyItem(), + new SummonFamiliar(), + new HolyBlade(), + new Bless(), + new HolyShield(), + new HolySteed(), + new HolyWord() + ] + ); + + public HeroEthic() { - public HeroEthic() + if (!RegisterEthic(this)) { - m_Definition = new EthicDefinition( - 0x482, - "Hero", - "(Hero)", - "I will defend the virtues", - new Power[] - { - new HolySense(), - new HolyItem(), - new SummonFamiliar(), - new HolyBlade(), - new Bless(), - new HolyShield(), - new HolySteed(), - new HolyWord() - } - ); + Delete(); } + } - public override bool IsEligible(Mobile mob) + public override bool IsEligible(Mobile mob) => mob.Kills < 5 && Faction.Find(mob) is TrueBritannians or CouncilOfMages; + + [AfterDeserialization] + private void AfterDeserialization() + { + if (!RegisterEthic(this)) { - if (mob.Kills >= 5) - { - return false; - } - - var fac = Faction.Find(mob); - - return fac is TrueBritannians or CouncilOfMages; + Delete(); } } } diff --git a/Projects/UOContent/Engines/Ethics/Hero/Mobiles/HolySteed.cs b/Projects/UOContent/Engines/Ethics/Hero/Mobiles/HolySteed.cs index 38c305a16..7bb0eab5c 100644 --- a/Projects/UOContent/Engines/Ethics/Hero/Mobiles/HolySteed.cs +++ b/Projects/UOContent/Engines/Ethics/Hero/Mobiles/HolySteed.cs @@ -1,91 +1,75 @@ +using ModernUO.Serialization; using Server.Ethics; -namespace Server.Mobiles +namespace Server.Mobiles; + +[SerializationGenerator(0, false)] +public partial class HolySteed : BaseMount { - public class HolySteed : BaseMount + public override string DefaultName => "a silver steed"; + + [Constructible] + public HolySteed() : base(0x75, 0x3EA8, AIType.AI_Melee, FightMode.Aggressor) { - public override string DefaultName => "a silver steed"; - [Constructible] - public HolySteed() : base(0x75, 0x3EA8, AIType.AI_Melee, FightMode.Aggressor) + SetStr(496, 525); + SetDex(86, 105); + SetInt(86, 125); + + SetHits(298, 315); + + SetDamage(16, 22); + + SetDamageType(ResistanceType.Physical, 40); + SetDamageType(ResistanceType.Fire, 40); + SetDamageType(ResistanceType.Energy, 20); + + SetResistance(ResistanceType.Physical, 55, 65); + SetResistance(ResistanceType.Fire, 30, 40); + SetResistance(ResistanceType.Cold, 30, 40); + SetResistance(ResistanceType.Poison, 30, 40); + SetResistance(ResistanceType.Energy, 20, 30); + + SetSkill(SkillName.MagicResist, 25.1, 30.0); + SetSkill(SkillName.Tactics, 97.6, 100.0); + SetSkill(SkillName.Wrestling, 80.5, 92.5); + + Fame = 14000; + Karma = 14000; + + VirtualArmor = 60; + + Tamable = false; + ControlSlots = 1; + } + + public override int StepsMax => 6400; + public override string CorpseName => "a holy corpse"; + public override bool IsDispellable => false; + public override bool IsBondable => false; + public override FoodType FavoriteFood => FoodType.FruitsAndVeggies | FoodType.GrainsAndHay; + + private static MonsterAbility[] _abilities = [MonsterAbilities.FireBreath]; + public override MonsterAbility[] GetMonsterAbilities() => _abilities; + + public override string ApplyNameSuffix(string suffix) + { + if (suffix.Length == 0) { - SetStr(496, 525); - SetDex(86, 105); - SetInt(86, 125); - - SetHits(298, 315); - - SetDamage(16, 22); - - SetDamageType(ResistanceType.Physical, 40); - SetDamageType(ResistanceType.Fire, 40); - SetDamageType(ResistanceType.Energy, 20); - - SetResistance(ResistanceType.Physical, 55, 65); - SetResistance(ResistanceType.Fire, 30, 40); - SetResistance(ResistanceType.Cold, 30, 40); - SetResistance(ResistanceType.Poison, 30, 40); - SetResistance(ResistanceType.Energy, 20, 30); - - SetSkill(SkillName.MagicResist, 25.1, 30.0); - SetSkill(SkillName.Tactics, 97.6, 100.0); - SetSkill(SkillName.Wrestling, 80.5, 92.5); - - Fame = 14000; - Karma = 14000; - - VirtualArmor = 60; - - Tamable = false; - ControlSlots = 1; + return base.ApplyNameSuffix(Ethic.Hero.Definition.Adjunct.String); } - public HolySteed(Serial serial) : base(serial) + return base.ApplyNameSuffix($"{suffix} {Ethic.Hero.Definition.Adjunct.String}"); + } + + public override void OnDoubleClick(Mobile from) + { + if (Ethic.Find(from) != Ethic.Hero) { + from.SendMessage("You may not ride this steed."); } - - public override int StepsMax => 6400; - public override string CorpseName => "a holy corpse"; - public override bool IsDispellable => false; - public override bool IsBondable => false; - public override FoodType FavoriteFood => FoodType.FruitsAndVeggies | FoodType.GrainsAndHay; - - private static MonsterAbility[] _abilities = { MonsterAbilities.FireBreath }; - public override MonsterAbility[] GetMonsterAbilities() => _abilities; - - public override string ApplyNameSuffix(string suffix) + else { - if (suffix.Length == 0) - { - return base.ApplyNameSuffix(Ethic.Hero.Definition.Adjunct.String); - } - - return base.ApplyNameSuffix($"{suffix} {Ethic.Hero.Definition.Adjunct.String}"); - } - - public override void OnDoubleClick(Mobile from) - { - if (Ethic.Find(from) != Ethic.Hero) - { - from.SendMessage("You may not ride this steed."); - } - else - { - base.OnDoubleClick(from); - } - } - - public override void Serialize(IGenericWriter writer) - { - base.Serialize(writer); - - writer.Write(0); // version - } - - public override void Deserialize(IGenericReader reader) - { - base.Deserialize(reader); - - var version = reader.ReadInt(); + base.OnDoubleClick(from); } } } diff --git a/Projects/UOContent/Engines/Ethics/Hero/Powers/Bless.cs b/Projects/UOContent/Engines/Ethics/Hero/Powers/Bless.cs index 848a053d4..12c128406 100644 --- a/Projects/UOContent/Engines/Ethics/Hero/Powers/Bless.cs +++ b/Projects/UOContent/Engines/Ethics/Hero/Powers/Bless.cs @@ -2,82 +2,81 @@ using System; using Server.Spells; using Server.Targeting; -namespace Server.Ethics.Hero -{ - public sealed class Bless : Power - { - public Bless() => - m_Definition = new PowerDefinition( - 15, - "Bless", - "Erstok Ontawl", - "" - ); +namespace Server.Ethics.Hero; - public override void BeginInvoke(Player from) +public sealed class Bless : Power +{ + public Bless() => + Definition = new PowerDefinition( + 15, + "Bless", + "Erstok Ontawl", + "" + ); + + public override void BeginInvoke(Player from) + { + from.Mobile.BeginTarget(12, true, TargetFlags.None, Power_OnTarget, from); + from.Mobile.SendMessage("Where do you wish to bless?"); + } + + private void Power_OnTarget(Mobile fromMobile, object obj, Player from) + { + if (obj is not IPoint3D p) { - from.Mobile.BeginTarget(12, true, TargetFlags.None, Power_OnTarget, from); - from.Mobile.SendMessage("Where do you wish to bless?"); + return; } - private void Power_OnTarget(Mobile fromMobile, object obj, Player from) + if (!CheckInvoke(from)) { - if (obj is not IPoint3D p) + return; + } + + var powerFunctioned = false; + + SpellHelper.GetSurfaceTop(ref p); + + foreach (var mob in from.Mobile.GetMobilesInRange(6)) + { + if (mob != from.Mobile && SpellHelper.ValidIndirectTarget(from.Mobile, mob)) { - return; + continue; } - if (!CheckInvoke(from)) + if (mob.GetStatMod("Holy Bless") != null) { - return; + continue; } - var powerFunctioned = false; - - SpellHelper.GetSurfaceTop(ref p); - - foreach (var mob in from.Mobile.GetMobilesInRange(6)) + if (!from.Mobile.CanBeBeneficial(mob, false)) { - if (mob != from.Mobile && SpellHelper.ValidIndirectTarget(from.Mobile, mob)) - { - continue; - } - - if (mob.GetStatMod("Holy Bless") != null) - { - continue; - } - - if (!from.Mobile.CanBeBeneficial(mob, false)) - { - continue; - } - - from.Mobile.DoBeneficial(mob); - - mob.AddStatMod(new StatMod(StatType.All, "Holy Bless", 10, TimeSpan.FromMinutes(30.0))); - - mob.FixedParticles(0x373A, 10, 15, 5018, EffectLayer.Waist); - mob.PlaySound(0x1EA); - - powerFunctioned = true; + continue; } - if (powerFunctioned) - { - SpellHelper.Turn(from.Mobile, p); + from.Mobile.DoBeneficial(mob); - Effects.PlaySound(new Point3D(p), from.Mobile.Map, 0x299); + mob.AddStatMod(new StatMod(StatType.All, "Holy Bless", 10, TimeSpan.FromMinutes(30.0))); - from.Mobile.LocalOverheadMessage(MessageType.Regular, 0x3B2, false, "You consecrate the area."); + mob.FixedParticles(0x373A, 10, 15, 5018, EffectLayer.Waist); + mob.PlaySound(0x1EA); - FinishInvoke(from); - } - else - { - from.Mobile.FixedEffect(0x3735, 6, 30); - from.Mobile.PlaySound(0x5C); - } + powerFunctioned = true; + } + + if (powerFunctioned) + { + SpellHelper.Turn(from.Mobile, p); + + Effects.PlaySound(new Point3D(p), from.Mobile.Map, 0x299); + + from.Mobile.LocalOverheadMessage(MessageType.Regular, 0x3B2, false, "You consecrate the area."); + + FinishInvoke(from); + } + else + { + from.Mobile.FixedEffect(0x3735, 6, 30); + from.Mobile.PlaySound(0x5C); } } } diff --git a/Projects/UOContent/Engines/Ethics/Hero/Powers/HolyBlade.cs b/Projects/UOContent/Engines/Ethics/Hero/Powers/HolyBlade.cs index 72820862e..da7223a41 100644 --- a/Projects/UOContent/Engines/Ethics/Hero/Powers/HolyBlade.cs +++ b/Projects/UOContent/Engines/Ethics/Hero/Powers/HolyBlade.cs @@ -1,17 +1,16 @@ -namespace Server.Ethics.Hero -{ - public sealed class HolyBlade : Power - { - public HolyBlade() => - m_Definition = new PowerDefinition( - 10, - "Holy Blade", - "Erstok Reyam", - "" - ); +namespace Server.Ethics.Hero; - public override void BeginInvoke(Player from) - { - } +public sealed class HolyBlade : Power +{ + public HolyBlade() => + Definition = new PowerDefinition( + 10, + "Holy Blade", + "Erstok Reyam", + "" + ); + + public override void BeginInvoke(Player from) + { } -} +} \ No newline at end of file diff --git a/Projects/UOContent/Engines/Ethics/Hero/Powers/HolyItem.cs b/Projects/UOContent/Engines/Ethics/Hero/Powers/HolyItem.cs index 908d505fb..fc9cc601a 100644 --- a/Projects/UOContent/Engines/Ethics/Hero/Powers/HolyItem.cs +++ b/Projects/UOContent/Engines/Ethics/Hero/Powers/HolyItem.cs @@ -1,71 +1,70 @@ using Server.Items; using Server.Targeting; -namespace Server.Ethics.Hero -{ - public sealed class HolyItem : Power - { - public HolyItem() => - m_Definition = new PowerDefinition( - 5, - "Holy Item", - "Vidda K'balc", - "" - ); +namespace Server.Ethics.Hero; - public override void BeginInvoke(Player from) +public sealed class HolyItem : Power +{ + public HolyItem() => + Definition = new PowerDefinition( + 5, + "Holy Item", + "Vidda K'balc", + "" + ); + + public override void BeginInvoke(Player from) + { + from.Mobile.BeginTarget(12, false, TargetFlags.None, Power_OnTarget, from); + from.Mobile.SendMessage("Which item do you wish to imbue?"); + } + + private void Power_OnTarget(Mobile fromMobile, object obj, Player from) + { + if (obj is not Item item) { - from.Mobile.BeginTarget(12, false, TargetFlags.None, Power_OnTarget, from); - from.Mobile.SendMessage("Which item do you wish to imbue?"); + from.Mobile.LocalOverheadMessage(MessageType.Regular, 0x3B2, false, "You may not imbue that."); + return; } - private void Power_OnTarget(Mobile fromMobile, object obj, Player from) + if (item.Parent != from.Mobile) { - if (obj is not Item item) + from.Mobile.LocalOverheadMessage( + MessageType.Regular, + 0x3B2, + false, + "You may only imbue items you are wearing." + ); + return; + } + + if ((item.SavedFlags & 0x300) != 0) + { + from.Mobile.LocalOverheadMessage(MessageType.Regular, 0x3B2, false, "That has already beem imbued."); + return; + } + + var canImbue = item is Spellbook or BaseClothing or BaseArmor or BaseWeapon && + item.Name == null; + + if (canImbue) + { + if (!CheckInvoke(from)) { - from.Mobile.LocalOverheadMessage(MessageType.Regular, 0x3B2, false, "You may not imbue that."); return; } - if (item.Parent != from.Mobile) - { - from.Mobile.LocalOverheadMessage( - MessageType.Regular, - 0x3B2, - false, - "You may only imbue items you are wearing." - ); - return; - } + item.Hue = Ethic.Hero.Definition.PrimaryHue; + item.SavedFlags |= 0x100; - if ((item.SavedFlags & 0x300) != 0) - { - from.Mobile.LocalOverheadMessage(MessageType.Regular, 0x3B2, false, "That has already beem imbued."); - return; - } + from.Mobile.FixedEffect(0x375A, 10, 20); + from.Mobile.PlaySound(0x209); - var canImbue = item is Spellbook or BaseClothing or BaseArmor or BaseWeapon && - item.Name == null; - - if (canImbue) - { - if (!CheckInvoke(from)) - { - return; - } - - item.Hue = Ethic.Hero.Definition.PrimaryHue; - item.SavedFlags |= 0x100; - - from.Mobile.FixedEffect(0x375A, 10, 20); - from.Mobile.PlaySound(0x209); - - FinishInvoke(from); - } - else - { - from.Mobile.LocalOverheadMessage(MessageType.Regular, 0x3B2, false, "You may not imbue that."); - } + FinishInvoke(from); + } + else + { + from.Mobile.LocalOverheadMessage(MessageType.Regular, 0x3B2, false, "You may not imbue that."); } } -} +} \ No newline at end of file diff --git a/Projects/UOContent/Engines/Ethics/Hero/Powers/HolySense.cs b/Projects/UOContent/Engines/Ethics/Hero/Powers/HolySense.cs index ee16f60ca..b6bcea48e 100644 --- a/Projects/UOContent/Engines/Ethics/Hero/Powers/HolySense.cs +++ b/Projects/UOContent/Engines/Ethics/Hero/Powers/HolySense.cs @@ -1,97 +1,76 @@ using System; using Server.Text; -namespace Server.Ethics.Hero +namespace Server.Ethics.Hero; + +public sealed class HolySense : Power { - public sealed class HolySense : Power + public HolySense() => + Definition = new PowerDefinition( + 0, + "Holy Sense", + "Drewrok Erstok", + "" + ); + + public override void BeginInvoke(Player from) { - public HolySense() => - m_Definition = new PowerDefinition( - 0, - "Holy Sense", - "Drewrok Erstok", - "" - ); + var opposition = Ethic.Evil; - public override void BeginInvoke(Player from) + var enemyCount = 0; + + var maxRange = 18 + from.Power; + + Player primary = null; + + foreach (var pl in opposition.Players) { - var opposition = Ethic.Evil; + var mob = pl.Mobile; - var enemyCount = 0; - - var maxRange = 18 + from.Power; - - Player primary = null; - - foreach (var pl in opposition.Players) + if (mob == null || mob.Map != from.Mobile.Map || !mob.Alive) { - var mob = pl.Mobile; - - if (mob == null || mob.Map != from.Mobile.Map || !mob.Alive) - { - continue; - } - - if (!mob.InRange(from.Mobile, Math.Max(18, maxRange - pl.Power))) - { - continue; - } - - if (primary == null || pl.Power > primary.Power) - { - primary = pl; - } - - ++enemyCount; + continue; } - using var sb = ValueStringBuilder.Create(); - - sb.Append("You sense "); - sb.Append(enemyCount == 0 ? "no" : enemyCount.ToString()); - sb.Append(enemyCount == 1 ? " enemy" : " enemies"); - - if (primary != null) + if (!mob.InRange(from.Mobile, Math.Max(18, maxRange - pl.Power))) { - sb.Append(", and a strong presence"); - - switch (from.Mobile.GetDirectionTo(primary.Mobile)) - { - case Direction.West: - sb.Append(" to the west."); - break; - case Direction.East: - sb.Append(" to the east."); - break; - case Direction.North: - sb.Append(" to the north."); - break; - case Direction.South: - sb.Append(" to the south."); - break; - - case Direction.Up: - sb.Append(" to the north-west."); - break; - case Direction.Down: - sb.Append(" to the south-east."); - break; - case Direction.Left: - sb.Append(" to the south-west."); - break; - case Direction.Right: - sb.Append(" to the north-east."); - break; - } - } - else - { - sb.Append('.'); + continue; } - from.Mobile.LocalOverheadMessage(MessageType.Regular, 0x59, false, sb.ToString()); + if (primary == null || pl.Power > primary.Power) + { + primary = pl; + } - FinishInvoke(from); + ++enemyCount; } + + using var sb = ValueStringBuilder.Create(); + sb.Append($"You sense {(enemyCount == 0 ? "no" : enemyCount.ToString())} {(enemyCount == 1 ? "enemy" : "enemies")}"); + + if (primary != null) + { + var direction = from.Mobile.GetDirectionTo(primary.Mobile) switch + { + Direction.East => "east", + Direction.North => "north", + Direction.South => "south", + Direction.Up => "north-west", + Direction.Down => "south-east", + Direction.Left => "south-west", + Direction.Right => "north-east", + _ => "west" + }; + + sb.Append($", and a strong presence to the {direction}."); + } + else + { + sb.Append('.'); + } + + from.Mobile.LocalOverheadMessage(MessageType.Regular, 0x59, false, sb.ToString()); + + FinishInvoke(from); } } diff --git a/Projects/UOContent/Engines/Ethics/Hero/Powers/HolyShield.cs b/Projects/UOContent/Engines/Ethics/Hero/Powers/HolyShield.cs index 1095b4e92..7c2821c93 100644 --- a/Projects/UOContent/Engines/Ethics/Hero/Powers/HolyShield.cs +++ b/Projects/UOContent/Engines/Ethics/Hero/Powers/HolyShield.cs @@ -1,38 +1,37 @@ -namespace Server.Ethics.Hero +namespace Server.Ethics.Hero; + +public sealed class HolyShield : Power { - public sealed class HolyShield : Power + public HolyShield() => + Definition = new PowerDefinition( + 20, + "Holy Shield", + "Erstok K'blac", + "" + ); + + public override void BeginInvoke(Player from) { - public HolyShield() => - m_Definition = new PowerDefinition( - 20, - "Holy Shield", - "Erstok K'blac", - "" - ); - - public override void BeginInvoke(Player from) + if (from.IsShielded) { - if (from.IsShielded) - { - from.Mobile.LocalOverheadMessage( - MessageType.Regular, - 0x3B2, - false, - "You are already under the protection of a holy shield." - ); - return; - } - - from.BeginShield(); - from.Mobile.LocalOverheadMessage( MessageType.Regular, 0x3B2, false, - "You are now under the protection of a holy shield." + "You are already under the protection of a holy shield." ); - - FinishInvoke(from); + return; } + + from.BeginShield(); + + from.Mobile.LocalOverheadMessage( + MessageType.Regular, + 0x3B2, + false, + "You are now under the protection of a holy shield." + ); + + FinishInvoke(from); } -} +} \ No newline at end of file diff --git a/Projects/UOContent/Engines/Ethics/Hero/Powers/HolySteed.cs b/Projects/UOContent/Engines/Ethics/Hero/Powers/HolySteed.cs index 3dbd96e0c..886007c62 100644 --- a/Projects/UOContent/Engines/Ethics/Hero/Powers/HolySteed.cs +++ b/Projects/UOContent/Engines/Ethics/Hero/Powers/HolySteed.cs @@ -1,45 +1,44 @@ using System; using Server.Mobiles; -namespace Server.Ethics.Hero +namespace Server.Ethics.Hero; + +public sealed class HolySteed : Power { - public sealed class HolySteed : Power + public HolySteed() => + Definition = new PowerDefinition( + 30, + "Holy Steed", + "Trubechs Yeliab", + "" + ); + + public override void BeginInvoke(Player from) { - public HolySteed() => - m_Definition = new PowerDefinition( - 30, - "Holy Steed", - "Trubechs Yeliab", - "" - ); - - public override void BeginInvoke(Player from) + if (from.Steed?.Deleted == true) { - if (from.Steed?.Deleted == true) - { - from.Steed = null; - } + from.Steed = null; + } - if (from.Steed != null) - { - from.Mobile.LocalOverheadMessage(MessageType.Regular, 0x3B2, false, "You already have a holy steed."); - return; - } + if (from.Steed != null) + { + from.Mobile.LocalOverheadMessage(MessageType.Regular, 0x3B2, false, "You already have a holy steed."); + return; + } - if (from.Mobile.Followers + 1 > from.Mobile.FollowersMax) - { - from.Mobile.SendLocalizedMessage(1049645); // You have too many followers to summon that creature. - return; - } + if (from.Mobile.Followers + 1 > from.Mobile.FollowersMax) + { + from.Mobile.SendLocalizedMessage(1049645); // You have too many followers to summon that creature. + return; + } - var steed = new Mobiles.HolySteed(); + var steed = new Mobiles.HolySteed(); - if (BaseCreature.Summon(steed, from.Mobile, from.Mobile.Location, 0x217, TimeSpan.FromHours(1.0))) - { - from.Steed = steed; + if (BaseCreature.Summon(steed, from.Mobile, from.Mobile.Location, 0x217, TimeSpan.FromHours(1.0))) + { + from.Steed = steed; - FinishInvoke(from); - } + FinishInvoke(from); } } -} +} \ No newline at end of file diff --git a/Projects/UOContent/Engines/Ethics/Hero/Powers/HolyWord.cs b/Projects/UOContent/Engines/Ethics/Hero/Powers/HolyWord.cs index 0cace0ef4..be34d3583 100644 --- a/Projects/UOContent/Engines/Ethics/Hero/Powers/HolyWord.cs +++ b/Projects/UOContent/Engines/Ethics/Hero/Powers/HolyWord.cs @@ -1,17 +1,16 @@ -namespace Server.Ethics.Hero -{ - public sealed class HolyWord : Power - { - public HolyWord() => - m_Definition = new PowerDefinition( - 100, - "Holy Word", - "Erstok Oostrac", - "" - ); +namespace Server.Ethics.Hero; - public override void BeginInvoke(Player from) - { - } +public sealed class HolyWord : Power +{ + public HolyWord() => + Definition = new PowerDefinition( + 100, + "Holy Word", + "Erstok Oostrac", + "" + ); + + public override void BeginInvoke(Player from) + { } -} +} \ No newline at end of file diff --git a/Projects/UOContent/Engines/Ethics/Hero/Powers/SummonFamiliar.cs b/Projects/UOContent/Engines/Ethics/Hero/Powers/SummonFamiliar.cs index c63c59c35..3bcef40b0 100644 --- a/Projects/UOContent/Engines/Ethics/Hero/Powers/SummonFamiliar.cs +++ b/Projects/UOContent/Engines/Ethics/Hero/Powers/SummonFamiliar.cs @@ -1,45 +1,44 @@ using System; using Server.Mobiles; -namespace Server.Ethics.Hero +namespace Server.Ethics.Hero; + +public sealed class SummonFamiliar : Power { - public sealed class SummonFamiliar : Power + public SummonFamiliar() => + Definition = new PowerDefinition( + 5, + "Summon Familiar", + "Trubechs Vingir", + "" + ); + + public override void BeginInvoke(Player from) { - public SummonFamiliar() => - m_Definition = new PowerDefinition( - 5, - "Summon Familiar", - "Trubechs Vingir", - "" - ); - - public override void BeginInvoke(Player from) + if (from.Familiar?.Deleted == true) { - if (from.Familiar?.Deleted == true) - { - from.Familiar = null; - } + from.Familiar = null; + } - if (from.Familiar != null) - { - from.Mobile.LocalOverheadMessage(MessageType.Regular, 0x3B2, false, "You already have a holy familiar."); - return; - } + if (from.Familiar != null) + { + from.Mobile.LocalOverheadMessage(MessageType.Regular, 0x3B2, false, "You already have a holy familiar."); + return; + } - if (from.Mobile.Followers + 1 > from.Mobile.FollowersMax) - { - from.Mobile.SendLocalizedMessage(1049645); // You have too many followers to summon that creature. - return; - } + if (from.Mobile.Followers + 1 > from.Mobile.FollowersMax) + { + from.Mobile.SendLocalizedMessage(1049645); // You have too many followers to summon that creature. + return; + } - var familiar = new HolyFamiliar(); + var familiar = new HolyFamiliar(); - if (BaseCreature.Summon(familiar, from.Mobile, from.Mobile.Location, 0x217, TimeSpan.FromHours(1.0))) - { - from.Familiar = familiar; + if (BaseCreature.Summon(familiar, from.Mobile, from.Mobile.Location, 0x217, TimeSpan.FromHours(1.0))) + { + from.Familiar = familiar; - FinishInvoke(from); - } + FinishInvoke(from); } } -} +} \ No newline at end of file diff --git a/Projects/UOContent/Engines/Factions/Core/FactionSystem.cs b/Projects/UOContent/Engines/Factions/Core/FactionSystem.cs index 04ea15734..d1da9557b 100644 --- a/Projects/UOContent/Engines/Factions/Core/FactionSystem.cs +++ b/Projects/UOContent/Engines/Factions/Core/FactionSystem.cs @@ -120,5 +120,7 @@ public class FactionPersistence : Item new TownState(reader); } } + + Timer.DelayCall(Delete); } } diff --git a/Projects/UOContent/Migrations/Server.Ethics.Ethic.v1.json b/Projects/UOContent/Migrations/Server.Ethics.Ethic.v1.json new file mode 100644 index 000000000..9cf29af5c --- /dev/null +++ b/Projects/UOContent/Migrations/Server.Ethics.Ethic.v1.json @@ -0,0 +1,4 @@ +{ + "version": 1, + "type": "Server.Ethics.Ethic" +} \ No newline at end of file diff --git a/Projects/UOContent/Migrations/Server.Ethics.EthicsEntity.v0.json b/Projects/UOContent/Migrations/Server.Ethics.EthicsEntity.v0.json new file mode 100644 index 000000000..302c010d4 --- /dev/null +++ b/Projects/UOContent/Migrations/Server.Ethics.EthicsEntity.v0.json @@ -0,0 +1,4 @@ +{ + "version": 0, + "type": "Server.Ethics.EthicsEntity" +} \ No newline at end of file diff --git a/Projects/UOContent/Migrations/Server.Ethics.Evil.EvilEthic.v0.json b/Projects/UOContent/Migrations/Server.Ethics.Evil.EvilEthic.v0.json new file mode 100644 index 000000000..d6b195a75 --- /dev/null +++ b/Projects/UOContent/Migrations/Server.Ethics.Evil.EvilEthic.v0.json @@ -0,0 +1,4 @@ +{ + "version": 0, + "type": "Server.Ethics.Evil.EvilEthic" +} \ No newline at end of file diff --git a/Projects/UOContent/Migrations/Server.Ethics.Hero.HeroEthic.v0.json b/Projects/UOContent/Migrations/Server.Ethics.Hero.HeroEthic.v0.json new file mode 100644 index 000000000..d3d89cc46 --- /dev/null +++ b/Projects/UOContent/Migrations/Server.Ethics.Hero.HeroEthic.v0.json @@ -0,0 +1,4 @@ +{ + "version": 0, + "type": "Server.Ethics.Hero.HeroEthic" +} \ No newline at end of file diff --git a/Projects/UOContent/Migrations/Server.Ethics.Player.v1.json b/Projects/UOContent/Migrations/Server.Ethics.Player.v1.json new file mode 100644 index 000000000..09109dc0b --- /dev/null +++ b/Projects/UOContent/Migrations/Server.Ethics.Player.v1.json @@ -0,0 +1,50 @@ +{ + "version": 1, + "type": "Server.Ethics.Player", + "properties": [ + { + "name": "Mobile", + "type": "Server.Mobile", + "rule": "SerializableInterfaceMigrationRule" + }, + { + "name": "Power", + "type": "int", + "rule": "PrimitiveTypeMigrationRule", + "ruleArguments": [ + "" + ] + }, + { + "name": "History", + "type": "int", + "rule": "PrimitiveTypeMigrationRule", + "ruleArguments": [ + "" + ] + }, + { + "name": "Steed", + "type": "Server.Mobile", + "rule": "SerializableInterfaceMigrationRule" + }, + { + "name": "Familiar", + "type": "Server.Mobile", + "rule": "SerializableInterfaceMigrationRule" + }, + { + "name": "Shield", + "type": "System.DateTime", + "rule": "PrimitiveTypeMigrationRule", + "ruleArguments": [ + "DeltaTime" + ] + }, + { + "name": "Ethic", + "type": "Server.Ethics.Ethic", + "rule": "SerializableInterfaceMigrationRule" + } + ] +} \ No newline at end of file diff --git a/Projects/UOContent/Migrations/Server.Mobiles.HolySteed.v0.json b/Projects/UOContent/Migrations/Server.Mobiles.HolySteed.v0.json new file mode 100644 index 000000000..5e16b9bc3 --- /dev/null +++ b/Projects/UOContent/Migrations/Server.Mobiles.HolySteed.v0.json @@ -0,0 +1,4 @@ +{ + "version": 0, + "type": "Server.Mobiles.HolySteed" +} \ No newline at end of file diff --git a/Projects/UOContent/Migrations/Server.Mobiles.UnholySteed.v0.json b/Projects/UOContent/Migrations/Server.Mobiles.UnholySteed.v0.json new file mode 100644 index 000000000..a17288b53 --- /dev/null +++ b/Projects/UOContent/Migrations/Server.Mobiles.UnholySteed.v0.json @@ -0,0 +1,4 @@ +{ + "version": 0, + "type": "Server.Mobiles.UnholySteed" +} \ No newline at end of file