示例#1
0
        private void tsAttachCharacter_Click(object sender, EventArgs e)
        {
            // Prompt the user to select a save file to associate with this Contact.
            OpenFileDialog openFileDialog = new OpenFileDialog
            {
                Filter = LanguageManager.GetString("DialogFilter_Chum5", GlobalOptions.Language) + '|' + LanguageManager.GetString("DialogFilter_All", GlobalOptions.Language)
            };

            if (!string.IsNullOrEmpty(_objSpirit.FileName) && File.Exists(_objSpirit.FileName))
            {
                openFileDialog.InitialDirectory = Path.GetDirectoryName(_objSpirit.FileName);
                openFileDialog.FileName         = Path.GetFileName(_objSpirit.FileName);
            }
            if (openFileDialog.ShowDialog(this) == DialogResult.OK)
            {
                _objSpirit.FileName = openFileDialog.FileName;
                imgLink.SetToolTip(LanguageManager.GetString(_objSpirit.EntityType == SpiritType.Spirit ? "Tip_Spirit_OpenFile" : "Tip_Sprite_OpenFile", GlobalOptions.Language));
                ContactDetailChanged?.Invoke(this, e);
            }
        }
示例#2
0
        private void imgNotes_Click(object sender, EventArgs e)
        {
            using (frmNotes frmContactNotes = new frmNotes(_objContact.Notes))
            {
                frmContactNotes.ShowDialog(this);
                if (frmContactNotes.DialogResult != DialogResult.OK)
                {
                    return;
                }
                _objContact.Notes = frmContactNotes.Notes;
            }

            string strTooltip = LanguageManager.GetString(_objContact.EntityType == ContactType.Enemy ? "Tip_Enemy_EditNotes" : "Tip_Contact_EditNotes");

            if (!string.IsNullOrEmpty(_objContact.Notes))
            {
                strTooltip += Environment.NewLine + Environment.NewLine + _objContact.Notes;
            }
            imgNotes.SetToolTip(strTooltip.WordWrap());
            ContactDetailChanged?.Invoke(this, new TextEventArgs("Notes"));
        }
示例#3
0
        private async void cmdNotes_Click(object sender, EventArgs e)
        {
            using (ThreadSafeForm <EditNotes> frmSpiritNotes = await ThreadSafeForm <EditNotes> .GetAsync(() => new EditNotes(_objSpirit.Notes, _objSpirit.NotesColor)))
            {
                if (await frmSpiritNotes.ShowDialogSafeAsync(_objSpirit.CharacterObject) != DialogResult.OK)
                {
                    return;
                }
                _objSpirit.Notes = frmSpiritNotes.MyForm.Notes;
            }

            string strTooltip = await LanguageManager.GetStringAsync(_objSpirit.EntityType == SpiritType.Spirit? "Tip_Spirit_EditNotes" : "Tip_Sprite_EditNotes");

            if (!string.IsNullOrEmpty(_objSpirit.Notes))
            {
                strTooltip += Environment.NewLine + Environment.NewLine + _objSpirit.Notes;
            }
            await cmdNotes.SetToolTipTextAsync(strTooltip.WordWrap());

            ContactDetailChanged?.Invoke(this, e);
        }
示例#4
0
        private async void tsRemoveCharacter_Click(object sender, EventArgs e)
        {
            // Remove the file association from the Contact.
            if (Program.ShowMessageBox(await LanguageManager.GetStringAsync("Message_RemoveCharacterAssociation"), await LanguageManager.GetStringAsync("MessageTitle_RemoveCharacterAssociation"), MessageBoxButtons.YesNo, MessageBoxIcon.Question) == DialogResult.Yes)
            {
                _objSpirit.FileName         = string.Empty;
                _objSpirit.RelativeFileName = string.Empty;
                string strText = await LanguageManager.GetStringAsync(
                    _objSpirit.EntityType == SpiritType.Spirit? "Tip_Spirit_LinkSpirit" : "Tip_Sprite_LinkSprite");

                await cmdLink.SetToolTipTextAsync(strText);

                // Set the relative path.
                Uri uriApplication = new Uri(Utils.GetStartupPath);
                Uri uriFile        = new Uri(_objSpirit.FileName);
                Uri uriRelative    = uriApplication.MakeRelativeUri(uriFile);
                _objSpirit.RelativeFileName = "../" + uriRelative;

                ContactDetailChanged?.Invoke(this, e);
            }
        }
        private void imgNotes_Click(object sender, EventArgs e)
        {
            frmNotes frmContactNotes = new frmNotes
            {
                Notes = _objContact.Notes
            };

            frmContactNotes.ShowDialog(this);

            if (frmContactNotes.DialogResult == DialogResult.OK && _objContact.Notes != frmContactNotes.Notes)
            {
                _objContact.Notes = frmContactNotes.Notes;

                string strTooltip = LanguageManager.GetString(_objContact.EntityType == ContactType.Enemy ? "Tip_Enemy_EditNotes" : "Tip_Contact_EditNotes", GlobalOptions.Language);
                if (!string.IsNullOrEmpty(_objContact.Notes))
                {
                    strTooltip += Environment.NewLine + Environment.NewLine + _objContact.Notes;
                }
                tipTooltip.SetToolTip(imgNotes, strTooltip.WordWrap(100));
                ContactDetailChanged?.Invoke(this, new TextEventArgs("Notes"));
            }
        }
示例#6
0
        private async void cmdNotes_Click(object sender, EventArgs e)
        {
            using (EditNotes frmContactNotes = new EditNotes(_objContact.Notes, _objContact.NotesColor))
            {
                await frmContactNotes.ShowDialogSafeAsync(this);

                if (frmContactNotes.DialogResult != DialogResult.OK)
                {
                    return;
                }
                _objContact.Notes = frmContactNotes.Notes;
            }

            string strTooltip = await LanguageManager.GetStringAsync("Tip_Contact_EditNotes");

            if (!string.IsNullOrEmpty(_objContact.Notes))
            {
                strTooltip += Environment.NewLine + Environment.NewLine + _objContact.Notes;
            }
            cmdNotes.ToolTipText = strTooltip.WordWrap();
            ContactDetailChanged?.Invoke(this, new TextEventArgs("Notes"));
        }
