Beispiel #1
0
                internal void Backup()
                {
                    Reset();
                    CharacterAccessoryController _controller = CharacterAccessory.GetController(_chaCtrl);
                    int        _coordinateIndex = _chaCtrl.fileStatus.coordinateType;
                    List <int> _slots           = _controller.PartsInfo.Keys.ToList();

                    foreach (string _key in _containerKeys)
                    {
                        int n = Traverse.Create(_extdataLink[_key]).Property("Count").GetValue <int>();
                        DebugMsg(LogLevel.Warning, $"[MaterialEditor][Backup][{_chaCtrl.GetFullname()}][_extdataLink[{_key}] count: {n}]");

                        for (int i = 0; i < n; i++)
                        {
                            object x = _extdataLink[_key].RefElementAt(i).JsonClone();                             // should I null cheack this?

                            //if (Traverse.Create(x).Field("ObjectType").GetValue<int>() != (int) ObjectType.Accessory) continue;
                            if (Traverse.Create(x).Field("ObjectType").Method("ToString").GetValue <string>() != "Accessory")
                            {
                                continue;
                            }
                            if (Traverse.Create(x).Field("CoordinateIndex").GetValue <int>() != _coordinateIndex)
                            {
                                continue;
                            }
                            if (_slots.IndexOf(Traverse.Create(x).Field("Slot").GetValue <int>()) < 0)
                            {
                                continue;
                            }

                            Traverse.Create(x).Field("CoordinateIndex").SetValue(-1);
                            Traverse.Create(_charaAccData[_key]).Method("Add", new object[] { x }).GetValue();
                        }

                        DebugMsg(LogLevel.Warning, $"[MaterialEditor][Backup][{_chaCtrl.GetFullname()}][_charaAccData[{_key}] count: {Traverse.Create(_charaAccData[_key]).Property("Count").GetValue<int>()}]");
                        //string json = JSONSerializer.Serialize(_charaAccData[_key].GetType(), _charaAccData[_key], true);
                        //DebugMsg(LogLevel.Warning, $"{_charaAccData[_key].GetType()}\n" + json);
                    }

                    object TextureDictionary = Traverse.Create(_pluginCtrl).Field("TextureDictionary").GetValue();

                    foreach (object x in _charaAccData["MaterialTexturePropertyList"] as IList)
                    {
                        int?TexID = Traverse.Create(x).Field("TexID").GetValue <int?>();
                        if (TexID != null)
                        {
                            if (_texData.ContainsKey((int)TexID))
                            {
                                continue;
                            }

                            object _tex = TextureDictionary.RefTryGetValue(TexID);
                            if (_tex != null)
                            {
                                _texData[(int)TexID] = Traverse.Create(_tex).Property("Data").GetValue <byte[]>();
                                DebugMsg(LogLevel.Warning, $"[TexID: {TexID}][Length: {_texData[(int) TexID].Length}]");
                            }
                        }
                    }
                }
Beispiel #2
0
            internal IEnumerator RefreshCoroutine()
            {
                DebugMsg(LogLevel.Warning, $"[RefreshCoroutine][{ChaControl.GetFullname()}] fired");

                yield return(new WaitForEndOfFrame());

                yield return(new WaitForEndOfFrame());

                TaskUnlock();

                if (CharaStudio.Running)
                {
                    if (CfgStudioFallbackReload.Value)
                    {
                        BigReload();
                    }
                    else
                    {
                        FastReload();
                    }
                }
                else
                {
                    ChaControl.ChangeCoordinateTypeAndReload(false);

                    if (MakerAPI.InsideAndLoaded)
                    {
                        CustomBase.Instance.updateCustomUI = true;
                    }
                }
                ChaControl.StartCoroutine(PreviewCoroutine());
            }
Beispiel #3
0
                internal List <string> Save()
                {
                    if (!_installed)
                    {
                        return(null);
                    }
                    List <string> _json = new List <string>();

                    foreach (object x in _charaAccData)
                    {
                        _json.Add(JSONSerializer.Serialize(_types["DynamicBoneData"], x));
                    }
#if DEBUG
                    DebugMsg(LogLevel.Debug, $"[DynamicBoneEditor][Save][{_chaCtrl.GetFullname()}]\n{JSONSerializer.Serialize(_json.GetType(), _json, true)}");
#endif
                    return(_json);
                }
