/// <summary> /// Add the item, its previous levels and its prerequisites to the given set and list. /// </summary> /// <param name="list">The list.</param> /// <param name="set">The set.</param> /// <param name="item">The item.</param> /// <param name="includeRoots">if set to <c>true</c> [include roots].</param> internal static void FillDependencies(this IList <StaticSkillLevel> list, SkillLevelSet <StaticSkillLevel> set, StaticSkillLevel item, bool includeRoots) { StaticSkill skill = item.Skill; // Add first level and prerequisites if (!set.Contains(skill, 1)) { // Prerequisites foreach (StaticSkillLevel prereq in skill.Prerequisites.Where(prereq => skill != prereq.Skill)) { list.FillDependencies(set, prereq, true); } // Include the first level StaticSkillLevel newItem = new StaticSkillLevel(skill, 1); list.Add(newItem); set.Set(newItem); } // Add greater levels Int64 max = includeRoots ? item.Level : item.Level - 1; for (int i = 2; i <= max; i++) { if (set.Contains(skill, i)) { continue; } StaticSkillLevel newItem = new StaticSkillLevel(skill, i); list.Add(newItem); set.Set(newItem); } }
/// <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> public List <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 (var itemToAdd in skillsToAdd) { // Already trained ? We skip it. if (m_character.GetSkillLevel(itemToAdd.Skill) >= itemToAdd.Level) { continue; } // 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 var item = new StaticSkillLevel(itemToAdd); foreach (var dependency in item.AllDependencies) { // Already in the "entries to add" list ? We skip it. if (entriesSet.Contains(dependency)) { continue; } // Already trained ? We skip it. if (m_character.GetSkillLevel(dependency.Skill) >= dependency.Level) { continue; } // Create an entry (even for existing ones, we will update them later from those new entries) var 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 var entry = CreateEntryToAdd(itemToAdd.Skill, itemToAdd.Level, PlanEntryType.Planned, note, ref lowestPrereqPriority); planEntries.Add(entry); entriesSet.Set(entry); } return(planEntries); }
/// <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> public List <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 (var itemToRemove in skillsToRemove) { // Not planned ? We skip it. if (!IsPlanned(itemToRemove.Skill, itemToRemove.Level)) { continue; } // Already in the "entries to remove" list ? We skip it (done at this point only because of recursive prereqs) if (entriesSet.Contains(itemToRemove)) { continue; } // Let's first gather dependencies var item = new StaticSkillLevel(itemToRemove); foreach (var dependencyEntry in m_items) { // Already in the "entries to remove" list ? We skip it. if (entriesSet.Contains(dependencyEntry)) { continue; } // Not dependent ? We skip it. if (!dependencyEntry.IsDependentOf(itemToRemove)) { continue; } // Gather this entry planEntries.Add(dependencyEntry); entriesSet.Set(dependencyEntry); } // Then add the item itself var entryToRemove = GetEntry(itemToRemove.Skill, itemToRemove.Level); planEntries.Add(entryToRemove); entriesSet.Set(entryToRemove); } return(planEntries); }
/// <summary> /// Recursive method to generate treenodes for tvSkillList /// </summary> /// <param name="requiredSkill">An EntityRequiredSkill object</param> /// <returns></returns> private TreeNode GetSkillNode(StaticSkillLevel prereq, ref bool allSkillsKnown, ref bool skillsUnplanned) { var character = (Character)m_plan.Character; Skill skill = character.Skills[prereq.Skill]; TreeNode node = new TreeNode(prereq.ToString()); node.Tag = new SkillLevel(skill, prereq.Level); // Skill requirement met if (skill.Level >= prereq.Level) { node.ImageIndex = 1; node.SelectedImageIndex = 1; } // Requirement not met, but planned else if (m_plan.IsPlanned(skill, prereq.Level)) { node.ImageIndex = 2; node.SelectedImageIndex = 2; allSkillsKnown = false; } // Requirement not met, but trainable else if (skill.Level < prereq.Level && skill.IsKnown) { node.ImageIndex = 3; node.SelectedImageIndex = 3; allSkillsKnown = false; skillsUnplanned = true; } // Requirement not met else { node.ImageIndex = 0; node.SelectedImageIndex = 0; allSkillsKnown = false; skillsUnplanned = true; } // Generate child nodes if required foreach (StaticSkillLevel childPrereq in skill.StaticData.Prerequisites) { node.Nodes.Add(GetSkillNode(childPrereq, ref allSkillsKnown, ref skillsUnplanned)); } return(node); }
/// <summary> /// Recursive method to generate treenodes for tvCertList. /// </summary> /// <param name="requiredSkill">An EntityRequiredSkill object</param> /// <returns></returns> private TreeNode GetSkillNode(StaticSkillLevel prereq) { var character = (Character)m_plan.Character; Skill skill = character.Skills[prereq.Skill]; TreeNode node = new TreeNode(prereq.ToString()); node.Tag = new SkillLevel(skill, prereq.Level); // Generate child prerequisite skill nodes if required foreach (StaticSkillLevel childPrereq in skill.StaticData.Prerequisites) { node.Nodes.Add(GetSkillNode(childPrereq)); } return(node); }
/// <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); }
/// <summary> /// Fills the given levels array with the prerequisites and when <c>includeRoots</c> is true, the item level itself. /// </summary> /// <param name="highestLevels"></param> /// <param name="list"></param> /// <param name="item"></param> /// <param name="includeRoots"></param> internal static void FillPrerequisites(Int64[] highestLevels, List <StaticSkillLevel> list, StaticSkillLevel item, bool includeRoots) { // Prerequisites if (highestLevels[item.Skill.ArrayIndex] == 0) { foreach (StaticSkillLevel prereq in item.Skill.Prerequisites.Where(prereq => prereq.Skill != item.Skill)) { FillPrerequisites(highestLevels, list, prereq, true); } } // The very level if (!includeRoots || highestLevels[item.Skill.ArrayIndex] >= item.Level) { return; } highestLevels[item.Skill.ArrayIndex] = item.Level; list.Add(item); }
/// <summary> /// Constructor from the skill object. /// </summary> /// <param name="skill"></param> /// <param name="level"></param> public SkillLevel(Skill skill, long level) { Skill = skill; Level = level; ssl = new StaticSkillLevel(this); }