Forráskód Böngészése

Add pane for prop management

Prop dragpoint and gizmo can be enabled and disabled individually.
Add a copy button and delete button.
habeebweeb 4 éve
szülő
commit
16517b4d07

+ 22 - 0
COM3D2.MeidoPhotoStudio.Plugin/MeidoPhotoStudio/DragPoint/DragPoint.cs

@@ -68,6 +68,28 @@ namespace COM3D2.MeidoPhotoStudio.Plugin
                 }
             }
         }
+        private bool dragPointEnabled = true;
+        public bool DragPointEnabled
+        {
+            get => dragPointEnabled;
+            set
+            {
+                if (dragPointEnabled == value) return;
+                dragPointEnabled = value;
+                ApplyDragType();
+            }
+        }
+        private bool gizmoEnabled = true;
+        public bool GizmoEnabled
+        {
+            get => GizmoGo != null && gizmoEnabled;
+            set
+            {
+                if (GizmoGo == null || (GizmoGo != null && gizmoEnabled == value)) return;
+                gizmoEnabled = value;
+                ApplyDragType();
+            }
+        }
 
         private void Awake()
         {

+ 2 - 2
COM3D2.MeidoPhotoStudio.Plugin/MeidoPhotoStudio/DragPoint/DragPointOther.cs

@@ -30,8 +30,8 @@ namespace COM3D2.MeidoPhotoStudio.Plugin
         protected override void ApplyDragType()
         {
             DragType current = CurrentDragType;
-            bool active = Transforming || Special;
-            ApplyProperties(active, active, Rotating);
+            bool active = (DragPointEnabled && Transforming) || Special;
+            ApplyProperties(active, active, GizmoEnabled && Rotating);
         }
 
         protected override void OnDestroy()

+ 5 - 39
COM3D2.MeidoPhotoStudio.Plugin/MeidoPhotoStudio/GUI/Panes/BackgroundWindow2Panes/AttachPropPane.cs

@@ -35,9 +35,6 @@ namespace COM3D2.MeidoPhotoStudio.Plugin
         private Button previousMaidButton;
         private Button nextMaidButton;
         private Dropdown meidoDropdown;
-        private Button previousDoguButton;
-        private Button nextDoguButton;
-        private Dropdown doguDropdown;
         private bool meidoDropdownActive = false;
         private bool doguDropdownActive = false;
         private bool PaneActive => meidoDropdownActive && doguDropdownActive;
@@ -51,11 +48,8 @@ namespace COM3D2.MeidoPhotoStudio.Plugin
             this.meidoManager = meidoManager;
 
             this.meidoManager.EndCallMeidos += (s, a) => SetMeidoDropdown();
-            this.propManager.DoguListChange += (s, a) => SetDoguDropdown();
-            this.propManager.DoguSelectChange += (s, a) =>
-            {
-                this.doguDropdown.SelectedItemIndex = this.propManager.CurrentDoguIndex;
-            };
+            this.propManager.DoguSelectChange += (s, a) => SwitchDogu();
+            this.propManager.DoguListChange += (s, a) => doguDropdownActive = this.propManager.DoguCount > 0;
 
             this.meidoDropdown = new Dropdown(new[] { Translation.Get("systemMessage", "noMaids") });
             this.meidoDropdown.SelectionChange += (s, a) => SwitchMaid();
@@ -66,15 +60,6 @@ namespace COM3D2.MeidoPhotoStudio.Plugin
             this.nextMaidButton = new Button(">");
             this.nextMaidButton.ControlEvent += (s, a) => this.meidoDropdown.Step(1);
 
-            this.doguDropdown = new Dropdown(new[] { Translation.Get("systemMessage", "noProps") });
-            this.doguDropdown.SelectionChange += (s, a) => SwitchDogu();
-
-            this.previousDoguButton = new Button("<");
-            this.previousDoguButton.ControlEvent += (s, a) => this.doguDropdown.Step(-1);
-
-            this.nextDoguButton = new Button(">");
-            this.nextDoguButton.ControlEvent += (s, a) => this.doguDropdown.Step(1);
-
             this.keepWorldPositionToggle = new Toggle(Translation.Get("attachPropPane", "keepWorldPosition"));
 
             foreach (AttachPoint attachPoint in Enum.GetValues(typeof(AttachPoint)))
@@ -124,12 +109,6 @@ namespace COM3D2.MeidoPhotoStudio.Plugin
 
             meidoDropdown.Draw(dropdownLayoutOptions);
 
-            GUILayout.BeginHorizontal();
-            doguDropdown.Draw(dropdownLayoutOptions);
-            previousDoguButton.Draw(arrowLayoutOptions);
-            nextDoguButton.Draw(arrowLayoutOptions);
-            GUILayout.EndHorizontal();
-
             keepWorldPositionToggle.Draw();
 
             DrawToggleGroup(AttachPoint.Head, AttachPoint.Neck);
@@ -182,7 +161,7 @@ namespace COM3D2.MeidoPhotoStudio.Plugin
             }
 
             this.propManager.AttachProp(
-                this.doguDropdown.SelectedItemIndex, point, meido, this.keepWorldPositionToggle.Value
+                this.propManager.CurrentDoguIndex, point, meido, this.keepWorldPositionToggle.Value
             );
         }
 
