Browse Source

Reformat part 9 small touches

Considering getting stylecop set up since my change in formatting kinda
aligns with their rules.
habeebweeb 2 years ago
parent
commit
dfe066e55c
52 changed files with 537 additions and 560 deletions
  1. 0 4
      src/MeidoPhotoStudio.Converter/Converters/MMConverter.cs
  2. 0 2
      src/MeidoPhotoStudio.Converter/Converters/MMPngConverter.cs
  3. 7 8
      src/MeidoPhotoStudio.Converter/MultipleMaids/MMConstants.cs
  4. 15 24
      src/MeidoPhotoStudio.Converter/MultipleMaids/MMSceneConverter.cs
  5. 0 1
      src/MeidoPhotoStudio.Converter/Utility/LZMA.cs
  6. 28 18
      src/MeidoPhotoStudio.Plugin/Constants.cs
  7. 9 8
      src/MeidoPhotoStudio.Plugin/DragPoint/CustomGizmo.cs
  8. 5 5
      src/MeidoPhotoStudio.Plugin/DragPoint/DragPoint.cs
  9. 2 0
      src/MeidoPhotoStudio.Plugin/DragPoint/DragPointGeneral.cs
  10. 0 2
      src/MeidoPhotoStudio.Plugin/DragPoint/DragPointGravity.cs
  11. 17 17
      src/MeidoPhotoStudio.Plugin/DragPoint/DragPointLight.cs
  12. 14 14
      src/MeidoPhotoStudio.Plugin/DragPoint/DragPointProp.cs
  13. 6 6
      src/MeidoPhotoStudio.Plugin/GUI/Controls/Button.cs
  14. 10 10
      src/MeidoPhotoStudio.Plugin/GUI/Controls/ComboBox.cs
  15. 3 6
      src/MeidoPhotoStudio.Plugin/GUI/Controls/DropDown.cs
  16. 7 7
      src/MeidoPhotoStudio.Plugin/GUI/Controls/KeyRebindButton.cs
  17. 10 10
      src/MeidoPhotoStudio.Plugin/GUI/Controls/SelectionGrid.cs
  18. 9 11
      src/MeidoPhotoStudio.Plugin/GUI/Controls/Slider.cs
  19. 3 3
      src/MeidoPhotoStudio.Plugin/GUI/Controls/TextArea.cs
  20. 3 3
      src/MeidoPhotoStudio.Plugin/GUI/Controls/TextField.cs
  21. 5 5
      src/MeidoPhotoStudio.Plugin/GUI/Controls/Toggle.cs
  22. 15 15
      src/MeidoPhotoStudio.Plugin/GUI/Panes/BackgroundWindow2Panes/AttachPropPane.cs
  23. 0 1
      src/MeidoPhotoStudio.Plugin/GUI/Panes/BackgroundWindow2Panes/ModPropsPane.cs
  24. 0 3
      src/MeidoPhotoStudio.Plugin/GUI/Panes/BackgroundWindow2Panes/MyRoomPropsPane.cs
  25. 1 1
      src/MeidoPhotoStudio.Plugin/GUI/Panes/BackgroundWindowPanes/BackgroundSelectorPane.cs
  26. 2 2
      src/MeidoPhotoStudio.Plugin/GUI/Panes/BackgroundWindowPanes/EffectsPanes/EffectPane.cs
  27. 2 2
      src/MeidoPhotoStudio.Plugin/GUI/Panes/BackgroundWindowPanes/LightsPane.cs
  28. 1 1
      src/MeidoPhotoStudio.Plugin/GUI/Panes/FaceWindowPanes/MaidFaceSliderPane.cs
  29. 1 1
      src/MeidoPhotoStudio.Plugin/GUI/Panes/MainWindowPanes/BGWindowPane.cs
  30. 1 0
      src/MeidoPhotoStudio.Plugin/GUI/Panes/MainWindowPanes/FaceWindowPane.cs
  31. 1 0
      src/MeidoPhotoStudio.Plugin/GUI/Panes/OtherPanes/MaidSwitcherPane.cs
  32. 2 2
      src/MeidoPhotoStudio.Plugin/GUI/Panes/OtherPanes/TabsPane.cs
  33. 8 8
      src/MeidoPhotoStudio.Plugin/GUI/Panes/PoseWindowPanes/GravityControlPane.cs
  34. 9 9
      src/MeidoPhotoStudio.Plugin/GUI/Panes/PoseWindowPanes/HandPresetPane.cs
  35. 7 7
      src/MeidoPhotoStudio.Plugin/GUI/Panes/PoseWindowPanes/MaidDressingPane.cs
  36. 32 32
      src/MeidoPhotoStudio.Plugin/GUI/Panes/PoseWindowPanes/MaidFreeLookPane.cs
  37. 0 10
      src/MeidoPhotoStudio.Plugin/MaidPlacementUtility.cs
  38. 1 1
      src/MeidoPhotoStudio.Plugin/Managers/InputManager.cs
  39. 1 1
      src/MeidoPhotoStudio.Plugin/Meido/IK/IK Chain/DragPointChain.cs
  40. 4 4
      src/MeidoPhotoStudio.Plugin/Meido/Meido.cs
  41. 7 6
      src/MeidoPhotoStudio.Plugin/Meido/MeidoDragPointManager.cs
  42. 18 17
      src/MeidoPhotoStudio.Plugin/MeidoPhotoStudio.cs
  43. 3 2
      src/MeidoPhotoStudio.Plugin/MenuFileUtility.cs
  44. 3 3
      src/MeidoPhotoStudio.Plugin/MenuItem.cs
  45. 0 3
      src/MeidoPhotoStudio.Plugin/ModelUtility.cs
  46. 0 1
      src/MeidoPhotoStudio.Plugin/MyGui.cs
  47. 0 1
      src/MeidoPhotoStudio.Plugin/Serialization/Serializers/ManagerSerializers/LightManagerSerializer.cs
  48. 1 0
      src/MeidoPhotoStudio.Plugin/Serialization/Serializers/ManagerSerializers/MeidoManagerSerializer.cs
  49. 229 229
      src/MeidoPhotoStudio.Plugin/Serialization/Serializers/MeidoSerializer.cs
  50. 1 0
      src/MeidoPhotoStudio.Plugin/Serialization/SimpleSerializers/DragPointPropDTOSerializer.cs
  51. 2 2
      src/MeidoPhotoStudio.Plugin/Translation.cs
  52. 32 32
      src/MeidoPhotoStudio.Plugin/Utility.cs

+ 0 - 4
src/MeidoPhotoStudio.Converter/Converters/MMConverter.cs

