Sfoglia il codice sorgente

Update save manager

habeebweeb 4 anni fa
parent
commit
1d5b42b2c2

+ 238 - 195
MultipleMaids/CM3D2/MultipleMaids/Plugin/MultipleMaids.Gui.cs

@@ -13,8 +13,6 @@ namespace CM3D2.MultipleMaids.Plugin
 {
     public partial class MultipleMaids
     {
-        const int DRAG_BAR_HEIGHT = 5;
-
         public void OnGUI()
         {
             for (int index1 = 0; index1 < maidCnt; ++index1)
@@ -75,6 +73,12 @@ namespace CM3D2.MultipleMaids.Plugin
 
                 saveManagerRect.x = (float)(Screen.width * 0.5f - saveManagerRect.width * 0.5f);
                 saveManagerRect.y = (float)(Screen.height * 0.5f - saveManagerRect.height * 0.5f);
+
+                saveModalRect.width = Mathf.Min(Screen.width * 0.35f, 480f);
+                saveModalRect.height = Mathf.Min(Screen.height * 0.45f, 360f);
+
+                saveModalRect.x = (float)(Screen.width * 0.5f - saveModalRect.width * 0.5f);
+                saveModalRect.y = (float)(Screen.height * 0.5f - saveModalRect.height * 0.5f);
             }
 
             if (bGuiMessage)
@@ -112,7 +116,7 @@ namespace CM3D2.MultipleMaids.Plugin
                 doguCombo.height = rectWin.height;
                 parCombo.height = rectWin.height;
                 lightCombo.height = rectWin.height;
-                GameMain.Instance.MainCamera.SetControl(true);
+
                 if (!sceneFlg && !faceFlg && !poseFlg && !kankyoFlg && !kankyo2Flg && !isF6 && okFlg)
                 {
                     if (Input.mouseScrollDelta.y != 0f)
@@ -128,109 +132,22 @@ namespace CM3D2.MultipleMaids.Plugin
                 }
                 else if (sceneFlg)
                 {
-                    rectWin = GUI.Window(129, rectWin, SaveSceneWindow, "", style);
+                    if (manageSave)
+                    {
+                        saveModalRect = GUI.ModalWindow(9999, saveModalRect, SaveManagerModal, "", style);
+                    }
 
                     saveManagerRect = GUI.Window(131, saveManagerRect, SaveManagerWindow, "", style);
 
                     if (Input.mouseScrollDelta.y != 0f)
                     {
-                        if (saveManagerRect.Contains(Event.current.mousePosition))
+                        if (saveManagerRect.Contains(Event.current.mousePosition)
+                            || (manageSave && saveModalRect.Contains(Event.current.mousePosition)))
                         {
                             GameMain.Instance.MainCamera.SetControl(false);
                             Input.ResetInputAxes();
                         }
                     }
-
-                    if (!saveManagerInitialize) InitializeSaveManager();
-
-                    Rect rect = default;
-                    dispNo = 0;
-                    for (int index = 0; index < 10; ++index)
-                    {
-                        rect = new Rect(0.0f, 0.0f, GetPix(170), GetPix(36));
-                        rect.x = rectWin.x;
-                        rect.y = rectWin.y + GetPix(64 + 50 * index);
-                        if (rect.Contains(Event.current.mousePosition))
-                        {
-                            dispNo = index + 1;
-                            break;
-                        }
-                    }
-
-                    if (saveScene2 > 0)
-                    {
-                        dispNo = 0;
-                    }
-
-                    if (dispNo == 0)
-                    {
-                        texture2D = null;
-                        dispNoOld = 0;
-                    }
-                    else if (dispNo != dispNoOld)
-                    {
-                        dispNoOld = dispNo;
-                        texture2D = null;
-                        try
-                        {
-                            IniKey iniKey = Preferences["scene"]["ss" + (page * 10 + dispNo)];
-                            if (iniKey.Value != null && iniKey.Value != "")
-                            {
-                                byte[] data = Convert.FromBase64String(iniKey.Value);
-                                texture2D = new Texture2D(1, 1, TextureFormat.ARGB32, false);
-                                texture2D.LoadImage(data);
-                            }
-                        }
-                        catch { }
-                    }
-
-                    if (texture2D != null)
-                    {
-                        if (waku == null)
-                        {
-                            waku = MakeTex(2, 2, new Color(1f, 1f, 1f, 1f));
-                            waku2 = MakeTex(2, 2, new Color(0.0f, 0.0f, 0.0f, 0.4f));
-                        }
-
-                        Rect position1 = new Rect(rect.x - texture2D.width - GetPix(18),
-                                                  rect.y - texture2D.height / 2 + GetPix(12),
-                                                   texture2D.width + GetPix(12),
-                                                   texture2D.height + GetPix(12));
-                        Rect position2 = new Rect(rect.x - texture2D.width - GetPix(12),
-                                                  rect.y - texture2D.height / 2 + GetPix(18),
-                                                   texture2D.width,
-                                                   texture2D.height);
-                        Rect position3 = new Rect(rect.x - texture2D.width - GetPix(16),
-                                                  rect.y - texture2D.height / 2 + GetPix(14),
-                                                   texture2D.width + GetPix(12),
-                                                   texture2D.height + GetPix(12));
-                        if (position1.y + (double)position1.height > Screen.height)
-                        {
-                            float num = position3.y + position3.height - Screen.height;
-                            position1.y -= num;
-                            position2.y -= num;
-                            position3.y -= num;
-                        }
-
-                        if (position1.y < 0)
-                        {
-                            position3.y -= position1.y;
-                            position2.y -= position1.y;
-                            position1.y -= position1.y;
-                        }
-
-                        if (rect.x + rect.width / 2 <= Screen.width / 2)
-                        {
-                            float offset = texture2D.width + rect.width + GetPix(24);
-                            position1.x += offset;
-                            position2.x += offset;
-                            position3.x += offset;
-                        }
-
-                        GUI.DrawTexture(position3, waku2);
-                        GUI.DrawTexture(position1, waku);
-                        GUI.DrawTexture(position2, texture2D);
-                    }
                 }
                 else if (kankyoFlg)
                 {
@@ -319,6 +236,8 @@ namespace CM3D2.MultipleMaids.Plugin
 
                     rectWin = GUI.Window(129, rectWin, FaceWindow, "", style);
                 }
+
+                GameMain.Instance.MainCamera.SetControl(true);
             }
         }
 