@@ -190,7 +169,7 @@ namespace COM3D2.MeidoPhotoStudio.Plugin
         {
             if (updating || selectedMaid == this.meidoDropdown.SelectedItemIndex) return;
             selectedMaid = this.meidoDropdown.SelectedItemIndex;
-            DragPointDogu dragDogu = this.propManager.GetDogu(this.doguDropdown.SelectedItemIndex);
+            DragPointDogu dragDogu = this.propManager.CurrentDogu;
             if (dragDogu != null)
             {
                 if (dragDogu.attachPointInfo.AttachPoint == AttachPoint.None) return;
@@ -201,23 +180,10 @@ namespace COM3D2.MeidoPhotoStudio.Plugin
         private void SwitchDogu()
         {
             if (updating) return;
-            DragPointDogu dragDogu = this.propManager.GetDogu(this.doguDropdown.SelectedItemIndex);
+            DragPointDogu dragDogu = this.propManager.CurrentDogu;
             if (dragDogu != null) SetAttachPointToggle(dragDogu.attachPointInfo.AttachPoint, true);
         }
 
-        private void SetDoguDropdown()
-        {
-            if (this.propManager.DoguCount == 0)
-            {
-                SetAttachPointToggle(AttachPoint.Head, false);
-            }
-            int index = Mathf.Clamp(this.doguDropdown.SelectedItemIndex, 0, this.propManager.DoguCount);
-
-            this.doguDropdown.SetDropdownItems(this.propManager.PropNameList, index);
-
-            doguDropdownActive = this.propManager.DoguCount != 0;
-        }
-
         private void SetMeidoDropdown()
         {
             if (this.meidoManager.ActiveMeidoList.Count == 0)

+ 124 - 0
COM3D2.MeidoPhotoStudio.Plugin/MeidoPhotoStudio/GUI/Panes/BackgroundWindow2Panes/PropManagerPane.cs

@@ -0,0 +1,124 @@
+using UnityEngine;
+
+namespace COM3D2.MeidoPhotoStudio.Plugin
+{
+    internal class PropManagerPane : BasePane
+    {
+        private PropManager propManager;
+        private Dropdown propDropdown;
+        private Button previousPropButton;
+        private Button nextPropButton;
+        private Toggle dragPointToggle;
+        private Toggle gizmoToggle;
+        private Button deletePropButton;
+        private Button copyPropButton;
+        private int CurrentDoguIndex => this.propManager.CurrentDoguIndex;
+
+        public PropManagerPane(PropManager propManager)
+        {
+            this.propManager = propManager;
+            this.propManager.DoguListChange += (s, a) =>
+            {
+                UpdatePropList();
+                UpdateToggles();
+            };
+
+            this.propManager.DoguSelectChange += (s, a) =>
+            {
+                this.updating = true;
+                this.propDropdown.SelectedItemIndex = CurrentDoguIndex;
+                this.updating = false;
+                UpdateToggles();
+            };
+
+            this.propDropdown = new Dropdown(this.propManager.PropNameList);
+            this.propDropdown.SelectionChange += (s, a) =>
+            {
+                if (updating) return;
+                this.propManager.SetCurrentDogu(this.propDropdown.SelectedItemIndex);
+                UpdateToggles();
+            };
+
+            this.previousPropButton = new Button("<");
+            this.previousPropButton.ControlEvent += (s, a) => this.propDropdown.Step(-1);
+
+            this.nextPropButton = new Button(">");
+            this.nextPropButton.ControlEvent += (s, a) => this.propDropdown.Step(1);
+
+            this.dragPointToggle = new Toggle("Cube");
+            this.dragPointToggle.ControlEvent += (s, a) =>
+            {
+                if (this.updating || this.propManager.DoguCount == 0) return;
+                this.propManager.CurrentDogu.DragPointEnabled = dragPointToggle.Value;
+            };
+
+            this.gizmoToggle = new Toggle("Gizmo");
+            this.gizmoToggle.ControlEvent += (s, a) =>
+            {
+                if (this.updating || this.propManager.DoguCount == 0) return;
+                this.propManager.CurrentDogu.GizmoEnabled = gizmoToggle.Value;
+            };
+
+            this.copyPropButton = new Button("Copy");
+            this.copyPropButton.ControlEvent += (s, a) => this.propManager.CopyDogu(CurrentDoguIndex);
+
+            this.deletePropButton = new Button("Delete");
+            this.deletePropButton.ControlEvent += (s, a) => this.propManager.RemoveDogu(CurrentDoguIndex);
+        }
+
+        public override void Draw()
+        {
+            float arrowButtonSize = 30;
+            GUILayoutOption[] arrowLayoutOptions = {
+                GUILayout.Width(arrowButtonSize),
+                GUILayout.Height(arrowButtonSize)
+            };
+
+            float dropdownButtonHeight = arrowButtonSize;
+            float dropdownButtonWidth = 140f;
+            GUILayoutOption[] dropdownLayoutOptions = new GUILayoutOption[] {
+                GUILayout.Height(dropdownButtonHeight),
+                GUILayout.Width(dropdownButtonWidth)
+            };
+
+            MiscGUI.WhiteLine();
+
+            GUI.enabled = this.propManager.DoguCount > 0;
+
+            GUILayout.BeginHorizontal();
+            this.propDropdown.Draw(dropdownLayoutOptions);
+            this.previousPropButton.Draw(arrowLayoutOptions);
+            this.nextPropButton.Draw(arrowLayoutOptions);
+            GUILayout.EndHorizontal();
+
+            GUILayoutOption noExpandWidth = GUILayout.ExpandWidth(false);
+
+            GUILayout.BeginHorizontal();
+            this.dragPointToggle.Draw(noExpandWidth);
+            this.gizmoToggle.Draw(noExpandWidth);
+            this.copyPropButton.Draw(noExpandWidth);
+            this.deletePropButton.Draw(noExpandWidth);
+            GUILayout.EndHorizontal();
+
+            GUI.enabled = true;
+        }
+
+        private void UpdatePropList()
+        {
+            this.updating = true;
+            this.propDropdown.SetDropdownItems(this.propManager.PropNameList, CurrentDoguIndex);
+            this.updating = false;
+        }
+
+        private void UpdateToggles()
+        {
+            DragPointDogu dogu = this.propManager.CurrentDogu;
+            if (dogu == null) return;
+
+            this.updating = true;
+            this.dragPointToggle.Value = dogu.DragPointEnabled;
+            this.gizmoToggle.Value = dogu.GizmoEnabled;
+            this.updating = false;
+        }
+    }
+}

+ 7 - 1
COM3D2.MeidoPhotoStudio.Plugin/MeidoPhotoStudio/GUI/Panes/MainWindowPanes/BG2WindowPane.cs

@@ -8,6 +8,7 @@ namespace COM3D2.MeidoPhotoStudio.Plugin
         private AttachPropPane attachPropPane;
         private MyRoomPropsPane myRoomPropsPane;
         private ModPropsPane modPropsPane;
+        private PropManagerPane propManagerPane;
         private SelectionGrid propTabs;
         private BasePane currentPropsPane;
         private static readonly string[] tabNames = { "props", "myRoom", "mod" };
@@ -22,6 +23,7 @@ namespace COM3D2.MeidoPhotoStudio.Plugin
             this.myRoomPropsPane = AddPane(new MyRoomPropsPane(propManager));
             this.modPropsPane = AddPane(new ModPropsPane(propManager));
             this.attachPropPane = AddPane(new AttachPropPane(this.meidoManager, propManager));
+            this.propManagerPane = AddPane(new PropManagerPane(propManager));
 
             this.propTabs = new SelectionGrid(Translation.GetArray("propsPaneTabs", tabNames));
             this.propTabs.ControlEvent += (s, a) =>
@@ -41,7 +43,11 @@ namespace COM3D2.MeidoPhotoStudio.Plugin
             this.propTabs.Draw();
             MiscGUI.WhiteLine();
             this.currentPropsPane.Draw();
-            if (this.propTabs.SelectedItemIndex == 0) this.attachPropPane.Draw();
+            if (this.propTabs.SelectedItemIndex == 0)
+            {
+                this.propManagerPane.Draw();
+                this.attachPropPane.Draw();
+            }
         }
 
         public override void UpdatePanes()

+ 94 - 81
COM3D2.MeidoPhotoStudio.Plugin/MeidoPhotoStudio/Managers/PropManager.cs

@@ -1,4 +1,5 @@
 using System;
+using System.IO;
 using System.Collections.Generic;
 using System.Linq;
 using UnityEngine;
@@ -52,7 +53,8 @@ namespace COM3D2.MeidoPhotoStudio.Plugin
                     : doguList.Select(dogu => dogu.Name).ToArray();
             }
         }
