using System; using System.IO; using System.Collections.Generic; using Newtonsoft.Json; using UnityEngine; using System.Linq; namespace MeidoPhotoStudio.Plugin { using static Meido; public class MaidFaceSliderPane : BasePane { private static readonly Dictionary SliderLimits = new Dictionary() { // Eye Shut ["eyeclose"] = 1f, // Eye Smile ["eyeclose2"] = 1f, // Glare ["eyeclose3"] = 1f, // Wide Eyes ["eyebig"] = 1f, // Wink 1 ["eyeclose6"] = 1f, // Wink 2 ["eyeclose5"] = 1f, // Highlight ["hitomih"] = 2f, // Pupil Size ["hitomis"] = 3f, // Brow 1 ["mayuha"] = 1f, // Brow 2 ["mayuw"] = 1f, // Brow Up ["mayuup"] = 1f, // Brow Down 1 ["mayuv"] = 1f, // Brow Down 2 ["mayuvhalf"] = 1f, // Mouth Open 1 ["moutha"] = 1f, // Mouth Open 2 ["mouths"] = 1f, // Mouth Narrow ["mouthc"] = 1f, // Mouth Widen ["mouthi"] = 1f, // Smile ["mouthup"] = 1.4f, // Frown ["mouthdw"] = 1f, // Mouth Pucker ["mouthhe"] = 1f, // Grin ["mouthuphalf"] = 2f, // Tongue Out ["tangout"] = 1f, // Tongue Up ["tangup"] = 1f, // Tongue Base ["tangopen"] = 1f }; private readonly MeidoManager meidoManager; private readonly Dictionary faceControls; private bool hasTangOpen; public MaidFaceSliderPane(MeidoManager meidoManager) { this.meidoManager = meidoManager; faceControls = new Dictionary(); foreach (string key in faceKeys) { string uiName = Translation.Get("faceBlendValues", key); Slider slider = new Slider(uiName, 0f, SliderLimits[key]); string myKey = key; slider.ControlEvent += (s, a) => SetFaceValue(myKey, slider.Value); faceControls[key] = slider; } foreach (string key in faceToggleKeys) { string uiName = Translation.Get("faceBlendValues", key); Toggle toggle = new Toggle(uiName); string myKey = key; toggle.ControlEvent += (s, a) => SetFaceValue(myKey, toggle.Value); faceControls[key] = toggle; } InitializeSliderLimits(faceControls); } private static void InitializeSliderLimits(Dictionary controls) { try { string sliderLimitsPath = Path.Combine(Constants.databasePath, "face_slider_limits.json"); string sliderLimitsJson = File.ReadAllText(sliderLimitsPath); foreach (var kvp in JsonConvert.DeserializeObject>(sliderLimitsJson)) { string key = kvp.Key; if (faceKeys.Contains(key) && controls.ContainsKey(key)) { float limit = kvp.Value; limit = kvp.Value >= 1f ? limit : SliderLimits[key]; Slider slider = (Slider)controls[kvp.Key]; slider.SetBounds(slider.Left, limit); } else Utility.LogWarning($"'{key}' is not a valid face key"); } } catch (IOException e) { Utility.LogWarning($"Could not open face slider limit database because {e.Message}"); } catch (Exception e) { Utility.LogError($"Could not apply face slider limit database because {e.Message}"); } } protected override void ReloadTranslation() { for (int i = 0; i < faceKeys.Length; i++) { Slider slider = (Slider)faceControls[faceKeys[i]]; slider.Label = Translation.Get("faceBlendValues", faceKeys[i]); } for (int i = 0; i < faceToggleKeys.Length; i++) { Toggle toggle = (Toggle)faceControls[faceToggleKeys[i]]; toggle.Label = Translation.Get("faceBlendValues", faceToggleKeys[i]); } } public override void UpdatePane() { updating = true; Meido meido = meidoManager.ActiveMeido; for (int i = 0; i < faceKeys.Length; i++) { Slider slider = (Slider)faceControls[faceKeys[i]]; try { slider.Value = meido.GetFaceBlendValue(faceKeys[i]); } catch { } } for (int i = 0; i < faceToggleKeys.Length; i++) { string hash = faceToggleKeys[i]; Toggle toggle = (Toggle)faceControls[hash]; toggle.Value = meido.GetFaceBlendValue(hash) > 0f; if (hash == "toothoff") toggle.Value = !toggle.Value; } hasTangOpen = meido.Body.Face.morph.Contains("tangopen"); updating = false; } public override void Draw() { GUI.enabled = meidoManager.HasActiveMeido; DrawSliders("eyeclose", "eyeclose2"); DrawSliders("eyeclose3", "eyebig"); DrawSliders("eyeclose6", "eyeclose5"); DrawSliders("hitomih", "hitomis"); DrawSliders("mayuha", "mayuw"); DrawSliders("mayuup", "mayuv"); DrawSliders("mayuvhalf"); DrawSliders("moutha", "mouths"); DrawSliders("mouthc", "mouthi"); DrawSliders("mouthup", "mouthdw"); DrawSliders("mouthhe", "mouthuphalf"); DrawSliders("tangout", "tangup"); if (hasTangOpen) DrawSliders("tangopen"); MpsGui.WhiteLine(); DrawToggles("hoho2", "shock", "nosefook"); DrawToggles("namida", "yodare", "toothoff"); DrawToggles("tear1", "tear2", "tear3"); DrawToggles("hohos", "hoho", "hohol"); GUI.enabled = true; } private void DrawSliders(params string[] keys) { GUILayout.BeginHorizontal(); foreach (string key in keys) faceControls[key].Draw(MpsGui.HalfSlider); GUILayout.EndHorizontal(); } private void DrawToggles(params string[] keys) { GUILayout.BeginHorizontal(); foreach (string key in keys) faceControls[key].Draw(); GUILayout.EndHorizontal(); } private void SetFaceValue(string key, float value) { if (updating) return; meidoManager.ActiveMeido.SetFaceBlendValue(key, value); } private void SetFaceValue(string key, bool value) { if (key == "toothoff") value = !value; SetFaceValue(key, value ? 1f : 0f); } } }