internal void Backup() { int _coordinateIndex = ChaControl.fileStatus.coordinateType; List <ChaFileAccessory.PartsInfo> _parts = MoreAccessoriesSupport.ListPartsInfo(ChaControl, _coordinateIndex); PartsInfo.Clear(); PartsResolveInfo.Clear(); for (int i = 0; i < _parts.Count; i++) { ChaFileAccessory.PartsInfo _part = MoreAccessoriesSupport.GetPartsInfo(ChaControl, _coordinateIndex, i); if (_part.type > 120) { byte[] _byte = MessagePackSerializer.Serialize(_part); PartsInfo[i] = MessagePackSerializer.Deserialize <ChaFileAccessory.PartsInfo>(_byte); PartsResolveInfo[i] = UniversalAutoResolver.TryGetResolutionInfo((ChaListDefine.CategoryNo)_part.type, _part.id); } } foreach (string _name in SupportList) { Traverse.Create(this).Field(_name).Method("Backup").GetValue(); } }
internal void AutoCopyCheck() { bool go = true; DebugMsg(LogLevel.Warning, $"[OnCoordinateChanged][{ChaControl.GetFullname()}][CurrentCoordinateIndex: {CurrentCoordinateIndex}]"); if (!AutoCopyToBlank) { go = false; } if (!FunctionEnable) { go = false; } if (ReferralIndex == 7 && PartsInfo.Count == 0) { go = false; } if (ReferralIndex < 7 && ReferralIndex == CurrentCoordinateIndex) { go = false; } if (MakerAPI.InsideAndLoaded && !CfgMakerMasterSwitch.Value) { go = false; } IEnumerator OnCoordinateChangedCoroutine() { DebugMsg(LogLevel.Warning, $"[OnCoordinateChangedCoroutine][{ChaControl.GetFullname()}] fired"); yield return(new WaitForEndOfFrame()); yield return(new WaitForEndOfFrame()); if (MoreAccessoriesSupport.ListUsedPartsInfo(ChaControl, CurrentCoordinateIndex).Count > 0) { yield break; } TaskLock(); if (ReferralIndex < 7) { CopyPartsInfo(); } else { RestorePartsInfo(); } } if (go) { ChaControl.StartCoroutine(OnCoordinateChangedCoroutine()); } }
internal void RestorePartsInfo() { DebugMsg(LogLevel.Warning, $"[RestorePartsInfo][{ChaControl.GetFullname()}] fired"); if (!DuringLoading) { return; } if (!FunctionEnable) { TaskUnlock(); return; } if (PartsInfo.Count == 0) { Logger.LogMessage($"Nothing to restore"); TaskUnlock(); return; } int _coordinateIndex = ChaControl.fileStatus.coordinateType; Dictionary <int, ChaFileAccessory.PartsInfo> RefUsedPartsInfo = MoreAccessoriesSupport.ListUsedPartsInfo(ChaControl, _coordinateIndex); if (RefUsedPartsInfo.Count > 0 && RefUsedPartsInfo.Keys.Min() <= PartsInfo.Keys.Max()) { Logger.LogMessage($"Error: parts overlap [RefUsedPartsInfo.Keys.Min(): {RefUsedPartsInfo.Keys.Min()}][PartsInfo.Keys.Max(): {PartsInfo.Keys.Max()}]"); TaskUnlock(); return; } DebugMsg(LogLevel.Info, $"[RestorePartsInfo][{ChaControl.GetFullname()}][Slots: {string.Join(",", PartsInfo.Keys.Select(Slot => Slot.ToString()).ToArray())}]"); foreach (KeyValuePair <int, ChaFileAccessory.PartsInfo> _part in PartsInfo) { MoreAccessoriesSupport.SetPartsInfo(ChaControl, _coordinateIndex, _part.Key, _part.Value); } if (CharaStudio.Running) { ChaControl.ChangeCoordinateTypeAndReload(false); ChaControl.StartCoroutine(RestorePluginSettingCoroutine()); return; } else { foreach (string _name in SupportList) { Traverse.Create(this).Field(_name).Method("Restore").GetValue(); } ChaControl.StartCoroutine(RefreshCoroutine()); } }
internal IEnumerator RefreshCharaStatePanelCoroutine() { DebugMsg(LogLevel.Warning, $"[RefreshCharaStatePanelCoroutine][{ChaControl.GetFullname()}] fired"); yield return(new WaitForEndOfFrame()); yield return(new WaitForEndOfFrame()); HairAccessoryCustomizer.UpdateAccessories(false); //AccStateSync.SyncAllAccToggle(); CharaStudio.RefreshCharaStatePanel(); MoreAccessoriesSupport.UpdateStudioUI(ChaControl); }
internal void CopyPartsInfo() { DebugMsg(LogLevel.Warning, $"[CopyPartsInfo][{ChaControl.GetFullname()}] fired"); if (!DuringLoading) { TaskUnlock(); return; } if (!FunctionEnable) { TaskUnlock(); return; } if (ReferralIndex == CurrentCoordinateIndex) { TaskUnlock(); return; } List <ChaFileAccessory.PartsInfo> PartsInfo = MoreAccessoriesSupport.ListPartsInfo(ChaControl, ReferralIndex); List <int> SlotIndexes = new List <int>(); for (int i = 0; i < PartsInfo.Count; i++) { if (PartsInfo[i].type > 120) { SlotIndexes.Add(i); } } DebugMsg(LogLevel.Warning, $"[CopyPartsInfo][{ChaControl.GetFullname()}][Slots: {string.Join(",", SlotIndexes.Select(Slot => Slot.ToString()).ToArray())}]"); AccessoryCopyEventArgs ev = new AccessoryCopyEventArgs(SlotIndexes, (ChaFileDefine.CoordinateType)ReferralIndex, (ChaFileDefine.CoordinateType)CurrentCoordinateIndex); MoreAccessoriesSupport.CopyPartsInfo(ChaControl, ev); if (CharaStudio.Running) { ChaControl.ChangeCoordinateTypeAndReload(false); ChaControl.StartCoroutine(CopyPluginSettingCoroutine(ev)); return; } else { foreach (string _name in SupportList) { Traverse.Create(this).Field(_name).Method("CopyPartsInfo", new object[] { ev }).GetValue(); } ChaControl.StartCoroutine(RefreshCoroutine()); } }
private void Start() { CharacterApi.RegisterExtraBehaviour <CharacterAccessoryController>(GUID); HooksInstance["General"] = Harmony.CreateAndPatchAll(typeof(Hooks)); MoreAccessoriesSupport.Init(); HairAccessoryCustomizerSupport.Init(); MaterialEditorSupport.Init(); MaterialRouterSupport.Init(); AccStateSyncSupport.Init(); DynamicBoneEditorSupport.Init(); if (CharaStudio.Running) { HooksInstance["Studio"] = Harmony.CreateAndPatchAll(typeof(HooksStudio)); SceneManager.sceneLoaded += CharaStudio.StartupCheck; } else { MakerAPI.MakerBaseLoaded += (object sender, RegisterCustomControlsEvent ev) => { HooksInstance["Maker"] = Harmony.CreateAndPatchAll(typeof(HooksMaker)); { BepInEx.Bootstrap.Chainloader.PluginInfos.TryGetValue("ClothingStateMenu", out PluginInfo _pluginInfo); if (_pluginInfo?.Instance != null) { HooksInstance["Maker"].Patch(_pluginInfo.Instance.GetType().GetMethod("OnGUI", AccessTools.all), prefix: new HarmonyMethod(typeof(HooksMaker), nameof(HooksMaker.DuringLoading_Prefix))); } } }; MakerAPI.MakerExiting += (object sender, EventArgs ev) => { HooksInstance["Maker"].UnpatchAll(HooksInstance["Maker"].Id); HooksInstance["Maker"] = null; SidebarToggleEnable = null; }; MakerAPI.RegisterCustomSubCategories += RegisterCustomSubCategories; } }
internal void Backup() { if (!_installed) { return; } _charaAccData.Clear(); int _coordinateIndex = _chaCtrl.fileStatus.coordinateType; object _extdataLink = GetExtDataLink(_coordinateIndex); if (_extdataLink == null) { return; } List <int> _slots = Traverse.Create(_extdataLink).Property("Keys").GetValue <ICollection <int> >().ToList(); #if DEBUG DebugMsg(LogLevel.Warning, $"[HairAccessoryCustomizer][Backup][keys: {string.Join(",", _slots.Select(x => x.ToString()).ToArray())}]"); #endif foreach (int _slotIndex in _slots) { if (!MoreAccessoriesSupport.IsHairAccessory(_chaCtrl, _slotIndex)) { continue; } object HairAccessoryInfo = _extdataLink.RefTryGetValue(_slotIndex); if (HairAccessoryInfo == null) { continue; } _charaAccData[_slotIndex] = HairAccessoryInfo.JsonClone(); } }
internal void TransferPartsInfo() { DebugMsg(LogLevel.Warning, $"[TransferPartsInfo][{ChaControl.GetFullname()}] fired"); if (QueueList.Count == 0) { TaskUnlock(); return; } for (int i = 0; i < QueueList.Count; i++) { int srcIndex = QueueList[i].srcSlot; int dstIndex = QueueList[i].dstSlot; DebugMsg(LogLevel.Warning, $"[TransferPartsInfo][{ChaControl.GetFullname()}][{srcIndex}][{dstIndex}]"); AccessoryTransferEventArgs ev = new AccessoryTransferEventArgs(srcIndex, dstIndex); MoreAccessoriesSupport.TransferPartsInfo(ChaControl, ev); MoreAccessoriesSupport.RemovePartsInfo(ChaControl, CurrentCoordinateIndex, srcIndex); foreach (string _name in SupportList) { Traverse.Create(this).Field(_name).Method("TransferPartsInfo", new object[] { ev }).GetValue(); Traverse.Create(this).Field(_name).Method("RemovePartsInfo", new object[] { srcIndex }).GetValue(); } } if (ReferralIndex < 7) { CopyPartsInfo(); } else { ChaControl.ChangeCoordinateTypeAndReload(false); ChaControl.StartCoroutine(RestorePartsInfoCoroutine()); } }
private void RegisterCustomSubCategories(object sender, RegisterSubCategoriesEvent args) { ChaControl _chaCtrl = CustomBase.Instance.chaCtrl; CharacterAccessoryController _pluginCtrl = GetController(_chaCtrl); SidebarToggleEnable = args.AddSidebarControl(new SidebarToggle("CharaAcc", CfgMakerMasterSwitch.Value, this)); SidebarToggleEnable.ValueChanged.Subscribe(value => CfgMakerMasterSwitch.Value = value); MakerCategory category = new MakerCategory("03_ClothesTop", "tglCharaAcc", MakerConstants.Clothes.Copy.Position + 1, "CharaAcc"); args.AddSubCategory(category); args.AddControl(new MakerText("The set to be used as a template to clone on load", category, this)); List <string> coordinateList = Enum.GetNames(typeof(ChaFileDefine.CoordinateType)).ToList(); coordinateList.Add("CharaAcc"); MakerDropdownRef = new MakerDropdown("Referral", coordinateList.ToArray(), category, 0, this); MakerDropdownRef.ValueChanged.Subscribe(value => { _pluginCtrl.SetReferralIndex(value); }); args.AddControl(MakerDropdownRef); MakerToggleEnable = args.AddControl(new MakerToggle(category, "Enable", false, this)); MakerToggleEnable.ValueChanged.Subscribe(value => { _pluginCtrl.FunctionEnable = value; }); MakerToggleAutoCopyToBlank = args.AddControl(new MakerToggle(category, "Auto Copy To Blank", false, this)); MakerToggleAutoCopyToBlank.ValueChanged.Subscribe(value => { _pluginCtrl.AutoCopyToBlank = value; }); args.AddControl(new MakerButton("Backup", category, this)).OnClick.AddListener(delegate { if (_pluginCtrl.DuringLoading) { return; } _pluginCtrl.Backup(); }); args.AddControl(new MakerButton("Restore", category, this)).OnClick.AddListener(delegate { if (_pluginCtrl.DuringLoading) { return; } if (MoreAccessoriesSupport.ListUsedPartsInfo(_chaCtrl, _chaCtrl.fileStatus.coordinateType).Count > 0) { Logger.LogMessage("Please clear the accessories on current coordinate before using this function"); return; } _pluginCtrl.TaskLock(); _pluginCtrl.RestorePartsInfo(); }); args.AddControl(new MakerButton("Reset", category, this)).OnClick.AddListener(delegate { if (_pluginCtrl.DuringLoading) { return; } _pluginCtrl.Reset(); MakerDropdownRef.Value = _pluginCtrl.ReferralIndex; MakerToggleEnable.Value = _pluginCtrl.FunctionEnable; MakerToggleAutoCopyToBlank.Value = _pluginCtrl.AutoCopyToBlank; }); #if DEBUG args.AddControl(new MakerButton("Transfer", category, this)).OnClick.AddListener(delegate { if (_pluginCtrl.DuringLoading) { return; } if (_pluginCtrl.ReferralIndex > 6) { Logger.LogMessage("Please choose a coordinate other than CharaAcc as referral"); return; } _pluginCtrl.TaskLock(); _pluginCtrl.PrepareQueue(); }); args.AddControl(new MakerButton("Hair info (local)", category, this)).OnClick.AddListener(delegate { _pluginCtrl.HairAccessoryCustomizer.DumpInfo(true); }); args.AddControl(new MakerButton("Hair info", category, this)).OnClick.AddListener(delegate { _pluginCtrl.HairAccessoryCustomizer.DumpInfo(false); }); #endif }
internal void PrepareQueue() { QueueList = new List <QueueItem>(); if (ReferralIndex < 0) { TaskUnlock(); return; } if (ReferralIndex < 7 && ReferralIndex == CurrentCoordinateIndex) { TaskUnlock(); return; } int RefLastNotEmpty = -1; if (ReferralIndex < 7) { Dictionary <int, ChaFileAccessory.PartsInfo> RefUsedPartsInfo = MoreAccessoriesSupport.ListUsedPartsInfo(ChaControl, ReferralIndex); RefLastNotEmpty = (RefUsedPartsInfo.Count == 0) ? -1 : RefUsedPartsInfo.Keys.Max(); } else { RefLastNotEmpty = (PartsInfo.Count == 0) ? -1 : PartsInfo.Keys.Max(); } DebugMsg(LogLevel.Warning, $"[PrepareQueue][{ChaControl.GetFullname()}][ReferralIndex: {ReferralIndex}][SrcLastNotEmpty: Slot{RefLastNotEmpty + 1:00}]"); if (RefLastNotEmpty < 0) { TaskUnlock(); return; } Dictionary <int, ChaFileAccessory.PartsInfo> CurUsedPartsInfo = MoreAccessoriesSupport.ListUsedPartsInfo(ChaControl, CurrentCoordinateIndex); if (CurUsedPartsInfo.Count == 0) { if (ReferralIndex < 7) { CopyPartsInfo(); } else { RestorePartsInfo(); } return; } int ToAdd = 0; int shift = 0; int CurFirstNotEmpty = CurUsedPartsInfo.Keys.Min(); int CurLastNotEmpty = CurUsedPartsInfo.Keys.Max(); List <int> UsedParts = CurUsedPartsInfo.Keys.ToList(); List <int> UsedPartsRev = new List <int>(); UsedPartsRev.AddRange(UsedParts); UsedPartsRev.Reverse(); DebugMsg(LogLevel.Warning, $"[PrepareQueue][{ChaControl.GetFullname()}][CurrentCoordinateIndex: {CurrentCoordinateIndex}][CurFirstNotEmpty: Slot{CurFirstNotEmpty + 1:00}][CurLastNotEmpty: Slot{CurLastNotEmpty + 1:00}]"); if (CurFirstNotEmpty <= RefLastNotEmpty) { shift = RefLastNotEmpty - CurFirstNotEmpty + 1; int NewMaxIndex = CurLastNotEmpty + shift; ToAdd = NewMaxIndex - MoreAccessoriesSupport.GetPartsCount(ChaControl, CurrentCoordinateIndex); } if (shift > 0) { foreach (int _slot in UsedPartsRev) { QueueList.Add(new QueueItem(_slot, _slot + shift)); } } if (ToAdd > 0) { MoreAccessoriesSupport.CheckAndPadPartInfo(ChaControl, CurrentCoordinateIndex, CurLastNotEmpty + shift); ChaControl.StartCoroutine(TransferPartsInfoCoroutine()); } else { if (QueueList.Count > 0) { TransferPartsInfo(); } else { if (ReferralIndex < 7) { CopyPartsInfo(); } else { ChaControl.ChangeCoordinateTypeAndReload(false); ChaControl.StartCoroutine(RestorePartsInfoCoroutine()); } } } }