-        public int CurrentDoguIndex { get; private set; }
+        public int CurrentDoguIndex { get; private set; } = 0;
+        public DragPointDogu CurrentDogu => DoguCount == 0 ? null : doguList[CurrentDoguIndex];
 
         public PropManager(MeidoManager meidoManager)
         {
@@ -61,7 +63,7 @@ namespace COM3D2.MeidoPhotoStudio.Plugin
             this.meidoManager.EndCallMeidos += OnEndCall;
         }
 
-        public void Serialize(System.IO.BinaryWriter binaryWriter)
+        public void Serialize(BinaryWriter binaryWriter)
         {
             binaryWriter.Write(header);
             binaryWriter.Write(doguList.Count);
@@ -76,7 +78,7 @@ namespace COM3D2.MeidoPhotoStudio.Plugin
             }
         }
 
-        public void Deserialize(System.IO.BinaryReader binaryReader)
+        public void Deserialize(BinaryReader binaryReader)
         {
             Dictionary<string, string> modToModPath = null;
             ClearDogu();
@@ -85,51 +87,14 @@ namespace COM3D2.MeidoPhotoStudio.Plugin
             {
                 string assetName = binaryReader.ReadString();
                 bool result = false;
-                if (assetName.EndsWith(".menu"))
-                {
-                    if (assetName.Contains('#'))
-                    {
-                        if (modToModPath == null)
-                        {
-                            modToModPath = new Dictionary<string, string>(StringComparer.InvariantCultureIgnoreCase);
-                            foreach (string mod in Menu.GetModFiles())
-                            {
-                                modToModPath.Add(System.IO.Path.GetFileName(mod), mod);
-                            }
-                        }
 
-                        string[] assetParts = assetName.Split('#');
-                        ModItem item = new ModItem()
-                        {
-                            MenuFile = modToModPath[assetParts[0]],
-                            BaseMenuFile = assetParts[1],
-                            IsMod = true,
-                            IsOfficialMod = true
-                        };
-                        result = SpawnModItemProp(item);
-                    }
-                    else
-                    {
-                        if (assetName.StartsWith("handitem")) result = SpawnObject(assetName);
-                        else result = SpawnModItemProp(new ModItem() { MenuFile = assetName });
-                    }
-                }
-                else if (assetName.StartsWith("MYR_"))
+                if (assetName.EndsWith(".menu") && assetName.Contains('#') && modToModPath == null)
                 {
-                    string[] assetParts = assetName.Split('#');
-                    int id = int.Parse(assetParts[0].Substring(4));
-                    string prefabName;
-                    if (assetParts.Length == 2 && !string.IsNullOrEmpty(assetParts[1])) prefabName = assetParts[1];
-                    else
-                    {
-                        // deserialize modifiedMM and maybe MM 23.0+.
-                        MyRoomCustom.PlacementData.Data data = MyRoomCustom.PlacementData.GetData(id);
-                        prefabName = !string.IsNullOrEmpty(data.resourceName) ? data.resourceName : data.assetName;
-                    }
-                    result = SpawnMyRoomProp(new MyRoomItem() { ID = id, PrefabName = prefabName });
+                    modToModPath = new Dictionary<string, string>(StringComparer.InvariantCultureIgnoreCase);
+                    foreach (string mod in Menu.GetModFiles()) modToModPath.Add(Path.GetFileName(mod), mod);
                 }
-                else if (assetName.StartsWith("BG_")) result = SpawnBG(assetName);
-                else result = SpawnObject(assetName);
+
+                result = SpawnFromAssetString(assetName, modToModPath);
 
                 AttachPointInfo info = AttachPointInfo.Deserialize(binaryReader);
 
@@ -146,6 +111,7 @@ namespace COM3D2.MeidoPhotoStudio.Plugin
                     dogu.attachPointInfo = info;
                 }
             }
