Ejemplo n.º 1
0
        public void CreateAllCritterPowersTest()
        {
            // Create a new Human character.
            Character objCharacter = new Character();

            objCharacter.LoadMetatype(Guid.Parse("e28e7075-f635-4c02-937c-e4fc61c51602"));

            TreeNode objNode = new TreeNode();

            XmlDocument objXmlDocument = XmlManager.Instance.Load("critterpowers.xml");

            foreach (XmlNode objXmlNode in objXmlDocument.SelectNodes("/chummer/powers/power"))
            {
                CritterPower objPower = new CritterPower(objCharacter);
                objPower.Create(objXmlNode, objCharacter, objNode, 0, "", false);
            }
        }
Ejemplo n.º 2
0
        public static bool TestNodeRequirements(XmlNode node, Character character, out string name,
                                                string strIgnoreQuality        = "", XmlDocument objMetatypeDocument = null, XmlDocument objCritterDocument = null,
                                                XmlDocument objQualityDocument = null)
        {
            XmlNode nameNode;

            switch (node.Name)
            {
            case "attribute":
                // Check to see if an Attribute meets a requirement.
                CharacterAttrib objAttribute =
                    character.GetAttribute(node["name"].InnerText);
                name = $"\n\t{objAttribute.DisplayAbbrev} {node["total"].InnerText}";
                return(objAttribute.TotalValue >=
                       Convert.ToInt32(node["total"].InnerText));

            case "attributetotal":
                // Check if the character's Attributes add up to a particular total.
                string strAttributes = Character.AttributeStrings.Aggregate(node["attributes"].InnerText,
                                                                            (current, strAttribute) => current.Replace(strAttribute, character.GetAttribute(strAttribute).DisplayAbbrev));
                name          = $"\n\t{strAttributes} {node["val"].InnerText}";
                strAttributes = Character.AttributeStrings.Aggregate(node["attributes"].InnerText,
                                                                     (current, strAttribute) => current.Replace(strAttribute, character.GetAttribute(strAttribute).Value.ToString()));
                XmlDocument     objXmlDocument = new XmlDocument();
                XPathNavigator  nav            = objXmlDocument.CreateNavigator();
                XPathExpression xprAttributes  = nav.Compile(strAttributes);
                return(Convert.ToInt32(nav.Evaluate(xprAttributes)) >= Convert.ToInt32(node["val"].InnerText));

            case "careerkarma":
                // Check Career Karma requirement.
                name = "\n\t" + LanguageManager.Instance.GetString("Message_SelectQuality_RequireKarma")
                       .Replace("{0}", node.InnerText);
                return(character.CareerKarma >= Convert.ToInt32(node.InnerText));

            case "critterpower":
                // Run through all of the Powers the character has and see if the current required item exists.
                if (character.CritterEnabled && character.CritterPowers != null)
                {
                    CritterPower critterPower = character.CritterPowers.FirstOrDefault(p => p.Name == node.InnerText);
                    if (critterPower != null)
                    {
                        name = critterPower.DisplayNameShort;
                        return(true);
                    }
                    XmlDocument critterPowers = XmlManager.Instance.Load("critterpowers.xml");
                    nameNode =
                        critterPowers.SelectSingleNode($"/chummer/powers/power[name = \"{node.InnerText}\"]");
                    name = nameNode["translate"] != null
                                                        ? "\n\t" + nameNode["translate"].InnerText
                                                        : "\n\t" + node.InnerText;
                    name += $" ({LanguageManager.Instance.GetString("Tab_Critter")})";
                    return(false);
                }
                break;

            case "bioware":
            case "cyberware":
            {
                int count = node.Attributes?["count"] != null?Convert.ToInt32(node.Attributes?["count"].InnerText) : 1;

                name  = null;
                name += node.Name == "cyberware"
                                                ? "\n\t" + LanguageManager.Instance.GetString("Label_Cyberware") + node.InnerText
                                                : "\n\t" + LanguageManager.Instance.GetString("Label_Bioware") + node.InnerText;
                return
                    (character.Cyberware.Count(
                         objCyberware =>
                         objCyberware.Name == node.InnerText && node.Attributes?["select"] == null ||
                         node.Attributes?["select"] != null && node.Attributes?["select"].InnerText == objCyberware.Location) >= count);
            }

            case "biowarecontains":
            case "cyberwarecontains":
            {
                int count = node.Attributes?["count"] != null?Convert.ToInt32(node.Attributes?["count"].InnerText) : 1;

                name  = null;
                name += node.Name == "cyberware"
                                                        ? "\n\t" + LanguageManager.Instance.GetString("Label_Cyberware") + node.InnerText
                                                        : "\n\t" + LanguageManager.Instance.GetString("Label_Bioware") + node.InnerText;
                Improvement.ImprovementSource source = Improvement.ImprovementSource.Cyberware;
                if (node.Name == "biowarecontains")
                {
                    source = Improvement.ImprovementSource.Bioware;
                }
                return(character.Cyberware.Count(objCyberware =>
                                                 objCyberware.SourceType == source && objCyberware.Name.Contains(node.InnerText) && node.Attributes?["select"] == null ||
                                                 node.Attributes?["select"] != null && node.Attributes?["select"].InnerText == objCyberware.Location) >= count);
            }

            case "damageresistance":
                // Damage Resistance must be a particular value.
                ImprovementManager objImprovementManager = new ImprovementManager(character);
                name = "\n\t" + LanguageManager.Instance.GetString("String_DamageResistance");
                return(character.BOD.TotalValue + objImprovementManager.ValueOf(Improvement.ImprovementType.DamageResistance) >=
                       Convert.ToInt32(node.InnerText));

            case "ess":
                if (node.Attributes["grade"] != null)
                {
                    decimal decGrade =
                        character.Cyberware.Where(
                            objCyberware =>
                            objCyberware.Grade.Name ==
                            node.Attributes?["grade"].InnerText)
                        .Sum(objCyberware => objCyberware.CalculatedESS);
                    if (node.InnerText.StartsWith("-"))
                    {
                        // Essence must be less than the value.
                        name = "\n\t" +
                               LanguageManager.Instance.GetString(
                            "Message_SelectQuality_RequireESSGradeBelow")
                               .Replace("{0}", node.InnerText)
                               .Replace("{1}", node.Attributes["grade"].InnerText)
                               .Replace("{2}", decGrade.ToString(CultureInfo.InvariantCulture));
                        return(decGrade <
                               Convert.ToDecimal(node.InnerText.Replace("-", string.Empty), GlobalOptions.InvariantCultureInfo));
                    }
                    // Essence must be equal to or greater than the value.
                    name = "\n\t" +
                           LanguageManager.Instance.GetString(
                        "Message_SelectQuality_RequireESSGradeAbove")
                           .Replace("{0}", node.InnerText)
                           .Replace("{1}", node.Attributes["grade"].InnerText)
                           .Replace("{2}", decGrade.ToString(CultureInfo.InvariantCulture));
                    return(decGrade >= Convert.ToDecimal(node.InnerText, GlobalOptions.InvariantCultureInfo));
                }
                // Check Essence requirement.
                if (node.InnerText.StartsWith("-"))
                {
                    // Essence must be less than the value.
                    name = "\n\t" +
                           LanguageManager.Instance.GetString(
                        "Message_SelectQuality_RequireESSBelow")
                           .Replace("{0}", node.InnerText)
                           .Replace("{1}", character.Essence.ToString(CultureInfo.InvariantCulture));
                    return(character.Essence <
                           Convert.ToDecimal(node.InnerText.Replace("-", string.Empty), GlobalOptions.InvariantCultureInfo));
                }
                // Essence must be equal to or greater than the value.
                name = "\n\t" +
                       LanguageManager.Instance.GetString(
                    "Message_SelectQuality_RequireESSAbove")
                       .Replace("{0}", node.InnerText)
                       .Replace("{1}", character.Essence.ToString(CultureInfo.InvariantCulture));
                return(character.Essence >= Convert.ToDecimal(node.InnerText, GlobalOptions.InvariantCultureInfo));

            case "group":
                // Check that clustered options are present (Magical Tradition + Skill 6, for example)
                string result = string.Empty;
                if (node.ChildNodes.Cast <XmlNode>().Any(childNode => !TestNodeRequirements(childNode, character, out result, strIgnoreQuality,
                                                                                            objMetatypeDocument,
                                                                                            objCritterDocument, objQualityDocument)))
                {
                    name = result;
                    return(false);
                }
                name = result;
                return(true);

            case "initiategrade":
                // Character's initiate grade must be higher than or equal to the required value.
                name = "\n\t" + LanguageManager.Instance.GetString("String_InitiateGrade") + " >= " + node.InnerText;
                return(character.InitiateGrade >= Convert.ToInt32(node.InnerText));

            case "martialtechnique":
                // Character needs a specific Martial Arts technique.
                XmlNode martialDoc = XmlManager.Instance.Load("martialarts.xml");
                nameNode = martialDoc.SelectSingleNode($"/chummer/techniques/technique[name = \"{node.InnerText}\"]");
                name     = nameNode["translate"] != null
                                                ? "\n\t" + nameNode["translate"].InnerText
                                                : "\n\t" + node.InnerText;
                name += $" ({LanguageManager.Instance.GetString("String_MartialArt")})";
                return(character.MartialArts.Any(martialart => martialart.Advantages.Any(technique => technique.Name == node.InnerText)));

            case "metamagic":
                XmlNode metamagicDoc = XmlManager.Instance.Load("metamagic.xml");
                nameNode =
                    metamagicDoc.SelectSingleNode($"/chummer/metamagics/metamagic[name = \"{node.InnerText}\"]");
                name = nameNode["translate"] != null
                                                ? "\n\t" + nameNode["translate"].InnerText
                                                : "\n\t" + node.InnerText;
                name += $" ({LanguageManager.Instance.GetString("String_Metamagic")})";
                return(character.Metamagics.Any(objMetamagic => objMetamagic.Name == node.InnerText));

            case "metamagicart":
            case "art":
                XmlNode metamagicArtDoc = XmlManager.Instance.Load("metamagic.xml");
                nameNode =
                    metamagicArtDoc.SelectSingleNode($"/chummer/arts/art[name = \"{node.InnerText}\"]");
                name = nameNode["translate"] != null
                                                ? "\n\t" + nameNode["translate"].InnerText
                                                : "\n\t" + node.InnerText;
                name += $" ({LanguageManager.Instance.GetString("String_Art")})";
                if (character.Options.IgnoreArt)
                {
                    if (node.Name == "art")
                    {
                        return(true);
                    }
                    foreach (Metamagic metamagic in character.Metamagics)
                    {
                        XmlNode metaNode =
                            metamagicArtDoc.SelectSingleNode($"/chummer/metamagics/metamagic[name = \"{metamagic.Name}\"]/required");
                        if (metaNode?.InnerXml.Contains($"<art>{node.InnerText}</art>") == true)
                        {
                            return(metaNode.InnerXml.Contains($"<art>{node.InnerText}</art>"));
                        }
                        metaNode =
                            metamagicArtDoc.SelectSingleNode($"/chummer/metamagics/metamagic[name = \"{metamagic.Name}\"]/forbidden");
                        if (metaNode?.InnerXml.Contains($"<art>{node.InnerText}</art>") == true)
                        {
                            return(metaNode.InnerXml.Contains($"<art>{node.InnerText}</art>"));
                        }
                    }
                    return(false);
                }
                return(character.Arts.Any(art => art.Name == node.InnerText));

            case "metatype":
                // Check the Metatype restriction.
                nameNode =
                    objMetatypeDocument.SelectSingleNode($"/chummer/metatypes/metatype[name = \"{node.InnerText}\"]") ??
                    objCritterDocument.SelectSingleNode($"/chummer/metatypes/metatype[name = \"{node.InnerText}\"]");
                name = nameNode["translate"] != null
                                                ? "\n\t" + nameNode["translate"].InnerText
                                                : "\n\t" + node.InnerText;
                name += $" ({LanguageManager.Instance.GetString("String_Metatype")})";
                return(node.InnerText == character.Metatype);

            case "metatypecategory":
                // Check the Metatype Category restriction.
                nameNode =
                    objMetatypeDocument.SelectSingleNode($"/chummer/categories/category[. = \"{node.InnerText}\"]") ??
                    objCritterDocument.SelectSingleNode($"/chummer/categories/category[. = \"{node.InnerText}\"]");
                name = nameNode?.Attributes["translate"] != null
                                                ? "\n\t" + nameNode.Attributes["translate"].InnerText
                                                : "\n\t" + node.InnerText;
                name += LanguageManager.Instance.GetString("String_MetatypeCategory");
                return(node.InnerText == character.MetatypeCategory);

            case "metavariant":
                // Check the Metavariant restriction.
                nameNode =
                    objMetatypeDocument.SelectSingleNode($"/chummer/metavariants/metavariant[name = \"{node.InnerText}\"]") ??
                    objCritterDocument.SelectSingleNode($"/chummer/metavariants/metavariant[name = \"{node.InnerText}\"]");
                name = nameNode["translate"] != null
                                                ? "\n\t" + nameNode["translate"].InnerText
                                                : "\n\t" + node.InnerText;
                name += $" ({LanguageManager.Instance.GetString("String_Metavariant")})";
                return(node.InnerText == character.Metavariant);

            case "power":
                // Run through all of the Powers the character has and see if the current required item exists.
                Power power = character.Powers.FirstOrDefault(p => p.Name == node.InnerText);
                if (power != null)
                {
                    name = power.DisplayNameShort;
                    return(true);
                }
                XmlDocument xmlPowers = XmlManager.Instance.Load("powers.xml");
                nameNode =
                    xmlPowers.SelectSingleNode($"/chummer/powers/power[name = \"{node.InnerText}\"]");
                name = nameNode["translate"] != null
                                                ? "\n\t" + nameNode["translate"].InnerText
                                                : "\n\t" + node.InnerText;
                name += $" ({LanguageManager.Instance.GetString("Tab_Adept")})";
                return(false);

            case "quality":
                Quality quality =
                    character.Qualities.FirstOrDefault(q => q.Name == node.InnerText && q.Name != strIgnoreQuality);
                if (quality != null)
                {
                    name = quality.DisplayNameShort;
                    return(true);
                }
                // ReSharper disable once RedundantIfElseBlock (Suppresses node warning)
                else
                {
                    nameNode =
                        objQualityDocument.SelectSingleNode($"/chummer/qualities/quality[name = \"{node.InnerText}\"]");
                    name = nameNode?["translate"] != null
                                                        ? "\n\t" + nameNode["translate"].InnerText
                                                        : "\n\t" + node.InnerText;
                    name += $" ({LanguageManager.Instance.GetString("String_Quality")})";
                    return(false);
                }

            case "skill":
                // Check if the character has the required Skill.
                if (node["type"] != null)
                {
                    KnowledgeSkill s = character.SkillsSection.KnowledgeSkills
                                       .Where(objSkill => objSkill.Name == node["name"]?.InnerText &&
                                              (node["spec"] == null ||
                                               objSkill.Specializations.Any(objSpec => objSpec.Name == node["spec"]?.InnerText)))
                                       .FirstOrDefault(objSkill => objSkill.LearnedRating >= Convert.ToInt32(node["val"]?.InnerText));

                    if (s != null)
                    {
                        name = s.DisplayName;
                        if (node["spec"] != null)
                        {
                            name += $" ({node["spec"].InnerText})";
                        }
                        if (node["val"] != null)
                        {
                            name += $" {node["val"].InnerText}";
                        }
                        return(true);
                    }
                }
                else
                {
                    Skill s = character.SkillsSection.Skills
                              .Where(objSkill => objSkill.Name == node["name"]?.InnerText &&
                                     (node["spec"] == null ||
                                      objSkill.Specializations.Any(objSpec => objSpec.Name == node["spec"]?.InnerText)))
                              .FirstOrDefault(objSkill => objSkill.LearnedRating >= Convert.ToInt32(node["val"]?.InnerText));

                    if (s != null)
                    {
                        name = s.DisplayName;
                        if (node["spec"] != null)
                        {
                            name += $" ({node["spec"].InnerText})";
                        }
                        if (node["val"] != null)
                        {
                            name += $" {node["val"].InnerText}";
                        }
                        return(true);
                    }
                }
                XmlDocument xmlSkills = XmlManager.Instance.Load("skills.xml");
                nameNode =
                    xmlSkills.SelectSingleNode($"/chummer/skills/skill[name = \"{node["name"].InnerText}\"]");
                name = nameNode?["translate"] != null
                                                ? "\n\t" + nameNode["translate"].InnerText
                                                : "\n\t" + node["name"].InnerText;
                if (node["spec"] != null)
                {
                    name += $" ({node["spec"].InnerText})";
                }
                if (node["val"] != null)
                {
                    name += $" {node["val"].InnerText}";
                }
                name += $" ({LanguageManager.Instance.GetString("Tab_Skills")})";
                return(false);

            case "skillgrouptotal":
                {
                    // Check if the total combined Ratings of Skill Groups adds up to a particular total.
                    int    intTotal  = 0;
                    var    strGroups = node["skillgroups"].InnerText.Split('+');
                    string outString = "\n\t";
                    for (int i = 0; i <= strGroups.Length - 1; i++)
                    {
                        foreach (SkillGroup objGroup in character.SkillsSection.SkillGroups)
                        {
                            if (objGroup.Name == strGroups[i])
                            {
                                outString += objGroup.DisplayName + ", ";
                                intTotal  += objGroup.Rating;
                                break;
                            }
                        }
                    }
                    name  = outString;
                    name += $" ({LanguageManager.Instance.GetString("String_ExpenseSkillGroup")})";
                    return(intTotal >= Convert.ToInt32(node["val"].InnerText));
                }

            case "spell":
                // Check for a specific Spell.
                XmlDocument xmlSpell = XmlManager.Instance.Load("spells.xml");
                nameNode =
                    xmlSpell.SelectSingleNode($"/chummer/spells/spell[name = \"{node.InnerText}\"]");
                name = nameNode["translate"] != null
                                                ? "\n\t" + nameNode["translate"].InnerText
                                                : "\n\t" + node.InnerText;
                name += $" ({LanguageManager.Instance.GetString("String_DescSpell")})";
                return(character.Spells.Any(spell => spell.Name == node.InnerText));

            case "spellcategory":
                // Check for a specified amount of a particular Spell category.
                XmlDocument xmlSpells = XmlManager.Instance.Load("spells.xml");
                nameNode =
                    xmlSpells.SelectSingleNode($"/chummer/categories/category[. = \"{node["name"].InnerText}\"]");
                name = nameNode["translate"] != null
                                                ? "\n\t" + nameNode["translate"].InnerText
                                                : "\n\t" + node.InnerText;
                name += $" ({LanguageManager.Instance.GetString("String_SpellCategory")})";
                return(character.Spells.Count(objSpell => objSpell.Category == node["name"].InnerText) >= Convert.ToInt32(node["count"].InnerText));

            case "spelldescriptor":
                // Check for a specified amount of a particular Spell Descriptor.
                name = "\n\t" + LanguageManager.Instance.GetString("Label_Descriptors") + " >= " + node["count"].InnerText;
                return(character.Spells.Count(objSpell => objSpell.Descriptors.Contains(node["name"].InnerText)) >= Convert.ToInt32(node["count"].InnerText));

            case "streetcredvsnotoriety":
                // Street Cred must be higher than Notoriety.
                name = "\n\t" + LanguageManager.Instance.GetString("String_StreetCred") + " >= " +
                       LanguageManager.Instance.GetString("String_Notoriety");
                return(character.StreetCred >= character.Notoriety);

            case "tradition":
                // Character needs a specific Tradition.
                XmlDocument xmlTradition = XmlManager.Instance.Load("traditions.xml");
                nameNode =
                    xmlTradition.SelectSingleNode($"/chummer/traditions/tradition[name = \"{node.InnerText}\"]");
                name = nameNode["translate"] != null
                                                ? "\n\t" + nameNode["translate"].InnerText
                                                : "\n\t" + node.InnerText;
                name += $" ({LanguageManager.Instance.GetString("String_Tradition")})";
                return(character.MagicTradition == node.InnerText);

            default:
                Utils.BreakIfDebug();
                break;
            }
            name = node.InnerText;
            return(false);
        }