@@ -81,14 +81,10 @@ public class MMConverter : IConverter
     private static string GenerateFilename(string iniFilePath, IniKey sceneKey)
     private static string GenerateFilename(string iniFilePath, IniKey sceneKey)
     {
     {
         var background = int.Parse(sceneKey.Key.Substring(1)) >= 10000;
         var background = int.Parse(sceneKey.Key.Substring(1)) >= 10000;
-
         var iniFilename = Path.GetFileNameWithoutExtension(iniFilePath);
         var iniFilename = Path.GetFileNameWithoutExtension(iniFilePath);
-
         var sceneName = sceneKey.Key;
         var sceneName = sceneKey.Key;
-
         var data = sceneKey.Value;
         var data = sceneKey.Value;
         var date = DateTime.Parse(data.Substring(0, data.IndexOf(',')));
         var date = DateTime.Parse(data.Substring(0, data.IndexOf(',')));
-
         var sceneDate = MPSSceneSerializer.FormatDate(date);
         var sceneDate = MPSSceneSerializer.FormatDate(date);
 
 
         return $"mm{(background ? "kankyo" : "scene")}_{iniFilename}_{sceneName}_{sceneDate}.png";
         return $"mm{(background ? "kankyo" : "scene")}_{iniFilename}_{sceneName}_{sceneDate}.png";

+ 0 - 2
src/MeidoPhotoStudio.Converter/Converters/MMPngConverter.cs

@@ -36,9 +36,7 @@ public class MMPngConverter : IConverter
     private static void ConvertScene(string pngFile, string outputFilename)
     private static void ConvertScene(string pngFile, string outputFilename)
     {
     {
         var fileStream = File.OpenRead(pngFile);
         var fileStream = File.OpenRead(pngFile);
-
         var thumbnailData = PngUtility.ExtractPng(fileStream) ?? MPSSceneSerializer.NoThumb;
         var thumbnailData = PngUtility.ExtractPng(fileStream) ?? MPSSceneSerializer.NoThumb;
-
         var kankyo = new byte[KankyoHeader.Length];
         var kankyo = new byte[KankyoHeader.Length];
         fileStream.Read(kankyo, 0, KankyoHeader.Length);
         fileStream.Read(kankyo, 0, KankyoHeader.Length);
 
 

+ 7 - 8
src/MeidoPhotoStudio.Converter/MultipleMaids/MMConstants.cs

@@ -12,20 +12,19 @@ public static class MMConstants
 
 
     public static readonly string[] FaceKeys =
     public static readonly string[] FaceKeys =
     {
     {
-        "eyeclose", "eyeclose2", "eyeclose3", "eyeclose6", "hitomih", "hitomis", "mayuha",
-        "mayuup", "mayuv", "mayuvhalf", "moutha", "mouths", "mouthdw", "mouthup", "tangout",
-        "tangup", "eyebig", "eyeclose5", "mayuw", "mouthhe", "mouthc", "mouthi", "mouthuphalf",
-        "tangopen",
-        "namida", "tear1", "tear2", "tear3", "shock", "yodare", "hoho", "hoho2", "hohos", "hohol",
-        "toothoff", "nosefook"
+        "eyeclose", "eyeclose2", "eyeclose3", "eyeclose6", "hitomih", "hitomis", "mayuha", "mayuup", "mayuv",
+        "mayuvhalf", "moutha", "mouths", "mouthdw", "mouthup", "tangout", "tangup", "eyebig", "eyeclose5", "mayuw",
+        "mouthhe", "mouthc", "mouthi", "mouthuphalf", "tangopen", "namida", "tear1", "tear2", "tear3", "shock",
+        "yodare", "hoho", "hoho2", "hohos", "hohol", "toothoff", "nosefook",
     };
     };
 
 
     public static readonly string[] MpnAttachProps =
     public static readonly string[] MpnAttachProps =
     {
     {
-        /* "", "", "", "", "", "", "", "", "", */
+        // NOTE: MPS only allows a subset of attached MPN props because MPS has a better method of attaching props.
+        // "", "", "", "", "", "", "", "", "",
         "kousokuu_tekaseone_i_.menu", "kousokuu_tekasetwo_i_.menu", "kousokul_ashikaseup_i_.menu",
         "kousokuu_tekaseone_i_.menu", "kousokuu_tekasetwo_i_.menu", "kousokul_ashikaseup_i_.menu",
         "kousokuu_tekasetwo_i_.menu", "kousokul_ashikasedown_i_.menu", "kousokuu_tekasetwodown_i_.menu",
         "kousokuu_tekasetwo_i_.menu", "kousokul_ashikasedown_i_.menu", "kousokuu_tekasetwodown_i_.menu",
-        "kousokuu_ushirode_i_.menu", "kousokuu_smroom_haritsuke_i_.menu"
+        "kousokuu_ushirode_i_.menu", "kousokuu_smroom_haritsuke_i_.menu",
     };
     };
 
 
     private static Dictionary<string, PlacementData.Data>? myrAssetNameToData;
     private static Dictionary<string, PlacementData.Data>? myrAssetNameToData;

+ 15 - 24
src/MeidoPhotoStudio.Converter/MultipleMaids/MMSceneConverter.cs

@@ -75,7 +75,6 @@ public static class MMSceneConverter
     {
     {
         var dataSegments = data.Split('_');
         var dataSegments = data.Split('_');
         var strArray2 = dataSegments[1].Split(';');
         var strArray2 = dataSegments[1].Split(';');
-
         var meidoCount = environment ? MeidoPhotoStudio.Plugin.MeidoPhotoStudio.kankyoMagic : strArray2.Length;
         var meidoCount = environment ? MeidoPhotoStudio.Plugin.MeidoPhotoStudio.kankyoMagic : strArray2.Length;
 
 
         return new()
         return new()
@@ -220,18 +219,16 @@ public static class MMSceneConverter
 
 
                 // check special case for ClavicleL
                 // check special case for ClavicleL
                 if (index is ClavicleLIndex)
                 if (index is ClavicleLIndex)
-                    /*
-                     * Versions of MM possibly serialized ClavicleL improperly.
-                     * At least I think that's what happened otherwise why would they make this check at all.
-                     * https://git.coder.horse/meidomustard/modifiedMM/src/master/MultipleMaids/CM3D2/MultipleMaids/Plugin/MultipleMaids.Update.cs#L4355
-                     *
-                     * Look at the way MM serializes rotations.
-                     * https://git.coder.horse/meidomustard/modifiedMM/src/master/MultipleMaids/CM3D2/MultipleMaids/Plugin/MultipleMaids.Update.cs#L2364
-                     * It is most definitely possible MM dev missed a component.
-                     *
-                     * Also why is strArray9.Length == 2 acceptable? If the length were only 2,
-                     * float.Parse(strArray9[2]) would throw an index out of range exception???
-                     */
+                    // NOTE: Versions of MM possibly serialized ClavicleL improperly.
+                    // At least I think that's what happened otherwise why would they make this check at all.
+                    // https://git.coder.horse/meidomustard/modifiedMM/src/master/MultipleMaids/CM3D2/MultipleMaids/Plugin/MultipleMaids.Update.cs#L4355
+                    // 
+                    // Look at the way MM serializes rotations.
+                    // https://git.coder.horse/meidomustard/modifiedMM/src/master/MultipleMaids/CM3D2/MultipleMaids/Plugin/MultipleMaids.Update.cs#L2364
+                    // It is most definitely possible MM dev missed a component.
+                    // 
+                    // Also why is strArray9.Length == 2 acceptable? If the length were only 2,
+                    // float.Parse(strArray9[2]) would throw an index out of range exception???
                     writer.Write(ConversionUtility.TryParseEulerAngle(data, out rotation));
                     writer.Write(ConversionUtility.TryParseEulerAngle(data, out rotation));
                 else
                 else
                     rotation = ConversionUtility.ParseEulerAngle(data);
                     rotation = ConversionUtility.ParseEulerAngle(data);
@@ -265,7 +262,6 @@ public static class MMSceneConverter
             // MPN attach props
             // MPN attach props
             var kousokuUpperMenu = string.Empty;
             var kousokuUpperMenu = string.Empty;
             var kousokuLowerMenu = string.Empty;
             var kousokuLowerMenu = string.Empty;
-
             var sixtyFourFlag = maidData.Length is 64;
             var sixtyFourFlag = maidData.Length is 64;
 
 
             if (!sixtyFourFlag)
             if (!sixtyFourFlag)
@@ -340,7 +336,6 @@ public static class MMSceneConverter
         var showingMessage = false;
         var showingMessage = false;
         var name = string.Empty;
         var name = string.Empty;
         var message = string.Empty;
         var message = string.Empty;
-
         var strArray3 = data[0].Split(',');
         var strArray3 = data[0].Split(',');
 
 
         if (strArray3.Length > 16)
         if (strArray3.Length > 16)
@@ -370,7 +365,6 @@ public static class MMSceneConverter
         writer.Write(1);
         writer.Write(1);
 
 
         var strArray3 = data[0].Split(',');
         var strArray3 = data[0].Split(',');
-
         var cameraTargetPos = DefaultCameraInfo.TargetPos;
         var cameraTargetPos = DefaultCameraInfo.TargetPos;
         var cameraDistance = DefaultCameraInfo.Distance;
         var cameraDistance = DefaultCameraInfo.Distance;
         var cameraRotation = DefaultCameraInfo.Angle;
         var cameraRotation = DefaultCameraInfo.Angle;
@@ -406,7 +400,6 @@ public static class MMSceneConverter
         var strArray4 = greaterThan5 ? data[2].Split(',') : null;
         var strArray4 = greaterThan5 ? data[2].Split(',') : null;
         var strArray5 = greaterThan5 ? data[3].Split(';') : null;
         var strArray5 = greaterThan5 ? data[3].Split(';') : null;
         var strArray7 = data.Length >= 6 ? data[5].Split(';') : null;
         var strArray7 = data.Length >= 6 ? data[5].Split(';') : null;
-
         var numberOfLights = 1 + (strArray5?.Length - 1 ?? 0);
         var numberOfLights = 1 + (strArray5?.Length - 1 ?? 0);
 
 
         writer.Write(numberOfLights);
         writer.Write(numberOfLights);
@@ -446,12 +439,10 @@ public static class MMSceneConverter
             writer.WriteVersion(1);
             writer.WriteVersion(1);
 
 
             for (var i = 0; i < 3; i++)
             for (var i = 0; i < 3; i++)
-            {
                 if (i == lightType || i is 0 && lightType is 3)
                 if (i == lightType || i is 0 && lightType is 3)
                     lightPropertySerializer.Serialize(lightProperty, writer);
                     lightPropertySerializer.Serialize(lightProperty, writer);
                 else
                 else
                     lightPropertySerializer.Serialize(DefaultLightProperty, writer);
                     lightPropertySerializer.Serialize(DefaultLightProperty, writer);
-            }
 
 
             var lightPosition = strArray7 is null
             var lightPosition = strArray7 is null
                 ? LightProperty.DefaultPosition
                 ? LightProperty.DefaultPosition
@@ -487,6 +478,7 @@ public static class MMSceneConverter
         {
         {
             var lightProperties = strArray5[i].Split(',');
             var lightProperties = strArray5[i].Split(',');
             var spotAngle = float.Parse(lightProperties[7]);
             var spotAngle = float.Parse(lightProperties[7]);
+
             var lightProperty = new LightProperty
             var lightProperty = new LightProperty
             {
             {
                 Rotation = Quaternion.Euler(float.Parse(lightProperties[4]), float.Parse(lightProperties[5]), 18f),
                 Rotation = Quaternion.Euler(float.Parse(lightProperties[4]), float.Parse(lightProperties[5]), 18f),
@@ -496,8 +488,8 @@ public static class MMSceneConverter
                 // MM does not save shadow strength for other lights 
                 // MM does not save shadow strength for other lights 
                 ShadowStrength = 0.098f,
                 ShadowStrength = 0.098f,
                 LightColour = new(
                 LightColour = new(
-                     float.Parse(lightProperties[1]), float.Parse(lightProperties[2]), float.Parse(lightProperties[3]),
-                     1f
+                    float.Parse(lightProperties[1]), float.Parse(lightProperties[2]), float.Parse(lightProperties[3]),
+                    1f
                 ),
                 ),
             };
             };
 
 
@@ -563,6 +555,7 @@ public static class MMSceneConverter
         writer.WriteVersion(1);
         writer.WriteVersion(1);
 
 
         var blurSize = float.Parse(effectData[13]);
         var blurSize = float.Parse(effectData[13]);
+
         writer.Write(blurSize > 0f); // active
         writer.Write(blurSize > 0f); // active
         writer.Write(blurSize); // blur size
         writer.Write(blurSize); // blur size
 
 
@@ -611,7 +604,6 @@ public static class MMSceneConverter
         writer.WriteVersion(1);
         writer.WriteVersion(1);
 
 
         var environmentData = data[0].Split(',');
         var environmentData = data[0].Split(',');
-
         var bgAsset = EnvironmentManager.defaultBg;
         var bgAsset = EnvironmentManager.defaultBg;
 
 
         if (!int.TryParse(environmentData[2], out _))
         if (!int.TryParse(environmentData[2], out _))
@@ -643,9 +635,9 @@ public static class MMSceneConverter
     {
     {
         var strArray3 = data[0].Split(',');
         var strArray3 = data[0].Split(',');
         var strArray6 = data.Length >= 5 ? data[4].Split(';') : null;
         var strArray6 = data.Length >= 5 ? data[4].Split(';') : null;
-
         var hasWProp = strArray3.Length > 37 && !string.IsNullOrEmpty(strArray3[37]);
         var hasWProp = strArray3.Length > 37 && !string.IsNullOrEmpty(strArray3[37]);
         var propCount = strArray6?.Length - 1 ?? 0;
         var propCount = strArray6?.Length - 1 ?? 0;
+
         propCount += hasWProp ? 1 : 0;
         propCount += hasWProp ? 1 : 0;
 
 
         writer.Write(PropManager.header);
         writer.Write(PropManager.header);
@@ -689,7 +681,6 @@ public static class MMSceneConverter
         {
         {
             var prop = strArray6[i];
             var prop = strArray6[i];
             var assetParts = prop.Split(',');
             var assetParts = prop.Split(',');
-
             var propInfo = AssetToPropInfo(assetParts[0]);
             var propInfo = AssetToPropInfo(assetParts[0]);
 
 
             var propDto = new DragPointPropDTO
             var propDto = new DragPointPropDTO

+ 0 - 1
src/MeidoPhotoStudio.Converter/Utility/LZMA.cs

@@ -8,7 +8,6 @@ internal static class LZMA
     public static MemoryStream Decompress(Stream inStream)
     public static MemoryStream Decompress(Stream inStream)
     {
     {
         var outStream = new MemoryStream();
         var outStream = new MemoryStream();
-
         var properties = new byte[5];
         var properties = new byte[5];
 
 
         if (inStream.Read(properties, 0, 5) is not 5)
         if (inStream.Read(properties, 0, 5) is not 5)

+ 28 - 18
src/MeidoPhotoStudio.Plugin/Constants.cs

@@ -412,7 +412,10 @@ public static class Constants
         static void AddDefaultPose()
         static void AddDefaultPose()
         {
         {
             if (!PoseDict.ContainsKey("normal"))
             if (!PoseDict.ContainsKey("normal"))
-                PoseDict["normal"] = new() { "maid_stand01" };
+                PoseDict["normal"] = new()
+                {
+                    "maid_stand01",
+                };
 
 
             if (!PoseGroupList.Contains("normal"))
             if (!PoseGroupList.Contains("normal"))
                 PoseGroupList.Insert(0, "normal");
                 PoseGroupList.Insert(0, "normal");
@@ -456,7 +459,6 @@ public static class Constants
 
 
     public static void InitializeHandPresets()
     public static void InitializeHandPresets()
     {
     {
-
         CustomHandGroupList.Clear();
         CustomHandGroupList.Clear();
         CustomHandDict.Clear();
         CustomHandDict.Clear();
 
 
@@ -641,6 +643,7 @@ public static class Constants
 
 
                 if (string.IsNullOrEmpty(iconFile))
                 if (string.IsNullOrEmpty(iconFile))
                 {
                 {
+                    // TODO: Remove '{iconFile}' since it will not add anymore information.
                     Utility.LogWarning($"Could not find icon '{iconFile}' for menu '{item.MenuFile}");
                     Utility.LogWarning($"Could not find icon '{iconFile}' for menu '{item.MenuFile}");
 
 
                     return true;
                     return true;
@@ -766,6 +769,8 @@ public static class Constants
 
 
         var com3d2DeskDogu = DoguDict[customDoguCategories[DoguCategory.Desk]];
         var com3d2DeskDogu = DoguDict[customDoguCategories[DoguCategory.Desk]];
 
 
+        GetDeskItems(GameUty.FileSystem);
+
         void GetDeskItems(AFileSystemBase fs)
         void GetDeskItems(AFileSystemBase fs)
         {
         {
             using var csvParser = OpenCsvParser("desk_item_detail.nei", fs);
             using var csvParser = OpenCsvParser("desk_item_detail.nei", fs);
@@ -791,8 +796,6 @@ public static class Constants
                     com3d2DeskDogu.Add(dogu);
                     com3d2DeskDogu.Add(dogu);
             }
             }
         }
         }
-
-        GetDeskItems(GameUty.FileSystem);
     }
     }
 
 
     private static void InitializePhotoBGItems()
     private static void InitializePhotoBGItems()
@@ -919,12 +922,14 @@ public static class Constants
 
 
         if (!MenuFilesReady)
         if (!MenuFilesReady)
         {
         {
-            if (!beginMpnAttachInit)
-                MenuFilesReadyChange += (_, _) =>
-                    InitializeMpnAttachProps();
+            if (beginMpnAttachInit)
+                return;
 
 
             beginMpnAttachInit = true;
             beginMpnAttachInit = true;
 
 
+            MenuFilesReadyChange += (_, _) =>
+                InitializeMpnAttachProps();
+
             return;
             return;
         }
         }
 
 
@@ -959,16 +964,7 @@ public static class Constants
 
 
         var myRoomData = PlacementData.GetAllDatas(false);
         var myRoomData = PlacementData.GetAllDatas(false);
 
 
-        myRoomData.Sort((a, b) =>
-            {
-                var res = a.categoryID.CompareTo(b.categoryID);
-
-                if (res is 0)
-                    res = a.ID.CompareTo(b.ID);
-
-                return res;
-            }
-        );
+        myRoomData.Sort(MyRoomDataComparator);
 
 
         foreach (var data in myRoomData)
         foreach (var data in myRoomData)
         {
         {
@@ -981,10 +977,24 @@ public static class Constants
             }
             }
 
 
             var asset = !string.IsNullOrEmpty(data.resourceName) ? data.resourceName : data.assetName;
             var asset = !string.IsNullOrEmpty(data.resourceName) ? data.resourceName : data.assetName;
-            var item = new MyRoomItem() { PrefabName = asset, ID = data.ID };
+            var item = new MyRoomItem()
+            {
+                PrefabName = asset,
+                ID = data.ID,
+            };
 
 
             MyRoomPropDict[category].Add(item);
             MyRoomPropDict[category].Add(item);
         }
         }
+
+        static int MyRoomDataComparator(PlacementData.Data a, PlacementData.Data b)
+        {
+            var res = a.categoryID.CompareTo(b.categoryID);
+
+            if (res is 0)
+                res = a.ID.CompareTo(b.ID);
+
+            return res;
+        }
     }
     }
 
 
     private static void InitializeModProps()
     private static void InitializeModProps()

+ 9 - 8
src/MeidoPhotoStudio.Plugin/DragPoint/CustomGizmo.cs

@@ -36,8 +36,6 @@ public class CustomGizmo : GizmoRender
     private Vector3 deltaScale = Vector3.zero;
     private Vector3 deltaScale = Vector3.zero;
     private Vector3 scaleOld = Vector3.one;
     private Vector3 scaleOld = Vector3.one;
     private GizmoType gizmoTypeOld;
     private GizmoType gizmoTypeOld;
-    private int SelectedType =>
-        (int)beSelectedType.GetValue(this);
 
 
     public GizmoType CurrentGizmoType
     public GizmoType CurrentGizmoType
     {
     {
@@ -71,6 +69,9 @@ public class CustomGizmo : GizmoRender
         }
         }
     }
     }
 
 
+    private int SelectedType =>
+        (int)beSelectedType.GetValue(this);
+
     public static CustomGizmo Make(Transform target, float scale = 0.25f, GizmoMode mode = GizmoMode.Local)
     public static CustomGizmo Make(Transform target, float scale = 0.25f, GizmoMode mode = GizmoMode.Local)
     {
     {
         var gizmoGo = new GameObject($"[MPS Gizmo {target.gameObject.name}]");
         var gizmoGo = new GameObject($"[MPS Gizmo {target.gameObject.name}]");
@@ -88,12 +89,6 @@ public class CustomGizmo : GizmoRender
         return gizmo;
         return gizmo;
     }
     }
 
 
-    public void SetAlternateTarget(Transform trans)
-    {
-        positionTransform = trans;
-        hasAlternateTarget = trans != null;
-    }
-
     public override void Update()
     public override void Update()
     {
     {
         BeginUpdate();
         BeginUpdate();
@@ -108,6 +103,12 @@ public class CustomGizmo : GizmoRender
         EndUpdate();
         EndUpdate();
     }
     }
 
 
+    public void SetAlternateTarget(Transform trans)
+    {
+        positionTransform = trans;
+        hasAlternateTarget = trans != null;
+    }
+
     private void BeginUpdate()
     private void BeginUpdate()
     {
     {
         var rotation = transform.rotation;
         var rotation = transform.rotation;

+ 5 - 5
src/MeidoPhotoStudio.Plugin/DragPoint/DragPoint.cs

@@ -39,14 +39,14 @@ public abstract class DragPoint : MonoBehaviour
     private float dragPointScale = 1f;
     private float dragPointScale = 1f;
     private bool gizmoEnabled = true;
     private bool gizmoEnabled = true;
 
 
-    public GameObject MyGameObject =>
-        MyObject.gameObject;
-
     public Vector3 OriginalScale { get; private set; }
     public Vector3 OriginalScale { get; private set; }
     public Transform MyObject { get; protected set; }
     public Transform MyObject { get; protected set; }
     public GameObject GizmoGo { get; protected set; }
     public GameObject GizmoGo { get; protected set; }
     public CustomGizmo Gizmo { get; protected set; }
     public CustomGizmo Gizmo { get; protected set; }
 
 
+    public GameObject MyGameObject =>
+        MyObject.gameObject;
+
     public Vector3 BaseScale
     public Vector3 BaseScale
     {
     {
         get => baseScale;
         get => baseScale;
@@ -205,8 +205,8 @@ public abstract class DragPoint : MonoBehaviour
     {
     {
         screenPoint = camera.WorldToScreenPoint(transform.position);
         screenPoint = camera.WorldToScreenPoint(transform.position);
         startMousePosition = Utility.MousePosition;
         startMousePosition = Utility.MousePosition;
-        startOffset =
-            transform.position - camera.ScreenToWorldPoint(new(startMousePosition.x, startMousePosition.y, screenPoint.z));
+        startOffset = transform.position
+            - camera.ScreenToWorldPoint(new(startMousePosition.x, startMousePosition.y, screenPoint.z));
         newOffset = transform.position - MyObject.position;
         newOffset = transform.position - MyObject.position;
     }
     }
 
 

+ 2 - 0
src/MeidoPhotoStudio.Plugin/DragPoint/DragPointGeneral.cs

@@ -144,6 +144,8 @@ public abstract class DragPointGeneral : DragPoint
         var cursorPosition = CursorPosition();
         var cursorPosition = CursorPosition();
         var mouseDelta = MouseDelta();
         var mouseDelta = MouseDelta();
 
 
+        // CurrentDragType can only be one thing at a time afaik so maybe refactor to else if chain
+
         if (CurrentDragType is DragType.MoveXZ)
         if (CurrentDragType is DragType.MoveXZ)
         {
         {
             MyObject.position = new(cursorPosition.x, MyObject.position.y, cursorPosition.z);
             MyObject.position = new(cursorPosition.x, MyObject.position.y, cursorPosition.z);

+ 0 - 2
src/MeidoPhotoStudio.Plugin/DragPoint/DragPointGravity.cs

@@ -20,7 +20,6 @@ public class DragPointGravity : DragPointGeneral
     public static GravityTransformControl MakeGravityControl(Maid maid, bool skirt = false)
     public static GravityTransformControl MakeGravityControl(Maid maid, bool skirt = false)
     {
     {
         var category = skirt ? "skirt" : "hair";
         var category = skirt ? "skirt" : "hair";
-
         var bone = maid.body0.GetBone("Bip01");
         var bone = maid.body0.GetBone("Bip01");
         var gravityGoName = $"GravityDatas_{maid.status.guid}_{category}";
         var gravityGoName = $"GravityDatas_{maid.status.guid}_{category}";
         var gravityTransform = maid.gameObject.transform.Find(gravityGoName);
         var gravityTransform = maid.gameObject.transform.Find(gravityGoName);
@@ -50,7 +49,6 @@ public class DragPointGravity : DragPointGeneral
         }
         }
 
 
         var gravityControl = gravityTransform.gameObject.AddComponent<GravityTransformControl>();
         var gravityControl = gravityTransform.gameObject.AddComponent<GravityTransformControl>();
-
         var slots = skirt ? skirtSlots : hairSlots;
         var slots = skirt ? skirtSlots : hairSlots;
 
 
         gravityControl.SetTargetSlods(slots);
         gravityControl.SetTargetSlods(slots);

+ 17 - 17
src/MeidoPhotoStudio.Plugin/DragPoint/DragPointLight.cs

@@ -149,6 +149,23 @@ public class DragPointLight : DragPointGeneral
             light.transform.localScale = Vector3.one * prop.Range;
             light.transform.localScale = Vector3.one * prop.Range;
     }
     }
 
 
+    public override void Set(Transform myObject)
+    {
+        base.Set(myObject);
+
+        light = myObject.gameObject.GetOrAddComponent<Light>();
+
+        // TODO: Use trasnform.SetPositionAndRotation
+        light.transform.position = LightProperty.DefaultPosition;
+        light.transform.rotation = LightProperty.DefaultRotation;
+
+        SetLightType(MPSLightType.Normal);
+
+        ScaleFactor = 50f;
+        DefaultRotation = LightProperty.DefaultRotation;
+        DefaultPosition = LightProperty.DefaultPosition;
+    }
+
     public void SetLightType(MPSLightType type)
     public void SetLightType(MPSLightType type)
     {
     {
         const string spotName = "spot";
         const string spotName = "spot";
@@ -235,23 +252,6 @@ public class DragPointLight : DragPointGeneral
     public void ResetLightPosition() =>
     public void ResetLightPosition() =>
         light.transform.position = LightProperty.DefaultPosition;
         light.transform.position = LightProperty.DefaultPosition;
 
 
-    public override void Set(Transform myObject)
-    {
-        base.Set(myObject);
-
-        light = myObject.gameObject.GetOrAddComponent<Light>();
-
-        // TODO: Use trasnform.SetPositionAndRotation
-        light.transform.position = LightProperty.DefaultPosition;
-        light.transform.rotation = LightProperty.DefaultRotation;
-
-        SetLightType(MPSLightType.Normal);
-
-        ScaleFactor = 50f;
-        DefaultRotation = LightProperty.DefaultRotation;
-        DefaultPosition = LightProperty.DefaultPosition;
-    }
-
     protected override void OnDestroy()
     protected override void OnDestroy()
     {
     {
         if (!IsMain)
         if (!IsMain)

+ 14 - 14
src/MeidoPhotoStudio.Plugin/DragPoint/DragPointProp.cs

@@ -28,12 +28,23 @@ public class DragPointProp : DragPointGeneral
         }
         }
     }
     }
 
 
+    public override void Set(Transform myObject)
+    {
+        base.Set(myObject);
+
+        DefaultRotation = MyObject.rotation;
+        DefaultPosition = MyObject.position;
+        DefaultScale = MyObject.localScale;
+        renderers = new(MyObject.GetComponentsInChildren<Renderer>());
+    }
+
     public void AttachTo(Meido meido, AttachPoint point, bool keepWorldPosition = true)
     public void AttachTo(Meido meido, AttachPoint point, bool keepWorldPosition = true)
     {
     {
         var attachPoint = meido?.IKManager.GetAttachPointTransform(point);
         var attachPoint = meido?.IKManager.GetAttachPointTransform(point);
 
 
         AttachPointInfo = meido is null ? AttachPointInfo.Empty : new(point, meido);
         AttachPointInfo = meido is null ? AttachPointInfo.Empty : new(point, meido);
 
 
+        // TODO: Use transform.SetPositionAndRotation MyObject.position = position;
         var position = MyObject.position;
         var position = MyObject.position;
         var rotation = MyObject.rotation;
         var rotation = MyObject.rotation;
         var scale = MyObject.localScale;
         var scale = MyObject.localScale;
@@ -41,7 +52,6 @@ public class DragPointProp : DragPointGeneral
         MyObject.transform.SetParent(attachPoint, keepWorldPosition);
         MyObject.transform.SetParent(attachPoint, keepWorldPosition);
 
 
         if (keepWorldPosition)
         if (keepWorldPosition)
-            // TODO: Use transform.SetPositionAndRotation MyObject.position = position;
             MyObject.rotation = rotation;
             MyObject.rotation = rotation;
         else
         else
         {
         {
@@ -64,16 +74,6 @@ public class DragPointProp : DragPointGeneral
         Utility.FixGameObjectScale(MyGameObject);
         Utility.FixGameObjectScale(MyGameObject);
     }
     }
 
 
-    public override void Set(Transform myObject)
-    {
-        base.Set(myObject);
-
-        DefaultRotation = MyObject.rotation;
-        DefaultPosition = MyObject.position;
-        DefaultScale = MyObject.localScale;
-        renderers = new(MyObject.GetComponentsInChildren<Renderer>());
-    }
-
     protected override void ApplyDragType()
     protected override void ApplyDragType()
     {
     {
         var active = DragPointEnabled && Transforming || Special;
         var active = DragPointEnabled && Transforming || Special;
@@ -100,9 +100,6 @@ public class PropInfo
     public string SubFilename { get; set; }
     public string SubFilename { get; set; }
     public int MyRoomID { get; set; }
     public int MyRoomID { get; set; }
 
 
-    public PropInfo(PropType type) =>
-        Type = type;
-
     public static PropInfo FromModItem(ModItem modItem) =>
     public static PropInfo FromModItem(ModItem modItem) =>
         new(PropType.Mod)
         new(PropType.Mod)
         {
         {
@@ -122,4 +119,7 @@ public class PropInfo
 
 
     public static PropInfo FromGameProp(string name) =>
     public static PropInfo FromGameProp(string name) =>
         new(PropType.Odogu) { Filename = name };
         new(PropType.Odogu) { Filename = name };
+
+    public PropInfo(PropType type) =>
+        Type = type;
 }
 }

+ 6 - 6
src/MeidoPhotoStudio.Plugin/GUI/Controls/Button.cs

@@ -10,16 +10,16 @@ public class Button : BaseControl
     public Button(string label) =>
     public Button(string label) =>
         Label = label;
         Label = label;
 
 
-    public void Draw(GUIStyle buttonStyle, params GUILayoutOption[] layoutOptions)
-    {
-        if (GUILayout.Button(Label, buttonStyle, layoutOptions))
-            OnControlEvent(EventArgs.Empty);
-    }
-
     public override void Draw(params GUILayoutOption[] layoutOptions)
     public override void Draw(params GUILayoutOption[] layoutOptions)
     {
     {
         var buttonStyle = new GUIStyle(GUI.skin.button);
         var buttonStyle = new GUIStyle(GUI.skin.button);
 
 
         Draw(buttonStyle, layoutOptions);
         Draw(buttonStyle, layoutOptions);
     }
     }
+
+    public void Draw(GUIStyle buttonStyle, params GUILayoutOption[] layoutOptions)
+    {
+        if (GUILayout.Button(Label, buttonStyle, layoutOptions))
+            OnControlEvent(EventArgs.Empty);
+    }
 }
 }

+ 10 - 10
src/MeidoPhotoStudio.Plugin/GUI/Controls/ComboBox.cs

@@ -23,6 +23,16 @@ public class ComboBox : BaseControl
         Value = itemList[0];
         Value = itemList[0];
     }
     }
 
 
+    public override void Draw(params GUILayoutOption[] layoutOptions)
+    {
+        var buttonStyle = new GUIStyle(GUI.skin.button)
+        {
+            alignment = TextAnchor.MiddleCenter,
+        };
+
+        Draw(buttonStyle, layoutOptions);
+    }
+
     public void SetDropdownItems(string[] itemList)
     public void SetDropdownItems(string[] itemList)
     {
     {
         var oldValue = Value;
         var oldValue = Value;
@@ -44,14 +54,4 @@ public class ComboBox : BaseControl
         BaseDropDown.Draw(style, GUILayout.ExpandWidth(false));
         BaseDropDown.Draw(style, GUILayout.ExpandWidth(false));
         GUILayout.EndHorizontal();
         GUILayout.EndHorizontal();
     }
     }
-
-    public override void Draw(params GUILayoutOption[] layoutOptions)
-    {
-        var buttonStyle = new GUIStyle(GUI.skin.button)
-        {
-            alignment = TextAnchor.MiddleCenter,
-        };
-
-        Draw(buttonStyle, layoutOptions);
-    }
 }
 }

+ 3 - 6
src/MeidoPhotoStudio.Plugin/GUI/Controls/DropDown.cs

@@ -28,6 +28,9 @@ public class Dropdown : BaseControl
     public Vector2 ScrollPos =>
     public Vector2 ScrollPos =>
         scrollPos;
         scrollPos;
 
 
+    public string SelectedItem =>
+        DropdownList[SelectedItemIndex];
+
     public Rect ButtonRect
     public Rect ButtonRect
     {
     {
         get => buttonRect;
         get => buttonRect;
@@ -47,9 +50,6 @@ public class Dropdown : BaseControl
         }
         }
     }
     }
 
 
-    public string SelectedItem =>
-        DropdownList[SelectedItemIndex];
-
     public Dropdown(string label, string[] itemList, int selectedItemIndex = 0)
     public Dropdown(string label, string[] itemList, int selectedItemIndex = 0)
         : this(itemList, selectedItemIndex)
         : this(itemList, selectedItemIndex)
     {
     {
@@ -262,12 +262,9 @@ public static class DropdownHelper
         buttonRect = dropdown.ButtonRect;
         buttonRect = dropdown.ButtonRect;
 
 
         var calculatedSize = dropdown.ElementSize;
         var calculatedSize = dropdown.ElementSize;
-
         var calculatedListHeight = calculatedSize.y * dropdownList.Length;
         var calculatedListHeight = calculatedSize.y * dropdownList.Length;
-
         var heightAbove = buttonRect.y;
         var heightAbove = buttonRect.y;
         var heightBelow = Screen.height - heightAbove - buttonRect.height;
         var heightBelow = Screen.height - heightAbove - buttonRect.height;
-
         var rectWidth = Mathf.Max(calculatedSize.x + 5, buttonRect.width);
         var rectWidth = Mathf.Max(calculatedSize.x + 5, buttonRect.width);
         var rectHeight = Mathf.Min(calculatedListHeight, Mathf.Max(heightAbove, heightBelow));
         var rectHeight = Mathf.Min(calculatedListHeight, Mathf.Max(heightAbove, heightBelow));
 
 

+ 7 - 7
src/MeidoPhotoStudio.Plugin/GUI/Controls/KeyRebindButton.cs

@@ -27,13 +27,6 @@ public class KeyRebindButton : BaseControl
             StartListening();
             StartListening();
     }
     }
 
 
-    public void Draw(GUIStyle buttonStyle, params GUILayoutOption[] layoutOptions)
-    {
-        GUI.enabled = !listening && !InputManager.Listening;
-        button.Draw(buttonStyle, layoutOptions);
-        GUI.enabled = true;
-    }
-
     public override void Draw(params GUILayoutOption[] layoutOptions)
     public override void Draw(params GUILayoutOption[] layoutOptions)
     {
     {
         var buttonStyle = new GUIStyle(GUI.skin.button);
         var buttonStyle = new GUIStyle(GUI.skin.button);
@@ -41,6 +34,13 @@ public class KeyRebindButton : BaseControl
         Draw(buttonStyle, layoutOptions);
         Draw(buttonStyle, layoutOptions);
     }
     }
 
 
+    public void Draw(GUIStyle buttonStyle, params GUILayoutOption[] layoutOptions)
+    {
+        GUI.enabled = !listening && !InputManager.Listening;
+        button.Draw(buttonStyle, layoutOptions);
+        GUI.enabled = true;
+    }
+
     private void StartListening()
     private void StartListening()
     {
     {
         listening = true;
         listening = true;

+ 10 - 10
src/MeidoPhotoStudio.Plugin/GUI/Controls/SelectionGrid.cs

@@ -28,6 +28,16 @@ public class SelectionGrid : BaseControl
         toggles = MakeToggles(items);
         toggles = MakeToggles(items);
     }
     }
 
 
+    public override void Draw(params GUILayoutOption[] layoutOptions)
+    {
+        GUILayout.BeginHorizontal();
+
+        foreach (var toggle in toggles)
+            toggle.Draw(layoutOptions);
+
+        GUILayout.EndHorizontal();
+    }
+
     public void SetItems(string[] items, int selectedItemIndex = -1)
     public void SetItems(string[] items, int selectedItemIndex = -1)
     {
     {
         if (selectedItemIndex < 0)
         if (selectedItemIndex < 0)
@@ -47,16 +57,6 @@ public class SelectionGrid : BaseControl
         SelectedItemIndex = Mathf.Clamp(selectedItemIndex, 0, items.Length - 1);
         SelectedItemIndex = Mathf.Clamp(selectedItemIndex, 0, items.Length - 1);
     }
     }
 
 
-    public override void Draw(params GUILayoutOption[] layoutOptions)
-    {
-        GUILayout.BeginHorizontal();
-
-        foreach (var toggle in toggles)
-            toggle.Draw(layoutOptions);
-
-        GUILayout.EndHorizontal();
-    }
-
     private SimpleToggle[] MakeToggles(string[] items)
     private SimpleToggle[] MakeToggles(string[] items)
     {
     {
         var toggles = new SimpleToggle[items.Length];
         var toggles = new SimpleToggle[items.Length];

+ 9 - 11
src/MeidoPhotoStudio.Plugin/GUI/Controls/Slider.cs

@@ -15,6 +15,8 @@ public class Slider : BaseControl
     private string textFieldValue;
     private string textFieldValue;
     private bool hasTextField;
     private bool hasTextField;
 
 
+    public bool HasReset { get; set; }
+
     public string Label
     public string Label
     {
     {
         get => label;
         get => label;
@@ -77,8 +79,6 @@ public class Slider : BaseControl
         }
         }
     }
     }
 
 
-    public bool HasReset { get; set; }
-
     public Slider(string label, float left, float right, float value = 0, float defaultValue = 0)
     public Slider(string label, float left, float right, float value = 0, float defaultValue = 0)
     {
     {
         Label = label;
         Label = label;
@@ -93,17 +93,9 @@ public class Slider : BaseControl
 
 
     public Slider(SliderProp prop) : this(string.Empty, prop.Left, prop.Right, prop.Initial, prop.Default) { }
     public Slider(SliderProp prop) : this(string.Empty, prop.Left, prop.Right, prop.Initial, prop.Default) { }
 
 
-    public void SetBounds(float left, float right)
-    {
-        this.left = left;
-        this.right = right;
-        value = Utility.Bound(value, left, right);
-    }
-
     public override void Draw(params GUILayoutOption[] layoutOptions)
     public override void Draw(params GUILayoutOption[] layoutOptions)
     {
     {
         var hasUpper = hasLabel || HasTextField || HasReset;
         var hasUpper = hasLabel || HasTextField || HasReset;
-
         var tempText = string.Empty;
         var tempText = string.Empty;
 
 
         if (hasUpper)
         if (hasUpper)
@@ -130,7 +122,6 @@ public class Slider : BaseControl
         }
         }
 
 
         var sliderStyle = hasUpper ? MpsGui.SliderStyle : MpsGui.SliderStyleNoLabel;
         var sliderStyle = hasUpper ? MpsGui.SliderStyle : MpsGui.SliderStyleNoLabel;
-
         var tempValue =
         var tempValue =
             GUILayout.HorizontalSlider(Value, Left, Right, sliderStyle, MpsGui.SliderThumbStyle, layoutOptions);
             GUILayout.HorizontalSlider(Value, Left, Right, sliderStyle, MpsGui.SliderThumbStyle, layoutOptions);
 
 
@@ -155,6 +146,13 @@ public class Slider : BaseControl
             Value = tempValue;
             Value = tempValue;
     }
     }
 
 
+    public void SetBounds(float left, float right)
+    {
+        this.left = left;
+        this.right = right;
+        value = Utility.Bound(value, left, right);
+    }
+
     private static string FormatValue(float value) =>
     private static string FormatValue(float value) =>
         value.ToString("0.####", CultureInfo.InvariantCulture);
         value.ToString("0.####", CultureInfo.InvariantCulture);
 }
 }

+ 3 - 3
src/MeidoPhotoStudio.Plugin/GUI/Controls/TextArea.cs

@@ -6,9 +6,9 @@ public class TextArea : BaseControl
 {
 {
     public string Value { get; set; } = string.Empty;
     public string Value { get; set; } = string.Empty;
 
 
-    public void Draw(GUIStyle textAreaStyle, params GUILayoutOption[] layoutOptions) =>
-        Value = GUILayout.TextArea(Value, textAreaStyle, layoutOptions);
-
     public override void Draw(params GUILayoutOption[] layoutOptions) =>
     public override void Draw(params GUILayoutOption[] layoutOptions) =>
         Draw(new(GUI.skin.textArea), layoutOptions);
         Draw(new(GUI.skin.textArea), layoutOptions);
+
+    public void Draw(GUIStyle textAreaStyle, params GUILayoutOption[] layoutOptions) =>
+        Value = GUILayout.TextArea(Value, textAreaStyle, layoutOptions);
 }
 }

+ 3 - 3
src/MeidoPhotoStudio.Plugin/GUI/Controls/TextField.cs

@@ -14,6 +14,9 @@ public class TextField : BaseControl
 
 
     public string Value { get; set; } = string.Empty;
     public string Value { get; set; } = string.Empty;
 
 
+    public override void Draw(params GUILayoutOption[] layoutOptions) =>
+        Draw(new(GUI.skin.textField), layoutOptions);
+
     public void Draw(GUIStyle textFieldStyle, params GUILayoutOption[] layoutOptions)
     public void Draw(GUIStyle textFieldStyle, params GUILayoutOption[] layoutOptions)
     {
     {
         GUI.SetNextControlName(controlName);
         GUI.SetNextControlName(controlName);
@@ -22,7 +25,4 @@ public class TextField : BaseControl
         if (Event.current.isKey && Event.current.keyCode is KeyCode.Return)
         if (Event.current.isKey && Event.current.keyCode is KeyCode.Return)
             OnControlEvent(EventArgs.Empty);
             OnControlEvent(EventArgs.Empty);
     }
     }
-
-    public override void Draw(params GUILayoutOption[] layoutOptions) =>
-        Draw(new(GUI.skin.textField), layoutOptions);
 }
 }

+ 5 - 5
src/MeidoPhotoStudio.Plugin/GUI/Controls/Toggle.cs

@@ -7,6 +7,8 @@ public class Toggle : BaseControl
 {
 {
     private bool value;
     private bool value;
 
 
+    public string Label { get; set; }
+
     public bool Value
     public bool Value
     {
     {
         get => value;
         get => value;
@@ -18,14 +20,15 @@ public class Toggle : BaseControl
         }
         }
     }
     }
 
 
-    public string Label { get; set; }
-
     public Toggle(string label, bool state = false)
     public Toggle(string label, bool state = false)
     {
     {
         Label = label;
         Label = label;
         value = state;
         value = state;
     }
     }
 
 
+    public override void Draw(params GUILayoutOption[] layoutOptions) =>
+        Draw(new(GUI.skin.toggle), layoutOptions);
+
     public void Draw(GUIStyle toggleStyle, params GUILayoutOption[] layoutOptions)
     public void Draw(GUIStyle toggleStyle, params GUILayoutOption[] layoutOptions)
     {
     {
         var value = GUILayout.Toggle(Value, Label, toggleStyle, layoutOptions);
         var value = GUILayout.Toggle(Value, Label, toggleStyle, layoutOptions);
@@ -41,7 +44,4 @@ public class Toggle : BaseControl
         if (value != Value)
         if (value != Value)
             Value = value;
             Value = value;
     }
     }
-
-    public override void Draw(params GUILayoutOption[] layoutOptions) =>
-        Draw(new(GUI.skin.toggle), layoutOptions);
 }
 }

+ 15 - 15
src/MeidoPhotoStudio.Plugin/GUI/Panes/BackgroundWindow2Panes/AttachPropPane.cs

@@ -30,7 +30,7 @@ public class AttachPropPane : BasePane
             [AttachPoint.Spine1a] = "spine1a",
             [AttachPoint.Spine1a] = "spine1a",
             [AttachPoint.Spine1] = "spine1",
             [AttachPoint.Spine1] = "spine1",
             [AttachPoint.Spine0a] = "spine0a",
             [AttachPoint.Spine0a] = "spine0a",
-            [AttachPoint.Spine0] = "spine0"
+            [AttachPoint.Spine0] = "spine0",
         };
         };
 
 
     private readonly PropManager propManager;
     private readonly PropManager propManager;
@@ -95,20 +95,6 @@ public class AttachPropPane : BasePane
         }
         }
     }
     }
 
 
