using System; using System.Collections.Generic; using System.Linq; using Server; using Server.Misc; using Server.Mobiles; namespace Server.Items { public interface IEpiphanyArmor { Alignment Alignment { get; } SurgeType Type { get; } int Frequency { get; } int Bonus { get; } } public static class EpiphanyHelper { public static Dictionary> Table { get; set; } public static readonly int MinTriggerDamage = 15; // TODO: Amount? public static int GetFrequency(Mobile m, IEpiphanyArmor armor) { if(m == null) return 1; return Math.Max(1, Math.Min(5, m.Items.Where(i => i is IEpiphanyArmor && ((IEpiphanyArmor)i).Alignment == armor.Alignment && ((IEpiphanyArmor)i).Type == armor.Type).Count())); } public static int GetBonus(Mobile m, IEpiphanyArmor armor) { if(m == null) return 0; switch(armor.Alignment) { default: return 0; case Alignment.Good: if(m.Karma <= 0) return 0; return Math.Min(20, m.Karma / (Titles.MaxKarma / 20)); case Alignment.Evil: if(m.Karma >= 0) return 0; return Math.Min(20, -m.Karma / (Titles.MaxKarma / 20)); } } public static void OnHit(Mobile m, int damage) { if(damage > MinTriggerDamage) { CheckHit(m, damage, SurgeType.Hits); CheckHit(m, damage, SurgeType.Stam); CheckHit(m, damage, SurgeType.Mana); } } public static void CheckHit(Mobile m, int damage, SurgeType type) { var item = m.Items.OfType().FirstOrDefault(i => ((IEpiphanyArmor)i).Type == type); if(item == null) return; if(Table == null) { Table = new Dictionary>(); } if(!Table.ContainsKey(m)) { Table[m] = new Dictionary(); } if (!Table[m].ContainsKey(type)) { Table[m][type] = damage; } else { damage += Table[m][type]; } int freq = GetFrequency(m, item); int bonus = GetBonus(m, item); if(freq > 0 && bonus > 0 && damage > Utility.Random(10000 / freq)) { Table[m].Remove(type); if(Table[m].Count == 0) Table.Remove(m); switch(type) { case SurgeType.Hits: m.Hits = Math.Min(m.HitsMax, m.Hits + bonus); break; case SurgeType.Stam: m.Hits = Math.Min(m.HitsMax, m.Hits + bonus); break; default: case SurgeType.Mana: m.Hits = Math.Min(m.HitsMax, m.Hits + bonus); break; } } else { Table[m][type] = damage; } } public static void OnKarmaChange(Mobile m) { foreach (var item in m.Items.Where(i => i is IEpiphanyArmor)) { item.InvalidateProperties(); } } public static void AddProperties(IEpiphanyArmor item, ObjectPropertyList list) { if(item == null) return; switch(item.Type) { case SurgeType.Hits: list.Add(1150830 + (int)item.Alignment + 1); // Set Ability: good healing burst break; case SurgeType.Stam: // NOTE: This doesn't exist on EA, but put it in here anyways! list.Add(1149953, String.Format("{0}\t{1}", "Set Ability", item.Alignment == Alignment.Evil ? "evil stamina burst" : "good stamina burst")); break; default: case SurgeType.Mana: list.Add(1150240 + (int)item.Alignment); // Set Ability: evil mana burst break; } if (item is Item) { list.Add(1150240, GetFrequency(((Item)item).Parent as Mobile, item).ToString()); // Set Bonus: Frequency ~1_val~ list.Add(1150243, GetBonus(((Item)item).Parent as Mobile, item).ToString()); // Karma Bonus: Burst level ~1_val~ } } } }