示例#1
0
        internal void RemoveSkills(FilterOptions skills, bool createKnowledge = true)
        {
            string strCategory;

            switch (skills)
            {
            case FilterOptions.Magician:
            case FilterOptions.Sorcery:
            case FilterOptions.Conjuring:
            case FilterOptions.Enchanting:
            case FilterOptions.Adept:
                strCategory = "Magical Active";
                break;

            case FilterOptions.Technomancer:
                strCategory = "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 _objCharacter.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 == strCategory)
                {
                    return;
                }
            }

            for (int i = Skills.Count - 1; i >= 0; i--)
            {
                if (Skills[i].SkillCategory == strCategory)
                {
                    Skill skill = Skills[i];
                    _dicSkillBackups.Add(skill.SkillId, skill);
                    Skills.RemoveAt(i);
                    SkillsDictionary.Remove(skill.IsExoticSkill ? skill.Name + " (" + skill.DisplaySpecializationMethod(GlobalOptions.DefaultLanguage) + ')' : skill.Name);

                    if (_objCharacter.Created && skill.TotalBaseRating > 0 && createKnowledge)
                    {
                        KnowledgeSkill kno = new KnowledgeSkill(_objCharacter)
                        {
                            Type          = skill.Name == "Arcana" ? "Academic" : "Professional",
                            WriteableName = skill.Name,
                            Base          = skill.Base,
                            Karma         = skill.Karma
                        };
                        kno.Specializations.AddRange(skill.Specializations);
                        KnowledgeSkills.MergeInto(kno, (x, y) => string.Compare(x.Type, y.Type, StringComparison.Ordinal) == 0 ? CompareSkills(x, y) : (string.Compare(x.Type, y.Type, StringComparison.Ordinal) == -1 ? -1 : 1), (objExistSkill, objNewSkill) =>
                        {
                            if (objNewSkill.Base > objExistSkill.Base)
                            {
                                objExistSkill.Base = objNewSkill.Base;
                            }
                            if (objNewSkill.Karma > objExistSkill.Karma)
                            {
                                objExistSkill.Karma = objNewSkill.Karma;
                            }
                            objExistSkill.Specializations.MergeInto(objNewSkill.Specializations, (x, y) => x.Free == y.Free ? string.Compare(x.DisplayName(GlobalOptions.Language), y.DisplayName(GlobalOptions.Language), StringComparison.Ordinal) : (x.Free ? 1 : -1));
                        });
                    }
                }
            }
            if (!_objCharacter.Created)
            {
                // zero out any skillgroups whose skills did not make the final cut
                foreach (SkillGroup objSkillGroup in SkillGroups)
                {
                    if (!objSkillGroup.SkillList.Any(x => SkillsDictionary.ContainsKey(x.Name)))
                    {
                        objSkillGroup.Base  = 0;
                        objSkillGroup.Karma = 0;
                    }
                }
            }
        }
