Ejemplo n.º 1
0
        /// <summary>
        /// Exports the character's selected skills as plan.
        /// </summary>
        /// <param name="character">The character.</param>
        /// <param name="selectedSkills">The selected skills.</param>
        /// <returns></returns>
        /// <exception cref="System.ArgumentNullException"></exception>
        public static async Task ExportCharacterSkillsAsPlanAsync(Character character, IEnumerable <Skill> selectedSkills = null)
        {
            character.ThrowIfNull(nameof(character));

            // Create a character without any skill
            CharacterScratchpad scratchpad = new CharacterScratchpad(character);

            scratchpad.ClearSkills();

            // Create a new plan
            Plan plan = new Plan(scratchpad)
            {
                Name = "Skills Plan"
            };

            IEnumerable <Skill> skills = selectedSkills ?? character.Skills.Where(skill => skill.IsPublic);

            // Add all trained skill levels that the character has trained so far
            foreach (Skill skill in skills)
            {
                plan.PlanTo(skill, skill.Level);
            }

            await ExportPlanAsync(plan, character);
        }
Ejemplo n.º 2
0
        /// <summary>
        /// Generate a trainings array from the skills already know by a character.
        /// </summary>
        /// <param name="character">The character.</param>
        /// <param name="plan">The plan.</param>
        /// <returns></returns>
        /// <exception cref="System.ArgumentNullException">character or plan</exception>
        public static RemappingResult OptimizeFromCharacter(Character character, BasePlan plan)
        {
            character.ThrowIfNull(nameof(character));

            plan.ThrowIfNull(nameof(plan));

            // Create a character without any skill
            CharacterScratchpad scratchpad = new CharacterScratchpad(character.After(plan.ChosenImplantSet));

            scratchpad.ClearSkills();

            // Create a new plan
            Plan newPlan = new Plan(scratchpad);

            // Add all trained skill levels that the character has trained so far
            foreach (Skill skill in character.Skills)
            {
                newPlan.PlanTo(skill, skill.Level);
            }

            // Create a new remapping
            RemappingResult remapping = new RemappingResult(scratchpad);

            // Add those skills to the remapping
            foreach (PlanEntry entry in newPlan)
            {
                remapping.Skills.Add(entry);
            }

            // Optimize
            remapping.Optimize(TimeSpan.MaxValue);
            return(remapping);
        }
Ejemplo n.º 3
0
        /// <summary>
        /// Gets the list of remapping results from a plan.
        /// </summary>
        /// <param name="plan"></param>
        /// <returns></returns>
        /// <exception cref="System.ArgumentNullException">plan</exception>
        public static Collection <RemappingResult> GetResultsFromRemappingPoints(BasePlan plan)
        {
            plan.ThrowIfNull(nameof(plan));

            CharacterScratchpad          scratchpad    = new CharacterScratchpad(plan.Character.After(plan.ChosenImplantSet));
            Collection <RemappingResult> remappingList = new Collection <RemappingResult>();
            Collection <ISkillLevel>     list          = new Collection <ISkillLevel>();

            // Scroll through the entries and split it into remappings
            foreach (PlanEntry entry in plan)
            {
                // Ends the current remapping and start a new one
                if (entry.Remapping != null)
                {
                    // Creates a new remapping
                    RemappingResult remapping = new RemappingResult(entry.Remapping, scratchpad.Clone());
                    remappingList.Add(remapping);
                    list = remapping.Skills;
                }

                // Add this skill to the training list
                scratchpad.Train(entry);
                list.Add(entry);
            }

            // Return
            return(remappingList);
        }
Ejemplo n.º 4
0
        /// <summary>
        /// Resets the scratchpad from the <see cref="BaseCharacter"/> it was built upon.
        /// </summary>
        public void Reset()
        {
            CharacterScratchpad character = m_character as CharacterScratchpad;

            if (character != null)
            {
                Reset(character);
            }
            else
            {
                ResetFromCharacter();
            }
        }
Ejemplo n.º 5
0
        /// <summary>
        /// Resets this scratchpad using the provided scratchpad.
        /// </summary>
        /// <param name="scratchpad"></param>
        private void Reset(CharacterScratchpad scratchpad)
        {
            m_skillPoints = scratchpad.m_skillPoints;
            TrainingTime  = scratchpad.TrainingTime;

            TrainedSkills.Clear();
            TrainedSkills.AddRange(scratchpad.TrainedSkills);

            for (int i = 0; i < m_attributes.Length; i++)
            {
                m_attributes[i].Reset(scratchpad.m_attributes[i]);
            }

            scratchpad.m_skillSP.CopyTo(m_skillSP, 0);
            scratchpad.m_skillLevels.CopyTo(m_skillLevels, 0);
        }