Ejemplo n.º 3
0
        private string GetName(Improvement source)
        {
            string value = string.Empty;

            switch (source.ImproveSource)
            {
            case Improvement.ImprovementSource.Bioware:
            case Improvement.ImprovementSource.Cyberware:
            {
                Cyberware q = _character.Cyberware.DeepFirstOrDefault(x => x.Children, x => x.InternalId == source.SourceName);
                value = q?.DisplayNameShort;
            }
            break;

            case Improvement.ImprovementSource.MartialArtAdvantage:
            {
                MartialArtAdvantage objAdvantage = CommonFunctions.FindMartialArtAdvantage(source.SourceName, _character.MartialArts);
                value = objAdvantage?.DisplayName;
            }
            break;

            case Improvement.ImprovementSource.Armor:
            {
                Armor objArmor = _character.Armor.FirstOrDefault(x => x.InternalId == source.SourceName);
                value = objArmor?.DisplayName;
            }
            break;

            case Improvement.ImprovementSource.ArmorMod:
            {
                ArmorMod objArmorMod = CommonFunctions.FindArmorMod(source.SourceName, _character.Armor);
                value = objArmorMod?.DisplayName;
            }
            break;

            case Improvement.ImprovementSource.CritterPower:
            {
                CritterPower objCritterPower = _character.CritterPowers.FirstOrDefault(x => x.InternalId == source.SourceName);
                value = objCritterPower?.DisplayName;
            }
            break;

            case Improvement.ImprovementSource.Quality:
            {
                Quality q = _character.Qualities.FirstOrDefault(x => x.InternalId == source.SourceName);
                value = q?.DisplayName;
            }
            break;

            case Improvement.ImprovementSource.Power:
            {
                Power power = _character.Powers.FirstOrDefault(x => x.InternalId == source.SourceName);
                value = power?.DisplayNameShort;
            }
            break;

            case Improvement.ImprovementSource.Custom:
            {
                return(source.CustomName);
            }

            case Improvement.ImprovementSource.Gear:
            {
                Gear objGear = _character.Gear.DeepFirstOrDefault(x => x.Children, x => x.InternalId == source.SourceName);
                if (objGear == null)
                {
                    objGear = CommonFunctions.FindArmorGear(source.SourceName, _character.Armor);
                    if (objGear == null)
                    {
                        objGear = CommonFunctions.FindWeaponGear(source.SourceName, _character.Weapons);
                        if (objGear == null)
                        {
                            objGear = CommonFunctions.FindCyberwareGear(source.SourceName, _character.Cyberware);
                            if (objGear == null)
                            {
                                objGear = CommonFunctions.FindVehicleGear(source.SourceName, _character.Vehicles);
                            }
                        }
                    }
                }
                value = objGear?.DisplayName;
            }
            break;

            default:
                return(source.SourceName);
            }

            if (string.IsNullOrEmpty(value))
            {
                Log.Warning(new object[] { "Skill Tooltip GetName value = null", source.SourceName, source.ImproveSource, source.ImproveType, source.ImprovedName });
                return(source.ImproveSource + " source not found");
            }
            return(value);
        }