示例#2
0
        internal void Load(XmlNode xmlSkillNode, bool blnLegacy = false)
        {
            if (xmlSkillNode == null)
            {
                return;
            }
            Timekeeper.Start("load_char_skills");

            if (!blnLegacy)
            {
                Timekeeper.Start("load_char_skills_groups");
                List <SkillGroup> lstLoadingSkillGroups = new List <SkillGroup>();
                using (XmlNodeList xmlGroupsList = xmlSkillNode.SelectNodes("groups/group"))
                    if (xmlGroupsList != null)
                    {
                        foreach (XmlNode xmlNode in xmlGroupsList)
                        {
                            SkillGroup objGroup = new SkillGroup(_objCharacter);
                            objGroup.Load(xmlNode);
                            lstLoadingSkillGroups.Add(objGroup);
                        }
                    }
                lstLoadingSkillGroups.Sort((i1, i2) => string.Compare(i2.DisplayName, i1.DisplayName, StringComparison.Ordinal));
                foreach (SkillGroup skillgroup in lstLoadingSkillGroups)
                {
                    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> lstLoadingSkills = new List <Skill>();
                using (XmlNodeList xmlSkillsList = xmlSkillNode.SelectNodes("skills/skill"))
                    if (xmlSkillsList != null)
                    {
                        foreach (XmlNode xmlNode in xmlSkillsList)
                        {
                            Skill objSkill = Skill.Load(_objCharacter, xmlNode);
                            if (objSkill != null)
                            {
                                lstLoadingSkills.Add(objSkill);
                            }
                        }
                    }
                lstLoadingSkills.Sort(CompareSkills);

                foreach (Skill objSkill in lstLoadingSkills)
                {
                    string strName = objSkill.IsExoticSkill
                        ? $"{objSkill.Name} ({objSkill.DisplaySpecializationMethod(GlobalOptions.DefaultLanguage)})"
                        : objSkill.Name;
                    bool blnDoAddToDictionary = true;
                    _lstSkills.MergeInto(objSkill, CompareSkills, (objExistSkill, objNewSkill) =>
                    {
                        blnDoAddToDictionary = false;
                        if (objNewSkill.Base > objExistSkill.Base)
                        {
                            objExistSkill.Base = objNewSkill.Base;
                        }
                        if (objNewSkill.Karma > objExistSkill.Karma)
                        {
                            objExistSkill.Karma = objNewSkill.Karma;
                        }
                        objExistSkill.Specializations.MergeInto(objNewSkill.Specializations, (x, y) => x.Free == y.Free ? string.Compare(x.DisplayName(GlobalOptions.Language), y.DisplayName(GlobalOptions.Language), StringComparison.Ordinal) : (x.Free ? 1 : -1));
                    });
                    if (blnDoAddToDictionary)
                    {
                        _dicSkills.Add(strName, objSkill);
                    }
                }
                // TODO: Skill groups don't refresh their CanIncrease property correctly when the last of their skills is being added, as the total basse rating will be zero. Call this here to force a refresh.
                foreach (SkillGroup g in SkillGroups)
                {
                    g.DoRefreshCareerIncrease();
                }
                Timekeeper.Finish("load_char_skills_normal");

                Timekeeper.Start("load_char_skills_kno");
                using (XmlNodeList xmlSkillsList = xmlSkillNode.SelectNodes("knoskills/skill"))
                    if (xmlSkillsList != null)
                    {
                        foreach (XmlNode xmlNode in xmlSkillsList)
                        {
                            if (Skill.Load(_objCharacter, xmlNode) is KnowledgeSkill objSkill)
                            {
                                KnowledgeSkills.Add(objSkill);
                            }
                        }
                    }
                Timekeeper.Finish("load_char_skills_kno");

                Timekeeper.Start("load_char_knowsoft_buffer");
                // Knowsoft Buffer.
                using (XmlNodeList xmlSkillsList = xmlSkillNode.SelectNodes("skilljackknowledgeskills/skill"))
                    if (xmlSkillsList != null)
                    {
                        foreach (XmlNode xmlNode in xmlSkillsList)
                        {
                            string strName = string.Empty;
                            if (xmlNode.TryGetStringFieldQuickly("name", ref strName))
                            {
                                KnowsoftSkills.Add(new KnowledgeSkill(_objCharacter, strName));
                            }
                        }
                    }
                Timekeeper.Finish("load_char_knowsoft_buffer");
            }
            else
            {
                List <Skill> lstTempSkillList = new List <Skill>();
                using (XmlNodeList xmlSkillsList = xmlSkillNode.SelectNodes("skills/skill"))
                    if (xmlSkillsList != null)
                    {
                        foreach (XmlNode xmlNode in xmlSkillsList)
                        {
                            Skill objSkill = Skill.LegacyLoad(_objCharacter, xmlNode);
                            if (objSkill != null)
                            {
                                lstTempSkillList.Add(objSkill);
                            }
                        }
                    }

                if (lstTempSkillList.Count > 0)
                {
                    List <Skill> lstUnsortedSkills = new List <Skill>();

                    //Variable/Anon method as to not clutter anywhere else. Not sure if clever or stupid
                    bool OldSkillFilter(Skill skill)
                    {
                        if (skill.Rating > 0)
                        {
                            return(true);
                        }

                        if (skill.SkillCategory == "Resonance Active" && !_objCharacter.RESEnabled)
                        {
                            return(false);
                        }

                        //This could be more fine grained, but frankly i don't care
                        if (skill.SkillCategory == "Magical Active" && !_objCharacter.MAGEnabled)
                        {
                            return(false);
                        }

                        return(true);
                    }

                    foreach (Skill objSkill in lstTempSkillList)
                    {
                        if (objSkill is KnowledgeSkill objKnoSkill)
                        {
                            KnowledgeSkills.Add(objKnoSkill);
                        }
                        else if (OldSkillFilter(objSkill))
                        {
                            lstUnsortedSkills.Add(objSkill);
                        }
                    }

                    lstUnsortedSkills.Sort(CompareSkills);

                    foreach (Skill objSkill in lstUnsortedSkills)
                    {
                        _lstSkills.Add(objSkill);
                        _dicSkills.Add(objSkill.IsExoticSkill ? objSkill.Name + " (" + objSkill.DisplaySpecializationMethod(GlobalOptions.DefaultLanguage) + ')' : objSkill.Name, objSkill);
                    }

                    UpdateUndoList(xmlSkillNode);
                }
            }

            //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?

            if (!_objCharacter.Created)
            {
                // zero out any skillgroups whose skills did not make the final cut
                foreach (SkillGroup objSkillGroup in SkillGroups)
                {
                    if (!objSkillGroup.SkillList.Any(x => SkillsDictionary.ContainsKey(x.Name)))
                    {
                        objSkillGroup.Base  = 0;
                        objSkillGroup.Karma = 0;
                    }
                }
            }

            //Workaround for probably breaking compability between earlier beta builds
            if (xmlSkillNode["skillptsmax"] == null)
            {
                xmlSkillNode = xmlSkillNode.OwnerDocument?["character"];
            }

            int intTmp = 0;

            if (xmlSkillNode.TryGetInt32FieldQuickly("skillptsmax", ref intTmp))
            {
                SkillPointsMaximum = intTmp;
            }
            if (xmlSkillNode.TryGetInt32FieldQuickly("skillgrpsmax", ref intTmp))
            {
                SkillGroupPointsMaximum = intTmp;
            }

            Timekeeper.Finish("load_char_skills");
        }