private void AddElement(Armor a, SpellElement e, List <SpellElement> elements)
 {
     a.ElementalResist |= (byte)e;
     elements.Remove(e);
     allElements.Remove(e);
 }
        private void EnsureFullProtectionForClass(List <Armor> armors, KeyValuePair <EquipPermission, List <Armor> > cls)
        {
            //No armors equippable
            if (cls.Value.Count == 0)
            {
                return;
            }

            List <SpellElement> elements = new List <SpellElement> {
                SpellElement.Fire, SpellElement.Lightning, SpellElement.Ice, SpellElement.Earth, SpellElement.Poison, SpellElement.Time, SpellElement.Death, SpellElement.Status
            };

            List <Armor> rares = cls.Value.Where(a => rareArmors.Contains(a.Id)).ToList();

            var existingResists = cls.Value.Where(a => a.ElementalResist > 0).ToList();

            (var complete, var a1, var a2) = CheckForCompleteProtection(existingResists);

            if (complete)
            {
                return;
            }

            //prefer a rare or legendary armor for a1
            if (a1 == null)
            {
                if (rares.Count > 0)
                {
                    a1 = rares.PickRandom(rng);
                }
                else
                {
                    a1 = cls.Value.PickRandom(rng);
                }
            }

            //second armor of different type
            if (a2 == null)
            {
                var a2rares      = cls.Value.Where(a => a.Type != a1.Type && rareArmors.Contains(a.Id)).ToList();
                var a2candidates = cls.Value.Where(a => a.Type != a1.Type).ToList();
                if (a2rares.Count > 0)
                {
                    a2 = a2rares.PickRandom(rng);
                }
                else if (a2candidates.Count > 0)
                {
                    a2 = a2candidates.PickRandom(rng);
                }
            }

            //third armor of different type
            Armor a3 = null;

            if (a2 != null)
            {
                var a3rares      = cls.Value.Where(a => a.Type != a1.Type && a.Type != a2.Type && rareArmors.Contains(a.Id)).ToList();
                var a3candidates = cls.Value.Where(a => a.Type != a1.Type && a.Type != a2.Type).ToList();
                if (a3rares.Count > 0)
                {
                    a3 = a3rares.PickRandom(rng);
                }
                else if (a3candidates.Count > 0)
                {
                    a3 = a3candidates.PickRandom(rng);
                }
            }

            var resist = (a1?.ElementalResist ?? 0) | (a2?.ElementalResist ?? 0) | (a3?.ElementalResist ?? 0);

            if ((resist & (byte)SpellElement.Fire) > 0)
            {
                elements.Remove(SpellElement.Fire);
            }
            if ((resist & (byte)SpellElement.Lightning) > 0)
            {
                elements.Remove(SpellElement.Lightning);
            }
            if ((resist & (byte)SpellElement.Ice) > 0)
            {
                elements.Remove(SpellElement.Ice);
            }
            if ((resist & (byte)SpellElement.Earth) > 0)
            {
                elements.Remove(SpellElement.Earth);
            }
            if ((resist & (byte)SpellElement.Poison) > 0)
            {
                elements.Remove(SpellElement.Poison);
            }
            if ((resist & (byte)SpellElement.Time) > 0)
            {
                elements.Remove(SpellElement.Time);
            }
            if ((resist & (byte)SpellElement.Death) > 0)
            {
                elements.Remove(SpellElement.Death);
            }
            if ((resist & (byte)SpellElement.Status) > 0)
            {
                elements.Remove(SpellElement.Status);
            }

            if (a1 != null && elements.Contains(SpellElement.Status))
            {
                AddElement(a1, SpellElement.Status, elements);
            }

            if (a1 != null && elements.Count > 0 && GetScore(a1.ElementalResist) < 6)
            {
                AddRandomElement(a1, elements);
            }
            if (a1 != null && elements.Count > 0 && GetScore(a1.ElementalResist) < 6)
            {
                AddRandomElement(a1, elements);
            }
            if (a1 != null && elements.Count > 0 && GetScore(a1.ElementalResist) < 6)
            {
                AddRandomElement(a1, elements);
            }

            if (a2 != null && elements.Count > 0 && GetScore(a2.ElementalResist) < 6)
            {
                AddRandomElement(a2, elements);
            }
            if (a2 != null && elements.Count > 0 && GetScore(a2.ElementalResist) < 6)
            {
                AddRandomElement(a2, elements);
            }
            if (a2 != null && elements.Count > 0 && GetScore(a2.ElementalResist) < 6)
            {
                AddRandomElement(a2, elements);
            }

            if (a3 != null && elements.Count > 0)
            {
                AddRandomElement(a3, elements);
            }
            if (a3 != null && elements.Count > 0)
            {
                AddRandomElement(a3, elements);
            }
            if (a3 != null && elements.Count > 0)
            {
                AddRandomElement(a3, elements);
            }
            if (a3 != null && elements.Count > 0)
            {
                AddRandomElement(a3, elements);
            }

            if (a1 != null && a2 == null && elements.Count > 0)
            {
                if (elements.Contains(SpellElement.Death))
                {
                    AddElement(a2, SpellElement.Death, elements);
                }
                else
                {
                    AddRandomElement(a2, elements);
                }
            }

            if (a2 != null && a3 == null && elements.Count > 0)
            {
                if (elements.Contains(SpellElement.Death))
                {
                    AddElement(a2, SpellElement.Death, elements);
                }
            }
        }