internal void RemoveSkills(FilterOptions skills) { string category; switch (skills) { case FilterOptions.Magician: case FilterOptions.Sorcery: case FilterOptions.Conjuring: case FilterOptions.Enchanting: case FilterOptions.Adept: category = "Magical Active"; break; case FilterOptions.Technomancer: category = "Resonance Active"; break; default: return; } // Check for duplicates (we'd normally want to make sure it's enabled, but SpecialSkills doesn't process the Enabled property properly) foreach (Improvement objImprovement in _character.Improvements.Where(x => x.ImproveType == Improvement.ImprovementType.SpecialSkills)) { FilterOptions eLoopFilter = (FilterOptions)Enum.Parse(typeof(FilterOptions), objImprovement.ImprovedName); string strLoopCategory = string.Empty; switch (eLoopFilter) { case FilterOptions.Magician: case FilterOptions.Sorcery: case FilterOptions.Conjuring: case FilterOptions.Enchanting: case FilterOptions.Adept: strLoopCategory = "Magical Active"; break; case FilterOptions.Technomancer: strLoopCategory = "Resonance Active"; break; } if (strLoopCategory == category) { return; } } for (int i = Skills.Count - 1; i >= 0; i--) { if (Skills[i].SkillCategory == category) { Skill skill = Skills[i]; _skillValueBackup[skill.SkillId] = skill; Skills.RemoveAt(i); SkillsDictionary.Remove(skill.IsExoticSkill ? skill.Name + " (" + skill.DisplaySpecialization + ")" : skill.Name); if (_character.Created && skill.TotalBaseRating > 0) { KnowledgeSkill kno = new KnowledgeSkill(_character) { Type = skill.Name == "Arcana" ? "Academic" : "Professional", WriteableName = skill.Name, Base = skill.Base, Karma = skill.Karma }; kno.Specializations.AddRange(skill.Specializations); KnowledgeSkills.Add(kno); } } } //remove skillgroups whose skills did not make the final cut for (var i = SkillGroups.Count - 1; i >= 0; i--) { if (!SkillGroups[i].GetEnumerable().Any(x => SkillsDictionary.ContainsKey(x.Name))) { SkillGroups.RemoveAt(i); i--; } } }
internal void Load(XmlNode skillNode, bool legacy = false) { if (skillNode == null) { return; } Timekeeper.Start("load_char_skills"); if (!legacy) { Timekeeper.Start("load_char_skills_groups"); List <SkillGroup> loadingSkillGroups = new List <SkillGroup>(); foreach (XmlNode node in skillNode.SelectNodes("groups/group")) { SkillGroup skillgroup = SkillGroup.Load(_character, node); if (skillgroup != null) { loadingSkillGroups.Add(skillgroup); } } loadingSkillGroups.Sort((i1, i2) => String.Compare(i2.DisplayName, i1.DisplayName, StringComparison.Ordinal)); foreach (SkillGroup skillgroup in loadingSkillGroups) { SkillGroups.Add(skillgroup); } Timekeeper.Finish("load_char_skills_groups"); Timekeeper.Start("load_char_skills_normal"); //Load skills. Because sorting a BindingList is complicated we use a temporery normal list List <Skill> loadingSkills = new List <Skill>(); foreach (XmlNode node in skillNode.SelectNodes("skills/skill")) { Skill skill = Skill.Load(_character, node); if (skill != null) { loadingSkills.Add(skill); } } loadingSkills.Sort(CompareSkills); foreach (Skill skill in loadingSkills) { _skills.Add(skill); } Timekeeper.Finish("load_char_skills_normal"); Timekeeper.Start("load_char_skills_kno"); foreach (XmlNode node in skillNode.SelectNodes("knoskills/skill")) { KnowledgeSkill skill = Skill.Load(_character, node) as KnowledgeSkill; if (skill != null) { KnowledgeSkills.Add(skill); } } Timekeeper.Finish("load_char_skills_kno"); Timekeeper.Start("load_char_knowsoft_buffer"); // Knowsoft Buffer. foreach (XmlNode objXmlSkill in skillNode.SelectNodes("skilljackknowledgeskills/skill")) { string strName = string.Empty; if (objXmlSkill.TryGetStringFieldQuickly("name", ref strName)) { KnowsoftSkills.Add(new KnowledgeSkill(_character, strName)); } } Timekeeper.Finish("load_char_knowsoft_buffer"); } else { List <Skill> tempSkillList = new List <Skill>(); foreach (XmlNode node in skillNode.SelectNodes("skills/skill")) { Skill skill = Skill.LegacyLoad(_character, node); if (skill != null) { tempSkillList.Add(skill); } } List <Skill> unsoredSkills = new List <Skill>(); //Variable/Anon method as to not clutter anywhere else. Not sure if clever or stupid Predicate <Skill> oldSkillFilter = skill => { if (skill.Rating > 0) { return(true); } if (skill.SkillCategory == "Resonance Active" && !_character.RESEnabled) { return(false); } //This could be more fine grained, but frankly i don't care if (skill.SkillCategory == "Magical Active" && !_character.MAGEnabled) { return(false); } return(true); }; foreach (Skill skill in tempSkillList) { KnowledgeSkill knoSkill = skill as KnowledgeSkill; if (knoSkill != null) { KnowledgeSkills.Add(knoSkill); } else if (oldSkillFilter(skill)) { unsoredSkills.Add(skill); } } unsoredSkills.Sort(CompareSkills); unsoredSkills.ForEach(x => _skills.Add(x)); UpdateUndoList(skillNode); } //This might give subtle bugs in the future, //but right now it needs to be run once when upgrading or it might crash. //As some didn't they crashed on loading skills. //After this have run, it won't (for the crash i'm aware) //TODO: Move it to the other side of the if someday? //remove skillgroups whose skills did not make the final cut for (var i = SkillGroups.Count - 1; i >= 0; i--) { if (!SkillGroups[i].GetEnumerable().Any(x => Skills.Contains(x))) { SkillGroups.RemoveAt(i); i--; } } //Workaround for probably breaking compability between earlier beta builds if (skillNode["skillptsmax"] == null) { skillNode = skillNode.OwnerDocument["character"]; } int intTmp = 0; if (skillNode.TryGetInt32FieldQuickly("skillptsmax", ref intTmp)) { SkillPointsMaximum = intTmp; } if (skillNode.TryGetInt32FieldQuickly("skillgrpsmax", ref intTmp)) { SkillGroupPointsMaximum = intTmp; } skillNode.TryGetBoolFieldQuickly("uneducated", ref _blnUneducated); skillNode.TryGetBoolFieldQuickly("uncouth", ref _blnUncouth); skillNode.TryGetBoolFieldQuickly("schoolofhardknocks", ref _blnSchoolOfHardKnocks); skillNode.TryGetBoolFieldQuickly("collegeeducation", ref _blnCollegeEducation); skillNode.TryGetBoolFieldQuickly("jackofalltrades", ref _blnJackOfAllTrades); skillNode.TryGetBoolFieldQuickly("techschool", ref _blnTechSchool); skillNode.TryGetBoolFieldQuickly("linguist", ref _blnLinguist); Timekeeper.Finish("load_char_skills"); }
internal void Load(XmlNode skillNode, bool legacy = false) { Timekeeper.Start("load_char_skills"); if (!legacy) { Timekeeper.Start("load_char_skills_groups"); (from XmlNode node in skillNode.SelectNodes("groups/group") let @group = SkillGroup.Load(_character, node) where @group != null orderby @group.DisplayName descending select @group).ForEach(x => SkillGroups.Add(x)); Timekeeper.Finish("load_char_skills_groups"); Timekeeper.Start("load_char_skills_normal"); //Load skills. Because sorting a BindingList is complicated we use a temporery normal list List <Skill> loadingSkills = (from XmlNode node in skillNode.SelectNodes("skills/skill") let skill = Skill.Load(_character, node) where skill != null select skill).ToList(); loadingSkills.Sort(CompareSkills); foreach (Skill skill in loadingSkills) { _skills.Add(skill); } Timekeeper.Finish("load_char_skills_normal"); Timekeeper.Start("load_char_skills_kno"); List <KnowledgeSkill> knoSkills = (from XmlNode node in skillNode.SelectNodes("knoskills/skill") let skill = (KnowledgeSkill)Skill.Load(_character, node) where skill != null select skill).ToList(); foreach (KnowledgeSkill skill in knoSkills) { KnowledgeSkills.Add(skill); } Timekeeper.Finish("load_char_skills_kno"); Timekeeper.Start("load_char_knowsoft_buffer"); // Knowsoft Buffer. XmlNodeList objXmlKnowsoftBuffer = skillNode.SelectNodes("skilljackknowledgeskills/skill"); foreach (XmlNode objXmlSkill in objXmlKnowsoftBuffer) { string strName = objXmlSkill["name"].InnerText; KnowsoftSkills.Add(new KnowledgeSkill(_character, strName)); } Timekeeper.Finish("load_char_knowsoft_buffer"); } else { XmlNodeList oldskills = skillNode.SelectNodes("skills/skill"); List <Skill> tempoerySkillList = (from XmlNode node in oldskills let skill = Skill.LegacyLoad(_character, node) where skill != null select skill).ToList(); List <Skill> unsoredSkills = new List <Skill>(); //Variable/Anon method as to not clutter anywhere else. Not sure if clever or stupid Predicate <Skill> oldSkillFilter = skill => { if (skill.Rating > 0) { return(true); } if (skill.SkillCategory == "Resonance Active" && !_character.RESEnabled) { return(false); } //This could be more fine grained, but frankly i don't care if (skill.SkillCategory == "Magical Active" && !_character.MAGEnabled) { return(false); } return(true); }; foreach (Skill skill in tempoerySkillList) { KnowledgeSkill knoSkill = skill as KnowledgeSkill; if (knoSkill != null) { KnowledgeSkills.Add(knoSkill); } else if (oldSkillFilter(skill)) { unsoredSkills.Add(skill); } } unsoredSkills.Sort(CompareSkills); unsoredSkills.ForEach(x => _skills.Add(x)); UpdateUndoList(skillNode); //remove skillgroups whose skills did not make the final cut for (var i = SkillGroups.Count - 1; i >= 0; i--) { if (SkillGroups[i].GetEnumerable().Any(x => Skills.Contains(x))) { continue; } SkillGroups.RemoveAt(i); } } //Workaround for probably breaking compability between earlier beta builds if (skillNode["skillptsmax"] == null) { skillNode = skillNode.OwnerDocument["character"]; } SkillPointsMaximum = Convert.ToInt32(skillNode["skillptsmax"].InnerText); SkillGroupPointsMaximum = Convert.ToInt32(skillNode["skillgrpsmax"].InnerText); skillNode.TryGetField("uneducated", out _blnUneducated); skillNode.TryGetField("uncouth", out _blnUncouth); skillNode.TryGetField("schoolofhardknocks", out _blnSchoolOfHardKnocks); skillNode.TryGetField("collegeeducation", out _blnCollegeEducation); skillNode.TryGetField("jackofalltrades", out _blnJackOfAllTrades); skillNode.TryGetField("techschool", out _blnTechSchool); skillNode.TryGetField("linguist", out _blnLinguist); Timekeeper.Finish("load_char_skills"); }