Example #1
0
        /// <summary>
        /// Given a list of skill to remove, we return a list of entries also including all dependencies. No entry is removed by this method.
        /// </summary>
        /// <returns>A list of all the entries to remove.</returns>
        protected IEnumerable <PlanEntry> GetAllEntriesToRemove <T>(IEnumerable <T> skillsToRemove)
            where T : ISkillLevel
        {
            SkillLevelSet <PlanEntry> entriesSet  = new SkillLevelSet <PlanEntry>();
            List <PlanEntry>          planEntries = new List <PlanEntry>();

            // For every items to add
            foreach (T itemToRemove in skillsToRemove.Where(
                         itemToRemove => IsPlanned(itemToRemove.Skill, itemToRemove.Level)).Where(
                         itemToRemove => !entriesSet.Contains(itemToRemove)))
            {
                // Let's first gather dependencies
                foreach (PlanEntry dependencyEntry in Items.Where(
                             dependencyEntry => !entriesSet.Contains(dependencyEntry)).Where(
                             dependencyEntry => dependencyEntry.IsDependentOf(itemToRemove)))
                {
                    // Gather this entry
                    planEntries.Add(dependencyEntry);
                    entriesSet.Set(dependencyEntry);
                }

                // Then add the item itself
                PlanEntry entryToRemove = GetEntry(itemToRemove.Skill, itemToRemove.Level);
                planEntries.Add(entryToRemove);
                entriesSet.Set(entryToRemove);
            }

            return(planEntries);
        }
Example #2
0
        /// <summary>
        /// Rebuild the plan from the given entries enumeration.
        /// </summary>
        /// <param name="entries">The entries.</param>
        /// <param name="preserveOldEntries">When true, old entries will be reused as often as possible, preserving their statistics.</param>
        /// <exception cref="System.ArgumentNullException">entries</exception>
        /// <remarks>
        /// Entries from another plan will be cloned.
        /// </remarks>
        public void RebuildPlanFrom(IEnumerable <PlanEntry> entries, bool preserveOldEntries)
        {
            entries.ThrowIfNull(nameof(entries));

            if (!preserveOldEntries)
            {
                RebuildPlanFrom(entries);
                return;
            }

            using (SuspendingEvents())
            {
                // Save the old entries
                SkillLevelSet <PlanEntry> set = new SkillLevelSet <PlanEntry>();
                foreach (PlanEntry entry in Items)
                {
                    set[entry.Skill, entry.Level] = entry;
                }

                // Clear items
                Items.Clear();
                for (int i = 0; i < m_lookup.Length; i++)
                {
                    m_lookup[i] = null;
                }

                // Add the new entries
                foreach (PlanEntry entry in entries)
                {
                    PlanEntry oldEntry = set[entry.Skill, entry.Level];

                    PlanEntry entryToAdd;
                    if (entry.Plan != this)
                    {
                        entryToAdd = entry.Clone(this);
                    }
                    else if (oldEntry != null)
                    {
                        entryToAdd = oldEntry;
                    }
                    else
                    {
                        entryToAdd = entry;
                    }

                    AddCore(entryToAdd);
                }
            }
        }
Example #3
0
        /// <summary>
        /// Given a list of skill to add, we return a list of all entries to add, also including all dependencies. No entry is added by this method.
        /// </summary>
        /// <param name="skillsToAdd">The enumerations of skills to add.</param>
        /// <param name="note">The note for new entries.</param>
        /// <param name="lowestPrereqPriority">The lowest priority (highest number) among all the prerequisites.</param>
        /// <returns>A list of all the entries to add.</returns>
        protected IEnumerable <PlanEntry> GetAllEntriesToAdd <T>(IEnumerable <T> skillsToAdd, string note,
                                                                 out int lowestPrereqPriority)
            where T : ISkillLevel
        {
            SkillLevelSet <PlanEntry> entriesSet  = new SkillLevelSet <PlanEntry>();
            List <PlanEntry>          planEntries = new List <PlanEntry>();

            lowestPrereqPriority = 1;

            // For every items to add
            foreach (T itemToAdd in skillsToAdd.Where(
                         itemToAdd => Character.GetSkillLevel(itemToAdd.Skill) < itemToAdd.Level))
            {
                // Already planned ? We update the lowestPrereqPriority and skip it.
                if (IsPlanned(itemToAdd.Skill, itemToAdd.Level))
                {
                    lowestPrereqPriority = Math.Max(GetEntry(itemToAdd.Skill, itemToAdd.Level).Priority, lowestPrereqPriority);
                    continue;
                }

                // Let's first add dependencies excluding those that the dependent skill is already trained
                StaticSkillLevel item = new StaticSkillLevel(itemToAdd);

                if (Character.GetSkillLevel(itemToAdd.Skill) < 1)
                {
                    foreach (StaticSkillLevel dependency in item.AllDependencies.Where(
                                 dependency => !entriesSet.Contains(dependency) && dependency.Skill != item.Skill &&
                                 Character.GetSkillLevel(dependency.Skill) < dependency.Level)
                             .Select(dependency => new
                    {
                        dependency,
                        depItems = item.AllDependencies.Where(
                            dep => item.Skill != dep.Skill &&
                            dep.Skill.Prerequisites.Any(
                                prereq => prereq.Skill == dependency.Skill))
                    })
                             .Where(dep => !dep.depItems.Any() ||
                                    !dep.depItems.All(depItem => Character.GetSkillLevel(depItem.Skill) >= depItem.Level))
                             .Select(dep => dep.dependency))
                    {
                        // Create an entry (even for existing ones, we will update them later from those new entries)
                        PlanEntry dependencyEntry = CreateEntryToAdd(dependency.Skill, dependency.Level,
                                                                     PlanEntryType.Prerequisite, note, ref lowestPrereqPriority);
                        planEntries.Add(dependencyEntry);
                        entriesSet.Set(dependencyEntry);
                    }

                    // Already in the "entries to add" list ? We skip it (done at this point only because of recursive prereqs)
                    if (entriesSet.Contains(itemToAdd))
                    {
                        continue;
                    }
                }

                // Then add the item itself
                PlanEntry entry = CreateEntryToAdd(itemToAdd.Skill, itemToAdd.Level,
                                                   PlanEntryType.Planned, note, ref lowestPrereqPriority);
                planEntries.Add(entry);
                entriesSet.Set(entry);
            }

            return(planEntries);
        }