Example #1
0
            internal static void SaveDataCallNormalizePostfix(ref SaveData.CharaData charaData)
            {
                var orig = charaData.callName;

                try
                {
                    if (Instance == null ||
                        Instance._matched.Contains(orig) ||
                        !TryGetReplacementsByPersonality(charaData.personality, out var replacements))
                    {
                        return;
                    }

                    var nickParam = SaveData.WorldData.GetCallName(charaData);
                    var key       = Instance.TextResourceHelper.GetSpecializedKey(nickParam, nickParam.Name);
                    if (!replacements.TryGetValue(key, out var translatedName))
                    {
                        return;
                    }
                    charaData.callName = translatedName;
                    Instance._matched.Add(translatedName);
                }
                catch (Exception err)
                {
                    Logger.LogWarning($"{nameof(SaveDataCallNormalizePostfix)}: {err.Message}");
                    UnityEngine.Debug.LogException(err);
                }
            }
Example #2
0
        public static GameDialogHelperCharaController GetGameDialogHelperController(this SaveData.CharaData charaData)
        {
            GameDialogHelperCharaController controller = null;

            charaData.SafeProc(cd => cd.chaCtrl.SafeProcObject(cc => controller = cc.GetGameDialogHelperController()));
            return(controller);
        }
 /// <summary>
 /// Mark character to reload next time their assigned ChaControl changes, so that any changes in function
 /// controller on previous chara can get propagated to controller on new chara
 /// todo limit this better to avoid unnecessary reloads? might not be an issue
 /// </summary>
 internal static bool SetDirty(SaveData.CharaData chara, bool dirty)
 {
     if (dirty && KKAPI.MainGame.GameAPI.GameBeingSaved)
     {
         return(false);
     }
     return(dirty ? _dirtyCharas.Add(chara) : _dirtyCharas.Remove(chara));
 }
        internal static IEnumerable <ChaFileControl> GetRelatedChaFiles(this SaveData.CharaData character)
        {
            var chafiles =
                character is SaveData.Heroine h ? KKAPI.MainGame.GameExtensions.GetRelatedChaFiles(h) :
                character is SaveData.Player p ? KKAPI.MainGame.GameExtensions.GetRelatedChaFiles(p) :
                null;

            return(chafiles);
        }
 private static void OnChaCtrlChangePre(ChaControl value, SaveData.CharaData __instance, bool __state)
 {
     // Only reload if the chactrl actually changes. Reload in postfix just in case any plugin expects CharaData.chaCtrl to already be set
     if (__state)
     {
         if (_dirtyCharas.Remove(__instance))
         {
             CharacterApi.ReloadChara(value);
         }
     }
 }
Example #6
0
            private static Exception CatchGetCallNameCrash(Exception __exception, SaveData.CharaData charaData, int id)
            {
                if (__exception != null)
                {
                    if (!CheckPersonalityAndOverride(charaData.charFile))
                    {
                        // If the personality does exist, the id will get auto reset even if we don't do anything
                        Utilities.Logger.Log(LogLevel.Warning, $"Failed to get CallName for personality={charaData.personality} id={id}. Resetting it to default.");
                        Utilities.Logger.LogWarning(__exception);
                    }
                }

                return(null);
            }
Example #7
0
        public static void DenialOverride(SaveData.CharaData __instance, ref ChaFileParameter.Denial __result)
        {
            var currentCrest = (__instance as SaveData.Heroine)?.GetCurrentCrest();

            if (currentCrest == CrestType.command)
            {
                __result = _noDenial;
            }
            else if (currentCrest == CrestType.suffer)
            {
                var newResult = new ChaFileParameter.Denial();
                newResult.Copy(__result);
                newResult.aibu    = true;
                newResult.anal    = true;
                newResult.massage = true;
                __result          = newResult;
            }
        }
        public static PregnancyData GetPregnancyData(this SaveData.CharaData chara)
        {
            if (chara == null)
            {
                return(new PregnancyData());
            }

            // Figure out which data to take if there are multiple
            // probably not necessary? null check should be enough?
            return(chara.GetRelatedChaFiles()
                   .Select(GetPregnancyData)
                   .Where(x => x != null)
                   .OrderByDescending(x => x.PregnancyCount)
                   .ThenByDescending(x => x.WeeksSinceLastPregnancy)
                   .ThenByDescending(x => x.Week)
                   .ThenByDescending(x => x.MenstruationSchedule)
                   .ThenByDescending(x => x.GameplayEnabled)
                   .FirstOrDefault() ?? new PregnancyData());
        }
