using Server.Ethics.Evil; using Server.Ethics.Hero; using Server.Items; using Server.Mobiles; namespace Server.Ethics { public abstract class Ethic { public static readonly Ethic Hero = new HeroEthic(); public static readonly Ethic Evil = new EvilEthic(); public static readonly Ethic[] Ethics = { 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) { 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) { var itemEthic = Find(item); if (itemEthic == null || Find(from) == itemEthic) { 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); 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)) { 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 eable = e.Mobile.GetItemsInRange(2); var found = false; foreach (var item in eable) { if (item is AnkhNorth || item is AnkhWest) { found = true; break; } } eable.Free(); 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; } } else { if (e.Mobile is PlayerMobile mobile && mobile.DuelContext != null) { return; } var ethic = pl.Ethic; 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; } } } 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) { 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); } } } }