Ejemplo n.º 6
0
        /// <summary>
        /// Performs the sort.
        /// </summary>
        /// <returns></returns>
        public IEnumerable <PlanEntry> Sort()
        {
            int initialCount = m_entries.Count();

            // Apply first pass (priorities grouping)
            // We split the entries into multiple priority groups if that selection is made
            List <PlanScratchpad> groupedPlan = new List <PlanScratchpad>();
            CharacterScratchpad   scratchpad  = new CharacterScratchpad(m_character);

            if (m_groupByPriority)
            {
                groupedPlan.AddRange(
                    m_entries.GroupBy(x => x.Priority).OrderBy(x => x.Key).Select(group => new PlanScratchpad(scratchpad, group)));
            }
            else
            {
                groupedPlan.Add(new PlanScratchpad(scratchpad, m_entries));
            }

            // Apply second pass (sorts)
            // We sort every group, and merge them once they're sorted
            List <PlanEntry> list = new List <PlanEntry>();

            foreach (PlanScratchpad group in groupedPlan)
            {
                group.UpdateStatistics(scratchpad, false, false);
                group.SimpleSort(m_sort, m_reverseOrder);
                list.AddRange(group);
            }

            // Fix prerequisites order
            FixPrerequisitesOrder(list);

            // Check we didn't mess up anything
            if (initialCount != list.Count)
            {
                throw new UnauthorizedAccessException("The sort algorithm messed up and deleted items");
            }

            // Return
            return(list);
        }
Ejemplo n.º 7
0
        /// <summary>
        /// Compute the best possible attributes to fulfill the given trainings array
        /// </summary>
        /// <param name="skills"></param>
        /// <param name="baseScratchpad"></param>
        /// <param name="maxDuration"></param>
        /// <returns></returns>
        internal static CharacterScratchpad Optimize <T>(IEnumerable <T> skills, CharacterScratchpad baseScratchpad,
                                                         TimeSpan maxDuration)
            where T : ISkillLevel
        {
            CharacterScratchpad bestScratchpad = new CharacterScratchpad(baseScratchpad);
            CharacterScratchpad tempScratchpad = new CharacterScratchpad(baseScratchpad);
            TimeSpan            baseTime       = baseScratchpad.TrainingTime;
            TimeSpan            bestTime       = TimeSpan.MaxValue;
            int bestSkillCount = 0;

            // Now, we have the points to spend, let's perform all the
            // combinations (less than 11^4 = 14,641)
            for (int per = 0; per <= EveConstants.MaxRemappablePointsPerAttribute; per++)
            {
                // WIL
                int maxWillpower = EveConstants.SpareAttributePointsOnRemap - per;
                for (int will = 0; will <= maxWillpower && will <= EveConstants.MaxRemappablePointsPerAttribute; will++)
                {
                    // INT
                    int maxIntelligence = maxWillpower - will;
                    for (int intell = 0;
                         intell <= maxIntelligence && intell <= EveConstants.MaxRemappablePointsPerAttribute;
                         intell++)
                    {
                        // MEM
                        int maxMemory = maxIntelligence - intell;
                        for (int mem = 0; mem <= maxMemory && mem <= EveConstants.MaxRemappablePointsPerAttribute; mem++)
                        {
                            // CHA
                            int cha = maxMemory - mem;

                            // Reject invalid combinations
                            if (cha > EveConstants.MaxRemappablePointsPerAttribute)
                            {
                                continue;
                            }

                            // Resets the scratchpad
                            tempScratchpad.Reset();

                            // Set new attributes
                            tempScratchpad.Memory.Base       = mem + EveConstants.CharacterBaseAttributePoints;
                            tempScratchpad.Charisma.Base     = cha + EveConstants.CharacterBaseAttributePoints;
                            tempScratchpad.Willpower.Base    = will + EveConstants.CharacterBaseAttributePoints;
                            tempScratchpad.Perception.Base   = per + EveConstants.CharacterBaseAttributePoints;
                            tempScratchpad.Intelligence.Base = intell + EveConstants.CharacterBaseAttributePoints;

                            // Train skills
                            int tempSkillCount = 0;
                            foreach (T skill in skills)
                            {
                                tempSkillCount++;
                                tempScratchpad.Train(skill);

                                // Did it go over max duration ?
                                if (tempScratchpad.TrainingTime - baseTime > maxDuration)
                                {
                                    break;
                                }

                                // Did it go over the best time so far without training more skills ?
                                if (tempSkillCount <= bestSkillCount && tempScratchpad.TrainingTime > bestTime)
                                {
                                    break;
                                }
                            }

                            // Did it manage to train more skills before the max duration,
                            // or did it train the same number of skills in a lesser time ?
                            if (tempSkillCount <= bestSkillCount &&
                                (tempSkillCount != bestSkillCount || tempScratchpad.TrainingTime >= bestTime))
                            {
                                continue;
                            }

                            bestScratchpad.Reset();
                            bestScratchpad.Memory.Base       = tempScratchpad.Memory.Base;
                            bestScratchpad.Charisma.Base     = tempScratchpad.Charisma.Base;
                            bestScratchpad.Willpower.Base    = tempScratchpad.Willpower.Base;
                            bestScratchpad.Perception.Base   = tempScratchpad.Perception.Base;
                            bestScratchpad.Intelligence.Base = tempScratchpad.Intelligence.Base;
                            bestTime       = tempScratchpad.TrainingTime;
                            bestSkillCount = tempSkillCount;
                        }
                    }
                }
            }

            // Return the best scratchpad found
            return(bestScratchpad);
        }
Ejemplo n.º 8
0
        /// <summary>
        /// Allow to store the state of this scratchpad to restore it later.
        /// The method returns an <see cref="IDisposable"/> object which, once disposed, will restore the state.
        /// </summary>
        /// <remarks>Use it in a <c>using</c> block to enforce an automatic restoration of the object even when exceptions are throw.</remarks>
        /// <returns>A disposable object which, once disposed, will restore the state of the </returns>
        public IDisposable BeginTemporaryChanges()
        {
            CharacterScratchpad clone = Clone();

            return(new DisposableWithCallback(() => Reset(clone)));
        }