MaidDressingPane.cs 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321
  1. using System.Collections.Generic;
  2. using UnityEngine;
  3. using static MeidoPhotoStudio.Plugin.Meido;
  4. using static TBody;
  5. namespace MeidoPhotoStudio.Plugin;
  6. public class MaidDressingPane : BasePane
  7. {
  8. public static readonly SlotID[] ClothingSlots =
  9. {
  10. // main slots
  11. SlotID.wear, SlotID.skirt, SlotID.bra, SlotID.panz, SlotID.headset, SlotID.megane, SlotID.accUde,
  12. SlotID.glove, SlotID.accSenaka, SlotID.stkg, SlotID.shoes, SlotID.body,
  13. // detailed slots
  14. SlotID.accAshi, SlotID.accHana, SlotID.accHat, SlotID.accHeso, SlotID.accKamiSubL, SlotID.accKamiSubR,
  15. SlotID.accKami_1_, SlotID.accKami_2_, SlotID.accKami_3_, SlotID.accKubi, SlotID.accKubiwa, SlotID.accMiMiL,
  16. SlotID.accMiMiR, SlotID.accNipL, SlotID.accNipR, SlotID.accShippo, SlotID.accXXX
  17. // unused slots
  18. // SlotID.mizugi, SlotID.onepiece, SlotID.accHead,
  19. };
  20. public static readonly SlotID[] BodySlots =
  21. {
  22. SlotID.body, SlotID.head, SlotID.eye, SlotID.hairF, SlotID.hairR, SlotID.hairS, SlotID.hairT,
  23. SlotID.hairAho, SlotID.chikubi, SlotID.underhair, SlotID.moza, SlotID.accHa
  24. };
  25. public static readonly SlotID[] WearSlots = { SlotID.wear, SlotID.mizugi, SlotID.onepiece };
  26. public static readonly SlotID[] HeadwearSlots =
  27. {
  28. SlotID.headset, SlotID.accHat, SlotID.accKamiSubL, SlotID.accKamiSubR, SlotID.accKami_1_,
  29. SlotID.accKami_2_, SlotID.accKami_3_
  30. };
  31. private static readonly string[] maskLabels = { "all", "underwear", "nude" };
  32. private readonly MeidoManager meidoManager;
  33. private readonly Dictionary<SlotID, Toggle> clothingToggles;
  34. private readonly Dictionary<SlotID, bool> loadedSlots;
  35. private readonly Toggle detailedClothingToggle;
  36. private readonly SelectionGrid maskModeGrid;
  37. private readonly Toggle curlingFrontToggle;
  38. private readonly Toggle curlingBackToggle;
  39. private readonly Toggle pantsuShiftToggle;
  40. private bool detailedClothing;
  41. public MaidDressingPane(MeidoManager meidoManager)
  42. {
  43. this.meidoManager = meidoManager;
  44. clothingToggles = new(ClothingSlots.Length);
  45. loadedSlots = new(ClothingSlots.Length);
  46. foreach (var slot in ClothingSlots)
  47. {
  48. var slotToggle = new Toggle(Translation.Get("clothing", slot.ToString()));
  49. slotToggle.ControlEvent += (s, a) => ToggleClothing(slot, slotToggle.Value);
  50. clothingToggles.Add(slot, slotToggle);
  51. loadedSlots[slot] = true;
  52. }
  53. detailedClothingToggle = new(Translation.Get("clothing", "detail"));
  54. detailedClothingToggle.ControlEvent += (s, a) => UpdateDetailedClothing();
  55. curlingFrontToggle = new(Translation.Get("clothing", "curlingFront"));
  56. curlingFrontToggle.ControlEvent += (s, a) => ToggleCurling(Curl.Front, curlingFrontToggle.Value);
  57. curlingBackToggle = new(Translation.Get("clothing", "curlingBack"));
  58. curlingBackToggle.ControlEvent += (s, a) => ToggleCurling(Curl.Back, curlingBackToggle.Value);
  59. pantsuShiftToggle = new(Translation.Get("clothing", "shiftPanties"));
  60. pantsuShiftToggle.ControlEvent += (s, a) => ToggleCurling(Curl.Shift, pantsuShiftToggle.Value);
  61. maskModeGrid = new(Translation.GetArray("clothing", maskLabels));
  62. maskModeGrid.ControlEvent += (s, a) => SetMaskMode((Mask)maskModeGrid.SelectedItemIndex);
  63. UpdateDetailedClothing();
  64. }
  65. public override void UpdatePane()
  66. {
  67. if (!meidoManager.HasActiveMeido)
  68. return;
  69. updating = true;
  70. var meido = meidoManager.ActiveMeido;
  71. var body = meido.Maid.body0;
  72. foreach (var clothingSlot in ClothingSlots)
  73. {
  74. var toggleValue = false;
  75. var hasSlot = false;
  76. if (clothingSlot == SlotID.wear)
  77. {
  78. foreach (var wearSlot in WearSlots)
  79. {
  80. if (body.GetMask(wearSlot))
  81. toggleValue = true;
  82. if (body.GetSlotLoaded(wearSlot))
  83. hasSlot = true;
  84. if (hasSlot && toggleValue)
  85. break;
  86. }
  87. }
  88. else if (clothingSlot == SlotID.megane)
  89. {
  90. toggleValue = body.GetMask(SlotID.megane) || body.GetMask(SlotID.accHead);
  91. hasSlot = body.GetSlotLoaded(SlotID.megane) || body.GetSlotLoaded(SlotID.accHead);
  92. }
  93. else if (!detailedClothing && clothingSlot == SlotID.headset)
  94. {
  95. foreach (var headwearSlot in HeadwearSlots)
  96. {
  97. if (body.GetMask(headwearSlot))
  98. toggleValue = true;
  99. if (body.GetSlotLoaded(headwearSlot))
  100. hasSlot = true;
  101. if (hasSlot && toggleValue)
  102. break;
  103. }
  104. }
  105. else
  106. {
  107. toggleValue = body.GetMask(clothingSlot);
  108. hasSlot = body.GetSlotLoaded(clothingSlot);
  109. }
  110. clothingToggles[clothingSlot].Value = hasSlot && toggleValue;
  111. loadedSlots[clothingSlot] = hasSlot;
  112. }
  113. curlingFrontToggle.Value = meido.CurlingFront;
  114. curlingBackToggle.Value = meido.CurlingBack;
  115. pantsuShiftToggle.Value = meido.PantsuShift;
  116. var maskMode = meido.CurrentMaskMode;
  117. maskModeGrid.SelectedItemIndex = maskMode is MaskMode.Nude ? (int)Mask.Nude : (int)maskMode;
  118. updating = false;
  119. }
  120. public override void Draw()
  121. {
  122. GUI.enabled = Enabled = meidoManager.HasActiveMeido;
  123. detailedClothingToggle.Draw();
  124. MpsGui.BlackLine();
  125. maskModeGrid.Draw();
  126. MpsGui.BlackLine();
  127. DrawSlotGroup(SlotID.wear, SlotID.skirt);
  128. DrawSlotGroup(SlotID.bra, SlotID.panz);
  129. DrawSlotGroup(SlotID.headset, SlotID.megane);
  130. DrawSlotGroup(SlotID.accUde, SlotID.glove, SlotID.accSenaka);
  131. DrawSlotGroup(SlotID.stkg, SlotID.shoes, SlotID.body);
  132. if (detailedClothing)
  133. {
  134. MpsGui.BlackLine();
  135. DrawSlotGroup(SlotID.accShippo, SlotID.accHat);
  136. DrawSlotGroup(SlotID.accKami_1_, SlotID.accKami_2_, SlotID.accKami_3_);
  137. DrawSlotGroup(SlotID.accKamiSubL, SlotID.accKamiSubR);
  138. DrawSlotGroup(SlotID.accMiMiL, SlotID.accMiMiR);
  139. DrawSlotGroup(SlotID.accNipL, SlotID.accNipR);
  140. DrawSlotGroup(SlotID.accHana, SlotID.accKubi, SlotID.accKubiwa);
  141. DrawSlotGroup(SlotID.accHeso, SlotID.accAshi, SlotID.accXXX);
  142. }
  143. MpsGui.BlackLine();
  144. GUILayout.BeginHorizontal();
  145. curlingFrontToggle.Draw();
  146. GUILayout.FlexibleSpace();
  147. curlingBackToggle.Draw();
  148. GUILayout.FlexibleSpace();
  149. pantsuShiftToggle.Draw();
  150. GUILayout.FlexibleSpace();
  151. GUILayout.EndHorizontal();
  152. GUI.enabled = true;
  153. }
  154. protected override void ReloadTranslation()
  155. {
  156. foreach (var slot in ClothingSlots)
  157. {
  158. var clothingToggle = clothingToggles[slot];
  159. if (slot is SlotID.headset)
  160. clothingToggle.Label = detailedClothing
  161. ? Translation.Get("clothing", "headset")
  162. : Translation.Get("clothing", "headwear");
  163. else
  164. clothingToggle.Label = Translation.Get("clothing", slot.ToString());
  165. }
  166. updating = true;
  167. maskModeGrid.SetItems(Translation.GetArray("clothing", maskLabels));
  168. updating = false;
  169. detailedClothingToggle.Label = Translation.Get("clothing", "detail");
  170. curlingFrontToggle.Label = Translation.Get("clothing", "curlingFront");
  171. curlingBackToggle.Label = Translation.Get("clothing", "curlingBack");
  172. pantsuShiftToggle.Label = Translation.Get("clothing", "shiftPanties");
  173. }
  174. private void ToggleClothing(SlotID slot, bool enabled)
  175. {
  176. if (updating)
  177. return;
  178. if (slot is SlotID.body)
  179. {
  180. meidoManager.ActiveMeido.SetBodyMask(enabled);
  181. return;
  182. }
  183. var body = meidoManager.ActiveMeido.Maid.body0;
  184. if (!detailedClothing && slot is SlotID.headset)
  185. {
  186. updating = true;
  187. foreach (var wearSlot in HeadwearSlots)
  188. {
  189. body.SetMask(wearSlot, enabled);
  190. clothingToggles[wearSlot].Value = enabled;
  191. }
  192. updating = false;
  193. }
  194. else
  195. {
  196. if (slot is SlotID.wear)
  197. foreach (var wearSlot in WearSlots)
  198. body.SetMask(wearSlot, enabled);
  199. else if (slot is SlotID.megane)
  200. {
  201. body.SetMask(SlotID.megane, enabled);
  202. body.SetMask(SlotID.accHead, enabled);
  203. }
  204. else
  205. body.SetMask(slot, enabled);
  206. }
  207. }
  208. private void ToggleCurling(Curl curl, bool enabled)
  209. {
  210. if (updating)
  211. return;
  212. meidoManager.ActiveMeido.SetCurling(curl, enabled);
  213. if (!enabled)
  214. return;
  215. updating = true;
  216. if (curl is Curl.Front && curlingBackToggle.Value)
  217. curlingBackToggle.Value = false;
  218. else if (curl is Curl.Back && curlingFrontToggle.Value)
  219. curlingFrontToggle.Value = false;
  220. updating = false;
  221. }
  222. private void SetMaskMode(Mask mask)
  223. {
  224. if (updating)
  225. return;
  226. meidoManager.ActiveMeido.SetMaskMode(mask);
  227. UpdatePane();
  228. }
  229. private void DrawSlotGroup(params SlotID[] slots)
  230. {
  231. GUILayout.BeginHorizontal();
  232. for (var i = 0; i < slots.Length; i++)
  233. {
  234. var slot = slots[i];
  235. GUI.enabled = Enabled && loadedSlots[slot];
  236. clothingToggles[slot].Draw();
  237. if (i < slots.Length - 1)
  238. GUILayout.FlexibleSpace();
  239. }
  240. GUILayout.EndHorizontal();
  241. GUI.enabled = Enabled;
  242. }
  243. private void UpdateDetailedClothing()
  244. {
  245. detailedClothing = detailedClothingToggle.Value;
  246. clothingToggles[SlotID.headset].Label = detailedClothing
  247. ? Translation.Get("clothing", "headset")
  248. : Translation.Get("clothing", "headwear");
  249. UpdatePane();
  250. }
  251. }