public static void OnInsertClickPre(HSprite __instance) { if (!Input.GetMouseButtonUp(0) || !__instance.IsSpriteAciotn()) { return; } if (__instance.flags.isInsertOK[Utilities.GetTargetHeroineId(__instance)]) { return; } var heroine = Utilities.GetTargetHeroine(__instance); if (heroine == null) { return; } var girlOrgasms = __instance.flags.count.sonyuOrg; // Check if girl allows raw if (girlOrgasms >= 4 + UnityEngine.Random.Range(0, 3) - heroine.lewdness / 45) { Utilities.ForceAllowInsert(__instance); } }
public static void OnInsertNoVoiceClickPre(HSprite __instance, out bool __state) { var heroineId = __instance.GetLeadingHeroineId(); __state = __instance.flags.isInsertOK[heroineId]; var heroine = Utilities.GetTargetHeroine(__instance); if (heroine == null) { return; } var girlOrgasms = __instance.flags.count.sonyuOrg; // Check if player can circumvent the raw deny if (!KoikatuGameplayMod.ForceInsert.Value) { return; } if (CanCircumventDeny(__instance) || girlOrgasms >= 3 + UnityEngine.Random.Range(0, 3) - heroine.lewdness / 66) { MakeGirlAngry(heroine, 20, 10); __instance.flags.isInsertOK[heroineId] = true; __instance.flags.isDenialvoiceWait = false; } }
public static void OnInsertNoVoiceClickPre(HSprite __instance) { if (!Input.GetMouseButtonUp(0) || !__instance.IsSpriteAciotn()) { return; } if (__instance.flags.isInsertOK[Utilities.GetTargetHeroineId(__instance)]) { return; } var heroine = Utilities.GetTargetHeroine(__instance); var girlOrgasms = __instance.flags.count.sonyuOrg; // Check if player can circumvent the raw deny if (!KoikatuGameplayMod.ForceInsert.Value) { return; } if (CanCircumventDeny(__instance) || girlOrgasms >= 3 + UnityEngine.Random.Range(0, 3) - heroine.lewdness / 66) { MakeGirlAngry(heroine, 20, 10); Utilities.ForceAllowInsert(__instance); __instance.flags.isDenialvoiceWait = false; } }
public static void OnInsertAnalClickPre(HSprite __instance) { if (!Input.GetMouseButtonUp(0) || !__instance.IsSpriteAciotn()) { return; } if (__instance.flags.isAnalInsertOK) { return; } // Check if player can circumvent the anal deny if (__instance.flags.count.sonyuAnalOrg >= 1) { var heroine = GetTargetHeroine(__instance); if (heroine != null && heroine.anger <= 80) { heroine.anger = Math.Min(100, heroine.anger + 20); } ForceAllowInsert(__instance); } }
private static bool CanCircumventDeny(HSprite __instance) { // OUT_A is resting after popping the cork outdoors return(string.Equals(__instance.flags.nowAnimStateName, "OUT_A", StringComparison.Ordinal) || string.Equals(__instance.flags.nowAnimStateName, "A_OUT_A", StringComparison.Ordinal) || __instance.flags.isDenialvoiceWait); }
private static int SpawnButtons(HSprite hSprite, int existingButtons) { var spawnedButtons = 0; foreach (var trespassingButton in _customTrespassingButtons) { try { trespassingButton.Dispose(); if (SpawnSingleButton(spawnedButtons + existingButtons, hSprite, trespassingButton)) { spawnedButtons++; } } catch (Exception ex) { KoikatuAPI.Logger.LogWarning($"Failed to spawn CustomTrespassingButton text={trespassingButton.ButtonText.Replace('\r', ' ').Replace('\n', ' ')}\n{ex}"); } } if (spawnedButtons > 0) { KoikatuAPI.Logger.LogInfo($"Created {spawnedButtons} CustomTrespassingButtons ({existingButtons} already existed)"); } return(spawnedButtons); }
/// <summary> /// Make girl angry if hero exploded inside raw /// </summary> private static void UpdateGirlAnger(HSprite __instance) { var heroine = GetTargetHeroine(__instance); if (heroine == null) { return; } if (!__instance.flags.isInsertOK) { if (__instance.flags.count.sonyuInside > 0) { if (__instance.flags.GetMenstruation(heroine.MenstruationDay) == HFlag.MenstruationType.危険日) { // If it's dangerous always make her angry heroine.anger = Math.Min(100, heroine.anger + __instance.flags.count.sonyuInside * 45); heroine.isAnger = true; } else { heroine.anger = Math.Min(100, heroine.anger + __instance.flags.count.sonyuInside * 25); } } else if (__instance.flags.count.sonyuOutside > 0) { heroine.anger = Math.Max(0, heroine.anger - __instance.flags.count.sonyuOutside * 10); } } if (heroine.anger >= 100) { heroine.isAnger = true; } }
public static void OnInsertNoVoiceClickPre(HSprite __instance) { if (!Input.GetMouseButtonUp(0) || !__instance.IsSpriteAciotn()) { return; } if (__instance.flags.isInsertOK) { return; } var heroine = GetTargetHeroine(__instance); var girlOrgasms = __instance.flags.count.sonyuOrg; // Check if player can circumvent the raw deny // OUT_A is resting after popping the cork outdoors if (CanCircumventDeny(__instance) || girlOrgasms >= 3 + RandomGen.Next(0, 3) - heroine.lewdness / 66) { MakeGirlAngry(heroine); ForceAllowInsert(__instance); __instance.flags.isDenialvoiceWait = false; } }
public static void OnInsertAnalNoVoiceClickPre(HSprite __instance) { if (!Input.GetMouseButtonUp(0) || !__instance.IsSpriteAciotn()) { return; } if (__instance.flags.isAnalInsertOK) { return; } var heroine = GetTargetHeroine(__instance); if (heroine == null) { return; } // Check if player can circumvent the anal deny if (CanCircumventDeny(__instance) || __instance.flags.count.sonyuAnalOrg >= 1) { MakeGirlAngry(heroine); heroine.anger = Math.Min(100, heroine.anger + 15); ForceAllowInsert(__instance); __instance.flags.isDenialvoiceWait = false; } }
public static void InitializeCheats() { CheatToolsWindow.OnShown = window => { _hFlag = Object.FindObjectOfType <HFlag>(); _talkScene = Object.FindObjectOfType <TalkScene>(); _hSprite = Object.FindObjectOfType <HSprite>(); _studioInstance = Studio.Studio.Instance; _soundInstance = Manager.Sound.Instance; _communicationInstance = Communication.Instance; _sceneInstance = Scene.Instance; _gameMgr = Game.Instance; _openInInspectorButtons = new[] { new KeyValuePair <object, string>(_gameMgr != null && _gameMgr.HeroineList.Count > 0 ? (Func <object>)(() => _gameMgr.HeroineList.Select(x => new ReadonlyCacheEntry(x.ChaName, x))) : null, "Heroine list"), new KeyValuePair <object, string>(_gameMgr, "Manager.Game.Instance"), new KeyValuePair <object, string>(_sceneInstance, "Manager.Scene.Instance"), new KeyValuePair <object, string>(_communicationInstance, "Manager.Communication.Instance"), new KeyValuePair <object, string>(_soundInstance, "Manager.Sound.Instance"), new KeyValuePair <object, string>(_hFlag, "HFlag"), new KeyValuePair <object, string>(_talkScene, "TalkScene"), new KeyValuePair <object, string>(_studioInstance, "Studio.Instance"), new KeyValuePair <object, string>((Func <object>)EditorUtilities.GetRootGoScanner, "Root Objects") }; }; CheatToolsWindow.Cheats.Add(new CheatEntry(w => _studioInstance == null && _gameMgr != null && !_gameMgr.saveData.isOpening, DrawPlayerCheats, "Start the game to see player cheats")); CheatToolsWindow.Cheats.Add(new CheatEntry(w => _hFlag != null, DrawHSceneCheats, null)); CheatToolsWindow.Cheats.Add(new CheatEntry(w => _gameMgr != null, DrawGirlCheatMenu, null)); CheatToolsWindow.Cheats.Add(CheatEntry.CreateOpenInInspectorButtons(() => _openInInspectorButtons)); CheatToolsWindow.Cheats.Add(new CheatEntry(w => _gameMgr != null, DrawGlobalUnlocks, null)); }
public static void OnInsertAnalNoVoiceClickPre(HSprite __instance) { if (!Input.GetMouseButtonUp(0) || !__instance.IsSpriteAciotn()) { return; } if (__instance.flags.isAnalInsertOK) { return; } var heroine = Utilities.GetTargetHeroine(__instance); if (heroine == null) { return; } // Check if player can circumvent the anal deny if (!KoikatuGameplayMod.ForceInsert.Value) { return; } if (CanCircumventDeny(__instance) || __instance.flags.count.sonyuAnalOrg >= 1) { MakeGirlAngry(heroine, 30, 15); Utilities.ForceAllowInsert(__instance); __instance.flags.isDenialvoiceWait = false; } }
public static void PadCLickStopVoice(HSprite __instance) { var interruptibleAnims = new string[] { "Idle", "_A", "_Loop" }; ForceStopVoice(ControlPadInterrupt.Value && __instance.IsSpriteAciotn() && (isVR || Input.GetMouseButtonDown(0)) && interruptibleAnims.Any(str => flags.nowAnimStateName.EndsWith(str)) && !flags.nowAnimStateName.Contains("Insert")); }
/// <summary> /// Get ID of the heroine that is currently in leading position in the h scene. 0 is the main heroine, 1 is the "tag along". /// In 3P returns the heroine the cum options affect. Outside of 3P it gets the single heroine. /// </summary> public static int GetLeadingHeroineId(this HSprite hSprite) { if (hSprite == null) { throw new ArgumentNullException(nameof(hSprite)); } return(GetLeadingHeroineId(hSprite.flags)); }
public static void HSpriteUpdatePost(HSprite __instance, bool __state) { // Restore original hcount if (__state) { __instance.flags.lstHeroine[0].hCount = 0; } }
public static void HSpriteUpdatePre(HSprite __instance, out bool __state) { // Skip code that hides the back button __state = false; if (__instance.flags.lstHeroine.Count != 0 && __instance.flags.lstHeroine[0].hCount == 0) { __state = true; __instance.flags.lstHeroine[0].hCount = 1; } }
private static void InitPointMenuAndHelpPost(HSprite __instance) { if (_defaultBtnShown == false) { // Prevent the "someone is watching" hint from appearing since no one actually is __instance.autoDisableTrespassingHelp.ForceFlag(); __instance.autoDisableTrespassingHelp.gameObject.SetActiveIfDifferent(false); __instance.menuActionSub.SetActive(false, 7); } }
public static void HookToEndHButton(HSprite __instance) { var f = typeof(HSprite).GetField("btnEnd", BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public); if (f == null) { throw new ArgumentException("Could not find field btnEnd in HSprite"); } var b = f.GetValue(__instance) as UnityEngine.UI.Button; b.OnClickAsObservable().Subscribe(unit => HSceneEndClicked?.Invoke(__instance)); }
public static void HarmonyPatch_HSprite_CreateMotionList(HSprite __instance, ref int _kind) { if (fixUI && _kind == 2 && UnlockAll.Value && __instance.menuActionSub.GetActive(5)) { var go = __instance.menuAction.GetObject(_kind); var rectTransform = go.transform as RectTransform; go = __instance.menuActionSub.GetObject(5); var rectTransform2 = go.transform as RectTransform; var anchoredPosition = rectTransform2.anchoredPosition; anchoredPosition.y = rectTransform.anchoredPosition.y + 350f; // may cause issues with different resolutions, f**k it rectTransform2.anchoredPosition = anchoredPosition; } }
private static void HideMenstrIconIfNeeded(HSprite __instance) { try { // Add the custom icons if necessary if (__instance.categoryMenstruation.lstObj.Count == 2) { var original = __instance.categoryMenstruation.lstObj[0]; void AddNewState(Sprite sprite) { var copy = UnityEngine.Object.Instantiate(original, original.transform.parent, false); copy.GetComponent <Image>().sprite = sprite; __instance.categoryMenstruation.lstObj.Add(copy); } AddNewState(_unknownSprite); // index 2 AddNewState(_pregSprite); AddNewState(_safeSprite); AddNewState(_riskySprite); AddNewState(_leaveSprite); } var heroineStatus = __instance.GetLeadingHeroine().GetHeroineStatus(); switch (heroineStatus) { case HeroineStatus.Unknown: __instance.categoryMenstruation.SetActiveToggle(2); break; case HeroineStatus.Pregnant: __instance.categoryMenstruation.SetActiveToggle(3); break; case HeroineStatus.Safe: __instance.categoryMenstruation.SetActiveToggle(4); break; case HeroineStatus.Risky: __instance.categoryMenstruation.SetActiveToggle(5); break; case HeroineStatus.OnLeave: __instance.categoryMenstruation.SetActiveToggle(6); break; } } catch (Exception ex) { UnityEngine.Debug.LogException(ex); } }
/// <summary> ///Function to lock female/male gauge depending on config /// </summary> internal static void LockGaugesAction(HSprite hSprite) { if (LockFemaleGauge.Value) { hSprite.OnFemaleGaugeLockOnGauge(); hSprite.flags.lockGugeFemale = true; } if (LockMaleGauge.Value) { hSprite.OnMaleGaugeLockOnGauge(); hSprite.flags.lockGugeMale = true; } }
public static void HookToEndHButton(HSprite __instance) { var f = typeof(HSprite).GetField("btnEnd", BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public); var b = f.GetValue(__instance) as UnityEngine.UI.Button; // Modify girl's lewdness after exiting h scene based on scene stats b.OnClickAsObservable().Subscribe(unit => { UpdateGirlLewdness(__instance); ApplyGirlAnger(__instance); }); }
public static void OnInsertAnalClickPre(HSprite __instance, out bool __state) { __state = __instance.flags.isAnalInsertOK; // Check if player can circumvent the anal deny if (__instance.flags.count.sonyuAnalOrg >= 1) { __instance.flags.isAnalInsertOK = true; var heroine = Utilities.GetTargetHeroine(__instance); if (heroine != null) { MakeGirlAngry(heroine, 20, 10); } } }
public static void SetSonyuStartPost(HSprite __instance) { var isTrap = IsATrap(Utilities.GetTargetHeroine(__instance)); var lstButton = __instance.sonyu.categoryActionButton.lstButton; // Toggle the front insert buttons. Anal buttons won't work properly if they are not already enabled so don't force enable. lstButton[0].gameObject.SetActive(!isTrap); lstButton[1].gameObject.SetActive(!isTrap); // Prevent getting stuck if (isTrap) { __instance.flags.isAnalInsertOK = true; } }
private static void InitTrespassingHelpPost(HSprite __instance) { var defaultBtnShown = __instance.btnTrespassing.gameObject.activeSelf; var spawnedCount = SpawnButtons(__instance, defaultBtnShown ? 1 : 0); if (spawnedCount > 0) { __instance.btnTrespassing.gameObject.SetActiveIfDifferent(true); _defaultBtnShown = defaultBtnShown; } else { _defaultBtnShown = null; } }
private static void InitPointMenuAndHelpPost(HSprite __instance, int _kind) { // Not initialized / no custom buttons if (_defaultBtnShown == null) { return; } //Console.WriteLine($"_kind={_kind} _defaultBtnShown={(_defaultBtnShown != null ? _defaultBtnShown.Value.ToString() : "NULL")} active={__instance.autoDisableTrespassingHelp.gameObject.activeSelf}"); if (_kind == 3) { bool menuIsVisible; if (_defaultBtnShown == false) { __instance.menuActionSub.SetActive(false, 7); // Toggle the menu based on our own buttons since the default button is always off menuIsVisible = !_customTrespassingButtons.Any(x => x.Instance != null && x.Instance.activeSelf); } else { menuIsVisible = !__instance.autoDisableTrespassingHelp.gameObject.activeSelf; } if (menuIsVisible) { foreach (var customItem in _customTrespassingButtons) { if (customItem.Instance != null) { customItem.Instance.SetActiveIfDifferent(true); } } return; } } // Disable all if not showing trespassing submenu foreach (var customItem in _customTrespassingButtons) { if (customItem.Instance != null) { customItem.Instance.SetActiveIfDifferent(false); } } }
private static void UpdateGirlLewdness(HSprite __instance) { if (!KoikatuGameplayMod.DecreaseLewd.Value) { return; } var flags = __instance.flags; var count = flags.count; var heroine = GetTargetHeroine(__instance); if (heroine == null) { return; } if (flags.GetOrgCount() == 0) { var massageTotal = (int)(count.selectAreas.Sum() / 4 + (+count.kiss + count.houshiOutside + count.houshiInside) * 10); if (massageTotal <= 5) { heroine.lewdness = Math.Max(0, heroine.lewdness - 30); } else { heroine.lewdness = Math.Min(100, heroine.lewdness + massageTotal); } } else if (count.aibuOrg > 0 && count.sonyuOrg + count.sonyuAnalOrg == 0) { heroine.lewdness = Math.Min(100, heroine.lewdness - (count.aibuOrg - 1) * 20); } else { int cumCount = count.sonyuCondomInside + count.sonyuInside + count.sonyuOutside + count.sonyuAnalCondomInside + count.sonyuAnalInside + count.sonyuAnalOutside; if (cumCount > 0) { heroine.lewdness = Math.Max(0, heroine.lewdness - cumCount * 20); } heroine.lewdness = Math.Max(0, heroine.lewdness - count.aibuOrg * 20); } }
public static void OnInsertClickPre(HSprite __instance, out bool __state) { var heroineId = __instance.GetLeadingHeroineId(); __state = __instance.flags.isInsertOK[heroineId]; var heroine = Utilities.GetTargetHeroine(__instance); if (heroine == null) { return; } var girlOrgasms = __instance.flags.count.sonyuOrg; // Check if girl allows raw if (girlOrgasms >= 4 + UnityEngine.Random.Range(0, 3) - heroine.lewdness / 45) { __instance.flags.isInsertOK[heroineId] = true; } }
public static void OnInsertAnalNoVoiceClickPre(HSprite __instance, out bool __state) { __state = __instance.flags.isAnalInsertOK; // Check if player can circumvent the anal deny if (!KoikatuGameplayMod.ForceInsert.Value) { return; } if (CanCircumventDeny(__instance) || __instance.flags.count.sonyuAnalOrg >= 1) { __instance.flags.isAnalInsertOK = true; __instance.flags.isDenialvoiceWait = false; var heroine = Utilities.GetTargetHeroine(__instance); if (heroine != null) { MakeGirlAngry(heroine, 30, 15); } } }
private static void OnInsertAnalNoVoiceClickPre(HSprite __instance, out bool __state) { __state = __instance.flags.isAnalInsertOK; // Check if player can circumvent the anal deny if (!_forceInsert.Value) { return; } if (CanCircumventDeny(__instance) || __instance.flags.count.sonyuAnalOrg >= 1) { __instance.flags.isAnalInsertOK = true; __instance.flags.isDenialvoiceWait = false; var heroine = __instance.GetLeadingHeroine(); if (heroine != null) { MakeGirlAngry(heroine, 30, 15); } } }
private static void ApplyGirlAnger(HSprite __instance) { if (!KoikatuGameplayMod.ForceInsertAnger.Value) { return; } var heroine = Utilities.GetTargetHeroine(__instance); if (heroine == null) { return; } if (!__instance.flags.isInsertOK[Utilities.GetTargetHeroineId(__instance)]) { if (__instance.flags.count.sonyuInside > 0) { if (HFlag.GetMenstruation(heroine.MenstruationDay) == HFlag.MenstruationType.危険日) { // If it's dangerous always make her angry heroine.anger = Math.Min(100, heroine.anger + __instance.flags.count.sonyuInside * 45); heroine.isAnger = true; } else { heroine.anger = Math.Min(100, heroine.anger + __instance.flags.count.sonyuInside * 25); } } else if (__instance.flags.count.sonyuOutside > 0) { heroine.anger = Math.Max(0, heroine.anger - __instance.flags.count.sonyuOutside * 10); } } if (heroine.anger >= 100) { heroine.isAnger = true; } }