Procházet zdrojové kódy

Refactor MeidoManager

- Removes the responsibility of keeping a list of meido to call from the
  MeidoManager.
- Reduce MeidoManager's reliance on Meido indices down to keeping only
  the original edit meido's index.

The change from indices to concrete Meido objects was done in order to
allow more freedom when building Meido lists. This is preparation for
adding support for x0 male dlc.
habeebweeb před 2 roky
rodič
revize
622be52f12

+ 40 - 8
src/MeidoPhotoStudio.Plugin/GUI/Panes/CallWindowPanes/MaidSelectorPane.cs

@@ -10,6 +10,8 @@ public class MaidSelectorPane : BasePane
     private readonly Button clearMaidsButton;
     private readonly Button callMaidsButton;
     private readonly Toggle activeMeidoListToggle;
+    private readonly List<Meido> selectedMeidoList = new();
+    private readonly HashSet<Meido> selectedMeidoSet = new();
 
     private Vector2 maidListScrollPos;
     private Vector2 activeMaidListScrollPos;
@@ -20,16 +22,16 @@ public class MaidSelectorPane : BasePane
 
         clearMaidsButton = new(Translation.Get("maidCallWindow", "clearButton"));
         clearMaidsButton.ControlEvent += (_, _) =>
-            this.meidoManager.ClearSelectList();
+            ClearSelectedMaids();
 
         callMaidsButton = new(Translation.Get("maidCallWindow", "callButton"));
         callMaidsButton.ControlEvent += (_, _) =>
-            this.meidoManager.CallMeidos();
+            this.meidoManager.CallMeidos(selectedMeidoList);
 
         activeMeidoListToggle = new(Translation.Get("maidCallWindow", "activeOnlyToggle"));
         this.meidoManager.BeginCallMeidos += (_, _) =>
         {
-            if (meidoManager.SelectedMeidoSet.Count is 0)
+            if (selectedMeidoSet.Count is 0)
                 activeMeidoListToggle.Value = false;
         };
     }
@@ -38,6 +40,8 @@ public class MaidSelectorPane : BasePane
     {
         base.Activate();
 
+        ClearSelectedMaids();
+
         // NOTE: Leaving this mode enabled pretty much softlocks meido selection so disable it on activation
         activeMeidoListToggle.Value = false;
     }
@@ -98,14 +102,14 @@ public class MaidSelectorPane : BasePane
         {
             var meido = meidoList[i];
             var y = i * buttonHeight;
-            var selectedMaid = meidoManager.SelectedMeidoSet.Contains(meido.StockNo);
+            var selected = selectedMeidoSet.Contains(meido);
 
             if (GUI.Button(new(0f, y, buttonWidth, buttonHeight), string.Empty))
-                meidoManager.SelectMeido(meido.StockNo);
+                SelectMaid(meido);
 
-            if (selectedMaid)
+            if (selected)
             {
-                var selectedIndex = meidoManager.SelectMeidoList.IndexOf(meido.StockNo) + 1;
+                var selectedIndex = selectedMeidoList.IndexOf(meido) + 1;
 
                 GUI.DrawTexture(new(5f, y + 5f, buttonWidth - 10f, buttonHeight - 10f), Texture2D.whiteTexture);
 
@@ -118,7 +122,7 @@ public class MaidSelectorPane : BasePane
             GUI.Label(
                 new(95f, y + 30f, buttonWidth - 80f, buttonHeight),
                 $"{meido.LastName}\n{meido.FirstName}",
-                selectedMaid ? labelSelectedStyle : labelStyle);
+                selected ? labelSelectedStyle : labelStyle);
         }
 
         GUI.EndScrollView();
@@ -130,4 +134,32 @@ public class MaidSelectorPane : BasePane
         callMaidsButton.Label = Translation.Get("maidCallWindow", "callButton");
         activeMeidoListToggle.Label = Translation.Get("maidCallWindow", "activeOnlyToggle");
     }