示例#7
0
        private async void tsAttachCharacter_Click(object sender, EventArgs e)
        {
            // Prompt the user to select a save file to associate with this Contact.
            using (OpenFileDialog openFileDialog = new OpenFileDialog
            {
                Filter = await LanguageManager.GetStringAsync("DialogFilter_Chum5") + '|' + await LanguageManager.GetStringAsync("DialogFilter_All")
            })
            {
                if (!string.IsNullOrEmpty(_objSpirit.FileName) && File.Exists(_objSpirit.FileName))
                {
                    openFileDialog.InitialDirectory = Path.GetDirectoryName(_objSpirit.FileName);
                    openFileDialog.FileName         = Path.GetFileName(_objSpirit.FileName);
                }

                if (openFileDialog.ShowDialog(this) == DialogResult.OK)
                {
                    _objSpirit.FileName = openFileDialog.FileName;
                    cmdLink.ToolTipText = await LanguageManager.GetStringAsync(_objSpirit.EntityType == SpiritType.Spirit? "Tip_Spirit_OpenFile" : "Tip_Sprite_OpenFile");

                    ContactDetailChanged?.Invoke(this, e);
                }
            }
        }
示例#8
0
        private void imgNotes_Click(object sender, EventArgs e)
        {
            frmNotes frmSpritNotes = new frmNotes
            {
                Notes = _objSpirit.Notes
            };

            frmSpritNotes.ShowDialog(this);

            if (frmSpritNotes.DialogResult == DialogResult.OK && _objSpirit.Notes != frmSpritNotes.Notes)
            {
                _objSpirit.Notes = frmSpritNotes.Notes;

                string strTooltip = LanguageManager.GetString(_objSpirit.EntityType == SpiritType.Spirit ? "Tip_Spirit_EditNotes" : "Tip_Sprite_EditNotes", GlobalOptions.Language);

                if (!string.IsNullOrEmpty(_objSpirit.Notes))
                {
                    strTooltip += "\n\n" + _objSpirit.Notes;
                }
                tipTooltip.SetToolTip(imgNotes, strTooltip.WordWrap(100));

                ContactDetailChanged?.Invoke(this, e);
            }
        }