Example #9
0
 private static void PassportSetPostfix(Passport __instance, SaveData.CharaData charaData)
 {
     if (_instance == null || !_instance.Enabled)
     {
         return;
     }
     try
     {
         if (_instance.TryNameLookup(__instance._activity.text, out var tmpResult))
         {
             __instance._activity.text = tmpResult;
         }
     }
     catch (Exception err)
     {
         TextResourceRedirector.Logger?.LogWarning(
             $"{nameof(PassportSetPostfix)}: Unexpected error: {err.Message}");
         UnityEngine.Debug.LogException(err);
     }
 }
Example #10
0
            /// <summary>
            ///     Enable/disable pregnancy icon
            /// </summary>
            private static void SetHeart(GameObject rootObj, SaveData.CharaData chara, bool classRoster)
            {
                var pregIconTr = rootObj.transform.Find(ICON_NAME);

                if (chara == null)
                {
                    if (pregIconTr != null)
                    {
                        Destroy(pregIconTr.gameObject);
                    }
                }
                else
                {
                    if (pregIconTr == null)
                    {
                        pregIconTr = new GameObject(ICON_NAME, typeof(RectTransform), typeof(CanvasRenderer), typeof(Image)).transform;
                        pregIconTr.SetParent(rootObj.transform, false);
                        var rt = pregIconTr.GetComponent <RectTransform>();
                        if (classRoster)
                        {
                            rt.anchorMax     = rt.anchorMin = rt.pivot = new Vector2(0, 1);
                            rt.offsetMin     = Vector2.zero;
                            rt.offsetMax     = new Vector2(48, 48);
                            rt.localScale    = Vector3.one;
                            rt.localPosition = new Vector3(4, -115, 0);
                        }
                        else // status screen during roaming mode
                        {
                            rt.anchorMax     = rt.anchorMin = rt.pivot = new Vector2(0.5f, 0.5f);
                            rt.offsetMin     = Vector2.zero;
                            rt.offsetMax     = new Vector2(48, 48);
                            rt.localScale    = Vector3.one;
                            rt.localPosition = new Vector3(-273, -85, 0);
                        }
                    }

                    AddPregIcon(pregIconTr, chara);
                }
            }
Example #11
0
            private static void AddPregIcon(Transform pregIconTransform, SaveData.CharaData chara)
            {
                var image = pregIconTransform.GetComponent <Image>();

                _currentHeroine.Add(new KeyValuePair <SaveData.CharaData, RectTransform>(chara, image.GetComponent <RectTransform>()));

                var status = chara.GetCharaStatus(chara.GetPregnancyData());

                switch (status)
                {
                case HeroineStatus.Unknown:
                    image.sprite = _unknownSprite;
                    break;

                case HeroineStatus.OnLeave:
                    image.sprite = _leaveSprite;
                    break;

                case HeroineStatus.Safe:
                    image.sprite = _safeSprite;
                    break;

                case HeroineStatus.Risky:
                    image.sprite = _riskySprite;
                    break;

                case HeroineStatus.Pregnant:
                    image.sprite = _pregSprite;
                    break;

                default:
                    throw new ArgumentOutOfRangeException();
                }

                pregIconTransform.gameObject.SetActiveIfDifferent(chara is SaveData.Heroine || status == HeroineStatus.Pregnant);
            }
