Exemple #1
0
        /// <summary>
        /// 將dict存入ChaControl ExtendedData
        /// </summary>
        /// <param name="chaCtrl">目標ChaControl</param>
        /// <param name="dict">要存入的dict</param>
        public static void SetToExtData(ChaControl chaCtrl, Dictionary <int, object> dict)
        {
            PluginData data = new PluginData();
            Dictionary <int, Dictionary <int, object> > allExtData = GetDataFromExtData(chaCtrl, out _);
            int coorType = chaCtrl.fileStatus.coordinateType;

            if ((null == dict || dict.Count == 0) && (null == allExtData || allExtData.Count == 0))
            {
                data = null;
            }
            else
            {
                if (null == allExtData)
                {
                    allExtData = new Dictionary <int, Dictionary <int, object> >();
                    Logger.LogDebug($"HairAccCustomizer info not found while saving.");
                }
                if (allExtData.ContainsKey(coorType))
                {
                    allExtData[coorType].Clear();
                    allExtData.Remove(coorType);
                }
                if (null != dict)
                {
                    allExtData[coorType] = dict;
                }
                data.data.Add("HairAccessories", MessagePackSerializer.Serialize(allExtData));
            }
            ExtendedSave.SetExtendedDataById(chaCtrl.chaFile, GUID, data);
        }
        private static void AddPregnancyWeek(ChaFileControl chaFile)
        {
            var data = ExtendedSave.GetExtendedDataById(chaFile, PregnancyPlugin.GUID);

            if (data == null)
            {
                return;
            }

            PregnancyDataUtils.DeserializeData(data, out var week, out var gameplayEnabled, out var fertility, out var schedule);
            // Advance the week of pregnancy. If week is 0 the character is not pregnant
            if (gameplayEnabled && week > 0)
            {
                if (week < PregnancyDataUtils.LeaveSchoolWeek)
                {
                    // Advance through in-school at full configured speed
                    var weekChange = PregnancyPlugin.PregnancyProgressionSpeed.Value;
                    week = Mathf.Min(PregnancyDataUtils.LeaveSchoolWeek, week + weekChange);
                }
                else if (week < PregnancyDataUtils.ReturnToSchoolWeek)
                {
                    // Make sure at least one week is spent out of school
                    var weekChange = Mathf.Min(PregnancyDataUtils.ReturnToSchoolWeek - PregnancyDataUtils.LeaveSchoolWeek - 1, PregnancyPlugin.PregnancyProgressionSpeed.Value);
                    week = week + weekChange;
                }

                if (week >= PregnancyDataUtils.ReturnToSchoolWeek)
                {
                    week = 0;
                }

                //Logger.Log(LogLevel.Debug, $"Preg - pregnancy week for {chaFile.parameter.fullname} is now {week}");
                ExtendedSave.SetExtendedDataById(chaFile, PregnancyPlugin.GUID, PregnancyDataUtils.SerializeData(week, true, fertility, schedule));
            }
        }
        private static void ExtendedSceneSave(string path)
        {
            try
            {
                Dictionary <string, object>    ExtendedData = new Dictionary <string, object>();
                List <AnimationControllerInfo> AnimationControllerInfoList = new List <AnimationControllerInfo>();

                foreach (var IKObj in IKObjectInfoList)
                {
                    AnimationControllerInfoList.Add(new AnimationControllerInfo {
                        CharDicKey = IKObj.CharacterKey, ItemDicKey = IKObj.ObjectKey, IKPart = IKObj.IKPart
                    });
                }

                if (AnimationControllerInfoList.Count == 0)
                {
                    ExtendedSave.SetSceneExtendedDataById(PluginName, null);
                }
                else
                {
                    ExtendedData.Add("AnimationInfo", AnimationControllerInfoList.Select(x => x.Serialize()).ToList());
                    ExtendedSave.SetSceneExtendedDataById(PluginName, new PluginData {
                        data = ExtendedData
                    });
                }
                Logger.Log(LogLevel.Debug, "Saved KK_AnimationController animations");
            }
            catch (Exception ex)
            {
                Logger.Log(LogLevel.Error | LogLevel.Message, "Could not save KK_AnimationController animations.");
                Logger.Log(LogLevel.Error, ex.ToString());
            }
        }
        /// <summary>
        /// Scene has to be fully loaded for all characters and objects to exist in the game
        /// </summary>
        private void SceneLoaded(Scene s, LoadSceneMode lsm)
        {
            if (s.name == "StudioNotification" && LoadClicked)
            {
                LoadClicked = false;

                try
                {
                    IKObjectInfoList.Clear();
                    PluginData ExtendedData = ExtendedSave.GetSceneExtendedDataById(PluginName);

                    if (ExtendedData != null && ExtendedData.data.ContainsKey("AnimationInfo"))
                    {
                        List <AnimationControllerInfo> AnimationControllerInfoList;

                        AnimationControllerInfoList = ((object[])ExtendedData.data["AnimationInfo"]).Select(x => AnimationControllerInfo.Unserialize((byte[])x)).ToList();

                        foreach (var AnimInfo in AnimationControllerInfoList)
                        {
                            IKObjectInfo LoadedAnimInfo = new IKObjectInfo();

                            var Character = Singleton <Studio.Studio> .Instance.dicObjectCtrl.Where(x => x.Key == AnimInfo.CharDicKey).Select(x => x.Value as OCIChar).First();

                            LoadedAnimInfo.CharacterKey    = AnimInfo.CharDicKey;
                            LoadedAnimInfo.CharacterObject = GameObject.Find(Character.charInfo.name);
                            LoadedAnimInfo.IKPart          = AnimInfo.IKPart;
                            LoadedAnimInfo.IKTarget        = Character.listIKTarget.Where(x => x.boneObject.name == AnimInfo.IKPart).First();

                            var LinkedItem = Singleton <Studio.Studio> .Instance.dicObjectCtrl.Where(x => x.Key == AnimInfo.ItemDicKey).Select(x => x.Value).First();

                            switch (LinkedItem)
                            {
                            case OCIItem Item:
                                LoadedAnimInfo.ObjectKey      = Item.objectInfo.dicKey;
                                LoadedAnimInfo.SelectedObject = Item.childRoot.gameObject;
                                break;

                            case OCIFolder Folder:
                                LoadedAnimInfo.ObjectKey      = Folder.objectInfo.dicKey;
                                LoadedAnimInfo.SelectedObject = Folder.childRoot.gameObject;
                                break;

                            case OCIRoute Route:
                                LoadedAnimInfo.ObjectKey      = Route.objectInfo.dicKey;
                                LoadedAnimInfo.SelectedObject = Route.childRoot.gameObject;
                                break;
                            }

                            IKObjectInfoList.Add(LoadedAnimInfo);
                        }
                    }
                    Logger.Log(LogLevel.Debug, "Loaded KK_AnimationController animations");
                }
                catch (Exception ex)
                {
                    Logger.Log(LogLevel.Error | LogLevel.Message, "Could not load KK_AnimationController animations.");
                    Logger.Log(LogLevel.Error, ex.ToString());
                }
            }
        }
        /// <summary>
        /// Save your custom data to the character card under the ID you specified when registering this controller.
        /// This should be used inside the <see cref="OnCardBeingSaved"/> event.
        /// Consider using one of the other "Get___ExtData" and "Set___ExtData" methods instead since they are more reliable and handle copying and transferring outfits and they conform to built in maker load toggles.
        /// </summary>
        /// <param name="data">Your custom data to be written to the character card. Can be null to remove the data.</param>
        public void SetExtendedData(PluginData data)
        {
            if (ExtendedDataId == null)
            {
                throw new ArgumentException(nameof(ExtendedDataId));
            }
            ExtendedSave.SetExtendedDataById(ChaFileControl, ExtendedDataId, data);

#if KK //todo || KKS
            // Needed for propagating changes back to the original charFile since they don't get copied back.
            var heroine = ChaControl.GetHeroine();
            if (heroine != null)
            {
                ExtendedSave.SetExtendedDataById(heroine.charFile, ExtendedDataId, data);

                if (ChaControl != heroine.chaCtrl)
                {
                    ExtendedSave.SetExtendedDataById(heroine.chaCtrl.chaFile, ExtendedDataId, data);

                    // Update other instance to reflect the new ext data
                    var other = heroine.chaCtrl.GetComponent(GetType()) as CharaCustomFunctionController;
                    if (other != null)
                    {
                        other.OnReloadInternal(KoikatuAPI.GetCurrentGameMode());
                    }
                }

                var npc = heroine.GetNPC();
                if (npc != null && npc.chaCtrl != null && npc.chaCtrl != ChaControl)
                {
                    ExtendedSave.SetExtendedDataById(npc.chaCtrl.chaFile, ExtendedDataId, data);

                    // Update other instance to reflect the new ext data
                    var other = npc.chaCtrl.GetComponent(GetType()) as CharaCustomFunctionController;
                    if (other != null)
                    {
                        other.OnReloadInternal(KoikatuAPI.GetCurrentGameMode());
                    }
                }
            }

            var player = ChaControl.GetPlayer();
            if (player != null)
            {
                ExtendedSave.SetExtendedDataById(player.charFile, ExtendedDataId, data);

                if (ChaControl != player.chaCtrl)
                {
                    ExtendedSave.SetExtendedDataById(player.chaCtrl.chaFile, ExtendedDataId, data);

                    // Update other instance to reflect the new ext data
                    var other = player.chaCtrl.GetComponent(GetType()) as CharaCustomFunctionController;
                    if (other != null)
                    {
                        other.OnReloadInternal(KoikatuAPI.GetCurrentGameMode());
                    }
                }
            }
#endif
        }
        private static void ApplyToAllDatas(Func<AgentData, PregnancyData, bool> action)
        {
            void ApplyToDatas(AgentData character)
                {
                    var chafiles = character.GetRelatedChaFiles();
                    if (chafiles == null) return;

                    foreach (var chaFile in chafiles)
                    {
                        var data = ExtendedSave.GetExtendedDataById(chaFile, PregnancyPlugin.GUID);
                        var pd = PregnancyData.Load(data) ?? new PregnancyData();
                        if (action(character, pd))
                            ExtendedSave.SetExtendedDataById(chaFile, PregnancyPlugin.GUID, pd.Save());
                    }
                }

                var heroineList = GetHeroineList();
                if (heroineList == null) return;

                foreach (var heroine in heroineList)
                {
                    ApplyToDatas(heroine);
                }
                // ApplyToDatas(Singleton<Map>.Instance.Player.AgentPartner.AgentData);  TODO find male AgentData, if we want to match what KK is now doing

                // If controller exists then update its state so it gets any pregnancy week updates
                foreach (var controller in FindObjectsOfType<PregnancyCharaController>())
                    controller.ReadData();
        }
 // Token: 0x06000006 RID: 6 RVA: 0x000020F8 File Offset: 0x000002F8
 private static void ExtendedSceneLoadInUpdate()
 {
     try
     {
         Logger.Log(LogLevel.Info, "Start loading VMDPlay info from scene data.");
         object obj;
         if (ExtendedSave.GetSceneExtendedDataById("KKVMDPlayExtSave").data.TryGetValue("xml", out obj))
         {
             if (obj != null && obj is byte[])
             {
                 Logger.Log(LogLevel.Info, string.Format("Found VMDPlay info XML data: {0}", ((byte[])obj).Length));
                 MemoryStream inStream = new MemoryStream((byte[])obj);
                 Console.WriteLine("ExtSave: Loading from PNG.");
                 XmlDocument xmlDocument = new XmlDocument();
                 xmlDocument.Load(inStream);
                 Console.WriteLine(xmlDocument.ToString());
                 KKVMDPlayExtSavePlugin.OnLoad(xmlDocument.DocumentElement);
             }
             else
             {
                 Logger.Log(LogLevel.Message, "Data not found.");
             }
         }
         else
         {
             Logger.Log(LogLevel.Message, "Data not found.");
         }
     }
     catch (Exception ex)
     {
         Logger.Log(LogLevel.Error, string.Format("Failed to load data. {0}", ex.StackTrace));
     }
 }