+
+    private void SelectMaid(Meido meido)
+    {
+        if (selectedMeidoSet.Contains(meido))
+        {
+            if (!MeidoPhotoStudio.EditMode || meido != meidoManager.OriginalEditingMeido)
+            {
+                selectedMeidoSet.Remove(meido);
+                selectedMeidoList.Remove(meido);
+            }
+        }
+        else
+        {
+            selectedMeidoSet.Add(meido);
+            selectedMeidoList.Add(meido);
+        }
+    }
+
+    private void ClearSelectedMaids()
+    {
+        selectedMeidoSet.Clear();
+        selectedMeidoList.Clear();
+
+        if (!MeidoPhotoStudio.EditMode)
+            return;
+
+        SelectMaid(meidoManager.OriginalEditingMeido);
+    }
 }

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

@@ -116,7 +116,7 @@ public class MaidSwitcherPane : BasePane
             return;
 
         updating = true;
-        editToggle.Value = meidoManager.ActiveMeido.IsEditMaid;
+        editToggle.Value = meidoManager.ActiveMeido == meidoManager.EditingMeido;
         updating = false;
     }
 
@@ -143,6 +143,6 @@ public class MaidSwitcherPane : BasePane
         }
 
         if (meidoManager.HasActiveMeido)
-            meidoManager.SetEditMaid(meidoManager.ActiveMeido);
+            meidoManager.EditingMeido = meidoManager.ActiveMeido;
     }
 }

+ 64 - 92
src/MeidoPhotoStudio.Plugin/Managers/MeidoManager.cs

@@ -11,14 +11,13 @@ public class MeidoManager : IManager
 {
     public const string Header = "MEIDO";
 
-    private static readonly CharacterMgr CharacterMgr = GameMain.Instance.CharacterMgr;
-
     private static bool active;
 
     private int selectedMeido;
     private bool globalGravity;
     private int undress;
-    private int tempEditMaidIndex = -1;
+    private Meido editingMeido;
+    private Meido temporaryEditingMeido;
 
     static MeidoManager() =>
         InputManager.Register(MpsKey.MeidoUndressing, KeyCode.H, "All maid undressing");
@@ -34,10 +33,6 @@ public class MeidoManager : IManager
 
     public Meido[] Meidos { get; private set; }
 
-    public HashSet<int> SelectedMeidoSet { get; } = new();
-
-    public List<int> SelectMeidoList { get; } = new();
-
     public List<Meido> ActiveMeidoList { get; } = new();
 
     public int SelectedMeido
@@ -52,8 +47,26 @@ public class MeidoManager : IManager
     public Meido ActiveMeido =>
         ActiveMeidoList.Count > 0 ? ActiveMeidoList[SelectedMeido] : null;
 
-    public Meido EditMeido =>
-        tempEditMaidIndex >= 0 ? Meidos[tempEditMaidIndex] : Meidos[EditMaidIndex];
+    public Meido EditingMeido
+    {
+        get => MeidoPhotoStudio.EditMode ? editingMeido : null;
+        set
+        {
+            if (!MeidoPhotoStudio.EditMode || value is null)
+                return;
+
+            editingMeido = value;
+            temporaryEditingMeido = editingMeido == OriginalEditingMeido ? null : editingMeido;
+
+            SetEditorMaid(editingMeido.Maid);
+        }
+    }
+
+    public Meido TemporaryEditingMeido =>
+        MeidoPhotoStudio.EditMode ? temporaryEditingMeido : null;
+
+    public Meido OriginalEditingMeido =>
+        MeidoPhotoStudio.EditMode && OriginalEditingMaidIndex >= 0 ? Meidos[OriginalEditingMaidIndex] : null;
 
     public bool HasActiveMeido =>
         ActiveMeido is not null;
@@ -82,28 +95,35 @@ public class MeidoManager : IManager
         }
     }
 
