Browse Source

Add clothing mask radio buttons

Functions similarly to pushing 'H' for undressing all the maids except
 it affects only the active maid.
habeebweeb 4 years ago
parent
commit
c060e4e98e

+ 4 - 1
COM3D2.MeidoPhotoStudio.Plugin/Config/MeidoPhotoStudio/Translations/en/translation.ui.json

@@ -121,7 +121,10 @@
         "curlingFront": "Curl Front",
         "curlingBack": "Curl Rear",
         "shiftPanties": "Shift",
-        "detail": "Detailed Clothing"
+        "detail": "Detailed Clothing",
+        "all": "All",
+        "underwear": "Underwear",
+        "nude": "Nude"
     },
     "gravityControlPane": {
         "hairToggle": "Hair",

+ 90 - 65
COM3D2.MeidoPhotoStudio.Plugin/MeidoPhotoStudio/GUI/Panes/PoseWindowPanes/MaidDressingPane.cs

@@ -1,76 +1,86 @@
+using System;
 using System.Collections.Generic;
 using UnityEngine;
 using static TBody;
 
 namespace COM3D2.MeidoPhotoStudio.Plugin
 {
+    using static Meido;
     public class MaidDressingPane : BasePane
     {
-        public static readonly SlotID[] clothingSlots = {
+        public static readonly SlotID[] ClothingSlots =
+        {
             // main slots
-            SlotID.wear, SlotID.skirt, SlotID.bra, SlotID.panz, SlotID.headset, SlotID.megane,
-            SlotID.accUde, SlotID.glove, SlotID.accSenaka, SlotID.stkg, SlotID.shoes, SlotID.body,
+            SlotID.wear, SlotID.skirt, SlotID.bra, SlotID.panz, SlotID.headset, SlotID.megane, SlotID.accUde,
+            SlotID.glove, SlotID.accSenaka, SlotID.stkg, SlotID.shoes, SlotID.body,
             // detailed slots
-            SlotID.accAshi, SlotID.accHana, SlotID.accHat, SlotID.accHeso, SlotID.accKamiSubL,
-            SlotID.accKamiSubR, SlotID.accKami_1_, SlotID.accKami_2_, SlotID.accKami_3_, SlotID.accKubi,
-            SlotID.accKubiwa, SlotID.accMiMiL, SlotID.accMiMiR, SlotID.accNipL, SlotID.accNipR,
-            SlotID.accShippo, SlotID.accXXX
+            SlotID.accAshi, SlotID.accHana, SlotID.accHat, SlotID.accHeso, SlotID.accKamiSubL, SlotID.accKamiSubR,
+            SlotID.accKami_1_, SlotID.accKami_2_, SlotID.accKami_3_, SlotID.accKubi, SlotID.accKubiwa, SlotID.accMiMiL,
+            SlotID.accMiMiR, SlotID.accNipL, SlotID.accNipR, SlotID.accShippo, SlotID.accXXX
             // unused slots
             // SlotID.mizugi, SlotID.onepiece, SlotID.accHead,
         };
-        public static readonly SlotID[] bodySlots = {
-            SlotID.body, SlotID.head, SlotID.eye, SlotID.hairF, SlotID.hairR,
-            SlotID.hairS, SlotID.hairT, SlotID.hairAho, SlotID.chikubi, SlotID.underhair,
-            SlotID.moza, SlotID.accHa
-        };
-        public static readonly SlotID[] wearSlots = {
-            SlotID.wear, SlotID.mizugi, SlotID.onepiece
+
+        public static readonly SlotID[] BodySlots =
+        {
+            SlotID.body, SlotID.head, SlotID.eye, SlotID.hairF, SlotID.hairR, SlotID.hairS, SlotID.hairT,
+            SlotID.hairAho, SlotID.chikubi, SlotID.underhair, SlotID.moza, SlotID.accHa
         };
-        public static readonly SlotID[] headwearSlots = {
-            SlotID.headset, SlotID.accHat, SlotID.accKamiSubL,
-            SlotID.accKamiSubR, SlotID.accKami_1_, SlotID.accKami_2_, SlotID.accKami_3_
+
+        public static readonly SlotID[] WearSlots = { SlotID.wear, SlotID.mizugi, SlotID.onepiece };
+
+        public static readonly SlotID[] HeadwearSlots =
+        {
+            SlotID.headset, SlotID.accHat, SlotID.accKamiSubL, SlotID.accKamiSubR, SlotID.accKami_1_,
+            SlotID.accKami_2_, SlotID.accKami_3_
         };
+
         private readonly MeidoManager meidoManager;
-        private readonly Dictionary<SlotID, Toggle> ClothingToggles;
-        private readonly Dictionary<SlotID, bool> LoadedSlots;
+        private readonly Dictionary<SlotID, Toggle> clothingToggles;
+        private readonly Dictionary<SlotID, bool> loadedSlots;
         private readonly Toggle detailedClothingToggle;
+        private readonly SelectionGrid maskModeGrid;
         private readonly Toggle curlingFrontToggle;
         private readonly Toggle curlingBackToggle;
         private readonly Toggle pantsuShiftToggle;
         private bool detailedClothing;
+        private static readonly string[] maskLabels = { "all", "underwear", "nude" };
 
         public MaidDressingPane(MeidoManager meidoManager)
         {
             this.meidoManager = meidoManager;
 
-            ClothingToggles = new Dictionary<SlotID, Toggle>(clothingSlots.Length);
-            LoadedSlots = new Dictionary<SlotID, bool>(clothingSlots.Length);
-            foreach (SlotID slot in clothingSlots)
+            clothingToggles = new Dictionary<SlotID, Toggle>(ClothingSlots.Length);
+            loadedSlots = new Dictionary<SlotID, bool>(ClothingSlots.Length);
+            foreach (SlotID slot in ClothingSlots)
             {
-                Toggle slotToggle = new Toggle(Translation.Get("clothing", slot.ToString()));
+                var slotToggle = new Toggle(Translation.Get("clothing", slot.ToString()));
                 slotToggle.ControlEvent += (s, a) => ToggleClothing(slot, slotToggle.Value);
-                ClothingToggles.Add(slot, slotToggle);
-                LoadedSlots[slot] = true;
+                clothingToggles.Add(slot, slotToggle);
+                loadedSlots[slot] = true;
             }
 
             detailedClothingToggle = new Toggle(Translation.Get("clothing", "detail"));
             detailedClothingToggle.ControlEvent += (s, a) => UpdateDetailedClothing();
 
             curlingFrontToggle = new Toggle(Translation.Get("clothing", "curlingFront"));
-            curlingFrontToggle.ControlEvent += (s, a) => ToggleCurling(Meido.Curl.front, curlingFrontToggle.Value);
+            curlingFrontToggle.ControlEvent += (s, a) => ToggleCurling(Curl.Front, curlingFrontToggle.Value);
             curlingBackToggle = new Toggle(Translation.Get("clothing", "curlingBack"));
-            curlingBackToggle.ControlEvent += (s, a) => ToggleCurling(Meido.Curl.back, curlingBackToggle.Value);
+            curlingBackToggle.ControlEvent += (s, a) => ToggleCurling(Curl.Back, curlingBackToggle.Value);
             pantsuShiftToggle = new Toggle(Translation.Get("clothing", "shiftPanties"));
-            pantsuShiftToggle.ControlEvent += (s, a) => ToggleCurling(Meido.Curl.shift, pantsuShiftToggle.Value);
+            pantsuShiftToggle.ControlEvent += (s, a) => ToggleCurling(Curl.Shift, pantsuShiftToggle.Value);
+
+            maskModeGrid = new SelectionGrid(Translation.GetArray("clothing", maskLabels));
+            maskModeGrid.ControlEvent += (s, a) => SetMaskMode((Mask)maskModeGrid.SelectedItemIndex);
 
             UpdateDetailedClothing();
         }
 
         protected override void ReloadTranslation()
         {
-            foreach (SlotID slot in clothingSlots)
+            foreach (SlotID slot in ClothingSlots)
             {
-                Toggle clothingToggle = ClothingToggles[slot];
+                Toggle clothingToggle = clothingToggles[slot];
                 if (slot == SlotID.headset)
                 {
                     clothingToggle.Label = detailedClothing
@@ -80,13 +90,17 @@ namespace COM3D2.MeidoPhotoStudio.Plugin
                 else clothingToggle.Label = Translation.Get("clothing", slot.ToString());
             }
 
+            updating = true;
+            maskModeGrid.SetItems(Translation.GetArray("clothing", maskLabels));
+            updating = false;
+
             detailedClothingToggle.Label = Translation.Get("clothing", "detail");
             curlingFrontToggle.Label = Translation.Get("clothing", "curlingFront");
             curlingBackToggle.Label = Translation.Get("clothing", "curlingBack");
             pantsuShiftToggle.Label = Translation.Get("clothing", "shiftPanties");
         }
 
-        public void ToggleClothing(SlotID slot, bool enabled)
+        private void ToggleClothing(SlotID slot, bool enabled)
         {
             if (updating) return;
 
@@ -101,10 +115,10 @@ namespace COM3D2.MeidoPhotoStudio.Plugin
             if (!detailedClothing && slot == SlotID.headset)
             {
                 updating = true;
-                foreach (SlotID wearSlot in headwearSlots)
+                foreach (SlotID wearSlot in HeadwearSlots)
                 {
                     body.SetMask(wearSlot, enabled);
-                    ClothingToggles[wearSlot].Value = enabled;
+                    clothingToggles[wearSlot].Value = enabled;
                 }
                 updating = false;
             }
@@ -112,10 +126,7 @@ namespace COM3D2.MeidoPhotoStudio.Plugin
             {
                 if (slot == SlotID.wear)
                 {
-                    foreach (SlotID wearSlot in wearSlots)
-                    {
-                        body.SetMask(wearSlot, enabled);
-                    }
+                    foreach (SlotID wearSlot in WearSlots) body.SetMask(wearSlot, enabled);
                 }
                 else if (slot == SlotID.megane)
                 {
@@ -126,25 +137,28 @@ namespace COM3D2.MeidoPhotoStudio.Plugin
             }
         }
 
-        public void ToggleCurling(Meido.Curl curl, bool enabled)
+        private void ToggleCurling(Curl curl, bool enabled)
         {
             if (updating) return;
 
             meidoManager.ActiveMeido.SetCurling(curl, enabled);
 
-            if (enabled)
-            {
-                updating = true;
-                if (curl == Meido.Curl.front && curlingBackToggle.Value)
-                {
-                    curlingBackToggle.Value = false;
-                }
-                else if (curl == Meido.Curl.back && curlingFrontToggle.Value)
-                {
-                    curlingFrontToggle.Value = false;
-                }
-                updating = false;
-            }
+            if (!enabled) return;
+
+            updating = true;
+            if (curl == Curl.Front && curlingBackToggle.Value) curlingBackToggle.Value = false;
+            else if (curl == Curl.Back && curlingFrontToggle.Value) curlingFrontToggle.Value = false;
+
+            updating = false;
+        }
+
+        private void SetMaskMode(Mask mask)
+        {
+            if (updating) return;
+
+            meidoManager.ActiveMeido.SetMaskMode(mask);
+
+            UpdatePane();
         }
 
         public override void UpdatePane()
@@ -155,13 +169,14 @@ namespace COM3D2.MeidoPhotoStudio.Plugin
 
             Meido meido = meidoManager.ActiveMeido;
             TBody body = meido.Maid.body0;
-            foreach (SlotID clothingSlot in clothingSlots)
+
+            foreach (SlotID clothingSlot in ClothingSlots)
             {
-                bool toggleValue = false;
-                bool hasSlot = false;
+                var toggleValue = false;
+                var hasSlot = false;
                 if (clothingSlot == SlotID.wear)
                 {
-                    foreach (SlotID wearSlot in wearSlots)
+                    foreach (SlotID wearSlot in WearSlots)
                     {
                         if (body.GetMask(wearSlot)) toggleValue = true;
                         if (body.GetSlotLoaded(wearSlot)) hasSlot = true;
@@ -175,7 +190,7 @@ namespace COM3D2.MeidoPhotoStudio.Plugin
                 }
                 else if (!detailedClothing && clothingSlot == SlotID.headset)
                 {
-                    foreach (SlotID headwearSlot in headwearSlots)
+                    foreach (SlotID headwearSlot in HeadwearSlots)
                     {
                         if (body.GetMask(headwearSlot)) toggleValue = true;
                         if (body.GetSlotLoaded(headwearSlot)) hasSlot = true;
@@ -188,34 +203,40 @@ namespace COM3D2.MeidoPhotoStudio.Plugin
                     hasSlot = body.GetSlotLoaded(clothingSlot);
                 }
 
-                ClothingToggles[clothingSlot].Value = hasSlot && toggleValue;
-                LoadedSlots[clothingSlot] = hasSlot;
+                clothingToggles[clothingSlot].Value = hasSlot && toggleValue;
+                loadedSlots[clothingSlot] = hasSlot;
             }
 
             curlingFrontToggle.Value = meido.CurlingFront;
             curlingBackToggle.Value = meido.CurlingBack;
             pantsuShiftToggle.Value = meido.PantsuShift;
 
+            MaskMode maskMode = meido.CurrentMaskMode;
+
+            maskModeGrid.SelectedItemIndex = maskMode == MaskMode.Nude ? (int)Mask.Nude : (int)maskMode;
+
             updating = false;
         }
 
         private void DrawSlotGroup(params SlotID[] slots)
         {
             GUILayout.BeginHorizontal();
-            for (int i = 0; i < slots.Length; i++)
+            for (var i = 0; i < slots.Length; i++)
             {
                 SlotID slot = slots[i];
-                GUI.enabled = Enabled && LoadedSlots[slot];
-                ClothingToggles[slot].Draw();
+                GUI.enabled = Enabled && loadedSlots[slot];
+                clothingToggles[slot].Draw();
                 if (i < slots.Length - 1) GUILayout.FlexibleSpace();
             }
             GUILayout.EndHorizontal();
+
+            GUI.enabled = Enabled;
         }
 
         private void UpdateDetailedClothing()
         {
             detailedClothing = detailedClothingToggle.Value;
-            ClothingToggles[SlotID.headset].Label = detailedClothing
+            clothingToggles[SlotID.headset].Label = detailedClothing
                 ? Translation.Get("clothing", "headset")
                 : Translation.Get("clothing", "headwear");
             UpdatePane();
@@ -223,10 +244,14 @@ namespace COM3D2.MeidoPhotoStudio.Plugin
 
         public override void Draw()
         {
-            Enabled = meidoManager.HasActiveMeido;
+            GUI.enabled = Enabled = meidoManager.HasActiveMeido;
 
-            GUI.enabled = Enabled;
             detailedClothingToggle.Draw();
+
+            MpsGui.BlackLine();
+
+            maskModeGrid.Draw();
+
             MpsGui.BlackLine();
 
             DrawSlotGroup(SlotID.wear, SlotID.skirt);
@@ -247,7 +272,7 @@ namespace COM3D2.MeidoPhotoStudio.Plugin
                 DrawSlotGroup(SlotID.accHeso, SlotID.accAshi, SlotID.accXXX);
             }
 
-            GUI.enabled = Enabled;
+            MpsGui.BlackLine();
 
             GUILayout.BeginHorizontal();
             curlingFrontToggle.Draw();

+ 3 - 12
COM3D2.MeidoPhotoStudio.Plugin/MeidoPhotoStudio/Managers/MeidoManager.cs

@@ -311,19 +311,10 @@ namespace COM3D2.MeidoPhotoStudio.Plugin
         private void UndressAll()
         {
             if (!HasActiveMeido) return;
-            undress = Utility.Wrap(undress + 1, 0, 3);
-            TBody.MaskMode maskMode = TBody.MaskMode.None;
-            switch (undress)
-            {
-                case 0: maskMode = TBody.MaskMode.None; break;
-                case 1: maskMode = TBody.MaskMode.Underwear; break;
-                case 2: maskMode = TBody.MaskMode.Nude; break;
-            }
 
-            foreach (Meido activeMeido in ActiveMeidoList)
-            {
-                activeMeido.SetMaskMode(maskMode);
-            }
+            undress = ++undress % Enum.GetNames(typeof(Meido.Mask)).Length;
+
+            foreach (Meido activeMeido in ActiveMeidoList) activeMeido.SetMaskMode((Meido.Mask)undress);
 
             UpdateMeido?.Invoke(ActiveMeido, new MeidoUpdateEventArgs(SelectedMeido));
         }

+ 28 - 30
COM3D2.MeidoPhotoStudio.Plugin/MeidoPhotoStudio/Meido/Meido.cs

@@ -1,11 +1,12 @@
 using System;
 using System.IO;
 using System.Collections;
+using System.Collections.Generic;
+using System.Reflection;
 using System.Linq;
 using System.Xml.Linq;
 using UnityEngine;
 using static TBody;
-using System.Collections.Generic;
 
 namespace COM3D2.MeidoPhotoStudio.Plugin
 {
@@ -13,6 +14,8 @@ namespace COM3D2.MeidoPhotoStudio.Plugin
     {
         private bool initialized;
         private float[] BlendSetValueBackup;
+        private readonly FieldInfo m_eMaskMode = Utility.GetFieldInfo<TBody>("m_eMaskMode");
+        public MaskMode CurrentMaskMode => !Body.isLoadedBody ? default : (MaskMode) m_eMaskMode.GetValue(Body);
         public DragPointGravity HairGravityControl { get; private set; }
         public DragPointGravity SkirtGravityControl { get; private set; }
         public bool HairGravityActive
@@ -38,8 +41,6 @@ namespace COM3D2.MeidoPhotoStudio.Plugin
             }
         }
         public const int meidoDataVersion = 1000;
-        public static readonly PoseInfo DefaultPose =
-            new PoseInfo(Constants.PoseGroupList[0], Constants.PoseDict[Constants.PoseGroupList[0]][0]);
         public static readonly string defaultFaceBlendSet = "通常";
         public static readonly string[] faceKeys = new string[24]
         {
@@ -56,10 +57,8 @@ namespace COM3D2.MeidoPhotoStudio.Plugin
             // cry 1, cry 2, cry 3, blush 1, blush 2, blush 3
             "tear1", "tear2", "tear3", "hohos", "hoho", "hohol"
         };
-        public enum Curl
-        {
-            front, back, shift
-        }
+        public enum Curl { Front, Back, Shift }
+        public enum Mask { All, Underwear, Nude }
         public event EventHandler<MeidoUpdateEventArgs> UpdateMeido;
         public int StockNo { get; }
         public Maid Maid { get; }
@@ -595,6 +594,9 @@ namespace COM3D2.MeidoPhotoStudio.Plugin
             Utility.SetFieldValue(Maid, "MabatakiVal", 0f);
         }
 
+        public void SetMaskMode(Mask maskMode)
+            => SetMaskMode(maskMode == Mask.Nude ? MaskMode.Nude : (MaskMode) maskMode);
+
         public void SetMaskMode(MaskMode maskMode)
         {
             bool invisibleBody = !Body.GetMask(SlotID.body);
@@ -605,28 +607,24 @@ namespace COM3D2.MeidoPhotoStudio.Plugin
         public void SetBodyMask(bool enabled)
         {
             Hashtable table = Utility.GetFieldValue<TBody, Hashtable>(Body, "m_hFoceHide");
-            foreach (SlotID bodySlot in MaidDressingPane.bodySlots)
-            {
-                table[bodySlot] = enabled;
-            }
-            if (Body.goSlot[19].m_strModelFileName.Contains("melala_body"))
-            {
-                table[SlotID.accHana] = enabled;
-            }
+            foreach (SlotID bodySlot in MaidDressingPane.BodySlots) table[bodySlot] = enabled;
             Body.FixMaskFlag();
             Body.FixVisibleFlag(false);
         }
 
         public void SetCurling(Curl curling, bool enabled)
         {
-            string[] name = curling == Curl.shift
+            string[] name = curling == Curl.Shift
                 ? new[] { "panz", "mizugi" }
                 : new[] { "skirt", "onepiece" };
             if (enabled)
             {
-                string action = curling == Curl.shift
-                    ? "パンツずらし" : curling == Curl.front
-                        ? "めくれスカート" : "めくれスカート後ろ";
+                var action = curling switch
+                {
+                    Curl.Shift => "パンツずらし",
+                    Curl.Front => "めくれスカート",
+                    _ => "めくれスカート後ろ"
+                };
                 Maid.ItemChangeTemp(name[0], action);
                 Maid.ItemChangeTemp(name[1], action);
             }
@@ -749,6 +747,7 @@ namespace COM3D2.MeidoPhotoStudio.Plugin
                     tempWriter.WriteVector3(Body.offsetLookTarget);
                     tempWriter.WriteVector3(Utility.GetFieldValue<TBody, Vector3>(Body, "HeadEulerAngle"));
                 }
+
                 // Head/eye to camera
                 tempWriter.Write(HeadToCam);
                 tempWriter.Write(EyeToCam);
@@ -757,14 +756,14 @@ namespace COM3D2.MeidoPhotoStudio.Plugin
                 // body visible
                 tempWriter.Write(Body.GetMask(SlotID.body));
                 // clothing
-                foreach (SlotID clothingSlot in MaidDressingPane.clothingSlots)
+                foreach (SlotID clothingSlot in MaidDressingPane.ClothingSlots)
                 {
                     bool value = true;
                     if (clothingSlot == SlotID.wear)
                     {
-                        if (MaidDressingPane.wearSlots.Any(slot => Body.GetSlotLoaded(slot)))
+                        if (MaidDressingPane.WearSlots.Any(slot => Body.GetSlotLoaded(slot)))
                         {
-                            value = MaidDressingPane.wearSlots.Any(slot => Body.GetMask(slot));
+                            value = MaidDressingPane.WearSlots.Any(slot => Body.GetMask(slot));
                         }
                     }
                     else if (clothingSlot == SlotID.megane)
@@ -775,12 +774,11 @@ namespace COM3D2.MeidoPhotoStudio.Plugin
                             value = slots.Any(slot => Body.GetMask(slot));
                         }
                     }
-                    else if (Body.GetSlotLoaded(clothingSlot))
-                    {
-                        value = Body.GetMask(clothingSlot);
-                    }
+                    else if (Body.GetSlotLoaded(clothingSlot)) { value = Body.GetMask(clothingSlot); }
+
                     tempWriter.Write(value);
                 }
+
                 // hair/skirt gravity
                 tempWriter.Write(HairGravityActive);
                 if (HairGravityActive) tempWriter.WriteVector3(HairGravityControl.Control.transform.localPosition);
@@ -872,7 +870,7 @@ namespace COM3D2.MeidoPhotoStudio.Plugin
             // body visible
             SetBodyMask(binaryReader.ReadBoolean());
             // clothing
-            foreach (SlotID clothingSlot in MaidDressingPane.clothingSlots)
+            foreach (SlotID clothingSlot in MaidDressingPane.ClothingSlots)
             {
                 bool value = binaryReader.ReadBoolean();
                 if (mmScene) continue;
@@ -912,9 +910,9 @@ namespace COM3D2.MeidoPhotoStudio.Plugin
             bool curlingPantsu = binaryReader.ReadBoolean();
             if (!mmScene)
             {
-                if (CurlingFront != curlingFront) SetCurling(Curl.front, curlingFront);
-                if (CurlingBack != curlingBack) SetCurling(Curl.back, curlingBack);
-                SetCurling(Curl.shift, curlingPantsu);
+                if (CurlingFront != curlingFront) SetCurling(Curl.Front, curlingFront);
+                if (CurlingBack != curlingBack) SetCurling(Curl.Back, curlingBack);
+                SetCurling(Curl.Shift, curlingPantsu);
             }
 
             bool hasKousokuUpper = binaryReader.ReadBoolean();