+            CurrentDoguIndex = 0;
             GameMain.Instance.StartCoroutine(DeserializeAttach());
         }
 
@@ -195,20 +161,6 @@ namespace COM3D2.MeidoPhotoStudio.Plugin
 
         public void Update() { }
 
-        private void ClearDogu()
-        {
-            foreach (DragPointDogu dogu in doguList)
-            {
-                if (dogu != null)
-                {
-                    dogu.Delete -= DeleteDogu;
-                    dogu.Select -= DeleteDogu;
-                    GameObject.Destroy(dogu.gameObject);
-                }
-            }
-            doguList.Clear();
-        }
-
         private GameObject GetDeploymentObject()
         {
             return GameObject.Find("Deployment Object Parent")
@@ -219,6 +171,7 @@ namespace COM3D2.MeidoPhotoStudio.Plugin
         {
             GameObject dogu = MenuFileUtility.LoadModel(modItem);
             string name = modItem.MenuFile;
+            if (modItem.IsOfficialMod) name = Path.GetFileNameWithoutExtension(name);
             if (dogu != null) AttachDragPoint(dogu, modItem.ToString(), name, new Vector3(0f, 0f, 0.5f));
             return dogu != null;
         }
@@ -378,6 +331,43 @@ namespace COM3D2.MeidoPhotoStudio.Plugin
             return false;
         }
 