Beispiel #4
0
            internal void SetReferralIndex(int _index)
            {
                DebugMsg(LogLevel.Warning, $"[SetReferralIndex][{ChaControl.GetFullname()}][_index: {_index}]");

                if (ReferralIndex != _index)
                {
                    ReferralIndex = MathfEx.RangeEqualOn(0, _index, RefMax) ? _index : RefMax;
                }
            }
Beispiel #5
0
            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());
                }
            }
Beispiel #6
0
            internal IEnumerator CopyPluginSettingCoroutine(AccessoryCopyEventArgs ev)
            {
                DebugMsg(LogLevel.Warning, $"[CopyPluginSettingCoroutine][{ChaControl.GetFullname()}] fired");

                yield return(new WaitForEndOfFrame());

                yield return(new WaitForEndOfFrame());

                CopyPluginSetting(ev);
            }
Beispiel #7
0
            internal IEnumerator TransferPartsInfoCoroutine()
            {
                DebugMsg(LogLevel.Warning, $"[TransferPartsInfoCoroutine][{ChaControl.GetFullname()}] fired");

                yield return(new WaitForEndOfFrame());

                yield return(new WaitForEndOfFrame());

                TransferPartsInfo();
            }
Beispiel #8
0
            internal IEnumerator RestorePluginSettingCoroutine()
            {
                DebugMsg(LogLevel.Warning, $"[RestorePluginSettingCoroutine][{ChaControl.GetFullname()}] fired");

                yield return(new WaitForEndOfFrame());

                yield return(new WaitForEndOfFrame());

                RestorePluginSetting();
            }
Beispiel #9
0
            internal void CopyPluginSetting(AccessoryCopyEventArgs ev)
            {
                DebugMsg(LogLevel.Warning, $"[CopyPluginSetting][{ChaControl.GetFullname()}] fired");

                foreach (string _name in SupportList)
                {
                    Traverse.Create(this).Field(_name).Method("CopyPartsInfo", new object[] { ev }).GetValue();
                }

                ChaControl.StartCoroutine(RefreshCoroutine());
            }
                internal Dictionary <int, string> Save()
                {
                    if (!_installed)
                    {
                        return(null);
                    }

                    Dictionary <int, string> _json = new Dictionary <int, string>();

                    foreach (KeyValuePair <int, object> x in _charaAccData)
                    {
                        FakeHairAccessoryInfo _info = new FakeHairAccessoryInfo(x.Value);
                        _json[x.Key] = JSONSerializer.Serialize(typeof(FakeHairAccessoryInfo), _info);
#if DEBUG
                        DebugMsg(LogLevel.Debug, $"[HairAccessoryCustomizer][Save][{_chaCtrl.GetFullname()}][{x.Key}]\n{DisplayObjectInfo(_info)}\n\n");
#endif
                    }

                    return(_json);
                }
Beispiel #11
0
            internal IEnumerator OnCoordinateBeingLoadedCoroutine()
            {
                DebugMsg(LogLevel.Warning, $"[OnCoordinateBeingLoadedCoroutine][{ChaControl.GetFullname()}] fired");

                yield return(new WaitForEndOfFrame());

                yield return(new WaitForEndOfFrame());

                TaskLock();
                PrepareQueue();
            }
Beispiel #12
0
            internal void RestorePluginSetting()
            {
                DebugMsg(LogLevel.Warning, $"[RestorePluginSetting][{ChaControl.GetFullname()}] fired");

                foreach (string _name in SupportList)
                {
                    Traverse.Create(this).Field(_name).Method("Restore").GetValue();
                }

                ChaControl.StartCoroutine(RefreshCoroutine());
            }
Beispiel #13
0
            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());
                }
            }
Beispiel #14
0
            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);
            }
Beispiel #15
0
            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());
                }
            }
Beispiel #16
0
            internal static bool DuringLoading_Prefix(CharaCustomFunctionController __instance)
            {
                ChaControl _chaCtrl = __instance.ChaControl;
                CharacterAccessoryController _pluginCtrl = GetController(_chaCtrl);

                if (_pluginCtrl.DuringLoading)
                {
#if DEBUG
                    DebugMsg(LogLevel.Warning, $"[DuringLoading_Prefix][{_chaCtrl.GetFullname()}] await loading");
#endif
                    return(false);
                }
                return(true);
            }