Example #12
0
        public static Guid GetCharaGuid(this SaveData.CharaData charaData,
                                        int guidVersion = PluginDataInfo.CurrentCharaGuidVersion)
        {
            if (guidVersion > PluginDataInfo.MaxCharaGuidVersion)
            {
                throw new ArgumentOutOfRangeException(nameof(guidVersion), $"Unknown guidVersion ({guidVersion})");
            }

            if (guidVersion < PluginDataInfo.MinimumSupportedCharaGuidVersion || charaData == null ||
                !charaData.charFileInitialized)
            {
                return(Guid.Empty);
            }

            var guidKeyBuilder = StringBuilderPool.Get();
            var intFmt         = "{0:04}";

            try
            {
                switch (guidVersion)
                {
                case 5:
                    guidKeyBuilder
                    .AppendFormat(intFmt,
                                  charaData is SaveData.Heroine heroine5
                                    ? heroine5.FixCharaIDOrPersonality
                                    : charaData.personality)
                    .Append('/')
                    .AppendFormat(intFmt, charaData.schoolClass)
                    .Append('/')
                    .AppendFormat(intFmt, charaData.schoolClassIndex)
                    .Append('/')
                    .Append(charaData.Name);
                    break;

                case 6:
                    guidKeyBuilder
                    .AppendFormat(intFmt,
                                  charaData is SaveData.Heroine heroine6
                                    ? heroine6.FixCharaIDOrPersonality
                                    : charaData.personality)
                    .Append('/')
                    .AppendFormat(intFmt, charaData.schoolClass)
                    .Append('/')
                    .AppendFormat(intFmt, charaData.schoolClassIndex)
                    .Append('/')
                    .Append(charaData.firstname)
                    .Append('/')
                    .Append(charaData.lastname)
                    .Append('/')
                    .Append(charaData.parameter.sex);
                    break;

                default:
                    throw new ArgumentOutOfRangeException(nameof(guidVersion),
                                                          $"Unsupported guidVersion ({guidVersion})");
                }

                if (guidKeyBuilder.Length == 0)
                {
                    return(Guid.Empty);
                }
                var guidKey = guidKeyBuilder.ToString();
                var result  = GuidCache.Get(guidKey);
                Logger?.DebugLogDebug(
                    $"{nameof(GetCharaGuid)} (version={guidVersion}): guidKey={guidKey}, result={result}");
                return(result);
            }
            finally
            {
                StringBuilderPool.Release(guidKeyBuilder);
            }
        }
Example #13
0
 public static void PersistData(this SaveData.CharaData charaData)
 {
     charaData.SafeProc(cd => cd.GetGameDialogHelperController().SafeProcObject(dhc => dhc.PersistToCard()));
 }
Example #14
0
 public static void StopPregnancy(SaveData.CharaData heroine)
 {
     _stoppedPregnancies.Add(heroine);
 }
 private static void OnChaCtrlChangePre(ChaControl value, SaveData.CharaData __instance, out bool __state)
 {
     __state = value != __instance.chaCtrl;
 }
Example #16
0
 internal static void SetClassChara(SaveData.CharaData charaData) => CheckPersonalityAndOverride(charaData.charFile);
 public static HeroineStatus GetHeroineStatus(this SaveData.CharaData chara, PregnancyData pregData = null) => GetCharaStatus(chara, pregData);
        public static HeroineStatus GetCharaStatus(this SaveData.CharaData chara, PregnancyData pregData = null)
        {
            if (chara is SaveData.Heroine heroine)
            {
                if (pregData == null)
                {
                    pregData = heroine.GetPregnancyData();
                }

                // Check if she wants to tell
                if (heroine.intimacy >= 80 ||
                    heroine.hCount >= 5 ||
                    heroine.parameter.attribute.bitch && heroine.favor > 50 ||
                    (heroine.isGirlfriend || heroine.favor >= 90) &&
                    (!heroine.isVirgin || heroine.hCount >= 2 || heroine.intimacy >= 40))
                {
                    var pregnancyWeek = pregData.Week;
                    if (pregnancyWeek > 0)
                    {
                        if (pregnancyWeek >= PregnancyData.LeaveSchoolWeek)
                        {
                            return(HeroineStatus.OnLeave);
                        }
                        if (PregnancyPlugin.ShowPregnancyIconEarly.Value)
                        {
                            return(HeroineStatus.Pregnant);
                        }
                        // Different personalities notice at different times
                        if (_earlyDetectPersonalities.Contains(heroine.personality))
                        {
                            if (pregnancyWeek > 1)
                            {
                                return(HeroineStatus.Pregnant);
                            }
                        }
                        else if (_lateDetectPersonalities.Contains(heroine.personality))
                        {
                            if (pregnancyWeek > 11)
                            {
                                return(HeroineStatus.Pregnant);
                            }
                        }
                        else
                        {
                            if (pregnancyWeek > 5)
                            {
                                return(HeroineStatus.Pregnant);
                            }
                        }
                    }

                    return(HFlag.GetMenstruation(heroine.MenstruationDay) == HFlag.MenstruationType.安全日
                            ? HeroineStatus.Safe
                            : HeroineStatus.Risky);
                }
            }
            else if (chara is SaveData.Player player)
            {
                if (pregData == null)
                {
                    pregData = player.GetPregnancyData();
                }
                return(pregData.IsPregnant ? HeroineStatus.Pregnant : HeroineStatus.Safe);
            }
            return(HeroineStatus.Unknown);
        }
Example #19
0
 public CharaDialogMemory(SaveData.CharaData charaData) :
     this(charaData.GetCharaGuid())
 {
 }