-    protected override void ReloadTranslation()
-    {
-        header = Translation.Get("attachPropPane", "header");
-        keepWorldPositionToggle.Label = Translation.Get("attachPropPane", "keepWorldPosition");
-
-        foreach (var attachPoint in Enum.GetValues(typeof(AttachPoint)).Cast<AttachPoint>())
-        {
-            if (attachPoint is AttachPoint.None)
-                continue;
-
-            toggles[attachPoint].Label = Translation.Get("attachPropPane", toggleTranslation[attachPoint]);
-        }
-    }
-
     public override void Draw()
     public override void Draw()
     {
     {
         const float dropdownButtonHeight = 30;
         const float dropdownButtonHeight = 30;
@@ -141,6 +127,20 @@ public class AttachPropPane : BasePane
         GUI.enabled = true;
         GUI.enabled = true;
     }
     }
 
 
+    protected override void ReloadTranslation()
+    {
+        header = Translation.Get("attachPropPane", "header");
+        keepWorldPositionToggle.Label = Translation.Get("attachPropPane", "keepWorldPosition");
+
+        foreach (var attachPoint in Enum.GetValues(typeof(AttachPoint)).Cast<AttachPoint>())
+        {
+            if (attachPoint is AttachPoint.None)
+                continue;
+
+            toggles[attachPoint].Label = Translation.Get("attachPropPane", toggleTranslation[attachPoint]);
+        }
+    }
+
     private void DrawToggleGroup(params AttachPoint[] attachPoints)
     private void DrawToggleGroup(params AttachPoint[] attachPoints)
     {
     {
         GUILayout.BeginHorizontal();
         GUILayout.BeginHorizontal();

+ 0 - 1
src/MeidoPhotoStudio.Plugin/GUI/Panes/BackgroundWindow2Panes/ModPropsPane.cs

@@ -112,7 +112,6 @@ public class ModPropsPane : BasePane
             const int columns = 4;
             const int columns = 4;
 
 
             var buttonSize = windowWidth / columns - 10f;
             var buttonSize = windowWidth / columns - 10f;
-
             var positionRect = new Rect(5f, offsetTop + dropdownButtonHeight, windowWidth - 10f, windowHeight - 145f);
             var positionRect = new Rect(5f, offsetTop + dropdownButtonHeight, windowWidth - 10f, windowHeight - 145f);
 
 
             var viewRect = new Rect(
             var viewRect = new Rect(

+ 0 - 3
src/MeidoPhotoStudio.Plugin/GUI/Panes/BackgroundWindow2Panes/MyRoomPropsPane.cs

@@ -44,7 +44,6 @@ public class MyRoomPropsPane : BasePane
         GUILayout.EndHorizontal();
         GUILayout.EndHorizontal();
 
 
         var windowRect = parent.WindowRect;
         var windowRect = parent.WindowRect;
-
         var windowHeight = windowRect.height;
         var windowHeight = windowRect.height;
         var windowWidth = windowRect.width;
         var windowWidth = windowRect.width;
 
 
@@ -52,9 +51,7 @@ public class MyRoomPropsPane : BasePane
         const int columns = 3;
         const int columns = 3;
 
 
         var buttonSize = windowWidth / columns - 10f;
         var buttonSize = windowWidth / columns - 10f;
-
         var listCount = myRoomPropList.Count;
         var listCount = myRoomPropList.Count;
-
         var positionRect = new Rect(5f, offsetTop + dropdownButtonHeight, windowWidth - 10f, windowHeight - 145f);
         var positionRect = new Rect(5f, offsetTop + dropdownButtonHeight, windowWidth - 10f, windowHeight - 145f);
         var viewRect = new Rect(0f, 0f, buttonSize * columns, buttonSize * Mathf.Ceil(listCount / (float)columns) + 5f);
         var viewRect = new Rect(0f, 0f, buttonSize * columns, buttonSize * Mathf.Ceil(listCount / (float)columns) + 5f);
 
 

+ 1 - 1
src/MeidoPhotoStudio.Plugin/GUI/Panes/BackgroundWindowPanes/BackgroundSelectorPane.cs

@@ -16,7 +16,6 @@ public class BackgroundSelectorPane : BasePane
         this.environmentManager = environmentManager;
         this.environmentManager = environmentManager;
 
 
         var theaterIndex = Constants.BGList.FindIndex(bg => bg == EnvironmentManager.defaultBg);
         var theaterIndex = Constants.BGList.FindIndex(bg => bg == EnvironmentManager.defaultBg);
-
         var bgList = new List<string>(Translation.GetList("bgNames", Constants.BGList));
         var bgList = new List<string>(Translation.GetList("bgNames", Constants.BGList));
 
 
         if (Constants.MyRoomCustomBGIndex >= 0)
         if (Constants.MyRoomCustomBGIndex >= 0)
@@ -79,6 +78,7 @@ public class BackgroundSelectorPane : BasePane
 
 
         var selectedIndex = bgDropdown.SelectedItemIndex;
         var selectedIndex = bgDropdown.SelectedItemIndex;
         var isCreative = bgDropdown.SelectedItemIndex >= Constants.MyRoomCustomBGIndex;
         var isCreative = bgDropdown.SelectedItemIndex >= Constants.MyRoomCustomBGIndex;
+
         var bg = isCreative
         var bg = isCreative
             ? Constants.MyRoomCustomBGList[selectedIndex - Constants.MyRoomCustomBGIndex].Key
             ? Constants.MyRoomCustomBGList[selectedIndex - Constants.MyRoomCustomBGIndex].Key
             : Constants.BGList[selectedIndex];
             : Constants.BGList[selectedIndex];

+ 2 - 2
src/MeidoPhotoStudio.Plugin/GUI/Panes/BackgroundWindowPanes/EffectsPanes/EffectPane.cs

@@ -7,8 +7,6 @@ public abstract class EffectPane<T> : BasePane where T : IEffectManager
     protected readonly Toggle effectToggle;
     protected readonly Toggle effectToggle;
     protected readonly Button resetEffectButton;
     protected readonly Button resetEffectButton;
 
 
-    protected abstract T EffectManager { get; set; }
-
     private bool enabled;
     private bool enabled;
 
 
     public override bool Enabled
     public override bool Enabled
@@ -25,6 +23,8 @@ public abstract class EffectPane<T> : BasePane where T : IEffectManager
         }
         }
     }
     }
 
 