示例#9
0
        /// <summary>
        /// Create a Critter, put them into Career Mode, link them, and open the newly-created Critter.
        /// </summary>
        /// <param name="strCritterName">Name of the Critter's Metatype.</param>
        /// <param name="intForce">Critter's Force.</param>
        private void CreateCritter(string strCritterName, int intForce)
        {
            // Code from frmMetatype.
            XmlDocument objXmlDocument = XmlManager.Load("critters.xml");

            XmlNode objXmlMetatype = objXmlDocument.SelectSingleNode("/chummer/metatypes/metatype[name = \"" + strCritterName + "\"]");

            // If the Critter could not be found, show an error and get out of here.
            if (objXmlMetatype == null)
            {
                MessageBox.Show(LanguageManager.GetString("Message_UnknownCritterType", GlobalOptions.Language).Replace("{0}", strCritterName), LanguageManager.GetString("MessageTitle_SelectCritterType", GlobalOptions.Language), MessageBoxButtons.OK, MessageBoxIcon.Error);
                return;
            }

            // The Critter should use the same settings file as the character.
            Character objCharacter = new Character
            {
                SettingsFile = _objSpirit.CharacterObject.SettingsFile,

                // Override the defaults for the setting.
                IgnoreRules = true,
                IsCritter   = true,
                BuildMethod = CharacterBuildMethod.Karma,
                BuildPoints = 0
            };

            if (!string.IsNullOrEmpty(txtCritterName.Text))
            {
                objCharacter.Name = txtCritterName.Text;
            }

            // Ask the user to select a filename for the new character.
            string strForce = LanguageManager.GetString("String_Force", GlobalOptions.Language);

            if (_objSpirit.EntityType == SpiritType.Sprite)
            {
                strForce = LanguageManager.GetString("String_Rating", GlobalOptions.Language);
            }
            SaveFileDialog saveFileDialog = new SaveFileDialog
            {
                Filter   = LanguageManager.GetString("DialogFilter_Chum5", GlobalOptions.Language) + '|' + LanguageManager.GetString("DialogFilter_All", GlobalOptions.Language),
                FileName = strCritterName + " (" + strForce + ' ' + _objSpirit.Force.ToString() + ").chum5"
            };

            if (saveFileDialog.ShowDialog(this) == DialogResult.OK)
            {
                string strFileName = saveFileDialog.FileName;
                objCharacter.FileName = strFileName;
            }
            else
            {
                objCharacter.DeleteCharacter();
                return;
            }

            Cursor = Cursors.WaitCursor;

            // Set Metatype information.
            if (strCritterName == "Ally Spirit")
            {
                objCharacter.BOD.AssignLimits(ExpressionToString(objXmlMetatype["bodmin"]?.InnerText, intForce, 0), ExpressionToString(objXmlMetatype["bodmax"]?.InnerText, intForce, 0), ExpressionToString(objXmlMetatype["bodaug"]?.InnerText, intForce, 0));
                objCharacter.AGI.AssignLimits(ExpressionToString(objXmlMetatype["agimin"]?.InnerText, intForce, 0), ExpressionToString(objXmlMetatype["agimax"]?.InnerText, intForce, 0), ExpressionToString(objXmlMetatype["agiaug"]?.InnerText, intForce, 0));
                objCharacter.REA.AssignLimits(ExpressionToString(objXmlMetatype["reamin"]?.InnerText, intForce, 0), ExpressionToString(objXmlMetatype["reamax"]?.InnerText, intForce, 0), ExpressionToString(objXmlMetatype["reaaug"]?.InnerText, intForce, 0));
                objCharacter.STR.AssignLimits(ExpressionToString(objXmlMetatype["strmin"]?.InnerText, intForce, 0), ExpressionToString(objXmlMetatype["strmax"]?.InnerText, intForce, 0), ExpressionToString(objXmlMetatype["straug"]?.InnerText, intForce, 0));
                objCharacter.CHA.AssignLimits(ExpressionToString(objXmlMetatype["chamin"]?.InnerText, intForce, 0), ExpressionToString(objXmlMetatype["chamax"]?.InnerText, intForce, 0), ExpressionToString(objXmlMetatype["chaaug"]?.InnerText, intForce, 0));
                objCharacter.INT.AssignLimits(ExpressionToString(objXmlMetatype["intmin"]?.InnerText, intForce, 0), ExpressionToString(objXmlMetatype["intmax"]?.InnerText, intForce, 0), ExpressionToString(objXmlMetatype["intaug"]?.InnerText, intForce, 0));
                objCharacter.LOG.AssignLimits(ExpressionToString(objXmlMetatype["logmin"]?.InnerText, intForce, 0), ExpressionToString(objXmlMetatype["logmax"]?.InnerText, intForce, 0), ExpressionToString(objXmlMetatype["logaug"]?.InnerText, intForce, 0));
                objCharacter.WIL.AssignLimits(ExpressionToString(objXmlMetatype["wilmin"]?.InnerText, intForce, 0), ExpressionToString(objXmlMetatype["wilmax"]?.InnerText, intForce, 0), ExpressionToString(objXmlMetatype["wilaug"]?.InnerText, intForce, 0));
                objCharacter.MAG.AssignLimits(ExpressionToString(objXmlMetatype["magmin"]?.InnerText, intForce, 0), ExpressionToString(objXmlMetatype["magmax"]?.InnerText, intForce, 0), ExpressionToString(objXmlMetatype["magaug"]?.InnerText, intForce, 0));
                objCharacter.RES.AssignLimits(ExpressionToString(objXmlMetatype["resmin"]?.InnerText, intForce, 0), ExpressionToString(objXmlMetatype["resmax"]?.InnerText, intForce, 0), ExpressionToString(objXmlMetatype["resaug"]?.InnerText, intForce, 0));
                objCharacter.EDG.AssignLimits(ExpressionToString(objXmlMetatype["edgmin"]?.InnerText, intForce, 0), ExpressionToString(objXmlMetatype["edgmax"]?.InnerText, intForce, 0), ExpressionToString(objXmlMetatype["edgaug"]?.InnerText, intForce, 0));
                objCharacter.ESS.AssignLimits(ExpressionToString(objXmlMetatype["essmin"]?.InnerText, intForce, 0), ExpressionToString(objXmlMetatype["essmax"]?.InnerText, intForce, 0), ExpressionToString(objXmlMetatype["essaug"]?.InnerText, intForce, 0));
            }
            else
            {
                int intMinModifier = -3;
                objCharacter.BOD.AssignLimits(ExpressionToString(objXmlMetatype["bodmin"]?.InnerText, intForce, intMinModifier), ExpressionToString(objXmlMetatype["bodmin"]?.InnerText, intForce, 3), ExpressionToString(objXmlMetatype["bodmin"]?.InnerText, intForce, 3));
                objCharacter.AGI.AssignLimits(ExpressionToString(objXmlMetatype["agimin"]?.InnerText, intForce, intMinModifier), ExpressionToString(objXmlMetatype["agimin"]?.InnerText, intForce, 3), ExpressionToString(objXmlMetatype["agimin"]?.InnerText, intForce, 3));
                objCharacter.REA.AssignLimits(ExpressionToString(objXmlMetatype["reamin"]?.InnerText, intForce, intMinModifier), ExpressionToString(objXmlMetatype["reamin"]?.InnerText, intForce, 3), ExpressionToString(objXmlMetatype["reamin"]?.InnerText, intForce, 3));
                objCharacter.STR.AssignLimits(ExpressionToString(objXmlMetatype["strmin"]?.InnerText, intForce, intMinModifier), ExpressionToString(objXmlMetatype["strmin"]?.InnerText, intForce, 3), ExpressionToString(objXmlMetatype["strmin"]?.InnerText, intForce, 3));
                objCharacter.CHA.AssignLimits(ExpressionToString(objXmlMetatype["chamin"]?.InnerText, intForce, intMinModifier), ExpressionToString(objXmlMetatype["chamin"]?.InnerText, intForce, 3), ExpressionToString(objXmlMetatype["chamin"]?.InnerText, intForce, 3));
                objCharacter.INT.AssignLimits(ExpressionToString(objXmlMetatype["intmin"]?.InnerText, intForce, intMinModifier), ExpressionToString(objXmlMetatype["intmin"]?.InnerText, intForce, 3), ExpressionToString(objXmlMetatype["intmin"]?.InnerText, intForce, 3));
                objCharacter.LOG.AssignLimits(ExpressionToString(objXmlMetatype["logmin"]?.InnerText, intForce, intMinModifier), ExpressionToString(objXmlMetatype["logmin"]?.InnerText, intForce, 3), ExpressionToString(objXmlMetatype["logmin"]?.InnerText, intForce, 3));
                objCharacter.WIL.AssignLimits(ExpressionToString(objXmlMetatype["wilmin"]?.InnerText, intForce, intMinModifier), ExpressionToString(objXmlMetatype["wilmin"]?.InnerText, intForce, 3), ExpressionToString(objXmlMetatype["wilmin"]?.InnerText, intForce, 3));
                objCharacter.MAG.AssignLimits(ExpressionToString(objXmlMetatype["magmin"]?.InnerText, intForce, intMinModifier), ExpressionToString(objXmlMetatype["magmin"]?.InnerText, intForce, 3), ExpressionToString(objXmlMetatype["magmin"]?.InnerText, intForce, 3));
                objCharacter.RES.AssignLimits(ExpressionToString(objXmlMetatype["resmin"]?.InnerText, intForce, intMinModifier), ExpressionToString(objXmlMetatype["resmin"]?.InnerText, intForce, 3), ExpressionToString(objXmlMetatype["resmin"]?.InnerText, intForce, 3));
                objCharacter.EDG.AssignLimits(ExpressionToString(objXmlMetatype["edgmin"]?.InnerText, intForce, intMinModifier), ExpressionToString(objXmlMetatype["edgmin"]?.InnerText, intForce, 3), ExpressionToString(objXmlMetatype["edgmin"]?.InnerText, intForce, 3));
                objCharacter.ESS.AssignLimits(ExpressionToString(objXmlMetatype["essmin"]?.InnerText, intForce, 0), ExpressionToString(objXmlMetatype["essmax"]?.InnerText, intForce, 0), ExpressionToString(objXmlMetatype["essaug"]?.InnerText, intForce, 0));
            }

            // If we're working with a Critter, set the Attributes to their default values.
            objCharacter.BOD.MetatypeMinimum = ExpressionToInt(objXmlMetatype["bodmin"]?.InnerText, intForce, 0);
            objCharacter.AGI.MetatypeMinimum = ExpressionToInt(objXmlMetatype["agimin"]?.InnerText, intForce, 0);
            objCharacter.REA.MetatypeMinimum = ExpressionToInt(objXmlMetatype["reamin"]?.InnerText, intForce, 0);
            objCharacter.STR.MetatypeMinimum = ExpressionToInt(objXmlMetatype["strmin"]?.InnerText, intForce, 0);
            objCharacter.CHA.MetatypeMinimum = ExpressionToInt(objXmlMetatype["chamin"]?.InnerText, intForce, 0);
            objCharacter.INT.MetatypeMinimum = ExpressionToInt(objXmlMetatype["intmin"]?.InnerText, intForce, 0);
            objCharacter.LOG.MetatypeMinimum = ExpressionToInt(objXmlMetatype["logmin"]?.InnerText, intForce, 0);
            objCharacter.WIL.MetatypeMinimum = ExpressionToInt(objXmlMetatype["wilmin"]?.InnerText, intForce, 0);
            objCharacter.MAG.MetatypeMinimum = ExpressionToInt(objXmlMetatype["magmin"]?.InnerText, intForce, 0);
            objCharacter.RES.MetatypeMinimum = ExpressionToInt(objXmlMetatype["resmin"]?.InnerText, intForce, 0);
            objCharacter.EDG.MetatypeMinimum = ExpressionToInt(objXmlMetatype["edgmin"]?.InnerText, intForce, 0);
            objCharacter.ESS.MetatypeMinimum = ExpressionToInt(objXmlMetatype["essmax"]?.InnerText, intForce, 0);

            // Sprites can never have Physical Attributes.
            if (objXmlMetatype["category"].InnerText.EndsWith("Sprite"))
            {
                objCharacter.BOD.AssignLimits("0", "0", "0");
                objCharacter.AGI.AssignLimits("0", "0", "0");
                objCharacter.REA.AssignLimits("0", "0", "0");
                objCharacter.STR.AssignLimits("0", "0", "0");
            }

            objCharacter.Metatype         = strCritterName;
            objCharacter.MetatypeCategory = objXmlMetatype["category"].InnerText;
            objCharacter.Metavariant      = string.Empty;
            objCharacter.MetatypeBP       = 0;

            if (objXmlMetatype["movement"] != null)
            {
                objCharacter.Movement = objXmlMetatype["movement"].InnerText;
            }
            // Load the Qualities file.
            XmlDocument objXmlQualityDocument = XmlManager.Load("qualities.xml");

            // Determine if the Metatype has any bonuses.
            if (objXmlMetatype.InnerXml.Contains("bonus"))
            {
                ImprovementManager.CreateImprovements(objCharacter, Improvement.ImprovementSource.Metatype, strCritterName, objXmlMetatype.SelectSingleNode("bonus"), false, 1, strCritterName);
            }

            // Create the Qualities that come with the Metatype.
            foreach (XmlNode objXmlQualityItem in objXmlMetatype.SelectNodes("qualities/*/quality"))
            {
                XmlNode       objXmlQuality = objXmlQualityDocument.SelectSingleNode("/chummer/qualities/quality[name = \"" + objXmlQualityItem.InnerText + "\"]");
                List <Weapon> lstWeapons    = new List <Weapon>();
                Quality       objQuality    = new Quality(objCharacter);
                string        strForceValue = objXmlQualityItem.Attributes?["select"]?.InnerText ?? string.Empty;
                QualitySource objSource     = objXmlQualityItem.Attributes["removable"]?.InnerText == bool.TrueString ? QualitySource.MetatypeRemovable : QualitySource.Metatype;
                objQuality.Create(objXmlQuality, objSource, lstWeapons, strForceValue);
                objCharacter.Qualities.Add(objQuality);

                // Add any created Weapons to the character.
                foreach (Weapon objWeapon in lstWeapons)
                {
                    objCharacter.Weapons.Add(objWeapon);
                }
            }

            // Add any Critter Powers the Metatype/Critter should have.
            XmlNode objXmlCritter = objXmlDocument.SelectSingleNode("/chummer/metatypes/metatype[name = \"" + objCharacter.Metatype + "\"]");

            objXmlDocument = XmlManager.Load("critterpowers.xml");
            foreach (XmlNode objXmlPower in objXmlCritter.SelectNodes("powers/power"))
            {
                XmlNode      objXmlCritterPower = objXmlDocument.SelectSingleNode("/chummer/powers/power[name = \"" + objXmlPower.InnerText + "\"]");
                CritterPower objPower           = new CritterPower(objCharacter);
                string       strForcedValue     = objXmlPower.Attributes?["select"]?.InnerText ?? string.Empty;
                int          intRating          = Convert.ToInt32(objXmlPower.Attributes?["rating"]?.InnerText);

                objPower.Create(objXmlCritterPower, intRating, strForcedValue);
                objCharacter.CritterPowers.Add(objPower);
            }

            if (objXmlCritter["optionalpowers"] != null)
            {
                //For every 3 full points of Force a spirit has, it may gain one Optional Power.
                for (int i = intForce - 3; i >= 0; i -= 3)
                {
                    XmlDocument objDummyDocument = new XmlDocument();
                    XmlNode     bonusNode        = objDummyDocument.CreateNode(XmlNodeType.Element, "bonus", null);
                    objDummyDocument.AppendChild(bonusNode);
                    XmlNode powerNode = objDummyDocument.ImportNode(objXmlMetatype["optionalpowers"].CloneNode(true), true);
                    objDummyDocument.ImportNode(powerNode, true);
                    bonusNode.AppendChild(powerNode);
                    ImprovementManager.CreateImprovements(objCharacter, Improvement.ImprovementSource.Metatype, objCharacter.Metatype, bonusNode, false, 1, objCharacter.Metatype);
                }
            }
            // Add any Complex Forms the Critter comes with (typically Sprites)
            XmlDocument objXmlProgramDocument = XmlManager.Load("complexforms.xml");

            foreach (XmlNode objXmlComplexForm in objXmlCritter.SelectNodes("complexforms/complexform"))
            {
                string      strForceValue         = objXmlComplexForm.Attributes?["select"]?.InnerText ?? string.Empty;
                XmlNode     objXmlComplexFormData = objXmlProgramDocument.SelectSingleNode("/chummer/complexforms/complexform[name = \"" + objXmlComplexForm.InnerText + "\"]");
                ComplexForm objComplexForm        = new ComplexForm(objCharacter);
                objComplexForm.Create(objXmlComplexFormData, strForceValue);
                objCharacter.ComplexForms.Add(objComplexForm);
            }

            // Add any Gear the Critter comes with (typically Programs for A.I.s)
            XmlDocument objXmlGearDocument = XmlManager.Load("gear.xml");

            foreach (XmlNode objXmlGear in objXmlCritter.SelectNodes("gears/gear"))
            {
                int intRating = 0;
                if (objXmlGear.Attributes["rating"] != null)
                {
                    intRating = ExpressionToInt(objXmlGear.Attributes["rating"].InnerText, decimal.ToInt32(nudForce.Value), 0);
                }
                string        strForceValue  = objXmlGear.Attributes?["select"]?.InnerText ?? string.Empty;
                XmlNode       objXmlGearItem = objXmlGearDocument.SelectSingleNode("/chummer/gears/gear[name = \"" + objXmlGear.InnerText + "\"]");
                Gear          objGear        = new Gear(objCharacter);
                List <Weapon> lstWeapons     = new List <Weapon>();
                objGear.Create(objXmlGearItem, intRating, lstWeapons, strForceValue);
                objGear.Cost = "0";
                objCharacter.Gear.Add(objGear);
            }

            // Add the Unarmed Attack Weapon to the character.
            objXmlDocument = XmlManager.Load("weapons.xml");
            XmlNode objXmlWeapon = objXmlDocument.SelectSingleNode("/chummer/weapons/weapon[name = \"Unarmed Attack\"]");

            if (objXmlWeapon != null)
            {
                List <Weapon> lstWeapons = new List <Weapon>();
                Weapon        objWeapon  = new Weapon(objCharacter);
                objWeapon.Create(objXmlWeapon, lstWeapons);
                objWeapon.ParentID = Guid.NewGuid().ToString("D"); // Unarmed Attack can never be removed
                objCharacter.Weapons.Add(objWeapon);
                foreach (Weapon objLoopWeapon in lstWeapons)
                {
                    objCharacter.Weapons.Add(objLoopWeapon);
                }
            }

            objCharacter.Alias   = strCritterName;
            objCharacter.Created = true;
            if (!objCharacter.Save())
            {
                Cursor = Cursors.Default;
                objCharacter.DeleteCharacter();
                return;
            }

            string strOpenFile = objCharacter.FileName;

            objCharacter.DeleteCharacter();

            // Link the newly-created Critter to the Spirit.
            _objSpirit.FileName = strOpenFile;
            tipTooltip.SetToolTip(imgLink, LanguageManager.GetString(_objSpirit.EntityType == SpiritType.Spirit ? "Tip_Spirit_OpenFile" : "Tip_Sprite_OpenFile", GlobalOptions.Language));
            ContactDetailChanged?.Invoke(this, null);

            Character objOpenCharacter = Program.MainForm.LoadCharacter(strOpenFile);

            Cursor = Cursors.Default;
            Program.MainForm.OpenCharacter(objOpenCharacter);
        }
