/// <summary> /// Removes completed skills /// </summary> public void CleanObsoleteEntries(ObsoleteRemovalPolicy policy) { using (SuspendingEvents()) { for (int i = 0; i < Items.Count; i++) { PlanEntry pe = Items[i]; if (Character.GetSkillLevel(pe.Skill) < pe.Level) { continue; } // Confirmed by API? if (policy == ObsoleteRemovalPolicy.ConfirmedOnly && pe.CharacterSkill.LastConfirmedLvl < pe.Level) { continue; } Items.RemoveAt(i); m_lookup[pe.Skill.ArrayIndex * 5 + pe.Level - 1] = null; i--; } } }
/// <summary> /// Checks whether a matching entry exists between before the provided <c>insertionIndex</c>. /// If the entry exist and is trained, remove it. /// If the entry exist later, it is moved to this <c>insertionIndex</c>. /// If the entry does not exit, it is inserted at <c>insertionIndex</c>. /// </summary> /// <param name="skill"></param> /// <param name="level"></param> /// <param name="insertionIndex"></param> /// <param name="newEntriesPriority"></param> /// <returns>True if the searched entry existed or is already trained; false if an insertion or a move was required.</returns> private bool EnsurePrerequisiteExistBefore(StaticSkill skill, Int64 level, int insertionIndex, int newEntriesPriority) { int skillIndex = IndexOf(skill, level); // Is the level already trained by the character ? if (Character.GetSkillLevel(skill) >= level) { // If the level is planned, remove it if (skillIndex != -1) { RemoveCore(skillIndex); } return(true); } // Is the prerequisite already planned before this very entry ? // Then we continue the foreach loop to the next prereq if (skillIndex != -1 && skillIndex < insertionIndex) { return(true); } // The prerequisite is not planned yet, we insert it just before this very entry if (skillIndex == -1) { PlanEntry newEntry = new PlanEntry(this, skill, level) { Type = PlanEntryType.Prerequisite, Priority = newEntriesPriority }; InsertCore(insertionIndex, newEntry); return(false); } // The prerequisite exists but it's located later in the plan // So we move it at the insertion index MoveCore(skillIndex, insertionIndex); return(false); }
/// <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); }