-    private static int EditMaidIndex { get; set; }
+    private static CharacterMgr CharacterMgr =>
+        GameMain.Instance.CharacterMgr;
+
+    private static int OriginalEditingMaidIndex { get; set; }
 
     public void ChangeMaid(int index) =>
         OnUpdateMeido(null, new(index));
 
     public void Activate()
     {
-        CharacterMgr.ResetCharaPosAll();
-
-        if (!MeidoPhotoStudio.EditMode)
-            CharacterMgr.DeactivateMaid(0);
-
         Meidos = CharacterMgr.GetStockMaidList()
             .Select((_, stockNo) => new Meido(stockNo))
             .ToArray();
 
-        tempEditMaidIndex = -1;
+        CharacterMgr.ResetCharaPosAll();
+
+        if (MeidoPhotoStudio.EditMode)
+        {
+            temporaryEditingMeido = null;
+            editingMeido = OriginalEditingMeido;
 
-        if (MeidoPhotoStudio.EditMode && EditMaidIndex >= 0)
-            Meidos[EditMaidIndex].IsEditMaid = true;
+            if (OriginalEditingMeido is not null)
+                CallMeidos(new List<Meido>() { OriginalEditingMeido });
+        }
+        else
+        {
+            CharacterMgr.DeactivateMaid(0);
+        }
 
-        ClearSelectList();
         active = true;
     }
 
@@ -120,7 +140,7 @@ public class MeidoManager : IManager
 
         if (MeidoPhotoStudio.EditMode && !GameMain.Instance.MainCamera.IsFadeOut())
         {
-            var meido = Meidos[EditMaidIndex];
+            var meido = OriginalEditingMeido;
 
             meido.Maid.Visible = true;
             meido.Stop = false;
@@ -138,71 +158,27 @@ public class MeidoManager : IManager
             UndressAll();
     }
 
-    public void CallMeidos()
+    public void CallMeidos(IList<Meido> meidoToCall)
     {
         BeginCallMeidos?.Invoke(this, EventArgs.Empty);
 
-        var moreThanEditMaid = ActiveMeidoList.Count > 1;
+        SelectedMeido = 0;
+
+        if (MeidoPhotoStudio.EditMode && meidoToCall.Count is 0)
+            meidoToCall.Add(OriginalEditingMeido);
 
-        UnloadMeidos();
+        UnloadMeidos(meidoToCall);
 
-        if (SelectMeidoList.Count is 0)
+        if (meidoToCall.Count is 0)
         {
             OnEndCallMeidos(this, EventArgs.Empty);
 
             return;
         }
 
-        void LoadMeido() =>
-            GameMain.Instance.StartCoroutine(LoadMeidos());
+        ActiveMeidoList.AddRange(meidoToCall);
 
-        if (MeidoPhotoStudio.EditMode && !moreThanEditMaid && SelectMeidoList.Count is 1)
-            LoadMeido();
-        else
-            GameMain.Instance.MainCamera.FadeOut(0.01f, f_bSkipable: false, f_dg: LoadMeido);
-    }
-
-    public void SelectMeido(int index)
-    {
-        if (SelectedMeidoSet.Contains(index))
-        {
-            if (!MeidoPhotoStudio.EditMode || index != EditMaidIndex)
-            {
-                SelectedMeidoSet.Remove(index);
-                SelectMeidoList.Remove(index);
-            }
-        }
-        else
-        {
-            SelectedMeidoSet.Add(index);
-            SelectMeidoList.Add(index);
-        }
-    }
-
-    public void ClearSelectList()
-    {
-        SelectedMeidoSet.Clear();
-        SelectMeidoList.Clear();
-
-        if (MeidoPhotoStudio.EditMode)
-        {
-            SelectedMeidoSet.Add(EditMaidIndex);
-            SelectMeidoList.Add(EditMaidIndex);
-        }
-    }
-
-    public void SetEditMaid(Meido meido)
-    {
-        if (!MeidoPhotoStudio.EditMode)
-            return;
-
-        EditMeido.IsEditMaid = false;
-
-        tempEditMaidIndex = meido.StockNo == EditMaidIndex ? -1 : meido.StockNo;
-
-        EditMeido.IsEditMaid = true;
-
-        SetEditorMaid(EditMeido.Maid);
+        GameMain.Instance.StartCoroutine(LoadMeidos(meidoToCall));
     }
 
     public Meido GetMeido(string guid) =>