示例#10
0
        /// <summary>
        /// Create a Critter, put them into Career Mode, link them, and open the newly-created Critter.
        /// </summary>
        /// <param name="strCritterName">Name of the Critter's Metatype.</param>
        /// <param name="intForce">Critter's Force.</param>
        private async void CreateCritter(string strCritterName, int intForce)
        {
            // Code from frmMetatype.
            XmlDocument objXmlDocument = await _objSpirit.CharacterObject.LoadDataAsync("critters.xml").ConfigureAwait(false);

            XmlNode objXmlMetatype = objXmlDocument.SelectSingleNode("/chummer/metatypes/metatype[name = " + strCritterName.CleanXPath() + "]");

            // If the Critter could not be found, show an error and get out of here.
            if (objXmlMetatype == null)
            {
                Program.MainForm.ShowMessageBox(string.Format(GlobalOptions.CultureInfo, LanguageManager.GetString("Message_UnknownCritterType"), strCritterName), LanguageManager.GetString("MessageTitle_SelectCritterType"), MessageBoxButtons.OK, MessageBoxIcon.Error);
                return;
            }

            using (new CursorWait(this))
            {
                // The Critter should use the same settings file as the character.
                using (Character objCharacter = new Character
                {
                    CharacterOptionsKey = _objSpirit.CharacterObject.CharacterOptionsKey,
                    // Override the defaults for the setting.
                    IgnoreRules = true,
                    IsCritter = true
                })
                {
                    if (!string.IsNullOrEmpty(txtCritterName.Text))
                    {
                        objCharacter.Name = txtCritterName.Text;
                    }

                    string strSpace = LanguageManager.GetString("String_Space");
                    using (SaveFileDialog saveFileDialog = new SaveFileDialog
                    {
                        Filter = LanguageManager.GetString("DialogFilter_Chum5") + '|' + LanguageManager.GetString("DialogFilter_All"),
                        FileName = strCritterName + strSpace + '(' + LanguageManager.GetString(_objSpirit.RatingLabel) + strSpace + _objSpirit.Force.ToString(GlobalOptions.InvariantCultureInfo) + ").chum5"
                    })
                    {
                        if (saveFileDialog.ShowDialog(this) != DialogResult.OK)
                        {
                            return;
                        }
                        string strFileName = saveFileDialog.FileName;
                        objCharacter.FileName = strFileName;
                    }

                    // Set Metatype information.
                    if (strCritterName == "Ally Spirit")
                    {
                        objCharacter.BOD.AssignLimits(
                            CommonFunctions.ExpressionToInt(objXmlMetatype["bodmin"]?.InnerText, intForce, 0, 0),
                            CommonFunctions.ExpressionToInt(objXmlMetatype["bodmax"]?.InnerText, intForce, 0, 0),
                            CommonFunctions.ExpressionToInt(objXmlMetatype["bodaug"]?.InnerText, intForce, 0, 0));
                        objCharacter.AGI.AssignLimits(
                            CommonFunctions.ExpressionToInt(objXmlMetatype["agimin"]?.InnerText, intForce, 0, 0),
                            CommonFunctions.ExpressionToInt(objXmlMetatype["agimax"]?.InnerText, intForce, 0, 0),
                            CommonFunctions.ExpressionToInt(objXmlMetatype["agiaug"]?.InnerText, intForce, 0, 0));
                        objCharacter.REA.AssignLimits(
                            CommonFunctions.ExpressionToInt(objXmlMetatype["reamin"]?.InnerText, intForce, 0, 0),
                            CommonFunctions.ExpressionToInt(objXmlMetatype["reamax"]?.InnerText, intForce, 0, 0),
                            CommonFunctions.ExpressionToInt(objXmlMetatype["reaaug"]?.InnerText, intForce, 0, 0));
                        objCharacter.STR.AssignLimits(
                            CommonFunctions.ExpressionToInt(objXmlMetatype["strmin"]?.InnerText, intForce, 0, 0),
                            CommonFunctions.ExpressionToInt(objXmlMetatype["strmax"]?.InnerText, intForce, 0, 0),
                            CommonFunctions.ExpressionToInt(objXmlMetatype["straug"]?.InnerText, intForce, 0, 0));
                        objCharacter.CHA.AssignLimits(
                            CommonFunctions.ExpressionToInt(objXmlMetatype["chamin"]?.InnerText, intForce, 0, 0),
                            CommonFunctions.ExpressionToInt(objXmlMetatype["chamax"]?.InnerText, intForce, 0, 0),
                            CommonFunctions.ExpressionToInt(objXmlMetatype["chaaug"]?.InnerText, intForce, 0, 0));
                        objCharacter.INT.AssignLimits(
                            CommonFunctions.ExpressionToInt(objXmlMetatype["intmin"]?.InnerText, intForce, 0, 0),
                            CommonFunctions.ExpressionToInt(objXmlMetatype["intmax"]?.InnerText, intForce, 0, 0),
                            CommonFunctions.ExpressionToInt(objXmlMetatype["intaug"]?.InnerText, intForce, 0, 0));
                        objCharacter.LOG.AssignLimits(
                            CommonFunctions.ExpressionToInt(objXmlMetatype["logmin"]?.InnerText, intForce, 0, 0),
                            CommonFunctions.ExpressionToInt(objXmlMetatype["logmax"]?.InnerText, intForce, 0, 0),
                            CommonFunctions.ExpressionToInt(objXmlMetatype["logaug"]?.InnerText, intForce, 0, 0));
                        objCharacter.WIL.AssignLimits(
                            CommonFunctions.ExpressionToInt(objXmlMetatype["wilmin"]?.InnerText, intForce, 0, 0),
                            CommonFunctions.ExpressionToInt(objXmlMetatype["wilmax"]?.InnerText, intForce, 0, 0),
                            CommonFunctions.ExpressionToInt(objXmlMetatype["wilaug"]?.InnerText, intForce, 0, 0));
                        objCharacter.MAG.AssignLimits(
                            CommonFunctions.ExpressionToInt(objXmlMetatype["magmin"]?.InnerText, intForce, 0, 0),
                            CommonFunctions.ExpressionToInt(objXmlMetatype["magmax"]?.InnerText, intForce, 0, 0),
                            CommonFunctions.ExpressionToInt(objXmlMetatype["magaug"]?.InnerText, intForce, 0, 0));
                        objCharacter.RES.AssignLimits(
                            CommonFunctions.ExpressionToInt(objXmlMetatype["resmin"]?.InnerText, intForce, 0, 0),
                            CommonFunctions.ExpressionToInt(objXmlMetatype["resmax"]?.InnerText, intForce, 0, 0),
                            CommonFunctions.ExpressionToInt(objXmlMetatype["resaug"]?.InnerText, intForce, 0, 0));
                        objCharacter.EDG.AssignLimits(
                            CommonFunctions.ExpressionToInt(objXmlMetatype["edgmin"]?.InnerText, intForce, 0, 0),
                            CommonFunctions.ExpressionToInt(objXmlMetatype["edgmax"]?.InnerText, intForce, 0, 0),
                            CommonFunctions.ExpressionToInt(objXmlMetatype["edgaug"]?.InnerText, intForce, 0, 0));
                        objCharacter.ESS.AssignLimits(
                            CommonFunctions.ExpressionToInt(objXmlMetatype["essmin"]?.InnerText, intForce, 0, 0),
                            CommonFunctions.ExpressionToInt(objXmlMetatype["essmax"]?.InnerText, intForce, 0, 0),
                            CommonFunctions.ExpressionToInt(objXmlMetatype["essaug"]?.InnerText, intForce, 0, 0));
                    }
                    else
                    {
                        int intMinModifier = -3;
                        objCharacter.BOD.AssignLimits(
                            CommonFunctions.ExpressionToInt(objXmlMetatype["bodmin"]?.InnerText, intForce, intMinModifier, 0),
                            CommonFunctions.ExpressionToInt(objXmlMetatype["bodmin"]?.InnerText, intForce, 3, 0),
                            CommonFunctions.ExpressionToInt(objXmlMetatype["bodmin"]?.InnerText, intForce, 3, 0));
                        objCharacter.AGI.AssignLimits(
                            CommonFunctions.ExpressionToInt(objXmlMetatype["agimin"]?.InnerText, intForce, intMinModifier, 0),
                            CommonFunctions.ExpressionToInt(objXmlMetatype["agimin"]?.InnerText, intForce, 3, 0),
                            CommonFunctions.ExpressionToInt(objXmlMetatype["agimin"]?.InnerText, intForce, 3, 0));
                        objCharacter.REA.AssignLimits(
                            CommonFunctions.ExpressionToInt(objXmlMetatype["reamin"]?.InnerText, intForce, intMinModifier, 0),
                            CommonFunctions.ExpressionToInt(objXmlMetatype["reamin"]?.InnerText, intForce, 3, 0),
                            CommonFunctions.ExpressionToInt(objXmlMetatype["reamin"]?.InnerText, intForce, 3, 0));
                        objCharacter.STR.AssignLimits(
                            CommonFunctions.ExpressionToInt(objXmlMetatype["strmin"]?.InnerText, intForce, intMinModifier, 0),
                            CommonFunctions.ExpressionToInt(objXmlMetatype["strmin"]?.InnerText, intForce, 3, 0),
                            CommonFunctions.ExpressionToInt(objXmlMetatype["strmin"]?.InnerText, intForce, 3, 0));
                        objCharacter.CHA.AssignLimits(
                            CommonFunctions.ExpressionToInt(objXmlMetatype["chamin"]?.InnerText, intForce, intMinModifier, 0),
                            CommonFunctions.ExpressionToInt(objXmlMetatype["chamin"]?.InnerText, intForce, 3, 0),
                            CommonFunctions.ExpressionToInt(objXmlMetatype["chamin"]?.InnerText, intForce, 3, 0));
                        objCharacter.INT.AssignLimits(
                            CommonFunctions.ExpressionToInt(objXmlMetatype["intmin"]?.InnerText, intForce, intMinModifier, 0),
                            CommonFunctions.ExpressionToInt(objXmlMetatype["intmin"]?.InnerText, intForce, 3, 0),
                            CommonFunctions.ExpressionToInt(objXmlMetatype["intmin"]?.InnerText, intForce, 3, 0));
                        objCharacter.LOG.AssignLimits(
                            CommonFunctions.ExpressionToInt(objXmlMetatype["logmin"]?.InnerText, intForce, intMinModifier, 0),
                            CommonFunctions.ExpressionToInt(objXmlMetatype["logmin"]?.InnerText, intForce, 3, 0),
                            CommonFunctions.ExpressionToInt(objXmlMetatype["logmin"]?.InnerText, intForce, 3, 0));
                        objCharacter.WIL.AssignLimits(
                            CommonFunctions.ExpressionToInt(objXmlMetatype["wilmin"]?.InnerText, intForce, intMinModifier, 0),
                            CommonFunctions.ExpressionToInt(objXmlMetatype["wilmin"]?.InnerText, intForce, 3, 0),
                            CommonFunctions.ExpressionToInt(objXmlMetatype["wilmin"]?.InnerText, intForce, 3, 0));
                        objCharacter.MAG.AssignLimits(
                            CommonFunctions.ExpressionToInt(objXmlMetatype["magmin"]?.InnerText, intForce, intMinModifier, 0),
                            CommonFunctions.ExpressionToInt(objXmlMetatype["magmin"]?.InnerText, intForce, 3, 0),
                            CommonFunctions.ExpressionToInt(objXmlMetatype["magmin"]?.InnerText, intForce, 3, 0));
                        objCharacter.RES.AssignLimits(
                            CommonFunctions.ExpressionToInt(objXmlMetatype["resmin"]?.InnerText, intForce, intMinModifier, 0),
                            CommonFunctions.ExpressionToInt(objXmlMetatype["resmin"]?.InnerText, intForce, 3, 0),
                            CommonFunctions.ExpressionToInt(objXmlMetatype["resmin"]?.InnerText, intForce, 3, 0));
                        objCharacter.EDG.AssignLimits(
                            CommonFunctions.ExpressionToInt(objXmlMetatype["edgmin"]?.InnerText, intForce, intMinModifier, 0),
                            CommonFunctions.ExpressionToInt(objXmlMetatype["edgmin"]?.InnerText, intForce, 3, 0),
                            CommonFunctions.ExpressionToInt(objXmlMetatype["edgmin"]?.InnerText, intForce, 3, 0));
                        objCharacter.ESS.AssignLimits(
                            CommonFunctions.ExpressionToInt(objXmlMetatype["essmin"]?.InnerText, intForce, 0, 0),
                            CommonFunctions.ExpressionToInt(objXmlMetatype["essmax"]?.InnerText, intForce, 0, 0),
                            CommonFunctions.ExpressionToInt(objXmlMetatype["essaug"]?.InnerText, intForce, 0, 0));
                    }

                    // If we're working with a Critter, set the Attributes to their default values.
                    objCharacter.BOD.MetatypeMinimum = CommonFunctions.ExpressionToInt(objXmlMetatype["bodmin"]?.InnerText, intForce, 0, 0);
                    objCharacter.AGI.MetatypeMinimum = CommonFunctions.ExpressionToInt(objXmlMetatype["agimin"]?.InnerText, intForce, 0, 0);
                    objCharacter.REA.MetatypeMinimum = CommonFunctions.ExpressionToInt(objXmlMetatype["reamin"]?.InnerText, intForce, 0, 0);
                    objCharacter.STR.MetatypeMinimum = CommonFunctions.ExpressionToInt(objXmlMetatype["strmin"]?.InnerText, intForce, 0, 0);
                    objCharacter.CHA.MetatypeMinimum = CommonFunctions.ExpressionToInt(objXmlMetatype["chamin"]?.InnerText, intForce, 0, 0);
                    objCharacter.INT.MetatypeMinimum = CommonFunctions.ExpressionToInt(objXmlMetatype["intmin"]?.InnerText, intForce, 0, 0);
                    objCharacter.LOG.MetatypeMinimum = CommonFunctions.ExpressionToInt(objXmlMetatype["logmin"]?.InnerText, intForce, 0, 0);
                    objCharacter.WIL.MetatypeMinimum = CommonFunctions.ExpressionToInt(objXmlMetatype["wilmin"]?.InnerText, intForce, 0, 0);
                    objCharacter.MAG.MetatypeMinimum = CommonFunctions.ExpressionToInt(objXmlMetatype["magmin"]?.InnerText, intForce, 0, 0);
                    objCharacter.RES.MetatypeMinimum = CommonFunctions.ExpressionToInt(objXmlMetatype["resmin"]?.InnerText, intForce, 0, 0);
                    objCharacter.EDG.MetatypeMinimum = CommonFunctions.ExpressionToInt(objXmlMetatype["edgmin"]?.InnerText, intForce, 0, 0);
                    objCharacter.ESS.MetatypeMinimum = CommonFunctions.ExpressionToInt(objXmlMetatype["essmax"]?.InnerText, intForce, 0, 0);

                    // Sprites can never have Physical Attributes.
                    if (objXmlMetatype["category"].InnerText.EndsWith("Sprite", StringComparison.Ordinal))
                    {
                        objCharacter.BOD.AssignLimits(0, 0, 0);
                        objCharacter.AGI.AssignLimits(0, 0, 0);
                        objCharacter.REA.AssignLimits(0, 0, 0);
                        objCharacter.STR.AssignLimits(0, 0, 0);
                    }

                    objCharacter.Metatype         = strCritterName;
                    objCharacter.MetatypeCategory = objXmlMetatype["category"].InnerText;
                    objCharacter.Metavariant      = string.Empty;
                    objCharacter.MetatypeBP       = 0;

                    if (objXmlMetatype["movement"] != null)
                    {
                        objCharacter.Movement = objXmlMetatype["movement"].InnerText;
                    }
                    // Load the Qualities file.
                    XmlDocument objXmlQualityDocument = _objSpirit.CharacterObject.LoadData("qualities.xml");

                    // Determine if the Metatype has any bonuses.
                    if (objXmlMetatype.InnerXml.Contains("bonus"))
                    {
                        ImprovementManager.CreateImprovements(objCharacter, Improvement.ImprovementSource.Metatype, strCritterName, objXmlMetatype.SelectSingleNode("bonus"), 1, strCritterName);
                    }

                    // Create the Qualities that come with the Metatype.
                    foreach (XmlNode objXmlQualityItem in objXmlMetatype.SelectNodes("qualities/*/quality"))
                    {
                        XmlNode       objXmlQuality = objXmlQualityDocument.SelectSingleNode("/chummer/qualities/quality[name = " + objXmlQualityItem.InnerText.CleanXPath() + "]");
                        List <Weapon> lstWeapons    = new List <Weapon>(1);
                        Quality       objQuality    = new Quality(objCharacter);
                        string        strForceValue = objXmlQualityItem.Attributes?["select"]?.InnerText ?? string.Empty;
                        QualitySource objSource     = objXmlQualityItem.Attributes["removable"]?.InnerText == bool.TrueString ? QualitySource.MetatypeRemovable : QualitySource.Metatype;
                        objQuality.Create(objXmlQuality, objSource, lstWeapons, strForceValue);
                        objCharacter.Qualities.Add(objQuality);

                        // Add any created Weapons to the character.
                        foreach (Weapon objWeapon in lstWeapons)
                        {
                            objCharacter.Weapons.Add(objWeapon);
                        }
                    }

                    // Add any Critter Powers the Metatype/Critter should have.
                    XmlNode objXmlCritter = objXmlDocument.SelectSingleNode("/chummer/metatypes/metatype[name = " + objCharacter.Metatype.CleanXPath() + "]");

                    objXmlDocument = _objSpirit.CharacterObject.LoadData("critterpowers.xml");
                    foreach (XmlNode objXmlPower in objXmlCritter.SelectNodes("powers/power"))
                    {
                        XmlNode      objXmlCritterPower = objXmlDocument.SelectSingleNode("/chummer/powers/power[name = " + objXmlPower.InnerText.CleanXPath() + "]");
                        CritterPower objPower           = new CritterPower(objCharacter);
                        string       strForcedValue     = objXmlPower.Attributes?["select"]?.InnerText ?? string.Empty;
                        int          intRating          = CommonFunctions.ExpressionToInt(objXmlPower.Attributes?["rating"]?.InnerText, intForce, 0, 0);

                        objPower.Create(objXmlCritterPower, intRating, strForcedValue);
                        objCharacter.CritterPowers.Add(objPower);
                    }

                    XmlNode xmlOptionalPowersNode = objXmlCritter["optionalpowers"];
                    if (xmlOptionalPowersNode != null && intForce >= 3)
                    {
                        XmlDocument objDummyDocument = new XmlDocument {
                            XmlResolver = null
                        };
                        //For every 3 full points of Force a spirit has, it may gain one Optional Power.
                        for (int i = intForce - 3; i >= 0; i -= 3)
                        {
                            XmlNode bonusNode = objDummyDocument.CreateNode(XmlNodeType.Element, "bonus", null);
                            XmlNode powerNode = objDummyDocument.ImportNode(xmlOptionalPowersNode.CloneNode(true), true);
                            bonusNode.AppendChild(powerNode);
                            objDummyDocument.AppendChild(bonusNode);
                        }
                        foreach (XmlNode bonusNode in objDummyDocument.SelectNodes("/bonus"))
                        {
                            ImprovementManager.CreateImprovements(objCharacter, Improvement.ImprovementSource.Metatype, objCharacter.Metatype, bonusNode, 1, objCharacter.Metatype);
                        }
                    }

                    // Add any Complex Forms the Critter comes with (typically Sprites)
                    XmlDocument objXmlProgramDocument = _objSpirit.CharacterObject.LoadData("complexforms.xml");
                    foreach (XmlNode objXmlComplexForm in objXmlCritter.SelectNodes("complexforms/complexform"))
                    {
                        string      strForceValue         = objXmlComplexForm.Attributes?["select"]?.InnerText ?? string.Empty;
                        XmlNode     objXmlComplexFormData = objXmlProgramDocument.SelectSingleNode("/chummer/complexforms/complexform[name = " + objXmlComplexForm.InnerText.CleanXPath() + "]");
                        ComplexForm objComplexForm        = new ComplexForm(objCharacter);
                        objComplexForm.Create(objXmlComplexFormData, strForceValue);
                        objCharacter.ComplexForms.Add(objComplexForm);
                    }

                    objCharacter.Alias   = strCritterName;
                    objCharacter.Created = true;
                    if (!objCharacter.Save())
                    {
                        return;
                    }
                }

                // Link the newly-created Critter to the Spirit.
                imgLink.SetToolTip(LanguageManager.GetString(_objSpirit.EntityType == SpiritType.Spirit ? "Tip_Spirit_OpenFile" : "Tip_Sprite_OpenFile"));
                ContactDetailChanged?.Invoke(this, EventArgs.Empty);

                Character objOpenCharacter = await Program.MainForm.LoadCharacter(_objSpirit.FileName).ConfigureAwait(false);

                Program.MainForm.OpenCharacter(objOpenCharacter);
            }
        }
