public void CanEquipQL50StoreBoughtEyeImplantAfterEquippingIntelligenceImplant()
        {
            var eye  = Implant.GetImplant(ImplantSlot.Eye, Skill.Tutoring, Skill.PsychoModi, Skill.TimeAndSpace, 50);
            var head = Implant.GetImplant(ImplantSlot.Head, Ability.Intelligence, null, null, 20);

            Assert.IsTrue(_character.TryEquipImplant(head));
            Assert.IsTrue(_character.TryEquipImplant(eye));
        }
        public void EquipMaxImplantUnequipsFirst()
        {
            _character.SetAbilityValue(Ability.Agility, 300); // Max sure it's not the limiting factor.
            var lowHead  = Implant.GetImplant(ImplantSlot.Head, Skill.Treatment, null, Ability.Sense, 20);
            var maxHead1 = _character.GetMaxImplant(lowHead.ImplantTemplate);

            _character.SetImplant(lowHead);
            var maxHead2            = _character.GetMaxImplant(lowHead.ImplantTemplate);
            var impossibleHotswapQL = Implant.GetMaxImplantQL(_character.GetAbilityValue(Ability.Agility), _character.TreatmentValue);

            Assert.AreEqual(maxHead1.QL, maxHead2.QL);
            Assert.IsTrue(impossibleHotswapQL > maxHead1.QL);
        }
        public void GetsTotalTreatmentIncrease()
        {
            var leftHand = Implant.GetImplant(ImplantSlot.LeftHand, Skill.FastAttack, ArmorClass.FireAC, Skill.MartialArts, 155);

            Assert.AreEqual(0, leftHand.TotalTreatmentIncrease);

            var head1 = Implant.GetImplant(ImplantSlot.Head, Skill.Treatment, null, Ability.Sense, 200);

            Assert.AreEqual(106.1, head1.TotalTreatmentIncrease);

            var head2 = Implant.GetImplant(ImplantSlot.Head, Ability.Intelligence, null, Ability.Sense, 200);

            Assert.AreEqual(7.975, head2.TotalTreatmentIncrease);
        }
        public void VerifiesAbilityAndTreatmentRequirements()
        {
            var leftHand = Implant.GetImplant(ImplantSlot.LeftHand, Skill.FastAttack, ArmorClass.FireAC, Skill.MartialArts, 155);

            Assert.AreEqual(Ability.Agility, leftHand.RequiredAbility);
            Assert.AreEqual(314, leftHand.RequiredAbilityValue);
            Assert.AreEqual(738, leftHand.RequiredTreatmentValue);

            var feet = Implant.GetImplant(ImplantSlot.Feet, Skill.EvadeClsC, Skill.MartialArts, Skill.DuckExp, 144);

            Assert.AreEqual(Ability.Agility, feet.RequiredAbility);
            Assert.AreEqual(292, feet.RequiredAbilityValue);
            Assert.AreEqual(686, feet.RequiredTreatmentValue);

            var eye = Implant.GetImplant(ImplantSlot.Eye, Skill.AimedShot, Skill.SensoryImpr, Skill.SharpObj, 132);

            Assert.AreEqual(Ability.Agility, eye.RequiredAbility);
            Assert.AreEqual(268, eye.RequiredAbilityValue);
            Assert.AreEqual(630, eye.RequiredTreatmentValue);
        }
        public void SetImplantIgnoresRequirementsButUnequipsFirst()
        {
            var lowHead  = Implant.GetImplant(ImplantSlot.Head, Skill.Treatment, null, Ability.Sense, 20);
            var highHead = Implant.GetImplant(ImplantSlot.Head, Skill.Treatment, null, Ability.Sense, 200);

            Assert.IsTrue(_character.TryEquipImplant(lowHead));
            Assert.IsFalse(_character.TryEquipImplant(highHead));
            Assert.AreEqual(296, (int)_character.TreatmentValue);
            Assert.AreEqual(98, _character.GetAbilityValue(Ability.Sense));
            Assert.IsTrue(_character.IsImplantSlotFull(ImplantSlot.Head));
            Assert.IsFalse(_character.IsImplantSlotFull(ImplantSlot.LeftArm));

            _character.SetImplant(highHead);

            Assert.AreEqual(highHead, _character.GetImplant(ImplantSlot.Head));
            Assert.AreEqual(387.5, _character.TreatmentValue);
            Assert.AreEqual(116, _character.GetAbilityValue(Ability.Sense));
            Assert.IsTrue(_character.IsImplantSlotFull(ImplantSlot.Head));
            Assert.IsFalse(_character.IsImplantSlotFull(ImplantSlot.LeftArm));
        }
        public void DegenerateLadderProcessEquipsImplantsInTheProperThreePhases()
        {
            // The three phases are
            //  1. the final ladder implants in initially empty slots,
            //  2. the final non-ladder implants in initially empty slots,
            //  3. the final implants in initially full slots.

            var alreadyEquippedImplants = new[]
            {
                Implant.GetImplant(ImplantSlot.Head, Skill.Treatment, null, Ability.Sense, 200),
                Implant.GetImplant(ImplantSlot.Leg, Ability.Agility, Ability.Stamina, null, 200),
                Implant.GetImplant(ImplantSlot.Ear, Skill.Perception, null, Ability.Intelligence, 200)
            };

            _character.SetImplants(alreadyEquippedImplants);

            var finalImplantTemplates = new[]
            {
                ImplantTemplate.GetImplantTemplate(ImplantSlot.Chest, Ability.Sense, Ability.Psychic, Ability.Strength), // 1
                ImplantTemplate.GetImplantTemplate(ImplantSlot.RightArm, Skill.Burst, null, null),                       // 2
                ImplantTemplate.GetImplantTemplate(ImplantSlot.Head, Skill.Treatment, null, null),                       // 3
                ImplantTemplate.GetImplantTemplate(ImplantSlot.Eye, null, Skill.Treatment, null),                        // 1
                ImplantTemplate.GetImplantTemplate(ImplantSlot.RightHand, null, null, Skill.Grenade),                    // 2
                ImplantTemplate.GetImplantTemplate(ImplantSlot.LeftArm, Skill.Brawling, null, null),                     // 2
                ImplantTemplate.GetImplantTemplate(ImplantSlot.Feet, null, Ability.Agility, null),                       // 1
                ImplantTemplate.GetImplantTemplate(ImplantSlot.Ear, null, null, Skill.PsychoModi)                        // 3
            };

            var ladderProcess = new DegenerateLadderProcess(_character, finalImplantTemplates);

            CollectionAssert.AreEquivalent(
                new[] { finalImplantTemplates[0], finalImplantTemplates[3], finalImplantTemplates[6] },
                ladderProcess.OrderedFinalImplants.Take(3).Select(i => i.ImplantTemplate).ToArray());
            CollectionAssert.AreEquivalent(
                new[] { finalImplantTemplates[1], finalImplantTemplates[4], finalImplantTemplates[5] },
                ladderProcess.OrderedFinalImplants.Skip(3).Take(3).Select(i => i.ImplantTemplate).ToArray());
            CollectionAssert.AreEquivalent(
                new[] { finalImplantTemplates[2], finalImplantTemplates[7] },
                ladderProcess.OrderedFinalImplants.Skip(6).Take(2).Select(i => i.ImplantTemplate).ToArray());
        }
        public void EquipsAndUnequipsSomeRandomImplants()
        {
            var head  = Implant.GetImplant(ImplantSlot.Head, Skill.Treatment, null, Ability.Sense, 20);
            var ear   = Implant.GetImplant(ImplantSlot.Ear, null, null, Ability.Intelligence, 20);
            var chest = Implant.GetImplant(ImplantSlot.Chest, Ability.Stamina, Ability.Psychic, Ability.Strength, 20);
            var eye   = Implant.GetImplant(ImplantSlot.Eye, null, Skill.Treatment, null, 20);
            var leg   = Implant.GetImplant(ImplantSlot.Leg, Ability.Agility, null, null, 20);
            var feet  = Implant.GetImplant(ImplantSlot.Feet, null, Ability.Agility, null, 20);

            Assert.IsTrue(_character.TryEquipImplant(head));
            Assert.AreEqual(296, (int)_character.TreatmentValue);
            Assert.AreEqual(98, _character.GetAbilityValue(Ability.Sense));
            Assert.IsTrue(_character.TryEquipImplant(ear));
            Assert.AreEqual(297, (int)_character.TreatmentValue);
            Assert.AreEqual(107, _character.GetAbilityValue(Ability.Intelligence));
            Assert.AreEqual(head, _character.UnequipImplant(ImplantSlot.Head));
            Assert.AreEqual(281, (int)_character.TreatmentValue);
            Assert.AreEqual(94, _character.GetAbilityValue(Ability.Sense));
            Assert.IsTrue(_character.TryEquipImplant(head));
            Assert.AreEqual(297, (int)_character.TreatmentValue);
            Assert.AreEqual(107, _character.GetAbilityValue(Ability.Intelligence));
            Assert.IsTrue(_character.TryEquipImplant(chest));
            Assert.IsTrue(_character.TryEquipImplant(eye));
            Assert.IsTrue(_character.TryEquipImplant(leg));
            Assert.IsTrue(_character.TryEquipImplant(feet));
            Assert.AreEqual(307, (int)_character.TreatmentValue);
            Assert.AreEqual(107, _character.GetAbilityValue(Ability.Agility));
            Assert.AreEqual(107, _character.GetAbilityValue(Ability.Intelligence));
            Assert.AreEqual(104, _character.GetAbilityValue(Ability.Psychic));
            Assert.AreEqual(98, _character.GetAbilityValue(Ability.Sense));
            Assert.AreEqual(101, _character.GetAbilityValue(Ability.Stamina));
            Assert.AreEqual(95, _character.GetAbilityValue(Ability.Strength));

            var ql50Eye = Implant.GetImplant(ImplantSlot.Eye, null, Skill.SensoryImpr, Skill.MatterCrea, 50);

            Assert.AreEqual(50, Implant.GetMaxImplantQLForAbilityValue(_character.GetAbilityValue(Ability.Psychic)));
            Assert.IsTrue(_character.TryEquipImplant(ql50Eye));
            Assert.AreEqual(298, (int)_character.TreatmentValue);
        }
        public void DegenerateLadderProcessUnequipsWeakLadderImplantsFirst()
        {
            // The head and ear are strong ladder implants and shouldn't be equipped before the weaker leg, eye, and feet.
            var alreadyEquippedImplants = new[]
            {
                Implant.GetImplant(ImplantSlot.Head, Skill.Treatment, null, Ability.Sense, 200),
                Implant.GetImplant(ImplantSlot.Leg, Ability.Agility, Ability.Stamina, null, 1),
                Implant.GetImplant(ImplantSlot.Ear, Skill.Perception, null, Ability.Intelligence, 200),
                Implant.GetImplant(ImplantSlot.Eye, null, Skill.Treatment, null, 1),
                Implant.GetImplant(ImplantSlot.Feet, null, Ability.Agility, null, 1)
            };

            _character.SetImplants(alreadyEquippedImplants);

            var finalImplantTemplates = new[]
            {
                ImplantTemplate.GetImplantTemplate(ImplantSlot.Chest, Ability.Sense, Ability.Psychic, Ability.Strength), // 1
                ImplantTemplate.GetImplantTemplate(ImplantSlot.RightArm, Skill.Burst, null, null),                       // 2
                ImplantTemplate.GetImplantTemplate(ImplantSlot.Head, Skill.Treatment, null, null),                       // 3
                ImplantTemplate.GetImplantTemplate(ImplantSlot.Eye, null, Skill.Treatment, Skill.Bow),                   // 1
                ImplantTemplate.GetImplantTemplate(ImplantSlot.RightHand, null, null, Skill.Grenade),                    // 2
                ImplantTemplate.GetImplantTemplate(ImplantSlot.LeftArm, Skill.Brawling, null, null),                     // 2
                ImplantTemplate.GetImplantTemplate(ImplantSlot.Feet, null, Ability.Agility, null),                       // 1
                ImplantTemplate.GetImplantTemplate(ImplantSlot.Ear, null, null, Skill.PsychoModi)                        // 3
            };

            var ladderProcess = new DegenerateLadderProcess(_character, finalImplantTemplates);

            var orderedFinalImplantSlots = ladderProcess.OrderedFinalImplants
                                           .Select(i => i.ImplantSlot)
                                           .ToArray();

            Assert.IsTrue(Array.IndexOf(orderedFinalImplantSlots, ImplantSlot.Head) > Array.IndexOf(orderedFinalImplantSlots, ImplantSlot.Eye));
            Assert.IsTrue(Array.IndexOf(orderedFinalImplantSlots, ImplantSlot.Head) > Array.IndexOf(orderedFinalImplantSlots, ImplantSlot.Feet));
            Assert.IsTrue(Array.IndexOf(orderedFinalImplantSlots, ImplantSlot.Ear) > Array.IndexOf(orderedFinalImplantSlots, ImplantSlot.Eye));
            Assert.IsTrue(Array.IndexOf(orderedFinalImplantSlots, ImplantSlot.Ear) > Array.IndexOf(orderedFinalImplantSlots, ImplantSlot.Feet));
        }
        public void DegenerateLadderProcessLeavesAlreadyEquippedImplantsAlone()
        {
            var alreadyEquippedImplants = new[]
            {
                Implant.GetImplant(ImplantSlot.Head, Skill.Treatment, null, Ability.Sense, 200),
                Implant.GetImplant(ImplantSlot.Leg, Ability.Agility, Ability.Stamina, null, 200)
            };

            _character.SetImplants(alreadyEquippedImplants);
            Assert.AreEqual(146, _character.GetAbilityValue(Ability.Agility));
            Assert.AreEqual(124, _character.GetAbilityValue(Ability.Stamina));
            Assert.AreEqual(116, _character.GetAbilityValue(Ability.Sense));
            Assert.AreEqual(391.625, _character.TreatmentValue);

            var finalImplantTemplates = new[]
            {
                ImplantTemplate.GetImplantTemplate(ImplantSlot.Chest, Ability.Sense, Ability.Psychic, Ability.Strength), // Psychic
                ImplantTemplate.GetImplantTemplate(ImplantSlot.RightArm, Ability.Strength, null, null),                  // Sense
                ImplantTemplate.GetImplantTemplate(ImplantSlot.Waist, null, Ability.Sense, Ability.Stamina),             // Psychic
                ImplantTemplate.GetImplantTemplate(ImplantSlot.Eye, null, Skill.Treatment, null),                        // Agility
                ImplantTemplate.GetImplantTemplate(ImplantSlot.RightHand, null, null, Skill.Treatment),                  // Intelligence
                ImplantTemplate.GetImplantTemplate(ImplantSlot.Feet, null, Ability.Agility, null),                       // Agility
                ImplantTemplate.GetImplantTemplate(ImplantSlot.Ear, null, null, Ability.Intelligence)                    // Psychic
            };
            var finalImplantSlots = finalImplantTemplates.Select(t => t.ImplantSlot).ToArray();

            var ladderProcess = new DegenerateLadderProcess(_character, finalImplantTemplates);

            Assert.AreEqual(146, _character.GetAbilityValue(Ability.Agility));
            Assert.AreEqual(124, _character.GetAbilityValue(Ability.Stamina));
            Assert.AreEqual(116, _character.GetAbilityValue(Ability.Sense));
            Assert.AreEqual(391.625, _character.TreatmentValue);
            Assert.AreEqual(_character.GetImplant(ImplantSlot.Head), alreadyEquippedImplants[0]);
            Assert.AreEqual(_character.GetImplant(ImplantSlot.Leg), alreadyEquippedImplants[1]);
            Assert.AreEqual(400, _character.GetTotalImplantQL());

            // The final QL should be greater than what we get by w/o any laddered equips.
            int unladderedTotalFinalImplantQL = 0;

            foreach (var implantTemplate in finalImplantTemplates)
            {
                unladderedTotalFinalImplantQL += _character.GetMaxImplant(implantTemplate).QL;
            }
            Assert.IsTrue(unladderedTotalFinalImplantQL < ladderProcess.TotalFinalImplantQL);

            // The final QL should be greater than what we get by laddering in the arbitrary order declared above.
            foreach (var implantTemplate in finalImplantTemplates)
            {
                _character.EquipMaxImplant(implantTemplate);
            }
            Assert.IsTrue(unladderedTotalFinalImplantQL < _character.GetTotalImplantQL(finalImplantSlots));
            Assert.IsTrue(_character.GetTotalImplantQL(finalImplantSlots) < ladderProcess.TotalFinalImplantQL);

            Assert.AreEqual(0, ladderProcess.OrderedLadderImplants.Count);

            // Some regression tests, I don't know for sure that 423 is what to expect, hopefully won't ever drop below this.
            Assert.AreEqual(388, unladderedTotalFinalImplantQL);
            Assert.AreEqual(406, _character.GetTotalImplantQL(finalImplantSlots));
            Assert.AreEqual(406 / (double)7, _character.GetAverageImplantQL(finalImplantSlots));
            Assert.AreEqual(423, ladderProcess.TotalFinalImplantQL);
            Assert.AreEqual(423 / (double)7, ladderProcess.AverageFinalImplantQL);
        }
        public void CannotDirectlyEquipQL50StoreBoughtEyeImplant()
        {
            var eye = Implant.GetImplant(ImplantSlot.Eye, Skill.Tutoring, Skill.PsychoModi, Skill.TimeAndSpace, 50);

            Assert.IsFalse(_character.CanEquipImplant(eye));
        }