+    protected abstract T EffectManager { get; set; }
+
     protected EffectPane(EffectManager effectManager)
     protected EffectPane(EffectManager effectManager)
     {
     {
         EffectManager = effectManager.Get<T>();
         EffectManager = effectManager.Get<T>();

+ 2 - 2
src/MeidoPhotoStudio.Plugin/GUI/Panes/BackgroundWindowPanes/LightsPane.cs

@@ -14,7 +14,7 @@ public class LightsPane : BasePane
     {
     {
         { "lights", "x" }, { "lights", "y" }, { "lights", "intensity" }, { "lights", "shadow" }, { "lights", "spot" },
         { "lights", "x" }, { "lights", "y" }, { "lights", "intensity" }, { "lights", "shadow" }, { "lights", "spot" },
         { "lights", "range" }, { "backgroundWindow", "red" }, { "backgroundWindow", "green" },
         { "lights", "range" }, { "backgroundWindow", "red" }, { "backgroundWindow", "green" },
-        { "backgroundWindow", "blue" }
+        { "backgroundWindow", "blue" },
     };
     };
 
 
     private readonly LightManager lightManager;
     private readonly LightManager lightManager;
@@ -99,6 +99,7 @@ public class LightsPane : BasePane
         {
         {
             var lightProp = (LightProp)i;
             var lightProp = (LightProp)i;
             var sliderProp = lightSliderProp[lightProp];
             var sliderProp = lightSliderProp[lightProp];
+
             var slider = new Slider(Translation.Get(sliderNames[i, 0], sliderNames[i, 1]), sliderProp)
             var slider = new Slider(Translation.Get(sliderNames[i, 0], sliderNames[i, 1]), sliderProp)
             {
             {
                 HasTextField = true,
                 HasTextField = true,
@@ -156,7 +157,6 @@ public class LightsPane : BasePane
     public override void Draw()
     public override void Draw()
     {
     {
         var isMain = lightManager.SelectedLightIndex is 0;
         var isMain = lightManager.SelectedLightIndex is 0;
-
         var noExpandWidth = GUILayout.ExpandWidth(false);
         var noExpandWidth = GUILayout.ExpandWidth(false);
 
 
         MpsGui.Header(lightHeader);
         MpsGui.Header(lightHeader);

+ 1 - 1
src/MeidoPhotoStudio.Plugin/GUI/Panes/FaceWindowPanes/MaidFaceSliderPane.cs

@@ -59,7 +59,7 @@ public class MaidFaceSliderPane : BasePane
         // Tongue Up
         // Tongue Up
         ["tangup"] = 1f,
         ["tangup"] = 1f,
         // Tongue Base
         // Tongue Base
-        ["tangopen"] = 1f
+        ["tangopen"] = 1f,
     };
     };
 
 
     private readonly MeidoManager meidoManager;
     private readonly MeidoManager meidoManager;

+ 1 - 1
src/MeidoPhotoStudio.Plugin/GUI/Panes/MainWindowPanes/BGWindowPane.cs

@@ -30,7 +30,7 @@ public class BGWindowPane : BaseMainWindowPane
             ["bloom"] = new BloomPane(effectManager),
             ["bloom"] = new BloomPane(effectManager),
             ["dof"] = new DepthOfFieldPane(effectManager),
             ["dof"] = new DepthOfFieldPane(effectManager),
             ["vignette"] = new VignettePane(effectManager),
             ["vignette"] = new VignettePane(effectManager),
-            ["fog"] = new FogPane(effectManager)
+            ["fog"] = new FogPane(effectManager),
         });
         });
 
 
         otherEffectsPane = AddPane(new OtherEffectsPane(effectManager));
         otherEffectsPane = AddPane(new OtherEffectsPane(effectManager));

+ 1 - 0
src/MeidoPhotoStudio.Plugin/GUI/Panes/MainWindowPanes/FaceWindowPane.cs

@@ -10,6 +10,7 @@ public class FaceWindowPane : BaseMainWindowPane
     private readonly MaidSwitcherPane maidSwitcherPane;
     private readonly MaidSwitcherPane maidSwitcherPane;
     private readonly SaveFacePane saveFacePane;
     private readonly SaveFacePane saveFacePane;
     private readonly Toggle saveFaceToggle;
     private readonly Toggle saveFaceToggle;
+
     private bool saveFaceMode;
     private bool saveFaceMode;
 
 
     public FaceWindowPane(MeidoManager meidoManager, MaidSwitcherPane maidSwitcherPane)
     public FaceWindowPane(MeidoManager meidoManager, MaidSwitcherPane maidSwitcherPane)

+ 1 - 0
src/MeidoPhotoStudio.Plugin/GUI/Panes/OtherPanes/MaidSwitcherPane.cs

@@ -96,6 +96,7 @@ public class MaidSwitcherPane : BasePane
             editToggle.Draw(new Rect(previousRect.x + 4f, previousRect.y, 40f, 20f));
             editToggle.Draw(new Rect(previousRect.x + 4f, previousRect.y, 40f, 20f));
 
 
         var labelRect = new Rect(previousRect.width - 45f, previousRect.y, 40f, 20f);
         var labelRect = new Rect(previousRect.width - 45f, previousRect.y, 40f, 20f);
+
         var slotStyle = new GUIStyle()
         var slotStyle = new GUIStyle()
         {
         {
             alignment = TextAnchor.UpperRight,
             alignment = TextAnchor.UpperRight,

+ 2 - 2
src/MeidoPhotoStudio.Plugin/GUI/Panes/OtherPanes/TabsPane.cs

@@ -9,10 +9,10 @@ public class TabsPane : BasePane
 
 
     private readonly SelectionGrid Tabs;
     private readonly SelectionGrid Tabs;
 
 
-    private Constants.Window selectedTab;
-
     public event EventHandler TabChange;
     public event EventHandler TabChange;
 
 
+    private Constants.Window selectedTab;
+
     public Constants.Window SelectedTab
     public Constants.Window SelectedTab
     {
     {
         get => selectedTab;
         get => selectedTab;

+ 8 - 8
src/MeidoPhotoStudio.Plugin/GUI/Panes/PoseWindowPanes/GravityControlPane.cs

@@ -30,14 +30,6 @@ public class GravityControlPane : BasePane
         header = Translation.Get("gravityControlPane", "gravityHeader");
         header = Translation.Get("gravityControlPane", "gravityHeader");
     }
     }
 
 
-    protected override void ReloadTranslation()
-    {
-        hairToggle.Label = Translation.Get("gravityControlPane", "hairToggle");
-        skirtToggle.Label = Translation.Get("gravityControlPane", "skirtToggle");
-        globalToggle.Label = Translation.Get("gravityControlPane", "globalToggle");
-        header = Translation.Get("gravityControlPane", "gravityHeader");
-    }
-
     public override void Draw()
     public override void Draw()
     {
     {
         var enabled = meidoManager.HasActiveMeido;
         var enabled = meidoManager.HasActiveMeido;
@@ -80,6 +72,14 @@ public class GravityControlPane : BasePane
         updating = false;
         updating = false;
     }
     }
 
 
+    protected override void ReloadTranslation()
+    {
+        hairToggle.Label = Translation.Get("gravityControlPane", "hairToggle");
+        skirtToggle.Label = Translation.Get("gravityControlPane", "skirtToggle");
+        globalToggle.Label = Translation.Get("gravityControlPane", "globalToggle");
+        header = Translation.Get("gravityControlPane", "gravityHeader");
+    }
+
     private void ToggleGravity(bool value, bool skirt = false)
     private void ToggleGravity(bool value, bool skirt = false)
     {
     {
         if (updating)
         if (updating)

+ 9 - 9
src/MeidoPhotoStudio.Plugin/GUI/Panes/PoseWindowPanes/HandPresetPane.cs

@@ -69,15 +69,6 @@ public class HandPresetPane : BasePane
         presetListEnabled = CurrentPresetList.Count > 0;
         presetListEnabled = CurrentPresetList.Count > 0;
     }
     }
 
 
-    protected override void ReloadTranslation()
-    {
-        leftHandButton.Label = Translation.Get("handPane", "leftHand");
-        rightHandButton.Label = Translation.Get("handPane", "rightHand");
-
-        if (CurrentPresetList.Count is 0)
-            presetDropdown.SetDropdownItems(UIPresetList());
-    }
-
     public override void Draw()
     public override void Draw()
     {
     {
         var dropdownWidth = GUILayout.Width(156f);
         var dropdownWidth = GUILayout.Width(156f);
@@ -107,6 +98,15 @@ public class HandPresetPane : BasePane
         GUI.enabled = true;
         GUI.enabled = true;
     }
     }
 
 
+    protected override void ReloadTranslation()
+    {
+        leftHandButton.Label = Translation.Get("handPane", "leftHand");
+        rightHandButton.Label = Translation.Get("handPane", "rightHand");
+
+        if (CurrentPresetList.Count is 0)
+            presetDropdown.SetDropdownItems(UIPresetList());
+    }
+
     private void ChangePresetCategory()
     private void ChangePresetCategory()
     {
     {
         presetListEnabled = CurrentPresetList.Count > 0;
         presetListEnabled = CurrentPresetList.Count > 0;

+ 7 - 7
src/MeidoPhotoStudio.Plugin/GUI/Panes/PoseWindowPanes/MaidDressingPane.cs

@@ -15,23 +15,23 @@ public class MaidDressingPane : BasePane
         // detailed slots
         // detailed slots
         SlotID.accAshi, SlotID.accHana, SlotID.accHat, SlotID.accHeso, SlotID.accKamiSubL, SlotID.accKamiSubR,
         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.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,
+        SlotID.accMiMiR, SlotID.accNipL, SlotID.accNipR, SlotID.accShippo, SlotID.accXXX,
+        // unused slots
+        // SlotID.mizugi, SlotID.onepiece, SlotID.accHead,
     };
     };
 
 
     public static readonly SlotID[] BodySlots =
     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
+        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[] WearSlots = { SlotID.wear, SlotID.mizugi, SlotID.onepiece };
 
 
     public static readonly SlotID[] HeadwearSlots =
     public static readonly SlotID[] HeadwearSlots =
     {
     {
-        SlotID.headset, SlotID.accHat, SlotID.accKamiSubL, SlotID.accKamiSubR, SlotID.accKami_1_,
-        SlotID.accKami_2_, SlotID.accKami_3_
+        SlotID.headset, SlotID.accHat, SlotID.accKamiSubL, SlotID.accKamiSubR, SlotID.accKami_1_, SlotID.accKami_2_,
+        SlotID.accKami_3_,
     };
     };
 
 
     private static readonly string[] maskLabels = { "all", "underwear", "nude" };
     private static readonly string[] maskLabels = { "all", "underwear", "nude" };

+ 32 - 32
src/MeidoPhotoStudio.Plugin/GUI/Panes/PoseWindowPanes/MaidFreeLookPane.cs

@@ -35,6 +35,38 @@ public class MaidFaceLookPane : BasePane
         bindLabel = Translation.Get("freeLookPane", "bindLabel");
         bindLabel = Translation.Get("freeLookPane", "bindLabel");
     }
     }
 
 
+    public override void Draw()
+    {
+        GUI.enabled = meidoManager.HasActiveMeido && meidoManager.ActiveMeido.FreeLook;
+        GUILayout.BeginHorizontal();
+        lookXSlider.Draw();
+        lookYSlider.Draw();
+        GUILayout.EndHorizontal();
+
+        GUI.enabled = meidoManager.HasActiveMeido;
+
+        GUILayout.BeginHorizontal();
+        GUILayout.Label(bindLabel, GUILayout.ExpandWidth(false));
+        eyeToCamToggle.Draw();
+        headToCamToggle.Draw();
+        GUILayout.EndHorizontal();
+
+        GUI.enabled = true;
+    }
+
+    public override void UpdatePane()
+    {
+        var meido = meidoManager.ActiveMeido;
+
+        updating = true;
+        SetBounds();
+        lookXSlider.Value = meido.Body.offsetLookTarget.z;
+        lookYSlider.Value = meido.Body.offsetLookTarget.x;
+        eyeToCamToggle.Value = meido.EyeToCam;
+        headToCamToggle.Value = meido.HeadToCam;
+        updating = false;
+    }
+
     public void SetHeadToCam(bool value, bool eye = false)
     public void SetHeadToCam(bool value, bool eye = false)
     {
     {
         if (updating)
         if (updating)
@@ -72,38 +104,6 @@ public class MaidFaceLookPane : BasePane
         lookYSlider.SetBounds(left, right);
         lookYSlider.SetBounds(left, right);
     }
     }
 
 
-    public override void UpdatePane()
-    {
-        var meido = meidoManager.ActiveMeido;
-
-        updating = true;
-        SetBounds();
-        lookXSlider.Value = meido.Body.offsetLookTarget.z;
-        lookYSlider.Value = meido.Body.offsetLookTarget.x;
-        eyeToCamToggle.Value = meido.EyeToCam;
-        headToCamToggle.Value = meido.HeadToCam;
-        updating = false;
-    }
-
-    public override void Draw()
-    {
-        GUI.enabled = meidoManager.HasActiveMeido && meidoManager.ActiveMeido.FreeLook;
-        GUILayout.BeginHorizontal();
-        lookXSlider.Draw();
-        lookYSlider.Draw();
-        GUILayout.EndHorizontal();
-
-        GUI.enabled = meidoManager.HasActiveMeido;
-
-        GUILayout.BeginHorizontal();
-        GUILayout.Label(bindLabel, GUILayout.ExpandWidth(false));
-        eyeToCamToggle.Draw();
-        headToCamToggle.Draw();
-        GUILayout.EndHorizontal();
-
-        GUI.enabled = true;
-    }
-
     protected override void ReloadTranslation()
     protected override void ReloadTranslation()
     {
     {
         lookXSlider.Label = Translation.Get("freeLookPane", "xSlider");
         lookXSlider.Label = Translation.Get("freeLookPane", "xSlider");

+ 0 - 10
src/MeidoPhotoStudio.Plugin/MaidPlacementUtility.cs

@@ -79,9 +79,7 @@ public static class MaidPlacementUtility
         for (var i = 0; i < list.Count; i++)
         for (var i = 0; i < list.Count; i++)
         {
         {
             var position = Vector3.zero;
             var position = Vector3.zero;
-
             var maid = list[i].Maid;
             var maid = list[i].Maid;
-
             var a = AlternatingSequence(i) * 0.6f;
             var a = AlternatingSequence(i) * 0.6f;
 
 
             if (vertical)
             if (vertical)
@@ -112,7 +110,6 @@ public static class MaidPlacementUtility
         for (var i = 0; i < list.Count; i++)
         for (var i = 0; i < list.Count; i++)
         {
         {
             var maid = list[i].Maid;
             var maid = list[i].Maid;
-
             var x = AlternatingSequence(i) * 0.4f;
             var x = AlternatingSequence(i) * 0.4f;
             var z = (inverse ? -1 : 1) * Mathf.Cos(AlternatingSequence(i) * pi) * 0.35f;
             var z = (inverse ? -1 : 1) * Mathf.Cos(AlternatingSequence(i) * pi) * 0.35f;
 
 
@@ -126,7 +123,6 @@ public static class MaidPlacementUtility
         for (var i = 0; i < list.Count; i++)
         for (var i = 0; i < list.Count; i++)
         {
         {
             var maid = list[i].Maid;
             var maid = list[i].Maid;
-
             var x = AlternatingSequence(i) * 0.4f;
             var x = AlternatingSequence(i) * 0.4f;
             var z = (inverse ? 1 : -1) * Mathf.Abs(AlternatingSequence(i)) * 0.4f;
             var z = (inverse ? 1 : -1) * Mathf.Abs(AlternatingSequence(i)) * 0.4f;
 
 
@@ -144,9 +140,7 @@ public static class MaidPlacementUtility
         for (var i = 0; i < maidCount; i++)
         for (var i = 0; i < maidCount; i++)
         {
         {
             var maid = list[i].Maid;
             var maid = list[i].Maid;
-
             var angle = pi / 2f + tau * AlternatingSequence(i) / maidCount;
             var angle = pi / 2f + tau * AlternatingSequence(i) / maidCount;
-
             var x = Mathf.Cos(angle) * radius;
             var x = Mathf.Cos(angle) * radius;
             var z = Mathf.Sin(angle) * radius;
             var z = Mathf.Sin(angle) * radius;
 
 
@@ -163,7 +157,6 @@ public static class MaidPlacementUtility
     public static void PlacementFan(IList<Meido> list, bool outer = false)
     public static void PlacementFan(IList<Meido> list, bool outer = false)
     {
     {
         var maidCount = list.Count;
         var maidCount = list.Count;
-
         var radius = 0.2f + 0.2f * maidCount;
         var radius = 0.2f + 0.2f * maidCount;
 
 
         list[0].Maid.SetPos(Vector3.zero);
         list[0].Maid.SetPos(Vector3.zero);
@@ -172,12 +165,9 @@ public static class MaidPlacementUtility
         for (var i = 1; i < maidCount; i++)
         for (var i = 1; i < maidCount; i++)
         {
         {
             var maid = list[i].Maid;
             var maid = list[i].Maid;
-
             var angle = pi * AlternatingSequence(i - 1) / maidCount;
             var angle = pi * AlternatingSequence(i - 1) / maidCount;
-
             var x = Mathf.Sin(angle) * radius;
             var x = Mathf.Sin(angle) * radius;
             var z = Mathf.Cos(angle) * radius;
             var z = Mathf.Cos(angle) * radius;
-
             var rotation = Mathf.Atan2(x, z);
             var rotation = Mathf.Atan2(x, z);
 
 
             if (outer)
             if (outer)

+ 1 - 1
src/MeidoPhotoStudio.Plugin/Managers/InputManager.cs

@@ -17,7 +17,7 @@ public enum MpsKey
     // Dragpoint
     // Dragpoint
     DragSelect, DragDelete, DragMove, DragRotate, DragScale, DragFinger,
     DragSelect, DragDelete, DragMove, DragRotate, DragScale, DragFinger,
     // Scene management
     // Scene management
-    SaveScene, LoadScene, OpenSceneManager
+    SaveScene, LoadScene, OpenSceneManager,
 }
 }
 
 
 public static class InputManager
 public static class InputManager

+ 1 - 1
src/MeidoPhotoStudio.Plugin/Meido/IK/IK Chain/DragPointChain.cs

@@ -18,7 +18,7 @@ public abstract class DragPointChain : DragPointMeido
         {
         {
             myObject.parent,
             myObject.parent,
             myObject.parent,
             myObject.parent,
-            myObject
+            myObject,
         };
         };
 
 
         ikCtrlData = IkCtrlData;
         ikCtrlData = IkCtrlData;

+ 4 - 4
src/MeidoPhotoStudio.Plugin/Meido/Meido.cs

@@ -24,7 +24,7 @@ public class Meido
             "eyeclose", "eyeclose2", "eyeclose3", "eyebig", "eyeclose6", "eyeclose5", "hitomih",
             "eyeclose", "eyeclose2", "eyeclose3", "eyebig", "eyeclose6", "eyeclose5", "hitomih",
             "hitomis", "mayuha", "mayuw", "mayuup", "mayuv", "mayuvhalf", "moutha", "mouths",
             "hitomis", "mayuha", "mayuw", "mayuup", "mayuv", "mayuvhalf", "moutha", "mouths",
             "mouthc", "mouthi", "mouthup", "mouthdw", "mouthhe", "mouthuphalf", "tangout",
             "mouthc", "mouthi", "mouthup", "mouthdw", "mouthhe", "mouthuphalf", "tangout",
-            "tangup", "tangopen"
+            "tangup", "tangopen",
         };
         };
 
 
     public static readonly string[] faceToggleKeys =
     public static readonly string[] faceToggleKeys =
@@ -33,7 +33,7 @@ public class Meido
             // blush, shade, nose up, tears, drool, teeth
             // blush, shade, nose up, tears, drool, teeth
             "hoho2", "shock", "nosefook", "namida", "yodare", "toothoff",
             "hoho2", "shock", "nosefook", "namida", "yodare", "toothoff",
             // cry 1, cry 2, cry 3, blush 1, blush 2, blush 3
             // cry 1, cry 2, cry 3, blush 1, blush 2, blush 3
-            "tear1", "tear2", "tear3", "hohos", "hoho", "hohol"
+            "tear1", "tear2", "tear3", "hohos", "hoho", "hohol",
         };
         };
 
 
     private readonly FieldInfo m_eMaskMode = Utility.GetFieldInfo<TBody>("m_eMaskMode");
     private readonly FieldInfo m_eMaskMode = Utility.GetFieldInfo<TBody>("m_eMaskMode");
@@ -645,7 +645,7 @@ public class Meido
             {
             {
                 Curl.Shift => "パンツずらし",
                 Curl.Shift => "パンツずらし",
                 Curl.Front => "めくれスカート",
                 Curl.Front => "めくれスカート",
-                _ => "めくれスカート後ろ"
+                _ => "めくれスカート後ろ",
             };
             };
 
 
             Maid.ItemChangeTemp(name[0], action);
             Maid.ItemChangeTemp(name[0], action);
@@ -753,7 +753,7 @@ public class Meido
             new[]
             new[]
             {
             {
                 MPN.skirt, MPN.onepiece, MPN.mizugi, MPN.panz, MPN.set_maidwear, MPN.set_mywear, MPN.set_underwear,
                 MPN.skirt, MPN.onepiece, MPN.mizugi, MPN.panz, MPN.set_maidwear, MPN.set_mywear, MPN.set_underwear,
-                MPN.hairf, MPN.hairr, MPN.hairs, MPN.hairt
+                MPN.hairf, MPN.hairr, MPN.hairs, MPN.hairt,
             };
             };
 
 
         Action action = null;
         Action action = null;

+ 7 - 6
src/MeidoPhotoStudio.Plugin/Meido/MeidoDragPointManager.cs

@@ -9,7 +9,7 @@ namespace MeidoPhotoStudio.Plugin;
 public enum AttachPoint
 public enum AttachPoint
 {
 {
     None, Head, Neck, UpperArmL, UpperArmR, ForearmL, ForearmR, MuneL, MuneR, HandL, HandR, Pelvis, ThighL, ThighR,
     None, Head, Neck, UpperArmL, UpperArmR, ForearmL, ForearmR, MuneL, MuneR, HandL, HandR, Pelvis, ThighL, ThighR,
-    CalfL, CalfR, FootL, FootR, Spine1a, Spine1, Spine0a, Spine0
+    CalfL, CalfR, FootL, FootR, Spine1a, Spine1, Spine0a, Spine0,
 }
 }
 
 
 public class MeidoDragPointManager
 public class MeidoDragPointManager
@@ -55,7 +55,7 @@ public class MeidoDragPointManager
         Toe2L, Toe21L, Toe2NubL,
         Toe2L, Toe21L, Toe2NubL,
         Toe0R, Toe01R, Toe0NubR,
         Toe0R, Toe01R, Toe0NubR,
         Toe1R, Toe11R, Toe1NubR,
         Toe1R, Toe11R, Toe1NubR,
-        Toe2R, Toe21R, Toe2NubR
+        Toe2R, Toe21R, Toe2NubR,
     }
     }
 
 
     private static readonly Dictionary<AttachPoint, Bone> PointToBone = new()
     private static readonly Dictionary<AttachPoint, Bone> PointToBone = new()
@@ -80,12 +80,12 @@ public class MeidoDragPointManager
         [AttachPoint.Spine1a] = Bone.Spine1a,
         [AttachPoint.Spine1a] = Bone.Spine1a,
         [AttachPoint.Spine1] = Bone.Spine1,
         [AttachPoint.Spine1] = Bone.Spine1,
         [AttachPoint.Spine0a] = Bone.Spine0a,
         [AttachPoint.Spine0a] = Bone.Spine0a,
-        [AttachPoint.Spine0] = Bone.Spine
+        [AttachPoint.Spine0] = Bone.Spine,
     };
     };
 
 
     private static readonly Bone[] SpineBones =
     private static readonly Bone[] SpineBones =
     {
     {
-        Bone.Neck, Bone.Spine, Bone.Spine0a, Bone.Spine1, Bone.Spine1a, Bone.Hip, Bone.ThighL, Bone.ThighR
+        Bone.Neck, Bone.Spine, Bone.Spine0a, Bone.Spine1, Bone.Spine1a, Bone.Hip, Bone.ThighL, Bone.ThighR,
     };
     };
 
 
     private static bool cubeActive;
     private static bool cubeActive;
@@ -279,6 +279,7 @@ public class MeidoDragPointManager
                 if (!reader.ReadBoolean())
                 if (!reader.ReadBoolean())
                 {
                 {
                     reader.ReadQuaternion();
                     reader.ReadQuaternion();
+
                     continue;
                     continue;
                 }
                 }
             }
             }
@@ -303,7 +304,7 @@ public class MeidoDragPointManager
         var pair = new[]
         var pair = new[]
             {
             {
                 Bone.ClavicleL, Bone.ClavicleR, Bone.UpperArmL, Bone.UpperArmR, Bone.ForearmL, Bone.ForearmR,
                 Bone.ClavicleL, Bone.ClavicleR, Bone.UpperArmL, Bone.UpperArmR, Bone.ForearmL, Bone.ForearmR,
-                Bone.ThighL, Bone.ThighR, Bone.CalfL, Bone.CalfR, Bone.HandL, Bone.HandR, Bone.FootL, Bone.FootR
+                Bone.ThighL, Bone.ThighR, Bone.CalfL, Bone.CalfR, Bone.HandL, Bone.HandR, Bone.FootL, Bone.FootR,
             };
             };
 
 
         var singleRotations = single.Select(bone => BoneTransform[bone].eulerAngles).ToList();
         var singleRotations = single.Select(bone => BoneTransform[bone].eulerAngles).ToList();
@@ -804,7 +805,7 @@ public class MeidoDragPointManager
             [Bone.Toe1NubR] = CMT.SearchObjName(transform, "Bip01 R Toe1Nub"),
             [Bone.Toe1NubR] = CMT.SearchObjName(transform, "Bip01 R Toe1Nub"),
             [Bone.Toe2R] = CMT.SearchObjName(transform, "Bip01 R Toe2"),
             [Bone.Toe2R] = CMT.SearchObjName(transform, "Bip01 R Toe2"),
             [Bone.Toe21R] = CMT.SearchObjName(transform, "Bip01 R Toe21"),
             [Bone.Toe21R] = CMT.SearchObjName(transform, "Bip01 R Toe21"),
-            [Bone.Toe2NubR] = CMT.SearchObjName(transform, "Bip01 R Toe2Nub")
+            [Bone.Toe2NubR] = CMT.SearchObjName(transform, "Bip01 R Toe2Nub"),
         };
         };
     }
     }
 }
 }