@@ -1445,6 +1364,9 @@ namespace CM3D2.MultipleMaids.Plugin
                     kankyoFlg = false;
                     kankyo2Flg = false;
                     bGui = true;
+
+                    if (!saveManagerInitialize) InitializeSaveManager();
+
                     for (int i = 0; i < 10; i++)
                     {
                         date[i] = "未保存";
@@ -9167,11 +9089,11 @@ namespace CM3D2.MultipleMaids.Plugin
         private void SaveManagerWindow(int winID)
         {
             GUIStyle labelStyle = new GUIStyle("label");
-            labelStyle.fontSize = GetPix(12);
+            labelStyle.fontSize = GetPix(13);
             labelStyle.alignment = TextAnchor.MiddleCenter;
             GUIStyle newSaveStyle = new GUIStyle("button");
-            newSaveStyle.fontSize = GetPix(50);
             newSaveStyle.alignment = TextAnchor.MiddleCenter;
+            newSaveStyle.fontSize = GetPix(90);
             GUIStyle saveImageStyle = new GUIStyle("label");
             saveImageStyle.fontSize = GetPix(12);
             saveImageStyle.alignment = TextAnchor.MiddleCenter;
@@ -9179,16 +9101,27 @@ namespace CM3D2.MultipleMaids.Plugin
             GUIStyle saveControlStyle = new GUIStyle("button");
             saveControlStyle.fontSize = GetPix(12);
             saveControlStyle.alignment = TextAnchor.MiddleCenter;
+            GUIStyle listStyle = new GUIStyle("button");
+            listStyle.fontSize = GetPix(14);
+            listStyle.alignment = TextAnchor.MiddleLeft;
+            GUIStyle textFieldStyle = new GUIStyle("textfield");
+            textFieldStyle.alignment = TextAnchor.MiddleLeft;
 
             // Window variables
-            float windowPadding = GetPix(10);
-            float windowPaddingY = GetPix(20);
+            int windowPadding = GetPix(10);
+            int windowPaddingY = GetPix(20);
+            int buttonSize = GetPix(25);
+
+            if (createSaveFlag || loadSaveFlag || manageSave)
+            {
+                GUI.enabled = false;
+            }
 
             if (GUI.Button(new Rect(
+                saveManagerRect.width - windowPadding - buttonSize,
                 windowPadding,
-                windowPadding,
-                GetPix(25),
-                GetPix(25)
+                buttonSize,
+                buttonSize
             ), "X", saveControlStyle))
             {
                 faceFlg = false;
@@ -9201,38 +9134,121 @@ namespace CM3D2.MultipleMaids.Plugin
             }
 
             if (GUI.Button(new Rect(
-                windowPaddingY + GetPix(25),
+                windowPadding,
                 windowPadding,
                 GetPix(65),
-                GetPix(25)
+                buttonSize
             ), "Refresh", saveControlStyle))
             {
-                InitializeSaveList();
+                RefreshSaveManager();
             }
 
-            if (createSaveFlag || loadSaveFlag)
+            int saveGridOffset = GetPix(200);
+            int saveGridX = windowPaddingY + saveGridOffset;
+            int saveGridY = windowPaddingY + buttonSize;
+            float saveGridWidth = saveManagerRect.width - saveGridX - windowPadding;
+            float saveGridHeight = saveManagerRect.height - saveGridY;
+
+            int numImages = saveScenes.Count;
+
+            #region Directory List
+
+            Rect dirListScrollRect = new Rect(
+                windowPadding,
+                windowPaddingY + buttonSize,
+                saveGridOffset,
+                saveGridHeight - windowPaddingY - buttonSize
+            );
+
+            Rect dirListScrollView = new Rect(0, 0,
+                saveGridOffset - 50,
+                GetPix(22) * directoryList.Length
+            );
+
+            GUI.Box(dirListScrollRect, "");
+
+            dirListScrollPos = GUI.BeginScrollView(dirListScrollRect, dirListScrollPos, dirListScrollView);
+
+            for (int i = 0; i < directoryList.Length; i++)
             {
-                GUI.enabled = false;
+                int listEntrySize = GetPix(30);
+                if (GUI.Button(new Rect(0,
+                    i * listEntrySize,
+                    saveGridOffset,
+                    listEntrySize), directoryList[i], listStyle))
+                {
+                    SwitchDirectory(directoryList[i]);
+                }
             }
 
-            #region SAVE_GRID
+            GUI.EndScrollView();
 
-            float saveGridX = windowPadding + Mathf.Max(480, GetPix(480)) + windowPadding;
-            float saveGridY = windowPaddingY;
-            float saveGridWidth = saveManagerRect.width - saveGridX - windowPadding;
-            float saveGridHeight = saveManagerRect.height - windowPaddingY;
+            if (!createDirectory)
+            {
+                if (GUI.Button(new Rect(
+                    windowPadding,
+                    saveGridHeight + windowPadding,
+                    saveGridOffset,
+                    buttonSize
+                ), "New Folder", saveControlStyle))
+                {
+                    createDirectory = true;
+                }
+            }
+            else
+            {
+                float textFieldWidth = saveGridOffset - buttonSize;
 
-            int numImages = saveScenes.Count;
+                Rect cancelRect = new Rect(
+                        textFieldWidth + windowPadding,
+                        saveGridHeight + windowPadding,
+                        buttonSize,
+                        buttonSize
+                    );
+
+                bool cancel = GUI.Button(cancelRect, "X", saveControlStyle); // || Event.current.Equals(Event.KeyboardEvent("escape"));
+
+                if (cancel)
+                {
+                    textFieldValue = "";
+                    createDirectory = false;
+                }
+                else if (Event.current.Equals(Event.KeyboardEvent("return")))
+                {
+                    MakeNewDirectory(textFieldValue);
+                    textFieldValue = "";
+                    createDirectory = false;
+                }
+                else
+                {
+                    textFieldValue = GUI.TextField(new Rect(
+                        windowPadding,
+                        saveGridHeight + windowPadding,
+                        textFieldWidth,
+                        buttonSize
+                    ), textFieldValue, 30, textFieldStyle);
+                }
+            }
+            #endregion
 
-            float scale = 0.5f;
-            float imageWidth = Mathf.Min(480f * scale, GetPix(480) * scale);
-            float imageHeight = Mathf.Min(270f * scale, GetPix(270) * scale);
-            float imagePadding = GetPix(12);
+            #region SAVE_GRID
+
+            GUI.Label(new Rect(
+                saveGridX,
+                windowPadding,
+                saveGridWidth,
+                GetPix(30)
+            ), directoryList[selectedDirectory], labelStyle);
+
+            float scale = 0.55f;
+            float imageWidth = 480f * scale;
+            float imageHeight = 270f * scale;
+            float imagePadding = GetPix(9);
 
             int maxColumns = Mathf.Max(1, (int)(saveGridWidth / (imageWidth + imagePadding)));
             float imageGridWidth = maxColumns * (imageWidth + imagePadding);
-            float imageGridX = saveGridX + (saveGridWidth / 2f - imageGridWidth / 2f) + windowPadding;
-            float imageGridOffset = (saveGridWidth - imageGridWidth) / 2f;
+            float imageGridX = saveGridX + (saveGridWidth / 2f - imageGridWidth / 2f) - windowPadding;
+            float imageGridOffset = (saveGridWidth - imageGridWidth) / 2f - windowPadding;
 
             Rect saveGridScrollRect = new Rect(
                 saveGridX + windowPadding
@@ -9242,8 +9258,8 @@ namespace CM3D2.MultipleMaids.Plugin
             );
 
             Rect saveGridScrollView = new Rect(0, 0
-                , saveGridWidth - 30
-                , (numImages / maxColumns + 1) * (imageHeight + imagePadding) + imagePadding
+                , saveGridWidth - 50
+                , (saveScenes.Count / maxColumns + 1) * (imageHeight + imagePadding) + imagePadding
             );
 
             GUI.Box(new Rect(
@@ -9265,26 +9281,26 @@ namespace CM3D2.MultipleMaids.Plugin
                 TakeScreenshot();
             }
 
-            int j = 1;
-            int i = numImages - 1;
-
-            while (i >= 0 && j <= numImages)
+            if (saveScenes.Count > 0)
             {
-                Texture2D saveImage = saveScenes[i]?.Item2 ?? null;
-                if (saveImage != null)
+                int j = 1;
+                int i = saveScenes.Count - 1;
+
+                while (i >= 0)
                 {
                     float imageX = (j % maxColumns) * imageWidth + (j % maxColumns) * imagePadding + imageGridOffset;
                     float imageY = (j / maxColumns) * imageHeight + (j / maxColumns + 1) * imagePadding;
 
-                    Rect buttonRect = new Rect(
+                    if (GUI.Button(new Rect(
                         imageX
                         , imageY
                         , imageWidth
-                        , imageHeight);
-                    if (GUI.Button(buttonRect, saveImage, saveImageStyle))
+                        , imageHeight), saveScenes[i].screenshot, saveImageStyle))
                     {
                         selectedSave = i;
+                        manageSave = true;
                     }
+
                     i--;
                     j++;
                 }
@@ -9293,90 +9309,117 @@ namespace CM3D2.MultipleMaids.Plugin
             GUI.EndScrollView();
             #endregion
 
-            #region SAVE_CONTROLS
-            if (numImages > 0)
+            if (createSaveFlag)
             {
-                Texture2D previewImage = saveScenes[selectedSave]?.Item2 ?? null;
-                if (previewImage != null)
+                if (File.Exists(thum_file_path_))
                 {
+                    if (overwriteFlag)
+                        Overwrite();
+                    SaveScene();
+                    createSaveFlag = false;
+                    overwriteFlag = false;
+                }
+            }
 
-                    float saveManagerX = windowPadding;
-                    float saveManagerY = windowPaddingY + GetPix(80);
+            GUI.DragWindow();
+        }
 
-                    int previewWidth = Mathf.Min(previewImage.width, GetPix(previewImage.width));
-                    int previewHeight = Mathf.Min(previewImage.height, GetPix(previewImage.height));
+        private void SaveManagerModal(int winID)
+        {
+            GUIStyle labelStyle = new GUIStyle("label");
+            labelStyle.fontSize = GetPix(13);
+            labelStyle.alignment = TextAnchor.MiddleCenter;
+            labelStyle.wordWrap = false;
+            GUIStyle saveControlStyle = new GUIStyle("button");
+            saveControlStyle.fontSize = GetPix(12);
+            saveControlStyle.alignment = TextAnchor.MiddleCenter;
 
-                    float previewX = saveManagerX + (saveGridX / 2 - previewWidth / 2);
-                    float previewY = saveManagerY;
+            Texture2D previewImage = saveScenes[selectedSave].screenshot;
 
-                    GUI.DrawTexture(new Rect(
-                        previewX - GetPix(6)
-                        , previewY - GetPix(6)
-                        , previewWidth + GetPix(12)
-                        , previewHeight + GetPix(12))
-                        , frame
-                    );
-                    GUI.DrawTexture(new Rect(
-                        previewX,
-                        previewY,
-                        previewWidth,
-                        previewHeight
-                    ), previewImage);
+            int windowPadding = GetPix(10);
+            int windowPaddingY = GetPix(20);
 
-                    int saveControlWidth = GetPix(70);
-                    int saveControlHeight = GetPix(30);
+            float previewWindowWidth = saveModalRect.width - windowPaddingY;
+            float previewWindowHeight = Mathf.Min(270 - windowPadding, saveModalRect.height - GetPix(70));
 
-                    float saveControlX = previewX + (previewWidth / 2) - (saveControlWidth / 2);
-                    float saveControlY = saveManagerY + previewHeight + windowPaddingY;
+            float scale = Mathf.Min(previewWindowWidth / previewImage.width, previewWindowHeight / previewImage.height);
+            float previewWidth = (previewImage.width * scale) - windowPaddingY;
+            float previewHeight = (previewImage.height * scale) - windowPaddingY;
 
-                    int saveControlSpacing = GetPix(90);
 
-                    if (GUI.Button(new Rect(
-                                saveControlX - saveControlSpacing
-                                , saveControlY
-                                , saveControlWidth
-                                , saveControlHeight)
-                                , "Overwrite", saveControlStyle))
-                    {
-                        saveManagerScrollPos.y = 0;
-                        createSaveFlag = true;
-                        overwriteFlag = true;
+            float previewX = (saveModalRect.width / 2 - previewWidth / 2);
+            float previewY = windowPaddingY;
 
-                        TakeScreenshot();
-                    }
+            GUI.DrawTexture(new Rect(
+                previewX - GetPix(6)
+                , previewY - GetPix(6)
+                , previewWidth + GetPix(12)
+                , previewHeight + GetPix(12))
+                , frame
+            );
 
-                    if (GUI.Button(new Rect(
-                        saveControlX + saveControlSpacing
-                        , saveControlY
-                        , saveControlWidth
-                        , saveControlHeight)
-                        , "Load", saveControlStyle))
-                    {
-                        loadSaveFlag = true;
-                        loadScene = 1;
-                    }
-                }
-            }
+            GUI.DrawTexture(new Rect(
+                previewX,
+                previewY,
+                previewWidth,
+                previewHeight
+            ), previewImage);
 
-            #endregion
+            string title = saveScenes[selectedSave].info.Name;
 
-            GUI.enabled = true;
+            float labelY = previewY + previewHeight + windowPadding;
+            int labelHeight = GetPix(20);
 
-            if (createSaveFlag)
+            GUI.Label(new Rect(
+                windowPadding,
+                labelY,
+                saveModalRect.width - windowPaddingY,
+                labelHeight
+            ), title, labelStyle);
+
+            int buttonHeight = GetPix(25);
+            int buttonWidth = GetPix(80);
+            float buttonY = saveModalRect.height - windowPadding - buttonHeight;
+
+
+            if (GUI.Button(new Rect(
+                windowPadding,
+                buttonY,
+                buttonWidth,
+                buttonHeight
+            ), "Overwrite", saveControlStyle))
             {
-                if (File.Exists(thum_file_path_))
-                {
-                    if (overwriteFlag)
-                        OverWrite();
-                    SaveScene();
-                    createSaveFlag = false;
-                    overwriteFlag = false;
-                }
+                manageSave = false;
+                createSaveFlag = true;
+                overwriteFlag = true;
+
+                TakeScreenshot();
+            }
+
+            if (GUI.Button(new Rect(
+                windowPaddingY + buttonWidth,
+                buttonY,
+                buttonWidth,
+                buttonHeight
+            ), "Load", saveControlStyle))
+            {
+                manageSave = false;
+                loadSaveFlag = true;
+                loadScene = 1;
+            }
+
+            if (GUI.Button(new Rect(
+                saveModalRect.width - buttonWidth - windowPadding,
+                buttonY,
+                buttonWidth,
+                buttonHeight
+            ), "Cancel", saveControlStyle))
+            {
+                manageSave = false;
             }
 
             GUI.DragWindow();
         }
-
         public void TakeScreenshot()
         {
             GameMain.Instance.SoundMgr.PlaySe("se002.ogg", false);

+ 118 - 31
MultipleMaids/SaveManager.cs

@@ -1,5 +1,6 @@
 using UnityEngine;
 using System;
+using System.Linq;
 using System.Collections.Generic;
 using System.Text;
 using System.IO;
@@ -10,18 +11,27 @@ namespace CM3D2.MultipleMaids.Plugin
     public partial class MultipleMaids
     {
         private static readonly byte[] pngEnd = Encoding.ASCII.GetBytes("IEND");
+        private static string sceneData;
+        private const string baseDirectoryName = "< Base Directory >";
+        private string saveScenePath = Path.Combine(Path.GetFullPath(".\\"), "Mod\\MultipleMaidsSave");
+        private List<SavePng> saveScenes = new List<SavePng>(50);
+        private string[] directoryList;
+        private Texture2D frame;
         private Rect saveManagerRect;
+        private Rect saveModalRect;
         private Vector2 saveManagerScrollPos = Vector2.zero;
-        private bool saveManagerInitialize;
-        private int selectedSave;
+        private Vector2 dirListScrollPos = Vector2.zero;
+        private bool saveManagerInitialize = false;
         private bool loadSaveFlag = false;
         private bool overwriteFlag = false;
         private bool createSaveFlag = false;
-        private string saveScenePath = Path.Combine(Path.GetFullPath(".\\"), "Mod\\MultipleMaidsSave");
-        private static string sceneData;
-        private List<Tuple<FileInfo, Texture2D>> saveScenes = new List<Tuple<FileInfo, Texture2D>>(50);
+        private bool manageSave = false;
+        private bool createDirectory = false;
+        private int selectedSave = 0;
+        private int selectedDirectory = 0;
+        private string currentDirectory = "";
+        private string textFieldValue = "";
 
-        private Texture2D frame;
 
         public void InitializeSaveManager()
         {
@@ -32,43 +42,78 @@ namespace CM3D2.MultipleMaids.Plugin
                 Directory.CreateDirectory(saveScenePath);
             }
 
+            GetSaveDirectories();
             InitializeSaveList();
             saveManagerInitialize = true;
         }
+        private void RefreshSaveManager()
+        {
+            SwitchDirectory(currentDirectory);
+            GetSaveDirectories();
+            InitializeSaveList();
+        }
 
         private void InitializeSaveList()
         {
             saveScenes.Clear();
 
-            DirectoryInfo info = new DirectoryInfo(saveScenePath);
+            string workingPath = Path.Combine(saveScenePath, currentDirectory);
+
+            DirectoryInfo info = new DirectoryInfo(workingPath);
 
             foreach (var save in info.GetFiles("*.png"))
             {
                 Texture2D screenshot = new Texture2D(1, 1, TextureFormat.ARGB32, false);
                 screenshot.LoadImage(File.ReadAllBytes(save.FullName));
 
-                saveScenes.Add(new Tuple<FileInfo, Texture2D>(save, screenshot));
+                saveScenes.Add(new SavePng(save, screenshot));
             }
 
-            saveScenes.Sort((a, b) => a.Item1.LastWriteTime.CompareTo(b.Item1.LastWriteTime));
+            selectedSave = saveScenes.Count == 0 ? 0 : saveScenes.Count - 1;
 
-            selectedSave = saveScenes.Count - 1;
+            saveScenes.Sort((a, b) => a.info.LastWriteTime.CompareTo(b.info.LastWriteTime));
+            saveManagerScrollPos.y = 0;
         }
 
-        private static bool BytesEqual(byte[] a, byte[] b)
+        private void GetSaveDirectories()
         {
-            if (a.Length != b.Length) return false;
+            DirectoryInfo[] directoryInfo = new DirectoryInfo(saveScenePath).GetDirectories();
+            directoryList = new string[directoryInfo.Length + 1];
+            directoryList[0] = baseDirectoryName;
 
-            for (int i = 0; i < a.Length; i++)
+            for (int i = 0; i < directoryInfo.Length; i++)
             {
-                if (a[i] != b[i]) return false;
+                directoryList[i + 1] = directoryInfo[i].Name;
             }
-            return true;
+        }
+
+        private void SwitchDirectory(string target)
+        {
+            if (target.Equals(baseDirectoryName)) target = "";
+
+            string targetDirectory = Path.Combine(saveScenePath, target);
+
+            if (!Directory.Exists(targetDirectory))
+            {
+                currentDirectory = "";
+                selectedDirectory = 0;
+                GetSaveDirectories();
+            }
+            else
+            {
+                selectedDirectory = Array.FindIndex(directoryList, d => d.Equals(target, StringComparison.OrdinalIgnoreCase));
+                selectedDirectory = selectedDirectory == -1 ? 0 : selectedDirectory;
+
+                if (target == currentDirectory) return;
+
+                currentDirectory = target;
+            }
+            InitializeSaveList();
         }
 
         private void LoadSave()
         {
-            string filePath = saveScenes[selectedSave].Item1.FullName;
+            string filePath = saveScenes[selectedSave].info.FullName;
             if (!File.Exists(filePath))
             {
                 InitializeSaveList();
@@ -87,6 +132,7 @@ namespace CM3D2.MultipleMaids.Plugin
 
                     if (bytesRead != pngEnd.Length)
                     {
+                        sceneData = null;
                         return;
                     }
 
@@ -103,23 +149,53 @@ namespace CM3D2.MultipleMaids.Plugin
                     sceneData = Encoding.Unicode.GetString(sceneStream.ToArray());
                 }
             }
+            SavePng temp = saveScenes[selectedSave];
+            saveScenes.RemoveAt(selectedSave);
+            saveScenes.Add(temp);
+            saveManagerScrollPos.y = 0;
         }
 
-        private void OverWrite()
+        private void Overwrite()
         {
-            string filePath = Path.Combine(saveScenePath, saveScenes[selectedSave].Item1.FullName);
-            if (File.Exists(filePath))
+            string filePath = saveScenes[selectedSave].info.FullName;
+            if (!File.Exists(filePath))
+            {
+                RefreshSaveManager();
+            }
+            else
             {
                 File.Delete(filePath);
+                saveScenes.RemoveAt(selectedSave);
+                saveManagerScrollPos.y = 0;
             }
-            saveScenes.RemoveAt(selectedSave);
+        }
+
+        private void MakeNewDirectory(string directoryName)
+        {
+            directoryName = string.Join("", directoryName.Split(Path.GetInvalidFileNameChars()));
+            string newDirectory = Path.Combine(saveScenePath, directoryName);
+            if (!Directory.Exists(newDirectory))
+            {
+                Directory.CreateDirectory(newDirectory);
+            }
+            GetSaveDirectories();
+            SwitchDirectory(directoryName);
         }
 
         private void SaveScene()
         {
-            string sceneString = SerializeScene(true);
+            string saveDirectory = Path.Combine(saveScenePath, currentDirectory);
 
-            thum_byte_to_base64_ = "";
+            if (!Directory.Exists(saveDirectory))
+            {
+
+                thum_byte_to_base64_ = "";
+                thum_file_path_ = "";
+                RefreshSaveManager();
+                return;
+            }
+
+            string sceneString = SerializeScene(true);
 
             #region MM GUI stuff
 
@@ -152,7 +228,10 @@ namespace CM3D2.MultipleMaids.Plugin
             TextureScale.Bilinear(screenshot, newWidth, newHeight);
             #endregion
 
-            string filePath = Path.Combine(saveScenePath, $"mmsave{DateTime.Now:yyyyMMddHHmmss}.png");
+            thum_byte_to_base64_ = "";
+            thum_file_path_ = "";
+
+            string filePath = Path.Combine(saveDirectory, $"mmsave{DateTime.Now:yyyyMMddHHmmss}.png");
             using (FileStream fileStream = File.Create(filePath))
             using (MemoryStream sceneStream = new MemoryStream(Encoding.Unicode.GetBytes(sceneString)))
             {
@@ -161,20 +240,28 @@ namespace CM3D2.MultipleMaids.Plugin
                 fileStream.Write(screenshotBuffer, 0, screenshotBuffer.Length);
                 fileStream.Write(sceneBuffer, 0, sceneBuffer.Length);
             }
-            saveScenes.Add(new Tuple<FileInfo, Texture2D>(new FileInfo(filePath), screenshot));
+            saveScenes.Add(new SavePng(new FileInfo(filePath), screenshot));
             selectedSave = saveScenes.Count - 1;
-            thum_file_path_ = "";
         }
 
-        private class Tuple<T1, T2>
+        private static bool BytesEqual(byte[] a, byte[] b)
         {
-            public T1 Item1 { get; }
-            public T2 Item2 { get; }
+            if (a.Length != b.Length) return false;
 
-            public Tuple(T1 Item1, T2 Item2)
+            for (int i = 0; i < a.Length; i++)
+            {
+                if (a[i] != b[i]) return false;
+            }
+            return true;
+        }
+        class SavePng
+        {
+            public FileInfo info { get; }
+            public Texture2D screenshot { get; }
+            public SavePng(FileInfo info, Texture2D screenshot)
             {
-                this.Item1 = Item1;
-                this.Item2 = Item2;
+                this.info = info;
+                this.screenshot = screenshot;
             }
         }
     }