Beispiel #17
0
            internal IEnumerator PreviewCoroutine()
            {
                DebugMsg(LogLevel.Warning, $"[PreviewCoroutine][{ChaControl.GetFullname()}] fired");

                yield return(new WaitForEndOfFrame());

                yield return(new WaitForEndOfFrame());

                AccStateSync.InitCurOutfitTriggerInfo("OnCoordinateBeingLoaded");

                if (CharaStudio.Loaded)
                {
                    ChaControl.StartCoroutine(RefreshCharaStatePanelCoroutine());
                }
            }
Beispiel #18
0
            protected override void OnCoordinateBeingLoaded(ChaFileCoordinate _coordinate)
            {
                TaskUnlock();
                bool go = true;

                DebugMsg(LogLevel.Warning, $"[OnCoordinateBeingLoaded][{ChaControl.GetFullname()}][FunctionEnable: {FunctionEnable}][ReferralIndex: {ReferralIndex}][PartsInfo.Count: {PartsInfo.Count}]");

                if (!FunctionEnable)
                {
                    go = false;
                }
                if (ReferralIndex == 7 && PartsInfo.Count == 0)
                {
                    go = false;
                }
                if (MakerAPI.InsideAndLoaded && !CfgMakerMasterSwitch.Value)
                {
                    go = false;
                }

                CoordinateLoadFlags _loadFlags = MakerAPI.GetCoordinateLoadFlags();

                if (MakerAPI.InsideAndLoaded && _loadFlags != null && !_loadFlags.Accessories)
                {
                    go = false;
                }

                if (go)
                {
                    TaskLock();
                    ChaControl.StartCoroutine(OnCoordinateBeingLoadedCoroutine());
                }
                else
                {
                    if (MakerAPI.InsideAndLoaded)
                    {
                        CustomBase.Instance.updateCustomUI = true;
                    }
                }
                base.OnCoordinateBeingLoaded(_coordinate);
            }
Beispiel #19
0
            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());
                }
            }
Beispiel #20
0
                internal static bool ChaControl_UpdateVisible_Patches_Prefix(ChaControl __0)
                {
                    CharacterAccessoryController _pluginCtrl = GetController(__0);

                    if (_pluginCtrl == null)
                    {
                        return(true);
                    }

                    if (_pluginCtrl.DuringLoading)
                    {
#if DEBUG
                        DebugMsg(LogLevel.Warning, $"[ChaControl_UpdateVisible_Patches_Prefix][{__0.GetFullname()}] await loading");
#endif
                        return(false);
                    }
                    return(true);
                }