+ 18 - 17
src/MeidoPhotoStudio.Plugin/MeidoPhotoStudio.cs

@@ -24,14 +24,14 @@ public class MeidoPhotoStudio : BaseUnityPlugin
     public static readonly byte[] SceneHeader = Encoding.UTF8.GetBytes("MPSSCENE");
     public static readonly byte[] SceneHeader = Encoding.UTF8.GetBytes("MPSSCENE");
     public static readonly string pluginString = $"{pluginName} {pluginVersion}";
     public static readonly string pluginString = $"{pluginName} {pluginVersion}";
 
 
-    public static bool EditMode =>
-        currentScene is Constants.Scene.Edit;
-
     public static event EventHandler<ScreenshotEventArgs> NotifyRawScreenshot;
     public static event EventHandler<ScreenshotEventArgs> NotifyRawScreenshot;
 
 
     private static event EventHandler<ScreenshotEventArgs> ScreenshotEvent;
     private static event EventHandler<ScreenshotEventArgs> ScreenshotEvent;
     private static Constants.Scene currentScene;
     private static Constants.Scene currentScene;
 
 
+    public static bool EditMode =>
+        currentScene is Constants.Scene.Edit;
+
     private HarmonyLib.Harmony harmony;
     private HarmonyLib.Harmony harmony;
     private WindowManager windowManager;
     private WindowManager windowManager;
     private SceneManager sceneManager;
     private SceneManager sceneManager;