Exemple #8
0
            internal static void ExtendedHousingLoad(CraftInfo info)
            {
                if (info == null)
                {
                    return; // TODO: check if this case needs debug logging message.
                }
                if (Sideloader.DebugLoggingResolveInfo.Value)
                {
                    Sideloader.Logger.LogInfo($"Resolving Extended Save Game");
                }

                PluginData ExtendedData = ExtendedSave.GetExtendedDataById(info, UARExtID);

                if (ExtendedData != null)
                {
                    var ResolvedInfo = ((Dictionary <int, byte[]>)ExtendedData.data[mapItemInfoKey]);
                    int index        = 0;
                    HousingObjectIteration(info.ObjectInfos, ref index, (item, i) =>
                    {
                        if (!ResolvedInfo.TryGetValue(i, out byte[] bytes))
                        {
                            return;
                        }
                        var extResolve = AIGameResolveInfo.Deserialize(bytes);
                        if (extResolve == null)
                        {
                            return;
                        }
                        item.ID = extResolve.Slot;
                        ResolveHousingFurniture(extResolve, item);
                    });
Exemple #9
0
            private static void ExtendedWorldLoad(WorldData worldData)
            {
                if (worldData == null)
                {
                    return;
                }

                var extResolve = ExtendedSave.GetExtendedDataById(worldData, UARExtID);

                if (extResolve == null)
                {
                    return;
                }

                foreach (var dataPair in extResolve.data)
                {
                    if (int.TryParse(dataPair.Key, out int id) &&
                        worldData.HousingData.CraftInfos.TryGetValue(id, out var craftInfo) &&
                        dataPair.Value is Dictionary <string, object> extData)
                    {
                        ExtendedSave.SetExtendedDataById(craftInfo, UARExtID, new PluginData()
                        {
                            data = extData
                        });
                        ExtendedHousingLoad(craftInfo);
                    }
                }
            }
Exemple #10
0
        private static void ExtendedSceneLoad(string path)
        {
            PluginData ExtendedData = ExtendedSave.GetSceneExtendedDataById(UniversalAutoResolver.UARExtID);

            UniversalAutoResolver.ResolveStudioObjects(ExtendedData, UniversalAutoResolver.ResolveType.Load);
            UniversalAutoResolver.ResolveStudioMap(ExtendedData, UniversalAutoResolver.ResolveType.Load);
        }
Exemple #11
0
        private static void ExtendedCardLoad(ChaFile file)
        {
            Logger.Log(LogLevel.Debug, $"Loading card [{file.charaFileName}]");

            var extData = ExtendedSave.GetExtendedDataById(file, UniversalAutoResolver.UARExtID);
            List <ResolveInfo> extInfo;

            if (extData == null || !extData.data.ContainsKey("info"))
            {
                Logger.Log(LogLevel.Debug, "No sideloader marker found");
                extInfo = null;
            }
            else
            {
                var tmpExtInfo = (object[])extData.data["info"];
                extInfo = tmpExtInfo.Select(x => ResolveInfo.Unserialize((byte[])x)).ToList();

                Logger.Log(LogLevel.Debug, "Sideloader marker found");
                Logger.Log(LogLevel.Debug, $"External info count: {extInfo.Count}");
                foreach (ResolveInfo info in extInfo)
                {
                    Logger.Log(LogLevel.Debug, $"External info: {info.GUID} : {info.Property} : {info.Slot}");
                }
            }

            IterateCardPrefixes(UniversalAutoResolver.ResolveStructure, file, extInfo);
        }
Exemple #12
0
        private void ExtendedSave_PoseBeingSaved(string poseName, PauseCtrl.FileInfo fileInfo, OCIChar ociChar, ExtendedSave.GameNames gameName)
        {
            var data = new PluginData();

            //Facial expression
#if PH
            data.data.Add(EyesPatternData, ociChar.charStatus.eyesPtn);
            data.data.Add(MouthPatternData, ociChar.charStatus.mouthPtn);
            data.data.Add(EyeOpenData, ociChar.charStatus.eyesOpenMax);
            data.data.Add(MouthOpenData, ociChar.oiCharInfo.mouthOpen);
#else
            data.data.Add(EyebrowPatternData, ociChar.charFileStatus.eyebrowPtn);
            data.data.Add(EyesPatternData, ociChar.charFileStatus.eyesPtn);
            data.data.Add(MouthPatternData, ociChar.charFileStatus.mouthPtn);
            data.data.Add(EyeOpenData, ociChar.charFileStatus.eyesOpenMax);
            data.data.Add(MouthOpenData, ociChar.oiCharInfo.mouthOpen);
#endif

            //Only save skirt FK if enabled
            if (ociChar.oiCharInfo.activeFK[SkirtFKIndex])
            {
                Dictionary <int, Vector3> skirtFK = new Dictionary <int, Vector3>();
                foreach (KeyValuePair <int, OIBoneInfo> item2 in ociChar.oiCharInfo.bones.Where(b => (OIBoneInfo.BoneGroup.Skirt & b.Value.group) != 0))
                {
                    skirtFK.Add(item2.Key, item2.Value.changeAmount.rot);
                }
                data.data.Add(SkirtFKData, MessagePackSerializer.Serialize(skirtFK));
            }

            //Joint correction
            data.data.Add(JointCorrectionData, MessagePackSerializer.Serialize(ociChar.oiCharInfo.expression));

            ExtendedSave.SetPoseExtendedDataById(PoseToolsData, data);
        }
Exemple #13
0
        /// <summary>
        /// Card saving
        /// </summary>
        private void ExtendedCardSave(ChaFile file)
        {
            PluginData ExtendedData = ExtendedSave.GetExtendedDataById(file, "KK_FutaMod");

            if (ExtendedData != null && ExtendedData.data.ContainsKey("Futa"))
            {
                if (Singleton <CustomBase> .IsInstance() && Singleton <CustomBase> .Instance.chaCtrl != null)
                {
                    //Saving card from chara maker, get the status from the character
                    ExtendedData.data["Futa"] = file.status.visibleSonAlways;
                    ExtendedSave.SetExtendedDataById(file, "KK_FutaMod", ExtendedData);
                }
                else
                {
                    //Not in chara maker, keep the existing extended data
                    ExtendedSave.SetExtendedDataById(file, "KK_FutaMod", ExtendedData);
                }
            }
            else
            {
                if (Singleton <CustomBase> .IsInstance() && Singleton <CustomBase> .Instance.chaCtrl != null)
                {
                    //Saving a character in chara maker that doesn't have extended data
                    ExtendedData      = new PluginData();
                    ExtendedData.data = new Dictionary <string, object> {
                        { "Futa", file.status.visibleSonAlways }
                    };
                    ExtendedSave.SetExtendedDataById(file, "KK_FutaMod", ExtendedData);
                }
            }
        }
Exemple #14
0
        /// <summary>
        /// Attempt to import old KK_CharaOverlaysBasedOnCoordinate data.
        /// Based on code from https://github.com/jim60105/KK/blob/99dd9a055679cea8bf2c7d85a357ca53c4233636/KK_CharaOverlaysBasedOnCoordinate/KK_CharaOverlaysBasedOnCoordinate.cs
        /// </summary>
        private bool TryImportCOBOC()
        {
#if KK || KKS
            var data = ExtendedSave.GetExtendedDataById(ChaFileControl, "com.jim60105.kk.charaoverlaysbasedoncoordinate");
            if (data == null)
            {
                return(false);
            }

            KoiSkinOverlayMgr.Logger.LogInfo("[Import] Trying to import KK_CharaOverlaysBasedOnCoordinate data.");

            Dictionary <TKey, TValue> ToDictionary <TKey, TValue>(object self)
            {
                if (!(self is IDictionary dictionary))
                {
                    KoiSkinOverlayMgr.Logger.LogWarning($"[Import] Failed to cast to Dictionary! Likely invalid data.");
                    return(null);
                }

                return(CastDict(dictionary).ToDictionary(entry => (TKey)entry.Key, entry => (TValue)entry.Value));

                IEnumerable <DictionaryEntry> CastDict(IDictionary dic)
                {
                    foreach (DictionaryEntry entry in dic)
                    {
                        yield return(entry);
                    }
                }
            }

            if ((!data.data.TryGetValue("AllCharaOverlayTable", out var tmpOverlayTable) || tmpOverlayTable == null) ||
                (!data.data.TryGetValue("AllCharaResources", out var tmpResources) || null == tmpResources))
            {
                KoiSkinOverlayMgr.Logger.LogWarning("[Import] Wrong PluginData version, can't import.");
            }
            internal static void ChaFileCoordinateSaveFilePostHook(ChaFileCoordinate __instance, string path)
            {
                if (DoingImport)
                {
                    return;
                }

                Sideloader.Logger.LogDebug($"Reloading coordinate [{path}]");

                var extData = ExtendedSave.GetExtendedDataById(__instance, UARExtIDOld) ?? ExtendedSave.GetExtendedDataById(__instance, UARExtID);

                var tmpExtInfo = (List <byte[]>)extData.data["info"];
                var extInfo    = tmpExtInfo.Select(ResolveInfo.Deserialize).ToList();

                Sideloader.Logger.LogDebug($"External info count: {extInfo.Count}");

                if (Sideloader.DebugLogging.Value)
                {
                    foreach (ResolveInfo info in extInfo)
                    {
                        Sideloader.Logger.LogDebug($"External info: {info.GUID} : {info.Property} : {info.Slot}");
                    }
                }

                void ResetStructResolveStructure(Dictionary <CategoryProperty, StructValue <int> > propertyDict, object structure, IEnumerable <ResolveInfo> extInfo2, string propertyPrefix = "")
                {
                    foreach (var kv in propertyDict)
                    {
                        var extResolve = extInfo.FirstOrDefault(x => x.Property == $"{propertyPrefix}{kv.Key.ToString()}");

                        if (extResolve != null)
                            kv.Value.SetMethod(structure, extResolve.LocalSlot); }
                    }
                }
Exemple #16
0
        protected override void OnCardBeingSaved(GameMode currentGameMode)
        {
            var pd = new PluginData {
                version = 2
            };

            OverlayStorage.Save(pd);

#if !EC
            if (!EnableInStudioSkin)
            {
                pd.data[nameof(EnableInStudioSkin)] = EnableInStudioSkin;
            }
            if (!EnableInStudioIris)
            {
                pd.data[nameof(EnableInStudioIris)] = EnableInStudioIris;
            }
#endif

            SetExtendedData(pd.data.Count > 0 ? pd : null);

#if KK || KKS
            ExtendedSave.SetExtendedDataById(ChaFileControl, "com.jim60105.kk.charaoverlaysbasedoncoordinate", null);
#endif
        }
            internal static void ExtendedCardLoad(ChaFile file)
            {
                Sideloader.Logger.LogDebug($"Loading card [{file.charaFileName}]");

                var extData = ExtendedSave.GetExtendedDataById(file, UARExtIDOld) ?? ExtendedSave.GetExtendedDataById(file, UARExtID);
                List <ResolveInfo> extInfo;

                if (extData == null || !extData.data.ContainsKey("info"))
                {
                    Sideloader.Logger.LogDebug("No sideloader marker found");
                    extInfo = null;
                }
                else
                {
                    var tmpExtInfo = (object[])extData.data["info"];
                    extInfo = tmpExtInfo.Select(x => ResolveInfo.Deserialize((byte[])x)).ToList();

                    Sideloader.Logger.LogDebug($"Sideloader marker found, external info count: {extInfo.Count}");

                    if (Sideloader.DebugLogging.Value)
                    {
                        foreach (ResolveInfo info in extInfo)
                        {
                            Sideloader.Logger.LogDebug($"External info: {info.GUID} : {info.Property} : {info.Slot}");
                        }
                    }
                }

                IterateCardPrefixes(ResolveStructure, file, extInfo);
            }
Exemple #18
0
        /// <summary>
        /// Method to retrieve a list of BoneModifiers from a selected card in the maker, without loading a character.
        /// </summary>
        public static List <BoneModifier> GetBoneModifiersFromCard()
        {
            ChaFile             file      = Utilities.GetSelectedCharacter();
            PluginData          bonedata  = ExtendedSave.GetExtendedDataById(file, "KKABMPlugin.ABMData");
            List <BoneModifier> modifiers = new List <BoneModifier>();

            if (bonedata != null)
            {
                try
                {
                    switch (bonedata.version)
                    {
                    // Only support for version 2
                    case 2:
                        modifiers = LZ4MessagePackSerializer.Deserialize <List <BoneModifier> >((byte[])bonedata.data["boneData"]);
                        break;

                    default:
                        throw new NotSupportedException($"Save version {bonedata.version} is not supported");
                    }
                }
                catch (Exception ex)
                {
                    Logger.Log(LogLevel.Error, "[KK_Archetypes] Failed to load KKABMX extended data - " + ex);
                }
            }
            return(modifiers);
        }
        private static void ApplyToAllDatas(Func <SaveData.CharaData, PregnancyData, bool> action)
        {
            void ApplyToDatas(SaveData.CharaData character)
            {
                var chafiles = character.GetRelatedChaFiles();

                if (chafiles == null)
                {
                    return;
                }
                foreach (var chaFile in chafiles)
                {
                    var data = ExtendedSave.GetExtendedDataById(chaFile, PregnancyPlugin.GUID);
                    var pd   = PregnancyData.Load(data) ?? new PregnancyData();
                    if (action(character, pd))
                    {
                        ExtendedSave.SetExtendedDataById(chaFile, PregnancyPlugin.GUID, pd.Save());
                    }
                }
            }

            foreach (var heroine in Game.Instance.HeroineList)
            {
                ApplyToDatas(heroine);
            }
            ApplyToDatas(Game.Instance.Player);

            // If controller exists then update its state so it gets any pregnancy week updates
            foreach (var controller in FindObjectsOfType <PregnancyCharaController>())
            {
                controller.ReadData();
            }
        }
Exemple #20
0
        public static void ChaFileCoordinateSaveFilePostHook(ChaFileCoordinate __instance, string path)
        {
            Logger.Log(LogLevel.Debug, $"Reloading coordinate [{path}]");

            var extData = ExtendedSave.GetExtendedDataById(__instance, UniversalAutoResolver.UARExtID);

            var tmpExtInfo = (List <byte[]>)extData.data["info"];
            var extInfo    = tmpExtInfo.Select(ResolveInfo.Unserialize);

            Logger.Log(LogLevel.Debug, $"External info count: {extInfo.Count()}");
            foreach (ResolveInfo info in extInfo)
            {
                Logger.Log(LogLevel.Debug, $"External info: {info.GUID} : {info.Property} : {info.Slot}");
            }

            void ResetStructResolveStructure(Dictionary <CategoryProperty, StructValue <int> > propertyDict, object structure, IEnumerable <ResolveInfo> extInfo2, string propertyPrefix = "")
            {
                foreach (var kv in propertyDict)
                {
                    var extResolve = extInfo.FirstOrDefault(x => x.Property == $"{propertyPrefix}{kv.Key.ToString()}");

                    if (extResolve != null)
                    {
                        kv.Value.SetMethod(structure, extResolve.LocalSlot);

                        Logger.Log(LogLevel.Debug, $"[UAR] Resetting {extResolve.GUID}:{extResolve.Property} to internal slot {extResolve.LocalSlot}");
                    }
                }
            }

            IterateCoordinatePrefixes(ResetStructResolveStructure, __instance, extInfo);
        }
Exemple #21
0
 /// <summary>
 /// Save your custom data to the scene under the ID you specified when registering this controller.
 /// </summary>
 /// <param name="data">Your custom data to be written to the scene. Can be null to remove the data.</param>
 public void SetExtendedData(PluginData data)
 {
     if (ExtendedDataId == null)
     {
         throw new ArgumentException(nameof(ExtendedDataId));
     }
     ExtendedSave.SetSceneExtendedDataById(ExtendedDataId, data);
 }
 /// <summary>
 /// Get extended data based on supplied ExtendedDataId. When in chara maker loads data from character that's being loaded.
 /// </summary>
 public PluginData GetExtendedData()
 {
     if (ExtendedDataId == null)
     {
         throw new ArgumentException(nameof(ExtendedDataId));
     }
     return(ExtendedSave.GetExtendedDataById(Manager.Game.Instance.saveData, ExtendedDataId));
 }
 /// <summary>
 /// Save your custom data to the character card under the ID you specified when registering this controller.
 /// </summary>
 /// <param name="data">Your custom data to be written to the character card. Can be null to remove the data.</param>
 public void SetExtendedData(PluginData data)
 {
     if (ExtendedDataId == null)
     {
         throw new ArgumentException(nameof(ExtendedDataId));
     }
     ExtendedSave.SetExtendedDataById(Manager.Game.Instance.saveData, ExtendedDataId, data);
 }
Exemple #24
0
 /// <summary>
 /// Save your custom data to the character card under the ID you specified when registering this controller.
 /// </summary>
 /// <param name="data">Your custom data to be written to the character card. Can be null to remove the data.</param>
 public void SetExtendedData(PluginData data)
 {
     if (ExtendedDataId == null)
     {
         throw new ArgumentException(nameof(ExtendedDataId));
     }
     ExtendedSave.SetExtendedDataById(CustomParameterControl, ExtendedDataId, data);
 }
Exemple #25
0
 /// <summary>
 /// Get extended data of the last loaded scene by using the ID you specified when registering this controller.
 /// </summary>
 public PluginData GetExtendedData()
 {
     if (ExtendedDataId == null)
     {
         throw new ArgumentException(nameof(ExtendedDataId));
     }
     return(ExtendedSave.GetSceneExtendedDataById(ExtendedDataId));
 }
Exemple #26
0
        public static void CopyChaFile(ChaFile dst, ChaFile src)
        {
            PluginData ExtendedData = ExtendedSave.GetExtendedDataById(src, "KK_FutaMod");

            if (ExtendedData != null && ExtendedData.data.ContainsKey("Futa"))
            {
                ExtendedSave.SetExtendedDataById(dst, "KK_FutaMod", ExtendedData);
            }
        }
        /// <summary>
        /// Get extended data of the current character by using the ID you specified when registering this controller.
        /// This should be used inside the <see cref="OnReload(KKAPI.GameMode,bool)"/> event.
        /// Consider using one of the other "Get___ExtData" and "Set___ExtData" methods instead since they are more reliable and handle copying and transferring outfits and they conform to built in maker load toggles.
        /// </summary>
        /// <param name="getFromLoadedChara">If true, when in chara maker load data from character that's being loaded.
        /// When outside maker or false, always grab current character's data.</param>
        public PluginData GetExtendedData(bool getFromLoadedChara)
        {
            if (ExtendedDataId == null)
            {
                throw new ArgumentException(nameof(ExtendedDataId));
            }
            var chaFile = getFromLoadedChara ? MakerAPI.LastLoadedChaFile ?? ChaFileControl : ChaFileControl;

            return(ExtendedSave.GetExtendedDataById(chaFile, ExtendedDataId));
        }
            internal static void ExtendedSceneLoad(string path)
            {
                PluginData ExtendedData = ExtendedSave.GetSceneExtendedDataById(UARExtID);

                ResolveStudioObjects(ExtendedData, ResolveType.Load);
                ResolveStudioMap(ExtendedData, ResolveType.Load);
                ResolveStudioFilter(ExtendedData, ResolveType.Load);
                ResolveStudioRamp(ExtendedData, ResolveType.Load);
                ResolveStudioBGM(ExtendedData, ResolveType.Load);
            }
Exemple #29
0
        /// <summary>
        /// Get extended data of the current character by using the ID you specified when registering this controller.
        /// </summary>
        /// <param name="getFromLoadedChara">If true, when in chara maker load data from character that's being loaded.
        /// When outside maker or false, always grab current character's data.</param>
        public PluginData GetExtendedData(bool getFromLoadedChara)
        {
            if (ExtendedDataId == null)
            {
                throw new ArgumentException(nameof(ExtendedDataId));
            }
            var customParameter = getFromLoadedChara ? MakerAPI.LastLoadedChaFile ?? CustomParameterControl : CustomParameterControl; //todo

            return(ExtendedSave.GetExtendedDataById(customParameter, ExtendedDataId));
        }
Exemple #30
0
        private static void ExtendedCardSave(ChaFile file)
        {
            List <ResolveInfo> resolutionInfo = new List <ResolveInfo>();

            void IterateStruct(object obj, Dictionary <CategoryProperty, StructValue <int> > dict, string propertyPrefix = "")
            {
                foreach (var kv in dict)
                {
                    int slot = kv.Value.GetMethod(obj);

                    var info = UniversalAutoResolver.LoadedResolutionInfo.FirstOrDefault(x => x.Property == kv.Key.ToString() &&
                                                                                         x.LocalSlot == slot);

                    if (info != null)
                    {
                        var newInfo = info.DeepCopy();
                        newInfo.Property = $"{propertyPrefix}{newInfo.Property}";

                        kv.Value.SetMethod(obj, newInfo.Slot);

                        resolutionInfo.Add(newInfo);
                    }
                }
            }

            IterateStruct(file.custom.face, StructReference.ChaFileFaceProperties);
            IterateStruct(file.custom.body, StructReference.ChaFileBodyProperties);
            IterateStruct(file.custom.hair, StructReference.ChaFileHairProperties);

            for (int i = 0; i < file.coordinate.Length; i++)
            {
                var    coordinate = file.coordinate[i];
                string prefix     = $"outfit{i}.";

                IterateStruct(coordinate.clothes, StructReference.ChaFileClothesProperties, prefix);
                IterateStruct(coordinate.makeup, StructReference.ChaFileMakeupProperties, prefix);

                for (int acc = 0; acc < coordinate.accessory.parts.Length; acc++)
                {
                    string accPrefix = $"{prefix}accessory{acc}.";

                    IterateStruct(coordinate.accessory.parts[acc], StructReference.ChaFileAccessoryPartsInfoProperties, accPrefix);
                }
            }

            ExtendedSave.SetExtendedDataById(file, UniversalAutoResolver.UARExtID, new PluginData
            {
                data = new Dictionary <string, object>
                {
                    { "info", resolutionInfo.Select(x => x.Serialize()).ToList() }
                }
            });
        }