示例#11
0
        /// <summary>
        /// Create a Critter, put them into Career Mode, link them, and open the newly-created Critter.
        /// </summary>
        /// <param name="strCritterName">Name of the Critter's Metatype.</param>
        /// <param name="intForce">Critter's Force.</param>
        private async ValueTask CreateCritter(string strCritterName, int intForce)
        {
            // Code from frmMetatype.
            XmlDocument objXmlDocument = await _objSpirit.CharacterObject.LoadDataAsync("critters.xml");

            XmlNode objXmlMetatype = objXmlDocument.SelectSingleNode("/chummer/metatypes/metatype[name = " + strCritterName.CleanXPath() + ']');

            // If the Critter could not be found, show an error and get out of here.
            if (objXmlMetatype == null)
            {
                Program.MainForm.ShowMessageBox(string.Format(GlobalSettings.CultureInfo, await LanguageManager.GetStringAsync("Message_UnknownCritterType"), strCritterName), await LanguageManager.GetStringAsync("MessageTitle_SelectCritterType"), MessageBoxButtons.OK, MessageBoxIcon.Error);
                return;
            }

            using (new CursorWait(this))
            {
                // The Critter should use the same settings file as the character.
                using (Character objCharacter = new Character
                {
                    SettingsKey = _objSpirit.CharacterObject.SettingsKey,
                    // Override the defaults for the setting.
                    IgnoreRules = true,
                    IsCritter = true,
                    Alias = strCritterName,
                    Created = true
                })
                {
                    if (!string.IsNullOrEmpty(txtCritterName.Text))
                    {
                        objCharacter.Name = txtCritterName.Text;
                    }

                    string strSpace = await LanguageManager.GetStringAsync("String_Space");

                    using (SaveFileDialog saveFileDialog = new SaveFileDialog
                    {
                        Filter = await LanguageManager.GetStringAsync("DialogFilter_Chum5") + '|' + await LanguageManager.GetStringAsync("DialogFilter_All"),
                        FileName = strCritterName + strSpace + '(' + await LanguageManager.GetStringAsync(_objSpirit.RatingLabel) + strSpace + _objSpirit.Force.ToString(GlobalSettings.InvariantCultureInfo) + ").chum5"
                    })
                    {
                        if (saveFileDialog.ShowDialog(this) != DialogResult.OK)
                        {
                            return;
                        }
                        string strFileName = saveFileDialog.FileName;
                        objCharacter.FileName = strFileName;
                    }

                    objCharacter.Create(objXmlMetatype["category"]?.InnerText, objXmlMetatype["id"]?.InnerText, string.Empty, objXmlMetatype, intForce);
                    objCharacter.MetatypeBP = 0;
                    using (LoadingBar frmProgressBar = ChummerMainForm.CreateAndShowProgressBar())
                    {
                        frmProgressBar.PerformStep(objCharacter.CharacterName, LoadingBar.ProgressBarTextPatterns.Saving);
                        if (!objCharacter.Save())
                        {
                            return;
                        }
                    }

                    // Link the newly-created Critter to the Spirit.
                    cmdLink.ToolTipText = await LanguageManager.GetStringAsync(_objSpirit.EntityType == SpiritType.Spirit? "Tip_Spirit_OpenFile" : "Tip_Sprite_OpenFile");

                    ContactDetailChanged?.Invoke(this, EventArgs.Empty);

                    Program.MainForm.OpenCharacter(objCharacter);
                }
            }
        }