@@ -158,7 +158,8 @@ public class MeidoPhotoStudio : BaseUnityPlugin
 
 
                         break;
                         break;
                     case MessageWindowManager.header:
                     case MessageWindowManager.header:
-                        Serialization.Get<MessageWindowManager>().Deserialize(messageWindowManager, dataReader, metadata);
+                        Serialization.Get<MessageWindowManager>()
+                            .Deserialize(messageWindowManager, dataReader, metadata);
 
 
                         break;
                         break;
                     case CameraManager.header:
                     case CameraManager.header:
@@ -305,7 +306,7 @@ public class MeidoPhotoStudio : BaseUnityPlugin
             MeidoDragPointManager.CubeActive,
             MeidoDragPointManager.CubeActive,
             PropManager.CubeActive,
             PropManager.CubeActive,
             LightManager.CubeActive,
             LightManager.CubeActive,
-            EnvironmentManager.CubeActive
+            EnvironmentManager.CubeActive,
         };
         };
 
 
         MeidoDragPointManager.CubeActive = false;
         MeidoDragPointManager.CubeActive = false;
@@ -335,6 +336,7 @@ public class MeidoPhotoStudio : BaseUnityPlugin
 
 
             CameraUtility.MainCamera.camera.targetTexture = null;
             CameraUtility.MainCamera.camera.targetTexture = null;
             RenderTexture.active = null;
             RenderTexture.active = null;
+
             DestroyImmediate(renderTexture);
             DestroyImmediate(renderTexture);
         }
         }
         else
         else
@@ -430,7 +432,6 @@ public class MeidoPhotoStudio : BaseUnityPlugin
             uiActive = true;
             uiActive = true;
 
 
         var maidSwitcherPane = new MaidSwitcherPane(meidoManager);
         var maidSwitcherPane = new MaidSwitcherPane(meidoManager);
-
         var sceneWindow = new SceneWindow(sceneManager);
         var sceneWindow = new SceneWindow(sceneManager);
 
 
         windowManager = new()
         windowManager = new()
@@ -443,10 +444,10 @@ public class MeidoPhotoStudio : BaseUnityPlugin
                 [Constants.Window.BG] =
                 [Constants.Window.BG] =
                     new BGWindowPane(environmentManager, lightManager, effectManager, sceneWindow, cameraManager),
                     new BGWindowPane(environmentManager, lightManager, effectManager, sceneWindow, cameraManager),
                 [Constants.Window.BG2] = new BG2WindowPane(meidoManager, propManager),
                 [Constants.Window.BG2] = new BG2WindowPane(meidoManager, propManager),
-                [Constants.Window.Settings] = new SettingsWindowPane()
+                [Constants.Window.Settings] = new SettingsWindowPane(),
             },
             },
             [Constants.Window.Message] = new MessageWindow(messageWindowManager),
             [Constants.Window.Message] = new MessageWindow(messageWindowManager),
-            [Constants.Window.Save] = sceneWindow
+            [Constants.Window.Save] = sceneWindow,
         };
         };
     }
     }
 
 
@@ -505,17 +506,17 @@ public class MeidoPhotoStudio : BaseUnityPlugin
         }
         }
 
 
         sysDialog.Show(
         sysDialog.Show(
-            string.Format(Translation.Get("systemMessage", "exitConfirm"), pluginName),
-            SystemDialog.TYPE.OK_CANCEL,
-            Exit,
-            () =>
-            {
-                sysDialog.Close();
-                uiActive = true;
-                active = true;
-            }
+            string.Format(Translation.Get("systemMessage", "exitConfirm"), pluginName), SystemDialog.TYPE.OK_CANCEL,
+            Exit, Resume
         );
         );
 
 
+        void Resume()
+        {
+            sysDialog.Close();
+            uiActive = true;
+            active = true;
+        }
+
         void Exit()
         void Exit()
         {
         {
             sysDialog.Close();
             sysDialog.Close();

+ 3 - 2
src/MeidoPhotoStudio.Plugin/MenuFileUtility.cs

@@ -15,8 +15,8 @@ public static class MenuFileUtility
     public static readonly string[] MenuCategories =
     public static readonly string[] MenuCategories =
     {
     {
         noCategory, "acchat", "headset", "wear", "skirt", "onepiece", "mizugi", "bra", "panz", "stkg", "shoes",
         noCategory, "acchat", "headset", "wear", "skirt", "onepiece", "mizugi", "bra", "panz", "stkg", "shoes",
-        "acckami", "megane", "acchead", "acchana", "accmimi", "glove", "acckubi", "acckubiwa", "acckamisub",
-        "accnip", "accude", "accheso", "accashi", "accsenaka", "accshippo", "accxxx"
+        "acckami", "megane", "acchead", "acchana", "accmimi", "glove", "acckubi", "acckubiwa", "acckamisub", "accnip",
+        "accude", "accheso", "accashi", "accsenaka", "accshippo", "accxxx",
     };
     };
 
 
     private static readonly HashSet<string> accMpn = new(StringComparer.InvariantCultureIgnoreCase);
     private static readonly HashSet<string> accMpn = new(StringComparer.InvariantCultureIgnoreCase);
@@ -43,6 +43,7 @@ public static class MenuFileUtility
             return null;
             return null;
         }
         }
 
 
+        // INFO: Don't really understand what this does.
         ref var buffer = ref GetFileBuffer(aFileBase.GetSize());
         ref var buffer = ref GetFileBuffer(aFileBase.GetSize());
 
 
         aFileBase.Read(ref buffer, aFileBase.GetSize());
         aFileBase.Read(ref buffer, aFileBase.GetSize());

+ 3 - 3
src/MeidoPhotoStudio.Plugin/MenuItem.cs

@@ -26,14 +26,14 @@ public class ModItem : MenuItem
             MenuFile = menuFile,
             MenuFile = menuFile,
             IsMod = true,
             IsMod = true,
             IsOfficialMod = true,
             IsOfficialMod = true,
-            Priority = 1000f
+            Priority = 1000f,
         };
         };
 
 
     public static ModItem Mod(string menuFile) =>
     public static ModItem Mod(string menuFile) =>
         new()
         new()
         {
         {
             MenuFile = menuFile,
             MenuFile = menuFile,
-            IsMod = true
+            IsMod = true,
         };
         };
 
 
     public static ModItem Deserialize(BinaryReader binaryReader) =>
     public static ModItem Deserialize(BinaryReader binaryReader) =>
@@ -46,7 +46,7 @@ public class ModItem : MenuItem
             Category = binaryReader.ReadNullableString(),
             Category = binaryReader.ReadNullableString(),
             Priority = float.Parse(binaryReader.ReadNullableString()),
             Priority = float.Parse(binaryReader.ReadNullableString()),
             IsMod = binaryReader.ReadBoolean(),
             IsMod = binaryReader.ReadBoolean(),
-            IsOfficialMod = binaryReader.ReadBoolean()
+            IsOfficialMod = binaryReader.ReadBoolean(),
         };
         };
 
 
     public ModItem() { }
     public ModItem() { }

+ 0 - 3
src/MeidoPhotoStudio.Plugin/ModelUtility.cs

