diff --git a/SVS_CheatTools/CheatToolsWindowInit.SVS.cs b/SVS_CheatTools/CheatToolsWindowInit.SVS.cs index 1051bb8..ac2bbe9 100644 --- a/SVS_CheatTools/CheatToolsWindowInit.SVS.cs +++ b/SVS_CheatTools/CheatToolsWindowInit.SVS.cs @@ -171,10 +171,12 @@ private static void DrawHSceneCheats(CheatToolsWindow cheatToolsWindow) private static void DrawGeneralCheats(CheatToolsWindow obj) { Hooks.RiggedRng = GUILayout.Toggle(Hooks.RiggedRng, new GUIContent("Rigged RNG (success if above 0%)", null, "All actions with at least 1% chance will always succeed. Must be activated BEFORE talking to a character.\nWARNING: This will affect RNG across the game. NPCs will (probably) always succeed with their actions which will skew the simulation heavily. Some events might never happen or keep repeating until this is turned off.")); + + GUILayout.Space(5); GUILayout.BeginHorizontal(); { - GUILayout.Label("Walking speed"); + GUILayout.Label("Walking speed:"); var normal = Hooks.SpeedMode == Hooks.SpeedModes.Normal || Hooks.SpeedMode == Hooks.SpeedModes.ReturnToNormal; var newNormal = GUILayout.Toggle(normal, "Normal"); @@ -186,6 +188,16 @@ private static void DrawGeneralCheats(CheatToolsWindow obj) Hooks.SpeedMode = Hooks.SpeedModes.Sanic; } GUILayout.EndHorizontal(); + + GUILayout.BeginHorizontal(); + { + Hooks.InterruptBlock = GUILayout.Toggle(Hooks.InterruptBlock, new GUIContent("Block interrupts", null, "Prevent NPCs from interrupting other characters.")); + Hooks.InterruptBlockAllow3P = GUILayout.Toggle(Hooks.InterruptBlockAllow3P, new GUIContent("except 3P", null, "Do not block NPCs interrupting to ask for a threesome.")); + Hooks.InterruptBlockAllowNonPlayer = GUILayout.Toggle(Hooks.InterruptBlockAllowNonPlayer, new GUIContent("only player", null, "Only block interrupts if player controls one of the involved characters.")); + } + GUILayout.EndHorizontal(); + + GUILayout.Space(5); GUI.enabled = ADV.ADVManager._instance?.IsADV == true; if (GUILayout.Button(new GUIContent("Force Unlock visible talk options", null, "Un-gray and make clickable all currently visible buttons in the talk menu. Mostly for use with the blackmail menu. If the chance is 0% you still won't be able to succeed at the action."))) diff --git a/SVS_CheatTools/Hooks.cs b/SVS_CheatTools/Hooks.cs index 74cf45d..839a0a1 100644 --- a/SVS_CheatTools/Hooks.cs +++ b/SVS_CheatTools/Hooks.cs @@ -1,12 +1,44 @@ using System; using HarmonyLib; using Pathfinding; -using Random = Il2CppSystem.Random; namespace CheatTools; internal static class Hooks { + #region No interruptions + + public static bool InterruptBlock; + public static bool InterruptBlockAllow3P = true; + public static bool InterruptBlockAllowNonPlayer = true; + + [HarmonyPostfix] + [HarmonyPatch(typeof(SV.ReactionManager), nameof(SV.ReactionManager.CheckIntervention))] + private static void ReactionManager_CheckIntervention_Postfix(SV.ReactionManager __instance, + SV.Chara.AI ai, SV.Chara.AI aiTarg1, SV.Chara.AI aiTarg2, + SV.SimulationDefine.CommandNo setCommandNo, + ref bool risSetAction) + { + if (!InterruptBlock) return; + + if (InterruptBlockAllow3P && (setCommandNo == SV.SimulationDefine.CommandNo.LetsHave3P || setCommandNo == SV.SimulationDefine.CommandNo.WantA3P)) return; + + if (InterruptBlockAllowNonPlayer) + { + var includesPc = ai._charaData.IsPC || aiTarg1?._charaData.IsPC == true || aiTarg2?._charaData.IsPC == true; + if (!includesPc) return; + } + +#if DEBUG + Console.WriteLine($"ai={ai._charaData.Name} aiTarg1={aiTarg1._charaData.Name} aiTarg2={aiTarg2._charaData.Name} setCommandNo={setCommandNo} risSetAction={risSetAction}"); +#endif + // Cancel the intervention + ai._charaData.charasGameParam.commandNo = (int)SV.SimulationDefine.CommandNo.None; + risSetAction = false; + } + + #endregion + #region Speedhack [HarmonyPostfix] @@ -72,8 +104,8 @@ private static void ProbabilityCalculation_Detect_Override(ref bool __result) } [HarmonyPostfix] - [HarmonyPatch(typeof(Random), nameof(Random.Next), typeof(int))] - [HarmonyPatch(typeof(Random), nameof(Random.Next), typeof(int), typeof(int))] + [HarmonyPatch(typeof(Il2CppSystem.Random), nameof(Il2CppSystem.Random.Next), typeof(int))] + [HarmonyPatch(typeof(Il2CppSystem.Random), nameof(Il2CppSystem.Random.Next), typeof(int), typeof(int))] private static void Random_Next_Override(int maxValue, ref int __result) { if (RiggedRng) __result = maxValue - 1;