@@ -286,14 +262,12 @@ public class MeidoManager : IManager
     [HarmonyPatch(typeof(SceneEdit), nameof(SceneEdit.Start))]
     private static void SceneEditStartPostfix()
     {
-        EditMaidIndex = -1;
-
         if (!SceneEdit.Instance.maid)
             return;
 
         var originalEditingMaid = SceneEdit.Instance.maid;
 
-        EditMaidIndex = GameMain.Instance.CharacterMgr.GetStockMaidList()
+        OriginalEditingMaidIndex = GameMain.Instance.CharacterMgr.GetStockMaidList()
             .FindIndex(maid => maid.status.guid == originalEditingMaid.status.guid);
 
         try
@@ -327,38 +301,36 @@ public class MeidoManager : IManager
         }
     }
 
-    private void UnloadMeidos()
+    private void UnloadMeidos(IList<Meido> meidoToCall)
     {
-        SelectedMeido = 0;
-
-        var commonMeidoIDs = new HashSet<int>(
-            ActiveMeidoList.Where(meido => SelectedMeidoSet.Contains(meido.StockNo)).Select(meido => meido.StockNo));
-
         foreach (var meido in ActiveMeidoList)
         {
             meido.UpdateMeido -= OnUpdateMeido;
             meido.GravityMove -= OnGravityMove;
 
-            if (!commonMeidoIDs.Contains(meido.StockNo))
+            if (!meidoToCall.Contains(meido))
                 meido.Unload();
         }
 
         ActiveMeidoList.Clear();
     }
 
-    private System.Collections.IEnumerator LoadMeidos()
+    private System.Collections.IEnumerator LoadMeidos(IList<Meido> meidoToLoad)
     {
-        foreach (var slot in SelectMeidoList)
-            ActiveMeidoList.Add(Meidos[slot]);
+        GameMain.Instance.MainCamera.FadeOut(0.01f, f_bSkipable: false);
 
-        for (var i = 0; i < ActiveMeidoList.Count; i++)
-            ActiveMeidoList[i].Load(i);
+        yield return new WaitForSeconds(0.01f);
 
-        while (Busy)
-            yield return null;
+        for (var meidoSlot = 0; meidoSlot < meidoToLoad.Count; meidoSlot++)
+            meidoToLoad[meidoSlot].Load(meidoSlot);
 
         yield return new WaitForEndOfFrame();
 
+        var waitForSeconds = new WaitForSeconds(0.5f);
+
+        while (Busy)
+            yield return waitForSeconds;
+
         OnEndCallMeidos(this, EventArgs.Empty);
     }
 
@@ -394,8 +366,8 @@ public class MeidoManager : IManager
             meido.GravityMove += OnGravityMove;
         }
 
-        if (MeidoPhotoStudio.EditMode && tempEditMaidIndex >= 0 && !SelectedMeidoSet.Contains(tempEditMaidIndex))
-            SetEditMaid(Meidos[EditMaidIndex]);
+        if (MeidoPhotoStudio.EditMode && !ActiveMeidoList.Contains(TemporaryEditingMeido))
+            EditingMeido = OriginalEditingMeido;
     }
 
     private void OnGravityMove(object sender, GravityEventArgs args)

+ 0 - 2
src/MeidoPhotoStudio.Plugin/Meido/Meido.cs

@@ -88,8 +88,6 @@ public class Meido
 
     public bool Active { get; private set; }
 
-    public bool IsEditMaid { get; set; }
-
     public PoseInfo CachedPose { get; private set; } = PoseInfo.DefaultPose;
 
     public string CurrentFaceBlendSet { get; private set; } = DefaultFaceBlendSet;

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

@@ -477,11 +477,7 @@ public class MeidoPhotoStudio : BaseUnityPlugin
         uiActive = true;
         active = true;
 
-        if (EditMode)
-        {
-            meidoManager.CallMeidos();
-        }
-        else
+        if (!EditMode)
         {
             // TODO: Rework this to not use null propagation (UNT008)
             var dailyPanel = GameObject.Find("UI Root")?.transform.Find("DailyPanel")?.gameObject;