@@ -216,7 +216,6 @@ public static class ModelUtility
 
 
         var rootName = binaryReader.ReadString();
         var rootName = binaryReader.ReadString();
         var boneCount = binaryReader.ReadInt32();
         var boneCount = binaryReader.ReadInt32();
-
         var boneDict = new Dictionary<string, GameObject>();
         var boneDict = new Dictionary<string, GameObject>();
         var boneList = new List<GameObject>(boneCount);
         var boneList = new List<GameObject>(boneCount);
 
 
@@ -278,11 +277,9 @@ public static class ModelUtility
             meshRenderer.motionVectorGenerationMode = MotionVectorGenerationMode.ForceNoMotion;
             meshRenderer.motionVectorGenerationMode = MotionVectorGenerationMode.ForceNoMotion;
 
 
             var sharedMesh = meshRenderer.sharedMesh = new();
             var sharedMesh = meshRenderer.sharedMesh = new();
-
             var vertCount = binaryReader.ReadInt32();
             var vertCount = binaryReader.ReadInt32();
             var subMeshCount = binaryReader.ReadInt32();
             var subMeshCount = binaryReader.ReadInt32();
             var meshBoneCount = binaryReader.ReadInt32();
             var meshBoneCount = binaryReader.ReadInt32();
-
             var meshBones = new Transform[meshBoneCount];
             var meshBones = new Transform[meshBoneCount];
 
 
             for (var i = 0; i < meshBoneCount; i++)
             for (var i = 0; i < meshBoneCount; i++)

+ 0 - 1
src/MeidoPhotoStudio.Plugin/MyGui.cs

@@ -94,5 +94,4 @@ public static class MpsGui
 
 
     private static void Line(GUIStyle style) =>
     private static void Line(GUIStyle style) =>
         GUILayout.Box(GUIContent.none, style, GUILayout.Height(1));
         GUILayout.Box(GUIContent.none, style, GUILayout.Height(1));
-
 }
 }

+ 0 - 1
src/MeidoPhotoStudio.Plugin/Serialization/Serializers/ManagerSerializers/LightManagerSerializer.cs

@@ -33,7 +33,6 @@ public class LightManagerSerializer : Serializer<LightManager>
         _ = reader.ReadVersion();
         _ = reader.ReadVersion();
 
 
         var lightCount = reader.ReadInt32();
         var lightCount = reader.ReadInt32();
-
         var list = GetLightList(manager);
         var list = GetLightList(manager);
 
 
         LightSerializer.Deserialize(list[0], reader, metadata);
         LightSerializer.Deserialize(list[0], reader, metadata);

+ 1 - 0
src/MeidoPhotoStudio.Plugin/Serialization/Serializers/ManagerSerializers/MeidoManagerSerializer.cs

@@ -59,6 +59,7 @@ public class MeidoManagerSerializer : Serializer<MeidoManager>
         _ = reader.ReadVersion();
         _ = reader.ReadVersion();
 
 
         var meidoCount = reader.ReadInt32();
         var meidoCount = reader.ReadInt32();
+
         for (var i = 0; i < meidoCount; i++)
         for (var i = 0; i < meidoCount; i++)
         {
         {
             if (i >= manager.ActiveMeidoList.Count)
             if (i >= manager.ActiveMeidoList.Count)

+ 229 - 229
src/MeidoPhotoStudio.Plugin/Serialization/Serializers/MeidoSerializer.cs

@@ -19,327 +19,327 @@ public class MeidoSerializer : Serializer<Meido>
     private static SimpleSerializer<TransformDTO> TransformDtoSerializer =>
     private static SimpleSerializer<TransformDTO> TransformDtoSerializer =>
         Serialization.GetSimple<TransformDTO>();
         Serialization.GetSimple<TransformDTO>();
 
 
-    private static void SerializeHead(Meido meido, BinaryWriter writer)
+    public override void Serialize(Meido meido, BinaryWriter writer)
     {
     {
-        var body = meido.Body;
-
-        writer.WriteVersion(headVersion);
-
-        // eye direction
-        writer.WriteQuaternion(body.quaDefEyeL * Quaternion.Inverse(meido.DefaultEyeRotL));
-        writer.WriteQuaternion(body.quaDefEyeR * Quaternion.Inverse(meido.DefaultEyeRotR));
-
-        // free look
-        writer.Write(meido.FreeLook);
-        writer.WriteVector3(body.offsetLookTarget);
-        writer.WriteVector3(Utility.GetFieldValue<TBody, Vector3>(body, "HeadEulerAngle"));
+        var maid = meido.Maid;
 
 
-        // Head/eye to camera
-        writer.Write(meido.HeadToCam);
-        writer.Write(meido.EyeToCam);
+        using var memoryStream = new MemoryStream();
+        using var tempWriter = new BinaryWriter(memoryStream, Encoding.UTF8);
 
 
-        // face
-        var faceDict = meido.SerializeFace();
+        tempWriter.WriteVersion(version);
 
 
-        writer.Write(faceDict.Count);
+        TransformDtoSerializer.Serialize(new TransformDTO(maid.transform), tempWriter);
 
 
-        foreach (var (hash, value) in faceDict)
-        {
-            writer.Write(hash);
-            writer.Write(value);
-        }
-    }
+        SerializeHead(meido, tempWriter);
 
 
-    private static void SerializeBody(Meido meido, BinaryWriter writer)
-    {
-        writer.WriteVersion(bodyVersion);
+        SerializeBody(meido, tempWriter);
 
 
-        // pose
-        var poseBuffer = meido.SerializePose(true);
+        SerializeClothing(meido, tempWriter);
 
 
-        writer.Write(poseBuffer.Length);
-        writer.Write(poseBuffer);
+        writer.Write(memoryStream.Length);
+        writer.Write(memoryStream.ToArray());
 
 
-        PoseInfoSerializer.Serialize(meido.CachedPose, writer);
+        static void SerializeHead(Meido meido, BinaryWriter writer)
+        {
+            var body = meido.Body;
 
 
-        // TODO: Think about how to indicate code for new versions of serialization.
-        #region v2
-        // sub mune rotation
-        var body = meido.Body;
+            writer.WriteVersion(headVersion);
 
 
-        writer.WriteQuaternion(body.GetBone("Mune_L_sub").localRotation);
-        writer.WriteQuaternion(body.GetBone("Mune_R_sub").localRotation);
-        #endregion
-    }
+            // eye direction
+            writer.WriteQuaternion(body.quaDefEyeL * Quaternion.Inverse(meido.DefaultEyeRotL));
+            writer.WriteQuaternion(body.quaDefEyeR * Quaternion.Inverse(meido.DefaultEyeRotR));
 
 
-    private static void SerializeClothing(Meido meido, BinaryWriter writer)
-    {
-        var maid = meido.Maid;
-        var body = meido.Body;
+            // free look
+            writer.Write(meido.FreeLook);
+            writer.WriteVector3(body.offsetLookTarget);
+            writer.WriteVector3(Utility.GetFieldValue<TBody, Vector3>(body, "HeadEulerAngle"));
 
 
-        writer.WriteVersion(clothingVersion);
+            // Head/eye to camera
+            writer.Write(meido.HeadToCam);
+            writer.Write(meido.EyeToCam);
 
 
-        // body visible
-        writer.Write(body.GetMask(TBody.SlotID.body));
+            // face
+            var faceDict = meido.SerializeFace();
 
 
-        // clothing
-        foreach (var clothingSlot in MaidDressingPane.ClothingSlots)
-        {
-            var value = true;
+            writer.Write(faceDict.Count);
 
 
-            if (clothingSlot is TBody.SlotID.wear)
+            foreach (var (hash, value) in faceDict)
             {
             {
-                if (MaidDressingPane.WearSlots.Any(slot => body.GetSlotLoaded(slot)))
-                    value = MaidDressingPane.WearSlots.Any(slot => body.GetMask(slot));
+                writer.Write(hash);
+                writer.Write(value);
             }
             }
-            else if (clothingSlot is TBody.SlotID.megane)
-            {
-                var slots = new[] { TBody.SlotID.megane, TBody.SlotID.accHead };
-
-                if (slots.Any(slot => body.GetSlotLoaded(slot)))
-                    value = slots.Any(slot => body.GetMask(slot));
-            }
-            else if (body.GetSlotLoaded(clothingSlot))
-                value = body.GetMask(clothingSlot);
-
-            writer.Write(value);
         }
         }
 
 
-        // zurashi and mekure
-        writer.Write(meido.CurlingFront);
-        writer.Write(meido.CurlingBack);
-        writer.Write(meido.PantsuShift);
-
-        // mpn attach props
-        var hasKousokuUpper = body.GetSlotLoaded(TBody.SlotID.kousoku_upper);
-
-        writer.Write(hasKousokuUpper);
-        writer.Write(maid.GetProp(MPN.kousoku_upper).strTempFileName);
-
-        var hasKousokuLower = body.GetSlotLoaded(TBody.SlotID.kousoku_lower);
+        static void SerializeBody(Meido meido, BinaryWriter writer)
+        {
+            writer.WriteVersion(bodyVersion);
 
 
-        writer.Write(hasKousokuLower);
-        writer.Write(maid.GetProp(MPN.kousoku_lower).strTempFileName);
+            // pose
+            var poseBuffer = meido.SerializePose(true);
 
 
-        // hair/skirt gravity
-        writer.Write(meido.HairGravityActive);
-        writer.Write(meido.HairGravityControl.Control.transform.localPosition);
+            writer.Write(poseBuffer.Length);
+            writer.Write(poseBuffer);
 
 
-        writer.Write(meido.SkirtGravityActive);
-        writer.Write(meido.SkirtGravityControl.Control.transform.localPosition);
-    }
+            PoseInfoSerializer.Serialize(meido.CachedPose, writer);
 
 
-    private static void DeserializeHead(Meido meido, BinaryReader reader, SceneMetadata metadata)
-    {
-        var body = meido.Body;
+            // TODO: Think about how to indicate code for new versions of serialization.
+            #region v2
+            // sub mune rotation
+            var body = meido.Body;
 
 
-        _ = reader.ReadVersion();
+            writer.WriteQuaternion(body.GetBone("Mune_L_sub").localRotation);
+            writer.WriteQuaternion(body.GetBone("Mune_R_sub").localRotation);
+            #endregion
+        }
 
 
-        var mmConverted = metadata.MMConverted;
+        static void SerializeClothing(Meido meido, BinaryWriter writer)
+        {
+            var maid = meido.Maid;
+            var body = meido.Body;
 
 
-        var eyeRotationL = reader.ReadQuaternion();
-        var eyeRotationR = reader.ReadQuaternion();
+            writer.WriteVersion(clothingVersion);
 
 
-        if (!mmConverted)
-        {
-            eyeRotationL *= meido.DefaultEyeRotL;
-            eyeRotationR *= meido.DefaultEyeRotR;
-        }
+            // body visible
+            writer.Write(body.GetMask(TBody.SlotID.body));
 
 
-        body.quaDefEyeL = eyeRotationL;
-        body.quaDefEyeR = eyeRotationR;
+            // clothing
+            foreach (var clothingSlot in MaidDressingPane.ClothingSlots)
+            {
+                var value = true;
+
+                if (clothingSlot is TBody.SlotID.wear)
+                {
+                    if (MaidDressingPane.WearSlots.Any(slot => body.GetSlotLoaded(slot)))
+                        value = MaidDressingPane.WearSlots.Any(slot => body.GetMask(slot));
+                }
+                else if (clothingSlot is TBody.SlotID.megane)
+                {
+                    var slots = new[] { TBody.SlotID.megane, TBody.SlotID.accHead };
+
+                    if (slots.Any(slot => body.GetSlotLoaded(slot)))
+                        value = slots.Any(slot => body.GetMask(slot));
+                }
+                else if (body.GetSlotLoaded(clothingSlot))
+                    value = body.GetMask(clothingSlot);
+
+                writer.Write(value);
+            }
 
 
-        var freeLook = meido.FreeLook = reader.ReadBoolean();
-        var offsetLookTarget = reader.ReadVector3();
-        var headEulerAngle = reader.ReadVector3();
+            // zurashi and mekure
+            writer.Write(meido.CurlingFront);
+            writer.Write(meido.CurlingBack);
+            writer.Write(meido.PantsuShift);
 
 
-        if (freeLook)
-            body.offsetLookTarget = offsetLookTarget;
+            // mpn attach props
+            var hasKousokuUpper = body.GetSlotLoaded(TBody.SlotID.kousoku_upper);
 
 
-        if (!metadata.MMConverted)
-        {
-            Utility.SetFieldValue(body, "HeadEulerAngleG", Vector3.zero);
-            Utility.SetFieldValue(body, "HeadEulerAngle", headEulerAngle);
-        }
+            writer.Write(hasKousokuUpper);
+            writer.Write(maid.GetProp(MPN.kousoku_upper).strTempFileName);
 
 
-        meido.HeadToCam = reader.ReadBoolean();
-        meido.EyeToCam = reader.ReadBoolean();
+            var hasKousokuLower = body.GetSlotLoaded(TBody.SlotID.kousoku_lower);
 
 
-        var faceBlendCount = reader.ReadInt32();
+            writer.Write(hasKousokuLower);
+            writer.Write(maid.GetProp(MPN.kousoku_lower).strTempFileName);
 
 
-        for (var i = 0; i < faceBlendCount; i++)
-        {
-            var hash = reader.ReadString();
-            var value = reader.ReadSingle();
+            // hair/skirt gravity
+            writer.Write(meido.HairGravityActive);
+            writer.Write(meido.HairGravityControl.Control.transform.localPosition);
 
 
-            meido.SetFaceBlendValue(hash, value);
+            writer.Write(meido.SkirtGravityActive);
+            writer.Write(meido.SkirtGravityControl.Control.transform.localPosition);
         }
         }
     }
     }
 
 
-    private static void DeserializeBody(Meido meido, BinaryReader reader, SceneMetadata metadata)
+    public override void Deserialize(Meido meido, BinaryReader reader, SceneMetadata metadata)
     {
     {
-        var version = reader.ReadVersion();
+        var maid = meido.Maid;
 
 
-        var muneSetting = new KeyValuePair<bool, bool>(true, true);
+        maid.GetAnimation().Stop();
+        meido.DetachAllMpnAttach();
+        meido.StopBlink();
 
 
-        if (metadata.MMConverted)
-            meido.IKManager.Deserialize(reader);
-        else
-        {
-            var poseBufferLength = reader.ReadInt32();
-            var poseBuffer = reader.ReadBytes(poseBufferLength);
+        reader.ReadInt64(); // data length
 
 
-            muneSetting = meido.SetFrameBinary(poseBuffer);
-        }
+        _ = reader.ReadVersion();
 
 
-        var poseInfo = PoseInfoSerializer.Deserialize(reader, metadata);
+        var transformDto = TransformDtoSerializer.Deserialize(reader, metadata);
+        var maidTransform = maid.transform;
 
 
-        Utility.SetPropertyValue(meido, nameof(Meido.CachedPose), poseInfo);
+        // TODO: use transform.SetRotationAndPosition
+        maidTransform.position = transformDto.Position;
+        maidTransform.rotation = transformDto.Rotation;
+        maidTransform.localScale = transformDto.LocalScale;
+
+        meido.IKManager.SetDragPointScale(maidTransform.localScale.x);
 
 
-        meido.SetMune(!muneSetting.Key, true);
-        meido.SetMune(!muneSetting.Value);
+        DeserializeHead(meido, reader, metadata);
 
 
-        if (version < 2)
-            return;
+        DeserializeBody(meido, reader, metadata);
 
 
-        var muneLSubRotation = reader.ReadQuaternion();
-        var muneSubRRotation = reader.ReadQuaternion();
+        DeserializeClothing(meido, reader, metadata);
 
 
-        var body = meido.Body;
+        static void DeserializeHead(Meido meido, BinaryReader reader, SceneMetadata metadata)
+        {
+            var body = meido.Body;
 
 
-        if (muneSetting.Key)
-            body.GetBone("Mune_L_sub").localRotation = muneLSubRotation;
+            _ = reader.ReadVersion();
 
 
-        if (muneSetting.Value)
-            body.GetBone("Mune_R_sub").localRotation = muneSubRRotation;
-    }
+            var mmConverted = metadata.MMConverted;
 
 
-    private static void DeserializeClothing(Meido meido, BinaryReader reader, SceneMetadata metadata)
-    {
-        var body = meido.Body;
+            var eyeRotationL = reader.ReadQuaternion();
+            var eyeRotationR = reader.ReadQuaternion();
 
 
-        _ = reader.ReadVersion();
+            if (!mmConverted)
+            {
+                eyeRotationL *= meido.DefaultEyeRotL;
+                eyeRotationR *= meido.DefaultEyeRotR;
+            }
 
 
-        meido.SetBodyMask(reader.ReadBoolean());
+            body.quaDefEyeL = eyeRotationL;
+            body.quaDefEyeR = eyeRotationR;
 
 
-        foreach (var clothingSlot in MaidDressingPane.ClothingSlots)
-        {
-            var value = reader.ReadBoolean();
+            var freeLook = meido.FreeLook = reader.ReadBoolean();
+            var offsetLookTarget = reader.ReadVector3();
+            var headEulerAngle = reader.ReadVector3();
 
 
-            if (metadata.MMConverted)
-                continue;
+            if (freeLook)
+                body.offsetLookTarget = offsetLookTarget;
 
 
-            if (clothingSlot is TBody.SlotID.wear)
+            if (!metadata.MMConverted)
             {
             {
-                body.SetMask(TBody.SlotID.wear, value);
-                body.SetMask(TBody.SlotID.mizugi, value);
-                body.SetMask(TBody.SlotID.onepiece, value);
+                Utility.SetFieldValue(body, "HeadEulerAngleG", Vector3.zero);
+                Utility.SetFieldValue(body, "HeadEulerAngle", headEulerAngle);
             }
             }
-            else if (clothingSlot is TBody.SlotID.megane)
+
+            meido.HeadToCam = reader.ReadBoolean();
+            meido.EyeToCam = reader.ReadBoolean();
+
+            var faceBlendCount = reader.ReadInt32();
+
+            for (var i = 0; i < faceBlendCount; i++)
             {
             {
-                body.SetMask(TBody.SlotID.megane, value);
-                body.SetMask(TBody.SlotID.accHead, value);
+                var hash = reader.ReadString();
+                var value = reader.ReadSingle();
+
+                meido.SetFaceBlendValue(hash, value);
             }
             }
-            else if (body.GetSlotLoaded(clothingSlot))
-                body.SetMask(clothingSlot, value);
         }
         }
 
 
-        // zurashi and mekure
-        var curlingFront = reader.ReadBoolean();
-        var curlingBack = reader.ReadBoolean();
-        var curlingPantsu = reader.ReadBoolean();
-
-        if (!metadata.MMConverted)
+        static void DeserializeBody(Meido meido, BinaryReader reader, SceneMetadata metadata)
         {
         {
-            if (meido.CurlingFront != curlingFront)
-                meido.SetCurling(Meido.Curl.Front, curlingFront);
-
-            if (meido.CurlingBack != curlingBack)
-                meido.SetCurling(Meido.Curl.Back, curlingBack);
+            var version = reader.ReadVersion();
 
 
-            meido.SetCurling(Meido.Curl.Shift, curlingPantsu);
-        }
+            var muneSetting = new KeyValuePair<bool, bool>(true, true);
 
 
-        // MPN attach upper prop
-        var hasKousokuUpper = reader.ReadBoolean();
-        var upperMenuFile = reader.ReadString();
+            if (metadata.MMConverted)
+                meido.IKManager.Deserialize(reader);
+            else
+            {
+                var poseBufferLength = reader.ReadInt32();
+                var poseBuffer = reader.ReadBytes(poseBufferLength);
 
 
-        if (hasKousokuUpper)
-            meido.SetMpnProp(new MpnAttachProp(MPN.kousoku_upper, upperMenuFile), false);
+                muneSetting = meido.SetFrameBinary(poseBuffer);
+            }
 
 
-        // MPN attach lower prop
-        var hasKousokuLower = reader.ReadBoolean();
-        var lowerMenuFile = reader.ReadString();
+            var poseInfo = PoseInfoSerializer.Deserialize(reader, metadata);
 
 
-        if (hasKousokuLower)
-            meido.SetMpnProp(new MpnAttachProp(MPN.kousoku_lower, lowerMenuFile), false);
+            Utility.SetPropertyValue(meido, nameof(Meido.CachedPose), poseInfo);
 
 
-        // hair gravity
-        var hairGravityActive = reader.ReadBoolean();
-        var hairPosition = reader.ReadVector3();
+            meido.SetMune(!muneSetting.Key, true);
+            meido.SetMune(!muneSetting.Value);
 
 
-        meido.HairGravityActive = hairGravityActive;
+            if (version < 2)
+                return;
 
 
-        if (meido.HairGravityActive)
-            meido.ApplyGravity(hairPosition);
+            var muneLSubRotation = reader.ReadQuaternion();
+            var muneSubRRotation = reader.ReadQuaternion();
 
 
-        // skirt gravity
-        var skirtGravityActive = reader.ReadBoolean();
-        var skirtPosition = reader.ReadVector3();
+            var body = meido.Body;
 
 
-        meido.SkirtGravityActive = skirtGravityActive;
+            if (muneSetting.Key)
+                body.GetBone("Mune_L_sub").localRotation = muneLSubRotation;
 
 
-        if (meido.SkirtGravityActive)
-            meido.ApplyGravity(skirtPosition, true);
-    }
+            if (muneSetting.Value)
+                body.GetBone("Mune_R_sub").localRotation = muneSubRRotation;
+        }
 
 
-    public override void Serialize(Meido meido, BinaryWriter writer)
-    {
-        var maid = meido.Maid;
+        static void DeserializeClothing(Meido meido, BinaryReader reader, SceneMetadata metadata)
+        {
+            var body = meido.Body;
 
 
-        using var memoryStream = new MemoryStream();
-        using var tempWriter = new BinaryWriter(memoryStream, Encoding.UTF8);
+            _ = reader.ReadVersion();
 
 
-        tempWriter.WriteVersion(version);
+            meido.SetBodyMask(reader.ReadBoolean());
 
 
-        TransformDtoSerializer.Serialize(new TransformDTO(maid.transform), tempWriter);
+            foreach (var clothingSlot in MaidDressingPane.ClothingSlots)
+            {
+                var value = reader.ReadBoolean();
+
+                if (metadata.MMConverted)
+                    continue;
+
+                if (clothingSlot is TBody.SlotID.wear)
+                {
+                    body.SetMask(TBody.SlotID.wear, value);
+                    body.SetMask(TBody.SlotID.mizugi, value);
+                    body.SetMask(TBody.SlotID.onepiece, value);
+                }
+                else if (clothingSlot is TBody.SlotID.megane)
+                {
+                    body.SetMask(TBody.SlotID.megane, value);
+                    body.SetMask(TBody.SlotID.accHead, value);
+                }
+                else if (body.GetSlotLoaded(clothingSlot))
+                    body.SetMask(clothingSlot, value);
+            }
 
 
-        SerializeHead(meido, tempWriter);
+            // zurashi and mekure
+            var curlingFront = reader.ReadBoolean();
+            var curlingBack = reader.ReadBoolean();
+            var curlingPantsu = reader.ReadBoolean();
 
 
-        SerializeBody(meido, tempWriter);
+            if (!metadata.MMConverted)
+            {
+                if (meido.CurlingFront != curlingFront)
+                    meido.SetCurling(Meido.Curl.Front, curlingFront);
 
 
-        SerializeClothing(meido, tempWriter);
+                if (meido.CurlingBack != curlingBack)
+                    meido.SetCurling(Meido.Curl.Back, curlingBack);
 
 
-        writer.Write(memoryStream.Length);
-        writer.Write(memoryStream.ToArray());
-    }
+                meido.SetCurling(Meido.Curl.Shift, curlingPantsu);
+            }
 
 
-    public override void Deserialize(Meido meido, BinaryReader reader, SceneMetadata metadata)
-    {
-        var maid = meido.Maid;
+            // MPN attach upper prop
+            var hasKousokuUpper = reader.ReadBoolean();
+            var upperMenuFile = reader.ReadString();
 
 
-        maid.GetAnimation().Stop();
-        meido.DetachAllMpnAttach();
-        meido.StopBlink();
+            if (hasKousokuUpper)
+                meido.SetMpnProp(new MpnAttachProp(MPN.kousoku_upper, upperMenuFile), false);
 
 
-        reader.ReadInt64(); // data length
+            // MPN attach lower prop
+            var hasKousokuLower = reader.ReadBoolean();
+            var lowerMenuFile = reader.ReadString();
 
 
-        _ = reader.ReadVersion();
+            if (hasKousokuLower)
+                meido.SetMpnProp(new MpnAttachProp(MPN.kousoku_lower, lowerMenuFile), false);
 
 
-        var transformDto = TransformDtoSerializer.Deserialize(reader, metadata);
-        var maidTransform = maid.transform;
+            // hair gravity
+            var hairGravityActive = reader.ReadBoolean();
+            var hairPosition = reader.ReadVector3();
 
 
-        // TODO: use transform.SetRotationAndPosition
-        maidTransform.position = transformDto.Position;
-        maidTransform.rotation = transformDto.Rotation;
-        maidTransform.localScale = transformDto.LocalScale;
+            meido.HairGravityActive = hairGravityActive;
 
 
-        meido.IKManager.SetDragPointScale(maidTransform.localScale.x);
+            if (meido.HairGravityActive)
+                meido.ApplyGravity(hairPosition);
 
 
-        DeserializeHead(meido, reader, metadata);
+            // skirt gravity
+            var skirtGravityActive = reader.ReadBoolean();
+            var skirtPosition = reader.ReadVector3();
 
 
-        DeserializeBody(meido, reader, metadata);
+            meido.SkirtGravityActive = skirtGravityActive;
 
 
-        DeserializeClothing(meido, reader, metadata);
+            if (meido.SkirtGravityActive)
+                meido.ApplyGravity(skirtPosition, true);
+        }
     }
     }
 }
 }

