MaidDressingPane.cs 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336
  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, SlotID.hairAho,
  23. 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_, SlotID.accKami_2_,
  29. 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 += (_, _) =>
  50. ToggleClothing(slot, slotToggle.Value);
  51. clothingToggles.Add(slot, slotToggle);
  52. loadedSlots[slot] = true;
  53. }
  54. detailedClothingToggle = new(Translation.Get("clothing", "detail"));
  55. detailedClothingToggle.ControlEvent += (_, _) =>
  56. UpdateDetailedClothing();
  57. curlingFrontToggle = new(Translation.Get("clothing", "curlingFront"));
  58. curlingFrontToggle.ControlEvent += (_, _) =>
  59. ToggleCurling(Curl.Front, curlingFrontToggle.Value);
  60. curlingBackToggle = new(Translation.Get("clothing", "curlingBack"));
  61. curlingBackToggle.ControlEvent += (_, _) =>
  62. ToggleCurling(Curl.Back, curlingBackToggle.Value);
  63. pantsuShiftToggle = new(Translation.Get("clothing", "shiftPanties"));
  64. pantsuShiftToggle.ControlEvent += (_, _) =>
  65. ToggleCurling(Curl.Shift, pantsuShiftToggle.Value);
  66. maskModeGrid = new(Translation.GetArray("clothing", MaskLabels));
  67. maskModeGrid.ControlEvent += (_, _) =>
  68. SetMaskMode((Mask)maskModeGrid.SelectedItemIndex);
  69. UpdateDetailedClothing();
  70. }
  71. public override void UpdatePane()
  72. {
  73. if (!meidoManager.HasActiveMeido)
  74. return;
  75. updating = true;
  76. var meido = meidoManager.ActiveMeido;
  77. var body = meido.Maid.body0;
  78. foreach (var clothingSlot in ClothingSlots)
  79. {
  80. var toggleValue = false;
  81. var hasSlot = false;
  82. if (clothingSlot is SlotID.wear)
  83. {
  84. foreach (var wearSlot in WearSlots)
  85. {
  86. if (body.GetMask(wearSlot))
  87. toggleValue = true;
  88. if (body.GetSlotLoaded(wearSlot))
  89. hasSlot = true;
  90. if (hasSlot && toggleValue)
  91. break;
  92. }
  93. }
  94. else if (clothingSlot is SlotID.megane)
  95. {
  96. toggleValue = body.GetMask(SlotID.megane) || body.GetMask(SlotID.accHead);
  97. hasSlot = body.GetSlotLoaded(SlotID.megane) || body.GetSlotLoaded(SlotID.accHead);
  98. }
  99. else if (!detailedClothing && clothingSlot is SlotID.headset)
  100. {
  101. foreach (var headwearSlot in HeadwearSlots)
  102. {
  103. if (body.GetMask(headwearSlot))
  104. toggleValue = true;
  105. if (body.GetSlotLoaded(headwearSlot))
  106. hasSlot = true;
  107. if (hasSlot && toggleValue)
  108. break;
  109. }
  110. }
  111. else
  112. {
  113. toggleValue = body.GetMask(clothingSlot);
  114. hasSlot = body.GetSlotLoaded(clothingSlot);
  115. }
  116. clothingToggles[clothingSlot].Value = hasSlot && toggleValue;
  117. loadedSlots[clothingSlot] = hasSlot;
  118. }
  119. curlingFrontToggle.Value = meido.CurlingFront;
  120. curlingBackToggle.Value = meido.CurlingBack;
  121. pantsuShiftToggle.Value = meido.PantsuShift;
  122. var maskMode = meido.CurrentMaskMode;
  123. maskModeGrid.SelectedItemIndex = maskMode is MaskMode.Nude ? (int)Mask.Nude : (int)maskMode;
  124. updating = false;
  125. }
  126. public override void Draw()
  127. {
  128. GUI.enabled = Enabled = meidoManager.HasActiveMeido;
  129. detailedClothingToggle.Draw();
  130. MpsGui.BlackLine();
  131. maskModeGrid.Draw();
  132. MpsGui.BlackLine();
  133. DrawSlotGroup(SlotID.wear, SlotID.skirt);
  134. DrawSlotGroup(SlotID.bra, SlotID.panz);
  135. DrawSlotGroup(SlotID.headset, SlotID.megane);
  136. DrawSlotGroup(SlotID.accUde, SlotID.glove, SlotID.accSenaka);
  137. DrawSlotGroup(SlotID.stkg, SlotID.shoes, SlotID.body);
  138. if (detailedClothing)
  139. {
  140. MpsGui.BlackLine();
  141. DrawSlotGroup(SlotID.accShippo, SlotID.accHat);
  142. DrawSlotGroup(SlotID.accKami_1_, SlotID.accKami_2_, SlotID.accKami_3_);
  143. DrawSlotGroup(SlotID.accKamiSubL, SlotID.accKamiSubR);
  144. DrawSlotGroup(SlotID.accMiMiL, SlotID.accMiMiR);
  145. DrawSlotGroup(SlotID.accNipL, SlotID.accNipR);
  146. DrawSlotGroup(SlotID.accHana, SlotID.accKubi, SlotID.accKubiwa);
  147. DrawSlotGroup(SlotID.accHeso, SlotID.accAshi, SlotID.accXXX);
  148. }
  149. MpsGui.BlackLine();
  150. GUILayout.BeginHorizontal();
  151. curlingFrontToggle.Draw();
  152. GUILayout.FlexibleSpace();
  153. curlingBackToggle.Draw();
  154. GUILayout.FlexibleSpace();
  155. pantsuShiftToggle.Draw();
  156. GUILayout.FlexibleSpace();
  157. GUILayout.EndHorizontal();
  158. GUI.enabled = true;
  159. }
  160. protected override void ReloadTranslation()
  161. {
  162. foreach (var slot in ClothingSlots)
  163. {
  164. var clothingToggle = clothingToggles[slot];
  165. if (slot is SlotID.headset)
  166. clothingToggle.Label = detailedClothing
  167. ? Translation.Get("clothing", "headset")
  168. : Translation.Get("clothing", "headwear");
  169. else
  170. clothingToggle.Label = Translation.Get("clothing", slot.ToString());
  171. }
  172. updating = true;
  173. maskModeGrid.SetItems(Translation.GetArray("clothing", MaskLabels));
  174. updating = false;
  175. detailedClothingToggle.Label = Translation.Get("clothing", "detail");
  176. curlingFrontToggle.Label = Translation.Get("clothing", "curlingFront");
  177. curlingBackToggle.Label = Translation.Get("clothing", "curlingBack");
  178. pantsuShiftToggle.Label = Translation.Get("clothing", "shiftPanties");
  179. }
  180. private void ToggleClothing(SlotID slot, bool enabled)
  181. {
  182. if (updating)
  183. return;
  184. if (slot is SlotID.body)
  185. {
  186. meidoManager.ActiveMeido.SetBodyMask(enabled);
  187. return;
  188. }
  189. var body = meidoManager.ActiveMeido.Maid.body0;
  190. if (!detailedClothing && slot is SlotID.headset)
  191. {
  192. updating = true;
  193. foreach (var wearSlot in HeadwearSlots)
  194. {
  195. body.SetMask(wearSlot, enabled);
  196. clothingToggles[wearSlot].Value = enabled;
  197. }
  198. updating = false;
  199. }
  200. else
  201. {
  202. if (slot is SlotID.wear)
  203. {
  204. foreach (var wearSlot in WearSlots)
  205. body.SetMask(wearSlot, enabled);
  206. }
  207. else if (slot is SlotID.megane)
  208. {
  209. body.SetMask(SlotID.megane, enabled);
  210. body.SetMask(SlotID.accHead, enabled);
  211. }
  212. else
  213. {
  214. body.SetMask(slot, enabled);
  215. }
  216. }
  217. }
  218. private void ToggleCurling(Curl curl, bool enabled)
  219. {
  220. if (updating)
  221. return;
  222. meidoManager.ActiveMeido.SetCurling(curl, enabled);
  223. if (!enabled)
  224. return;
  225. updating = true;
  226. if (curl is Curl.Front && curlingBackToggle.Value)
  227. curlingBackToggle.Value = false;
  228. else if (curl is Curl.Back && curlingFrontToggle.Value)
  229. curlingFrontToggle.Value = false;
  230. updating = false;
  231. }
  232. private void SetMaskMode(Mask mask)
  233. {
  234. if (updating)
  235. return;
  236. meidoManager.ActiveMeido.SetMaskMode(mask);
  237. UpdatePane();
  238. }
  239. private void DrawSlotGroup(params SlotID[] slots)
  240. {
  241. GUILayout.BeginHorizontal();
  242. for (var i = 0; i < slots.Length; i++)
  243. {
  244. var slot = slots[i];
  245. GUI.enabled = Enabled && loadedSlots[slot];
  246. clothingToggles[slot].Draw();
  247. if (i < slots.Length - 1)
  248. GUILayout.FlexibleSpace();
  249. }
  250. GUILayout.EndHorizontal();
  251. GUI.enabled = Enabled;
  252. }
  253. private void UpdateDetailedClothing()
  254. {
  255. detailedClothing = detailedClothingToggle.Value;
  256. clothingToggles[SlotID.headset].Label = detailedClothing
  257. ? Translation.Get("clothing", "headset")
  258. : Translation.Get("clothing", "headwear");
  259. UpdatePane();
  260. }
  261. }