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(); }
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); }
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); }
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)); } }
/// <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."); }
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(); } }
/// <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); }
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); });
/// <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); } } }
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); } } }
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); } } }
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); }
/// <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)); }
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. /// </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)); }
/// <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)); }
public static void ChangeCharaPrefix(OCIChar __instance) { ChangeCharaVisibleState = true; PluginData ExtendedData = ExtendedSave.GetExtendedDataById(__instance.charInfo.chaFile, "KK_InvisibleBody"); if (ExtendedData != null && (bool)ExtendedData.data["Visible"] == false) { //character is invisible, set it back to visible before the character is changed out ChangeCharaVisibleState = false; SetVisibleState(__instance.charInfo, forceVisible: true, forceVisibleState: true, saveVisibleState: false); } }
/// <summary> /// Get extended data of the specified coordinate by using the ID you specified when registering this controller. /// This should be used inside the <see cref="OnCoordinateBeingLoaded(ChaFileCoordinate,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="coordinate">Coordinate you want to get the data from</param> public PluginData GetCoordinateExtendedData(ChaFileCoordinate coordinate) { if (coordinate == null) { throw new ArgumentNullException(nameof(coordinate)); } if (ExtendedDataId == null) { throw new ArgumentException(nameof(ExtendedDataId)); } return(ExtendedSave.GetExtendedDataById(coordinate, ExtendedDataId)); }
/// <summary> /// Register new functionality that will be automatically added to all characters (where applicable). /// Offers easy API for saving and loading extended data, and for running logic to apply it to the characters. /// All necessary hooking and event subscribing is done for you. All you have to do is create a type /// that inherits from <code>CharaExtraBehaviour</code> (don't make instances, the API will make them for you). /// </summary> /// <typeparam name="T">Type with your custom logic to add to a character</typeparam> /// <param name="extendedDataId">Extended data ID used by this behaviour. Set to null if not used. Needed to copy the data in some situations.</param> public static void RegisterExtraBehaviour <T>(string extendedDataId) where T : CharaCustomFunctionController, new() { void BasicCopier(ChaFile dst, ChaFile src) { var extendedData = ExtendedSave.GetExtendedDataById(src, extendedDataId); ExtendedSave.SetExtendedDataById(dst, extendedDataId, extendedData); } var copier = extendedDataId == null ? (CopyExtendedDataFunc)null : BasicCopier; RegisterExtraBehaviour <T>(extendedDataId, copier); }
private static void GetMenstruationOverridePrefix() { if (_lastHeroine != null) { // Get a schedule directly this way since the controller is not spawned in class roster var schedule = _lastHeroine.GetRelatedChaFiles() .Select(c => PregnancyData.Load(ExtendedSave.GetExtendedDataById(c, GUID))?.MenstruationSchedule ?? MenstruationSchedule.Default) .FirstOrDefault(x => x != MenstruationSchedule.Default); _menstruationsBackup = HFlag.menstruations; HFlag.menstruations = PregnancyCharaController.GetMenstruationsArr(schedule); } }
public static void CreateChara(ChaControl __result, ChaFileControl _chaFile, byte _sex) { if (_sex == 0 || _chaFile == null) { return; } PluginData ExtendedData = ExtendedSave.GetExtendedDataById(_chaFile, "KK_FutaMod"); if (ExtendedData != null && ExtendedData.data.ContainsKey("Futa")) { __result.chaFile.status.visibleSonAlways = (bool)ExtendedData.data["Futa"]; } }
private static void StartPregnancy(ChaFileControl chaFile) { var data = ExtendedSave.GetExtendedDataById(chaFile, PregnancyPlugin.GUID); PregnancyDataUtils.DeserializeData(data, out var week, out var gameplayEnabled, out var fertility, out var schedule); // If week is 0 the character is not pregnant if (gameplayEnabled && week <= 0) { //Logger.Log(LogLevel.Debug, "Preg - starting pregnancy on " + chaFile.parameter.fullname + ", new week is " + 1); ExtendedSave.SetExtendedDataById(chaFile, PregnancyPlugin.GUID, PregnancyDataUtils.SerializeData(1, true, fertility, schedule)); } }
private static bool CanGetSpawned(AgentActor heroine) { var isOnLeave = heroine.GetRelatedChaFiles() .Any(c => { var pd = PregnancyData.Load(ExtendedSave.GetExtendedDataById(heroine.ChaControl.chaFile, GUID)); if (pd == null) { return(false); } return(pd.GameplayEnabled && pd.Week >= PregnancyData.LeaveSchoolWeek); }); return(!isOnLeave); }
private static bool LoadExtendedData_ver1(ParamCharaController controller) { #if DEBUG BreastPhysicsController.Logger.LogDebug("Call LoadExtendedData_ver1"); #endif var chaFile = MakerAPI.LastLoadedChaFile ?? controller.ChaFileControl; var dataVer1 = ExtendedSave.GetExtendedDataById(chaFile, ExtendedDataID_ver1); if (dataVer1 != null) { #if DEBUG BreastPhysicsController.Logger.LogDebug("Found ver1 ExtendedData."); #endif Compatibility.BreastDynamicBoneParameter paramVer1 = new Compatibility.BreastDynamicBoneParameter(); var byteDBParams = new object(); if (dataVer1.data.TryGetValue(ExtendedDataKey_ver1, out byteDBParams) && byteDBParams is byte[]) { if (paramVer1.SetParamByte((byte[])byteDBParams)) { BreastPhysicsController.Logger.LogInfo("Loaded ver1 parameters from ExtendedData."); if (paramVer1.CopyParamsTo(controller.paramCustom)) { foreach (ParamBustCustom bust in controller.paramCustom.GetAllBustParameters()) { bust.enabled = true; } controller.Enabled = true; return(true); } else { #if DEBUG BreastPhysicsController.Logger.LogDebug("Failed copy ver1 parameters to controller"); #endif } } else { BreastPhysicsController.Logger.LogError("Loaded ver1 parameters from ExtendedData is invalid."); } } } #if DEBUG BreastPhysicsController.Logger.LogDebug("Not found ver1 plugin data."); #endif return(false); }
/// <param name="c">ChaFile to test</param> ///// <param name="afterWasDiscovered">The girl knows about it / tested it</param> public static PregnancyData GetPregnancyData(this ChaFileControl c) { if (c == null) { return(null); } var d = ExtendedSave.GetExtendedDataById(c, PregnancyPlugin.GUID); if (d == null) { return(null); } return(PregnancyData.Load(d)); }
internal static void ExtendedCardLoad(ChaFile file) { string cardName = file.charaFileName; if (cardName.IsNullOrEmpty()) { cardName = file.parameter?.fullname?.Trim(); } Sideloader.Logger.LogDebug($"Loading card [{cardName}]"); 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); #if AI || HS2 //Resolve the bundleID to the same ID as the hair foreach (var hairPart in file.custom.hair.parts) { if (hairPart.id > BaseSlotID) { hairPart.bundleId = hairPart.id; } } #endif }
/// <param name="c">ChaFile to test</param> /// <param name="afterWasDiscovered">The girl knows about it / tested it</param> public static bool IsChaFilePregnant(this ChaFileControl c, bool afterWasDiscovered) { if (c == null) { return(false); } var d = ExtendedSave.GetExtendedDataById(c, PregnancyPlugin.GUID); if (d == null) { return(false); } DeserializeData(d, out var week, out _, out _, out _); return(afterWasDiscovered ? week > 1 : week > 0); }
/// <summary> /// 從ExtendedData取得給定ChaControl的HairAccessories和單一hairAccessoryInfo /// </summary> /// <param name="chaCtrl">要查詢的ChaControl</param> /// <param name="nowcoordinateExtData">nowCoordinate的hairAccessoryInfo</param> /// <returns>整個HairAccessories</returns> public static Dictionary <int, object> GetDataFromCoordinate(ChaFileCoordinate coordinate) { Dictionary <int, object> nowcoordinateExtData; PluginData data = ExtendedSave.GetExtendedDataById(coordinate, GUID); if (data != null && data.data.TryGetValue("CoordinateHairAccessories", out object loadedHairAccessories) && loadedHairAccessories != null) { nowcoordinateExtData = MessagePackSerializer.Deserialize <Dictionary <int, object> >((byte[])loadedHairAccessories); if (null == nowcoordinateExtData) { nowcoordinateExtData = new Dictionary <int, object>(); } Logger.LogDebug($"Get Hair Accessories from coordinate {coordinate.coordinateName}: {nowcoordinateExtData.Count} (1)"); Logger.LogDebug($"->{string.Join(",", nowcoordinateExtData.Select(x => x.Key.ToString()).ToArray())}"); return(nowcoordinateExtData); } Logger.LogDebug($"No Hair Accessories get from coordinate {coordinate.coordinateFileName}"); return(null); }
private static void GetMenstruationOverridePrefix() { if (_lastHeroine != null) { // Get a schedule directly this way since the controller is not spawned in class roster var schedule = _lastHeroine.GetRelatedChaFiles().Select(control => { var d = ExtendedSave.GetExtendedDataById(control, GUID); if (d == null) { return(PregnancyDataUtils.MenstruationSchedule.Default); } PregnancyDataUtils.DeserializeData(d, out _, out _, out _, out var s); return(s); }).FirstOrDefault(x => x != PregnancyDataUtils.MenstruationSchedule.Default); _menstruationsBackup = HFlag.menstruations; HFlag.menstruations = PregnancyCharaController.GetMenstruationsArr(schedule); } }
public static void ResolveStructure(Dictionary <CategoryProperty, StructValue <int> > propertyDict, object structure, ChaFile save) { //BepInLogger.Log($"Tried to resolve structure: {structure.GetType().Name}"); var extData = ExtendedSave.GetExtendedDataById(save, UARExtID); if (extData == null || !extData.data.ContainsKey("info")) { //BepInLogger.Log($"No info to load!"); return; } var tmpExtInfo = (object[])extData.data["info"]; var extInfo = tmpExtInfo.Select(x => ResolveInfo.Unserialize((byte[])x)); //BepInLogger.Log($"Internal info count: {LoadedResolutionInfo.Count}"); //foreach (ResolveInfo info in LoadedResolutionInfo) // BepInLogger.Log($"Internal info: {info.ModID} : {info.Property} : {info.Slot}"); //BepInLogger.Log($"External info count: {extInfo.Count()}"); //foreach (ResolveInfo info in extInfo) // BepInLogger.Log($"External info: {info.ModID} : {info.Property} : {info.Slot}"); foreach (var kv in propertyDict) { var extResolve = extInfo.FirstOrDefault(x => x.Property == kv.Key.ToString()); if (extResolve != null) { var intResolve = LoadedResolutionInfo.FirstOrDefault(x => x.CanResolve(extResolve)); if (intResolve != null) { BepInLogger.Log($"[UAR] Resolving {extResolve.ModID}:{extResolve.Property} from slot {extResolve.Slot} to slot {intResolve.LocalSlot}"); kv.Value.SetMethod(structure, intResolve.LocalSlot); } } } }