Please disclose if any significant portion of your mod was created using AI tools by adding the 'AI Generated' category. Failing to do so may result in the mod being removed from Thunderstore.
Decompiled source of DeathHeadHopperFix v0.2.8
plugins\DeathHeadHopperFix.dll
Decompiled 2 weeks ago
The result has been truncated due to the large size, download it to view full contents!
using System; using System.Collections; using System.Collections.Generic; using System.Diagnostics; using System.Globalization; using System.IO; using System.Linq; using System.Reflection; using System.Reflection.Emit; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using System.Security; using System.Security.Permissions; using System.Threading; using BepInEx; using BepInEx.Configuration; using BepInEx.Logging; using DeathHeadHopper; using DeathHeadHopper.Abilities; using DeathHeadHopper.Abilities.Charge; using DeathHeadHopper.DeathHead; using DeathHeadHopper.DeathHead.Handlers; using DeathHeadHopper.Helpers; using DeathHeadHopper.Items; using DeathHeadHopper.Managers; using DeathHeadHopper.Patches; using DeathHeadHopper.UI; using DeathHeadHopperFix.API.Abilities; using DeathHeadHopperFix.API.Battery; using DeathHeadHopperFix.Modules.Battery; using DeathHeadHopperFix.Modules.Config; using DeathHeadHopperFix.Modules.Gameplay.Core.Abilities; using DeathHeadHopperFix.Modules.Gameplay.Core.Audio; using DeathHeadHopperFix.Modules.Gameplay.Core.Bootstrap; using DeathHeadHopperFix.Modules.Gameplay.Core.Input; using DeathHeadHopperFix.Modules.Gameplay.Core.Interop; using DeathHeadHopperFix.Modules.Gameplay.Core.Runtime; using DeathHeadHopperFix.Modules.Gameplay.Spectate; using DeathHeadHopperFix.Modules.Gameplay.Stun; using DeathHeadHopperFix.Modules.Stamina; using DeathHeadHopperFix.Modules.Utilities; using ExitGames.Client.Photon; using HarmonyLib; using Microsoft.CodeAnalysis; using Photon.Pun; using Photon.Realtime; using REPOLib.Modules; using TMPro; using UnityEngine; using UnityEngine.Events; using UnityEngine.SceneManagement; 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(".NETFramework,Version=v4.8", FrameworkDisplayName = ".NET Framework 4.8")] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("0.0.0.0")] [module: UnverifiableCode] [module: RefSafetyRules(11)] namespace Microsoft.CodeAnalysis { [CompilerGenerated] [Embedded] internal sealed class EmbeddedAttribute : Attribute { } } namespace System.Runtime.CompilerServices { [CompilerGenerated] [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] [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] [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 DeathHeadHopperFix { [BepInPlugin("AdrenSnyder.DeathHeadHopperFix", "Death Head Hopper - Fix", "0.2.8")] public sealed class Plugin : BaseUnityPlugin { private const string TargetAssemblyName = "DeathHeadHopper"; private Harmony? _harmony; private bool _patched; private bool _patchAttempted; private Assembly? _targetAssembly; private static ManualLogSource? _log; internal static Plugin? Instance { get; private set; } private void Awake() { //IL_0032: Unknown result type (might be due to invalid IL or missing references) //IL_003c: Expected O, but got Unknown Instance = this; _log = ((BaseUnityPlugin)this).Logger; ConfigManager.Initialize(((BaseUnityPlugin)this).Config, ((BaseUnityPlugin)this).Logger); WarnUnsafeDebugFlagsInRelease(); _harmony = new Harmony("AdrenSnyder.DeathHeadHopperFix"); DhhPatchRegistryModule.Initialize(((BaseUnityPlugin)this).Logger); if (FeatureFlags.DebugLogging) { ((BaseUnityPlugin)this).Logger.LogInfo((object)"[Fix:StartupDiag] Fix Harmony.PatchAll begin."); } try { _harmony.PatchAll(typeof(Plugin).Assembly); } catch (Exception ex) { ((BaseUnityPlugin)this).Logger.LogError((object)"[Fix:StartupDiag] Fix Harmony.PatchAll failed."); ((BaseUnityPlugin)this).Logger.LogError((object)ex); throw; } if (FeatureFlags.DebugLogging) { ((BaseUnityPlugin)this).Logger.LogInfo((object)"[Fix:StartupDiag] Fix Harmony.PatchAll complete."); } DHHApiGuardModule.DetectGameApiChanges(); ApplyEarlyPatches(); AppDomain.CurrentDomain.AssemblyLoad += OnAssemblyLoad; Assembly[] assemblies = AppDomain.CurrentDomain.GetAssemblies(); foreach (Assembly asm in assemblies) { TryPatchIfTargetAssembly(asm); } } private void OnDestroy() { AppDomain.CurrentDomain.AssemblyLoad -= OnAssemblyLoad; if ((Object)(object)Instance == (Object)(object)this) { Instance = null; } } private void OnAssemblyLoad(object sender, AssemblyLoadEventArgs args) { TryPatchIfTargetAssembly(args.LoadedAssembly); } private void ApplyEarlyPatches() { if (_harmony != null) { StatsModule.ApplyHooks(_harmony); ItemUpgradeModule.Apply(_harmony); } } private void TryPatchIfTargetAssembly(Assembly asm) { if (_patched || _patchAttempted || asm == null) { return; } string name = asm.GetName().Name; if (!string.Equals(name, "DeathHeadHopper", StringComparison.OrdinalIgnoreCase)) { return; } _patchAttempted = true; try { ManualLogSource? log = _log; if (log != null) { log.LogInfo((object)"Detected DeathHeadHopper assembly load. Applying patches..."); } Harmony harmony = _harmony; if (harmony == null) { throw new InvalidOperationException("Harmony instance is null."); } DHHStatsBootstrapModule.Apply(harmony, asm, _log); PrefabModule.Apply(harmony, asm, _log); AudioModule.Apply(harmony, asm, _log); bool flag = DHHShopVanillaPoolModule.Apply(harmony, asm, _log); _targetAssembly = asm; DHHApiGuardModule.Apply(harmony, asm); BatteryJumpPatchModule.Apply(harmony, _log); JumpForceModule.Apply(harmony, _log); ChargeAbilityTuningModule.Apply(harmony, asm); ChargeHoldReleaseModule.Apply(harmony, asm, _log); InputModule.Apply(harmony, asm, _log); AbilityModule.ApplyAbilitySpotLabelOverlay(harmony); AbilityModule.ApplyAbilityManagerHooks(harmony); _patched = true; if (flag) { ManualLogSource? log2 = _log; if (log2 != null) { log2.LogInfo((object)"Patches applied successfully."); } } else { ManualLogSource? log3 = _log; if (log3 != null) { log3.LogWarning((object)"DHH patch setup completed with incomplete shop hook registration; see [Fix:Shop] messages."); } } } catch (Exception ex) { ManualLogSource? log4 = _log; if (log4 != null) { log4.LogError((object)ex); } } } private void WarnUnsafeDebugFlagsInRelease() { if (!Debug.isDebugBuild && (InternalDebugFlags.DisableBatteryModule || InternalDebugFlags.DisableAbilityPatches || InternalDebugFlags.DisableSpectateChecks)) { ManualLogSource? log = _log; if (log != null) { log.LogWarning((object)("[DebugSafety] Internal debug bypass flags are enabled in a non-debug build. " + $"DisableBatteryModule={InternalDebugFlags.DisableBatteryModule}, " + $"DisableAbilityPatches={InternalDebugFlags.DisableAbilityPatches}, " + $"DisableSpectateChecks={InternalDebugFlags.DisableSpectateChecks}")); } } } } } namespace DeathHeadHopperFix.Modules.Utilities { internal static class LogLimiter { public const int DefaultFrameInterval = 240; private static readonly Dictionary<string, int> _lastFrameByKey = new Dictionary<string, int>(StringComparer.Ordinal); public static bool ShouldLog(string key, int frameInterval = 240) { if (string.IsNullOrEmpty(key)) { return true; } if (frameInterval <= 0) { return true; } int frameCount = Time.frameCount; if (_lastFrameByKey.TryGetValue(key, out var value) && frameCount - value < frameInterval) { return false; } _lastFrameByKey[key] = frameCount; return true; } public static void Reset(string key) { if (!string.IsNullOrEmpty(key)) { _lastFrameByKey.Remove(key); } } public static void Clear() { _lastFrameByKey.Clear(); } } internal static class NetworkProtocol { internal const string ModId = "DeathHeadHopperFix"; internal const int ProtocolVersion = 1; internal const string RoomKeyPrefix = "DeathHeadHopperFix.Room."; internal static string BuildRoomKey(string localKey) { return string.IsNullOrWhiteSpace(localKey) ? "DeathHeadHopperFix.Room." : ("DeathHeadHopperFix.Room." + localKey.Trim()); } } internal readonly struct NetworkEnvelope { internal string ModId { get; } internal int ProtocolVersion { get; } internal string MessageType { get; } internal int MessageSeq { get; } internal object? Payload { get; } internal NetworkEnvelope(string modId, int protocolVersion, string messageType, int messageSeq, object? payload) { ModId = (string.IsNullOrWhiteSpace(modId) ? string.Empty : modId.Trim()); ProtocolVersion = protocolVersion; MessageType = (string.IsNullOrWhiteSpace(messageType) ? string.Empty : messageType.Trim()); MessageSeq = messageSeq; Payload = payload; } internal object?[] ToEventPayload() { return new object[5] { ModId, ProtocolVersion, MessageType, MessageSeq, Payload }; } internal bool IsExpectedSource() { return ModId == "DeathHeadHopperFix" && ProtocolVersion == 1 && !string.IsNullOrWhiteSpace(MessageType); } internal static bool TryParse(object? customData, out NetworkEnvelope envelope) { envelope = default(NetworkEnvelope); if (!(customData is object[] array) || array.Length < 5) { return false; } if (array[0] is string modId && array[1] is int protocolVersion && array[2] is string messageType) { object obj = array[3]; int messageSeq = default(int); int num; if (obj is int) { messageSeq = (int)obj; num = 1; } else { num = 0; } if (num != 0) { envelope = new NetworkEnvelope(modId, protocolVersion, messageType, messageSeq, array[4]); return true; } } return false; } } internal static class PhotonEventCodes { internal const byte ConfigSync = 79; } internal static class SpectateContextHelper { private static readonly FieldInfo? s_spectatePlayerField = AccessTools.Field(typeof(SpectateCamera), "player"); private static readonly FieldInfo? s_playerDeathHeadSpectatedField = AccessTools.Field(typeof(PlayerDeathHead), "spectated"); internal static bool IsSpectatingLocalPlayerTarget() { SpectateCamera instance = SpectateCamera.instance; PlayerAvatar instance2 = PlayerAvatar.instance; if ((Object)(object)instance == (Object)null || (Object)(object)instance2 == (Object)null || s_spectatePlayerField == null) { return false; } object? value = s_spectatePlayerField.GetValue(instance); PlayerAvatar val = (PlayerAvatar)((value is PlayerAvatar) ? value : null); return (Object)(object)val != (Object)null && val == instance2; } internal static bool IsSpectatingLocalDeathHead() { SpectateCamera instance = SpectateCamera.instance; if ((Object)(object)instance == (Object)null || !instance.CheckState((State)2)) { return false; } PlayerDeathHead val = PlayerController.instance?.playerAvatarScript?.playerDeathHead; if ((Object)(object)val == (Object)null || s_playerDeathHeadSpectatedField == null) { return false; } return s_playerDeathHeadSpectatedField.GetValue(val) as bool? == true; } internal static bool IsLocalDeathHeadSpectated() { PlayerDeathHead val = PlayerController.instance?.playerAvatarScript?.playerDeathHead; if ((Object)(object)val == (Object)null || s_playerDeathHeadSpectatedField == null) { return false; } return s_playerDeathHeadSpectatedField.GetValue(val) as bool? == true; } } } namespace DeathHeadHopperFix.Modules.Stamina { internal sealed class StaminaRechargeModule : MonoBehaviour { private DeathHeadController? _controller; private bool _isOwner; private float _rechargeAccumulator; private Rigidbody? _rb; private void Awake() { _controller = ((Component)this).GetComponent<DeathHeadController>(); if ((Object)(object)_controller == (Object)null) { ((Behaviour)this).enabled = false; return; } PhotonView component = ((Component)this).GetComponent<PhotonView>(); _isOwner = !SemiFunc.IsMultiplayer() || ((Object)(object)component != (Object)null && component.IsMine); _rb = ((Component)this).GetComponent<Rigidbody>(); } private void Update() { if (!_isOwner || (Object)(object)_controller == (Object)null) { return; } if (!FeatureFlags.RechargeWithStamina) { _rechargeAccumulator = 0f; return; } _rechargeAccumulator += Time.deltaTime; if (!(_rechargeAccumulator < FeatureFlags.RechargeTickInterval)) { if (!FeatureFlags.RechargeStaminaOnlyStationary || IsHeadStationary()) { DHHBatteryHelper.RechargeDhhAbilityEnergy(_controller, _rechargeAccumulator); } _rechargeAccumulator = 0f; } } private bool IsHeadStationary() { //IL_0015: Unknown result type (might be due to invalid IL or missing references) //IL_001a: Unknown result type (might be due to invalid IL or missing references) int result; if (!((Object)(object)_rb == (Object)null)) { Vector3 linearVelocity = _rb.linearVelocity; result = ((((Vector3)(ref linearVelocity)).sqrMagnitude < FeatureFlags.HeadStationaryVelocitySqrThreshold) ? 1 : 0); } else { result = 1; } return (byte)result != 0; } } } namespace DeathHeadHopperFix.Modules.Gameplay.Stun { internal static class ChargeHoldReleaseModule { private sealed class ChargeHoldState { public float StartTime; public bool IsHolding; public float LaunchScale = 1f; public float ChargingStartTime; public float RestingTime; } private sealed class ChargeMotionDiagnosticTrace { public float LastSampleTime = float.NegativeInfinity; public int SampleCount; public bool SampleLimitLogged; public bool HasPreviousSamplePosition; public Vector3 PreviousHeadSamplePosition; public Vector3 PreviousTumbleSamplePosition; public ChargeHandler? ChargeHandler; public PhysGrabObject? PhysGrabObject; public int PhysGrabSampleCount; public float LastPhysGrabSampleTime = float.NegativeInfinity; public bool PhysGrabSampleLimitLogged; public int MovePositionLogCount; public float LastMovePositionLogTime = float.NegativeInfinity; public bool MovePositionLimitLogged; public int RigidbodyPositionLogCount; public float LastRigidbodyPositionLogTime = float.NegativeInfinity; public bool RigidbodyPositionLimitLogged; public int TransformPositionLogCount; public float LastTransformPositionLogTime = float.NegativeInfinity; public bool TransformPositionLimitLogged; } private struct ChargeMotionSnapshot { public bool Enabled; public int HandlerId; public int SampleNumber; public ChargeState State; public int HeadRigidbodyId; public Vector3 HeadPosition; public Vector3 HeadDeltaSincePreviousSample; public Vector3 HeadVelocity; public bool HeadIsKinematic; public Vector3 TargetStartOffset; public Vector3 CurrentStartOffset; public Vector3 StartVelocity; public Vector3 ChargeDirection; public float ChargeStrength; public float WindupTimer; public float ChargeTimer; public int BounceCount; public int EnemiesHit; public bool IsColliding; public bool IsGrabbed; public bool IsFrozen; public int TumbleRigidbodyId; public Vector3 TumblePosition; public Vector3 TumbleDeltaSincePreviousSample; public Vector3 TumbleVelocity; public bool TumbleIsKinematic; } private struct PhysGrabMotionSnapshot { public bool Enabled; public ChargeHandler? ChargeHandler; public int HandlerId; public int SampleNumber; public ChargeState ChargeState; public int PhysGrabObjectId; public int RigidbodyId; public Vector3 TransformPosition; public Vector3 RigidbodyPosition; public Vector3 LinearVelocity; public bool IsKinematic; public bool Frozen; public float FrozenTimer; public Vector3 FrozenPosition; public Vector3 FrozenVelocity; public bool Grabbed; public int PlayerGrabberCount; } [HarmonyPatch(typeof(ChargeHandler), "StartWindup")] private static class ChargeHandlerStartWindupPatch { [HarmonyPrepare] private static bool Prepare() { return s_chargeGroundPatchReady; } [HarmonyPrefix] private static void Prefix(ChargeHandler __instance, out bool __state) { //IL_000c: Unknown result type (might be due to invalid IL or missing references) //IL_0012: Invalid comparison between Unknown and I4 __state = (Object)(object)__instance != (Object)null && (int)__instance.State == 0; } [HarmonyPostfix] private static void Postfix(ChargeHandler __instance, bool __state) { //IL_000e: Unknown result type (might be due to invalid IL or missing references) //IL_0014: Invalid comparison between Unknown and I4 if (__state && !((Object)(object)__instance == (Object)null) && (int)__instance.State == 1) { ApplyGroundOffsetGuard(__instance); } } } [HarmonyPatch(typeof(ChargeHandler), "FixedUpdate")] private static class ChargeHandlerMotionDiagnosticPatch { [HarmonyPrepare] private static bool Prepare() { return s_chargeMotionDiagnosticPatchReady; } [HarmonyPrefix] private static void Prefix(ChargeHandler __instance, out ChargeMotionSnapshot __state) { __state = default(ChargeMotionSnapshot); try { __state = BeginChargeMotionDiagnosticSample(__instance); } catch (Exception exception) { LogChargeMotionDiagnosticFailure("FixedUpdate prefix", exception); } } [HarmonyPostfix] private static void Postfix(ChargeHandler __instance, ChargeMotionSnapshot __state) { if (!__state.Enabled || (Object)(object)__instance == (Object)null) { return; } try { ChargeMotionSnapshot chargeMotionSnapshot = CaptureChargeMotionSnapshot(__instance, __state.HandlerId); LogChargeMotionSample(__state, chargeMotionSnapshot); CompleteChargeMotionDiagnosticSample(chargeMotionSnapshot); } catch (Exception exception) { LogChargeMotionDiagnosticFailure("FixedUpdate postfix", exception); } } } [HarmonyPatch(typeof(PhysGrabObject), "FixedUpdate")] private static class PhysGrabObjectMotionDiagnosticPatch { [HarmonyPrepare] private static bool Prepare() { return s_chargeMotionDiagnosticPatchReady; } [HarmonyPrefix] private static void Prefix(PhysGrabObject __instance, out PhysGrabMotionSnapshot __state) { __state = default(PhysGrabMotionSnapshot); try { __state = BeginPhysGrabMotionDiagnosticSample(__instance); } catch (Exception exception) { LogChargeMotionDiagnosticFailure("PhysGrabObject.FixedUpdate prefix", exception); } } [HarmonyPostfix] private static void Postfix(PhysGrabObject __instance, PhysGrabMotionSnapshot __state) { if (!__state.Enabled || (Object)(object)__instance == (Object)null) { return; } try { PhysGrabMotionSnapshot after = CapturePhysGrabMotionSnapshot(__instance, __state.ChargeHandler, __state.HandlerId, __state.SampleNumber); LogPhysGrabMotionSample(__state, after); } catch (Exception exception) { LogChargeMotionDiagnosticFailure("PhysGrabObject.FixedUpdate postfix", exception); } } } [HarmonyPatch(typeof(Rigidbody), "MovePosition")] private static class RigidbodyMovePositionDiagnosticPatch { [HarmonyPrepare] private static bool Prepare() { return s_chargeMotionDiagnosticPatchReady; } [HarmonyPrefix] private static void Prefix(Rigidbody __instance, [HarmonyArgument(0)] Vector3 requestedPosition) { //IL_0003: Unknown result type (might be due to invalid IL or missing references) try { LogChargeRigidbodyPositionCommand(__instance, requestedPosition, "Rigidbody.MovePosition"); } catch (Exception exception) { LogChargeMotionDiagnosticFailure("Rigidbody.MovePosition observer", exception); } } } [HarmonyPatch(typeof(Rigidbody), "set_position")] private static class RigidbodyPositionSetterDiagnosticPatch { [HarmonyPrepare] private static bool Prepare() { return s_chargeMotionDiagnosticPatchReady; } [HarmonyPrefix] private static void Prefix(Rigidbody __instance, [HarmonyArgument(0)] Vector3 requestedPosition) { //IL_0003: Unknown result type (might be due to invalid IL or missing references) try { LogChargeRigidbodyPositionCommand(__instance, requestedPosition, "Rigidbody.position"); } catch (Exception exception) { LogChargeMotionDiagnosticFailure("Rigidbody.position observer", exception); } } } [HarmonyPatch(typeof(Transform), "set_position")] private static class TransformPositionSetterDiagnosticPatch { [HarmonyPrepare] private static bool Prepare() { return s_chargeMotionDiagnosticPatchReady; } [HarmonyPrefix] private static void Prefix(Transform __instance, [HarmonyArgument(0)] Vector3 requestedPosition) { //IL_0003: Unknown result type (might be due to invalid IL or missing references) try { LogChargeTransformPositionCommand(__instance, requestedPosition); } catch (Exception exception) { LogChargeMotionDiagnosticFailure("Transform.position observer", exception); } } } [HarmonyPatch(typeof(ChargeHandler), "StartCharge")] private static class ChargeHandlerStartChargeDiagnosticPatch { [HarmonyPrepare] private static bool Prepare() { return s_chargeMotionDiagnosticPatchReady; } [HarmonyPrefix] private static void Prefix(ChargeHandler __instance, out ChargeMotionSnapshot __state) { __state = default(ChargeMotionSnapshot); try { __state = (FeatureFlags.DebugLogging ? CaptureChargeMotionSnapshot(__instance, GetUnityObjectInstanceId((Object?)(object)__instance)) : default(ChargeMotionSnapshot)); } catch (Exception exception) { LogChargeMotionDiagnosticFailure("StartCharge prefix", exception); } } [HarmonyPostfix] private static void Postfix(ChargeHandler __instance, ChargeMotionSnapshot __state) { if (!__state.Enabled || (Object)(object)__instance == (Object)null) { return; } try { ChargeMotionSnapshot after = CaptureChargeMotionSnapshot(__instance, __state.HandlerId); LogChargeMotionEvent("start-charge", __state, after); } catch (Exception exception) { LogChargeMotionDiagnosticFailure("StartCharge postfix", exception); } } } [HarmonyPatch(typeof(ChargeHandler), "EndCharge")] private static class ChargeHandlerEndChargeDiagnosticPatch { [HarmonyPrepare] private static bool Prepare() { return s_chargeMotionDiagnosticPatchReady; } [HarmonyPrefix] private static void Prefix(ChargeHandler __instance, out ChargeMotionSnapshot __state) { __state = default(ChargeMotionSnapshot); try { __state = (FeatureFlags.DebugLogging ? CaptureChargeMotionSnapshot(__instance, GetUnityObjectInstanceId((Object?)(object)__instance)) : default(ChargeMotionSnapshot)); } catch (Exception exception) { LogChargeMotionDiagnosticFailure("EndCharge prefix", exception); } } [HarmonyPostfix] private static void Postfix(ChargeHandler __instance, ChargeMotionSnapshot __state) { if (!__state.Enabled || (Object)(object)__instance == (Object)null) { return; } try { ChargeMotionSnapshot after = CaptureChargeMotionSnapshot(__instance, __state.HandlerId); LogChargeMotionEvent("end-charge", __state, after); RemoveChargeMotionDiagnosticTrace(__instance); } catch (Exception exception) { LogChargeMotionDiagnosticFailure("EndCharge postfix", exception); } } } private readonly struct DiminishingReturnsResult { public float BaseValue { get; } public float IncreasePerLevel { get; } public int AppliedLevel { get; } public int ThresholdLevel { get; } public float DiminishingFactor { get; } public int LinearLevels { get; } public int ExtraLevels { get; } public float LinearContribution { get; } public float DiminishingContribution { get; } public float DiminishingComponent { get; } public float FinalValue { get; } public DiminishingReturnsResult(float baseValue, float increasePerLevel, int appliedLevel, int thresholdLevel, float diminishingFactor, int linearLevels, int extraLevels, float linearContribution, float diminishingContribution, float diminishingComponent, float finalValue) { BaseValue = baseValue; IncreasePerLevel = increasePerLevel; AppliedLevel = appliedLevel; ThresholdLevel = thresholdLevel; DiminishingFactor = diminishingFactor; LinearLevels = linearLevels; ExtraLevels = extraLevels; LinearContribution = linearContribution; DiminishingContribution = diminishingContribution; DiminishingComponent = diminishingComponent; FinalValue = finalValue; } } private const string ChargeStrengthLogKey = "Fix:Charge.Strength"; private const string ChargePermissiveFallbackLogKey = "Fix:Charge.PermissiveFallback"; private const float RemoteReleaseCommandTag = -777f; private const float RemoteCancelCommandTag = -778f; private const float ChargeRestStopSeconds = 0.35f; private const float ChargeFailsafeSeconds = 10f; private const float ChargeRestVelocitySqrThreshold = 0.01f; private const float ChargeRestAngularVelocitySqrThreshold = 0.04f; private const float GroundContactProbeStartOffset = 0.02f; private const float GroundContactProbeDistance = 0.04f; private const float GroundContactMinimumNormalY = 0.5f; private const float ChargeMotionDiagnosticSampleInterval = 0.5f; private const int ChargeMotionDiagnosticMaxSamples = 24; private const float PositionCommandDiagnosticInterval = 0.15f; private const int PositionCommandDiagnosticMaxSamplesPerApi = 12; private static ManualLogSource? s_log; private static bool s_chargeGroundPatchReady; private static bool s_chargeMotionDiagnosticPatchReady; private static readonly Dictionary<int, ChargeHoldState> s_chargeHoldStates = new Dictionary<int, ChargeHoldState>(); private static readonly Dictionary<int, ChargeMotionDiagnosticTrace> s_chargeMotionDiagnosticTraces = new Dictionary<int, ChargeMotionDiagnosticTrace>(); private static readonly Dictionary<int, ChargeMotionDiagnosticTrace> s_chargeMotionDiagnosticPhysGrabTraces = new Dictionary<int, ChargeMotionDiagnosticTrace>(); private static readonly Dictionary<int, ChargeMotionDiagnosticTrace> s_chargeMotionDiagnosticRigidbodyTraces = new Dictionary<int, ChargeMotionDiagnosticTrace>(); private static readonly Dictionary<int, ChargeMotionDiagnosticTrace> s_chargeMotionDiagnosticTransformTraces = new Dictionary<int, ChargeMotionDiagnosticTrace>(); private static float s_lastLocalHoldInputStartTime; private static bool s_localHoldUiActive; private static bool s_localHoldInputPending; internal static void Apply(Harmony harmony, Assembly asm, ManualLogSource? log) { s_log = log; s_chargeGroundPatchReady = true; harmony.CreateClassProcessor(typeof(ChargeHandlerStartWindupPatch)).Patch(); if (FeatureFlags.DebugLogging) { s_chargeMotionDiagnosticPatchReady = true; harmony.CreateClassProcessor(typeof(ChargeHandlerMotionDiagnosticPatch)).Patch(); harmony.CreateClassProcessor(typeof(PhysGrabObjectMotionDiagnosticPatch)).Patch(); harmony.CreateClassProcessor(typeof(ChargeHandlerStartChargeDiagnosticPatch)).Patch(); harmony.CreateClassProcessor(typeof(ChargeHandlerEndChargeDiagnosticPatch)).Patch(); TryInstallChargePositionCommandDiagnosticPatch(harmony, typeof(RigidbodyMovePositionDiagnosticPatch), "Rigidbody.MovePosition"); TryInstallChargePositionCommandDiagnosticPatch(harmony, typeof(RigidbodyPositionSetterDiagnosticPatch), "Rigidbody.position setter"); TryInstallChargePositionCommandDiagnosticPatch(harmony, typeof(TransformPositionSetterDiagnosticPatch), "Transform.position setter"); } PatchChargeHandlerDamageModeIfPossible(harmony, asm); PatchChargeAbilityHoldReleaseIfPossible(harmony, asm); PatchStunHandlerHoldScalingIfPossible(harmony, asm); } private static void TryInstallChargePositionCommandDiagnosticPatch(Harmony harmony, Type patchType, string targetDescription) { try { harmony.CreateClassProcessor(patchType).Patch(); } catch (Exception ex) { ManualLogSource? obj = s_log; if (obj != null) { obj.LogWarning((object)("[Fix:ChargeMotion] Could not install the " + targetDescription + " observer; other charge diagnostics remain active. error=" + ex.GetType().Name + ": " + ex.Message)); } } } private static void ApplyGroundOffsetGuard(ChargeHandler chargeHandler) { //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_0062: 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_00b2: Unknown result type (might be due to invalid IL or missing references) //IL_00b7: 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_01a3: Unknown result type (might be due to invalid IL or missing references) Vector3 targetStartOffset = chargeHandler.targetStartOffset; bool flag = false; float num = 0f; bool? flag2 = null; try { DeathHeadController controller = chargeHandler.controller; Vector3? obj; if (controller == null) { obj = null; } else { CollisionHandler collisionHandler = controller.collisionHandler; obj = ((collisionHandler != null) ? collisionHandler.GetGroundPointDown() : ((Vector3?)null)); } Vector3? val = obj; flag = val.HasValue; if (val.HasValue) { num = Vector3.Distance(val.Value, ((Component)chargeHandler).transform.position); } flag2 = HasTightGroundContact(chargeHandler); if ((!flag || Mathf.Approximately(num, 0f)) && flag2 == false) { chargeHandler.targetStartOffset = Vector3.zero; } } catch (Exception ex) { if (FeatureFlags.DebugLogging && LogLimiter.ShouldLog("Fix:ChargeGround.ProbeFailure", 600)) { ManualLogSource? obj2 = s_log; if (obj2 != null) { obj2.LogWarning((object)("[Fix:ChargeGround] Ground probe failed; preserving vanilla offset. error=" + ex.GetType().Name + ": " + ex.Message)); } } } if (FeatureFlags.DebugLogging) { ManualLogSource? obj3 = s_log; if (obj3 != null) { obj3.LogInfo((object)($"[Fix:ChargeGround] start-windup groundPointAvailable={flag} " + string.Format("groundDistance={0:F3} groundContact={1} ", num, flag2?.ToString() ?? "unknown") + "vanillaOffset=" + FormatVector(targetStartOffset) + " finalOffset=" + FormatVector(chargeHandler.targetStartOffset))); } } } private static bool? HasTightGroundContact(ChargeHandler chargeHandler) { //IL_00e1: Unknown result type (might be due to invalid IL or missing references) //IL_00e6: Unknown result type (might be due to invalid IL or missing references) //IL_00ec: Unknown result type (might be due to invalid IL or missing references) //IL_00f8: Unknown result type (might be due to invalid IL or missing references) //IL_010a: Unknown result type (might be due to invalid IL or missing references) //IL_012e: Unknown result type (might be due to invalid IL or missing references) //IL_0130: 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_008d: Unknown result type (might be due to invalid IL or missing references) //IL_0091: Unknown result type (might be due to invalid IL or missing references) //IL_015d: Unknown result type (might be due to invalid IL or missing references) //IL_0162: Unknown result type (might be due to invalid IL or missing references) //IL_017a: Unknown result type (might be due to invalid IL or missing references) PlayerDeathHead val = chargeHandler.controller?.deathHead; if ((Object)(object)val == (Object)null) { return null; } Collider[] componentsInChildren = ((Component)val).GetComponentsInChildren<Collider>(true); Collider val2 = null; float num = float.PositiveInfinity; Collider[] array = componentsInChildren; foreach (Collider val3 in array) { if (!((Object)(object)val3 == (Object)null) && val3.enabled && ((Component)val3).gameObject.activeInHierarchy && !val3.isTrigger) { Bounds bounds = val3.bounds; float y = ((Bounds)(ref bounds)).min.y; if (!(y >= num)) { val2 = val3; num = y; } } } if ((Object)(object)val2 == (Object)null) { return null; } Bounds bounds2 = val2.bounds; Vector3 val4 = default(Vector3); ((Vector3)(ref val4))..ctor(((Bounds)(ref bounds2)).center.x, ((Bounds)(ref bounds2)).min.y + 0.02f, ((Bounds)(ref bounds2)).center.z); int mask = LayerMask.GetMask(new string[1] { "Default" }); RaycastHit[] array2 = Physics.RaycastAll(val4, Vector3.down, 0.04f, mask, (QueryTriggerInteraction)1); PhysGrabObject component = ((Component)val).GetComponent<PhysGrabObject>(); RaycastHit[] array3 = array2; for (int j = 0; j < array3.Length; j++) { RaycastHit val5 = array3[j]; Collider collider = ((RaycastHit)(ref val5)).collider; if (!((Object)(object)collider == (Object)null) && !(((RaycastHit)(ref val5)).normal.y < 0.5f) && !((Object)(object)((Component)collider).transform == (Object)(object)((Component)val).transform) && !((Component)collider).transform.IsChildOf(((Component)val).transform) && (!((Object)(object)component != (Object)null) || !((Object)(object)((Component)collider).GetComponentInParent<PhysGrabObject>() == (Object)(object)component))) { return true; } } return false; } private static string FormatVector(Vector3 value) { //IL_0006: 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_001c: Unknown result type (might be due to invalid IL or missing references) return $"({value.x:F3},{value.y:F3},{value.z:F3})"; } private static void BeginChargeMotionDiagnosticTrace(ChargeHandler chargeHandler) { int unityObjectInstanceId = GetUnityObjectInstanceId((Object?)(object)chargeHandler); if (FeatureFlags.DebugLogging && unityObjectInstanceId != 0) { if (!s_chargeMotionDiagnosticTraces.TryGetValue(unityObjectInstanceId, out ChargeMotionDiagnosticTrace value)) { value = new ChargeMotionDiagnosticTrace(); s_chargeMotionDiagnosticTraces[unityObjectInstanceId] = value; } value.ChargeHandler = chargeHandler; RegisterPhysGrabMotionDiagnosticTarget(value, unityObjectInstanceId); } } private static void RemoveChargeMotionDiagnosticTrace(ChargeHandler? chargeHandler) { if ((Object)(object)chargeHandler == (Object)null) { return; } int unityObjectInstanceId = GetUnityObjectInstanceId((Object?)(object)chargeHandler); if (unityObjectInstanceId != 0) { if (s_chargeMotionDiagnosticTraces.TryGetValue(unityObjectInstanceId, out ChargeMotionDiagnosticTrace value) && (Object)(object)value.PhysGrabObject != (Object)null) { int unityObjectInstanceId2 = GetUnityObjectInstanceId((Object?)(object)value.PhysGrabObject); RemoveDiagnosticTraceMapping(s_chargeMotionDiagnosticPhysGrabTraces, unityObjectInstanceId2, value); RemoveDiagnosticTraceMapping(s_chargeMotionDiagnosticRigidbodyTraces, GetUnityObjectInstanceId((Object?)(object)value.PhysGrabObject.rb), value); RemoveDiagnosticTraceMapping(s_chargeMotionDiagnosticTransformTraces, GetUnityObjectInstanceId((Object?)(object)((Component)value.PhysGrabObject).transform), value); } s_chargeMotionDiagnosticTraces.Remove(unityObjectInstanceId); } } private static void RemoveDiagnosticTraceMapping(Dictionary<int, ChargeMotionDiagnosticTrace> mappings, int instanceId, ChargeMotionDiagnosticTrace trace) { if (instanceId != 0 && mappings.TryGetValue(instanceId, out ChargeMotionDiagnosticTrace value) && trace == value) { mappings.Remove(instanceId); } } private static void RegisterPhysGrabMotionDiagnosticTarget(ChargeMotionDiagnosticTrace trace, int handlerId) { ChargeHandler chargeHandler = trace.ChargeHandler; if ((Object)(object)chargeHandler == (Object)null || handlerId == 0) { return; } PhysGrabObject val = (((Object)(object)chargeHandler.impactDetector != (Object)null) ? chargeHandler.impactDetector.physGrabObject : null); if (!((Object)(object)val == (Object)null)) { trace.PhysGrabObject = val; int unityObjectInstanceId = GetUnityObjectInstanceId((Object?)(object)val); if (unityObjectInstanceId != 0) { s_chargeMotionDiagnosticPhysGrabTraces[unityObjectInstanceId] = trace; } int unityObjectInstanceId2 = GetUnityObjectInstanceId((Object?)(object)val.rb); if (unityObjectInstanceId2 != 0) { s_chargeMotionDiagnosticRigidbodyTraces[unityObjectInstanceId2] = trace; } int unityObjectInstanceId3 = GetUnityObjectInstanceId((Object?)(object)((Component)val).transform); if (unityObjectInstanceId3 != 0) { s_chargeMotionDiagnosticTransformTraces[unityObjectInstanceId3] = trace; } } } private static ChargeMotionSnapshot BeginChargeMotionDiagnosticSample(ChargeHandler? chargeHandler) { //IL_0034: Unknown result type (might be due to invalid IL or missing references) //IL_003a: Invalid comparison between Unknown and I4 //IL_0176: Unknown result type (might be due to invalid IL or missing references) //IL_017c: Unknown result type (might be due to invalid IL or missing references) //IL_0181: Unknown result type (might be due to invalid IL or missing references) //IL_0186: Unknown result type (might be due to invalid IL or missing references) //IL_018e: 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_0199: Unknown result type (might be due to invalid IL or missing references) //IL_019e: Unknown result type (might be due to invalid IL or missing references) if (!FeatureFlags.DebugLogging || (Object)(object)chargeHandler == (Object)null) { return default(ChargeMotionSnapshot); } int unityObjectInstanceId = GetUnityObjectInstanceId((Object?)(object)chargeHandler); if (unityObjectInstanceId == 0 || (int)chargeHandler.State == 0) { return default(ChargeMotionSnapshot); } if (!s_chargeMotionDiagnosticTraces.TryGetValue(unityObjectInstanceId, out ChargeMotionDiagnosticTrace value)) { value = new ChargeMotionDiagnosticTrace(); value.ChargeHandler = chargeHandler; s_chargeMotionDiagnosticTraces[unityObjectInstanceId] = value; RegisterPhysGrabMotionDiagnosticTarget(value, unityObjectInstanceId); } float time = Time.time; if (value.SampleCount >= 24) { if (!value.SampleLimitLogged) { value.SampleLimitLogged = true; ManualLogSource? obj = s_log; if (obj != null) { obj.LogDebug((object)($"[Fix:ChargeMotion] sampling-limit reached handler={unityObjectInstanceId} " + $"samples={value.SampleCount} interval={0.5f:F1}s")); } } return default(ChargeMotionSnapshot); } if (time - value.LastSampleTime < 0.5f) { return default(ChargeMotionSnapshot); } value.LastSampleTime = time; value.SampleCount++; ChargeMotionSnapshot result = CaptureChargeMotionSnapshot(chargeHandler, unityObjectInstanceId); result.SampleNumber = value.SampleCount; if (value.HasPreviousSamplePosition) { result.HeadDeltaSincePreviousSample = result.HeadPosition - value.PreviousHeadSamplePosition; result.TumbleDeltaSincePreviousSample = result.TumblePosition - value.PreviousTumbleSamplePosition; } return result; } private static void CompleteChargeMotionDiagnosticSample(ChargeMotionSnapshot snapshot) { //IL_0029: Unknown result type (might be due to invalid IL or missing references) //IL_002e: 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_003a: Unknown result type (might be due to invalid IL or missing references) if (snapshot.Enabled && s_chargeMotionDiagnosticTraces.TryGetValue(snapshot.HandlerId, out ChargeMotionDiagnosticTrace value)) { value.PreviousHeadSamplePosition = snapshot.HeadPosition; value.PreviousTumbleSamplePosition = snapshot.TumblePosition; value.HasPreviousSamplePosition = true; } } private static PhysGrabMotionSnapshot BeginPhysGrabMotionDiagnosticSample(PhysGrabObject? physGrabObject) { //IL_0054: Unknown result type (might be due to invalid IL or missing references) //IL_005a: Invalid comparison between Unknown and I4 if (!FeatureFlags.DebugLogging || (Object)(object)physGrabObject == (Object)null) { return default(PhysGrabMotionSnapshot); } int unityObjectInstanceId = GetUnityObjectInstanceId((Object?)(object)physGrabObject); if (unityObjectInstanceId == 0 || !s_chargeMotionDiagnosticPhysGrabTraces.TryGetValue(unityObjectInstanceId, out ChargeMotionDiagnosticTrace value) || (Object)(object)value.ChargeHandler == (Object)null || (int)value.ChargeHandler.State == 0) { return default(PhysGrabMotionSnapshot); } float time = Time.time; if (value.PhysGrabSampleCount >= 24) { if (!value.PhysGrabSampleLimitLogged) { value.PhysGrabSampleLimitLogged = true; ManualLogSource? obj = s_log; if (obj != null) { obj.LogDebug((object)($"[Fix:ChargeMotion] PhysGrabObject sampling-limit reached handler={GetUnityObjectInstanceId((Object?)(object)value.ChargeHandler)} " + $"samples={value.PhysGrabSampleCount} interval={0.5f:F1}s")); } } return default(PhysGrabMotionSnapshot); } if (time - value.LastPhysGrabSampleTime < 0.5f) { return default(PhysGrabMotionSnapshot); } value.LastPhysGrabSampleTime = time; value.PhysGrabSampleCount++; return CapturePhysGrabMotionSnapshot(physGrabObject, value.ChargeHandler, GetUnityObjectInstanceId((Object?)(object)value.ChargeHandler), value.PhysGrabSampleCount); } private static PhysGrabMotionSnapshot CapturePhysGrabMotionSnapshot(PhysGrabObject? physGrabObject, ChargeHandler? chargeHandler, int handlerId, int sampleNumber) { //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) //IL_009b: Unknown result type (might be due to invalid IL or missing references) //IL_00a0: 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) //IL_00b2: Unknown result type (might be due to invalid IL or missing references) //IL_00bf: Unknown result type (might be due to invalid IL or missing references) //IL_00c4: Unknown result type (might be due to invalid IL or missing references) //IL_00f8: 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_0105: Unknown result type (might be due to invalid IL or missing references) //IL_010a: Unknown result type (might be due to invalid IL or missing references) if (!FeatureFlags.DebugLogging || (Object)(object)physGrabObject == (Object)null || (Object)(object)chargeHandler == (Object)null || handlerId == 0 || (Object)(object)physGrabObject.rb == (Object)null) { return default(PhysGrabMotionSnapshot); } return new PhysGrabMotionSnapshot { Enabled = true, ChargeHandler = chargeHandler, HandlerId = handlerId, SampleNumber = sampleNumber, ChargeState = chargeHandler.State, PhysGrabObjectId = GetUnityObjectInstanceId((Object?)(object)physGrabObject), RigidbodyId = GetUnityObjectInstanceId((Object?)(object)physGrabObject.rb), TransformPosition = ((Component)physGrabObject).transform.position, RigidbodyPosition = physGrabObject.rb.position, LinearVelocity = physGrabObject.rb.linearVelocity, IsKinematic = physGrabObject.rb.isKinematic, Frozen = physGrabObject.frozen, FrozenTimer = physGrabObject.frozenTimer, FrozenPosition = physGrabObject.frozenPosition, FrozenVelocity = physGrabObject.frozenVelocity, Grabbed = physGrabObject.grabbed, PlayerGrabberCount = ((physGrabObject.playerGrabbing != null) ? physGrabObject.playerGrabbing.Count : 0) }; } private static void LogPhysGrabMotionSample(PhysGrabMotionSnapshot before, PhysGrabMotionSnapshot after) { //IL_0066: Unknown result type (might be due to invalid IL or missing references) //IL_0074: Unknown result type (might be due to invalid IL or missing references) //IL_00ac: Unknown result type (might be due to invalid IL or missing references) //IL_00c2: Unknown result type (might be due to invalid IL or missing references) //IL_00d8: Unknown result type (might be due to invalid IL or missing references) //IL_00ef: Unknown result type (might be due to invalid IL or missing references) //IL_0107: 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) //IL_012a: Unknown result type (might be due to invalid IL or missing references) //IL_0130: Unknown result type (might be due to invalid IL or missing references) //IL_0135: Unknown result type (might be due to invalid IL or missing references) //IL_014d: Unknown result type (might be due to invalid IL or missing references) //IL_0165: Unknown result type (might be due to invalid IL or missing references) //IL_01f6: Unknown result type (might be due to invalid IL or missing references) //IL_020e: Unknown result type (might be due to invalid IL or missing references) //IL_0226: Unknown result type (might be due to invalid IL or missing references) //IL_023e: Unknown result type (might be due to invalid IL or missing references) if (before.Enabled && after.Enabled) { ManualLogSource? obj = s_log; if (obj != null) { obj.LogDebug((object)($"[Fix:ChargeMotion] physgrab-sample={before.SampleNumber} handler={before.HandlerId} " + $"state={before.ChargeState}->{after.ChargeState} physGrab={before.PhysGrabObjectId} rb={before.RigidbodyId} " + "transformPos=" + FormatVector(before.TransformPosition) + "->" + FormatVector(after.TransformPosition) + " rbPos=" + FormatVector(before.RigidbodyPosition) + "->" + FormatVector(after.RigidbodyPosition) + " fixedTransformDelta=" + FormatVector(after.TransformPosition - before.TransformPosition) + " fixedRbDelta=" + FormatVector(after.RigidbodyPosition - before.RigidbodyPosition) + " velocity=" + FormatVector(before.LinearVelocity) + "->" + FormatVector(after.LinearVelocity) + " " + $"kinematic={before.IsKinematic}->{after.IsKinematic} frozen={before.Frozen}->{after.Frozen} " + $"frozenTimer={before.FrozenTimer:F2}->{after.FrozenTimer:F2} " + "frozenPosition=" + FormatVector(before.FrozenPosition) + "->" + FormatVector(after.FrozenPosition) + " frozenVelocity=" + FormatVector(before.FrozenVelocity) + "->" + FormatVector(after.FrozenVelocity) + " " + $"grabbed={before.Grabbed}->{after.Grabbed} playerGrabbers={before.PlayerGrabberCount}->{after.PlayerGrabberCount}")); } } } private static void LogChargeRigidbodyPositionCommand(Rigidbody? rigidbody, Vector3 requestedPosition, string api) { //IL_005d: Unknown result type (might be due to invalid IL or missing references) //IL_0062: 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) //IL_0064: 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) //IL_006a: 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_004e: Invalid comparison between Unknown and I4 //IL_0093: Unknown result type (might be due to invalid IL or missing references) //IL_0094: Unknown result type (might be due to invalid IL or missing references) if (!FeatureFlags.DebugLogging || (Object)(object)rigidbody == (Object)null) { return; } int unityObjectInstanceId = GetUnityObjectInstanceId((Object?)(object)rigidbody); if (unityObjectInstanceId != 0 && s_chargeMotionDiagnosticRigidbodyTraces.TryGetValue(unityObjectInstanceId, out ChargeMotionDiagnosticTrace value) && !((Object)(object)value.ChargeHandler == (Object)null) && (int)value.ChargeHandler.State != 0) { Vector3 position = rigidbody.position; Vector3 val = requestedPosition - position; if (!(((Vector3)(ref val)).sqrMagnitude < 0.0001f) && TryAcquirePositionCommandLog(value, api)) { LogChargePositionCommand(value, api, unityObjectInstanceId, position, requestedPosition, rigidbody); } } } private static void LogChargeTransformPositionCommand(Transform? transform, Vector3 requestedPosition) { //IL_005f: Unknown result type (might be due to invalid IL or missing references) //IL_0064: 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) //IL_0066: Unknown result type (might be due to invalid IL or missing references) //IL_0067: Unknown result type (might be due to invalid IL or missing references) //IL_006c: Unknown result type (might be due to invalid IL or missing references) //IL_004a: Unknown result type (might be due to invalid IL or missing references) //IL_0050: Invalid comparison between Unknown and I4 //IL_00cb: Unknown result type (might be due to invalid IL or missing references) //IL_00cc: Unknown result type (might be due to invalid IL or missing references) if (!FeatureFlags.DebugLogging || (Object)(object)transform == (Object)null) { return; } int unityObjectInstanceId = GetUnityObjectInstanceId((Object?)(object)transform); if (unityObjectInstanceId != 0 && s_chargeMotionDiagnosticTransformTraces.TryGetValue(unityObjectInstanceId, out ChargeMotionDiagnosticTrace value) && !((Object)(object)value.ChargeHandler == (Object)null) && (int)value.ChargeHandler.State != 0) { Vector3 position = transform.position; Vector3 val = requestedPosition - position; if (!(((Vector3)(ref val)).sqrMagnitude < 0.0001f) && TryAcquirePositionCommandLog(value, "Transform.position")) { PhysGrabObject physGrabObject = value.PhysGrabObject; Rigidbody val2 = (((Object)(object)physGrabObject != (Object)null) ? physGrabObject.rb : null); LogChargePositionCommand(value, "Transform.position", ((Object)(object)val2 != (Object)null) ? GetUnityObjectInstanceId((Object?)(object)val2) : 0, position, requestedPosition, val2); } } } private static bool TryAcquirePositionCommandLog(ChargeMotionDiagnosticTrace trace, string api) { float time = Time.time; if (api == "Rigidbody.MovePosition") { if (trace.MovePositionLogCount >= 12) { if (!trace.MovePositionLimitLogged) { trace.MovePositionLimitLogged = true; ManualLogSource? obj = s_log; if (obj != null) { obj.LogDebug((object)("[Fix:ChargeMotion] position-command sampling-limit reached api=" + api + " " + $"handler={GetUnityObjectInstanceId((Object?)(object)trace.ChargeHandler)}")); } } return false; } if (time - trace.LastMovePositionLogTime < 0.15f) { return false; } trace.LastMovePositionLogTime = time; trace.MovePositionLogCount++; return true; } if (api == "Rigidbody.position") { if (trace.RigidbodyPositionLogCount >= 12) { if (!trace.RigidbodyPositionLimitLogged) { trace.RigidbodyPositionLimitLogged = true; ManualLogSource? obj2 = s_log; if (obj2 != null) { obj2.LogDebug((object)("[Fix:ChargeMotion] position-command sampling-limit reached api=" + api + " " + $"handler={GetUnityObjectInstanceId((Object?)(object)trace.ChargeHandler)}")); } } return false; } if (time - trace.LastRigidbodyPositionLogTime < 0.15f) { return false; } trace.LastRigidbodyPositionLogTime = time; trace.RigidbodyPositionLogCount++; return true; } if (trace.TransformPositionLogCount >= 12) { if (!trace.TransformPositionLimitLogged) { trace.TransformPositionLimitLogged = true; ManualLogSource? obj3 = s_log; if (obj3 != null) { obj3.LogDebug((object)("[Fix:ChargeMotion] position-command sampling-limit reached api=" + api + " " + $"handler={GetUnityObjectInstanceId((Object?)(object)trace.ChargeHandler)}")); } } return false; } if (time - trace.LastTransformPositionLogTime < 0.15f) { return false; } trace.LastTransformPositionLogTime = time; trace.TransformPositionLogCount++; return true; } private static void LogChargePositionCommand(ChargeMotionDiagnosticTrace trace, string api, int rigidbodyId, Vector3 currentPosition, Vector3 requestedPosition, Rigidbody? rigidbody) { //IL_0055: 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_00a0: Unknown result type (might be due to invalid IL or missing references) //IL_00b1: Unknown result type (might be due to invalid IL or missing references) //IL_00b3: Unknown result type (might be due to invalid IL or missing references) //IL_00b4: 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_00d3: Unknown result type (might be due to invalid IL or missing references) ChargeHandler chargeHandler = trace.ChargeHandler; if (!((Object)(object)chargeHandler == (Object)null)) { PhysGrabObject physGrabObject = trace.PhysGrabObject; ManualLogSource? obj = s_log; if (obj != null) { obj.LogDebug((object)($"[Fix:ChargeMotion] position-command api={api} handler={GetUnityObjectInstanceId((Object?)(object)chargeHandler)} " + $"state={chargeHandler.State} physGrab={(((Object)(object)physGrabObject != (Object)null) ? GetUnityObjectInstanceId((Object?)(object)physGrabObject) : 0)} " + $"rb={rigidbodyId} requested={FormatVector(requestedPosition)} " + "current=" + FormatVector(currentPosition) + " delta=" + FormatVector(requestedPosition - currentPosition) + " velocity=" + FormatVector(((Object)(object)rigidbody != (Object)null) ? rigidbody.linearVelocity : Vector3.zero) + " " + $"kinematic={(Object)(object)rigidbody != (Object)null && rigidbody.isKinematic} " + $"frozen={(Object)(object)physGrabObject != (Object)null && physGrabObject.frozen} " + $"grabbed={(Object)(object)physGrabObject != (Object)null && physGrabObject.grabbed}")); } } } private static ChargeMotionSnapshot CaptureChargeMotionSnapshot(ChargeHandler? chargeHandler, int handlerId) { //IL_00a6: Unknown result type (might be due to invalid IL or missing references) //IL_00ab: Unknown result type (might be due to invalid IL or missing references) //IL_00d6: Unknown result type (might be due to invalid IL or missing references) //IL_00ce: Unknown result type (might be due to invalid IL or missing references) //IL_00db: Unknown result type (might be due to invalid IL or missing references) //IL_00f3: Unknown result type (might be due to invalid IL or missing references) //IL_00eb: Unknown result type (might be due to invalid IL or missing references) //IL_00f8: Unknown result type (might be due to invalid IL or missing references) //IL_0119: Unknown result type (might be due to invalid IL or missing references) //IL_011e: Unknown result type (might be due to invalid IL or missing references) //IL_0126: Unknown result type (might be due to invalid IL or missing references) //IL_012b: Unknown result type (might be due to invalid IL or missing references) //IL_0133: Unknown result type (might be due to invalid IL or missing references) //IL_0138: Unknown result type (might be due to invalid IL or missing references) //IL_0140: Unknown result type (might be due to invalid IL or missing references) //IL_0145: Unknown result type (might be due to invalid IL or missing references) //IL_0238: 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_023d: Unknown result type (might be due to invalid IL or missing references) //IL_0255: Unknown result type (might be due to invalid IL or missing references) //IL_024d: Unknown result type (might be due to invalid IL or missing references) //IL_025a: Unknown result type (might be due to invalid IL or missing references) if (!FeatureFlags.DebugLogging || (Object)(object)chargeHandler == (Object)null || handlerId == 0) { return default(ChargeMotionSnapshot); } Rigidbody rb = chargeHandler.rb; DeathHeadController controller = chargeHandler.controller; Rigidbody val = controller?.deathHead?.playerAvatar?.tumble?.rb; PhysGrabObject val2 = (((Object)(object)chargeHandler.impactDetector != (Object)null) ? chargeHandler.impactDetector.physGrabObject : null); return new ChargeMotionSnapshot { Enabled = true, HandlerId = handlerId, State = chargeHandler.State, HeadRigidbodyId = GetUnityObjectInstanceId((Object?)(object)rb), HeadPosition = (((Object)(object)rb != (Object)null) ? rb.position : ((Component)chargeHandler).transform.position), HeadVelocity = (((Object)(object)rb != (Object)null) ? rb.linearVelocity : Vector3.zero), HeadIsKinematic = ((Object)(object)rb != (Object)null && rb.isKinematic), TargetStartOffset = chargeHandler.targetStartOffset, CurrentStartOffset = chargeHandler.currentStartOffset, StartVelocity = chargeHandler.startVelocity, ChargeDirection = chargeHandler.chargeDirection, ChargeStrength = chargeHandler.chargeStrength, WindupTimer = chargeHandler.windupTimer, ChargeTimer = chargeHandler.chargeTimer, BounceCount = ((chargeHandler.bounceColliders != null) ? chargeHandler.bounceColliders.Count : 0), EnemiesHit = chargeHandler.enemiesHit, IsColliding = (controller?.collisionHandler?.isColliding == true), IsGrabbed = ((Object)(object)val2 != (Object)null && val2.grabbed), IsFrozen = ((Object)(object)val2 != (Object)null && val2.frozen), TumbleRigidbodyId = (((Object)(object)val != (Object)null) ? GetUnityObjectInstanceId((Object?)(object)val) : 0), TumblePosition = (((Object)(object)val != (Object)null) ? val.position : Vector3.zero), TumbleVelocity = (((Object)(object)val != (Object)null) ? val.linearVelocity : Vector3.zero), TumbleIsKinematic = ((Object)(object)val != (Object)null && val.isKinematic) }; } private static void LogChargeMotionSample(ChargeMotionSnapshot before, ChargeMotionSnapshot after) { //IL_0074: Unknown result type (might be due to invalid IL or missing references) //IL_007f: Unknown result type (might be due to invalid IL or missing references) //IL_00a2: 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) //IL_00c8: Unknown result type (might be due to invalid IL or missing references) //IL_00ce: Unknown result type (might be due to invalid IL or missing references) //IL_00d3: 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_00ff: 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_015c: Unknown result type (might be due to invalid IL or missing references) //IL_0174: Unknown result type (might be due to invalid IL or missing references) //IL_018c: Unknown result type (might be due to invalid IL or missing references) //IL_01a4: 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_01d4: Unknown result type (might be due to invalid IL or missing references) //IL_01ec: Unknown result type (might be due to invalid IL or missing references) //IL_0204: Unknown result type (might be due to invalid IL or missing references) //IL_0371: Unknown result type (might be due to invalid IL or missing references) //IL_0389: Unknown result type (might be due to invalid IL or missing references) //IL_03a1: Unknown result type (might be due to invalid IL or missing references) //IL_03b9: Unknown result type (might be due to invalid IL or missing references) //IL_03d1: Unknown result type (might be due to invalid IL or missing references) if (before.Enabled && after.Enabled) { ChargeHoldState value; bool flag = s_chargeHoldStates.TryGetValue(before.HandlerId, out value) && value.IsHolding; string text = $"[Fix:ChargeMotion] sample={before.SampleNumber} handler={before.HandlerId} " + $"held={flag} state={before.State}->{after.State} " + $"headRB={before.HeadRigidbodyId} pos={FormatVector(before.HeadPosition)}->{FormatVector(after.HeadPosition)} " + "fixedDelta=" + FormatVector(after.HeadPosition - before.HeadPosition) + " sinceSampleDelta=" + FormatVector(before.HeadDeltaSincePreviousSample) + " vel=" + FormatVector(before.HeadVelocity) + "->" + FormatVector(after.HeadVelocity) + " " + $"kinematic={before.HeadIsKinematic}->{after.HeadIsKinematic} " + "targetOffset=" + FormatVector(before.TargetStartOffset) + "->" + FormatVector(after.TargetStartOffset) + " currentOffset=" + FormatVector(before.CurrentStartOffset) + "->" + FormatVector(after.CurrentStartOffset) + " startVelocity=" + FormatVector(before.StartVelocity) + "->" + FormatVector(after.StartVelocity) + " chargeDirection=" + FormatVector(before.ChargeDirection) + "->" + FormatVector(after.ChargeDirection) + " " + $"strength={before.ChargeStrength:F2}->{after.ChargeStrength:F2} " + $"windupTimer={before.WindupTimer:F2}->{after.WindupTimer:F2} " + $"chargeTimer={before.ChargeTimer:F2}->{after.ChargeTimer:F2} " + $"bounces={before.BounceCount}->{after.BounceCount} enemiesHit={before.EnemiesHit}->{after.EnemiesHit} " + $"colliding={before.IsColliding}->{after.IsColliding} grabbed={before.IsGrabbed}->{after.IsGrabbed} " + $"frozen={before.IsFrozen}->{after.IsFrozen} " + $"tumbleRB={before.TumbleRigidbodyId}->{after.TumbleRigidbodyId} " + "tumblePos=" + FormatVector(before.TumblePosition) + "->" + FormatVector(after.TumblePosition) + " tumbleSinceSampleDelta=" + FormatVector(before.TumbleDeltaSincePreviousSample) + " tumbleVel=" + FormatVector(before.TumbleVelocity) + "->" + FormatVector(after.TumbleVelocity) + " " + $"tumbleKinematic={before.TumbleIsKinematic}->{after.TumbleIsKinematic}"; ManualLogSource? obj = s_log; if (obj != null) { obj.LogDebug((object)text); } } } private static void LogChargeMotionEvent(string eventName, ChargeHandler? chargeHandler) { if (!FeatureFlags.DebugLogging) { return; } try { int num = (((Object)(object)chargeHandler != (Object)null) ? GetUnityObjectInstanceId((Object?)(object)chargeHandler) : 0); ChargeMotionSnapshot chargeMotionSnapshot = CaptureChargeMotionSnapshot(chargeHandler, num); if (!chargeMotionSnapshot.Enabled) { ManualLogSource? obj = s_log; if (obj != null) { obj.LogDebug((object)("[Fix:ChargeMotion] event=" + eventName + " handler=unavailable")); } } else { ChargeHoldState value; bool isHolding = s_chargeHoldStates.TryGetValue(num, out value) && value.IsHolding; LogChargeMotionEvent(eventName, chargeMotionSnapshot, chargeMotionSnapshot, isHolding); } } catch (Exception exception) { LogChargeMotionDiagnosticFailure("event " + eventName, exception); } } private static void LogChargeMotionEvent(string eventName, ChargeMotionSnapshot before, ChargeMotionSnapshot after) { ChargeHoldState value; bool isHolding = s_chargeHoldStates.TryGetValue(before.HandlerId, out value) && value.IsHolding; LogChargeMotionEvent(eventName, before, after, isHolding); } private static void LogChargeMotionEvent(string eventName, ChargeMotionSnapshot before, ChargeMotionSnapshot after, bool isHolding) { //IL_0061: Unknown result type (might be due to invalid IL or missing references) //IL_006c: Unknown result type (might be due to invalid IL or missing references) //IL_0092: Unknown result type (might be due to invalid IL or missing references) //IL_00a8: Unknown result type (might be due to invalid IL or missing references) //IL_00be: Unknown result type (might be due to invalid IL or missing references) //IL_00d5: Unknown result type (might be due to invalid IL or missing references) //IL_011a: Unknown result type (might be due to invalid IL or missing references) //IL_0132: Unknown result type (might be due to invalid IL or missing references) //IL_014a: Unknown result type (might be due to invalid IL or missing references) //IL_0162: Unknown result type (might be due to invalid IL or missing references) //IL_017a: Unknown result type (might be due to invalid IL or missing references) //IL_0192: Unknown result type (might be due to invalid IL or missing references) //IL_01aa: Unknown result type (might be due to invalid IL or missing references) //IL_01c2: Unknown result type (might be due to invalid IL or missing references) //IL_0333: Unknown result type (might be due to invalid IL or missing references) //IL_034b: Unknown result type (might be due to invalid IL or missing references) //IL_0363: Unknown result type (might be due to invalid IL or missing references) //IL_037b: Unknown result type (might be due to invalid IL or missing references) if (FeatureFlags.DebugLogging && before.Enabled && after.Enabled) { ManualLogSource? obj = s_log; if (obj != null) { obj.LogDebug((object)($"[Fix:ChargeMotion] event={eventName} handler={before.HandlerId} held={isHolding} " + $"state={before.State}->{after.State} headRB={before.HeadRigidbodyId} " + "pos=" + FormatVector(before.HeadPosition) + "->" + FormatVector(after.HeadPosition) + " vel=" + FormatVector(before.HeadVelocity) + "->" + FormatVector(after.HeadVelocity) + " " + $"kinematic={before.HeadIsKinematic}->{after.HeadIsKinematic} " + "targetOffset=" + FormatVector(before.TargetStartOffset) + "->" + FormatVector(after.TargetStartOffset) + " currentOffset=" + FormatVector(before.CurrentStartOffset) + "->" + FormatVector(after.CurrentStartOffset) + " startVelocity=" + FormatVector(before.StartVelocity) + "->" + FormatVector(after.StartVelocity) + " chargeDirection=" + FormatVector(before.ChargeDirection) + "->" + FormatVector(after.ChargeDirection) + " " + $"strength={before.ChargeStrength:F2}->{after.ChargeStrength:F2} " + $"windupTimer={before.WindupTimer:F2}->{after.WindupTimer:F2} " + $"chargeTimer={before.ChargeTimer:F2}->{after.ChargeTimer:F2} " + $"bounces={before.BounceCount}->{after.BounceCount} enemiesHit={before.EnemiesHit}->{after.EnemiesHit} " + $"colliding={before.IsColliding}->{after.IsColliding} grabbed={before.IsGrabbed}->{after.IsGrabbed} " + $"frozen={before.IsFrozen}->{after.IsFrozen} tumbleRB={before.TumbleRigidbodyId}->{after.TumbleRigidbodyId} " + "tumblePos=" + FormatVector(before.TumblePosition) + "->" + FormatVector(after.TumblePosition) + " tumbleVel=" + FormatVector(before.TumbleVelocity) + "->" + FormatVector(after.TumbleVelocity) + " " + $"tumbleKinematic={before.TumbleIsKinematic}->{after.TumbleIsKinematic}")); } } } private static void LogChargeMotionDiagnosticFailure(string phase, Exception exception) { if (FeatureFlags.DebugLogging && LogLimiter.ShouldLog("Fix:ChargeMotion.DiagnosticFailure", 120)) { ManualLogSource? obj = s_log; if (obj != null) { obj.LogWarning((object)("[Fix:ChargeMotion] Diagnostic failed during " + phase + "; gameplay continues. error=" + exception.GetType().Name + ": " + exception.Message)); } } } private static void PatchChargeHandlerDamageModeIfPossible(Harmony harmony, Assembly asm) { //IL_005d: Unknown result type (might be due to invalid IL or missing references) //IL_006b: Expected O, but got Unknown //IL_00a0: Unknown result type (might be due to invalid IL or missing references) //IL_00ad: Expected O, but got Unknown //IL_01aa: Unknown result type (might be due to invalid IL or missing references) //IL_01b7: Expected O, but got Unknown //IL_020d: Unknown result type (might be due to invalid IL or missing references) //IL_021a: Expected O, but got Unknown //IL_0254: Unknown result type (might be due to invalid IL or missing references) //IL_0261: Expected O, but got Unknown //IL_029b: Unknown result type (might be due to invalid IL or missing references) //IL_02a8: Expected O, but got Unknown //IL_02e1: Unknown result type (might be due to invalid IL or missing references) //IL_02ef: Expected O, but got Unknown //IL_0328: Unknown result type (might be due to invalid IL or missing references) //IL_0336: Expected O, but got Unknown //IL_0371: Unknown result type (might be due to invalid IL or missing references) //IL_037f: Expected O, but got Unknown //IL_0394: Unknown result type (might be due to invalid IL or missing references) //IL_03a1: Expected O, but got Unknown MethodInfo methodInfo = AccessTools.Method(typeof(ChargeHandler), "ChargeWindup", new Type[1] { typeof(Vector3) }, (Type[])null); MethodInfo method = typeof(ChargeHoldReleaseModule).GetMethod("ChargeHandler_ChargeWindup_Prefix", BindingFlags.Static | BindingFlags.NonPublic); if (methodInfo != null && method != null) { harmony.Patch((MethodBase)methodInfo, new HarmonyMethod(method), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null); } MethodInfo method2 = typeof(ChargeHoldReleaseModule).GetMethod("ChargeHandler_ChargeWindup_Postfix", BindingFlags.Static | BindingFlags.NonPublic); if (methodInfo != null && method2 != null) { harmony.Patch((MethodBase)methodInfo, (HarmonyMethod)null, new HarmonyMethod(method2), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null); } MethodInfo methodInfo2 = AccessTools.Method(typeof(ChargeHandler), "ResetState", Type.EmptyTypes, (Type[])null); MethodInfo methodInfo3 = AccessTools.Method(typeof(ChargeHandler), "FixedUpdate", Type.EmptyTypes, (Type[])null); MethodInfo methodInfo4 = AccessTools.Method(typeof(ChargeHandler), "CancelCharge", Type.EmptyTypes, (Type[])null); MethodInfo methodInfo5 = AccessTools.Method(typeof(ChargeHandler), "EnemyHit", (Type[])null, (Type[])null); MethodInfo methodInfo6 = AccessTools.Method(typeof(ChargeHandler), "UpdateWindupDirection", new Type[1] { typeof(Vector3) }, (Type[])null); MethodInfo methodInfo7 = AccessTools.Method(typeof(ChargeHandler), "SyncChargeStateRPC", (Type[])null, (Type[])null); MethodInfo method3 = typeof(ChargeHoldReleaseModule).GetMethod("ChargeHandler_SyncChargeStateRPC_Prefix", BindingFlags.Static | BindingFlags.NonPublic); MethodInfo method4 = typeof(ChargeHoldReleaseModule).GetMethod("ChargeHandler_ResetState_Postfix", BindingFlags.Static | BindingFlags.NonPublic); if (methodInfo2 != null && method4 != null) { harmony.Patch((MethodBase)methodInfo2, (HarmonyMethod)null, new HarmonyMethod(method4), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null); } MethodInfo methodInfo8 = AccessTools.Method(typeof(ChargeHandler), "EndCharge", Type.EmptyTypes, (Type[])null); MethodInfo method5 = typeof(ChargeHoldReleaseModule).GetMethod("ChargeHandler_EndCharge_Postfix", BindingFlags.Static | BindingFlags.NonPublic); if (methodInfo8 != null && method5 != null) { harmony.Patch((MethodBase)methodInfo8, (HarmonyMethod)null, new HarmonyMethod(method5), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null); } MethodInfo method6 = typeof(ChargeHoldReleaseModule).GetMethod("ChargeHandler_FixedUpdate_Postfix", BindingFlags.Static | BindingFlags.NonPublic); if (methodInfo3 != null && method6 != null) { harmony.Patch((MethodBase)methodInfo3, (HarmonyMethod)null, new HarmonyMethod(method6), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null); } MethodInfo method7 = typeof(ChargeHoldReleaseModule).GetMethod("ChargeHandler_CancelCharge_Postfix", BindingFlags.Static | BindingFlags.NonPublic); if (methodInfo4 != null && method7 != null) { harmony.Patch((MethodBase)methodInfo4, (HarmonyMethod)null, new HarmonyMethod(method7), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null); } MethodInfo method8 = typeof(ChargeHoldReleaseModule).GetMethod("ChargeHandler_EnemyHit_Prefix", BindingFlags.Static | BindingFlags.NonPublic); if (methodInfo5 != null && method8 != null) { harmony.Patch((MethodBase)methodInfo5, new HarmonyMethod(method8), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null); } MethodInfo method9 = typeof(ChargeHoldReleaseModule).GetMethod("ChargeHandler_UpdateWindupDirection_Prefix", BindingFlags.Static | BindingFlags.NonPublic); if (methodInfo6 != null && method9 != null) { harmony.Patch((MethodBase)methodInfo6, new HarmonyMethod(method9), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null); } MethodInfo method10 = typeof(ChargeHoldReleaseModule).GetMethod("ChargeHandler_SyncChargeStateRPC_Postfix", BindingFlags.Static | BindingFlags.NonPublic); if (methodInfo7 != null) { if (method3 != null) { harmony.Patch((MethodBase)methodInfo7, new HarmonyMethod(method3), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null); } if (method10 != null) { harmony.Patch((MethodBase)methodInfo7, (HarmonyMethod)null, new HarmonyMethod(method10), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null); } } } private static bool ChargeHandler_ChargeWindup_Prefix(ChargeHandler __instance) { if ((Object)(object)__instance == (Object)null) { return true; } if (IsChargeHandlerHeadGrabbed(__instance)) { if (FeatureFlags.DebugLogging && LogLimiter.ShouldLog("Fix:Charge.Grabbed", 30)) { Debug.Log((object)"[Fix:Charge] Charge windup blocked because the head is grabbed."); } return false; } return true; } private static void ChargeHandler_ChargeWindup_Postfix(ChargeHandler __instance) { if (!((Object)(object)__instance == (Object)null) && IsChargeState(__instance, "Windup")) { int unityObjectInstanceId = GetUnityObjectInstanceId((Object?)(object)__instance); if (unityObjectInstanceId != 0) { ChargeHoldState orCreateChargeHoldState = GetOrCreateChargeHoldState(unityObjectInstanceId); orCreateChargeHoldState.StartTime = Time.time; orCreateChargeHoldState.IsHolding = true; orCreateChargeHoldState.LaunchScale = 1f; BeginChargeMotionDiagnosticTrace(__instance); LogChargeMotionEvent("windup-start", __instance); s_localHoldUiActive = true; AbilityModule.SetChargeSlotActivationProgress(0f); } } } private static void ChargeHandler_FixedUpdate_Postfix(ChargeHandler __instance) { if ((Object)(object)__instance == (Object)null) { return; } int unityObjectInstanceId = GetUnityObjectInstanceId((Object?)(object)__instance); if (unityObjectInstanceId == 0) { return; } if (SemiFunc.IsMasterClientOrSingleplayer() && IsChargeState(__instance, "Charging")) { if (!TryStopStalledCharge(__instance, unityObjectInstanceId)) { TryStopAtBounceLimit(__instance); } return; } if (!IsLocalChargeHandler(__instance)) { if (s_chargeHoldStates.TryGetValue(unityObjectInstanceId, out ChargeHoldState value)) { if (!IsChargeState(__instance, "Windup")) { s_chargeHoldStates.Remove(unityObjectInstanceId); } else if (value.IsHolding) { __instance.windupTimer = Mathf.Max(0.01f, __instance.windupTime); } } return; } if (!s_chargeHoldStates.TryGetValue(unityObjectInstanceId, out ChargeHoldState value2)) { if (!IsChargeState(__instance, "Windup") || !s_localHoldInputPending) { if (!s_localHoldUiActive) { AbilityModule.SetChargeSlotActivationProgress(0f); } return; } value2 = GetOrCreateChargeHoldState(unityObjectInstanceId); value2.StartTime = ((s_lastLocalHoldInputStartTime > 0f) ? s_lastLocalHoldInputStartTime : Time.time); value2.IsHolding = true; value2.LaunchScale = 1f; s_localHoldUiActive = true; AbilityModule.SetChargeSlotActivationProgress(0f); } if (!IsChargeState(__instance, "Windup")) { s_chargeHoldStates.Remove(unityObjectInstanceId); s_localHoldUiActive = false; AbilityModule.SetChargeSlotActivationProgress(0f); if (!s_localHoldUiActive) { AbilityModule.SetChargeSlotActivationProgress(0f); } return; } if (s_localHoldUiActive && value2.IsHolding) { float num = Mathf.Max(0.2f, FeatureFlags.ChargeAbilityHoldSeconds); float progress = Mathf.Clamp01((Time.time - value2.StartTime) / num); float minimumChargeReleaseScale = GetMinimumChargeReleaseScale(__instance); AbilityModule.SetChargeSlotActivationProgress(progress, minimumChargeReleaseScale); } else { if (!value2.IsHolding) { if (!s_localHoldUiActive) { AbilityModule.SetChargeSlotActivationProgress(0f); } if (!IsChargeState(__instance, "Windup")) { s_chargeHoldStates.Remove(unityObjectInstanceId); } return; } if (!IsChargeState(__instance, "Windup")) { s_chargeHoldStates.Remove(unityObjectInstanceId); AbilityModule.SetChargeSlotActivationProgress(0f); return; } float num2 = Mathf.Max(0.2f, FeatureFlags.ChargeAbilityHoldSeconds); float progress2 = Mathf.Clamp01((Time.time - value2.StartTime) / num2); float minimumChargeReleaseScale2 = GetMinimumChargeReleaseScale(__instance); AbilityModule.SetChargeSlotActivationProgress(progress2, minimumChargeReleaseScale2); } if (value2.IsHolding) { __instance.windupTimer = Mathf.Max(0.01f, __instance.windupTime); } } private static bool TryStopStalledCharge(ChargeHandler chargeHandler, int id) { //IL_006f: Unknown result type (might be due to invalid IL or missing references) //IL_0074: Unknown result type (might be due to invalid IL or missing references) //IL_0085: Unknown result type (might be due to invalid IL or missing references) //IL_008a: Unknown result type (might be due to invalid IL or missing references) ChargeHoldState orCreateChargeHoldState = GetOrCreateChargeHoldState(id); if (orCreateChargeHoldState.ChargingStartTime <= 0f) { orCreateChargeHoldState.ChargingStartTime = Time.time; } DeathHeadController controller = chargeHandler.controller; Rigidbody rb = chargeHandler.rb; int num; if (controller != null && controller.collisionHandler?.isColliding == true && (Object)(object)rb != (Object)null) { Vector3 val = rb.linearVelocity; if (((Vector3)(ref val)).sqrMagnitude <= 0.01f) { val = rb.angularVelocity; num = ((((Vector3)(ref val)).sqrMagnitude <= 0.04f) ? 1 : 0); goto IL_00a0; } } num = 0; goto IL_00a0; IL_00a0: bool flag = (byte)num != 0; orCreateChargeHoldState.RestingTime = (flag ? (orCreateChargeHoldState.RestingTime + Time.fixedDeltaTime) : 0f); bool flag2 = orCreateChargeHoldState.RestingTime >= 0.35f; bool flag3 = Time.time - orCreateChargeHoldState.ChargingStartTime >= 10f; if (!flag2 && !flag3) { return false; } chargeHandler.EndCharge(); if (FeatureFlags.DebugLogging && LogLimiter.ShouldLog("Fix:DHHCharge.StalledStop", 30)) { string text = (flag2 ? "stable-rest" : "failsafe-timeout"); ManualLogSource? obj = s_log; if (obj != null) { obj.LogDebug((object)("[Fix:DHHCharge] Ended authoritative Charging state (" + text + ").")); } } return true; } private static void TryStopAtBounceLimit(ChargeHandler chargeHandler) { int num = Mathf.Max(0, Mathf.CeilToInt(chargeHandler.maxBounces)); if (num <= 0 || chargeHandler.bounceColliders.Count < num) { return; } if (FeatureFlags.DebugLogging && LogLimiter.ShouldLog("Fix:DHHCharge.BounceLimit", 5)) { ManualLogSource? obj = s_log; if (obj != null) { obj.LogDebug((object)("[Fix:DHHCharge] Ending charge at bounce limit: " + $"bounces={chargeHandler.bounceColliders.Count} maxBounces={num} " + $"chargeTimer={chargeHandler.chargeTimer:F2}.")); } } chargeHandler.EndCharge(); } private static void PatchChargeAbilityHoldReleaseIfPossible(Harmony harmony, Assembly asm) { //IL_00ed: Unknown result type (might be due to invalid IL or missing references) //IL_00fb: Expected O, but got Unknown //IL_00dc: Unknown result type (might be due to invalid IL or missing references) //IL_00e9: Expected O, but got Unknown //IL_011b: Unknown result type (might be due to invalid IL or missing references) //IL_0128: Expected O, but got Unknown MethodInfo methodInfo = AccessTools.Method(typeof(ChargeAbility), "OnAbilityDown", Type.EmptyTypes, (Type[])null); MethodInfo methodInfo2 = AccessTools.Method(typeof(ChargeAbility), "OnAbilityUp", Type.EmptyTypes, (Type[])null); MethodInfo methodInfo3 = AccessTools.Method(typeof(ChargeAbility), "OnAbilityCancel", Type.EmptyTypes, (Type[])null); if (methodInfo2 == null) { return; } MethodInfo method = typeof(ChargeHoldReleaseModule).GetMethod("ChargeAbility_OnAbilityUp_Prefix", BindingFlags.Static | BindingFlags.NonPublic); if (!(method == null)) { MethodInfo method2 = typeof(ChargeHoldReleaseModule).GetMethod("ChargeAbility_OnAbilityDown_Postfix", BindingFlags.Static | BindingFlags.NonPublic); MethodInfo method3 = typeof(ChargeHoldReleaseModule).GetMethod("ChargeAbility_OnAbilityCancel_Postfix", BindingFlags.Static | BindingFlags.NonPublic); if (methodInfo != null && method2 != null) { harmony.Patch((MethodBase)methodInfo, (HarmonyMethod)null, new HarmonyMethod(method2), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null); } harmony.Patch((MethodBase)methodInfo2, new HarmonyMethod(method), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null); if (methodInfo3 != null && method3 != null) { harmony.Patch((MethodBase)methodInfo3, (HarmonyMethod)null, new HarmonyMethod(method3), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null); } } } private static void PatchStunHandlerHoldScalingIfPossible(Harmony harmony, Assembly asm) { //IL_004a: Unknown result type (might be due to invalid IL or missing references) //IL_0058: Expected O, but got Unknown MethodInfo methodInfo = AccessTools.PropertyGetter(typeof(StunHandler), "StunDuration"); if (!(methodInfo == null)) { MethodInfo method = typeof(ChargeHoldReleaseModule).GetMethod("StunHandler_StunDuration_Prefix", BindingFlags.Static | BindingFlags.NonPublic); if (!(method == null)) { harmony.Patch((MethodBase)methodInfo, new HarmonyMethod(method), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null); } } } private static void ChargeHandler_CancelCharge_Postfix(ChargeHandler __instance) { LogChargeMotionEvent("cancel-charge", __instance); RemoveChargeMotionDiagnosticTrace(__instance); StopChargeWindupLoop(__instance); ClearChargeHoldState(__instance); SynchronizeFinalChargeState(__instance); } private static void ChargeHandler_SyncChargeStateRPC_Prefix(ChargeHandler __instance, ChargeState state) { //IL_000e: Unknown result type (might be due to invalid IL or missing references) //IL_0010: Invalid comparison between Unknown and I4 //IL_0012: Unknown result type (might be due to invalid IL or missing references) //IL_0014: Invalid comparison between Unknown and I4 if (!((Object)(object)__instance == (Object)null) && (int)state != 1 && (int)state != 2) { LogChargeMotionEvent("sync-state-stop", __instance); RemoveChargeMotionDiagnosticTrace(__instance); StopChargeWindupLoop(__instance); ClearChargeHoldState(__instance); } } private static void ChargeHandler_SyncChargeStateRPC_Postfix(ChargeHandler __instance) { if (!((Object)(object)__instance == (Object)null) && !IsChargeState(__instance, "Windup") && !IsChargeState(__instance, "Charging")) { StopChargeWindupLoop(__instance); ClearChargeHoldState(__instance); } } private static bool ChargeHandler_EnemyHit_Prefix(ChargeHandler __instance) { if ((Object)(object)__instance == (Object)null) { return true; } int unityObjectInstanceId = GetUnityObjectInstanceId((Object?)(object)__instance); if (unityObjectInstanceId == 0 || !s_chargeHoldStates.TryGetValue(unityObjectInstanceId, out ChargeHoldState value)) { return true; } __instance.enemiesHit++; int abilityLevel = __instance.AbilityLevel; int num = Mathf.FloorToInt(EvaluateStatWithDiminishingReturns(1f, 0.5f, abilityLevel, 20, 0.9f).FinalValue); int num2 = Mathf.Max(1, Mathf.RoundToInt((float)num * Mathf.Clamp01(value.LaunchScale))); if (__instance.enemiesHit >= num2) { if (FeatureFlags.DebugLogging && LogLimiter.ShouldLog("Fix:DHHCharge.EnemyHitLimit", 5)) { ManualLogSource? obj = s_log; if (obj != null) { obj.LogDebug((object)("[Fix:DHHCharge] Ending charge at enemy-hit limit: " + $"enemiesHit={__instance.enemiesHit} maxEnemies={num2} " + $"bounces={__instance.bounceColliders.Count} chargeTimer={__instance.chargeTimer:F2}.")); } } __instance.EndCharge(); } return false; } private static bool StunHandler_StunDuration_Prefix(StunHandler __instance, ref float __result) { if ((Object)(object)__instance == (Object)null) { return true; } ChargeHandler chargeHandler = __instance.chargeHandler; if ((Object)(object)chargeHandler == (Object)null) { return true; } int unityObjectInstanceId = GetUnityObjectInstanceId((Object?)(object)chargeHandler); if (unityObjectInstanceId == 0 || !s_chargeHoldStates.TryGetValue(unityObjectInstanceId, out ChargeHoldState value)) { return true; } int abilityLevel = chargeHandler.AbilityLevel; float num = 5f + 1f * (float)abilityLevel; __result = num * Mathf.Clamp01(value.LaunchScale); return false; } private static bool ChargeAbility_OnAbilityUp_Prefix() { return TryReleaseHeldCharge(); } private static void ChargeAbility_OnAbilityDown_Postfix() { s_lastLocalHoldInputStartTime = Time.time; s_localHoldInputPending = true; AbilityModule.SetChargeSlotActivationProgress(0f); ChargeHandler localChargeHandler = GetLocalChargeHandler(); LogChargeMotionEvent("input-down", localChargeHandler); if ((Object)(object)localChargeHandler != (Object)null && !IsChargeState(localChargeHandler, "Windup")) { ClearChargeHoldState(localChargeHandler); } } private static void ChargeAbility_OnAbilityCancel_Postfix() { s_localHoldInputPending = false; s_localHoldUiActive = false; AbilityModule.SetChargeSlotActivationProgress(0f); ChargeHandler localChargeHandler = GetLocalChargeHandler(); LogChargeMotionEvent("input-cancel", localChargeHandler); if (!((Object)(object)localChargeHandler == (Object)null)) { ClearChargeHoldState(localChargeHandler); } } private static bool TryReleaseHeldCharge() { ChargeHandler localChargeHandler = GetLocalChargeHandler(); LogChargeMotionEvent("input-release", localChargeHandler); if ((Object)(object)localChargeHandler == (Object)null) { s_localHoldInputPending = false; s_localHoldUiActive = false; AbilityModule.SetChargeSlotActivationProgress(0f); return true; } if (!IsChargeState(localChargeHandler, "Windup")) { s_localHoldInputPending = false; s_localHoldUiActive = false; AbilityModule.SetChargeSlotActivationProgress(0f); return true; } int unityObjectInstanceId = GetUnityObjectInstanceId((Object?)(object)localChargeHandler); if (unityObjectInstanceId == 0) { s_localHoldInputPending = false; s_localHoldUiActive = false; AbilityModule.SetChargeSlotActivationProgress(0f); return true; } if (!s_chargeHoldStates.TryGetValue(unityObjectInstanceId, out ChargeHoldState value)) { value = GetOrCreateChargeHoldState(unityObjectInstanceId); value.StartTime = ((s_lastLocalHoldInputStartTime > 0f) ? s_lastLocalHoldInputStartTime : Time.time); value.IsHolding = true; value.LaunchScale = 1f; } if (!value.IsHolding) { return true; } if (SemiFunc.IsMultiplayer() && !SemiFunc.IsMasterClientOrSingleplayer()) { if (!ConfigSyncManager.IsRemoteHostFixCompatible()) { value.IsHolding = false; value.LaunchScale = 0f; s_localHoldInputPending = false; s_localHoldUiActive = false; AbilityModule.SetChargeSlotActivationProgress(0f); StopChargeWindupLoop(localChargeHandler); if (FeatureFlags.DebugLogging && LogLimiter.ShouldLog("Fix:Charge.PermissiveFallback", 120)) { Debug.Log((object)"[Fix:DHHCharge][PermissiveGate] Host fix marker missing. Sending authoritative cancel fallback."); } TrySendVanillaRemoteCancelCommand(localChargeHandler); return false; } value.IsHolding = false; s_localHoldInputPending = false; s_localHoldUiActive = false; AbilityModule.SetChargeSlotActivationProgress(0f); if (!TrySendRemoteReleaseCommand(localChargeHandler)) { StopChargeWindupLoop(localChargeHandler); TrySendVanillaRemoteCancelCommand(localChargeHandler); } return false; } float num = Mathf.Max(0.2f, FeatureFlags.ChargeAbilityHoldSeconds); float num2 = Mathf.Clamp01((Time.time - value.StartTime) / num); float minimumChargeReleaseScale = GetMinimumChargeReleaseScale(localChargeHandler); if (num2 < minimumChargeReleaseScale) { value.IsHolding = false; value.LaunchScale = 0f; s_localHoldInputPending = false; s_localHoldUiActive = false; AbilityModule.SetChargeSlotActivationProgress(0f); StopChargeWindupLoop(localChargeHandler); localChargeHandler.CancelCharge(); return false; } value.IsHolding = false; value.LaunchScale = num2; localChargeHandler.chargeStrength *= num2; localChargeHandler.maxBounces = Mathf.Max(0f, localChargeHandler.maxBounces * num2); localChargeHandler.windupTimer = -1f; s_localHoldInputPending = false; s_localHoldUiActive = false; AbilityModule.SetChargeSlotActivationProgress(0f); return true; } private static bool ChargeHandler_UpdateWindupDirection_Prefix(ChargeHandler __instance, Vector3 chargeDirection) { //IL_002c: Unknown result type (might be due to invalid IL or missing references) //IL_005a: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)__instance == (Object)null) { return true; } if (!SemiFunc.IsMasterClientOrSingleplayer()) { return true; } if (Mathf.Abs(chargeDirection.x - -778f) < 0.001f) { __instance.CancelCharge(); return false; } if (Mathf.Abs(chargeDirection.x - -777f) > 0.001f) { return true; } LogChargeMotionEvent("remote-release-received", __instance); int unityObjectInstanceId = GetUnityObjectInstanceId((Object?)(object)__instance); if (unityObjectInstanceId == 0 || !s_chargeHoldStates.TryGetValue(unityObjectInstanceId, out ChargeHoldState value)) { return false; } if (!IsChargeState(__instance, "Windup")) { return false; } float num = Mathf.Max(0.2f, FeatureFlags.ChargeAbilityHoldSeconds); float num2 = Mathf.Clamp01((Time.time - value.StartTime) / num); float minimumChargeReleaseScale = GetMinimumChargeReleaseScale(__instance); value.IsHolding = false; if (num2 < minimumChargeReleaseScale) { value.LaunchScale = 0f; __instance.CancelCharge(); return false; } value.LaunchScale = num2; __instance.chargeStrength *= num2; __instance.maxBounces = Mathf.Max(0f, __instance.maxBounces * num2); __instance.windupTimer = -1f; return false; } private static bool TrySendRemoteReleaseCommand(ChargeHandler chargeHandler) { //IL_005d: Unknown result type (might be due to invalid IL or missing references) PhotonView chargePhotonView = GetChargePhotonView(chargeHandler); if ((Object)(object)chargePhotonView == (Object)null || chargePhotonView.ViewID <= 0) { return false; } if (!PhotonNetwork.InRoom || PhotonNetwork.IsMasterClient) { return false; } chargePhotonView.RPC("UpdateWindupDirection", (RpcTarget)2, new object[1] { (object)new Vector3(-777f, 0f, 0f) }); return true; } private static bool TrySendVanillaRemoteCancelCommand(ChargeHandler chargeHandler) { PhotonView chargePhotonView = GetChargePhotonView(chargeHandler); if ((Object)(object)chargePhotonView == (Object)null || chargePhotonView.ViewID <= 0) { return false; } if (!PhotonNetwork.InRoom || PhotonNetwork.IsMasterClient) { return false; } chargePhotonView.RPC("CancelCharge", (RpcTarget)2, Array.Empty<object>()); return true; } private static PhotonView? GetChargePhotonView(ChargeHandler chargeHandler) { if (chargeHandler != null) { PhotonView component = ((Component)chargeHandler).GetComponent<PhotonView>(); if ((Object)(object)component != (Object)null && component.ViewID > 0) { return component; } } return GetDhhInputManagerHeadPhotonView(); } private static PhotonView? GetDhhInputManagerHeadPhotonView() { return ((Object)(object)DHHInputManager.instance != (Object)null) ? DHHInputManager.instance.headPhotonView : null; } private static float GetMinimumChargeReleaseScale(ChargeHandler chargeHandler) { if ((Object)(object)chargeHandler == (Object)null) { return 0f; } float num = 0f; TryGetEffectiveChargeAbilityLevel(chargeHandler, out var abilityLevel); float effectiveChargeStrengthForThreshold = GetEffectiveChargeStrengthForThreshold(chargeHandler, abilityLevel); if (effectiveChargeStrengthForThreshold > 0f) { num = Mathf.Max(num, RequiredScaleForMinimumOne(effectiveChargeStrengthForThreshold)); } float effectiveMaxBouncesForThreshold = GetEffectiveMaxBouncesForThreshold(chargeHandler, abilityLevel); if (effectiveMaxBouncesForThreshold > 0f) { num = Mathf.Max(num, RequiredScaleForMinimumOne(effectiveMaxBouncesForThreshold)); } if (abilityLevel > 0) { float baseValue = 5f + 1f * (float)abilityLevel; num = Mathf.Max(num, RequiredScaleForMinimumOne(baseValue)); } if (float.IsNaN(num) || float.IsInfinity(num)) { return 1f; } return Mathf.Clamp01(num); } private static float GetEffectiveChargeStrengthForThreshold(ChargeHandler chargeHandler, int abilityLevel) { if (chargeHandler.chargeStrength > 0f) { return chargeHandler.chargeStrength; } if (abilityLevel <= 0) { return 0f; } return EvaluateStatWithDiminishingReturns(FeatureFlags.DHHChargeStrengthBaseValue, FeatureFlags.DHHChargeStrengthIncreasePerLevel, abilityLevel, FeatureFlags.DHHChargeStrengthThresholdLevel, FeatureFlags.DHHChargeStrengthDiminishingFactor).FinalValue; } private static float GetEffectiveMaxBouncesForThreshold(ChargeHandler chargeHandler, int abilityLevel) { if (chargeHandler.maxBounces > 0f) { return chargeHandler.maxBounces; } if (abilityLevel <= 0) { return 0f; } float baseValue = ((chargeHandler.baseMaxBounces > 0) ? ((float)chargeHandler.baseMaxBounces) : 3f); return Mathf.FloorToInt(EvaluateStatWithDiminishingReturns(baseValue, 0.5f, abilityLevel, 20, 0.9f).FinalValue); } private static bool TryGetEffectiveChargeAbilityLevel(ChargeHandler chargeHandler, out int abilityLevel) { abilityLevel = Mathf.Max(0, chargeHandler.AbilityLevel); if (abilityLevel > 0) { return true; } if (!SemiFunc.IsMasterClientOrSingleplayer() && IsLocalChargeHandler(chargeHandler) && TryGetLocalPlayerChargeUpgrade(out var upgrade)) { abilityLevel = Mathf.Max(0, upgrade); return true; } return abilityLevel >= 0; } private static bool TryGetLocalPlayerChargeUpgrade(out int upgrade) { upgrade = 0; PlayerAvatar instance = PlayerAvatar.instance; string text = (((Object)(object)instance != (Object)null) ? SemiFunc.PlayerGetSteamID(instance) : null); if (string.IsNullOrWhiteSpace(text)) { return false; } try { upgrade = DHHStatsManager.GetHeadChargeUpgrade(text); return true; } catch { return false; } } private static float RequiredScaleForMinimumOne(float baseValue) { if (baseValue <= 0f) { return float.PositiveInfinity; } return 1f / baseValue; } private static bool IsChargeHandlerHeadGrabbed(ChargeHandler chargeHandler) { PhysGrabObjectImpactDetector impactDetector = chargeHandler.impactDetector; if ((Object)(object)impactDetector == (Object)null) { return false; } PhysGrabObject physGrabObject = impactDetector.physGrabObject; if ((Object)(object)physGrabObject == (Object)null) { return false; } return physGrabObject.grabbed; } private static int GetUnityObjectInstanceId(Object? obj) { return (obj != (Object)null) ? obj.GetInstanceID() : 0; } private static ChargeHoldState GetOrCreateChargeHoldState(int id) { if (!s_chargeHoldStates.TryGetValue(id, out ChargeHoldState value)) { value = new ChargeHoldState(); s_chargeHoldStates[id] = value; } return value; } private static bool IsChargeState(ChargeHandler chargeHandler, string stateName) { //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) if ((Object)(object)chargeHandler == (Object)null) { return false; } return string.Equals(((object)chargeHandler.State/*cast due to .constrained prefix*/).ToString(), stateName, StringComparison.Ordinal); } private static bool IsLocalChargeHandler(ChargeHandler chargeHandler) { ChargeHandler localChargeHandler = GetLocalChargeHandler(); if ((Object)(object)localChargeHandler == (Object)null) { return false; } return localChargeHandler == chargeHandler; } private static ChargeHandler? GetLocalChargeHandler() { PlayerAvatar instance = PlayerAvatar.instance; if ((Object)(object)instance?.playerDeathHead == (Object)null) { return null; } return ((Component)instance.playerDeathHead).GetComponent<DeathHeadController>()?.chargeHandler; } private static void ClearChargeHoldState(ChargeHandler? chargeHandler) { if (!((Object)(object)chargeHandler == (Object)null)) { int unityObjectInstanceId = GetUnityObjectInstanceId((Object?)(object)chargeHandler); if (unityObjectInstanceId != 0) { s_chargeHoldStates.Remove(unityObjectInstance