+        private bool SpawnFromAssetString(string assetName, Dictionary<string, string> modDict = null)
+        {
+            bool result = false;
+            if (assetName.EndsWith(".menu"))
+            {
+                if (assetName.Contains('#'))
+                {
+                    string[] assetParts = assetName.Split('#');
+                    string menuFile = modDict == null ? Menu.GetModPathFileName(assetParts[0]) : modDict[assetParts[0]];
+
+                    ModItem item = ModItem.OfficialMod(menuFile);
+                    item.BaseMenuFile = assetParts[1];
+                    result = SpawnModItemProp(item);
+                }
+                else if (assetName.StartsWith("handitem")) result = SpawnObject(assetName);
+                else result = SpawnModItemProp(ModItem.Mod(assetName));
+            }
+            else if (assetName.StartsWith("MYR_"))
+            {
+                string[] assetParts = assetName.Split('#');
+                int id = int.Parse(assetParts[0].Substring(4));
+                string prefabName;
+                if (assetParts.Length == 2 && !string.IsNullOrEmpty(assetParts[1])) prefabName = assetParts[1];
+                else
+                {
+                    // deserialize modifiedMM and maybe MM 23.0+.
+                    MyRoomCustom.PlacementData.Data data = MyRoomCustom.PlacementData.GetData(id);
+                    prefabName = !string.IsNullOrEmpty(data.resourceName) ? data.resourceName : data.assetName;
+                }
+                result = SpawnMyRoomProp(new MyRoomItem() { ID = id, PrefabName = prefabName });
+            }
+            else if (assetName.StartsWith("BG_")) result = SpawnBG(assetName);
+            else result = SpawnObject(assetName);
+
+            return result;
+        }
+
         private void AttachDragPoint(GameObject dogu, string assetName, string name, Vector3 position)
         {
             // TODO: Figure out why some props aren't centred properly
@@ -406,10 +396,32 @@ namespace COM3D2.MeidoPhotoStudio.Plugin
             OnDoguListChange();
         }
 
