public static Image GetCharacterBuImage(string name, string emotion, Color hairColor, bool crop,
                                                PlayerGender playerGender)
        {
            var hairName           = "_bu_髪";
            var dat_id             = "FSID_BU_" + name;
            var isUser             = name == "username";
            var playerGenderString = playerGender.ToIfString();

            if (isUser)
            {
                dat_id   = $"FSID_BU_{playerGender.ToIfString(true)}_顔{EyeStyles[0].ToUpper()}";
                name     = $"{EyeStyles[0]}{playerGenderString}";
                hairName = $"{playerGenderString}{hairName}0";
            }
            else
            {
                hairName = name + hairName + "0";
            }
            var   splitEmotions = emotion.Split(new[] { ',' }, StringSplitOptions.RemoveEmptyEntries);
            var   resname       = name + "_bu_" + splitEmotions[0];
            Image characterImage;

            if (ResourceList.Contains(resname))
            {
                characterImage = (Image)Resources.ResourceManager.GetObject(resname);
                Debug.Assert(characterImage != null, $"{nameof(characterImage)} != null");
            }
            else
            {
                characterImage = new Bitmap(1, 1);
            }

            using (var g = Graphics.FromImage(characterImage))
            {
#if ACCESSORY
                if (isUser)
                {
                    g.DrawImage(
                        Resources.ResourceManager.GetObject(playerGenderString +
                                                            "_bu_アクセサリ1_" + 0)
                        as Image, new Point(0, 0));
                }
#endif

                for (var i = 1; i < splitEmotions.Length; i++)
                {
                    //TODO(Robin): Redundant; see above
                    var exresname = name + "_bu_" + splitEmotions[i];
                    if (splitEmotions[i] == "汗" && ResourceList.Contains(exresname))
                    {
                        g.DrawImage((Image)Resources.ResourceManager.GetObject(exresname),
                                    new Point(BitConverter.ToUInt16(faceData[dat_id], 0x40),
                                              BitConverter.ToUInt16(faceData[dat_id], 0x42)));
                    }
                    else if (splitEmotions[i] == "照" && ResourceList.Contains(exresname))
                    {
                        g.DrawImage((Image)Resources.ResourceManager.GetObject(exresname),
                                    new Point(BitConverter.ToUInt16(faceData[dat_id], 0x38),
                                              BitConverter.ToUInt16(faceData[dat_id], 0x3A)));
                    }
                }
                if (ResourceList.Contains(hairName))
                {
                    var hair = Resources.ResourceManager.GetObject(hairName) as Bitmap;
                    g.DrawImage(ColorHair(hair, hairColor), new Point(0, 0));
                }
#if ACCESSORY
                if (isUser)
                {
                    var Acc = new[] { new Point(66, 5), new Point(65, 21) }[0 - 2];
                    g.DrawImage(
                        Resources.ResourceManager.GetObject((new[] { "マイユニ男1", "マイユニ女2" })[playerGender] +
                                                            "_bu_アクセサリ2_" + 0)
                        as Image, Acc);
                }
#endif
            }
            if (crop)
            {
                var Cropped = new Bitmap(BitConverter.ToUInt16(faceData[dat_id], 0x34),
                                         BitConverter.ToUInt16(faceData[dat_id], 0x36));
                using (var g = Graphics.FromImage(Cropped))
                {
                    g.DrawImage(characterImage,
                                new Point(-BitConverter.ToUInt16(faceData[dat_id], 0x30),
                                          -BitConverter.ToUInt16(faceData[dat_id], 0x32)));
                }
                characterImage = Cropped;
            }
            characterImage.RotateFlip(RotateFlipType.RotateNoneFlipX);
            return(characterImage);
        }
        public static Image GetCharacterStageImage(string name, string emotions, Color hairColor, bool Slot1,
                                                   PlayerGender playerGender)
        {
            var isUser   = name == "username";
            var hairName = "_st_髪";
            var dat_id   = "FSID_ST_" + name;

            if (isUser)
            {
                dat_id   = "FSID_ST_" + playerGender.ToIfString(true) + "_顔" + EyeStyles[0].ToUpper();
                name     = EyeStyles[0] + playerGender.ToIfString();
                hairName = name.Substring(1) + hairName + 0;
            }
            else
            {
                hairName = name + hairName + "0";
            }
            var   splitEmotions = emotions.Split(new[] { ',' }, StringSplitOptions.RemoveEmptyEntries);
            var   resourceName  = name + "_st_" + splitEmotions[0];
            Image characterImage;

            if (ResourceList.Contains(resourceName))
            {
                characterImage = (Image)Resources.ResourceManager.GetObject(resourceName);
                Debug.Assert(characterImage != null, $"{nameof(characterImage)} != null");
            }
            else
            {
                characterImage = new Bitmap(1, 1);
            }
            using (var g = Graphics.FromImage(characterImage))
            {
#if ACCESSORY
                if (isUser)
                {
                    g.DrawImage(
                        Resources.ResourceManager.GetObject(playerGender.ToIfString() + "_st_アクセサリ1_" + 0)
                        as Image, new Point(0, 0));
                }
#endif
                for (var i = 1; i < splitEmotions.Length; i++)
                {
                    var emotion   = splitEmotions[i];
                    var exresname = name + "_st_" + emotion;
                    if (!ResourceList.Contains(exresname))
                    {
                        continue;
                    }

                    var image = Resources.ResourceManager.GetObject(exresname) as Image;
                    Debug.Assert(image != null, $"{nameof(image)} != null");
                    byte xOffset, yOffset;
                    switch (emotion)
                    {
                    case "汗":
                        xOffset = 0x40;
                        yOffset = 0x42;
                        break;

                    case "照":
                        xOffset = 0x38;
                        yOffset = 0x3A;
                        break;

                    default:
                        throw new ArgumentOutOfRangeException(nameof(emotions), emotion, "Unexpected emotion.");
                    }
                    g.DrawImage(image,
                                new Point(BitConverter.ToUInt16(faceData[dat_id], xOffset),
                                          BitConverter.ToUInt16(faceData[dat_id], yOffset)));
                }
                if (ResourceList.Contains(hairName))
                {
                    var hair = Resources.ResourceManager.GetObject(hairName) as Bitmap;
                    g.DrawImage(ColorHair(hair, hairColor), new Point(0, 0));
                }
#if ACCESSORY
                if (isUser)
                {
                    g.DrawImage(
                        Resources.ResourceManager.GetObject(playerGender.ToIfString() + "_st_アクセサリ2_" + 0)
                        as Image, new Point(133, 28));
                }
#endif
            }
            if (Slot1)
            {
                characterImage.RotateFlip(RotateFlipType.RotateNoneFlipX);
            }
            return(characterImage);
        }