+ 1 - 0
src/MeidoPhotoStudio.Plugin/Serialization/SimpleSerializers/DragPointPropDTOSerializer.cs

@@ -42,6 +42,7 @@ public class DragPointPropDTOSerializer : SimpleSerializer<DragPointPropDTO>
     }
     }
 }
 }
 
 
+// TODO: Extract other classes to another file
 public class DragPointPropDTO
 public class DragPointPropDTO
 {
 {
     public TransformDTO TransformDTO { get; set; }
     public TransformDTO TransformDTO { get; set; }

+ 2 - 2
src/MeidoPhotoStudio.Plugin/Translation.cs

@@ -15,12 +15,12 @@ public static class Translation
     private static readonly ConfigEntry<string> currentLanguage;
     private static readonly ConfigEntry<string> currentLanguage;
     private static readonly ConfigEntry<bool> suppressWarnings;
     private static readonly ConfigEntry<bool> suppressWarnings;
 
 
+    public static event EventHandler ReloadTranslationEvent;
+
     private static Dictionary<string, Dictionary<string, string>> Translations;
     private static Dictionary<string, Dictionary<string, string>> Translations;
     private static bool forceSuppressWarnings;
     private static bool forceSuppressWarnings;
     private static bool suppressWarningsCached;
     private static bool suppressWarningsCached;
 
 
-    public static event EventHandler ReloadTranslationEvent;
-
     public static bool SuppressWarnings
     public static bool SuppressWarnings
     {
     {
         get => suppressWarningsCached;
         get => suppressWarningsCached;

+ 32 - 32
src/MeidoPhotoStudio.Plugin/Utility.cs

@@ -19,12 +19,6 @@ public static class Utility
     public static readonly BepInEx.Logging.ManualLogSource Logger =
     public static readonly BepInEx.Logging.ManualLogSource Logger =
         BepInEx.Logging.Logger.CreateLogSource(MeidoPhotoStudio.pluginName);
         BepInEx.Logging.Logger.CreateLogSource(MeidoPhotoStudio.pluginName);
 
 
-    public static string Timestamp =>
-        $"{DateTime.Now:yyyyMMddHHmmss}";
-
-    public static Vector3 MousePosition =>
-        mousePosition.Position;
-
     internal static readonly byte[] pngHeader = { 137, 80, 78, 71, 13, 10, 26, 10 };
     internal static readonly byte[] pngHeader = { 137, 80, 78, 71, 13, 10, 26, 10 };
     internal static readonly byte[] pngEnd = System.Text.Encoding.ASCII.GetBytes("IEND");
     internal static readonly byte[] pngEnd = System.Text.Encoding.ASCII.GetBytes("IEND");
     internal static readonly Regex guidRegEx =
     internal static readonly Regex guidRegEx =
@@ -32,6 +26,12 @@ public static class Utility
     internal static readonly GameObject mousePositionGo;
     internal static readonly GameObject mousePositionGo;
     internal static readonly MousePosition mousePosition;
     internal static readonly MousePosition mousePosition;
 
 
+    public static string Timestamp =>
+        $"{DateTime.Now:yyyyMMddHHmmss}";
+
+    public static Vector3 MousePosition =>
+        mousePosition.Position;
+
     static Utility()
     static Utility()
     {
     {
         mousePositionGo = new();
         mousePositionGo = new();
@@ -255,32 +255,6 @@ public static class Utility
         File.WriteAllBytes(Path.Combine(Constants.configPath, name), data);
         File.WriteAllBytes(Path.Combine(Constants.configPath, name), data);
 }
 }
 
 
-public class MousePosition : MonoBehaviour
-{
-    public Vector3 Position =>
-        mousePosition;
-
-    private Vector3 mousePosition;
-
-    private void Awake()
-    {
-        DontDestroyOnLoad(this);
-
-        mousePosition = Input.mousePosition;
-    }
-
-    private void Update()
-    {
-        if (Input.GetMouseButton(0))
-        {
-            mousePosition.x += Input.GetAxis("Mouse X") * 20;
-            mousePosition.y += Input.GetAxis("Mouse Y") * 20;
-        }
-        else
-            mousePosition = Input.mousePosition;
-    }
-}
-
 public static class KeyValuePairExtensions
 public static class KeyValuePairExtensions
 {
 {
     public static void Deconstruct<TKey, TValue>(this KeyValuePair<TKey, TValue> kvp, out TKey key, out TValue value)
     public static void Deconstruct<TKey, TValue>(this KeyValuePair<TKey, TValue> kvp, out TKey key, out TValue value)
@@ -447,3 +421,29 @@ public static class BinaryExtensions
         return matrix;
         return matrix;
     }
     }
 }
 }
+
+public class MousePosition : MonoBehaviour
+{
+    private Vector3 mousePosition;
+
+    public Vector3 Position =>
+        mousePosition;
+
+    private void Awake()
+    {
+        DontDestroyOnLoad(this);
+
+        mousePosition = Input.mousePosition;
+    }
+
+    private void Update()
+    {
+        if (Input.GetMouseButton(0))
+        {
+            mousePosition.x += Input.GetAxis("Mouse X") * 20;
+            mousePosition.y += Input.GetAxis("Mouse Y") * 20;
+        }
+        else
+            mousePosition = Input.mousePosition;
+    }
+}