Beispiel #21
0
            protected override void OnReload(GameMode currentGameMode)
            {
                TaskUnlock();

                PluginData ExtendedData = GetExtendedData();

                PartsInfo.Clear();
                PartsResolveInfo.Clear();
                FunctionEnable  = false;
                AutoCopyToBlank = false;
                ReferralIndex   = RefMax;
                MaterialEditor.Reset();

                if (ExtendedData != null)
                {
                    if (ExtendedData.data.TryGetValue("MoreAccessoriesExtdata", out object loadedMoreAccessoriesExtdata) && loadedMoreAccessoriesExtdata != null)
                    {
                        PartsInfo = MessagePackSerializer.Deserialize <Dictionary <int, ChaFileAccessory.PartsInfo> >((byte[])loadedMoreAccessoriesExtdata);
                    }
                    if (ExtendedData.data.TryGetValue("ResolutionInfoExtdata", out object loadedResolutionInfoExtdata) && loadedResolutionInfoExtdata != null)
                    {
                        PartsResolveInfo = MessagePackSerializer.Deserialize <Dictionary <int, ResolveInfo> >((byte[])loadedResolutionInfoExtdata);
                    }

                    foreach (string _name in SupportList)
                    {
                        if (ExtendedData.data.TryGetValue($"{_name}Extdata", out object loadedExtdata) && loadedExtdata != null)
                        {
                            if (_name == "HairAccessoryCustomizer")
                            {
                                Traverse.Create(this).Field(_name).Method("Load", new object[] { MessagePackSerializer.Deserialize <Dictionary <int, string> >((byte[])loadedExtdata) }).GetValue();
                            }
                            else if (_name == "AccStateSync")
                            {
                                if (ExtendedData.version < 2)
                                {
                                    Traverse.Create(this).Field(_name).Method("Migrate", new object[] { MessagePackSerializer.Deserialize <Dictionary <int, string> >((byte[])loadedExtdata) }).GetValue();
                                }
                                else
                                {
                                    Traverse.Create(this).Field(_name).Method("Load", new object[] { MessagePackSerializer.Deserialize <Dictionary <string, string> >((byte[])loadedExtdata) }).GetValue();
                                }
                            }
                            else if (_name == "MaterialEditor")
                            {
                                Traverse.Create(this).Field(_name).Method("Load", new object[] { MessagePackSerializer.Deserialize <Dictionary <string, string> >((byte[])loadedExtdata) }).GetValue();
                            }
                            else if ((_name == "MaterialRouter") || (_name == "DynamicBoneEditor"))
                            {
                                Traverse.Create(this).Field(_name).Method("Load", new object[] { MessagePackSerializer.Deserialize <List <string> >((byte[])loadedExtdata) }).GetValue();
                            }
                        }
                    }

                    if (ExtendedData.data.TryGetValue("FunctionEnable", out object loadedFunctionEnable) && loadedFunctionEnable != null)
                    {
                        FunctionEnable = (bool)loadedFunctionEnable;
                    }
                    if (ExtendedData.data.TryGetValue("AutoCopyToBlank", out object loadedAutoCopyToBlank) && loadedAutoCopyToBlank != null)
                    {
                        AutoCopyToBlank = (bool)loadedAutoCopyToBlank;
                    }

                    if (ExtendedData.data.TryGetValue("ReferralIndex", out object loadedReferralIndex) && loadedReferralIndex != null)
                    {
                        SetReferralIndex((int)loadedReferralIndex);
                    }
                    if (ExtendedData.data.TryGetValue("TextureContainer", out object loadedTextureContainer) && loadedTextureContainer != null)
                    {
                        MaterialEditor.TexContainer = MessagePackSerializer.Deserialize <Dictionary <int, byte[]> >((byte[])loadedTextureContainer);
                    }

                    foreach (KeyValuePair <int, ChaFileAccessory.PartsInfo> _part in PartsInfo)
                    {
                        if (!PartsResolveInfo.ContainsKey(_part.Key))
                        {
                            continue;
                        }
                        if (PartsResolveInfo[_part.Key] == null)
                        {
                            continue;
                        }

                        ResolveInfo _info = PartsResolveInfo[_part.Key];
                        MigrateData(ref _info);

                        if (_info != null)
                        {
                            if (!_info.GUID.IsNullOrEmpty())
                            {
                                _info = UniversalAutoResolver.TryGetResolutionInfo(PartsResolveInfo[_part.Key].Slot, PartsResolveInfo[_part.Key].CategoryNo, PartsResolveInfo[_part.Key].GUID);
                            }
                            PartsResolveInfo[_part.Key] = _info.JsonClone() as ResolveInfo;
                            _part.Value.id = _info.LocalSlot;
                        }
                        else
                        {
                            PartsResolveInfo[_part.Key] = null;
                        }
                    }
                }

                if (MakerAPI.InsideAndLoaded)
                {
                    MakerToggleEnable.Value          = FunctionEnable;
                    MakerToggleAutoCopyToBlank.Value = AutoCopyToBlank;
                    MakerDropdownRef.Value           = ReferralIndex;
                }

                IEnumerator OnReloadCoroutine()
                {
                    DebugMsg(LogLevel.Warning, $"[OnReloadCoroutine][{ChaControl.GetFullname()}] fired");

                    yield return(new WaitForEndOfFrame());

                    yield return(new WaitForEndOfFrame());

                    AutoCopyCheck();
                }

                ChaControl.StartCoroutine(OnReloadCoroutine());

                base.OnReload(currentGameMode);
            }
Beispiel #22
0
            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());
                        }
                    }
                }
            }