Decompiled source of coopPlus v1.1.3
AOEHealingFix.dll
Decompiled a week agousing System; using System.Collections.Generic; using System.Diagnostics; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using System.Security; using System.Security.Permissions; using BepInEx; using BepInEx.Logging; using HarmonyLib; using Microsoft.CodeAnalysis; using Peak.Afflictions; using Photon.Pun; using UnityEngine; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)] [assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")] [assembly: AssemblyCompany("AOEHealingFix")] [assembly: AssemblyConfiguration("Debug")] [assembly: AssemblyFileVersion("1.0.0.0")] [assembly: AssemblyInformationalVersion("1.0.0")] [assembly: AssemblyProduct("AOEHealingFix")] [assembly: AssemblyTitle("AOEHealingFix")] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("1.0.0.0")] [module: UnverifiableCode] [module: RefSafetyRules(11)] namespace Microsoft.CodeAnalysis { [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] internal sealed class EmbeddedAttribute : Attribute { } } namespace System.Runtime.CompilerServices { [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] [AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)] internal sealed class RefSafetyRulesAttribute : Attribute { public readonly int Version; public RefSafetyRulesAttribute(int P_0) { Version = P_0; } } } namespace AOEHealingFix { [BepInPlugin("jill920.aoefix", "AOE Healing Fix", "1.0.0")] public class AOEHealingFixPlugin : BaseUnityPlugin { public const string MOD_GUID = "jill920.aoefix"; public const string MOD_NAME = "AOE Healing Fix"; public const string MOD_VERSION = "1.0.0"; public static AOEHealingFixPlugin Instance; public static ManualLogSource Logger; private void Awake() { //IL_0018: Unknown result type (might be due to invalid IL or missing references) //IL_001e: Expected O, but got Unknown Instance = this; Logger = ((BaseUnityPlugin)this).Logger; try { Harmony val = new Harmony("jill920.aoefix"); val.PatchAll(Assembly.GetExecutingAssembly()); Logger.LogInfo((object)"[AOE Healing Fix 1.0.0] Loaded successfully!"); Logger.LogInfo((object)" AOE healing now works on carried/downed players"); } catch (Exception ex) { Logger.LogError((object)("Harmony patch failed: " + ex.Message)); } } } [HarmonyPatch(typeof(AOE), "Explode")] internal static class AOE_Explode_Patch { [HarmonyPrefix] private static bool Prefix(AOE __instance) { //IL_0032: Unknown result type (might be due to invalid IL or missing references) //IL_00cb: Unknown result type (might be due to invalid IL or missing references) //IL_00d0: Unknown result type (might be due to invalid IL or missing references) //IL_0164: Unknown result type (might be due to invalid IL or missing references) //IL_0170: Unknown result type (might be due to invalid IL or missing references) //IL_0175: Unknown result type (might be due to invalid IL or missing references) //IL_02ac: Unknown result type (might be due to invalid IL or missing references) //IL_02b3: Unknown result type (might be due to invalid IL or missing references) //IL_0313: Unknown result type (might be due to invalid IL or missing references) //IL_031a: Unknown result type (might be due to invalid IL or missing references) //IL_0326: Unknown result type (might be due to invalid IL or missing references) //IL_032b: Unknown result type (might be due to invalid IL or missing references) //IL_03d6: Unknown result type (might be due to invalid IL or missing references) //IL_03dc: Expected I4, but got Unknown //IL_0406: Unknown result type (might be due to invalid IL or missing references) //IL_0429: Unknown result type (might be due to invalid IL or missing references) //IL_0430: Expected I4, but got Unknown //IL_0486: Unknown result type (might be due to invalid IL or missing references) //IL_0490: Expected I4, but got Unknown AOEHealingFixPlugin.Logger.LogInfo((object)("[AOE DEBUG] Explode() called on " + ((Object)__instance).name)); AOEHealingFixPlugin.Logger.LogInfo((object)$"[AOE DEBUG] statusAmount: {__instance.statusAmount}, statusType: {__instance.statusType}"); AOEHealingFixPlugin.Logger.LogInfo((object)$"[AOE DEBUG] range: {__instance.range}, hasAffliction: {__instance.hasAffliction}"); if (!(__instance.statusAmount < 0f)) { AOEHealingFixPlugin.Logger.LogInfo((object)"[AOE DEBUG] Not a healing AOE (statusAmount >= 0), letting original handle"); return true; } AOEHealingFixPlugin.Logger.LogInfo((object)$"[AOE DEBUG] HEALING AOE DETECTED! statusAmount: {__instance.statusAmount}"); float statusAmount = __instance.statusAmount; STATUSTYPE statusType = __instance.statusType; STATUSTYPE[] addtlStatus = __instance.addtlStatus; bool hasAffliction = __instance.hasAffliction; Affliction affliction = __instance.affliction; __instance.statusAmount = 0f; __instance.hasAffliction = false; __instance.affliction = null; __instance.Explode(); __instance.statusAmount = statusAmount; __instance.hasAffliction = hasAffliction; __instance.affliction = affliction; if (!PhotonNetwork.IsMasterClient) { AOEHealingFixPlugin.Logger.LogInfo((object)"[AOE DEBUG] Skipping healing application - not MasterClient"); return false; } AOEHealingFixPlugin.Logger.LogInfo((object)"[AOE DEBUG] MasterClient: Processing healing..."); float num = Mathf.Abs(statusAmount); Collider[] array = Physics.OverlapSphere(((Component)__instance).transform.position, __instance.range, LayerMask.op_Implicit(HelperFunctions.GetMask(__instance.mask))); List<Character> list = new List<Character>(); AOEHealingFixPlugin.Logger.LogInfo((object)$"[AOE DEBUG] Found {array.Length} colliders in range"); Collider[] array2 = array; Character item = default(Character); Character val2 = default(Character); foreach (Collider val in array2) { if (CharacterRagdoll.TryGetCharacterFromCollider(val, ref item) && !list.Contains(item)) { list.Add(item); } if (CharacterRagdoll.TryGetCharacterFromCollider(val, ref val2) && (Object)(object)val2.data.carriedPlayer != (Object)null && !list.Contains(val2.data.carriedPlayer)) { list.Add(val2.data.carriedPlayer); AOEHealingFixPlugin.Logger.LogInfo((object)("[AOE DEBUG] Found carried player " + val2.data.carriedPlayer.characterName + " via carrier " + val2.characterName)); } } foreach (Character item2 in list) { float num2 = Vector3.Distance(((Component)__instance).transform.position, item2.Center); if (num2 > __instance.range) { continue; } float num3 = Mathf.Pow(1f - num2 / __instance.range, __instance.factorPow); if (num3 < __instance.minFactor) { continue; } if (__instance.requireLineOfSigh) { RaycastHit val3 = HelperFunctions.LineCheck(((Component)__instance).transform.position, item2.Center, (LayerType)1, 0f, (QueryTriggerInteraction)1); if (Object.op_Implicit((Object)(object)((RaycastHit)(ref val3)).transform)) { continue; } } float num4 = num * num3; AOEHealingFixPlugin.Logger.LogInfo((object)$"[AOE DEBUG] Healing {item2.characterName} for {num4:F4} (factor: {num3:F4}) | IsCarried: {item2.data.isCarried}"); HealingReceiver component = ((Component)item2).GetComponent<HealingReceiver>(); if ((Object)(object)component != (Object)null) { ((MonoBehaviourPun)component).photonView.RPC("RPC_ApplyHealing", ((MonoBehaviourPun)component).photonView.Owner, new object[2] { (int)statusType, num4 }); if (addtlStatus != null) { STATUSTYPE[] array3 = addtlStatus; foreach (STATUSTYPE val4 in array3) { ((MonoBehaviourPun)component).photonView.RPC("RPC_ApplyHealing", ((MonoBehaviourPun)component).photonView.Owner, new object[2] { (int)val4, num4 }); } } if (hasAffliction && affliction != null) { ((MonoBehaviourPun)component).photonView.RPC("RPC_ApplyAffliction", ((MonoBehaviourPun)component).photonView.Owner, new object[1] { (int)affliction.GetAfflictionType() }); } } else { AOEHealingFixPlugin.Logger.LogError((object)("[AOE DEBUG] No HealingReceiver on " + item2.characterName + "! Make sure Character_Awake_Patch is running.")); } } AOEHealingFixPlugin.Logger.LogInfo((object)$"[AOE DEBUG] Healing applied to {list.Count} characters"); return false; } } [HarmonyPatch(typeof(Character), "Awake")] internal static class Character_Awake_Patch { [HarmonyPostfix] private static void Postfix(Character __instance) { if ((Object)(object)((Component)__instance).GetComponent<HealingReceiver>() == (Object)null) { ((Component)__instance).gameObject.AddComponent<HealingReceiver>(); AOEHealingFixPlugin.Logger.LogInfo((object)("Added HealingReceiver to " + __instance.characterName)); } } } public class HealingReceiver : MonoBehaviourPun { private Character character; private void Awake() { character = ((Component)this).GetComponent<Character>(); } [PunRPC] public void RPC_ApplyHealing(int statusTypeInt, float amount) { //IL_006d: Unknown result type (might be due to invalid IL or missing references) //IL_007e: Unknown result type (might be due to invalid IL or missing references) //IL_0095: Unknown result type (might be due to invalid IL or missing references) //IL_00af: Unknown result type (might be due to invalid IL or missing references) //IL_00cb: Unknown result type (might be due to invalid IL or missing references) if (!((MonoBehaviourPun)this).photonView.IsMine) { ManualLogSource logger = AOEHealingFixPlugin.Logger; Character obj = character; logger.LogInfo((object)("[HEAL] Skipped " + ((obj != null) ? obj.characterName : null) + " - not owner")); } else if (!((Object)(object)character == (Object)null) && !(amount <= 0f)) { STATUSTYPE val = (STATUSTYPE)statusTypeInt; float currentStatus = character.refs.afflictions.GetCurrentStatus(val); character.refs.afflictions.SubtractStatus(val, amount, true, false); float currentStatus2 = character.refs.afflictions.GetCurrentStatus(val); AOEHealingFixPlugin.Logger.LogInfo((object)($"[HEAL] {character.characterName} healed: {val} " + $"{currentStatus:F3} → {currentStatus2:F3} (-{amount:F3}) | IsCarried: {character.data.isCarried} | " + "Carrier: " + (((Object)(object)character.data.carrier != (Object)null) ? character.data.carrier.characterName : "none"))); } } [PunRPC] public void RPC_ApplyAffliction(int afflictionTypeInt) { //IL_0028: Unknown result type (might be due to invalid IL or missing references) //IL_0029: Unknown result type (might be due to invalid IL or missing references) if (((MonoBehaviourPun)this).photonView.IsMine && !((Object)(object)character == (Object)null)) { AfflictionType val = (AfflictionType)afflictionTypeInt; Affliction val2 = Affliction.CreateBlankAffliction(val); if (val2 != null) { character.refs.afflictions.AddAffliction(val2, true); } } } } }
BetterFriendJump.dll
Decompiled a week agousing System; using System.Diagnostics; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using System.Security; using System.Security.Permissions; using BepInEx; using BepInEx.Logging; using HarmonyLib; using Microsoft.CodeAnalysis; using UnityEngine; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)] [assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("0.0.0.0")] [module: UnverifiableCode] [module: RefSafetyRules(11)] namespace Microsoft.CodeAnalysis { [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] internal sealed class EmbeddedAttribute : Attribute { } } namespace System.Runtime.CompilerServices { [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] [AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)] internal sealed class RefSafetyRulesAttribute : Attribute { public readonly int Version; public RefSafetyRulesAttribute(int P_0) { Version = P_0; } } [AttributeUsage(AttributeTargets.Assembly, AllowMultiple = true)] internal sealed class IgnoresAccessChecksToAttribute : Attribute { public IgnoresAccessChecksToAttribute(string assemblyName) { } } } namespace BetterFriendJump { [HarmonyPatch(typeof(CharacterMovement), "JumpRpc")] public static class PatchJumpRpc { private const float FRIEND_JUMP_FORCE = 2050f; [HarmonyPostfix] private static void Postfix(CharacterMovement __instance, bool isPalJump) { //IL_0044: Unknown result type (might be due to invalid IL or missing references) //IL_004e: Unknown result type (might be due to invalid IL or missing references) if (!isPalJump) { return; } Character component = ((Component)__instance).GetComponent<Character>(); if ((Object)(object)component == (Object)null) { return; } foreach (Bodypart part in component.refs.ragdoll.partList) { part.AddForce(Vector3.up * 2050f, (ForceMode)5); } } } [BepInPlugin("jill920.BetterFriendJump", "BetterFriendJump", "1.0.1")] public class Plugin : BaseUnityPlugin { public const string MOD_GUID = "jill920.BetterFriendJump"; public const string MOD_NAME = "BetterFriendJump"; public const string MOD_VERSION = "1.0.1"; public static ManualLogSource Log; private void Awake() { Log = ((BaseUnityPlugin)this).Logger; Harmony.CreateAndPatchAll(Assembly.GetExecutingAssembly(), "jill920.BetterFriendJump"); Log.LogInfo((object)"[BetterFriendJump 1.0.1] Loaded! Friend jump force: 2000"); } } }
BetterFriendPull.dll
Decompiled a week agousing System; using System.Collections.Generic; using System.Diagnostics; using System.Reflection; using System.Reflection.Emit; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using System.Security; using System.Security.Permissions; using BepInEx; using BepInEx.Configuration; using BepInEx.Logging; using HarmonyLib; using Microsoft.CodeAnalysis; using Photon.Pun; using UnityEngine; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)] [assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")] [assembly: AssemblyCompany("BetterFriendPull")] [assembly: AssemblyConfiguration("Debug")] [assembly: AssemblyFileVersion("1.0.0.0")] [assembly: AssemblyInformationalVersion("1.0.0+4d83d2fcd8cc02921a02fe7ced1336060af8c951")] [assembly: AssemblyProduct("BetterFriendPull")] [assembly: AssemblyTitle("BetterFriendPull")] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("1.0.0.0")] [module: UnverifiableCode] [module: RefSafetyRules(11)] namespace Microsoft.CodeAnalysis { [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] internal sealed class EmbeddedAttribute : Attribute { } } namespace System.Runtime.CompilerServices { [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] [AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)] internal sealed class RefSafetyRulesAttribute : Attribute { public readonly int Version; public RefSafetyRulesAttribute(int P_0) { Version = P_0; } } } namespace BetterFriendPull { [HarmonyPatch(typeof(CharacterGrabbing), "Reach")] public static class PatchReachRange { [HarmonyTranspiler] private static IEnumerable<CodeInstruction> Transpiler(IEnumerable<CodeInstruction> instructions) { //IL_0080: Unknown result type (might be due to invalid IL or missing references) //IL_008a: Expected O, but got Unknown //IL_00fc: Unknown result type (might be due to invalid IL or missing references) //IL_0106: Expected O, but got Unknown List<CodeInstruction> list = new List<CodeInstruction>(instructions); for (int i = 0; i < list.Count; i++) { if (list[i].opcode == OpCodes.Ldc_R4 && Mathf.Approximately((float)list[i].operand, 4f)) { Debug.Log((object)$"[BetterFriendPull] Replacing 4f range with {Plugin.PullRange.Value}f"); list[i] = new CodeInstruction(OpCodes.Ldc_R4, (object)Plugin.PullRange.Value); } if (list[i].opcode == OpCodes.Ldc_R4 && Mathf.Approximately((float)list[i].operand, 60f)) { Debug.Log((object)$"[BetterFriendPull] Replacing 60f angle with {Plugin.PullAngle.Value}f"); list[i] = new CodeInstruction(OpCodes.Ldc_R4, (object)Plugin.PullAngle.Value); } } return list; } } [HarmonyPatch(typeof(CharacterGrabbing), "TargetCanBeHelped")] public static class PatchVerticalLimit { [HarmonyTranspiler] private static IEnumerable<CodeInstruction> Transpiler(IEnumerable<CodeInstruction> instructions) { //IL_00f0: Unknown result type (might be due to invalid IL or missing references) //IL_00fa: Expected O, but got Unknown List<CodeInstruction> list = new List<CodeInstruction>(instructions); for (int i = 0; i < list.Count; i++) { if (!(list[i].opcode == OpCodes.Ldc_R4) || !Mathf.Approximately((float)list[i].operand, 1f)) { continue; } bool flag = false; for (int j = Mathf.Max(0, i - 8); j < i; j++) { if (list[j].opcode == OpCodes.Callvirt && list[j].operand.ToString().Contains("get_isClimbing")) { flag = true; break; } } if (flag) { Debug.Log((object)$"[BetterFriendPull] Replacing vertical limit 1f with {Plugin.PullVerticalLimit.Value}f"); list[i] = new CodeInstruction(OpCodes.Ldc_R4, (object)Plugin.PullVerticalLimit.Value); } } return list; } } [HarmonyPatch(typeof(Character), "DragTowards")] public static class PatchPullForce { [HarmonyPrefix] private static void Prefix(Character __instance, Vector3 target, ref float force) { if (!Mathf.Approximately(Plugin.PullForceMultiplier.Value, 1f)) { force *= Plugin.PullForceMultiplier.Value; if (Plugin.PullForceMultiplier.Value != 1f) { Debug.Log((object)$"[BetterFriendPull] Pull force multiplied: {force / Plugin.PullForceMultiplier.Value:F0} → {force:F0}"); } } } } public static class StaminaFreezeManager { private static HashSet<Character> _protectedChars = new HashSet<Character>(); private static Dictionary<Character, float> _protectUntil = new Dictionary<Character, float>(); public static void ProtectCharacter(Character c) { if (Plugin.EnableStaminaFreeze.Value) { _protectedChars.Add(c); _protectUntil[c] = Time.time + Plugin.StaminaFreezeCooldown.Value; } } public static bool IsProtected(Character c) { if (!Plugin.EnableStaminaFreeze.Value) { return false; } float time = Time.time; List<Character> list = new List<Character>(); foreach (KeyValuePair<Character, float> item in _protectUntil) { if (time > item.Value) { list.Add(item.Key); } } foreach (Character item2 in list) { _protectedChars.Remove(item2); _protectUntil.Remove(item2); } return _protectedChars.Contains(c); } } [HarmonyPatch(typeof(Character), "DragTowards")] public static class PatchTrackPullSimple { [HarmonyPrefix] private static void Prefix(Character __instance) { StaminaFreezeManager.ProtectCharacter(__instance); if (((MonoBehaviourPun)__instance).photonView.IsMine && Plugin.EnableStaminaFreeze.Value) { Debug.Log((object)("[BetterFriendPull] Stamina frozen for " + __instance.characterName)); } } } [HarmonyPatch(typeof(Character), "UseStamina")] public static class PatchBlockStamina { [HarmonyPrefix] private static bool Prefix(Character __instance) { if (StaminaFreezeManager.IsProtected(__instance)) { return false; } return true; } } [BepInPlugin("jill920.BetterFriendPull", "BetterFriendPull", "1.0.1")] public class Plugin : BaseUnityPlugin { public static ManualLogSource Log; public static ConfigEntry<float> PullRange; public static ConfigEntry<float> PullAngle; public static ConfigEntry<float> PullVerticalLimit; public static ConfigEntry<float> PullForceMultiplier; public static ConfigEntry<bool> EnableStaminaFreeze; public static ConfigEntry<float> StaminaFreezeCooldown; public static HashSet<Character> PullProtectedCharacters = new HashSet<Character>(); public static Dictionary<Character, float> PullProtectionEndTime = new Dictionary<Character, float>(); private void Awake() { //IL_00f0: Unknown result type (might be due to invalid IL or missing references) //IL_00f6: Expected O, but got Unknown Log = ((BaseUnityPlugin)this).Logger; PullRange = ((BaseUnityPlugin)this).Config.Bind<float>("Settings", "Pull Range", 6f, "Max distance to detect climbing friends (vanilla: 4)"); PullAngle = ((BaseUnityPlugin)this).Config.Bind<float>("Settings", "Pull Angle", 60f, "Cone angle in degrees (vanilla: 60)"); PullVerticalLimit = ((BaseUnityPlugin)this).Config.Bind<float>("Settings", "Vertical Pull Limit", 1f, "Max height difference to pull (vanilla: 1)"); PullForceMultiplier = ((BaseUnityPlugin)this).Config.Bind<float>("Settings", "Pull Force Multiplier", 1f, "Multiply pull force (vanilla: 1)"); EnableStaminaFreeze = ((BaseUnityPlugin)this).Config.Bind<bool>("Stamina", "Enable Stamina Freeze", true, "Prevent stamina drain while being pulled"); StaminaFreezeCooldown = ((BaseUnityPlugin)this).Config.Bind<float>("Stamina", "Stamina Freeze Cooldown", 0.8f, "Seconds after pull ends to keep stamina frozen (prevents instant drain)"); Harmony val = new Harmony(((BaseUnityPlugin)this).Info.Metadata.GUID); val.PatchAll(); Log.LogInfo((object)$"BetterFriendPull loaded. Range: {PullRange.Value}m, Stamina Freeze: {EnableStaminaFreeze.Value}, Cooldown: {StaminaFreezeCooldown.Value}s"); } private void Update() { float time = Time.time; List<Character> list = new List<Character>(); foreach (KeyValuePair<Character, float> item in PullProtectionEndTime) { if (time > item.Value) { list.Add(item.Key); } } foreach (Character item2 in list) { PullProtectedCharacters.Remove(item2); PullProtectionEndTime.Remove(item2); if ((Object)(object)item2 != (Object)null && ((MonoBehaviourPun)item2).photonView.IsMine) { Log.LogDebug((object)("Stamina freeze expired for " + item2.characterName)); } } if (!Application.isFocused || (Object)(object)Character.localCharacter == (Object)null || (!Input.GetKey((KeyCode)306) && !Input.GetKey((KeyCode)305))) { return; } if (Input.GetKeyDown((KeyCode)273)) { ConfigEntry<float> pullRange = PullRange; pullRange.Value += 0.5f; Log.LogInfo((object)$"↑ Pull Range increased to {PullRange.Value}m"); } if (Input.GetKeyDown((KeyCode)274)) { ConfigEntry<float> pullRange2 = PullRange; pullRange2.Value -= 0.5f; Log.LogInfo((object)$"↓ Pull Range decreased to {PullRange.Value}m"); } if (Input.GetKeyDown((KeyCode)275)) { ConfigEntry<float> pullAngle = PullAngle; pullAngle.Value += 5f; Log.LogInfo((object)$"→ Pull Angle increased to {PullAngle.Value}°"); } if (Input.GetKeyDown((KeyCode)276)) { ConfigEntry<float> pullAngle2 = PullAngle; pullAngle2.Value -= 5f; Log.LogInfo((object)$"← Pull Angle decreased to {PullAngle.Value}°"); } if (Input.GetKeyDown((KeyCode)280)) { ConfigEntry<float> pullVerticalLimit = PullVerticalLimit; pullVerticalLimit.Value += 0.5f; Log.LogInfo((object)$"PgUp Vertical Limit increased to {PullVerticalLimit.Value}m"); } if (Input.GetKeyDown((KeyCode)281)) { ConfigEntry<float> pullVerticalLimit2 = PullVerticalLimit; pullVerticalLimit2.Value -= 0.5f; Log.LogInfo((object)$"PgDn Vertical Limit decreased to {PullVerticalLimit.Value}m"); } if (Input.GetKey((KeyCode)304) || Input.GetKey((KeyCode)303)) { if (Input.GetKeyDown((KeyCode)273)) { ConfigEntry<float> pullForceMultiplier = PullForceMultiplier; pullForceMultiplier.Value += 0.25f; Log.LogInfo((object)$"↑ Pull Force increased to {PullForceMultiplier.Value}x"); } if (Input.GetKeyDown((KeyCode)274)) { ConfigEntry<float> pullForceMultiplier2 = PullForceMultiplier; pullForceMultiplier2.Value -= 0.25f; Log.LogInfo((object)$"↓ Pull Force decreased to {PullForceMultiplier.Value}x"); } } if (Input.GetKeyDown((KeyCode)115)) { EnableStaminaFreeze.Value = !EnableStaminaFreeze.Value; Log.LogInfo((object)("Stamina Freeze: " + (EnableStaminaFreeze.Value ? "ENABLED" : "DISABLED"))); } } } }
BlowgunEnhanced.dll
Decompiled a week agousing System; using System.Diagnostics; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using System.Security; using System.Security.Permissions; using BepInEx; using BepInEx.Logging; using HarmonyLib; using Microsoft.CodeAnalysis; using Photon.Pun; using UnityEngine; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)] [assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")] [assembly: AssemblyCompany("BlowgunEnhanced")] [assembly: AssemblyConfiguration("Debug")] [assembly: AssemblyFileVersion("1.0.0.0")] [assembly: AssemblyInformationalVersion("1.0.0+e2fc2576a986539ed321b56e932194c0a5465ff8")] [assembly: AssemblyProduct("BlowgunEnhanced")] [assembly: AssemblyTitle("BlowgunEnhanced")] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("1.0.0.0")] [module: UnverifiableCode] [module: RefSafetyRules(11)] namespace Microsoft.CodeAnalysis { [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] internal sealed class EmbeddedAttribute : Attribute { } } namespace System.Runtime.CompilerServices { [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] [AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)] internal sealed class RefSafetyRulesAttribute : Attribute { public readonly int Version; public RefSafetyRulesAttribute(int P_0) { Version = P_0; } } } namespace BlowgunEnhanced { [BepInPlugin("jill920.blowgunenhanced", "Blowgun Enhanced", "1.0.0")] public class BlowgunEnhancedPlugin : BaseUnityPlugin { public const string MOD_GUID = "jill920.blowgunenhanced"; public const string MOD_NAME = "Blowgun Enhanced"; public const string MOD_VERSION = "1.0.0"; public static BlowgunEnhancedPlugin Instance; public static ManualLogSource Logger; public static bool IsDizzinessModInstalled; public static bool IsFatigueModInstalled; public static bool debugMode; private void Awake() { Instance = this; Logger = ((BaseUnityPlugin)this).Logger; debugMode = ((BaseUnityPlugin)this).Config.Bind<bool>("Debug", "EnableLogs", false, "Enable debug logging").Value; CheckForInstalledMods(); try { Harmony.CreateAndPatchAll(Assembly.GetExecutingAssembly(), "jill920.blowgunenhanced"); Logger.LogInfo((object)"[Blowgun Enhanced 1.0.0] Loaded successfully!"); Logger.LogInfo((object)$" Dizziness Mod detected (initial): {IsDizzinessModInstalled}"); Logger.LogInfo((object)$" Fatigue Mod detected (initial): {IsFatigueModInstalled}"); } catch (Exception ex) { Logger.LogError((object)("Failed to load: " + ex.Message)); } } private void CheckForInstalledMods() { IsDizzinessModInstalled = false; IsFatigueModInstalled = false; Assembly[] assemblies = AppDomain.CurrentDomain.GetAssemblies(); foreach (Assembly assembly in assemblies) { try { if (assembly.GetType("DizzinessMod.DizzinessTracker") != null) { IsDizzinessModInstalled = true; } if (assembly.GetType("FatigueMod.FatigueTracker") != null) { IsFatigueModInstalled = true; } } catch { } } } } } namespace BlowgunEnhanced.Patches { [HarmonyPatch(typeof(Action_RaycastDart), "RPC_DartImpact")] internal static class Action_RaycastDart_Patch { private static bool _fatigueCheckDone; private static bool _fatigueAvailable; private static bool _dizzinessCheckDone; private static bool _dizzinessAvailable; private static bool IsFatigueModPresent() { if (_fatigueCheckDone) { return _fatigueAvailable; } _fatigueCheckDone = true; if (BlowgunEnhancedPlugin.IsFatigueModInstalled) { _fatigueAvailable = true; return true; } try { Assembly[] assemblies = AppDomain.CurrentDomain.GetAssemblies(); foreach (Assembly assembly in assemblies) { if (assembly.GetType("FatigueMod.FatigueTracker") != null) { _fatigueAvailable = true; BlowgunEnhancedPlugin.IsFatigueModInstalled = true; BlowgunEnhancedPlugin.Logger.LogInfo((object)"Blowgun: Fatigue Mod detected at runtime!"); return true; } } } catch { } return false; } private static bool IsDizzinessModPresent() { if (_dizzinessCheckDone) { return _dizzinessAvailable; } _dizzinessCheckDone = true; if (BlowgunEnhancedPlugin.IsDizzinessModInstalled) { _dizzinessAvailable = true; return true; } try { Assembly[] assemblies = AppDomain.CurrentDomain.GetAssemblies(); foreach (Assembly assembly in assemblies) { if (assembly.GetType("DizzinessMod.DizzinessTracker") != null) { _dizzinessAvailable = true; BlowgunEnhancedPlugin.IsDizzinessModInstalled = true; BlowgunEnhancedPlugin.Logger.LogInfo((object)"Blowgun: Dizziness Mod detected at runtime!"); return true; } } } catch { } return false; } [HarmonyPostfix] private static void Postfix(int characterID, Vector3 origin, Vector3 endpoint) { if (characterID == -1) { return; } try { PhotonView photonView = PhotonNetwork.GetPhotonView(characterID); if ((Object)(object)photonView == (Object)null) { return; } Character component = ((Component)photonView).GetComponent<Character>(); if ((Object)(object)component == (Object)null || !component.IsLocal) { return; } bool flag = IsDizzinessModPresent(); bool flag2 = IsFatigueModPresent(); if (flag || flag2) { if (flag) { ClearDizziness(component); } if (flag2) { ClearFatigue(component); } if (BlowgunEnhancedPlugin.debugMode) { BlowgunEnhancedPlugin.Logger.LogInfo((object)("Blowgun: Cleared Dizziness/Fatigue for " + component.characterName)); } } } catch (Exception ex) { BlowgunEnhancedPlugin.Logger.LogWarning((object)("Failed to process blowgun hit: " + ex.Message)); } } private static void ClearDizziness(Character character) { try { Component component = ((Component)character).GetComponent("DizzinessMod.DizzinessTracker"); if ((Object)(object)component == (Object)null) { return; } FieldInfo field = ((object)component).GetType().GetField("dizzinessValue", BindingFlags.Instance | BindingFlags.Public); if (field == null) { return; } float num = (float)field.GetValue(component); if (num > 0.01f) { field.SetValue(component, 0f); if (BlowgunEnhancedPlugin.debugMode) { BlowgunEnhancedPlugin.Logger.LogInfo((object)$"Blowgun: Cleared Dizziness: {num:F3} → 0"); } } } catch (Exception ex) { BlowgunEnhancedPlugin.Logger.LogWarning((object)("Failed to clear Dizziness: " + ex.Message)); } } private static void ClearFatigue(Character character) { try { Component component = ((Component)character).GetComponent("FatigueMod.FatigueTracker"); if ((Object)(object)component == (Object)null) { return; } FieldInfo field = ((object)component).GetType().GetField("fatigueValue", BindingFlags.Instance | BindingFlags.Public); if (!(field == null)) { float num = (float)field.GetValue(component); field.SetValue(component, 0f); if (BlowgunEnhancedPlugin.debugMode && num > 0.01f) { BlowgunEnhancedPlugin.Logger.LogInfo((object)$"Blowgun: Cleared Fatigue: {num:F3} → 0"); } } } catch (Exception ex) { BlowgunEnhancedPlugin.Logger.LogWarning((object)("Failed to clear Fatigue: " + ex.Message)); } } } }
CursedSkullEnhanced.dll
Decompiled a week agousing System; using System.Diagnostics; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using System.Security; using System.Security.Permissions; using BepInEx; using BepInEx.Logging; using HarmonyLib; using Microsoft.CodeAnalysis; using Peak.Afflictions; using UnityEngine; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)] [assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")] [assembly: AssemblyCompany("CursedSkullEnhanced")] [assembly: AssemblyConfiguration("Debug")] [assembly: AssemblyFileVersion("1.0.0.0")] [assembly: AssemblyInformationalVersion("1.0.0+0a4f7b16fa778ffc5cd0ca73c4eecf8a56cf834e")] [assembly: AssemblyProduct("CursedSkullEnhanced")] [assembly: AssemblyTitle("CursedSkullEnhanced")] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("1.0.0.0")] [module: UnverifiableCode] [module: RefSafetyRules(11)] namespace Microsoft.CodeAnalysis { [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] internal sealed class EmbeddedAttribute : Attribute { } } namespace System.Runtime.CompilerServices { [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] [AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)] internal sealed class RefSafetyRulesAttribute : Attribute { public readonly int Version; public RefSafetyRulesAttribute(int P_0) { Version = P_0; } } } namespace CursedSkullEnhanced { [BepInPlugin("jill920.cursedskullenhanced", "Cursed Skull Enhanced", "1.0.0")] public class CursedSkullEnhancedPlugin : BaseUnityPlugin { public const string MOD_GUID = "jill920.cursedskullenhanced"; public const string MOD_NAME = "Cursed Skull Enhanced"; public const string MOD_VERSION = "1.0.0"; public static CursedSkullEnhancedPlugin Instance; public static ManualLogSource Logger; public static bool IsDizzinessModInstalled; public static bool IsFatigueModInstalled; public static bool debugMode; private void Awake() { Instance = this; Logger = ((BaseUnityPlugin)this).Logger; debugMode = ((BaseUnityPlugin)this).Config.Bind<bool>("Debug", "EnableLogs", false, "Enable debug logging").Value; Harmony.CreateAndPatchAll(Assembly.GetExecutingAssembly(), "jill920.cursedskullenhanced"); CheckForInstalledMods(); Logger.LogInfo((object)"[Cursed Skull Enhanced 1.0.0] Loaded successfully!"); Logger.LogInfo((object)$" Dizziness Mod detected: {IsDizzinessModInstalled}"); Logger.LogInfo((object)$" Fatigue Mod detected: {IsFatigueModInstalled}"); } private void CheckForInstalledMods() { IsDizzinessModInstalled = false; IsFatigueModInstalled = false; Assembly[] assemblies = AppDomain.CurrentDomain.GetAssemblies(); foreach (Assembly assembly in assemblies) { try { if (assembly.GetType("DizzinessMod.DizzinessTracker") != null) { IsDizzinessModInstalled = true; } if (assembly.GetType("FatigueMod.FatigueTracker") != null) { IsFatigueModInstalled = true; } } catch { } } } } } namespace CursedSkullEnhanced.Patches { [HarmonyPatch(typeof(Action_ApplyMassAffliction), "TryAddAfflictionToLocalCharacter")] internal static class Action_ApplyMassAffliction_Patch { [HarmonyPostfix] private static void Postfix(Action_ApplyMassAffliction __instance) { Character localCharacter = Character.localCharacter; if (!((Object)(object)localCharacter == (Object)null) && ((Action_ApplyAffliction)__instance).affliction is Affliction_ClearAllStatus) { ClearDizzinessAndFatigue(localCharacter); if (CursedSkullEnhancedPlugin.debugMode) { CursedSkullEnhancedPlugin.Logger.LogInfo((object)("Cursed Skull: Cleared Dizziness/Fatigue for " + localCharacter.characterName)); } } } private static void ClearDizzinessAndFatigue(Character character) { if (IsDizzinessModPresent()) { ClearDizziness(character); } if (IsFatigueModPresent()) { ClearFatigue(character); } } private static bool IsDizzinessModPresent() { if (CursedSkullEnhancedPlugin.IsDizzinessModInstalled) { return true; } try { Assembly[] assemblies = AppDomain.CurrentDomain.GetAssemblies(); foreach (Assembly assembly in assemblies) { if (assembly.GetType("DizzinessMod.DizzinessTracker") != null) { CursedSkullEnhancedPlugin.IsDizzinessModInstalled = true; return true; } } } catch { } return false; } private static bool IsFatigueModPresent() { if (CursedSkullEnhancedPlugin.IsFatigueModInstalled) { return true; } try { Assembly[] assemblies = AppDomain.CurrentDomain.GetAssemblies(); foreach (Assembly assembly in assemblies) { if (assembly.GetType("FatigueMod.FatigueTracker") != null) { CursedSkullEnhancedPlugin.IsFatigueModInstalled = true; return true; } } } catch { } return false; } private static void ClearDizziness(Character character) { try { Component component = ((Component)character).GetComponent("DizzinessMod.DizzinessTracker"); if ((Object)(object)component == (Object)null) { return; } FieldInfo field = ((object)component).GetType().GetField("dizzinessValue", BindingFlags.Instance | BindingFlags.Public); if (field == null) { return; } float num = (float)field.GetValue(component); if (num > 0.01f) { field.SetValue(component, 0f); if (CursedSkullEnhancedPlugin.debugMode) { CursedSkullEnhancedPlugin.Logger.LogInfo((object)$"Cleared Dizziness: {num:F3} → 0"); } } } catch (Exception ex) { CursedSkullEnhancedPlugin.Logger.LogWarning((object)("Failed to clear Dizziness: " + ex.Message)); } } private static void ClearFatigue(Character character) { try { Component component = ((Component)character).GetComponent("FatigueMod.FatigueTracker"); if ((Object)(object)component == (Object)null) { return; } FieldInfo field = ((object)component).GetType().GetField("fatigueValue", BindingFlags.Instance | BindingFlags.Public); if (!(field == null)) { float num = (float)field.GetValue(component); field.SetValue(component, 0f); if (CursedSkullEnhancedPlugin.debugMode && num > 0.01f) { CursedSkullEnhancedPlugin.Logger.LogInfo((object)$"Cleared Fatigue: {num:F3} → 0"); } } } catch (Exception ex) { CursedSkullEnhancedPlugin.Logger.LogWarning((object)("Failed to clear Fatigue: " + ex.Message)); } } } [HarmonyPatch(typeof(ItemCooking), "RPC_CookingExplode")] internal static class ItemCooking_Explode_Patch { private const float CURSED_SKULL_RADIUS = 900f; private const int CURSED_SKULL_ITEM_ID = 25; [HarmonyPrefix] private static void Prefix(ItemCooking __instance) { //IL_0030: Unknown result type (might be due to invalid IL or missing references) //IL_0035: Unknown result type (might be due to invalid IL or missing references) //IL_005e: Unknown result type (might be due to invalid IL or missing references) //IL_0061: Unknown result type (might be due to invalid IL or missing references) Item item = ((ItemComponent)__instance).item; if ((Object)(object)item == (Object)null || item.itemID != 25) { return; } Vector3 position = ((Component)__instance).transform.position; foreach (Character allCharacter in Character.AllCharacters) { if (!((Object)(object)allCharacter == (Object)null)) { float num = Vector3.Distance(position, allCharacter.Center); if (!(num > 900f)) { ClearDizzinessAndFatigue(allCharacter); } } } CursedSkullEnhancedPlugin.Logger.LogInfo((object)$"Cursed Skull explosion: Cleared Dizziness/Fatigue for players within {900f} units"); } private static void ClearDizzinessAndFatigue(Character character) { if (CursedSkullEnhancedPlugin.IsDizzinessModInstalled) { ClearDizziness(character); } if (CursedSkullEnhancedPlugin.IsFatigueModInstalled) { ClearFatigue(character); } } private static void ClearDizziness(Character character) { try { Component component = ((Component)character).GetComponent("DizzinessMod.DizzinessTracker"); if ((Object)(object)component == (Object)null) { return; } FieldInfo field = ((object)component).GetType().GetField("dizzinessValue", BindingFlags.Instance | BindingFlags.Public); if (field == null) { return; } float num = (float)field.GetValue(component); if (num > 0.01f) { field.SetValue(component, 0f); if (CursedSkullEnhancedPlugin.debugMode) { CursedSkullEnhancedPlugin.Logger.LogInfo((object)$"Cleared Dizziness for {character.characterName}: {num:F3} → 0"); } } } catch (Exception ex) { CursedSkullEnhancedPlugin.Logger.LogWarning((object)("Failed to clear Dizziness: " + ex.Message)); } } private static bool IsFatigueModPresent() { if (CursedSkullEnhancedPlugin.IsFatigueModInstalled) { return true; } try { Assembly[] assemblies = AppDomain.CurrentDomain.GetAssemblies(); foreach (Assembly assembly in assemblies) { if (assembly.GetType("FatigueMod.FatigueTracker") != null) { CursedSkullEnhancedPlugin.IsFatigueModInstalled = true; return true; } } } catch { } return false; } private static void ClearFatigue(Character character) { if (!IsFatigueModPresent()) { return; } try { Component component = ((Component)character).GetComponent("FatigueMod.FatigueTracker"); if ((Object)(object)component == (Object)null) { return; } FieldInfo field = ((object)component).GetType().GetField("fatigueValue", BindingFlags.Instance | BindingFlags.Public); if (!(field == null)) { field.SetValue(component, 0f); if (CursedSkullEnhancedPlugin.debugMode) { CursedSkullEnhancedPlugin.Logger.LogInfo((object)("Cleared Fatigue for " + character.characterName)); } } } catch (Exception ex) { CursedSkullEnhancedPlugin.Logger.LogWarning((object)("Failed to clear Fatigue: " + ex.Message)); } } } }
DizzinessMod.dll
Decompiled a week agousing System; using System.Collections.Generic; using System.Diagnostics; using System.IO; using System.Linq; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using System.Security; using System.Security.Permissions; using BepInEx; using BepInEx.Configuration; using BepInEx.Logging; using HarmonyLib; using Microsoft.CodeAnalysis; using Peak.Afflictions; using Photon.Pun; using UnityEngine; using UnityEngine.UI; using Zorro.Core; using Zorro.Core.CLI; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)] [assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("0.0.0.0")] [module: UnverifiableCode] [module: RefSafetyRules(11)] namespace Microsoft.CodeAnalysis { [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] internal sealed class EmbeddedAttribute : Attribute { } } namespace System.Runtime.CompilerServices { [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] [AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)] internal sealed class RefSafetyRulesAttribute : Attribute { public readonly int Version; public RefSafetyRulesAttribute(int P_0) { Version = P_0; } } } namespace DizzinessMod { [HarmonyPatch(typeof(Action_ModifyStatus), "RunAction")] internal static class Action_ModifyStatus_Patch { private static readonly HashSet<ushort> healingItemIDs = new HashSet<ushort> { 24 }; private static FieldInfo itemField; private static FieldInfo characterField; private static PropertyInfo characterProperty; [HarmonyPostfix] private static void Postfix(Action_ModifyStatus __instance) { //IL_01a3: Unknown result type (might be due to invalid IL or missing references) if (itemField == null) { itemField = typeof(ItemActionBase).GetField("item", BindingFlags.Instance | BindingFlags.NonPublic); } object? obj = itemField?.GetValue(__instance); Item val = (Item)((obj is Item) ? obj : null); if ((Object)(object)val == (Object)null || __instance.changeAmount >= 0f || !healingItemIDs.Contains(val.itemID)) { return; } if (characterProperty == null) { characterProperty = typeof(ItemActionBase).GetProperty("character", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); } Character val2 = null; if (characterProperty != null) { object? value = characterProperty.GetValue(__instance); val2 = (Character)((value is Character) ? value : null); } if ((Object)(object)val2 == (Object)null) { if (characterField == null) { characterField = typeof(ItemActionBase).GetField("character", BindingFlags.Instance | BindingFlags.NonPublic); } object? obj2 = characterField?.GetValue(__instance); val2 = (Character)((obj2 is Character) ? obj2 : null); } if ((Object)(object)val2 == (Object)null) { DizzinessPlugin.Logger.LogWarning((object)$"Target character is null for item {((Object)val).name} (ID:{val.itemID})"); return; } DizzinessPlugin.Logger.LogInfo((object)$"Healing item used - Item: {((Object)val).name} (ID:{val.itemID}), Target: {val2.characterName}, Status: {__instance.statusType}, Amount: {__instance.changeAmount}"); if (val2.IsLocal) { if (val2.data.isSkeleton && !val2.data.dead && !val2.data.fullyPassedOut) { DizzinessPlugin.Logger.LogInfo((object)"Skipping dizziness reduction - target is a living skeleton"); return; } DizzinessTracker component = ((Component)val2).GetComponent<DizzinessTracker>(); if ((Object)(object)component != (Object)null) { float num = Mathf.Abs(__instance.changeAmount) * 0.1f; float dizzinessValue = component.dizzinessValue; component.dizzinessValue = Mathf.Max(0f, component.dizzinessValue - num); DizzinessPlugin.Logger.LogInfo((object)$"Reduced dizziness by {num:F3} (from {dizzinessValue:F3} to {component.dizzinessValue:F3})"); } else { DizzinessPlugin.Logger.LogWarning((object)("No DizzinessTracker found on " + val2.characterName)); } } else { DizzinessPlugin.Logger.LogInfo((object)("Skipping dizziness reduction - target is not local player: " + val2.characterName)); } } } [HarmonyPatch(typeof(CharacterData), "set_isSkeleton")] internal static class CharacterData_SetSkeleton_Patch { [HarmonyPostfix] private static void Postfix(CharacterData __instance, bool value) { if (!value) { return; } Character component = ((Component)__instance).GetComponent<Character>(); if ((Object)(object)component == (Object)null || !component.IsLocal) { return; } Component component2 = ((Component)component).GetComponent("DizzinessMod.DizzinessTracker"); if ((Object)(object)component2 != (Object)null) { FieldInfo field = ((object)component2).GetType().GetField("dizzinessValue", BindingFlags.Instance | BindingFlags.Public); if (field != null) { field.SetValue(component2, 0f); DizzinessPlugin.Logger.LogInfo((object)"Cleared dizziness on skeleton transformation"); } } } } [HarmonyPatch(typeof(BarAffliction), "ChangeAffliction")] internal static class BarAffliction_ChangeAffliction_Patch { [HarmonyPrefix] private static bool Prefix(BarAffliction __instance, StaminaBar bar) { //IL_002a: Unknown result type (might be due to invalid IL or missing references) //IL_0035: Expected O, but got Unknown //IL_004c: Unknown result type (might be due to invalid IL or missing references) //IL_0057: Expected O, but got Unknown //IL_0071: Unknown result type (might be due to invalid IL or missing references) if (((Object)((Component)__instance).gameObject).name != "DizzinessCustomBar") { return true; } Character observedCharacter = Character.observedCharacter; if ((Object)observedCharacter == (Object)null) { return false; } DizzinessTracker component = ((Component)observedCharacter).GetComponent<DizzinessTracker>(); if ((Object)component == (Object)null) { return false; } float dizzinessValue = component.dizzinessValue; __instance.size = bar.fullBar.sizeDelta.x * dizzinessValue; if (dizzinessValue > 0.01f) { if (__instance.size < bar.minAfflictionWidth) { __instance.size = bar.minAfflictionWidth; } ((Component)__instance).gameObject.SetActive(true); } else { ((Component)__instance).gameObject.SetActive(false); } return false; } } [HarmonyPatch(typeof(CharacterMovement), "CameraLook")] internal static class CameraDizzinessPatch { private static float swayPhase; private static float lurchTimer; [HarmonyPrefix] private static void Prefix(CharacterMovement __instance) { //IL_015e: Unknown result type (might be due to invalid IL or missing references) //IL_01a8: Unknown result type (might be due to invalid IL or missing references) //IL_01ad: Unknown result type (might be due to invalid IL or missing references) //IL_01b2: Unknown result type (might be due to invalid IL or missing references) //IL_01ba: Unknown result type (might be due to invalid IL or missing references) //IL_01bc: Unknown result type (might be due to invalid IL or missing references) //IL_03f6: Unknown result type (might be due to invalid IL or missing references) //IL_0443: Unknown result type (might be due to invalid IL or missing references) //IL_0448: Unknown result type (might be due to invalid IL or missing references) //IL_044d: Unknown result type (might be due to invalid IL or missing references) //IL_045e: Unknown result type (might be due to invalid IL or missing references) //IL_0468: Unknown result type (might be due to invalid IL or missing references) //IL_046d: Unknown result type (might be due to invalid IL or missing references) Character component = ((Component)__instance).GetComponent<Character>(); if ((Object)(object)component == (Object)null || !component.IsLocal) { return; } DizzinessTracker component2 = ((Component)component).GetComponent<DizzinessTracker>(); if ((Object)(object)component2 == (Object)null) { return; } float dizzinessValue = component2.dizzinessValue; if (dizzinessValue <= 0.05f) { return; } float num = Mathf.Clamp01((dizzinessValue - 0.05f) / 0.95f); if ((Object)(object)component.input != (Object)null && dizzinessValue > 0.15f) { float num2 = Mathf.Clamp01((dizzinessValue - 0.15f) / 0.85f); float num3 = Mathf.Sin(Time.time * 1.2f) * 90f * num2; num3 += Mathf.Sin(Time.time * 0.6f) * 45f * num2; float num4 = num3 * (MathF.PI / 180f); Vector2 val = default(Vector2); ((Vector2)(ref val))..ctor(component.input.lookInput.x * Mathf.Cos(num4) - component.input.lookInput.y * Mathf.Sin(num4), component.input.lookInput.x * Mathf.Sin(num4) + component.input.lookInput.y * Mathf.Cos(num4)); float num5 = num2 * 0.8f; val += new Vector2((Mathf.PerlinNoise(Time.time * 4f, 0f) - 0.5f) * 2f * num5, (Mathf.PerlinNoise(Time.time * 3f, 1000f) - 0.5f) * 2f * num5); component.input.lookInput = val; } float num6 = 0.8f + dizzinessValue * 0.8f; swayPhase += Time.deltaTime * num6; float num7 = Mathf.Sin(swayPhase) * num * 60f; float num8 = Mathf.Cos(swayPhase * 0.8f) * num * 30f; float num9 = Mathf.Sin(swayPhase * 0.5f) * num * 20f; lurchTimer += Time.deltaTime; if (dizzinessValue > 0.4f && lurchTimer > 3f) { float num10 = (dizzinessValue - 0.4f) / 0.6f; if (Random.value < num10 * 0.4f) { float num11 = Random.Range(-35f, 35f) * num10; float num12 = Random.Range(-20f, 20f) * num10; num7 += num11; num8 += num12; lurchTimer = 0f; if (DizzinessPlugin.debugMode.Value) { DizzinessPlugin.Logger.LogInfo((object)$"Camera lurch! Yaw:{num11:F0}, Pitch:{num12:F0}"); } } } float num13 = num; num7 += (Mathf.PerlinNoise(Time.time * 1.5f, 0f) - 0.5f) * 8f * num13; num8 += (Mathf.PerlinNoise(Time.time * 1.2f, 1000f) - 0.5f) * 5f * num13; component.data.lookValues.x += num7 * Time.deltaTime * 3f; component.data.lookValues.y += num8 * Time.deltaTime * 3f; component.data.lookValues.y = Mathf.Clamp(component.data.lookValues.y, -85f, 85f); if (dizzinessValue > 0.3f) { float num14 = Mathf.Clamp01((dizzinessValue - 0.3f) / 0.7f); float num15 = num14 * 0.4f; CharacterInput input = component.input; input.movementInput += new Vector2((Mathf.PerlinNoise(Time.time * 2f, 0f) - 0.5f) * 2f * num15, (Mathf.PerlinNoise(Time.time * 1.5f, 1000f) - 0.5f) * 2f * num15); component.input.movementInput = Vector2.ClampMagnitude(component.input.movementInput, 1f); } } } [HarmonyPatch(typeof(CharacterAfflictions))] [HarmonyPatch(/*Could not decode attribute arguments.*/)] internal static class CharacterAfflictions_statusSum_Patch { [HarmonyPostfix] private static void Postfix(CharacterAfflictions __instance, ref float __result) { //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_0012: Expected O, but got Unknown //IL_0026: Unknown result type (might be due to invalid IL or missing references) //IL_0031: Expected O, but got Unknown //IL_003e: Unknown result type (might be due to invalid IL or missing references) //IL_0049: Expected O, but got Unknown if (!((Object)__instance.character == (Object)null)) { DizzinessTracker component = ((Component)__instance.character).GetComponent<DizzinessTracker>(); if (!((Object)component == (Object)null) && !((Object)__instance.character.data == (Object)null)) { __result += component.dizzinessValue; } } } } public static class CharacterFallHelper { private static MethodInfo _fallMethod; public static void TriggerFall(Character character, float seconds, float screenShake = 0f) { if ((Object)(object)character == (Object)null || !character.IsLocal) { return; } if (_fallMethod == null) { _fallMethod = typeof(Character).GetMethod("Fall", BindingFlags.Instance | BindingFlags.NonPublic); if (_fallMethod == null) { DizzinessPlugin.Logger.LogError((object)"Could not find Character.Fall method!"); return; } } _fallMethod.Invoke(character, new object[2] { seconds, screenShake }); if (DizzinessPlugin.debugMode.Value) { DizzinessPlugin.Logger.LogInfo((object)$"Stumble triggered! Duration: {seconds:F2}s, Dizziness: {GetDizzinessValue(character):F2}"); } } public static void TriggerScreenShake(float amount, float duration = 0.2f, float scale = 15f) { if (!((Object)(object)GamefeelHandler.instance == (Object)null)) { GamefeelHandler.instance.AddPerlinShake(amount, duration, scale); } } private static float GetDizzinessValue(Character character) { DizzinessTracker component = ((Component)character).GetComponent<DizzinessTracker>(); return ((Object)(object)component != (Object)null) ? component.dizzinessValue : 0f; } } [HarmonyPatch(typeof(Character), "Awake")] internal static class Character_Awake_Patch { [HarmonyPostfix] private static void Postfix(Character __instance) { if ((Object)(object)((Component)__instance).GetComponent<DizzinessTracker>() == (Object)null) { ((Component)__instance).gameObject.AddComponent<DizzinessTracker>(); } if ((Object)(object)((Component)__instance).GetComponent<DizzinessRpcReceiver>() == (Object)null) { ((Component)__instance).gameObject.AddComponent<DizzinessRpcReceiver>(); } if ((Object)(object)((Component)__instance).GetComponent<DizzinessControlModifier>() == (Object)null) { ((Component)__instance).gameObject.AddComponent<DizzinessControlModifier>(); } } } [HarmonyPatch(typeof(Character), "CheckJump")] internal static class Character_CheckJump_Patch { [HarmonyPostfix] private static void Postfix(Character __instance, ref bool __result) { if (!__result) { return; } DizzinessTracker component = ((Component)__instance).GetComponent<DizzinessTracker>(); if (!((Object)(object)component == (Object)null)) { float dizzinessValue = component.dizzinessValue; if (dizzinessValue > 0.7f) { __result = false; } } } } [HarmonyPatch(typeof(Character), "HasMeaningfulTempStatuses")] internal static class Character_HasMeaningfulTempStatuses_Patch { [HarmonyPostfix] private static void Postfix(Character __instance, ref bool __result) { DizzinessTracker component = ((Component)__instance).GetComponent<DizzinessTracker>(); if (!((Object)(object)component == (Object)null) && !__result && component.dizzinessValue > 0.05f) { __result = true; } } } public static class DizzinessBarInjector { public static BarAffliction injectedBar; private static bool injectionFailed; public static void TryInjectBar() { //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_0011: Expected O, but got Unknown //IL_002c: Unknown result type (might be due to invalid IL or missing references) //IL_0037: Expected O, but got Unknown //IL_004f: Unknown result type (might be due to invalid IL or missing references) //IL_005a: Expected O, but got Unknown //IL_0099: Unknown result type (might be due to invalid IL or missing references) //IL_00a4: Expected O, but got Unknown //IL_00cf: Unknown result type (might be due to invalid IL or missing references) //IL_00da: Expected O, but got Unknown //IL_00a8: Unknown result type (might be due to invalid IL or missing references) //IL_00ae: Invalid comparison between Unknown and I4 //IL_012c: Unknown result type (might be due to invalid IL or missing references) //IL_0137: Expected O, but got Unknown //IL_016b: Unknown result type (might be due to invalid IL or missing references) //IL_0176: Expected O, but got Unknown //IL_0150: Unknown result type (might be due to invalid IL or missing references) //IL_015a: Expected O, but got Unknown //IL_017f: Unknown result type (might be due to invalid IL or missing references) //IL_018a: Expected O, but got Unknown //IL_01ad: Unknown result type (might be due to invalid IL or missing references) //IL_01dc: Unknown result type (might be due to invalid IL or missing references) //IL_01e7: Expected O, but got Unknown //IL_01eb: Unknown result type (might be due to invalid IL or missing references) //IL_01f7: Unknown result type (might be due to invalid IL or missing references) //IL_0201: Expected O, but got Unknown //IL_0201: Expected O, but got Unknown //IL_0290: Unknown result type (might be due to invalid IL or missing references) //IL_029a: Expected O, but got Unknown //IL_020e: Unknown result type (might be due to invalid IL or missing references) //IL_0213: Unknown result type (might be due to invalid IL or missing references) //IL_0219: Unknown result type (might be due to invalid IL or missing references) //IL_022a: Unknown result type (might be due to invalid IL or missing references) if ((Object)injectedBar != (Object)null || injectionFailed) { return; } try { if ((Object)GUIManager.instance == (Object)null) { return; } StaminaBar bar = GUIManager.instance.bar; if ((Object)bar == (Object)null || bar.afflictions == null || bar.afflictions.Length == 0) { return; } BarAffliction val = null; BarAffliction[] afflictions = bar.afflictions; BarAffliction[] array = afflictions; foreach (BarAffliction val2 in array) { if (!((Object)val2 == (Object)null) && (int)val2.afflictionType == 4) { val = val2; break; } } if ((Object)val == (Object)null) { DizzinessPlugin.Logger.LogWarning((object)"Crab template bar not found in StaminaBar.afflictions"); injectionFailed = true; return; } GameObject val3 = Object.Instantiate<GameObject>(((Component)val).gameObject, ((Component)val).transform.parent); ((Object)val3).name = "DizzinessCustomBar"; BarAffliction component = val3.GetComponent<BarAffliction>(); if ((Object)component == (Object)null) { DizzinessPlugin.Logger.LogError((object)"Cloned GameObject has no BarAffliction component"); Object.Destroy((Object)val3); injectionFailed = true; return; } if ((Object)DizzinessPlugin.DizzinessIconSprite != (Object)null && (Object)component.icon != (Object)null) { component.icon.sprite = DizzinessPlugin.DizzinessIconSprite; ((Graphic)component.icon).color = Color.white; } Image[] componentsInChildren = ((Component)component).GetComponentsInChildren<Image>(true); Image[] array2 = componentsInChildren; foreach (Image val4 in array2) { if (!((Object)component.icon != (Object)null) || !((Object)val4 == (Object)component.icon)) { Color dizzinessColor = DizzinessPlugin.DizzinessColor; dizzinessColor.a = ((Graphic)val4).color.a; ((Graphic)val4).color = dizzinessColor; } } component.size = 0f; val3.SetActive(false); FieldInfo field = typeof(StaminaBar).GetField("afflictions", BindingFlags.Instance | BindingFlags.Public); if (field == null) { DizzinessPlugin.Logger.LogError((object)"StaminaBar.afflictions field not found"); Object.Destroy((Object)val3); injectionFailed = true; return; } BarAffliction[] array3 = (BarAffliction[])field.GetValue(bar); BarAffliction[] array4 = (BarAffliction[])(object)new BarAffliction[array3.Length + 1]; Array.Copy(array3, array4, array3.Length); array4[array3.Length] = component; field.SetValue(bar, array4); injectedBar = component; DizzinessPlugin.Logger.LogInfo((object)$"Independent bar injected. New array size: {array4.Length}"); } catch (Exception arg) { DizzinessPlugin.Logger.LogError((object)$"Bar injection failed: {arg}"); injectionFailed = true; } } } public class DizzinessControlModifier : MonoBehaviour { private Character character; private DizzinessTracker tracker; private float originalMovementModifier; [Header("Control Loss Settings")] public AnimationCurve controlReductionCurve = AnimationCurve.EaseInOut(0f, 1f, 1f, 0.3f); [Header("Thresholds")] [Range(0f, 1f)] public float wobbleStartThreshold = 0.15f; [Range(0f, 1f)] public float collapseThreshold = 1f; [Range(0f, 1f)] public float maxMovementReduction = 0.7f; private void Awake() { character = ((Component)this).GetComponent<Character>(); tracker = ((Component)this).GetComponent<DizzinessTracker>(); if ((Object)(object)character != (Object)null && (Object)(object)character.refs.movement != (Object)null) { originalMovementModifier = character.refs.movement.movementModifier; } } private void Update() { if (!((Object)(object)character == (Object)null) && !((Object)(object)tracker == (Object)null) && character.IsLocal) { float dizzinessValue = tracker.dizzinessValue; float num = RemapDizzinessToCurve(dizzinessValue); float num2 = controlReductionCurve.Evaluate(num); character.data.ragdollControlClamp = Mathf.Clamp01(num2); float num3 = 1f; if (dizzinessValue > wobbleStartThreshold) { float num4 = Mathf.Clamp01((dizzinessValue - wobbleStartThreshold) / (collapseThreshold - wobbleStartThreshold)); num3 = Mathf.Lerp(1f, maxMovementReduction, num4); } character.refs.movement.movementModifier = originalMovementModifier * num3; } } private float RemapDizzinessToCurve(float dizziness) { if (dizziness <= wobbleStartThreshold) { return 0f; } if (dizziness >= collapseThreshold) { return 1f; } float num = (dizziness - wobbleStartThreshold) / (collapseThreshold - wobbleStartThreshold); return Mathf.Clamp01(num); } } [HarmonyPatch(typeof(CharacterMovement), "GetMovementForce")] internal static class CharacterMovement_GetMovementForce_Patch { [HarmonyPostfix] private static void Postfix(CharacterMovement __instance, ref float __result) { } } [HarmonyPatch(typeof(CharacterInput), "Sample")] internal static class CharacterInput_Sample_Patch { private static Vector2 lastMovementInput; private static float lastInputTime; [HarmonyPrefix] private static void Prefix(CharacterInput __instance, bool playerMovementActive) { //IL_009f: Unknown result type (might be due to invalid IL or missing references) //IL_00a4: Unknown result type (might be due to invalid IL or missing references) //IL_0086: Unknown result type (might be due to invalid IL or missing references) //IL_008b: Unknown result type (might be due to invalid IL or missing references) //IL_00d9: Unknown result type (might be due to invalid IL or missing references) //IL_00f2: Unknown result type (might be due to invalid IL or missing references) //IL_00f7: Unknown result type (might be due to invalid IL or missing references) //IL_00fc: Unknown result type (might be due to invalid IL or missing references) //IL_0103: Unknown result type (might be due to invalid IL or missing references) //IL_010d: Unknown result type (might be due to invalid IL or missing references) //IL_0112: Unknown result type (might be due to invalid IL or missing references) if (!playerMovementActive) { return; } Character component = ((Component)__instance).GetComponent<Character>(); if ((Object)(object)component == (Object)null) { return; } DizzinessTracker component2 = ((Component)component).GetComponent<DizzinessTracker>(); if ((Object)(object)component2 == (Object)null) { return; } float dizzinessValue = component2.dizzinessValue; if (!(dizzinessValue <= 0.1f)) { float num = Mathf.Lerp(0f, 4f, dizzinessValue); if (Time.time - lastInputTime > num) { lastMovementInput = __instance.movementInput; lastInputTime = Time.time; } else { __instance.movementInput = lastMovementInput; } if (dizzinessValue > 0.2f) { float num2 = Mathf.Lerp(0f, 0.3f, (dizzinessValue - 0.2f) / 0.8f); __instance.movementInput += new Vector2(Random.Range(0f - num2, num2), Random.Range(0f - num2, num2)); __instance.movementInput = Vector2.ClampMagnitude(__instance.movementInput, 1f); } } } } public static class DizzinessDebugCommands { [ConsoleCommand] public static void ListAllItemsWithIDs() { try { ItemDatabase instance = SingletonAsset<ItemDatabase>.Instance; if (instance?.itemLookup == null) { DizzinessPlugin.Logger.LogError((object)"ItemDatabase not found!"); return; } DizzinessPlugin.Logger.LogInfo((object)$"=== ITEM DATABASE ({instance.itemLookup.Count} items) ==="); foreach (KeyValuePair<ushort, Item> item in instance.itemLookup.OrderBy((KeyValuePair<ushort, Item> x) => ((Object)x.Value).name)) { DizzinessPlugin.Logger.LogInfo((object)$"ID: {item.Key} | Name: {((Object)item.Value).name}"); } DizzinessPlugin.Logger.LogInfo((object)$"=== END OF ITEM DATABASE ({instance.itemLookup.Count} items) ==="); } catch (Exception ex) { DizzinessPlugin.Logger.LogError((object)("ListAllItemsWithIDs failed: " + ex.Message)); } } public static void TestDizzinessReduction() { Character localCharacter = Character.localCharacter; if ((Object)(object)localCharacter == (Object)null) { DizzinessPlugin.Logger.LogError((object)"No local character!"); return; } DizzinessTracker component = ((Component)localCharacter).GetComponent<DizzinessTracker>(); if ((Object)(object)component == (Object)null) { DizzinessPlugin.Logger.LogError((object)"No DizzinessTracker!"); return; } float dizzinessValue = component.dizzinessValue; component.dizzinessValue = Mathf.Max(0f, component.dizzinessValue - 0.5f); DizzinessPlugin.Logger.LogInfo((object)$"Test: Reduced dizziness from {dizzinessValue:F3} to {component.dizzinessValue:F3}"); } } [BepInPlugin("com.tambistudios.dizziness", "Dizziness Mod", "1.2.0")] public class DizzinessPlugin : BaseUnityPlugin { public const string MOD_GUID = "com.tambistudios.dizziness"; public const string MOD_NAME = "Dizziness Mod"; public const string MOD_VERSION = "1.2.0"; public static DizzinessPlugin Instance; public static ManualLogSource Logger; public static ConfigEntry<bool> debugMode; public const float SPEED_THRESHOLD = 7f; public const float DIZZINESS_GAIN_BASE = 0.0012f; public const float RECOVERY_PER_SEC = 0.035f; public const float REST_REQUIRED = 8f; public const float SUSTAINED_VELOCITY_DELAY = 0.25f; public const float DIZZINESS_REDUCTION_MULTIPLIER = 0.1f; public const float MAX_DIZZINESS_GAIN_PER_SECOND = 0.35f; public static readonly Color DizzinessColor = new Color(0.25f, 0.88f, 0.82f, 1f); public static Sprite DizzinessIconSprite; public const string CUSTOM_BAR_NAME = "DizzinessCustomBar"; private void Awake() { //IL_003e: Unknown result type (might be due to invalid IL or missing references) Instance = this; Logger = ((BaseUnityPlugin)this).Logger; debugMode = ((BaseUnityPlugin)this).Config.Bind<bool>("Debug", "EnableDebugKeys", false, "Enables F5 (teleport 100m up), F7 (set dizziness 100%) and on-screen debug HUD."); LoadIconSprite(); try { new Harmony("com.tambistudios.dizziness").PatchAll(); Logger.LogInfo((object)"[Dizziness From Speed 1.2.0] Loaded."); } catch (Exception arg) { Logger.LogError((object)$"Harmony patch failed: {arg}"); } } private static void LoadIconSprite() { //IL_0042: Unknown result type (might be due to invalid IL or missing references) //IL_0048: Expected O, but got Unknown //IL_0084: Unknown result type (might be due to invalid IL or missing references) //IL_0093: Unknown result type (might be due to invalid IL or missing references) try { using Stream stream = Assembly.GetExecutingAssembly().GetManifestResourceStream("DizzinessMod.Assets.dizziness_icon.png"); if (stream == null) { Logger.LogWarning((object)"Embedded icon not found in resources!"); return; } using MemoryStream memoryStream = new MemoryStream(); stream.CopyTo(memoryStream); Texture2D val = new Texture2D(2, 2, (TextureFormat)4, false); ((Texture)val).wrapMode = (TextureWrapMode)1; ((Texture)val).filterMode = (FilterMode)1; if (ImageConversion.LoadImage(val, memoryStream.ToArray())) { DizzinessIconSprite = Sprite.Create(val, new Rect(0f, 0f, (float)((Texture)val).width, (float)((Texture)val).height), new Vector2(0.5f, 0.5f)); Logger.LogInfo((object)$"Icon loaded: {((Texture)val).width}x{((Texture)val).height}"); } } catch (Exception arg) { Logger.LogError((object)$"LoadIconSprite failed: {arg}"); } } public static float GetEtcDamageMultiplier() { try { return Ascents.etcDamageMultiplier; } catch { return 1f; } } public static bool IsDizzinessDisabled() { return GetEtcDamageMultiplier() <= 0.001f; } public static float GetGainMultiplier() { float etcDamageMultiplier = GetEtcDamageMultiplier(); if (etcDamageMultiplier <= 0.001f) { return 0f; } if (etcDamageMultiplier <= 0.6f) { return 1f; } if (etcDamageMultiplier <= 1.5f) { return 3f; } return 5f; } private void Update() { //IL_0008: Unknown result type (might be due to invalid IL or missing references) //IL_0013: Expected O, but got Unknown //IL_001b: Unknown result type (might be due to invalid IL or missing references) //IL_0026: Expected O, but got Unknown //IL_0040: Unknown result type (might be due to invalid IL or missing references) //IL_004b: Expected O, but got Unknown //IL_0081: Unknown result type (might be due to invalid IL or missing references) //IL_008c: Expected O, but got Unknown //IL_00b7: Unknown result type (might be due to invalid IL or missing references) //IL_00c2: Expected O, but got Unknown //IL_0121: Unknown result type (might be due to invalid IL or missing references) //IL_012c: Expected O, but got Unknown //IL_00d5: Unknown result type (might be due to invalid IL or missing references) //IL_00da: Unknown result type (might be due to invalid IL or missing references) //IL_00e4: Unknown result type (might be due to invalid IL or missing references) //IL_00e9: Unknown result type (might be due to invalid IL or missing references) Character localCharacter = Character.localCharacter; if ((Object)localCharacter != (Object)null && (Object)((Component)localCharacter).GetComponent<DizzinessTracker>() == (Object)null) { ((Component)localCharacter).gameObject.AddComponent<DizzinessTracker>(); if ((Object)((Component)localCharacter).GetComponent<DizzinessRpcReceiver>() == (Object)null) { ((Component)localCharacter).gameObject.AddComponent<DizzinessRpcReceiver>(); } Logger.LogInfo((object)"DizzinessTracker attached (fallback)."); } DizzinessBarInjector.TryInjectBar(); if (!debugMode.Value || !((Object)localCharacter != (Object)null)) { return; } if (Input.GetKeyDown((KeyCode)286)) { Rigidbody playerRigidbody = DizzinessTracker.GetPlayerRigidbody(localCharacter); if ((Object)playerRigidbody != (Object)null) { Transform transform = ((Component)playerRigidbody).transform; transform.position += Vector3.up * 100f; Logger.LogInfo((object)"[F5] Teleported +100m up."); } } if (Input.GetKeyDown((KeyCode)288)) { DizzinessTracker component = ((Component)localCharacter).GetComponent<DizzinessTracker>(); if ((Object)component != (Object)null) { component.dizzinessValue = 1f; Logger.LogInfo((object)"[F7] Forced dizziness = 1.0"); } } } private void OnGUI() { //IL_001f: Unknown result type (might be due to invalid IL or missing references) //IL_002a: Expected O, but got Unknown //IL_003c: Unknown result type (might be due to invalid IL or missing references) //IL_0047: Expected O, but got Unknown //IL_0054: Unknown result type (might be due to invalid IL or missing references) //IL_005b: Expected O, but got Unknown //IL_006c: Unknown result type (might be due to invalid IL or missing references) //IL_0088: Unknown result type (might be due to invalid IL or missing references) //IL_0093: Expected O, but got Unknown //IL_009c: Unknown result type (might be due to invalid IL or missing references) //IL_00a1: Unknown result type (might be due to invalid IL or missing references) //IL_0117: Unknown result type (might be due to invalid IL or missing references) //IL_016f: Unknown result type (might be due to invalid IL or missing references) //IL_01e5: Unknown result type (might be due to invalid IL or missing references) //IL_0247: Unknown result type (might be due to invalid IL or missing references) //IL_0256: Unknown result type (might be due to invalid IL or missing references) //IL_0261: Expected O, but got Unknown if (!debugMode.Value) { return; } Character localCharacter = Character.localCharacter; if ((Object)localCharacter == (Object)null) { return; } DizzinessTracker component = ((Component)localCharacter).GetComponent<DizzinessTracker>(); if (!((Object)component == (Object)null)) { GUIStyle val = new GUIStyle(); val.fontSize = 18; val.normal.textColor = Color.white; float num = 0f; Rigidbody playerRigidbody = DizzinessTracker.GetPlayerRigidbody(localCharacter); if ((Object)playerRigidbody != (Object)null) { Vector3 linearVelocity = playerRigidbody.linearVelocity; num = ((Vector3)(ref linearVelocity)).magnitude; } float etcDamageMultiplier = GetEtcDamageMultiplier(); float gainMultiplier = GetGainMultiplier(); string text = (IsDizzinessDisabled() ? "DISABLED" : $"x{gainMultiplier:F0}"); float statusSum = localCharacter.refs.afflictions.statusSum; float maxStamina = localCharacter.GetMaxStamina(); float currentStamina = localCharacter.data.currentStamina; GUI.Label(new Rect(20f, 100f, 700f, 30f), $"Speed: {num:F1} Dizziness: {component.dizzinessValue:F3} etcMult: {etcDamageMultiplier:F2} ({text})", val); GUI.Label(new Rect(20f, 122f, 700f, 30f), $"Ground: {component.isGrounded} Climb: {component.isClimbing} Resting: {component.IsResting} RestTimer: {component.restTimer:F2}/{6f}", val); GUI.Label(new Rect(20f, 144f, 700f, 30f), $"FullyOut: {localCharacter.data.fullyPassedOut} Sum: {statusSum:F2} MaxStam: {maxStamina:F2} CurStam: {currentStamina:F2}", val); GUI.Label(new Rect(20f, 166f, 700f, 30f), "CustomBar: " + (((Object)DizzinessBarInjector.injectedBar != (Object)null) ? "OK" : "missing"), val); } } } public class DizzinessRpcReceiver : MonoBehaviourPun { [PunRPC] public void Dizziness_RPC_Sync(float value) { //IL_0009: Unknown result type (might be due to invalid IL or missing references) //IL_0014: Expected O, but got Unknown DizzinessTracker component = ((Component)this).GetComponent<DizzinessTracker>(); if ((Object)component != (Object)null && !component.character.IsLocal) { component.dizzinessValue = Mathf.Clamp01(value); } } } public class DizzinessTracker : MonoBehaviour { private float sustainedVelocityTimer; private float lastHighVelocityTime; public Character character; public float dizzinessValue; public float restTimer; public bool isGrounded; public bool isClimbing; private bool wasFullyPassedOut; private float lastSyncSent; private const float SYNC_INTERVAL = 0.2f; private Rigidbody _cachedRb; private static FieldInfo _groundedField; private static bool _groundedFieldSearched; private static FieldInfo[] _climbingFields; private static bool _climbingFieldsSearched; private float _lastStumbleTime; private float _stumbleCooldown = 2f; public bool IsResting { get { //IL_001d: Unknown result type (might be due to invalid IL or missing references) //IL_0028: Expected O, but got Unknown //IL_0034: Unknown result type (might be due to invalid IL or missing references) //IL_0039: Unknown result type (might be due to invalid IL or missing references) if (isClimbing) { return false; } Rigidbody playerRigidbody = GetPlayerRigidbody(character); if ((Object)playerRigidbody == (Object)null) { return false; } Vector3 linearVelocity = playerRigidbody.linearVelocity; return ((Vector3)(ref linearVelocity)).magnitude < 7f; } } private void CheckForStumble(float dizziness) { if (dizziness < 0.25f || Time.time - _lastStumbleTime < _stumbleCooldown) { return; } float num = dizziness - 0.25f; float num2 = Mathf.Pow(num / 0.75f, 1.5f) * 0.15f; float num3 = num2 * Time.deltaTime * 60f; if (Random.value < num3) { float num4 = Mathf.Lerp(0.15f, 0.6f, (dizziness - 0.25f) / 0.75f); num4 *= Random.Range(0.8f, 1.2f); CharacterFallHelper.TriggerFall(character, num4); _lastStumbleTime = Time.time; if (DizzinessPlugin.debugMode.Value) { DizzinessPlugin.Logger.LogInfo((object)$"STUMBLE! Duration: {num4:F2}s, Dizziness: {dizziness:F2}"); } } } public static Rigidbody GetPlayerRigidbody(Character c) { //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_000d: Expected O, but got Unknown //IL_001e: Unknown result type (might be due to invalid IL or missing references) //IL_0029: Expected O, but got Unknown //IL_0034: Unknown result type (might be due to invalid IL or missing references) //IL_003f: Expected O, but got Unknown if ((Object)c == (Object)null) { return null; } DizzinessTracker component = ((Component)c).GetComponent<DizzinessTracker>(); if ((Object)component != (Object)null) { if ((Object)component._cachedRb != (Object)null) { return component._cachedRb; } component._cachedRb = ((Component)c).GetComponentInChildren<Rigidbody>(); return component._cachedRb; } return ((Component)c).GetComponentInChildren<Rigidbody>(); } private void Awake() { character = ((Component)this).GetComponent<Character>(); } private bool IsSkeleton() { if ((Object)(object)character == (Object)null || (Object)(object)character.data == (Object)null) { return false; } if (character.data.isSkeleton && !character.data.dead && !character.data.fullyPassedOut) { return true; } return false; } private void Update() { //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_0012: Expected O, but got Unknown if ((Object)character == (Object)null || !character.IsLocal) { return; } isGrounded = DetectGrounded(); isClimbing = DetectClimbing(); bool fullyPassedOut = character.data.fullyPassedOut; if (wasFullyPassedOut && !fullyPassedOut) { float maxStamina = character.GetMaxStamina(); if (maxStamina > 0.001f) { character.data.currentStamina = maxStamina; DizzinessPlugin.Logger.LogInfo((object)$"Recovered from pass-out: stamina restored to {maxStamina:F2}"); } } wasFullyPassedOut = fullyPassedOut; if (DizzinessPlugin.IsDizzinessDisabled()) { if (dizzinessValue > 0f) { dizzinessValue = Mathf.Max(0f, dizzinessValue - 0.05f * Time.deltaTime); MaybeSendSync(); } } else { UpdateLocalDizziness(); CheckForStumble(dizzinessValue); MaybeSendSync(); } character.ClampStamina(); } private bool DetectGrounded() { //IL_0022: Unknown result type (might be due to invalid IL or missing references) //IL_002d: Expected O, but got Unknown //IL_00a8: Unknown result type (might be due to invalid IL or missing references) //IL_00b3: Expected O, but got Unknown //IL_00ef: Unknown result type (might be due to invalid IL or missing references) //IL_00fa: Expected O, but got Unknown //IL_010c: Unknown result type (might be due to invalid IL or missing references) //IL_0111: Unknown result type (might be due to invalid IL or missing references) //IL_011b: Unknown result type (might be due to invalid IL or missing references) //IL_0120: Unknown result type (might be due to invalid IL or missing references) //IL_0125: Unknown result type (might be due to invalid IL or missing references) if (!_groundedFieldSearched) { _groundedFieldSearched = true; if ((Object)character.data != (Object)null) { FieldInfo field = ((object)character.data).GetType().GetField("isGrounded", BindingFlags.Instance | BindingFlags.Public); if (field != null && field.FieldType == typeof(bool)) { _groundedField = field; DizzinessPlugin.Logger.LogInfo((object)"Ground detect: using character.data.isGrounded"); } } } if (_groundedField != null && (Object)character.data != (Object)null) { try { return (bool)_groundedField.GetValue(character.data); } catch { } } Rigidbody playerRigidbody = GetPlayerRigidbody(character); if ((Object)playerRigidbody == (Object)null) { return false; } return Physics.Raycast(((Component)playerRigidbody).transform.position + Vector3.up * 0.5f, Vector3.down, 1.5f, -1, (QueryTriggerInteraction)1); } private bool DetectClimbing() { //IL_0022: Unknown result type (might be due to invalid IL or missing references) //IL_002d: Expected O, but got Unknown //IL_0108: Unknown result type (might be due to invalid IL or missing references) //IL_0113: Expected O, but got Unknown if (!_climbingFieldsSearched) { _climbingFieldsSearched = true; if ((Object)character.data != (Object)null) { Type type = ((object)character.data).GetType(); string[] array = new string[3] { "isClimbing", "isRopeClimbing", "isVineClimbing" }; List<FieldInfo> list = new List<FieldInfo>(); string[] array2 = array; string[] array3 = array2; foreach (string text in array3) { FieldInfo field = type.GetField(text, BindingFlags.Instance | BindingFlags.Public); if (field != null && field.FieldType == typeof(bool)) { list.Add(field); DizzinessPlugin.Logger.LogInfo((object)("Climb detect: found character.data." + text)); } } _climbingFields = list.ToArray(); } } if (_climbingFields == null || (Object)character.data == (Object)null) { return false; } try { FieldInfo[] climbingFields = _climbingFields; for (int j = 0; j < climbingFields.Length; j++) { if ((bool)climbingFields[j].GetValue(character.data)) { return true; } } } catch { } return false; } private bool IsInvincible() { if ((Object)(object)character == (Object)null || character.refs == null || (Object)(object)character.refs.afflictions == (Object)null) { return false; } Affliction val = default(Affliction); if (character.refs.afflictions.HasAfflictionType((AfflictionType)14, ref val)) { return true; } if (character.refs.afflictions.HasAfflictionType((AfflictionType)16, ref val)) { return true; } return false; } private void UpdateLocalDizziness() { //IL_0053: Unknown result type (might be due to invalid IL or missing references) //IL_005e: Expected O, but got Unknown //IL_006a: Unknown result type (might be due to invalid IL or missing references) //IL_006f: Unknown result type (might be due to invalid IL or missing references) if (IsResting && !character.data.fullyPassedOut) { restTimer += Time.deltaTime; } else { restTimer = 0f; } Rigidbody playerRigidbody = GetPlayerRigidbody(character); if ((Object)playerRigidbody == (Object)null) { return; } Vector3 linearVelocity = playerRigidbody.linearVelocity; float magnitude = ((Vector3)(ref linearVelocity)).magnitude; if (magnitude > 7f) { sustainedVelocityTimer += Time.deltaTime; lastHighVelocityTime = Time.time; } else { sustainedVelocityTimer = Mathf.Max(0f, sustainedVelocityTimer - Time.deltaTime * 2f); } if (!IsInvincible() && !IsSkeleton() && magnitude > 7f && sustainedVelocityTimer >= 0.25f) { float gainMultiplier = DizzinessPlugin.GetGainMultiplier(); float num = magnitude - 7f; float num2 = num * num * 0.0012f * gainMultiplier; float num3 = Mathf.Min(num2, 0.35f); float num4 = Mathf.Lerp(1f, 0.1f, dizzinessValue / 0.8f); float num5 = num3 * num4; dizzinessValue = Mathf.Min(1f, dizzinessValue + num5 * Time.deltaTime); if (DizzinessPlugin.debugMode.Value && num5 > 0.001f) { DizzinessPlugin.Logger.LogInfo((object)$"Dizziness gain: raw={num2:F4}/s, capped={num3:F4}/s, actual={num5:F4}/s, dizziness={dizzinessValue:F3}"); } } if (!IsSkeleton() && ((IsResting && restTimer >= 8f) || character.data.fullyPassedOut)) { dizzinessValue = Mathf.Max(0f, dizzinessValue - 0.035f * Time.deltaTime); } } private void MaybeSendSync() { //IL_0033: Unknown result type (might be due to invalid IL or missing references) //IL_003e: Expected O, but got Unknown if (Time.time - lastSyncSent < 0.2f) { return; } lastSyncSent = Time.time; PhotonView component = ((Component)character).GetComponent<PhotonView>(); if ((Object)component == (Object)null || !PhotonNetwork.InRoom) { return; } try { component.RPC("Dizziness_RPC_Sync", (RpcTarget)1, new object[1] { dizzinessValue }); } catch (Exception ex) { DizzinessPlugin.Logger.LogWarning((object)("RPC send failed: " + ex.Message)); } } } }
FaerieLanternEnhanced.dll
Decompiled a week agousing System; using System.Diagnostics; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using System.Security; using System.Security.Permissions; using BepInEx; using BepInEx.Logging; using HarmonyLib; using Microsoft.CodeAnalysis; using UnityEngine; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)] [assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")] [assembly: AssemblyCompany("FaerieLanternEnhanced")] [assembly: AssemblyConfiguration("Debug")] [assembly: AssemblyFileVersion("1.0.0.0")] [assembly: AssemblyInformationalVersion("1.0.0+6e98fd25e396354a38bb3faf9a061fac7078c358")] [assembly: AssemblyProduct("FaerieLanternEnhanced")] [assembly: AssemblyTitle("FaerieLanternEnhanced")] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("1.0.0.0")] [module: UnverifiableCode] [module: RefSafetyRules(11)] namespace Microsoft.CodeAnalysis { [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] internal sealed class EmbeddedAttribute : Attribute { } } namespace System.Runtime.CompilerServices { [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] [AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)] internal sealed class RefSafetyRulesAttribute : Attribute { public readonly int Version; public RefSafetyRulesAttribute(int P_0) { Version = P_0; } } } namespace FaerieLanternEnhanced { [BepInPlugin("jill920.faerielanternenhanced", "Faerie Lantern Enhanced", "1.0.1")] public class FaerieLanternEnhancedPlugin : BaseUnityPlugin { public const string MOD_GUID = "jill920.faerielanternenhanced"; public const string MOD_NAME = "Faerie Lantern Enhanced"; public const string MOD_VERSION = "1.0.1"; public static FaerieLanternEnhancedPlugin Instance; public static ManualLogSource Logger; public static bool IsDizzinessModInstalled = false; public static bool IsFatigueModInstalled = false; public static bool debugMode = false; public static float dizzinessHealRate = 0.025f; public static float fatigueHealRate = 0.025f; public static float effectRadius = 7.2f; private void Awake() { Instance = this; Logger = ((BaseUnityPlugin)this).Logger; debugMode = ((BaseUnityPlugin)this).Config.Bind<bool>("Debug", "EnableLogs", false, "Enable debug logging").Value; dizzinessHealRate = ((BaseUnityPlugin)this).Config.Bind<float>("Healing", "DizzinessHealRate", 0.025f, "Dizziness reduction per second while near lit Faerie Lantern").Value; fatigueHealRate = ((BaseUnityPlugin)this).Config.Bind<float>("Healing", "FatigueHealRate", 0.025f, "Fatigue reduction per second while near lit Faerie Lantern").Value; effectRadius = ((BaseUnityPlugin)this).Config.Bind<float>("Healing", "EffectRadius", 7.2f, "Radius in meters for lantern healing effects").Value; CheckForInstalledMods(); try { Harmony.CreateAndPatchAll(Assembly.GetExecutingAssembly(), "jill920.faerielanternenhanced"); Logger.LogInfo((object)"[Faerie Lantern Enhanced 1.0.1] Loaded successfully!"); Logger.LogInfo((object)$" Dizziness Mod detected: {IsDizzinessModInstalled}"); Logger.LogInfo((object)$" Fatigue Mod detected: {IsFatigueModInstalled}"); Logger.LogInfo((object)$" Dizziness heal rate: {dizzinessHealRate}/s"); Logger.LogInfo((object)$" Fatigue heal rate: {fatigueHealRate}/s"); Logger.LogInfo((object)$" Effect radius: {effectRadius}m"); } catch (Exception ex) { Logger.LogError((object)("Failed to load: " + ex.Message)); } } private void CheckForInstalledMods() { IsDizzinessModInstalled = false; IsFatigueModInstalled = false; Assembly[] assemblies = AppDomain.CurrentDomain.GetAssemblies(); foreach (Assembly assembly in assemblies) { try { if (assembly.GetType("DizzinessMod.DizzinessTracker") != null) { IsDizzinessModInstalled = true; } if (assembly.GetType("FatigueMod.FatigueTracker") != null) { IsFatigueModInstalled = true; } } catch { } } if (!IsFatigueModInstalled) { try { IsFatigueModInstalled = Type.GetType("FatigueMod.FatigueTracker, Assembly-CSharp") != null; } catch { } } if (!IsDizzinessModInstalled) { try { IsDizzinessModInstalled = Type.GetType("DizzinessMod.DizzinessTracker, Assembly-CSharp") != null; } catch { } } } } } namespace FaerieLanternEnhanced.Patches { [HarmonyPatch(typeof(ItemCooking), "RPC_CookingExplode")] internal static class ItemCooking_Explode_Patch { private const int FAERIE_LANTERN_ID = 43; private const float EXPLOSION_RADIUS = 4.8f; private static bool _fatigueCheckDone; private static bool _fatigueAvailable; private static bool _dizzinessCheckDone; private static bool _dizzinessAvailable; private static bool IsFatigueModPresent() { if (_fatigueCheckDone) { return _fatigueAvailable; } _fatigueCheckDone = true; if (FaerieLanternEnhancedPlugin.IsFatigueModInstalled) { _fatigueAvailable = true; return true; } try { Assembly[] assemblies = AppDomain.CurrentDomain.GetAssemblies(); foreach (Assembly assembly in assemblies) { if (assembly.GetType("FatigueMod.FatigueTracker") != null) { _fatigueAvailable = true; FaerieLanternEnhancedPlugin.IsFatigueModInstalled = true; FaerieLanternEnhancedPlugin.Logger.LogInfo((object)"Faerie Lantern Explosion: Fatigue Mod detected at runtime!"); return true; } } } catch { } return false; } private static bool IsDizzinessModPresent() { if (_dizzinessCheckDone) { return _dizzinessAvailable; } _dizzinessCheckDone = true; if (FaerieLanternEnhancedPlugin.IsDizzinessModInstalled) { _dizzinessAvailable = true; return true; } try { Assembly[] assemblies = AppDomain.CurrentDomain.GetAssemblies(); foreach (Assembly assembly in assemblies) { if (assembly.GetType("DizzinessMod.DizzinessTracker") != null) { _dizzinessAvailable = true; FaerieLanternEnhancedPlugin.IsDizzinessModInstalled = true; FaerieLanternEnhancedPlugin.Logger.LogInfo((object)"Faerie Lantern Explosion: Dizziness Mod detected at runtime!"); return true; } } } catch { } return false; } [HarmonyPrefix] private static void Prefix(ItemCooking __instance) { //IL_0032: Unknown result type (might be due to invalid IL or missing references) //IL_0037: Unknown result type (might be due to invalid IL or missing references) //IL_006d: Unknown result type (might be due to invalid IL or missing references) //IL_0070: Unknown result type (might be due to invalid IL or missing references) Item item = ((ItemComponent)__instance).item; if ((Object)(object)item == (Object)null || item.itemID != 43) { return; } Vector3 position = ((Component)__instance).transform.position; bool flag = IsDizzinessModPresent(); bool flag2 = IsFatigueModPresent(); foreach (Character allCharacter in Character.AllCharacters) { if ((Object)(object)allCharacter == (Object)null) { continue; } float num = Vector3.Distance(position, allCharacter.Center); if (!(num > 4.8f)) { float num2 = 1f - num / 4.8f; float amount = -0.25f * num2; if (flag) { AddDizziness(allCharacter, amount); } if (flag2) { AddFatigue(allCharacter, amount); } } } FaerieLanternEnhancedPlugin.Logger.LogInfo((object)$"Faerie Lantern explosion: Applied status restoration within {4.8f}m"); } private static void AddDizziness(Character character, float amount) { try { Component component = ((Component)character).GetComponent("DizzinessMod.DizzinessTracker"); if ((Object)(object)component == (Object)null) { return; } FieldInfo field = ((object)component).GetType().GetField("dizzinessValue", BindingFlags.Instance | BindingFlags.Public); if (!(field == null)) { float num = (float)field.GetValue(component); float num2 = Mathf.Clamp01(num + amount); field.SetValue(component, num2); if (FaerieLanternEnhancedPlugin.debugMode) { FaerieLanternEnhancedPlugin.Logger.LogInfo((object)$"Explosion changed Dizziness: {num:F3} → {num2:F3} ({amount:F3})"); } } } catch (Exception ex) { FaerieLanternEnhancedPlugin.Logger.LogWarning((object)("Failed to modify Dizziness: " + ex.Message)); } } private static void AddFatigue(Character character, float amount) { try { Component component = ((Component)character).GetComponent("FatigueMod.FatigueTracker"); if ((Object)(object)component == (Object)null) { return; } FieldInfo field = ((object)component).GetType().GetField("fatigueValue", BindingFlags.Instance | BindingFlags.Public); if (!(field == null)) { float num = (float)field.GetValue(component); float num2 = Mathf.Clamp01(num + amount); field.SetValue(component, num2); if (FaerieLanternEnhancedPlugin.debugMode) { FaerieLanternEnhancedPlugin.Logger.LogInfo((object)$"Explosion changed Fatigue: {num:F3} → {num2:F3} ({amount:F3})"); } } } catch (Exception ex) { FaerieLanternEnhancedPlugin.Logger.LogWarning((object)("Failed to modify Fatigue: " + ex.Message)); } } } [HarmonyPatch(typeof(Lantern), "Update")] internal static class Lantern_Update_Patch { private const int FAERIE_LANTERN_ID = 43; private static FieldInfo _litField; private static bool _fatigueCheckDone; private static bool _fatigueAvailable; private static bool IsLit(Lantern lantern) { if (_litField == null) { _litField = typeof(Lantern).GetField("lit", BindingFlags.Instance | BindingFlags.NonPublic); } return _litField != null && (bool)_litField.GetValue(lantern); } private static bool IsFatigueModPresent() { if (_fatigueCheckDone) { return _fatigueAvailable; } _fatigueCheckDone = true; try { Assembly[] assemblies = AppDomain.CurrentDomain.GetAssemblies(); foreach (Assembly assembly in assemblies) { if (assembly.GetType("FatigueMod.FatigueTracker") != null) { _fatigueAvailable = true; FaerieLanternEnhancedPlugin.IsFatigueModInstalled = true; FaerieLanternEnhancedPlugin.Logger.LogInfo((object)"Fatigue Mod detected at runtime!"); return true; } } } catch { } return false; } private static bool IsDizzinessModPresent() { if (FaerieLanternEnhancedPlugin.IsDizzinessModInstalled) { return true; } try { Assembly[] assemblies = AppDomain.CurrentDomain.GetAssemblies(); foreach (Assembly assembly in assemblies) { if (assembly.GetType("DizzinessMod.DizzinessTracker") != null) { FaerieLanternEnhancedPlugin.IsDizzinessModInstalled = true; return true; } } } catch { } return false; } [HarmonyPostfix] private static void Postfix(Lantern __instance) { //IL_0049: Unknown result type (might be due to invalid IL or missing references) //IL_004e: Unknown result type (might be due to invalid IL or missing references) //IL_00aa: Unknown result type (might be due to invalid IL or missing references) //IL_00ad: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)((ItemComponent)__instance).item == (Object)null || ((ItemComponent)__instance).item.itemID != 43 || !IsLit(__instance)) { return; } Vector3 position = ((Component)__instance).transform.position; float effectRadius = FaerieLanternEnhancedPlugin.effectRadius; float deltaTime = Time.deltaTime; bool flag = IsDizzinessModPresent(); bool flag2 = IsFatigueModPresent(); if (!flag && !flag2) { return; } foreach (Character allCharacter in Character.AllCharacters) { if ((Object)(object)allCharacter == (Object)null) { continue; } float num = Vector3.Distance(position, allCharacter.Center); if (!(num > effectRadius)) { if (flag) { ReduceDizziness(allCharacter, FaerieLanternEnhancedPlugin.dizzinessHealRate * deltaTime); } if (flag2) { ReduceFatigue(allCharacter, FaerieLanternEnhancedPlugin.fatigueHealRate * deltaTime); } if (FaerieLanternEnhancedPlugin.debugMode) { FaerieLanternEnhancedPlugin.Logger.LogInfo((object)$"Faerie Lantern healing {allCharacter.characterName} (dist={num:F2}m)"); } } } } private static void ReduceDizziness(Character character, float amount) { try { Component component = ((Component)character).GetComponent("DizzinessMod.DizzinessTracker"); if ((Object)(object)component == (Object)null) { return; } FieldInfo field = ((object)component).GetType().GetField("dizzinessValue", BindingFlags.Instance | BindingFlags.Public); if (!(field == null)) { float num = (float)field.GetValue(component); float num2 = Mathf.Max(0f, num - amount); field.SetValue(component, num2); if (FaerieLanternEnhancedPlugin.debugMode && amount > 0.001f) { FaerieLanternEnhancedPlugin.Logger.LogInfo((object)$"Reduced Dizziness: {num:F3} → {num2:F3} (-{amount:F3})"); } } } catch (Exception ex) { FaerieLanternEnhancedPlugin.Logger.LogWarning((object)("Failed to reduce Dizziness: " + ex.Message)); } } private static void ReduceFatigue(Character character, float amount) { try { Component component = ((Component)character).GetComponent("FatigueMod.FatigueTracker"); if ((Object)(object)component == (Object)null) { return; } FieldInfo field = ((object)component).GetType().GetField("fatigueValue", BindingFlags.Instance | BindingFlags.Public); if (!(field == null)) { float num = (float)field.GetValue(component); float num2 = Mathf.Max(0f, num - amount); field.SetValue(component, num2); if (FaerieLanternEnhancedPlugin.debugMode && amount > 0.001f) { FaerieLanternEnhancedPlugin.Logger.LogInfo((object)$"Reduced Fatigue: {num:F3} → {num2:F3} (-{amount:F3})"); } } } catch (Exception ex) { FaerieLanternEnhancedPlugin.Logger.LogWarning((object)("Failed to reduce Fatigue: " + ex.Message)); } } } }
FatigueMod.dll
Decompiled a week agousing System; using System.Collections; using System.Collections.Generic; using System.Diagnostics; using System.IO; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using System.Security; using System.Security.Permissions; using BepInEx; using BepInEx.Configuration; using BepInEx.Logging; using HarmonyLib; using Microsoft.CodeAnalysis; using Peak.Afflictions; using Photon.Pun; using UnityEngine; using UnityEngine.UI; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)] [assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("0.0.0.0")] [module: UnverifiableCode] [module: RefSafetyRules(11)] namespace Microsoft.CodeAnalysis { [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] internal sealed class EmbeddedAttribute : Attribute { } } namespace System.Runtime.CompilerServices { [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] [AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)] internal sealed class RefSafetyRulesAttribute : Attribute { public readonly int Version; public RefSafetyRulesAttribute(int P_0) { Version = P_0; } } } namespace FatigueMod { [HarmonyPatch(typeof(Action_ApplyAffliction), "RunAction")] internal static class Action_ApplyAffliction_Patch { private static FieldInfo characterField; private static FieldInfo afflictionField; [HarmonyPrefix] private static void Prefix(Action_ApplyAffliction __instance) { //IL_00c2: Unknown result type (might be due to invalid IL or missing references) if (characterField == null) { characterField = typeof(ItemActionBase).GetField("character", BindingFlags.Instance | BindingFlags.NonPublic); } object? obj = characterField?.GetValue(__instance); Character val = (Character)((obj is Character) ? obj : null); if ((Object)(object)val == (Object)null || !val.IsLocal) { return; } if (afflictionField == null) { afflictionField = typeof(Action_ApplyAffliction).GetField("affliction", BindingFlags.Instance | BindingFlags.Public); } object? obj2 = afflictionField?.GetValue(__instance); Affliction val2 = (Affliction)((obj2 is Affliction) ? obj2 : null); if (val2 == null) { return; } FatiguePlugin.Logger.LogInfo((object)($"[DEBUG] Action_ApplyAffliction: {val2.GetAfflictionType()} " + "applied to " + val.characterName)); Affliction_InfiniteStamina val3 = (Affliction_InfiniteStamina)(object)((val2 is Affliction_InfiniteStamina) ? val2 : null); if (val3 != null) { FatigueAfflictionHandler.OnAfflictionApplied(val, (Affliction)(object)val3); return; } Affliction_FasterBoi val4 = (Affliction_FasterBoi)(object)((val2 is Affliction_FasterBoi) ? val2 : null); if (val4 != null) { FatigueAfflictionHandler.OnAfflictionApplied(val, (Affliction)(object)val4); } } } [HarmonyPatch(typeof(Action_GiveExtraStamina), "RunAction")] internal static class Action_GiveExtraStamina_Patch { private static FieldInfo characterField; [HarmonyPostfix] private static void Postfix(Action_GiveExtraStamina __instance) { if (characterField == null) { characterField = typeof(ItemActionBase).GetField("character", BindingFlags.Instance | BindingFlags.NonPublic); } object? obj = characterField?.GetValue(__instance); Character val = (Character)((obj is Character) ? obj : null); if ((Object)(object)val == (Object)null || !val.IsLocal) { return; } FatigueTracker component = ((Component)val).GetComponent<FatigueTracker>(); if ((Object)(object)component == (Object)null) { return; } if (val.data.isSkeleton && !val.data.dead && !val.data.fullyPassedOut) { if (FatiguePlugin.debugMode.Value) { FatiguePlugin.Logger.LogInfo((object)"Skipping fatigue reduction - target is a living skeleton"); } return; } float amount = __instance.amount; float num = amount * FatiguePlugin.extraStaminaFatigueReductionRatio.Value; float fatigueValue = component.fatigueValue; component.fatigueValue = Mathf.Max(0f, component.fatigueValue - num); if (FatiguePlugin.debugMode.Value && num > 0.001f) { FatiguePlugin.Logger.LogInfo((object)($"Extra stamina ({amount:F2}) reduced fatigue by {num:F3} " + $"(from {fatigueValue:F3} to {component.fatigueValue:F3})")); } } } [HarmonyPatch(typeof(Action_ModifyStatus), "RunAction")] internal static class Action_ModifyStatus_Patch { [CompilerGenerated] private sealed class <CleanupProcessedItem>d__6 : IEnumerator<object>, IEnumerator, IDisposable { private int <>1__state; private object <>2__current; public Item item; object IEnumerator<object>.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public <CleanupProcessedItem>d__6(int <>1__state) { this.<>1__state = <>1__state; } [DebuggerHidden] void IDisposable.Dispose() { <>1__state = -2; } private bool MoveNext() { //IL_0026: Unknown result type (might be due to invalid IL or missing references) //IL_0030: Expected O, but got Unknown switch (<>1__state) { default: return false; case 0: <>1__state = -1; <>2__current = (object)new WaitForSeconds(2f); <>1__state = 1; return true; case 1: <>1__state = -1; processedCureAlls.Remove(item); return false; } } bool IEnumerator.MoveNext() { //ILSpy generated this explicit interface implementation from .override directive in MoveNext return this.MoveNext(); } [DebuggerHidden] void IEnumerator.Reset() { throw new NotSupportedException(); } } private static HashSet<Item> processedCureAlls = new HashSet<Item>(); private static readonly HashSet<ushort> healingItemIDs = new HashSet<ushort> { 24 }; private static FieldInfo itemField; private static FieldInfo characterField; private static PropertyInfo characterProperty; [HarmonyPrefix] private static void Prefix(Action_ModifyStatus __instance) { if (itemField == null) { itemField = typeof(ItemActionBase).GetField("item", BindingFlags.Instance | BindingFlags.NonPublic); } object? obj = itemField?.GetValue(__instance); Item val = (Item)((obj is Item) ? obj : null); if ((Object)(object)val == (Object)null || val.itemID != 24 || processedCureAlls.Contains(val)) { return; } if (characterProperty == null) { characterProperty = typeof(ItemActionBase).GetProperty("character", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); } Character val2 = null; if (characterProperty != null) { object? value = characterProperty.GetValue(__instance); val2 = (Character)((value is Character) ? value : null); } if ((Object)(object)val2 == (Object)null) { if (characterField == null) { characterField = typeof(ItemActionBase).GetField("character", BindingFlags.Instance | BindingFlags.NonPublic); } object? obj2 = characterField?.GetValue(__instance); val2 = (Character)((obj2 is Character) ? obj2 : null); } if ((Object)(object)val2 == (Object)null || !val2.IsLocal) { return; } if (val2.data.dead || val2.data.fullyPassedOut) { if (FatiguePlugin.debugMode.Value) { FatiguePlugin.Logger.LogInfo((object)"Skipping fatigue reduction - target is dead or passed out"); } return; } FatigueTracker component = ((Component)val2).GetComponent<FatigueTracker>(); if (!((Object)(object)component == (Object)null)) { float num = 0.15f; float fatigueValue = component.fatigueValue; component.fatigueValue = Mathf.Max(0f, component.fatigueValue - num); processedCureAlls.Add(val); ((MonoBehaviour)__instance).StartCoroutine(CleanupProcessedItem(val)); if (FatiguePlugin.debugMode.Value) { FatiguePlugin.Logger.LogInfo((object)($"Cure-All consumed: Removed {num:F3} fatigue " + $"(from {fatigueValue:F3} to {component.fatigueValue:F3})")); } } } [IteratorStateMachine(typeof(<CleanupProcessedItem>d__6))] private static IEnumerator CleanupProcessedItem(Item item) { //yield-return decompiler failed: Unexpected instruction in Iterator.Dispose() return new <CleanupProcessedItem>d__6(0) { item = item }; } } [HarmonyPatch(typeof(CharacterData), "set_isSkeleton")] internal static class CharacterData_SetSkeleton_Patch { [HarmonyPostfix] private static void Postfix(CharacterData __instance, bool value) { if (!value) { return; } Character component = ((Component)__instance).GetComponent<Character>(); if ((Object)(object)component == (Object)null || !component.IsLocal) { return; } Component component2 = ((Component)component).GetComponent("FatigueMod.FatigueTracker"); if ((Object)(object)component2 != (Object)null) { FieldInfo field = ((object)component2).GetType().GetField("fatigueValue", BindingFlags.Instance | BindingFlags.Public); if (field != null) { field.SetValue(component2, 0f); FatiguePlugin.Logger.LogInfo((object)"Cleared fatigue on skeleton transformation"); } } } } [HarmonyPatch(typeof(Affliction), "OnApplied")] internal static class Affliction_OnApplied_Patch { [HarmonyPostfix] private static void Postfix(Affliction __instance) { if (!((Object)(object)__instance.character == (Object)null) && (__instance is Affliction_InfiniteStamina || __instance is Affliction_FasterBoi)) { FatigueAfflictionHandler.OnAfflictionApplied(__instance.character, __instance); } } } [HarmonyPatch(typeof(Affliction), "OnRemoved")] internal static class Affliction_OnRemoved_Patch { [HarmonyPostfix] private static void Postfix(Affliction __instance) { if (!((Object)(object)__instance.character == (Object)null) && (__instance is Affliction_InfiniteStamina || __instance is Affliction_FasterBoi)) { FatigueAfflictionHandler.OnAfflictionRemoved(__instance.character, __instance); } } } [HarmonyPatch(typeof(BarAffliction), "ChangeAffliction")] internal static class BarAffliction_ChangeAffliction_Patch { [HarmonyPrefix] private static bool Prefix(BarAffliction __instance, StaminaBar bar) { //IL_002a: Unknown result type (might be due to invalid IL or missing references) //IL_0035: Expected O, but got Unknown //IL_004c: Unknown result type (might be due to invalid IL or missing references) //IL_0057: Expected O, but got Unknown //IL_0074: Unknown result type (might be due to invalid IL or missing references) if (((Object)((Component)__instance).gameObject).name != "FatigueCustomBar") { return true; } Character observedCharacter = Character.observedCharacter; if ((Object)observedCharacter == (Object)null) { return false; } FatigueTracker component = ((Component)observedCharacter).GetComponent<FatigueTracker>(); if ((Object)component == (Object)null) { return false; } float fatigueValue = component.fatigueValue; __instance.size = bar.fullBar.sizeDelta.x * fatigueValue; if (fatigueValue > 0.01f) { if (__instance.size < bar.minAfflictionWidth) { __instance.size = bar.minAfflictionWidth; } ((Component)__instance).gameObject.SetActive(true); } else { ((Component)__instance).gameObject.SetActive(false); } if (FatiguePlugin.debugMode.Value && Mathf.Abs(fatigueValue - FatiguePlugin._lastLoggedFatigue) > 0.05f) { FatiguePlugin._lastLoggedFatigue = fatigueValue; FatiguePlugin.Logger.LogInfo((object)$"Fatigue bar updated: value={fatigueValue:F3}, size={__instance.size:F1}"); } return false; } } [HarmonyPatch(typeof(BarAffliction), "UpdateAffliction")] internal static class BarAffliction_UpdateAffliction_Patch { [HarmonyPrefix] private static bool Prefix(BarAffliction __instance, StaminaBar bar) { if (((Object)((Component)__instance).gameObject).name != "FatigueCustomBar") { return true; } __instance.width = Mathf.Lerp(__instance.width, __instance.size, Mathf.Min(Time.deltaTime * 10f, 0.1f)); return false; } } [HarmonyPatch(typeof(CharacterAfflictions))] [HarmonyPatch(/*Could not decode attribute arguments.*/)] internal static class CharacterAfflictions_statusSum_Patch { [HarmonyPostfix] private static void Postfix(CharacterAfflictions __instance, ref float __result) { if (!((Object)(object)__instance.character == (Object)null)) { FatigueTracker component = ((Component)__instance.character).GetComponent<FatigueTracker>(); if (!((Object)(object)component == (Object)null)) { __result += component.fatigueValue; } } } } [HarmonyPatch(typeof(Character), "AddExtraStamina")] internal static class Character_AddExtraStamina_Patch { [HarmonyPostfix] private static void Postfix(Character __instance, float add) { if (!__instance.IsLocal || add <= 0f) { return; } if (__instance.data.isSkeleton && !__instance.data.dead && !__instance.data.fullyPassedOut) { if (FatiguePlugin.debugMode.Value) { FatiguePlugin.Logger.LogInfo((object)"Skipping fatigue reduction - target is a living skeleton"); } return; } FatigueTracker component = ((Component)__instance).GetComponent<FatigueTracker>(); if (!((Object)(object)component == (Object)null)) { float num = add * FatiguePlugin.extraStaminaFatigueReductionRatio.Value; float fatigueValue = component.fatigueValue; component.fatigueValue = Mathf.Max(0f, component.fatigueValue - num); if (FatiguePlugin.debugMode.Value && num > 0.001f) { FatiguePlugin.Logger.LogInfo((object)($"AddExtraStamina ({add:F2}) reduced fatigue by {num:F3} " + $"(from {fatigueValue:F3} to {component.fatigueValue:F3})")); } } } } [HarmonyPatch(typeof(Character), "Awake")] internal static class Character_Awake_Patch { [HarmonyPostfix] private static void Postfix(Character __instance) { //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_0012: Expected O, but got Unknown //IL_002a: Unknown result type (might be due to invalid IL or missing references) //IL_0035: Expected O, but got Unknown if ((Object)((Component)__instance).GetComponent<FatigueTracker>() == (Object)null) { ((Component)__instance).gameObject.AddComponent<FatigueTracker>(); } if ((Object)((Component)__instance).GetComponent<FatigueRpcReceiver>() == (Object)null) { ((Component)__instance).gameObject.AddComponent<FatigueRpcReceiver>(); } } } [HarmonyPatch(typeof(Character), "HasMeaningfulTempStatuses")] internal static class Character_HasMeaningfulTempStatuses_Patch { [HarmonyPostfix] private static void Postfix(Character __instance, ref bool __result) { FatigueTracker component = ((Component)__instance).GetComponent<FatigueTracker>(); if (!((Object)(object)component == (Object)null) && !__result && component.fatigueValue > 0.05f) { __result = true; } } } [HarmonyPatch(typeof(Character), "UseStamina")] public static class Character_UseStamina_Patch { [HarmonyPostfix] public static void Postfix(Character __instance, float usage, bool useBonusStamina, ref bool __result) { if (__result && !(usage <= 0f) && !FatiguePlugin.IsFatigueDisabled()) { FatigueTracker component = ((Component)__instance).GetComponent<FatigueTracker>(); if (!((Object)(object)component == (Object)null)) { component.OnStaminaUsed(usage); } } } } public static class FatigueAfflictionHandler { private class AfflictionData { public AfflictionType type; public float cachedFatigue; public float bonusFatigueOnEnd; public bool fatigueBlocked; } private static Dictionary<int, AfflictionData> activeAfflictions = new Dictionary<int, AfflictionData>(); public static void OnAfflictionApplied(Character character, Affliction affliction) { //IL_0060: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)character == (Object)null || !character.IsLocal) { return; } FatigueTracker component = ((Component)character).GetComponent<FatigueTracker>(); if (!((Object)(object)component == (Object)null)) { int viewID = ((MonoBehaviourPun)character).photonView.ViewID; Affliction_FasterBoi val = (Affliction_FasterBoi)(object)((affliction is Affliction_FasterBoi) ? affliction : null); if (val != null) { AfflictionData afflictionData = new AfflictionData { type = (AfflictionType)2, cachedFatigue = component.fatigueValue, bonusFatigueOnEnd = 0.1f, fatigueBlocked = true }; activeAfflictions[viewID] = afflictionData; component.fatigueValue = 0f; FatiguePlugin.Logger.LogInfo((object)($"[Fatigue] Energy Drink consumed - Fatigue blocked for {((Affliction)val).totalTime:F1}s. " + $"Cached fatigue: {afflictionData.cachedFatigue:F3}, will add +{afflictionData.bonusFatigueOnEnd:F3} on end.")); } } } private static bool IsInvincible(Character character) { if ((Object)(object)character == (Object)null || (Object)(object)character.refs?.afflictions == (Object)null) { return false; } Affliction val = default(Affliction); if (character.refs.afflictions.HasAfflictionType((AfflictionType)14, ref val)) { return true; } if (character.refs.afflictions.HasAfflictionType((AfflictionType)16, ref val)) { return true; } return false; } public static void OnAfflictionRemoved(Character character, Affliction affliction) { //IL_005c: Unknown result type (might be due to invalid IL or missing references) //IL_0062: Invalid comparison between Unknown and I4 if ((Object)(object)character == (Object)null || !character.IsLocal) { return; } FatigueTracker component = ((Component)character).GetComponent<FatigueTracker>(); if ((Object)(object)component == (Object)null) { return; } int viewID = ((MonoBehaviourPun)character).photonView.ViewID; if (activeAfflictions.TryGetValue(viewID, out var value) && (int)value.type == 2 && affliction is Affliction_FasterBoi) { float num; if (IsInvincible(character)) { num = value.cachedFatigue; FatiguePlugin.Logger.LogInfo((object)("[Fatigue] Energy Drink effect ended - Character is INVINCIBLE (BingBongShield/Milk). " + $"Restored {value.cachedFatigue:F3} fatigue (NO BONUS added).")); } else { num = value.cachedFatigue + value.bonusFatigueOnEnd; FatiguePlugin.Logger.LogInfo((object)($"[Fatigue] Energy Drink effect ended - Restored {value.cachedFatigue:F3} " + $"+ bonus {value.bonusFatigueOnEnd:F3} = {num:F3}")); } component.fatigueValue = Mathf.Min(1f, num); activeAfflictions.Remove(viewID); } } public static bool IsFatigueBlocked(Character character) { if ((Object)(object)character == (Object)null) { return false; } int viewID = ((MonoBehaviourPun)character).photonView.ViewID; return activeAfflictions.ContainsKey(viewID); } } public static class FatigueBarInjector { public static BarAffliction injectedBar; private static bool injectionFailed; public static void TryInjectBar() { //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_0011: Expected O, but got Unknown //IL_002c: Unknown result type (might be due to invalid IL or missing references) //IL_0037: Expected O, but got Unknown //IL_004f: Unknown result type (might be due to invalid IL or missing references) //IL_005a: Expected O, but got Unknown //IL_0099: Unknown result type (might be due to invalid IL or missing references) //IL_00a4: Expected O, but got Unknown //IL_00cf: Unknown result type (might be due to invalid IL or missing references) //IL_00da: Expected O, but got Unknown //IL_00a8: Unknown result type (might be due to invalid IL or missing references) //IL_00ae: Invalid comparison between Unknown and I4 //IL_012c: Unknown result type (might be due to invalid IL or missing references) //IL_0137: Expected O, but got Unknown //IL_016b: Unknown result type (might be due to invalid IL or missing references) //IL_0176: Expected O, but got Unknown //IL_0150: Unknown result type (might be due to invalid IL or missing references) //IL_015a: Expected O, but got Unknown //IL_017f: Unknown result type (might be due to invalid IL or missing references) //IL_018a: Expected O, but got Unknown //IL_01ad: Unknown result type (might be due to invalid IL or missing references) //IL_01dc: Unknown result type (might be due to invalid IL or missing references) //IL_01e7: Expected O, but got Unknown //IL_01eb: Unknown result type (might be due to invalid IL or missing references) //IL_01f7: Unknown result type (might be due to invalid IL or missing references) //IL_0201: Expected O, but got Unknown //IL_0201: Expected O, but got Unknown //IL_0290: Unknown result type (might be due to invalid IL or missing references) //IL_029a: Expected O, but got Unknown //IL_020e: Unknown result type (might be due to invalid IL or missing references) //IL_0213: Unknown result type (might be due to invalid IL or missing references) //IL_0219: Unknown result type (might be due to invalid IL or missing references) //IL_022a: Unknown result type (might be due to invalid IL or missing references) if ((Object)injectedBar != (Object)null || injectionFailed) { return; } try { if ((Object)GUIManager.instance == (Object)null) { return; } StaminaBar bar = GUIManager.instance.bar; if ((Object)bar == (Object)null || bar.afflictions == null || bar.afflictions.Length == 0) { return; } BarAffliction val = null; BarAffliction[] afflictions = bar.afflictions; BarAffliction[] array = afflictions; foreach (BarAffliction val2 in array) { if (!((Object)val2 == (Object)null) && (int)val2.afflictionType == 4) { val = val2; break; } } if ((Object)val == (Object)null) { FatiguePlugin.Logger.LogWarning((object)"Crab template bar not found in StaminaBar.afflictions"); injectionFailed = true; return; } GameObject val3 = Object.Instantiate<GameObject>(((Component)val).gameObject, ((Component)val).transform.parent); ((Object)val3).name = "FatigueCustomBar"; BarAffliction component = val3.GetComponent<BarAffliction>(); if ((Object)component == (Object)null) { FatiguePlugin.Logger.LogError((object)"Cloned GameObject has no BarAffliction component"); Object.Destroy((Object)val3); injectionFailed = true; return; } if ((Object)FatiguePlugin.FatigueIconSprite != (Object)null && (Object)component.icon != (Object)null) { component.icon.sprite = FatiguePlugin.FatigueIconSprite; ((Graphic)component.icon).color = Color.white; } Image[] componentsInChildren = ((Component)component).GetComponentsInChildren<Image>(true); Image[] array2 = componentsInChildren; foreach (Image val4 in array2) { if (!((Object)component.icon != (Object)null) || !((Object)val4 == (Object)component.icon)) { Color fatigueColor = FatiguePlugin.FatigueColor; fatigueColor.a = ((Graphic)val4).color.a; ((Graphic)val4).color = fatigueColor; } } component.size = 0f; val3.SetActive(false); FieldInfo field = typeof(StaminaBar).GetField("afflictions", BindingFlags.Instance | BindingFlags.Public); if (field == null) { FatiguePlugin.Logger.LogError((object)"StaminaBar.afflictions field not found"); Object.Destroy((Object)val3); injectionFailed = true; return; } BarAffliction[] array3 = (BarAffliction[])field.GetValue(bar); BarAffliction[] array4 = (BarAffliction[])(object)new BarAffliction[array3.Length + 1]; Array.Copy(array3, array4, array3.Length); array4[array3.Length] = component; field.SetValue(bar, array4); injectedBar = component; if (FatiguePlugin.debugMode.Value) { FatiguePlugin.Logger.LogInfo((object)$"Independent bar injected. New array size: {array4.Length}"); } } catch (Exception arg) { FatiguePlugin.Logger.LogError((object)$"Bar injection failed: {arg}"); injectionFailed = true; } } } [BepInPlugin("jill920.fatiguefromstamina", "Fatigue Mod", "1.2.0")] public class FatiguePlugin : BaseUnityPlugin { public const string MOD_GUID = "jill920.fatiguefromstamina"; public static float _lastLoggedFatigue = -1f; public const string MOD_NAME = "Fatigue Mod"; public const string MOD_VERSION = "1.2.0"; public static FatiguePlugin Instance; public static ManualLogSource Logger; public static ConfigEntry<bool> debugMode; public static readonly Color FatigueColor = new Color(1f, 0.5f, 0f, 1f); public static Sprite FatigueIconSprite; public const string CUSTOM_BAR_NAME = "FatigueCustomBar"; public static ConfigEntry<string> healingItemsConfig; public static ConfigEntry<float> extraStaminaFatigueReductionRatio; public static ConfigEntry<float> baseExertionRate; public static ConfigEntry<float> maxExertionRate; public static ConfigEntry<float> exertionRampUpTime; public static ConfigEntry<float> baseRecoveryRate; public static ConfigEntry<float> minRecoveryRate; public static ConfigEntry<float> recoveryRampDownTime; public static ConfigEntry<float> exertionDecayRate; public static ConfigEntry<float> staminaToRecoveryPenalty; public const float PLAY_DEAD_RECOVERY_MULTIPLIER = 1.66f; public const float ENERGY_DRINK_BONUS_FATIGUE = 0.1f; public const float zeroStaminaFatigue = 0.035f; private void Awake() { //IL_0077: Unknown result type (might be due to invalid IL or missing references) //IL_0081: Expected O, but got Unknown //IL_00b4: Unknown result type (might be due to invalid IL or missing references) //IL_00be: Expected O, but got Unknown //IL_00f1: Unknown result type (might be due to invalid IL or missing references) //IL_00fb: Expected O, but got Unknown //IL_012e: Unknown result type (might be due to invalid IL or missing references) //IL_0138: Expected O, but got Unknown //IL_016b: Unknown result type (might be due to invalid IL or missing references) //IL_0175: Expected O, but got Unknown //IL_01a8: Unknown result type (might be due to invalid IL or missing references) //IL_01b2: Expected O, but got Unknown //IL_01e5: Unknown result type (might be due to invalid IL or missing references) //IL_01ef: Expected O, but got Unknown //IL_0222: Unknown result type (might be due to invalid IL or missing references) //IL_022c: Expected O, but got Unknown //IL_026e: Unknown result type (might be due to invalid IL or missing references) //IL_0274: Expected O, but got Unknown healingItemsConfig = ((BaseUnityPlugin)this).Config.Bind<string>("Healing", "HealingItemIDs", "24", "Comma-separated list of item IDs that reduce fatigue when used"); extraStaminaFatigueReductionRatio = ((BaseUnityPlugin)this).Config.Bind<float>("Recovery", "ExtraStaminaFatigueReductionRatio", 0.4f, "Amount of fatigue removed per unit of extra stamina given."); baseExertionRate = ((BaseUnityPlugin)this).Config.Bind<float>("Exertion", "BaseExertionRate", 0.04f, new ConfigDescription("Base fatigue gained per stamina used (rested state)", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0.02f, 0.1f), Array.Empty<object>())); maxExertionRate = ((BaseUnityPlugin)this).Config.Bind<float>("Exertion", "MaxExertionRate", 0.12f, new ConfigDescription("Maximum fatigue gained per stamina used (fully exerted)", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0.08f, 0.2f), Array.Empty<object>())); exertionRampUpTime = ((BaseUnityPlugin)this).Config.Bind<float>("Exertion", "ExertionRampUpTime", 40f, new ConfigDescription("Seconds of continuous sprinting to reach max exertion", (AcceptableValueBase)(object)new AcceptableValueRange<float>(20f, 60f), Array.Empty<object>())); baseRecoveryRate = ((BaseUnityPlugin)this).Config.Bind<float>("Recovery", "BaseRecoveryRate", 0.0045f, new ConfigDescription("Fatigue recovered per second when fully rested", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0.003f, 0.015f), Array.Empty<object>())); minRecoveryRate = ((BaseUnityPlugin)this).Config.Bind<float>("Recovery", "MinRecoveryRate", 0.001f, new ConfigDescription("Minimum fatigue recovery during heavy activity", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0.001f, 0.005f), Array.Empty<object>())); recoveryRampDownTime = ((BaseUnityPlugin)this).Config.Bind<float>("Recovery", "RecoveryRampDownTime", 12f, new ConfigDescription("Seconds of rest to reach full recovery rate after heavy exertion", (AcceptableValueBase)(object)new AcceptableValueRange<float>(5f, 20f), Array.Empty<object>())); exertionDecayRate = ((BaseUnityPlugin)this).Config.Bind<float>("Exertion", "ExertionDecayRate", 0.8f, new ConfigDescription("How fast exertion level decays when resting (per second)", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0.3f, 1.5f), Array.Empty<object>())); staminaToRecoveryPenalty = ((BaseUnityPlugin)this).Config.Bind<float>("Recovery", "StaminaToRecoveryPenalty", 0.15f, new ConfigDescription("How much stamina usage reduces recovery multiplier (per 10 stamina)", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0.05f, 0.3f), Array.Empty<object>())); Instance = this; Logger = ((BaseUnityPlugin)this).Logger; debugMode = ((BaseUnityPlugin)this).Config.Bind<bool>("Debug", "EnableDebugKeys", false, "..."); LoadIconSprite(); try { Harmony val = new Harmony("jill920.fatiguefromstamina"); val.PatchAll(Assembly.GetExecutingAssembly()); IEnumerable<MethodBase> patchedMethods = val.GetPatchedMethods(); foreach (MethodBase item in patchedMethods) { Logger.LogInfo((object)("Patched: " + item.DeclaringType?.Name + "." + item.Name)); } Logger.LogInfo((object)"[Fatigue From Stamina 1.1.0] Loaded with tug-of-war fatigue system."); } catch (Exception arg) { Logger.LogError((object)$"Harmony patch failed: {arg}"); } } private static void LoadIconSprite() { //IL_0042: Unknown result type (might be due to invalid IL or missing references) //IL_0048: Expected O, but got Unknown //IL_0084: Unknown result type (might be due to invalid IL or missing references) //IL_0093: Unknown result type (might be due to invalid IL or missing references) try { using Stream stream = Assembly.GetExecutingAssembly().GetManifestResourceStream("FatigueMod.Assets.fatigue_icon.png"); if (stream == null) { Logger.LogWarning((object)"Embedded icon not found in resources!"); return; } using MemoryStream memoryStream = new MemoryStream(); stream.CopyTo(memoryStream); Texture2D val = new Texture2D(2, 2, (TextureFormat)4, false); ((Texture)val).wrapMode = (TextureWrapMode)1; ((Texture)val).filterMode = (FilterMode)1; if (ImageConversion.LoadImage(val, memoryStream.ToArray())) { FatigueIconSprite = Sprite.Create(val, new Rect(0f, 0f, (float)((Texture)val).width, (float)((Texture)val).height), new Vector2(0.5f, 0.5f)); Logger.LogInfo((object)$"Icon loaded: {((Texture)val).width}x{((Texture)val).height}"); } } catch (Exception arg) { Logger.LogError((object)$"LoadIconSprite failed: {arg}"); } } public static float GetEtcDamageMultiplier() { try { return Ascents.etcDamageMultiplier; } catch { return 1f; } } public static bool IsFatigueDisabled() { return GetEtcDamageMultiplier() <= 0.001f; } public static float GetGainMultiplier() { float etcDamageMultiplier = GetEtcDamageMultiplier(); if (etcDamageMultiplier <= 0.001f) { return 0f; } if (etcDamageMultiplier <= 0.6f) { return 1f; } if (etcDamageMultiplier <= 1.5f) { return 2f; } return 3f; } private void Update() { Character localCharacter = Character.localCharacter; if ((Object)(object)localCharacter != (Object)null && (Object)(object)((Component)localCharacter).GetComponent<FatigueTracker>() == (Object)null) { ((Component)localCharacter).gameObject.AddComponent<FatigueTracker>(); if ((Object)(object)((Component)localCharacter).GetComponent<FatigueRpcReceiver>() == (Object)null) { ((Component)localCharacter).gameObject.AddComponent<FatigueRpcReceiver>(); } Logger.LogInfo((object)"FatigueTracker attached (fallback)."); } FatigueBarInjector.TryInjectBar(); if (debugMode.Value && !((Object)(object)localCharacter == (Object)null) && Input.GetKeyDown((KeyCode)288)) { FatigueTracker component = ((Component)localCharacter).GetComponent<FatigueTracker>(); if ((Object)(object)component != (Object)null) { component.fatigueValue = 0.5f; Logger.LogInfo((object)"[F7] Forced fatigue = 0.5"); } } } private void OnGUI() { //IL_004a: Unknown result type (might be due to invalid IL or missing references) //IL_0050: Expected O, but got Unknown //IL_005f: Unknown result type (might be due to invalid IL or missing references) //IL_0089: Unknown result type (might be due to invalid IL or missing references) //IL_008e: Unknown result type (might be due to invalid IL or missing references) //IL_0103: Unknown result type (might be due to invalid IL or missing references) //IL_0149: Unknown result type (might be due to invalid IL or missing references) //IL_0194: Unknown result type (might be due to invalid IL or missing references) //IL_01f5: Unknown result type (might be due to invalid IL or missing references) if (!debugMode.Value) { return; } Character localCharacter = Character.localCharacter; if ((Object)(object)localCharacter == (Object)null) { return; } FatigueTracker component = ((Component)localCharacter).GetComponent<FatigueTracker>(); if (!((Object)(object)component == (Object)null)) { GUIStyle val = new GUIStyle(); val.fontSize = 18; val.normal.textColor = Color.white; float num = 0f; Rigidbody playerRigidbody = FatigueTracker.GetPlayerRigidbody(localCharacter); if ((Object)(object)playerRigidbody != (Object)null) { Vector3 linearVelocity = playerRigidbody.linearVelocity; num = ((Vector3)(ref linearVelocity)).magnitude; } float etcDamageMultiplier = GetEtcDamageMultiplier(); float gainMultiplier = GetGainMultiplier(); string text = (IsFatigueDisabled() ? "DISABLED" : $"x{gainMultiplier:F0}"); float statusSum = localCharacter.refs.afflictions.statusSum; float maxStamina = localCharacter.GetMaxStamina(); float currentStamina = localCharacter.data.currentStamina; GUI.Label(new Rect(20f, 100f, 700f, 30f), $"Speed: {num:F1} Fatigue: {component.fatigueValue:F3} Exertion: {component.currentExertionLevel:F2}", val); GUI.Label(new Rect(20f, 122f, 700f, 30f), $"Ground: {component.isGrounded} Climb: {component.isClimbing} RecoveryMult: {component.currentRecoveryMultiplier:F2}x", val); GUI.Label(new Rect(20f, 144f, 700f, 30f), $"FullyOut: {localCharacter.data.fullyPassedOut} Sum: {statusSum:F2} MaxStam: {maxStamina:F2} CurStam: {currentStamina:F2}", val); GUI.Label(new Rect(20f, 166f, 700f, 30f), "CustomBar: " + (((Object)(object)FatigueBarInjector.injectedBar != (Object)null) ? "OK" : "missing"), val); } } } public class FatigueRpcReceiver : MonoBehaviourPun { private Character character; private void Awake() { character = ((Component)this).GetComponent<Character>(); } [PunRPC] public void Fatigue_RPC_Sync(float value) { FatigueTracker component = ((Component)this).GetComponent<FatigueTracker>(); if ((Object)(object)component != (Object)null && !component.character.IsLocal) { component.fatigueValue = Mathf.Clamp01(value); } } [PunRPC] public void RPC_ReduceFatigue(float amount) { if (!((MonoBehaviourPun)this).photonView.IsMine) { if (FatiguePlugin.debugMode.Value) { ManualLogSource logger = FatiguePlugin.Logger; Character obj = character; logger.LogInfo((object)("[FATIGUE RPC] Skipping " + ((obj != null) ? obj.characterName : null) + " - not owner")); } } else { if ((Object)(object)character == (Object)null || amount <= 0f) { return; } if (character.data.dead) { if (FatiguePlugin.debugMode.Value) { FatiguePlugin.Logger.LogInfo((object)("[FATIGUE RPC] Skipping " + character.characterName + " - is dead")); } return; } FatigueTracker component = ((Component)this).GetComponent<FatigueTracker>(); if (!((Object)(object)component == (Object)null)) { float fatigueValue = component.fatigueValue; component.fatigueValue = Mathf.Max(0f, component.fatigueValue - amount); if (FatiguePlugin.debugMode.Value) { FatiguePlugin.Logger.LogInfo((object)$"[FATIGUE RPC] {character.characterName}: Fatigue {fatigueValue:F3} -> {component.fatigueValue:F3} (-{amount:F3})"); } } } } private bool IsInvincible() { if ((Object)(object)character == (Object)null || (Object)(object)character.refs?.afflictions == (Object)null) { return false; } Affliction val = default(Affliction); if (character.refs.afflictions.HasAfflictionType((AfflictionType)14, ref val)) { return true; } if (character.refs.afflictions.HasAfflictionType((AfflictionType)16, ref val)) { return true; } return false; } } public class FatigueTracker : MonoBehaviour { public Character character; public float fatigueValue; public float currentExertionLevel; public float currentRecoveryMultiplier; public bool isGrounded; public bool isClimbing; private float _lastValidStaminaUseTime; private float _playDeadEndTime = 0f; private const float PLAY_DEAD_DURATION = 4f; private float _staminaUsedInWindow; private const float EXERTION_WINDOW = 16f; private const float MAX_STAMINA_FOR_EXERTION = 2f; private float _timeAtZeroStamina; private float _zeroStaminaPenalty; private float _lastStaminaCheck; private float _staminaUsageRate; private float _staminaRateSmoothing = 0.2f; private float _lastStaminaTime; private float _lastSyncSent; private const float SYNC_INTERVAL = 0.2f; private float _smoothedVelocity; private float _velocitySmoothing = 0.95f; public bool IsPlayingDead => Time.time < _playDeadEndTime; public bool IsResting { get { //IL_005e: Unknown result type (might be due to invalid IL or missing references) //IL_0063: Unknown result type (might be due to invalid IL or missing references) if (isClimbing) { return false; } if (character.data.isSprinting) { return false; } Rigidbody playerRigidbody = GetPlayerRigidbody(character); if ((Object)(object)playerRigidbody == (Object)null) { return false; } float num = _smoothedVelocity * _velocitySmoothing; Vector3 linearVelocity = playerRigidbody.linearVelocity; _smoothedVelocity = num + ((Vector3)(ref linearVelocity)).magnitude * (1f - _velocitySmoothing); bool flag = _smoothedVelocity < 1.5f; if (FatiguePlugin.debugMode.Value && Time.frameCount % 120 == 0) { FatiguePlugin.Logger.LogInfo((object)$"IsResting: {flag}, Velocity: {_smoothedVelocity:F2}"); } return flag; } } private bool IsInvincible() { if ((Object)(object)character == (Object)null || (Object)(object)character.refs?.afflictions == (Object)null) { return false; } Affliction val = default(Affliction); if (character.refs.afflictions.HasAfflictionType((AfflictionType)14, ref val)) { return true; } if (character.refs.afflictions.HasAfflictionType((AfflictionType)16, ref val)) { return true; } return false; } private float GetBonusStaminaPercentage() { float extraStamina = character.data.extraStamina; float num = Mathf.Clamp01(extraStamina); if (FatiguePlugin.debugMode.Value && Time.frameCount % 300 == 0) { FatiguePlugin.Logger.LogInfo((object)$"Bonus Stamina: {extraStamina:F2} = {num:F2}%"); } return num; } private bool IsImmuneToStaminaDrainFatigue() { if ((Object)(object)character == (Object)null) { return false; } if (IsSkeleton()) { return true; } if (IsInvincible()) { return true; } return false; } private bool IsSkeleton() { if ((Object)(object)character == (Object)null || (Object)(object)character.data == (Object)null) { return false; } if (character.data.isSkeleton && !character.data.dead && !character.data.fullyPassedOut) { return true; } return false; } private void Awake() { character = ((Component)this).GetComponent<Character>(); currentExertionLevel = 0f; currentRecoveryMultiplier = 1f; _lastStaminaTime = Time.time; _smoothedVelocity = 0f; _lastStaminaCheck = character.data.currentStamina; _timeAtZeroStamina = 0f; _zeroStaminaPenalty = 0f; _lastValidStaminaUseTime = -1f; } public static Rigidbody GetPlayerRigidbody(Character c) { if ((Object)(object)c == (Object)null) { return null; } return ((Component)c).GetComponentInChildren<Rigidbody>(); } private float GetCurrentMaxStamina() { return Mathf.Max(0f, 1f - character.refs.afflictions.statusSum); } private void UpdateZeroStaminaPenalty() { bool flag = IsTrulyOutOfStamina(); float num = 0.01f; if (flag) { _timeAtZeroStamina += Time.deltaTime; float num2 = Mathf.Clamp01(_timeAtZeroStamina / 4f); _zeroStaminaPenalty = Mathf.MoveTowards(_zeroStaminaPenalty, num2, Time.deltaTime * 2f); bool flag2 = Time.time - _lastValidStaminaUseTime < 0.5f; if (_lastStaminaCheck > num && flag && !IsImmuneToStaminaDrainFatigue() && flag2) { float num3 = 0.035f; fatigueValue = Mathf.Min(1f, fatigueValue + num3); if (FatiguePlugin.debugMode.Value) { FatiguePlugin.Logger.LogInfo((object)($"STAMINA ZERO (Primary + Bonus)! +{num3:F3} fatigue (total: {fatigueValue:F3}) | " + $"Last valid use: {Time.time - _lastValidStaminaUseTime:F2}s ago")); } } else if (_lastStaminaCheck > num && flag && !flag2) { if (FatiguePlugin.debugMode.Value) { FatiguePlugin.Logger.LogInfo((object)("STAMINA ZERO but from NON-MOVEMENT action (heavy item, etc.) - No fatigue penalty applied | " + $"Last valid use: {Time.time - _lastValidStaminaUseTime:F2}s ago")); } } else if (_lastStaminaCheck > num && flag && IsImmuneToStaminaDrainFatigue() && FatiguePlugin.debugMode.Value) { FatiguePlugin.Logger.LogInfo((object)"STAMINA ZERO but IMMUNE (Skeleton/Milk/Shield) - No fatigue penalty applied"); } } else if (_zeroStaminaPenalty > 0f) { float num4 = 1f; _zeroStaminaPenalty = Mathf.MoveTowards(_zeroStaminaPenalty, 0f, Time.deltaTime * num4); _timeAtZeroStamina = Mathf.MoveTowards(_timeAtZeroStamina, 0f, Time.deltaTime); } _lastStaminaCheck = character.data.currentStamina + character.data.extraStamina; if (FatiguePlugin.debugMode.Value && _zeroStaminaPenalty > 0.01f && Time.frameCount % 60 == 0) { FatiguePlugin.Logger.LogInfo((object)($"Zero stamina penalty: {_zeroStaminaPenalty:F2} (time at zero: {_timeAtZeroStamina:F1}s) | " + $"Primary: {character.data.currentStamina:F2}, Bonus: {character.data.extraStamina:F2}")); } } public void OnStaminaUsed(float usage) { if (usage <= 0f) { return; } float time = Time.time; float num = time - _lastStaminaTime; bool flag = character.data.isClimbing || character.data.isRopeClimbing || character.data.isVineClimbing; bool flag2 = false; string text = "UNKNOWN"; if (character.data.isSprinting) { flag2 = true; text = "SPRINT"; } else if (flag) { flag2 = true; text = "CLIMB"; } else if (character.data.sinceJump < 0.1f) { flag2 = true; text = "JUMP"; } else if (character.data.isGrounded && ((Vector3)(ref character.data.worldMovementInput)).magnitude > 0.5f) { flag2 = false; text = "MOVE"; } else { text = "OTHER"; } if (flag2) { _lastValidStaminaUseTime = time; } bool flag3 = character.data.currentStamina <= 0.01f && character.data.extraStamina > 0f; bool flag4 = character.data.currentStamina > 0.01f; float bonusStaminaPercentage = GetBonusStaminaPercentage(); float num2 = 1f; string text2 = "PRIMARY"; if (flag3) { num2 = Mathf.Lerp(1f, 0.4f, bonusStaminaPercentage); text2 = (flag ? "BONUS_CLIMB" : "BONUS"); } else if (flag4) { num2 = Mathf.Lerp(1f, 0.4f, bonusStaminaPercentage); text2 = (flag ? "PRIMARY_CLIMB" : "PRIMARY"); } float num3 = (flag ? 1f : 1f); float num4 = num2 * num3; num4 = Mathf.Clamp(num4, 0.35f, 1.2f); float num5 = usage / Mathf.Max(0.016f, num); _staminaUsageRate = Mathf.Lerp(_staminaUsageRate, num5, _staminaRateSmoothing); float num6 = usage * num4; _staminaUsedInWindow += num6; _lastStaminaTime = time; if (FatiguePlugin.debugMode.Value && usage > 0.01f) { FatiguePlugin.Logger.LogInfo((object)($"Stamina used: {usage:F2} ({text2}, action: {text}, valid: {flag2}, mult: {num4:F2}, climbing: {flag}, bonus%: {bonusStaminaPercentage:F2}) | " + $"Primary: {character.data.currentStamina:F2}, Bonus: {character.data.extraStamina:F2} | " + $"Rate: {_staminaUsageRate:F0}/s | Window total: {_staminaUsedInWindow:F1}/{2f:F0}")); } if (!IsInvincible() && !IsSkeleton() && !FatigueAfflictionHandler.IsFatigueBlocked(character) && !IsImmuneToStaminaDrainFatigue()) { float num7 = Mathf.Clamp01(_staminaUsedInWindow / 2f); float num8 = Mathf.Clamp01((_staminaUsageRate - 30f) / 90f) * 0.6f; num7 = Mathf.Min(1f, num7 + num8); float num9 = _zeroStaminaPenalty * 0.5f; num7 = Mathf.Min(1f, num7 + num9); if (num7 > currentExertionLevel) { currentExertionLevel = Mathf.MoveTowards(currentExertionLevel, num7, Time.deltaTime * 3f); } else { currentExertionLevel = Mathf.MoveTowards(currentExertionLevel, num7, Time.deltaTime * 1f); } float num10 = Mathf.Lerp(FatiguePlugin.baseExertionRate.Value, FatiguePlugin.maxExertionRate.Value, currentExertionLevel); float num11 = usage * num10 * num4 * FatiguePlugin.GetGainMultiplier(); if (num11 > 0f) { fatigueValue = Mathf.Min(1f, fatigueValue + num11); if (FatiguePlugin.debugMode.Value && num11 > 0.001f) { FatiguePlugin.Logger.LogInfo((object)($" -> Fatigue +{num11:F4} (total: {fatigueValue:F3}) | " + $"Exertion: {currentExertionLevel:F2} | Rate: {num10:F3} | " + $"Source: {text2} (base: {num2:F2}, climb: {num3:F2}, final: {num4:F2})")); } } } else if (FatiguePlugin.debugMode.Value && (IsInvincible() || IsSkeleton() || IsImmuneToStaminaDrainFatigue())) { FatiguePlugin.Logger.LogInfo((object)"Fatigue gain blocked by immunity (Skeleton/Invincible/Shield)"); } } public void SetPlayingDead(bool playing) { if (playing) { _playDeadEndTime = Time.time + 4f; if (FatiguePlugin.debugMode.Value) { FatiguePlugin.Logger.LogInfo((object)$"Play Dead emote started - Fatigue recovery boosted for {4f} seconds. End time: {_playDeadEndTime:F2}"); } } else { _playDeadEndTime = 0f; if (FatiguePlugin.debugMode.Value) { FatiguePlugin.Logger.LogInfo((object)"Play Dead emote ended"); } } } private void UpdateStaminaWindow() { float num = Time.time - _lastStaminaTime; if (num > 0.5f) { float num2 = 0.125f; float num3 = Time.deltaTime * num2; _staminaUsedInWindow = Mathf.Max(0f, _staminaUsedInWindow - num3); } if (num > 1f) { _staminaUsageRate = Mathf.MoveTowards(_staminaUsageRate, 0f, Time.deltaTime * 20f); } } private float GetStaminaPercentage() { float currentMaxStamina = GetCurrentMaxStamina(); if (currentMaxStamina <= 0f) { return 0f; } float num = character.data.currentStamina + character.data.extraStamina; return Mathf.Clamp01(num / currentMaxStamina); } private bool IsTrulyOutOfStamina() { return character.data.currentStamina <= 0.01f && character.data.extraStamina <= 0.01f; } private float CalculateRecoveryMultiplier() { if (character.data.passedOut || character.data.fullyPassedOut) { if (FatiguePlugin.debugMode.Value && Time.frameCount % 60 == 0) { FatiguePlugin.Logger.LogInfo((object)"Unconscious state detected - maximum recovery applied"); } return 1f; } float num = 1f; float num2 = Mathf.Clamp01(currentExertionLevel) * 0.8f; num -= num2; float staminaDeficitPenalty = GetStaminaDeficitPenalty(); if (!float.IsNaN(staminaDeficitPenalty) && !float.IsInfinity(staminaDeficitPenalty)) { num -= staminaDeficitPenalty; } float num3 = Mathf.Clamp01(_zeroStaminaPenalty) * 0.8f; num -= num3; if (IsResting) { num += 0.15f; } num = Mathf.Clamp(num, 0f, 1f); if (IsPlayingDead && !float.IsNaN(num)) { num *= 1.66f; } if (float.IsNaN(num) || float.IsInfinity(num)) { num = 1f; } return num; } private float GetCurrentRecoveryMultiplier() { if (character.data.passedOut || character.data.fullyPassedOut) { if (FatiguePlugin.debugMode.Value && Time.frameCount % 60 == 0) { FatiguePlugin.Logger.LogInfo((object)"Unconscious state detected - maximum recovery applied"); } currentRecoveryMultiplier = 1f; return 1f; } float num = 1f; float num2 = currentExertionLevel * 0.8f; num -= num2; float staminaDeficitPenalty = GetStaminaDeficitPenalty(); num -= staminaDeficitPenalty; float num3 = _zeroStaminaPenalty * 0.8f; num -= num3; if (IsResting) { num += 0.15f; } if (IsPlayingDead) { num *= 1.66f; } num = (currentRecoveryMultiplier = Mathf.Clamp(num, 0f, 1.66f)); if (FatiguePlugin.debugMode.Value && Time.frameCount % 60 == 0) { FatiguePlugin.Logger.LogInfo((object)($"Recovery calc - Exertion: {currentExertionLevel:F2} (penalty: {num2:F2}), " + $"Stamina%: {GetStaminaPercentage():F2} (penalty: {staminaDeficitPenalty:F2}), " + $"Resting: {IsResting}, PlayDead: {IsPlayingDead}, Final mult: {num:F2}")); } return num; } private float GetCurrentRecoveryRate() { float num = GetCurrentRecoveryMultiplier(); float num2 = FatiguePlugin.baseRecoveryRate.Value * num; if (character.data.passedOut || character.data.fullyPassedOut) { num2 = Mathf.Max(num2, FatiguePlugin.baseRecoveryRate.Value); } return num2; } private float GetStaminaDeficitPenalty() { float num = Mathf.Clamp01(GetStaminaPercentage()); float num2 = Mathf.Pow(1f - num, 1.5f) * 0.95f; return Mathf.Clamp01(num2); } private void UpdateExertionDecay() { float num = Time.time - _lastStaminaTime; if (num > 1f) { float num2 = 1f / FatiguePlugin.exertionRampUpTime.Value; float num3 = Time.deltaTime * num2 * FatiguePlugin.exertionDecayRate.Value; currentExertionLevel = Mathf.Max(0f, currentExertionLevel - num3); } if (FatiguePlugin.debugMode.Value && Time.frameCount % 300 == 0) { float num4 = CalculateRecoveryMultiplier(); FatiguePlugin.Logger.LogInfo((object)($"Exertion: {currentExertionLevel:F3} | Stamina used: {_staminaUsedInWindow:F1}/{2f:F0} | " + $"Stamina %: {GetStaminaPercentage():F2} | Zero penalty: {_zeroStaminaPenalty:F2} | " + $"Recovery mult: {num4:F2} | Play Dead: {IsPlayingDead}")); } } private void Update() { if ((Object)(object)character == (Object)null || !character.IsLocal) { return; } isGrounded = character.data.isGrounded; isClimbing = character.data.isClimbing || character.data.isRopeClimbing || character.data.isVineClimbing; if (!character.data.passedOut && !character.data.fullyPassedOut) { UpdateZeroStaminaPenalty(); UpdateStaminaWindow(); UpdateExertionDecay(); } else { currentExertionLevel = Mathf.MoveTowards(currentExertionLevel, 0f, Time.deltaTime * 2f); _zeroStaminaPenalty = Mathf.MoveTowards(_zeroStaminaPenalty, 0f, Time.deltaTime); } float num = (currentRecoveryMultiplier = CalculateRecoveryMultiplier()); if (!IsSkeleton() && fatigueValue > 0f) { float num2 = FatiguePlugin.baseRecoveryRate.Value * num; if (character.data.passedOut || character.data.fullyPassedOut) { num2 = Mathf.Max(num2, FatiguePlugin.baseRecoveryRate.Value); } if (num2 > 0f) { float num3 = fatigueValue; float num4 = num2 * Time.deltaTime; fatigueValue = Mathf.Max(0f, fatigueValue - num4); if (FatiguePlugin.debugMode.Value && num4 > 0.0005f && Time.frameCount % 60 == 0) { string arg = ((character.data.passedOut || character.data.fullyPassedOut) ? "UNCONSCIOUS" : "CONSCIOUS"); FatiguePlugin.Logger.LogInfo((object)($"Recovery: {num4:F4}/s (mult: {num:F2}, {arg}) | " + $"Fatigue: {num3:F3} -> {fatigueValue:F3}")); } } } MaybeSendSync(); } private void MaybeSendSync() { if (Time.time - _lastSyncSent < 0.2f) { return; } _lastSyncSent = Time.time; PhotonView component = ((Component)character).GetComponent<PhotonView>(); if ((Object)(object)component == (Object)null || !PhotonNetwork.InRoom) { return; } try { component.RPC("Fatigue_RPC_Sync", (RpcTarget)1, new object[1] { fatigueValue }); } catch (Exception ex) { FatiguePlugin.Logger.LogWarning((object)("RPC send failed: " + ex.Message)); } } } } namespace FatigueMod.Patches { [HarmonyPatch(typeof(AOE), "Explode")] internal static class AOE_CureAll_Patch { private static FieldInfo hasExplodedField; private static bool isProcessing; static AOE_CureAll_Patch() { isProcessing = false; hasExplodedField = typeof(AOE).GetField("hasExploded", BindingFlags.Instance | BindingFlags.NonPublic); } [HarmonyPrefix] private static bool Prefix(AOE __instance) { //IL_00d7: Unknown result type (might be due to invalid IL or missing references) //IL_00dc: Unknown result type (might be due to invalid IL or missing references) if (isProcessing) { return true; } if (hasExplodedField != null && (bool)hasExplodedField.GetValue(__instance)) { return true; } if (!((Object)__instance).name.Contains("CureAll") && !((Object)__instance).name.Contains("AOE_CureAll")) { return true; } if (FatiguePlugin.debugMode.Value) { FatiguePlugin.Logger.LogInfo((object)("[CUREALL AOE] Processing " + ((Object)__instance).name)); } isProcessing = true; try { if (hasExplodedField != null) { hasExplodedField.SetValue(__instance, true); } float statusAmount = __instance.statusAmount; STATUSTYPE statusType = __instance.statusType; STATUSTYPE[] addtlStatus = __instance.addtlStatus; bool hasAffliction = __instance.hasAffliction; Affliction affliction = __instance.affliction; __instance.statusAmount = 0f; __instance.hasAffliction = false; __instance.affliction = null; __instance.statusAmount = statusAmount; __instance.hasAffliction = hasAffliction; __instance.affliction = affliction; return true; } finally { isProcessing = false; } } [HarmonyPostfix] private static void Postfix(AOE __instance) { //IL_00d0: Unknown result type (might be due to invalid IL or missing references) //IL_00dc: Unknown result type (might be due to invalid IL or missing references) //IL_00e1: Unknown result type (might be due to invalid IL or missing references) //IL_00a9: Unknown result type (might be due to invalid IL or missing references) //IL_02f3: Unknown result type (might be due to invalid IL or missing references) //IL_02fa: Unknown result type (might be due to invalid IL or missing references) //IL_035a: Unknown result type (might be due to invalid IL or missing references) //IL_0361: Unknown result type (might be due to invalid IL or missing references) //IL_036d: Unknown result type (might be due to invalid IL or missing references) //IL_0372: Unknown result type (might be due to invalid IL or missing references) if (isProcessing || (!((Object)__instance).name.Contains("CureAll") && !((Object)__instance).name.Contains("AOE_CureAll"))) { return; } if (!PhotonNetwork.IsMasterClient) { if (FatiguePlugin.debugMode.Value) { FatiguePlugin.Logger.LogInfo((object)"[CUREALL AOE] Skipping fatigue reduction - not MasterClient"); } return; } if (FatiguePlugin.debugMode.Value) { FatiguePlugin.Logger.LogInfo((object)"[CUREALL AOE] Postfix - applying fatigue reduction to characters in range"); FatiguePlugin.Logger.LogInfo((object)$"[CUREALL AOE] Position: {((Component)__instance).transform.position}, Range: {__instance.range}"); } Collider[] array = Physics.OverlapSphere(((Component)__instance).transform.position, __instance.range, LayerMask.op_Implicit(HelperFunctions.GetMask(__instance.mask))); List<Character> list = new List<Character>(); Collider[] array2 = array; Character item = default(Character); Character val2 = default(Character); foreach (Collider val in array2) { if (CharacterRagdoll.TryGetCharacterFromCollider(val, ref item) && !list.Contains(item)) { list.Add(item); } if (CharacterRagdoll.TryGetCharacterFromCollider(val, ref val2) && (Object)(object)val2.data.carriedPlayer != (Object)null && !list.Contains(val2.data.carriedPlayer)) { list.Add(val2.data.carriedPlayer); if (FatiguePlugin.debugMode.Value) { FatiguePlugin.Logger.LogInfo((object)("[CUREALL AOE] Found carried player " + val2.data.carriedPlayer.characterName)); } } } if (FatiguePlugin.debugMode.Value) { FatiguePlugin.Logger.LogInfo((object)$"[CUREALL AOE] Found {list.Count} characters in range"); foreach (Character item2 in list) { FatiguePlugin.Logger.LogInfo((object)$"[CUREALL AOE] - {item2.characterName} (IsDead: {item2.data.dead}, IsSkeleton: {item2.data.isSkeleton})"); } } foreach (Character item3 in list) { if (item3.data.dead || item3.data.fullyPassedOut) { if (FatiguePlugin.debugMode.Value) { FatiguePlugin.Logger.LogInfo((object)("[CUREALL AOE] Skipping " + item3.characterName + " - dead or passed out")); } continue; } float num = Vector3.Distance(((Component)__instance).transform.position, item3.Center); if (num > __instance.range) { continue; } float num2 = Mathf.Pow(1f - num / __instance.range, __instance.factorPow); if (num2 < __instance.minFactor) { continue; } if (__instance.requireLineOfSigh) { RaycastHit val3 = HelperFunctions.LineCheck(((Component)__instance).transform.position, item3.Center, (LayerType)1, 0f, (QueryTriggerInteraction)1); if (Object.op_Implicit((Object)(object)((RaycastHit)(ref val3)).transform)) { continue; } } float num3 = 0.1f * num2; FatigueRpcReceiver component = ((Component)item3).GetComponent<FatigueRpcReceiver>(); if ((Object)(object)component != (Object)null) { ((MonoBehaviourPun)component).photonView.RPC("RPC_ReduceFatigue", ((MonoBehaviourPun)component).photonView.Owner, new object[1] { num3 }); if (FatiguePlugin.debugMode.Value) { FatiguePlugin.Logger.LogInfo((object)$"[CUREALL AOE] Sent fatigue reduction RPC to {item3.characterName}: -{num3:F3} fatigue"); } } else { FatiguePlugin.Logger.LogWarning((object)("[CUREALL AOE] No FatigueRpcReceiver on " + item3.characterName)); } } } } [HarmonyPatch(typeof(CharacterAnimations), "PlayEmote")] internal static class CharacterAnimations_PlayEmote_Patch { [CompilerGenerated] private sealed class <ResetPlayDeadAfterDelay>d__2 : IEnumerator<object>, IEnumerator, IDisposable { private int <>1__state; private object <>2__current; public FatigueTracker tracker; public float delay; public CharacterAnimations animator; object IEnumerator<object>.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public <ResetPlayDeadAfterDelay>d__2(int <>1__state) { this.<>1__state = <>1__state; } [DebuggerHidden] void IDisposable.Dispose() { <>1__state = -2; } private bool MoveNext() { //IL_0027: Unknown result type (might be due to invalid IL or missing references) //IL_0031: Expected O, but got Unknown switch (<>1__state) { default: return false; case 0: <>1__state = -1; <>2__current = (object)new WaitForSeconds(delay); <>1__state = 1; return true; case 1: <>1__state = -1; if ((Object)(object)tracker != (Object)null && tracker.IsPlayingDead) { tracker.SetPlayingDead(playing: false); activeResetCoroutine = null; if (FatiguePlugin.debugMode.Value) { FatiguePlugin.Logger.LogInfo((object)"Play Dead emote timeout - resetting recovery rate"); } } return false; } } bool IEnumerator.MoveNext() { //ILSpy generated this explicit interface implementation from .override directive in MoveNext return this.MoveNext(); } [DebuggerHidden] void IEnumerator.Reset() { throw new NotSupportedException(); } } private static Coroutine activeResetCoroutine; [HarmonyPrefix] private static void Prefix(CharacterAnimations __instance, string emoteName) { Character component = ((Component)__instance).GetComponent<Character>(); if ((Object)(object)component == (Object)null || !component.IsLocal) { return; } FatigueTracker component2 = ((Component)component).GetComponent<FatigueTracker>(); if ((Object)(object)component2 == (Object)null || !(emoteName == "A_Scout_Emote_PlayDead")) { return; } if (activeResetCoroutine != null) { ((MonoBehaviour)__instance).StopCoroutine(activeResetCoroutine); if (FatiguePlugin.debugMode.Value) { FatiguePlugin.Logger.LogInfo((object)"Previous Play Dead reset coroutine cancelled - duration refreshed"); } } component2.SetPlayingDead(playing: true); activeResetCoroutine = ((MonoBehaviour)__instance).StartCoroutine(ResetPlayDeadAfterDelay(component2, 5f, __instance)); } [IteratorStateMachine(typeof(<ResetPlayDeadAfterDelay>d__2))] private static IEnumerator ResetPlayDeadAfterDelay(FatigueTracker tracker, float delay, CharacterAnimations animator) { //yield-return decompiler failed: Unexpected instruction in Iterator.Dispose() return new <ResetPlayDeadAfterDelay>d__2(0) { tracker = tracker, delay = delay, animator = animator }; } } [HarmonyPatch(typeof(EmoteWheel), "Choose")] internal static class EmoteWheel_Choose_Patch { [HarmonyPrefix] private static void Prefix(EmoteWheel __instance) { FieldInfo field = typeof(EmoteWheel).GetField("chosenEmoteData", BindingFlags.Instance | BindingFlags.NonPublic); if (field == null) { return; } object? value = field.GetValue(__instance); EmoteWheelData val = (EmoteWheelData)((value is EmoteWheelData) ? value : null); if ((Object)(object)val == (Object)null || !(val.anim == "A_Scout_Emote_PlayDead")) { return; } Character localCharacter = Character.localCharacter; if ((Object)(object)localCharacter == (Object)null) { return; } FatigueTracker component = ((Component)localCharacter).GetComponent<FatigueTracker>(); if (!((Object)(object)component == (Object)null)) { component.SetPlayingDead(playing: true); if (FatiguePlugin.debugMode.Value) { FatiguePlugin.Logger.LogInfo((object)"Play Dead emote detected via EmoteWheel.Choose()"); } } } } }
FeedingFrenzy.dll
Decompiled a week agousing System; using System.Collections; using System.Collections.Generic; using System.Diagnostics; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using System.Security; using System.Security.Permissions; using BepInEx; using BepInEx.Configuration; using BepInEx.Logging; using HarmonyLib; using Microsoft.CodeAnalysis; using Photon.Pun; using UnityEngine; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)] [assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")] [assembly: AssemblyCompany("FeedingFrenzy")] [assembly: AssemblyConfiguration("Debug")] [assembly: AssemblyFileVersion("1.0.0.0")] [assembly: AssemblyInformationalVersion("1.0.0+792ec908dc89689b0fce079d4b9e41033c968a90")] [assembly: AssemblyProduct("FeedingFrenzy")] [assembly: AssemblyTitle("FeedingFrenzy")] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("1.0.0.0")] [module: UnverifiableCode] [module: RefSafetyRules(11)] namespace Microsoft.CodeAnalysis { [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] internal sealed class EmbeddedAttribute : Attribute { } } namespace System.Runtime.CompilerServices { [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] [AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)] internal sealed class RefSafetyRulesAttribute : Attribute { public readonly int Version; public RefSafetyRulesAttribute(int P_0) { Version = P_0; } } } namespace FeedingFrenzy { [HarmonyPatch(typeof(Character), "AddExtraStamina")] internal static class AddExtraStamina_Multiplier_Patch { private static Dictionary<int, float> feedTimes = new Dictionary<int, float>(); private const float FED_WINDOW = 3f; public static void MarkAsFed(int characterID) { feedTimes[characterID] = Time.time; if (FeedingFrenzyPlugin.debugMode.Value) { FeedingFrenzyPlugin.Log.LogInfo((object)$"[FeedingFrenzy] Marked character {characterID} as fed"); } } [HarmonyPrefix] private static void Prefix(Character __instance, ref float add) { if (!(add <= 0f)) { int ownerActorNr = ((MonoBehaviourPun)__instance).photonView.OwnerActorNr; if (feedTimes.TryGetValue(ownerActorNr, out var value) && Time.time - value <= 3f) { float num = add; add = num * FeedingFrenzyPlugin.extraStaminaMultiplier.Value; FeedingFrenzyPlugin.Log.LogInfo((object)("[FeedingFrenzy] " + __instance.characterName + " fed! " + $"Extra stamina multiplier: {num:F2} → {add:F2}")); feedTimes.Remove(ownerActorNr); } } } } [BepInPlugin("jill920.FeedingFrenzy", "Feeding Frenzy", "1.1.0")] public class FeedingFrenzyPlugin : BaseUnityPlugin { public const string MOD_GUID = "jill920.FeedingFrenzy"; public const string MOD_NAME = "Feeding Frenzy"; public const string MOD_VERSION = "1.1.0"; public static ConfigEntry<float> extraStaminaMultiplier; public static ConfigEntry<float> flatExtraStaminaBonus; public static ConfigEntry<bool> debugMode; public static FeedingFrenzyPlugin Instance { get; private set; } public static ManualLogSource Log { get; private set; } private void Awake() { Instance = this; Log = ((BaseUnityPlugin)this).Logger; extraStaminaMultiplier = ((BaseUnityPlugin)this).Config.Bind<float>("Multiplier", "ExtraStaminaMultiplier", 1.5f, "Multiplier applied to extra stamina from items when feeding another player.\nExample: 1.5 = 50% more stamina, 2.0 = 100% more stamina"); flatExtraStaminaBonus = ((BaseUnityPlugin)this).Config.Bind<float>("FlatBonus", "FlatExtraStaminaBonus", 0.05f, "Flat bonus stamina given to the receiver when fed by another player.\nThis is applied AFTER the feeding animation completes.\nSet to 0 to disable."); debugMode = ((BaseUnityPlugin)this).Config.Bind<bool>("Debug", "EnableDebugLogs", false, "Enable debug logging"); Harmony val = Harmony.CreateAndPatchAll(typeof(GameUtils_StartFeed_Patch), "jill920.FeedingFrenzy"); val.PatchAll(typeof(AddExtraStamina_Multiplier_Patch)); val.PatchAll(typeof(Item_SendFeedDataRPC_Patch)); Log.LogInfo((object)"[Feeding Frenzy 1.1.0] Loaded successfully!"); Log.LogInfo((object)$" Multiplier: {extraStaminaMultiplier.Value}x"); Log.LogInfo((object)$" Flat Bonus: +{flatExtraStaminaBonus.Value} stamina"); } } [HarmonyPatch(typeof(GameUtils), "StartFeed")] internal static class GameUtils_StartFeed_Patch { [HarmonyPrefix] private static void Prefix(int giverID, int receiverID, ushort itemID, float totalItemTime) { Character val = default(Character); Character val2 = default(Character); if (Character.GetCharacterWithPhotonID(giverID, ref val) && Character.GetCharacterWithPhotonID(receiverID, ref val2)) { AddExtraStamina_Multiplier_Patch.MarkAsFed(((MonoBehaviourPun)val2).photonView.OwnerActorNr); FeedingFrenzyPlugin.Log.LogInfo((object)$"[FeedingFrenzy] Native feed detected: {val.characterName} -> {val2.characterName} (Item ID: {itemID})"); } } } [HarmonyPatch(typeof(Item), "SendFeedDataRPC")] internal static class Item_SendFeedDataRPC_Patch { [CompilerGenerated] private sealed class <ApplyFlatBonusAfterDelay>d__1 : IEnumerator<object>, IEnumerator, IDisposable { private int <>1__state; private object <>2__current; public Character receiver; public float delay; public int itemID; private float <flatBonus>5__1; object IEnumerator<object>.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public <ApplyFlatBonusAfterDelay>d__1(int <>1__state) { this.<>1__state = <>1__state; } [DebuggerHidden] void IDisposable.Dispose() { <>1__state = -2; } private bool MoveNext() { //IL_0032: Unknown result type (might be due to invalid IL or missing references) //IL_003c: Expected O, but got Unknown switch (<>1__state) { default: return false; case 0: <>1__state = -1; <>2__current = (object)new WaitForSeconds(delay); <>1__state = 1; return true; case 1: <>1__state = -1; <>2__current = null; <>1__state = 2; return true; case 2: <>1__state = -1; <flatBonus>5__1 = FeedingFrenzyPlugin.flatExtraStaminaBonus.Value; if (<flatBonus>5__1 > 0f) { receiver.AddExtraStamina(<flatBonus>5__1); if (FeedingFrenzyPlugin.debugMode.Value) { FeedingFrenzyPlugin.Log.LogInfo((object)("[FeedingFrenzy] Flat bonus applied to " + receiver.characterName + " " + $"(Item ID: {itemID}) after {delay:F2}s: +{<flatBonus>5__1:F2} stamina")); } } return false; } } bool IEnumerator.MoveNext() { //ILSpy generated this explicit interface implementation from .override directive in MoveNext return this.MoveNext(); } [DebuggerHidden] void IEnumerator.Reset() { throw new NotSupportedException(); } } [HarmonyPostfix] private static void Postfix(Item __instance, int giverID, int recieverID, int itemID, float totalUsingTime) { Character val = default(Character); if (Character.GetCharacterWithPhotonID(recieverID, ref val) && val.IsLocal) { ((MonoBehaviour)FeedingFrenzyPlugin.Instance).StartCoroutine(ApplyFlatBonusAfterDelay(val, totalUsingTime, itemID)); } } [IteratorStateMachine(typeof(<ApplyFlatBonusAfterDelay>d__1))] private static IEnumerator ApplyFlatBonusAfterDelay(Character receiver, float delay, int itemID) { //yield-return decompiler failed: Unexpected instruction in Iterator.Dispose() return new <ApplyFlatBonusAfterDelay>d__1(0) { receiver = receiver, delay = delay, itemID = itemID }; } } }
HuddleUp.dll
Decompiled a week agousing System; using System.Collections; using System.Collections.Generic; using System.Diagnostics; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using System.Security; using System.Security.Permissions; using BepInEx; using BepInEx.Configuration; using BepInEx.Logging; using HarmonyLib; using Microsoft.CodeAnalysis; using Photon.Pun; using UnityEngine; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)] [assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")] [assembly: AssemblyCompany("HuddleUp")] [assembly: AssemblyConfiguration("Debug")] [assembly: AssemblyFileVersion("1.0.0.0")] [assembly: AssemblyInformationalVersion("1.0.0+32c891598c8d63aa827b48670b46b3dd6bc44eb0")] [assembly: AssemblyProduct("HuddleUp")] [assembly: AssemblyTitle("HuddleUp")] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("1.0.0.0")] [module: UnverifiableCode] [module: RefSafetyRules(11)] namespace Microsoft.CodeAnalysis { [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] internal sealed class EmbeddedAttribute : Attribute { } } namespace System.Runtime.CompilerServices { [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] [AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)] internal sealed class RefSafetyRulesAttribute : Attribute { public readonly int Version; public RefSafetyRulesAttribute(int P_0) { Version = P_0; } } } namespace HuddleUp { [HarmonyPatch(typeof(CharacterHeatEmission), "Update")] internal static class CharacterHeatEmission_Patch { [CompilerGenerated] private sealed class <CheckReductionNextFrame>d__3 : IEnumerator<object>, IEnumerator, IDisposable { private int <>1__state; private object <>2__current; public CharacterHeatEmission heatSource; public Character target; public float coldBefore; public int sourceId; public Character giver; private float <coldAfter>5__1; private float <reduction>5__2; private int <targetId>5__3; private float <total>5__4; private float <reward>5__5; object IEnumerator<object>.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public <CheckReductionNextFrame>d__3(int <>1__state) { this.<>1__state = <>1__state; } [DebuggerHidden] void IDisposable.Dispose() { <>1__state = -2; } private bool MoveNext() { switch (<>1__state) { default: return false; case 0: <>1__state = -1; <>2__current = null; <>1__state = 1; return true; case 1: <>1__state = -1; <coldAfter>5__1 = target.refs.afflictions.GetCurrentStatus((STATUSTYPE)2); <reduction>5__2 = coldBefore - <coldAfter>5__1; if (<reduction>5__2 <= 0.001f) { return false; } if (!HuddleUpPlugin.IsRewardActive()) { if (HuddleUpPlugin.debugMode.Value) { HuddleUpPlugin.Logger.LogInfo((object)$"[Huddle] Cold reduction detected ({<reduction>5__2:F3}) but rewards not active - skipping"); } return false; } <targetId>5__3 = ((MonoBehaviourPun)target).photonView.ViewID; if (!HuddleUpPlugin.coldReductionTracker.ContainsKey(<targetId>5__3)) { HuddleUpPlugin.coldReductionTracker[<targetId>5__3] = new Dictionary<int, float>(); } if (!HuddleUpPlugin.coldReductionTracker[<targetId>5__3].ContainsKey(sourceId)) { HuddleUpPlugin.coldReductionTracker[<targetId>5__3][sourceId] = 0f; } HuddleUpPlugin.coldReductionTracker[<targetId>5__3][sourceId] += <reduction>5__2; <total>5__4 = HuddleUpPlugin.coldReductionTracker[<targetId>5__3][sourceId]; if (HuddleUpPlugin.debugMode.Value) { HuddleUpPlugin.Logger.LogInfo((object)("[Huddle] " + giver.characterName + " -> " + target.characterName + ": " + $"reduced cold by {<reduction>5__2:F3} (total: {<total>5__4:F3}/{HuddleUpPlugin.requiredColdReduction.Value:F2})")); } if (<total>5__4 >= HuddleUpPlugin.requiredColdReduction.Value) { HuddleUpPlugin.coldReductionTracker[<targetId>5__3][sourceId] = 0f; <reward>5__5 = HuddleUpPlugin.staminaReward.Value; target.AddExtraStamina(<reward>5__5); HuddleUpPlugin.Logger.LogInfo((object)($"[Huddle] {target.characterName} gained {<reward>5__5:F2} bonus stamina " + "from huddling with " + giver.characterName + "!")); } return false; } } bool IEnumerator.MoveNext() { //ILSpy generated this explicit interface implementation from .override directive in MoveNext return this.MoveNext(); } [DebuggerHidden] void IEnumerator.Reset() { throw new NotSupportedException(); } } private static FieldInfo _characterField; private static FieldInfo GetCharacterField() { if (_characterField == null) { _characterField = typeof(CharacterHeatEmission).GetField("character", BindingFlags.Instance | BindingFlags.NonPublic); } return _characterField; } [HarmonyPostfix] private static void Postfix(CharacterHeatEmission __instance) { //IL_0076: Unknown result type (might be due to invalid IL or missing references) //IL_007c: Unknown result type (might be due to invalid IL or missing references) FieldInfo characterField = GetCharacterField(); if (characterField == null) { return; } object? value = characterField.GetValue(__instance); Character val = (Character)((value is Character) ? value : null); if ((Object)(object)val == (Object)null) { return; } Character localCharacter = Character.localCharacter; if ((Object)(object)localCharacter == (Object)null || (Object)(object)val == (Object)(object)localCharacter) { return; } int instanceID = ((Object)__instance).GetInstanceID(); HuddleUpPlugin.UpdateHeatSourceActivity(instanceID); float num = Vector3.Distance(((Component)__instance).transform.position, localCharacter.Center); if (num >= __instance.radius) { return; } if (!HuddleUpPlugin.IsRewardActive()) { if (HuddleUpPlugin.debugMode.Value) { HuddleUpPlugin.Logger.LogInfo((object)"[Huddle] Skipping tracking - rewards not active (daytime or night-only mode enabled)"); } } else { float currentStatus = localCharacter.refs.afflictions.GetCurrentStatus((STATUSTYPE)2); ((MonoBehaviour)HuddleUpPlugin.Instance).StartCoroutine(CheckReductionNextFrame(__instance, localCharacter, currentStatus, instanceID, val)); } } [IteratorStateMachine(typeof(<CheckReductionNextFrame>d__3))] private static IEnumerator CheckReductionNextFrame(CharacterHeatEmission heatSource, Character target, float coldBefore, int sourceId, Character giver) { //yield-return decompiler failed: Unexpected instruction in Iterator.Dispose() return new <CheckReductionNextFrame>d__3(0) { heatSource = heatSource, target = target, coldBefore = coldBefore, sourceId = sourceId, giver = giver }; } } [BepInPlugin("jill920.huddleup", "Huddle Up", "1.0.1")] public class HuddleUpPlugin : BaseUnityPlugin { public const string MOD_GUID = "jill920.huddleup"; public const string MOD_NAME = "Huddle Up"; public const string MOD_VERSION = "1.0.1"; public static HuddleUpPlugin Instance; public static ManualLogSource Logger; public static ConfigEntry<bool> debugMode; public static ConfigEntry<float> requiredColdReduction; public static ConfigEntry<float> staminaReward; public static ConfigEntry<bool> nightOnly; public static Dictionary<int, Dictionary<int, float>> coldReductionTracker = new Dictionary<int, Dictionary<int, float>>(); private static Dictionary<int, float> _heatSourceLastActiveTime = new Dictionary<int, float>(); private void Awake() { //IL_0060: Unknown result type (might be due to invalid IL or missing references) //IL_006a: Expected O, but got Unknown //IL_009d: Unknown result type (might be due to invalid IL or missing references) //IL_00a7: Expected O, but got Unknown //IL_00d6: Unknown result type (might be due to invalid IL or missing references) //IL_00e0: Expected O, but got Unknown //IL_00eb: Unknown result type (might be due to invalid IL or missing references) //IL_00f1: Expected O, but got Unknown Instance = this; Logger = ((BaseUnityPlugin)this).Logger; debugMode = ((BaseUnityPlugin)this).Config.Bind<bool>("Debug", "EnableDebug", false, "Enable debug logging to console"); requiredColdReduction = ((BaseUnityPlugin)this).Config.Bind<float>("Balance", "RequiredColdReduction", 0.025f, new ConfigDescription("Amount of cold that must be removed before rewarding stamina", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0.025f, 0.1f), Array.Empty<object>())); staminaReward = ((BaseUnityPlugin)this).Config.Bind<float>("Balance", "StaminaReward", 0.01f, new ConfigDescription("Amount of bonus stamina to give when threshold is reached", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0.01f, 0.025f), Array.Empty<object>())); nightOnly = ((BaseUnityPlugin)this).Config.Bind<bool>("Balance", "NightOnly", true, new ConfigDescription("Only grant stamina rewards from huddling at night (when cold is actually dangerous)", (AcceptableValueBase)(object)new AcceptableValueList<bool>(new bool[2] { true, false }), Array.Empty<object>())); try { Harmony val = new Harmony("jill920.huddleup"); val.PatchAll(Assembly.GetExecutingAssembly()); Logger.LogInfo((object)"[Huddle Up 1.0.1] Loaded successfully!"); } catch (Exception ex) { Logger.LogError((object)("Harmony patch failed: " + ex.Message)); } } public static bool IsRewardActive() { if (!nightOnly.Value) { return true; } if ((Object)(object)DayNightManager.instance == (Object)null) { return false; } return DayNightManager.instance.isDay < 0.5f; } private void Update() { if (Time.frameCount % 3600 == 0) { CleanupInactiveSources(); } } private void CleanupInactiveSources() { float time = Time.time; List<int> list = new List<int>(); foreach (KeyValuePair<int, float> item in _heatSourceLastActiveTime) { if (time - item.Value > 30f) { list.Add(item.Key); } } foreach (int item2 in list) { _heatSourceLastActiveTime.Remove(item2); foreach (Dictionary<int, float> value in coldReductionTracker.Values) { value.Remove(item2); } } if (debugMode.Value && list.Count > 0) { Logger.LogInfo((object)$"Cleaned up {list.Count} inactive heat sources"); } } public static void UpdateHeatSourceActivity(int sourceId) { _heatSourceLastActiveTime[sourceId] = Time.time; } } }
NapberryEnhanced.dll
Decompiled a week agousing System; using System.Diagnostics; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using System.Security; using System.Security.Permissions; using BepInEx; using BepInEx.Logging; using HarmonyLib; using Microsoft.CodeAnalysis; using Photon.Pun; using UnityEngine; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)] [assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")] [assembly: AssemblyCompany("NapberryEnhanced")] [assembly: AssemblyConfiguration("Debug")] [assembly: AssemblyFileVersion("1.0.0.0")] [assembly: AssemblyInformationalVersion("1.0.0+9f939f10744bc87e8c173d53861967b31b4d3377")] [assembly: AssemblyProduct("NapberryEnhanced")] [assembly: AssemblyTitle("NapberryEnhanced")] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("1.0.0.0")] [module: UnverifiableCode] [module: RefSafetyRules(11)] namespace Microsoft.CodeAnalysis { [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] internal sealed class EmbeddedAttribute : Attribute { } } namespace System.Runtime.CompilerServices { [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] [AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)] internal sealed class RefSafetyRulesAttribute : Attribute { public readonly int Version; public RefSafetyRulesAttribute(int P_0) { Version = P_0; } } } namespace NapberryEnhanced { [BepInPlugin("jill920.napberryenhanced", "Napberry Enhanced", "1.0.0")] public class NapberryEnhancedPlugin : BaseUnityPlugin { public const string MOD_GUID = "jill920.napberryenhanced"; public const string MOD_NAME = "Napberry Enhanced"; public const string MOD_VERSION = "1.0.0"; public static NapberryEnhancedPlugin Instance; public static ManualLogSource Logger; public static bool IsDizzinessModInstalled; public static bool IsFatigueModInstalled; public static bool debugMode; private void Awake() { Instance = this; Logger = ((BaseUnityPlugin)this).Logger; debugMode = ((BaseUnityPlugin)this).Config.Bind<bool>("Debug", "EnableLogs", false, "Enable debug logging").Value; CheckForInstalledMods(); try { Harmony.CreateAndPatchAll(Assembly.GetExecutingAssembly(), "jill920.napberryenhanced"); Logger.LogInfo((object)"[Napberry Enhanced 1.0.0] Loaded successfully!"); Logger.LogInfo((object)$" Dizziness Mod detected: {IsDizzinessModInstalled}"); Logger.LogInfo((object)$" Fatigue Mod detected: {IsFatigueModInstalled}"); } catch (Exception ex) { Logger.LogError((object)("Failed to load: " + ex.Message)); } } private void CheckForInstalledMods() { IsDizzinessModInstalled = false; IsFatigueModInstalled = false; Assembly[] assemblies = AppDomain.CurrentDomain.GetAssemblies(); foreach (Assembly assembly in assemblies) { try { if (assembly.GetType("DizzinessMod.DizzinessTracker") != null) { IsDizzinessModInstalled = true; } if (assembly.GetType("FatigueMod.FatigueTracker") != null) { IsFatigueModInstalled = true; } } catch { } } } } } namespace NapberryEnhanced.Patches { [HarmonyPatch(typeof(Item), "Consume")] internal static class Item_Consume_Patch { private const int NAPBERRY_ITEM_ID = 110; private static bool _fatigueCheckDone; private static bool _fatigueAvailable; private static bool _dizzinessCheckDone; private static bool _dizzinessAvailable; private static bool IsFatigueModPresent() { if (_fatigueCheckDone) { return _fatigueAvailable; } _fatigueCheckDone = true; if (NapberryEnhancedPlugin.IsFatigueModInstalled) { _fatigueAvailable = true; return true; } try { Assembly[] assemblies = AppDomain.CurrentDomain.GetAssemblies(); foreach (Assembly assembly in assemblies) { if (assembly.GetType("FatigueMod.FatigueTracker") != null) { _fatigueAvailable = true; NapberryEnhancedPlugin.IsFatigueModInstalled = true; NapberryEnhancedPlugin.Logger.LogInfo((object)"Napberry: Fatigue Mod detected at runtime!"); return true; } } } catch { } return false; } private static bool IsDizzinessModPresent() { if (_dizzinessCheckDone) { return _dizzinessAvailable; } _dizzinessCheckDone = true; if (NapberryEnhancedPlugin.IsDizzinessModInstalled) { _dizzinessAvailable = true; return true; } try { Assembly[] assemblies = AppDomain.CurrentDomain.GetAssemblies(); foreach (Assembly assembly in assemblies) { if (assembly.GetType("DizzinessMod.DizzinessTracker") != null) { _dizzinessAvailable = true; NapberryEnhancedPlugin.IsDizzinessModInstalled = true; NapberryEnhancedPlugin.Logger.LogInfo((object)"Napberry: Dizziness Mod detected at runtime!"); return true; } } } catch { } return false; } [HarmonyPostfix] private static void Postfix(Item __instance, int consumerID) { if (__instance.itemID != 110) { return; } PhotonView photonView = PhotonNetwork.GetPhotonView(consumerID); if ((Object)(object)photonView == (Object)null) { return; } Character component = ((Component)photonView).GetComponent<Character>(); if ((Object)(object)component == (Object)null || !component.IsLocal) { return; } bool flag = IsDizzinessModPresent(); bool flag2 = IsFatigueModPresent(); if (flag || flag2) { if (flag) { ClearDizziness(component); } if (flag2) { ClearFatigue(component); } if (NapberryEnhancedPlugin.debugMode) { NapberryEnhancedPlugin.Logger.LogInfo((object)("Napberry: Cleared Dizziness/Fatigue for " + component.characterName)); } } } private static void ClearDizziness(Character character) { try { Component component = ((Component)character).GetComponent("DizzinessMod.DizzinessTracker"); if ((Object)(object)component == (Object)null) { return; } FieldInfo field = ((object)component).GetType().GetField("dizzinessValue", BindingFlags.Instance | BindingFlags.Public); if (!(field == null)) { float num = (float)field.GetValue(component); field.SetValue(component, 0f); if (NapberryEnhancedPlugin.debugMode && num > 0.01f) { NapberryEnhancedPlugin.Logger.LogInfo((object)$"Napberry: Cleared Dizziness: {num:F3} → 0"); } } } catch (Exception ex) { NapberryEnhancedPlugin.Logger.LogWarning((object)("Failed to clear Dizziness: " + ex.Message)); } } private static void ClearFatigue(Character character) { try { Component component = ((Component)character).GetComponent("FatigueMod.FatigueTracker"); if ((Object)(object)component == (Object)null) { return; } FieldInfo field = ((object)component).GetType().GetField("fatigueValue", BindingFlags.Instance | BindingFlags.Public); if (!(field == null)) { float num = (float)field.GetValue(component); field.SetValue(component, 0f); if (NapberryEnhancedPlugin.debugMode && num > 0.01f) { NapberryEnhancedPlugin.Logger.LogInfo((object)$"Napberry: Cleared Fatigue: {num:F3} → 0"); } } } catch (Exception ex) { NapberryEnhancedPlugin.Logger.LogWarning((object)("Failed to clear Fatigue: " + ex.Message)); } } } }
PandoraEnhanced.dll
Decompiled a week agousing System; using System.Diagnostics; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using System.Security; using System.Security.Permissions; using BepInEx; using BepInEx.Logging; using HarmonyLib; using Microsoft.CodeAnalysis; using Peak.Afflictions; using Photon.Realtime; using UnityEngine; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)] [assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("0.0.0.0")] [module: UnverifiableCode] [module: RefSafetyRules(11)] namespace Microsoft.CodeAnalysis { [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] internal sealed class EmbeddedAttribute : Attribute { } } namespace System.Runtime.CompilerServices { [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] [AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)] internal sealed class RefSafetyRulesAttribute : Attribute { public readonly int Version; public RefSafetyRulesAttribute(int P_0) { Version = P_0; } } } namespace PandoraEnhanced { [BepInPlugin("jill920.pandoraenhanced", "Pandora Enhanced", "1.0.0")] public class PandoraEnhancedPlugin : BaseUnityPlugin { public const string MOD_GUID = "jill920.pandoraenhanced"; public const string MOD_NAME = "Pandora Enhanced"; public const string MOD_VERSION = "1.0.0"; public static PandoraEnhancedPlugin Instance; public static ManualLogSource Logger; public static bool IsDizzinessModInstalled { get; private set; } public static bool IsFatigueModInstalled { get; private set; } private void Awake() { //IL_001f: Unknown result type (might be due to invalid IL or missing references) //IL_0025: Expected O, but got Unknown Instance = this; Logger = ((BaseUnityPlugin)this).Logger; CheckForInstalledMods(); try { Harmony val = new Harmony("jill920.pandoraenhanced"); val.PatchAll(); Logger.LogInfo((object)"[Pandora Enhanced 1.0.0] Loaded successfully!"); Logger.LogInfo((object)$" Dizziness Mod detected: {IsDizzinessModInstalled}"); Logger.LogInfo((object)$" Fatigue Mod detected: {IsFatigueModInstalled}"); } catch (Exception ex) { Logger.LogError((object)("Failed to load: " + ex.Message)); } } private void CheckForInstalledMods() { Assembly[] assemblies = AppDomain.CurrentDomain.GetAssemblies(); foreach (Assembly assembly in assemblies) { try { if (assembly.GetType("DizzinessMod.DizzinessTracker") != null) { IsDizzinessModInstalled = true; } if (assembly.GetType("FatigueMod.FatigueTracker") != null) { IsFatigueModInstalled = true; } } catch { } } } } } namespace PandoraEnhanced.Patches { [HarmonyPatch(typeof(Affliction_Chaos), "OnApplied")] internal static class Affliction_Chaos_Patch_PreserveTotal { private static FieldInfo _isInvincibleField; private static bool IsInvincible(Character character) { if ((Object)(object)character == (Object)null || (Object)(object)character.data == (Object)null) { return false; } try { if (_isInvincibleField == null) { _isInvincibleField = typeof(CharacterData).GetField("isInvincible", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); } if (_isInvincibleField != null) { return (bool)_isInvincibleField.GetValue(character.data); } } catch (Exception ex) { PandoraEnhancedPlugin.Logger.LogWarning((object)("Failed to check invincibility: " + ex.Message)); } return false; } private static void ClearDizziness(Character character) { try { PandoraEnhancedPlugin.Logger.LogInfo((object)"ClearDizziness: Looking for tracker..."); Component component = ((Component)character).GetComponent("DizzinessMod.DizzinessTracker"); if ((Object)(object)component == (Object)null) { PandoraEnhancedPlugin.Logger.LogWarning((object)"ClearDizziness: Tracker not found!"); return; } PandoraEnhancedPlugin.Logger.LogInfo((object)"ClearDizziness: Tracker found, getting field..."); FieldInfo field = ((object)component).GetType().GetField("dizzinessValue", BindingFlags.Instance | BindingFlags.Public); if (field == null) { PandoraEnhancedPlugin.Logger.LogWarning((object)"ClearDizziness: dizzinessValue field not found!"); return; } float num = (float)field.GetValue(component); PandoraEnhancedPlugin.Logger.LogInfo((object)$"ClearDizziness: Current value = {num:F3}"); if (num > 0.01f) { field.SetValue(component, 0f); PandoraEnhancedPlugin.Logger.LogInfo((object)$"Cleared Dizziness: {num:F3} → 0"); } else { PandoraEnhancedPlugin.Logger.LogInfo((object)"ClearDizziness: Value already near 0, nothing to clear"); } } catch (Exception ex) { PandoraEnhancedPlugin.Logger.LogError((object)("ClearDizziness failed: " + ex.Message + "\n" + ex.StackTrace)); } } private static bool IsLivingSkeleton(Character character) { if ((Object)(object)character == (Object)null || (Object)(object)character.data == (Object)null) { return false; } if (character.data.isSkeleton && !character.data.dead && !character.data.fullyPassedOut) { return true; } return false; } private static void ClearFatigue(Character character) { try { Component component = ((Component)character).GetComponent("FatigueMod.FatigueTracker"); if ((Object)(object)component == (Object)null) { return; } FieldInfo field = ((object)component).GetType().GetField("fatigueValue", BindingFlags.Instance | BindingFlags.Public); if (!(field == null)) { float num = (float)field.GetValue(component); if (num > 0.01f) { field.SetValue(component, 0f); PandoraEnhancedPlugin.Logger.LogInfo((object)$"Cleared Fatigue: {num:F3} → 0"); } } } catch (Exception ex) { PandoraEnhancedPlugin.Logger.LogWarning((object)("Failed to clear Fatigue: " + ex.Message)); } } [HarmonyPrefix] private static void Prefix(Affliction_Chaos __instance) { Character character = ((Affliction)__instance).character; if ((Object)(object)character == (Object)null || !character.IsLocal) { return; } if (IsLivingSkeleton(character)) { if (PandoraEnhancedPlugin.IsDizzinessModInstalled) { ClearDizziness(character); } if (PandoraEnhancedPlugin.IsFatigueModInstalled) { ClearFatigue(character); } return; } PandoraEnhancedPlugin.Logger.LogInfo((object)"Pandora Prefix - Starting clear"); bool flag = IsInvincible(character); PandoraEnhancedPlugin.Logger.LogInfo((object)$"Pandora Prefix - Invincible: {flag}"); PandoraEnhancedPlugin.Logger.LogInfo((object)$"Pandora Prefix - Dizziness mod installed: {PandoraEnhancedPlugin.IsDizzinessModInstalled}"); PandoraEnhancedPlugin.Logger.LogInfo((object)$"Pandora Prefix - Fatigue mod installed: {PandoraEnhancedPlugin.IsFatigueModInstalled}"); if (PandoraEnhancedPlugin.IsDizzinessModInstalled) { PandoraEnhancedPlugin.Logger.LogInfo((object)"Attempting to clear Dizziness..."); ClearDizziness(character); } if (PandoraEnhancedPlugin.IsFatigueModInstalled) { PandoraEnhancedPlugin.Logger.LogInfo((object)"Attempting to clear Fatigue..."); ClearFatigue(character); } if (flag) { PandoraEnhancedPlugin.Logger.LogInfo((object)"Pandora's Chaos: Invincible active - skipping Dizziness/Fatigue addition after clear"); } } [HarmonyPostfix] private static void Postfix(Affliction_Chaos __instance) { Character character = ((Affliction)__instance).character; if ((Object)(object)character == (Object)null || !character.IsLocal) { return; } if (IsLivingSkeleton(character)) { PandoraEnhancedPlugin.Logger.LogInfo((object)"Pandora's Chaos: Living skeleton - skipping Dizziness/Fatigue entirely"); return; } if (IsInvincible(character)) { PandoraEnhancedPlugin.Logger.LogInfo((object)"Pandora's Chaos: Invincible active - no Dizziness/Fatigue added"); return; } bool isDizzinessModInstalled = PandoraEnhancedPlugin.IsDizzinessModInstalled; bool isFatigueModInstalled = PandoraEnhancedPlugin.IsFatigueModInstalled; if (!isDizzinessModInstalled && !isFatigueModInstalled) { return; } float statusSum = character.refs.afflictions.statusSum; float num = 1f - statusSum; if (num <= 0.01f) { PandoraEnhancedPlugin.Logger.LogInfo((object)$"Pandora's Chaos: No space for Dizziness/Fatigue (total={statusSum:F3})"); return; } float num2 = 0f; float num3 = 0f; if (isDizzinessModInstalled && isFatigueModInstalled) { num2 = num * Random.Range(0f, 0.35f); float num4 = num - num2; num3 = num4 * Random.Range(0f, 0.5f); } else if (isDizzinessModInstalled) { num2 = num * Random.Range(0f, 0.35f); } else if (isFatigueModInstalled) { num3 = num * Random.Range(0f, 0.35f); } float num5 = num2 + num3; if (num5 > 0.01f) { if (isDizzinessModInstalled && num2 > 0.01f) { AddDizziness(character, num2); } if (isFatigueModInstalled && num3 > 0.01f) { AddFatigue(character, num3); } character.refs.afflictions.PushStatuses((Player)null); GUIManager.instance.bar.ChangeBar(); PandoraEnhancedPlugin.Logger.LogInfo((object)($"Pandora's Chaos: Total={statusSum:F3}, " + $"Added Dizziness={num2:F3}, Fatigue={num3:F3}")); } } private static void AddDizziness(Character character, float amount) { try { if (IsInvincible(character)) { return; } Component component = ((Component)character).GetComponent("DizzinessMod.DizzinessTracker"); if (!((Object)(object)component == (Object)null)) { FieldInfo field = ((object)component).GetType().GetField("dizzinessValue", BindingFlags.Instance | BindingFlags.Public); if (!(field == null)) { float num = (float)field.GetValue(component); field.SetValue(component, Mathf.Clamp01(num + amount)); } } } catch (Exception ex) { PandoraEnhancedPlugin.Logger.LogWarning((object)("Dizziness failed: " + ex.Message)); } } private static void AddFatigue(Character character, float amount) { try { if (IsInvincible(character)) { return; } Component component = ((Component)character).GetComponent("FatigueMod.FatigueTracker"); if (!((Object)(object)component == (Object)null)) { FieldInfo field = ((object)component).GetType().GetField("fatigueValue", BindingFlags.Instance | BindingFlags.Public); if (!(field == null)) { float num = (float)field.GetValue(component); field.SetValue(component, Mathf.Clamp01(num + amount)); } } } catch (Exception ex) { PandoraEnhancedPlugin.Logger.LogWarning((object)("Fatigue failed: " + ex.Message)); } } } }
RopeAnchorFix.dll
Decompiled a week agousing System; using System.Collections; using System.Collections.Generic; using System.Diagnostics; using System.Reflection; using System.Reflection.Emit; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using System.Security; using System.Security.Permissions; using BepInEx; using BepInEx.Logging; using HarmonyLib; using Microsoft.CodeAnalysis; using Photon.Pun; using RopeAnchorFix.Patches; using UnityEngine; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)] [assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")] [assembly: AssemblyCompany("RopeAnchorFix")] [assembly: AssemblyConfiguration("Debug")] [assembly: AssemblyFileVersion("1.0.0.0")] [assembly: AssemblyInformationalVersion("1.0.0+547eac5980954cd1eaea844e07ee33fbadaa77c2")] [assembly: AssemblyProduct("RopeAnchorFix")] [assembly: AssemblyTitle("RopeAnchorFix")] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("1.0.0.0")] [module: UnverifiableCode] [module: RefSafetyRules(11)] namespace Microsoft.CodeAnalysis { [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] internal sealed class EmbeddedAttribute : Attribute { } } namespace System.Runtime.CompilerServices { [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] [AttributeUsage(AttributeTargets.Class | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Parameter | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter, AllowMultiple = false, Inherited = false)] internal sealed class NullableAttribute : Attribute { public readonly byte[] NullableFlags; public NullableAttribute(byte P_0) { NullableFlags = new byte[1] { P_0 }; } public NullableAttribute(byte[] P_0) { NullableFlags = P_0; } } [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] [AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Method | AttributeTargets.Interface | AttributeTargets.Delegate, AllowMultiple = false, Inherited = false)] internal sealed class NullableContextAttribute : Attribute { public readonly byte Flag; public NullableContextAttribute(byte P_0) { Flag = P_0; } } [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] [AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)] internal sealed class RefSafetyRulesAttribute : Attribute { public readonly int Version; public RefSafetyRulesAttribute(int P_0) { Version = P_0; } } } namespace RopeAnchorFix { [BepInPlugin("jill920.ropeanchorfix", "Rope Anchor Range Fix", "1.0.0")] public class RopeAnchorFixPlugin : BaseUnityPlugin { public const string MOD_GUID = "jill920.ropeanchorfix"; public const string MOD_NAME = "Rope Anchor Range Fix"; public const string MOD_VERSION = "1.0.0"; public static RopeAnchorFixPlugin Instance { get; private set; } public static ManualLogSource Logger { get; private set; } public static bool DebugMode { get; private set; } private void Awake() { Instance = this; Logger = ((BaseUnityPlugin)this).Logger; DebugMode = ((BaseUnityPlugin)this).Config.Bind<bool>("Debug", "EnableLogs", false, "Enable debug logging to console").Value; try { Harmony val = Harmony.CreateAndPatchAll(Assembly.GetExecutingAssembly(), "jill920.ropeanchorfix"); Logger.LogInfo((object)"[Rope Anchor Range Fix 1.0.0] Loaded successfully!"); Logger.LogInfo((object)$" Blue preview range: {RopeTier_FullFix_Patch.BluePreviewRange}m"); Logger.LogInfo((object)$" Red preview range: {RopeTier_FullFix_Patch.RedPreviewRange}m"); Logger.LogInfo((object)$" Use ground position: {RopeTier_FullFix_Patch.UseGroundPosition}"); if (DebugMode) { Logger.LogInfo((object)" Debug logging: ENABLED"); } } catch (Exception ex) { Logger.LogError((object)("Failed to load: " + ex.Message)); Logger.LogError((object)ex.StackTrace); } } } } namespace RopeAnchorFix.Patches { [HarmonyPatch(typeof(RopeTier))] internal static class RopeTier_FullFix_Patch { [CompilerGenerated] private sealed class <RestoreCameraPosition>d__40 : IEnumerator<object>, IEnumerator, IDisposable { private int <>1__state; private object <>2__current; public Vector3 originalPos; object? IEnumerator<object>.Current { [DebuggerHidden] get { return <>2__current; } } object? IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public <RestoreCameraPosition>d__40(int <>1__state) { this.<>1__state = <>1__state; } [DebuggerHidden] void IDisposable.Dispose() { <>1__state = -2; } private bool MoveNext() { //IL_0051: Unknown result type (might be due to invalid IL or missing references) switch (<>1__state) { default: return false; case 0: <>1__state = -1; <>2__current = null; <>1__state = 1; return true; case 1: <>1__state = -1; if ((Object)(object)MainCamera.instance != (Object)null) { ((Component)MainCamera.instance).transform.position = originalPos; } return false; } } bool IEnumerator.MoveNext() { //ILSpy generated this explicit interface implementation from .override directive in MoveNext return this.MoveNext(); } [DebuggerHidden] void IEnumerator.Reset() { throw new NotSupportedException(); } } private static FieldInfo? _maxAnchorGhostDistanceField; private static FieldInfo? _maxAnchorDistanceField; private static FieldInfo? _releaseCheckField; private static FieldInfo? _goodAnchorPlaceField; private static FieldInfo? _ropeAnchorField; private static FieldInfo? _timeWithGoodAnchorField; private static FieldInfo? _itemField; private static FieldInfo? _itemOverrideProgressField; private static FieldInfo? _itemOverrideForceProgressField; private static MethodInfo? _getBodypartMethod; private static FieldInfo? _mainCameraInstanceField; private static Vector3 _lockedAnchorPosition; private static bool _isCasting; public static float BluePreviewRange { get; set; } public static float RedPreviewRange { get; set; } public static bool UseGroundPosition { get; set; } public static float VerticalOffset { get; set; } public static bool UseConsistentRaycastHeight { get; set; } public static float FixedRaycastHeight { get; set; } static RopeTier_FullFix_Patch() { BluePreviewRange = 2f; RedPreviewRange = 2.5f; UseGroundPosition = true; VerticalOffset = 0.07f; UseConsistentRaycastHeight = true; FixedRaycastHeight = 1.2f; Type typeFromHandle = typeof(RopeTier); _maxAnchorGhostDistanceField = AccessTools.Field(typeFromHandle, "maxAnchorGhostDistance"); _maxAnchorDistanceField = AccessTools.Field(typeFromHandle, "maxAnchorDistance"); _releaseCheckField = AccessTools.Field(typeFromHandle, "releaseCheck"); _goodAnchorPlaceField = AccessTools.Field(typeFromHandle, "goodAnchorPlace"); _ropeAnchorField = AccessTools.Field(typeFromHandle, "ropeAnchor"); _timeWithGoodAnchorField = AccessTools.Field(typeFromHandle, "timeWithGoodAnchor"); _itemField = AccessTools.Field(typeFromHandle, "item"); Type typeFromHandle2 = typeof(Item); _itemOverrideProgressField = AccessTools.Field(typeFromHandle2, "overrideProgress"); _itemOverrideForceProgressField = AccessTools.Field(typeFromHandle2, "overrideForceProgress"); _getBodypartMethod = AccessTools.Method(typeof(Character), "GetBodypart", new Type[1] { typeof(BodypartType) }, (Type[])null); Type typeFromHandle3 = typeof(MainCamera); _mainCameraInstanceField = AccessTools.Field(typeFromHandle3, "instance"); } [HarmonyPatch("Update")] [HarmonyTranspiler] private static IEnumerable<CodeInstruction> Transpiler_Update(IEnumerable<CodeInstruction> instructions) { List<CodeInstruction> list = new List<CodeInstruction>(instructions); for (int i = 0; i < list.Count; i++) { if (list[i].opcode == OpCodes.Ldfld && list[i].operand is FieldInfo fieldInfo && fieldInfo == _maxAnchorGhostDistanceField) { list[i].operand = _maxAnchorDistanceField; if (RopeAnchorFixPlugin.DebugMode) { RopeAnchorFixPlugin.Logger.LogInfo((object)"Patched: maxAnchorGhostDistance -> maxAnchorDistance"); } } if (list[i].opcode == OpCodes.Callvirt && list[i].operand is MethodInfo methodInfo && methodInfo.Name == "get_Center" && methodInfo.DeclaringType == typeof(Character)) { list[i].opcode = OpCodes.Call; list[i].operand = AccessTools.Method(typeof(RopeTier_FullFix_Patch), "GetDistancePoint", (Type[])null, (Type[])null); if (RopeAnchorFixPlugin.DebugMode) { RopeAnchorFixPlugin.Logger.LogInfo((object)"Patched: Character.Center -> GetDistancePoint"); } } if (i >= 1 && list[i].opcode == OpCodes.Callvirt && list[i].operand is MethodInfo methodInfo2 && methodInfo2.Name == "get_position" && methodInfo2.DeclaringType == typeof(Transform) && i > 0 && list[i - 1].opcode == OpCodes.Ldsfld && list[i - 1].operand is FieldInfo fieldInfo2 && fieldInfo2 == _mainCameraInstanceField && RopeAnchorFixPlugin.DebugMode) { RopeAnchorFixPlugin.Logger.LogInfo((object)("Found camera position access at index " + i)); } } return list; } [HarmonyPatch("Update")] [HarmonyPrefix] private static void Prefix_Update(RopeTier __instance) { //IL_0091: Unknown result type (might be due to invalid IL or missing references) //IL_0096: Unknown result type (might be due to invalid IL or missing references) //IL_0191: Unknown result type (might be due to invalid IL or missing references) //IL_0197: Invalid comparison between Unknown and I4 //IL_00e0: Unknown result type (might be due to invalid IL or missing references) //IL_00e5: Unknown result type (might be due to invalid IL or missing references) //IL_00e9: Unknown result type (might be due to invalid IL or missing references) //IL_00f0: Unknown result type (might be due to invalid IL or missing references) //IL_00fd: Unknown result type (might be due to invalid IL or missing references) //IL_0113: Unknown result type (might be due to invalid IL or missing references) //IL_0160: Unknown result type (might be due to invalid IL or missing references) //IL_0131: Unknown result type (might be due to invalid IL or missing references) //IL_013d: Unknown result type (might be due to invalid IL or missing references) //IL_022b: Unknown result type (might be due to invalid IL or missing references) //IL_0230: Unknown result type (might be due to invalid IL or missing references) //IL_0234: Unknown result type (might be due to invalid IL or missing references) //IL_0239: Unknown result type (might be due to invalid IL or missing references) //IL_0253: Unknown result type (might be due to invalid IL or missing references) //IL_0289: Unknown result type (might be due to invalid IL or missing references) //IL_028e: Unknown result type (might be due to invalid IL or missing references) //IL_0292: Unknown result type (might be due to invalid IL or missing references) //IL_02a9: Unknown result type (might be due to invalid IL or missing references) //IL_02d2: Unknown result type (might be due to invalid IL or missing references) //IL_02d7: Unknown result type (might be due to invalid IL or missing references) //IL_02d9: Unknown result type (might be due to invalid IL or missing references) //IL_02de: Unknown result type (might be due to invalid IL or missing references) //IL_03c3: Unknown result type (might be due to invalid IL or missing references) if (!((MonoBehaviourPun)__instance).photonView.IsMine) { return; } if (_maxAnchorDistanceField != null) { _maxAnchorDistanceField.SetValue(__instance, BluePreviewRange); } if (_maxAnchorGhostDistanceField != null) { _maxAnchorGhostDistanceField.SetValue(__instance, RedPreviewRange); } if (UseConsistentRaycastHeight && (Object)(object)MainCamera.instance != (Object)null) { Vector3 position = ((Component)MainCamera.instance).transform.position; object? obj = _itemField?.GetValue(__instance); Item val = (Item)((obj is Item) ? obj : null); if ((Object)(object)val != (Object)null && (Object)(object)val.holderCharacter != (Object)null) { Character holderCharacter = val.holderCharacter; Vector3 characterPosition = GetCharacterPosition(holderCharacter); Vector3 val2 = default(Vector3); ((Vector3)(ref val2))..ctor(position.x, characterPosition.y + FixedRaycastHeight, position.z); ((Component)MainCamera.instance).transform.position = val2; if (RopeAnchorFixPlugin.DebugMode) { RopeAnchorFixPlugin.Logger.LogInfo((object)$"Camera height adjusted: {position.y:F2} -> {val2.y:F2} (fixed height: {FixedRaycastHeight}m above ground)"); } ((MonoBehaviour)__instance).StartCoroutine(RestoreCameraPosition(position)); } } object? obj2 = _itemField?.GetValue(__instance); Item val3 = (Item)((obj2 is Item) ? obj2 : null); if ((Object)(object)val3 == (Object)null || (int)val3.itemState != 1) { _isCasting = false; return; } bool flag = _releaseCheckField != null && (bool)_releaseCheckField.GetValue(__instance); RaycastHit? val4 = _goodAnchorPlaceField?.GetValue(__instance) as RaycastHit?; object obj3 = _ropeAnchorField?.GetValue(__instance); if (!_isCasting && obj3 != null && val4.HasValue && !flag) { _isCasting = true; RaycastHit value = val4.Value; _lockedAnchorPosition = ((RaycastHit)(ref value)).point; if (RopeAnchorFixPlugin.DebugMode) { RopeAnchorFixPlugin.Logger.LogInfo((object)$"=== CASTING STARTED === Anchor locked at: {_lockedAnchorPosition}"); } } if (_isCasting && obj3 != null && val4.HasValue) { RaycastHit value2 = val4.Value; ((RaycastHit)(ref value2)).point = _lockedAnchorPosition; _goodAnchorPlaceField?.SetValue(__instance, value2); Character holderCharacter2 = val3.holderCharacter; if ((Object)(object)holderCharacter2 != (Object)null) { Vector3 characterPosition2 = GetCharacterPosition(holderCharacter2); float num = Vector3.Distance(_lockedAnchorPosition, characterPosition2); if (RopeAnchorFixPlugin.DebugMode && Time.frameCount % 30 == 0) { RopeAnchorFixPlugin.Logger.LogInfo((object)$"Cast distance: {num:F2}m / {BluePreviewRange:F2}m"); } if (num > BluePreviewRange) { if (RopeAnchorFixPlugin.DebugMode) { RopeAnchorFixPlugin.Logger.LogInfo((object)$"=== CAST CANCELLED === Distance {num:F2}m > {BluePreviewRange:F2}m"); } if (_itemOverrideProgressField != null) { _itemOverrideProgressField.SetValue(val3, 0f); } if (_itemOverrideForceProgressField != null) { _itemOverrideForceProgressField.SetValue(val3, false); } if (obj3 != null) { Object.DestroyImmediate((Object)(object)((Component)(RopeAnchor)obj3).gameObject); } if (_ropeAnchorField != null) { _ropeAnchorField.SetValue(__instance, null); } if (_goodAnchorPlaceField != null) { _goodAnchorPlaceField.SetValue(__instance, null); } if (_timeWithGoodAnchorField != null) { _timeWithGoodAnchorField.SetValue(__instance, 0f); } if (_releaseCheckField != null) { _releaseCheckField.SetValue(__instance, false); } _isCasting = false; } } } if (_isCasting && flag && obj3 == null) { _isCasting = false; if (RopeAnchorFixPlugin.DebugMode) { RopeAnchorFixPlugin.Logger.LogInfo((object)"=== CASTING COMPLETED ==="); } } } [IteratorStateMachine(typeof(<RestoreCameraPosition>d__40))] private static IEnumerator RestoreCameraPosition(Vector3 originalPos) { //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_0008: Unknown result type (might be due to invalid IL or missing references) //yield-return decompiler failed: Unexpected instruction in Iterator.Dispose() return new <RestoreCameraPosition>d__40(0) { originalPos = originalPos }; } public static Vector3 GetDistancePoint(Character character) { //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_000a: Unknown result type (might be due to invalid IL or missing references) return GetCharacterPosition(character); } private static Vector3 GetCharacterPosition(Character character) { //IL_000c: Unknown result type (might be due to invalid IL or missing references) //IL_0011: Unknown result type (might be due to invalid IL or missing references) //IL_002a: Unknown result type (might be due to invalid IL or missing references) //IL_002f: Unknown result type (might be due to invalid IL or missing references) //IL_001f: Unknown result type (might be due to invalid IL or missing references) //IL_0024: Unknown result type (might be due to invalid IL or missing references) //IL_004b: Unknown result type (might be due to invalid IL or missing references) //IL_0031: Unknown result type (might be due to invalid IL or missing references) //IL_0032: Unknown result type (might be due to invalid IL or missing references) //IL_003c: Unknown result type (might be due to invalid IL or missing references) //IL_0041: Unknown result type (might be due to invalid IL or missing references) //IL_0046: Unknown result type (might be due to invalid IL or missing references) //IL_0047: Unknown result type (might be due to invalid IL or missing references) //IL_0048: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)character == (Object)null) { return Vector3.zero; } Vector3 val = ((!UseGroundPosition) ? GetBodypartPosition(character) : GetGroundPosition(character)); return val + Vector3.up * VerticalOffset; } private static Vector3 GetBodypartPosition(Character character) { //IL_0011: Unknown result type (might be due to invalid IL or missing references) //IL_0016: Unknown result type (might be due to invalid IL or missing references) //IL_00a1: Unknown result type (might be due to invalid IL or missing references) //IL_0099: Unknown result type (might be due to invalid IL or missing references) //IL_009e: Unknown result type (might be due to invalid IL or missing references) //IL_0060: Unknown result type (might be due to invalid IL or missing references) //IL_0065: Unknown result type (might be due to invalid IL or missing references) if (_getBodypartMethod == null) { return character.Center; } try { object? obj = _getBodypartMethod.Invoke(character, new object[1] { (object)(BodypartType)0 }); Bodypart val = (Bodypart)((obj is Bodypart) ? obj : null); if ((Object)(object)val != (Object)null && (Object)(object)((Component)val).transform != (Object)null) { return ((Component)val).transform.position; } } catch (Exception ex) { if (RopeAnchorFixPlugin.DebugMode) { RopeAnchorFixPlugin.Logger.LogError((object)("Failed to get bodypart: " + ex.Message)); } } return character.Center; } private static Vector3 GetGroundPosition(Character character) { //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_000e: Unknown result type (might be due to invalid IL or missing references) //IL_000f: Unknown result type (might be due to invalid IL or missing references) //IL_0010: Unknown result type (might be due to invalid IL or missing references) //IL_0016: Unknown result type (might be due to invalid IL or missing references) //IL_001b: Unknown result type (might be due to invalid IL or missing references) //IL_0027: Unknown result type (might be due to invalid IL or missing references) //IL_002c: Unknown result type (might be due to invalid IL or missing references) //IL_0060: Unknown result type (might be due to invalid IL or missing references) //IL_0061: Unknown result type (might be due to invalid IL or missing references) //IL_0043: Unknown result type (might be due to invalid IL or missing references) //IL_0048: Unknown result type (might be due to invalid IL or missing references) //IL_0052: Unknown result type (might be due to invalid IL or missing references) //IL_0057: Unknown result type (might be due to invalid IL or missing references) //IL_005c: Unknown result type (might be due to invalid IL or missing references) //IL_0095: Unknown result type (might be due to invalid IL or missing references) //IL_009a: Unknown result type (might be due to invalid IL or missing references) //IL_00a4: Unknown result type (might be due to invalid IL or missing references) //IL_00a9: Unknown result type (might be due to invalid IL or missing references) //IL_00ae: Unknown result type (might be due to invalid IL or missing references) //IL_0077: Unknown result type (might be due to invalid IL or missing references) //IL_007c: Unknown result type (might be due to invalid IL or missing references) //IL_0086: Unknown result type (might be due to invalid IL or missing references) //IL_008b: Unknown result type (might be due to invalid IL or missing references) //IL_0090: Unknown result type (might be due to invalid IL or missing references) //IL_00b2: Unknown result type (might be due to invalid IL or missing references) Vector3 center = character.Center; float num = 3f; RaycastHit val = HelperFunctions.LineCheck(center, center + Vector3.down * num, (LayerType)1, 0f, (QueryTriggerInteraction)1); if ((Object)(object)((RaycastHit)(ref val)).collider != (Object)null) { return ((RaycastHit)(ref val)).point + Vector3.up * 0.1f; } RaycastHit val2 = default(RaycastHit); if (Physics.Raycast(center, Vector3.down, ref val2, num)) { return ((RaycastHit)(ref val2)).point + Vector3.up * 0.1f; } return character.Center - Vector3.up * 0.8f; } } }
ScuttlePenalty.dll
Decompiled a week agousing System; using System.Collections.Generic; using System.Diagnostics; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using System.Security; using System.Security.Permissions; using BepInEx; using BepInEx.Logging; using HarmonyLib; using Microsoft.CodeAnalysis; using Photon.Pun; using ScuttlePenalty.Core; using ScuttlePenalty.Utils; using UnityEngine; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)] [assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")] [assembly: AssemblyCompany("ScuttlePenalty")] [assembly: AssemblyConfiguration("Debug")] [assembly: AssemblyFileVersion("1.0.0.0")] [assembly: AssemblyInformationalVersion("1.0.0+fe42d853a6b27dae0bba338b4f740d2abb3fac53")] [assembly: AssemblyProduct("ScuttlePenalty")] [assembly: AssemblyTitle("ScuttlePenalty")] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("1.0.0.0")] [module: UnverifiableCode] [module: RefSafetyRules(11)] namespace Microsoft.CodeAnalysis { [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] internal sealed class EmbeddedAttribute : Attribute { } } namespace System.Runtime.CompilerServices { [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] [AttributeUsage(AttributeTargets.Class | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Parameter | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter, AllowMultiple = false, Inherited = false)] internal sealed class NullableAttribute : Attribute { public readonly byte[] NullableFlags; public NullableAttribute(byte P_0) { NullableFlags = new byte[1] { P_0 }; } public NullableAttribute(byte[] P_0) { NullableFlags = P_0; } } [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] [AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Method | AttributeTargets.Interface | AttributeTargets.Delegate, AllowMultiple = false, Inherited = false)] internal sealed class NullableContextAttribute : Attribute { public readonly byte Flag; public NullableContextAttribute(byte P_0) { Flag = P_0; } } [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] [AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)] internal sealed class RefSafetyRulesAttribute : Attribute { public readonly int Version; public RefSafetyRulesAttribute(int P_0) { Version = P_0; } } } namespace ScuttlePenalty { [BepInPlugin("jill920.scuttlepenalty", "Scuttle Penalty", "1.5.0")] public class ScuttlePenaltyPlugin : BaseUnityPlugin { public const string MOD_GUID = "jill920.scuttlepenalty"; public const string MOD_NAME = "Scuttle Penalty"; public const string MOD_VERSION = "1.5.0"; public static ScuttlePenaltyPlugin Instance; public static ManualLogSource Logger; public static bool DebugMode; public const float REGRAB_PENALTY = 0.28f; public const float REGRAB_WINDOW_MS = 500f; public const int PENALTY_START_AT = 2; public const float REGRAB_PENALTY_MULTIPLIER = 0.5f; public const float MAX_REGRAB_PENALTY_MULTIPLIER = 3.5f; public const float MIN_PITCH_FOR_PENALTY = 30f; public const float MAX_PITCH_FOR_EXPLOIT = -30f; public const float TENDERFOOT_BASELINE = 0.14f; public const float MAX_ANGLE_MULTIPLIER = 2.5f; public const float MIN_ANGLE_MULTIPLIER = 0.1f; public const float MIN_OVERDRAIN_TO_REFUND = 0.02f; public const float REFUND_PERCENTAGE = 0.95f; public const float MAX_REFUND_PER_EVENT = 0.35f; public const float MAX_REFUND_PER_WINDOW = 0.6f; public const float REFUND_WINDOW_SECONDS = 10f; public const float MIN_CLIMB_DURATION_SECONDS = 0.2f; public const float MAX_COMPENSATION_PER_WINDOW = 0.5f; public const float COMPENSATION_WINDOW_SECONDS = 10f; public const float MIN_IMMEDIATE_COMPENSATION = 0.08f; public const float MAX_IMMEDIATE_COMPENSATION = 0.25f; private void Awake() { Instance = this; Logger = ((BaseUnityPlugin)this).Logger; string[] commandLineArgs = Environment.GetCommandLineArgs(); string[] array = commandLineArgs; foreach (string text in array) { if (text.Equals("-ScuttleDebug", StringComparison.OrdinalIgnoreCase)) { DebugMode = true; break; } } Harmony.CreateAndPatchAll(Assembly.GetExecutingAssembly(), "jill920.scuttlepenalty"); Logger.LogInfo((object)"[Scuttle Penalty 1.5.0] Loaded"); Logger.LogInfo((object)(" Debug Mode: " + (DebugMode ? "ENABLED" : "DISABLED"))); Logger.LogInfo((object)$" Penalty: {0.28f} stamina per re-grab (starting at re-grab #{3})"); Logger.LogInfo((object)$" Immediate Compensation: {0.08f}-{0.25f} stamina on forced re-grabs"); Logger.LogInfo((object)$" Final Refund: Returns {95f}% of remaining over-drain"); } } } namespace ScuttlePenalty.Utils { public static class StaminaHelper { private static MethodInfo? _useStaminaMethod; public static void ApplyStaminaPenalty(Character character, float amount) { if (_useStaminaMethod == null) { _useStaminaMethod = typeof(Character).GetMethod("UseStamina", BindingFlags.Instance | BindingFlags.NonPublic); } if (_useStaminaMethod != null) { _useStaminaMethod.Invoke(character, new object[2] { amount, true }); } else { character.data.currentStamina = Mathf.Max(0f, character.data.currentStamina - amount); } } public static void ApplyStaminaRefund(Character character, float amount) { if (!(amount <= 0.001f)) { character.AddStamina(amount); } } } } namespace ScuttlePenalty.Patches { [HarmonyPatch(typeof(CharacterClimbing))] internal static class CharacterClimbing_StartPatch { private static void LogDebug(string message) { if (ScuttlePenaltyPlugin.DebugMode) { ScuttlePenaltyPlugin.Logger.LogInfo((object)message); } } private static void LogWarning(string message) { ScuttlePenaltyPlugin.Logger.LogWarning((object)message); } private static ReGrabTracker GetTracker(Character character) { int viewID = ((MonoBehaviourPun)character).photonView.ViewID; if (!SharedState.Trackers.ContainsKey(viewID)) { SharedState.Trackers[viewID] = new ReGrabTracker(); } return SharedState.Trackers[viewID]; } private static CompensationTracker GetCompensationTracker(Character character) { int viewID = ((MonoBehaviourPun)character).photonView.ViewID; if (!SharedState.CompensationTrackers.ContainsKey(viewID)) { SharedState.CompensationTrackers[viewID] = new CompensationTracker(); } return SharedState.CompensationTrackers[viewID]; } [HarmonyPatch("StartClimbRpc")] [HarmonyPrefix] private static void Prefix(CharacterClimbing __instance, Vector3 climbPos, Vector3 climbNormal) { Character component = ((Component)__instance).GetComponent<Character>(); if ((Object)(object)component == (Object)null || !component.IsLocal) { return; } ReGrabTracker tracker = GetTracker(component); int viewID = ((MonoBehaviourPun)component).photonView.ViewID; float time = Time.time; float currentStamina = component.data.currentStamina; float extraStamina = component.data.extraStamina; tracker.StartNewClimb(time, currentStamina, extraStamina); bool flag = SharedState.LastClimbEndTime.ContainsKey(viewID) && SharedState.LastClimbEndTime[viewID] > 0f; float num = (flag ? (time - SharedState.LastClimbEndTime[viewID]) : 999f); bool flag2 = flag && num < 0.5f; string text = (SharedState.LastStopReason.ContainsKey(viewID) ? SharedState.LastStopReason[viewID] : ""); if (flag2) { float num2 = num * 1000f; if (text == "MOUSE1") { tracker.RegisterReGrab(time); int consecutiveReGrabs = tracker.ConsecutiveReGrabs; if (consecutiveReGrabs >= 2) { float num3 = Mathf.Min(1f + (float)(consecutiveReGrabs - 2) * 0.5f, 3.5f); float num4 = 0.28f * num3; StaminaHelper.ApplyStaminaPenalty(component, num4); LogWarning($"PENALTY #{consecutiveReGrabs}: -{num4:F2} stamina (re-grab after {num2:F0}ms)"); } else { LogDebug($"RE-GRAB #{consecutiveReGrabs}: FREE (wall switch) - {num2:F0}ms after MOUSE1 release"); } return; } tracker.CurrentClimbIsForcedReGrab = true; float y = component.data.lookValues.y; LogDebug($"FORCED RE-GRAB DETECTED: Pitch={y:F1}°, lastReason={text}, timeSinceStop={num2:F0}ms"); if (y > 30f) { float num5 = Mathf.Clamp01((y - 30f) / 60f); float num6 = Mathf.Lerp(0.08f, 0.25f, num5); CompensationTracker compensationTracker = GetCompensationTracker(component); compensationTracker.ResetWindow(time); if (compensationTracker.CanCompensate(num6)) { StaminaHelper.ApplyStaminaRefund(component, num6); compensationTracker.AddCompensation(num6); tracker.ImmediateCompensationGiven = num6; LogWarning($"IMMEDIATE COMPENSATION: +{num6:F3} stamina (pitch={y:F1}°)"); } else if (ScuttlePenaltyPlugin.DebugMode) { LogDebug("IMMEDIATE COMPENSATION SKIPPED: Rate limit exceeded"); } } if (tracker.ConsecutiveReGrabs > 0) { LogDebug("RE-GRAB CHAIN RESET: Previous stop was " + text); tracker.Reset(); } } else if (tracker.ConsecutiveReGrabs > 0 && ScuttlePenaltyPlugin.DebugMode) { LogDebug("RE-GRAB CHAIN RESET: Long delay between climbs"); tracker.Reset(); } } } [HarmonyPatch(typeof(CharacterClimbing))] internal static class CharacterClimbing_StopPatch { private static void LogDebug(string message) { if (ScuttlePenaltyPlugin.DebugMode) { ScuttlePenaltyPlugin.Logger.LogInfo((object)message); } } private static void LogWarning(string message) { ScuttlePenaltyPlugin.Logger.LogWarning((object)message); } private static ReGrabTracker GetTracker(Character character) { int viewID = ((MonoBehaviourPun)character).photonView.ViewID; if (!SharedState.Trackers.ContainsKey(viewID)) { SharedState.Trackers[viewID] = new ReGrabTracker(); } return SharedState.Trackers[viewID]; } [HarmonyPatch("StopClimbingRpc")] [HarmonyPrefix] private static void Prefix(CharacterClimbing __instance, float setFall) { Character component = ((Component)__instance).GetComponent<Character>(); if ((Object)(object)component == (Object)null || !component.IsLocal) { return; } ReGrabTracker tracker = GetTracker(component); int viewID = ((MonoBehaviourPun)component).photonView.ViewID; float time = Time.time; float currentStamina = component.data.currentStamina; float extraStamina = component.data.extraStamina; tracker.EndCurrentClimb(time, currentStamina, extraStamina); float duration = tracker.CurrentClimb.Duration; float totalStaminaLost = tracker.CurrentClimb.TotalStaminaLost; float totalStartStamina = tracker.CurrentClimb.TotalStartStamina; string text = "OTHER"; if (component.input.jumpWasPressed) { text = "JUMP"; } else if (component.input.usePrimaryWasReleased) { text = "MOUSE1"; } else if (setFall > 0f) { text = "VAULT"; } LogDebug($"CLIMB STOPPED: Reason={text}, Duration={duration * 1000f:F0}ms, " + $"Loss={totalStaminaLost:F3}, StartStam={totalStartStamina:F3}, EndStam={currentStamina:F3}"); if (tracker.CurrentClimbIsForcedReGrab) { float y = component.data.lookValues.y; LogDebug($"FORCED RE-GRAB CLIMB ENDED: Pitch={y:F1}°, Duration={duration * 1000f:F0}ms, Loss={totalStaminaLost:F3}"); if (y > 30f && duration >= 0.2f && totalStaminaLost > 0f) { float num = RefundCalculator.CalculateRefund(duration, totalStaminaLost, totalStartStamina, y); if (tracker.ImmediateCompensationGiven > 0f) { float num2 = num; num = Mathf.Max(0f, num - tracker.ImmediateCompensationGiven); LogDebug($"ADJUSTING REFUND: Immediate given={tracker.ImmediateCompensationGiven:F3}, " + $"Original refund={num2:F3}, Final refund={num:F3}"); } if (num > 0f) { tracker.Refund.ResetWindow(time); if (tracker.Refund.CanRefund(num)) { StaminaHelper.ApplyStaminaRefund(component, num); tracker.Refund.AddRefund(num); float num3 = RefundCalculator.CalculateExpectedLoss(duration, y); float num4 = totalStaminaLost - num3; LogWarning($"FINAL REFUND | Pitch={y:F1}° | Duration={duration * 1000f:F0}ms | " + $"Expected={num3:F3} | Actual={totalStaminaLost:F3} | Over={num4:F3} | " + $"Refund={num:F3} | Total={tracker.Refund.RefundAmountInWindow:F3}/{0.6f:F3}"); } else if (ScuttlePenaltyPlugin.DebugMode) { LogDebug("REFUND SKIPPED: Rate limit exceeded"); } } else if (ScuttlePenaltyPlugin.DebugMode) { LogDebug("REFUND SKIPPED: Calculated refund amount was 0 after subtracting immediate compensation"); } } else if (ScuttlePenaltyPlugin.DebugMode) { LogDebug($"REFUND SKIPPED: Conditions not met - pitch={y:F1}°, duration={duration:F2}s, loss={totalStaminaLost:F3}"); } tracker.CurrentClimbIsForcedReGrab = false; tracker.ImmediateCompensationGiven = 0f; } SharedState.LastClimbEndTime[viewID] = time; SharedState.LastStopReason[viewID] = text; } } } namespace ScuttlePenalty.Core { public class ClimbData { public float StartTime { get; set; } public float EndTime { get; set; } public float StartStamina { get; set; } public float EndStamina { get; set; } public float StartBonus { get; set; } public float EndBonus { get; set; } public float Duration => EndTime - StartTime; public float TotalStaminaLost => StartStamina + StartBonus - (EndStamina + EndBonus); public float TotalStartStamina => StartStamina + StartBonus; public void Reset() { StartTime = 0f; EndTime = 0f; StartStamina = 1f; EndStamina = 1f; StartBonus = 0f; EndBonus = 0f; } public void RecordStart(float time, float stamina, float bonus) { StartTime = time; StartStamina = stamina; StartBonus = bonus; } public void RecordEnd(float time, float stamina, float bonus) { EndTime = time; EndStamina = stamina; EndBonus = bonus; } } public class CompensationTracker { public float LastCompensationTime { get; private set; } = -10f; public float CompensationAmountInWindow { get; private set; } = 0f; public void ResetWindow(float currentTime) { if (currentTime - LastCompensationTime > 10f) { CompensationAmountInWindow = 0f; LastCompensationTime = currentTime; } } public bool CanCompensate(float amount) { return CompensationAmountInWindow + amount <= 0.6f; } public void AddCompensation(float amount) { CompensationAmountInWindow += amount; } } public static class RefundCalculator { public static float GetDifficultyBaseline() { float num = Ascents.climbStaminaMultiplier; if (RunSettings.GetValue((SETTINGTYPE)20000, false) == 1) { num *= 4f; } return 0.14f * num; } public static float GetExpectedDrainRate(float pitch) { float difficultyBaseline = GetDifficultyBaseline(); if (pitch >= -30f && pitch <= 30f) { return difficultyBaseline; } if (pitch > 30f) { float num = 1f + (pitch - 30f) / 60f * 1.5f; return difficultyBaseline * Mathf.Min(num, 2.5f); } if (pitch < -30f) { float num2 = 1f - (Mathf.Abs(pitch) - Mathf.Abs(-30f)) / 60f * 0.9f; return difficultyBaseline * Mathf.Max(num2, 0.1f); } return difficultyBaseline; } public static float CalculateExpectedLoss(float duration, float pitch) { return duration * GetExpectedDrainRate(pitch); } public static float CalculateRefund(float duration, float actualLoss, float startStamina, float pitch) { float num = CalculateExpectedLoss(duration, pitch); float num2 = actualLoss - num; if (num2 <= 0.02f) { return 0f; } float num3 = num2 * 0.95f; num3 = Mathf.Min(num3, 0.35f); float num4 = Mathf.Max(0f, startStamina - (startStamina - actualLoss)); return Mathf.Min(num3, num4); } } public class RefundTracker { public float LastRefundTime { get; private set; } = -10f; public float RefundAmountInWindow { get; private set; } = 0f; public void ResetWindow(float currentTime) { if (currentTime - LastRefundTime > 10f) { RefundAmountInWindow = 0f; LastRefundTime = currentTime; } } public bool CanRefund(float amount) { return RefundAmountInWindow + amount <= 0.6f; } public void AddRefund(float amount) { RefundAmountInWindow += amount; } } public class ReGrabTracker { public int ConsecutiveReGrabs { get; set; } = 0; public float LastReGrabTime { get; set; } = 0f; public bool CurrentClimbIsForcedReGrab { get; set; } = false; public float ImmediateCompensationGiven { get; set; } = 0f; public ClimbData CurrentClimb { get; private set; } public RefundTracker Refund { get; private set; } public ReGrabTracker() { CurrentClimb = new ClimbData(); Refund = new RefundTracker(); CurrentClimb.Reset(); } public void Reset() { ConsecutiveReGrabs = 0; LastReGrabTime = 0f; CurrentClimbIsForcedReGrab = false; ImmediateCompensationGiven = 0f; } public void RegisterReGrab(float currentTime) { ConsecutiveReGrabs++; LastReGrabTime = currentTime; } public void StartNewClimb(float time, float stamina, float bonus) { CurrentClimb.RecordStart(time, stamina, bonus); CurrentClimbIsForcedReGrab = false; ImmediateCompensationGiven = 0f; } public void EndCurrentClimb(float time, float stamina, float bonus) { CurrentClimb.RecordEnd(time, stamina, bonus); } } public static class SharedState { public static Dictionary<int, float> LastClimbEndTime { get; } = new Dictionary<int, float>(); public static Dictionary<int, string> LastStopReason { get; } = new Dictionary<int, string>(); public static Dictionary<int, ReGrabTracker> Trackers { get; } = new Dictionary<int, ReGrabTracker>(); public static Dictionary<int, CompensationTracker> CompensationTrackers { get; } = new Dictionary<int, CompensationTracker>(); } }
StaminaAdjuster.dll
Decompiled a week agousing System; using System.Diagnostics; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using System.Security; using System.Security.Permissions; using BepInEx; using BepInEx.Logging; using HarmonyLib; using Microsoft.CodeAnalysis; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)] [assembly: AssemblyCompany("StaminaAdjuster")] [assembly: AssemblyConfiguration("Debug")] [assembly: AssemblyFileVersion("1.0.0.0")] [assembly: AssemblyInformationalVersion("1.0.0+45474b8f820e22b4b62e4177fd48df206621e63c")] [assembly: AssemblyProduct("Allows all stamina values to be changed from a config.")] [assembly: AssemblyTitle("StaminaAdjuster")] [assembly: TargetFramework(".NETFramework,Version=v4.7.1", FrameworkDisplayName = ".NET Framework 4.7.1")] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("1.0.0.0")] [module: UnverifiableCode] [module: RefSafetyRules(11)] namespace Microsoft.CodeAnalysis { [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] internal sealed class EmbeddedAttribute : Attribute { } } namespace System.Runtime.CompilerServices { [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] [AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)] internal sealed class RefSafetyRulesAttribute : Attribute { public readonly int Version; public RefSafetyRulesAttribute(int P_0) { Version = P_0; } } } namespace StaminaAdjuster { [HarmonyPatch(typeof(CharacterClimbing), "Start")] internal class Patch2 { private static void Postfix(CharacterClimbing __instance) { __instance.maxStaminaUsage = 0.2f; __instance.minStaminaUsage = 0.01f; } } [BepInPlugin("StaminaAdjuster", "Stamina Adjuster", "1.0.1")] public class Plugin : BaseUnityPlugin { internal static ManualLogSource Log; public const string MOD_GUID = "StaminaAdjuster"; public const string MOD_NAME = "Stamina Adjuster"; public const string MOD_VERSION = "1.0.1"; public const float MAX_CLIMB_STAMINA_USAGE = 0.2f; public const float MIN_CLIMB_STAMINA_USAGE = 0.01f; private void Awake() { Log = ((BaseUnityPlugin)this).Logger; Harmony.CreateAndPatchAll(Assembly.GetExecutingAssembly(), "StaminaAdjuster"); Log.LogInfo((object)"[Stamina Adjuster 1.0.1] Loaded!"); Log.LogInfo((object)$" MaxClimbStaminaUsage: {0.2f}"); Log.LogInfo((object)$" MinClimbStaminaUsage: {0.01f}"); } } }