-        public DragPointDogu GetDogu(int doguIndex)
+        public void SetCurrentDogu(int doguIndex)
         {
-            if (doguList.Count == 0 || doguIndex >= doguList.Count || doguIndex < 0) return null;
-            return doguList[doguIndex];
+            if (doguIndex >= 0 && doguIndex < DoguCount)
+            {
+                this.CurrentDoguIndex = doguIndex;
+                this.DoguSelectChange?.Invoke(this, EventArgs.Empty);
+            }
+        }
+
+        public void RemoveDogu(int doguIndex)
+        {
+            if (doguIndex >= 0 && doguIndex < DoguCount)
+            {
+                DestroyDogu(doguList[doguIndex]);
+                doguList.RemoveAt(doguIndex);
+                CurrentDoguIndex = Utility.Bound(CurrentDoguIndex, 0, DoguCount - 1);
+                OnDoguListChange();
+            }
+        }
+
+        public void CopyDogu(int doguIndex)
+        {
+            if (doguIndex >= 0 && doguIndex < DoguCount)
+            {
+                SpawnFromAssetString(doguList[doguIndex].assetName);
+            }
         }
 
         public void AttachProp(
@@ -468,6 +480,16 @@ namespace COM3D2.MeidoPhotoStudio.Plugin
             }
         }
 
+        private void ClearDogu()
+        {
+            for (int i = DoguCount - 1; i >= 0; i--)
+            {
+                DestroyDogu(doguList[i]);
+            }
+            doguList.Clear();
+            CurrentDoguIndex = 0;
+        }
+
         private void OnEndCall(object sender, EventArgs args) => ReattachProps(useGuid: true);
 
         private void ReattachProps(bool useGuid, bool forceStay = false)
@@ -486,30 +508,21 @@ namespace COM3D2.MeidoPhotoStudio.Plugin
         private void DeleteDogu(object sender, EventArgs args)
         {
             DragPointDogu dogu = (DragPointDogu)sender;
-            doguList.RemoveAll(dragDogu =>
-                {
-                    if (dragDogu == dogu)
-                    {
-                        dogu.Delete -= DeleteDogu;
-                        dogu.Select -= SelectDogu;
-                        GameObject.Destroy(dragDogu.gameObject);
-                        return true;
-                    }
-                    return false;
-                }
-            );
-            OnDoguListChange();
+            RemoveDogu(doguList.FindIndex(dragDogu => dragDogu == dogu));
+        }
+
+        private void DestroyDogu(DragPointDogu dogu)
+        {
+            if (dogu == null) return;
+            dogu.Delete -= DeleteDogu;
+            dogu.Select -= SelectDogu;
+            GameObject.Destroy(dogu.gameObject);
         }
 
         private void SelectDogu(object sender, EventArgs args)
         {
             DragPointDogu dogu = (DragPointDogu)sender;
-            int doguIndex = doguList.IndexOf(dogu);
-            if (doguIndex != -1)
-            {
-                CurrentDoguIndex = doguIndex;
-                DoguSelectChange?.Invoke(this, EventArgs.Empty);
-            }
+            SetCurrentDogu(doguList.IndexOf(dogu));
         }
 
         private void OnCubeSmall(object sender, EventArgs args)