using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using HarmonyLib;
using Microsoft.CodeAnalysis;
using UnityEngine;
[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)]
[assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")]
[assembly: IgnoresAccessChecksTo("")]
[assembly: AssemblyCompany("REPOJP")]
[assembly: AssemblyConfiguration("Debug")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0")]
[assembly: AssemblyProduct("REPOJP")]
[assembly: AssemblyTitle("REPOJP")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.0.0.0")]
[module: UnverifiableCode]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
[CompilerGenerated]
[Microsoft.CodeAnalysis.Embedded]
internal sealed class EmbeddedAttribute : Attribute
{
}
}
namespace System.Runtime.CompilerServices
{
[CompilerGenerated]
[Microsoft.CodeAnalysis.Embedded]
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Parameter | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter, AllowMultiple = false, Inherited = false)]
internal sealed class NullableAttribute : Attribute
{
public readonly byte[] NullableFlags;
public NullableAttribute(byte P_0)
{
NullableFlags = new byte[1] { P_0 };
}
public NullableAttribute(byte[] P_0)
{
NullableFlags = P_0;
}
}
[CompilerGenerated]
[Microsoft.CodeAnalysis.Embedded]
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Method | AttributeTargets.Interface | AttributeTargets.Delegate, AllowMultiple = false, Inherited = false)]
internal sealed class NullableContextAttribute : Attribute
{
public readonly byte Flag;
public NullableContextAttribute(byte P_0)
{
Flag = P_0;
}
}
[CompilerGenerated]
[Microsoft.CodeAnalysis.Embedded]
[AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)]
internal sealed class RefSafetyRulesAttribute : Attribute
{
public readonly int Version;
public RefSafetyRulesAttribute(int P_0)
{
Version = P_0;
}
}
}
namespace REPOJP.GambitEnhancements
{
[BepInPlugin("REPOJP.GambitEnhancements", "GambitEnhancements", "1.0.0")]
public sealed class GambitEnhancementsPlugin : BaseUnityPlugin
{
public const string PluginGuid = "REPOJP.GambitEnhancements";
public const string PluginName = "GambitEnhancements";
public const string PluginVersion = "1.0.0";
internal static GambitEnhancementsPlugin Instance;
internal static ManualLogSource Log;
private Harmony _harmony;
internal static ConfigEntry<bool> EnableMod;
internal static ConfigEntry<bool> EnableVerboseLog;
internal static ConfigEntry<int> RouletteDurationSeconds;
internal static ConfigEntry<bool> ForceCarryToGoalAfterRoulette;
internal static ConfigEntry<float> ReleaseGrabDistance;
internal static ConfigEntry<bool> RunAwayDuringRoulette;
internal static ConfigEntry<float> RouletteRunSpeed;
internal static ConfigEntry<float> RouletteRunAcceleration;
internal static ConfigEntry<float> GoalReachedDistance;
internal static ConfigEntry<float> EscapeDestinationRefreshInterval;
internal static ConfigEntry<bool> StrengthenPlayerLockDuringRoulette;
internal static ConfigEntry<float> RouletteFollowForceMultiplier;
internal static ConfigEntry<float> RouletteFollowForceGrabbedMultiplier;
internal static ConfigEntry<float> RouletteLockLerpSpeed;
internal static ConfigEntry<bool> ImmuneToStunDuringRoulette;
internal static ConfigEntry<bool> BlockStunSetCallDuringRoulette;
internal static ConfigEntry<bool> EnableJumpAssistDuringRoulette;
internal static ConfigEntry<float> JumpAssistInterval;
internal static ConfigEntry<float> StuckVelocityThreshold;
internal static ConfigEntry<float> StuckDistanceThreshold;
internal static ConfigEntry<float> StuckRepathDelay;
internal static ConfigEntry<bool> InstantRepathWhenStuck;
internal static ConfigEntry<float> SameGoalReapplyInterval;
private void Awake()
{
//IL_009d: Unknown result type (might be due to invalid IL or missing references)
//IL_00a7: Expected O, but got Unknown
//IL_00fa: Unknown result type (might be due to invalid IL or missing references)
//IL_0104: Expected O, but got Unknown
//IL_0157: Unknown result type (might be due to invalid IL or missing references)
//IL_0161: Expected O, but got Unknown
//IL_0194: Unknown result type (might be due to invalid IL or missing references)
//IL_019e: Expected O, but got Unknown
//IL_01d1: Unknown result type (might be due to invalid IL or missing references)
//IL_01db: Expected O, but got Unknown
//IL_020e: Unknown result type (might be due to invalid IL or missing references)
//IL_0218: Expected O, but got Unknown
//IL_026b: Unknown result type (might be due to invalid IL or missing references)
//IL_0275: Expected O, but got Unknown
//IL_02a8: Unknown result type (might be due to invalid IL or missing references)
//IL_02b2: Expected O, but got Unknown
//IL_02e5: Unknown result type (might be due to invalid IL or missing references)
//IL_02ef: Expected O, but got Unknown
//IL_0382: Unknown result type (might be due to invalid IL or missing references)
//IL_038c: Expected O, but got Unknown
//IL_03bf: Unknown result type (might be due to invalid IL or missing references)
//IL_03c9: Expected O, but got Unknown
//IL_03fc: Unknown result type (might be due to invalid IL or missing references)
//IL_0406: Expected O, but got Unknown
//IL_0439: Unknown result type (might be due to invalid IL or missing references)
//IL_0443: Expected O, but got Unknown
//IL_0496: Unknown result type (might be due to invalid IL or missing references)
//IL_04a0: Expected O, but got Unknown
//IL_04ab: Unknown result type (might be due to invalid IL or missing references)
//IL_04b5: Expected O, but got Unknown
Instance = this;
Log = ((BaseUnityPlugin)this).Logger;
((Component)this).transform.parent = null;
((Object)((Component)this).gameObject).hideFlags = (HideFlags)61;
Object.DontDestroyOnLoad((Object)(object)((Component)this).gameObject);
EnableMod = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "EnableMod", true, "Enable or disable this mod");
EnableVerboseLog = ((BaseUnityPlugin)this).Config.Bind<bool>("Logging", "EnableVerboseLog", true, "Enable verbose logs");
RouletteDurationSeconds = ((BaseUnityPlugin)this).Config.Bind<int>("Roulette", "RouletteDurationSeconds", 10, new ConfigDescription("Roulette duration in whole seconds", (AcceptableValueBase)(object)new AcceptableValueRange<int>(0, 10), Array.Empty<object>()));
ForceCarryToGoalAfterRoulette = ((BaseUnityPlugin)this).Config.Bind<bool>("Roulette", "ForceCarryToGoalAfterRoulette", true, "Keep dragging the grabbed player to the selected farthest destination even after roulette has ended");
ReleaseGrabDistance = ((BaseUnityPlugin)this).Config.Bind<float>("Roulette", "ReleaseGrabDistance", 4.999999f, new ConfigDescription("Release the grabbed player if Gambit and the target become farther apart than this distance", (AcceptableValueBase)(object)new AcceptableValueRange<float>(1f, 50f), Array.Empty<object>()));
RunAwayDuringRoulette = ((BaseUnityPlugin)this).Config.Bind<bool>("Movement", "RunAwayDuringRoulette", true, "Run away during roulette");
RouletteRunSpeed = ((BaseUnityPlugin)this).Config.Bind<float>("Movement", "RouletteRunSpeed", 6f, new ConfigDescription("Run speed during roulette or forced carry", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 20f), Array.Empty<object>()));
RouletteRunAcceleration = ((BaseUnityPlugin)this).Config.Bind<float>("Movement", "RouletteRunAcceleration", 12f, new ConfigDescription("Run acceleration during roulette or forced carry", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 50f), Array.Empty<object>()));
GoalReachedDistance = ((BaseUnityPlugin)this).Config.Bind<float>("Movement", "GoalReachedDistance", 5f, new ConfigDescription("Distance at which the farthest destination is considered reached", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0.25f, 10f), Array.Empty<object>()));
EscapeDestinationRefreshInterval = ((BaseUnityPlugin)this).Config.Bind<float>("Movement", "EscapeDestinationRefreshInterval", 3f, new ConfigDescription("Reserved compatibility setting for destination refresh interval", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0.1f, 30f), Array.Empty<object>()));
StrengthenPlayerLockDuringRoulette = ((BaseUnityPlugin)this).Config.Bind<bool>("Grab", "StrengthenPlayerLockDuringRoulette", true, "Strengthen player lock during roulette and forced carry");
RouletteFollowForceMultiplier = ((BaseUnityPlugin)this).Config.Bind<float>("Grab", "RouletteFollowForceMultiplier", 1f, new ConfigDescription("Follow force multiplier while target is not grabbed by another player", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 10f), Array.Empty<object>()));
RouletteFollowForceGrabbedMultiplier = ((BaseUnityPlugin)this).Config.Bind<float>("Grab", "RouletteFollowForceGrabbedMultiplier", 3f, new ConfigDescription("Follow force multiplier while target is grabbed by another player", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 10f), Array.Empty<object>()));
RouletteLockLerpSpeed = ((BaseUnityPlugin)this).Config.Bind<float>("Grab", "RouletteLockLerpSpeed", 6f, new ConfigDescription("Lock lerp speed during roulette and forced carry", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 20f), Array.Empty<object>()));
ImmuneToStunDuringRoulette = ((BaseUnityPlugin)this).Config.Bind<bool>("Stun", "ImmuneToStunDuringRoulette", true, "Prevent stun during roulette only");
BlockStunSetCallDuringRoulette = ((BaseUnityPlugin)this).Config.Bind<bool>("Stun", "BlockStunSetCallDuringRoulette", true, "Block EnemyStateStunned.Set during roulette only");
EnableJumpAssistDuringRoulette = ((BaseUnityPlugin)this).Config.Bind<bool>("Assist", "EnableJumpAssistDuringRoulette", true, "Enable jump assist during roulette and forced carry");
JumpAssistInterval = ((BaseUnityPlugin)this).Config.Bind<float>("Assist", "JumpAssistInterval", 0.5f, new ConfigDescription("Jump assist call interval", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0.02f, 5f), Array.Empty<object>()));
StuckVelocityThreshold = ((BaseUnityPlugin)this).Config.Bind<float>("Assist", "StuckVelocityThreshold", 0.15f, new ConfigDescription("Velocity threshold for stuck detection", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0.01f, 3f), Array.Empty<object>()));
StuckDistanceThreshold = ((BaseUnityPlugin)this).Config.Bind<float>("Assist", "StuckDistanceThreshold", 2f, new ConfigDescription("Distance threshold for stuck detection", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0.1f, 10f), Array.Empty<object>()));
StuckRepathDelay = ((BaseUnityPlugin)this).Config.Bind<float>("Assist", "StuckRepathDelay", 0.2f, new ConfigDescription("Delay before stronger stuck recovery starts", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0.01f, 5f), Array.Empty<object>()));
InstantRepathWhenStuck = ((BaseUnityPlugin)this).Config.Bind<bool>("Assist", "InstantRepathWhenStuck", true, "When stuck, reapply the same goal and trigger stronger recovery");
SameGoalReapplyInterval = ((BaseUnityPlugin)this).Config.Bind<float>("Assist", "SameGoalReapplyInterval", 5f, new ConfigDescription("Minimum interval between same-goal reapply operations while stuck", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0.1f, 30f), Array.Empty<object>()));
_harmony = new Harmony("REPOJP.GambitEnhancements");
_harmony.PatchAll();
Log.LogInfo((object)"GambitEnhancements 1.0.0 loaded");
}
private void OnDestroy()
{
if (_harmony != null)
{
_harmony.UnpatchSelf();
}
}
internal static bool ModEnabled()
{
return EnableMod.Value;
}
internal static void Verbose(string message)
{
if (EnableVerboseLog.Value && Log != null)
{
Log.LogInfo((object)message);
}
}
}
internal static class GambitEnhancementsCore
{
private sealed class SpinnyRuntimeState
{
public bool GrabValuesStored;
public float OriginalFollowForceMultiplier;
public float OriginalFollowForceGrabbedMultiplier;
public float OriginalLockLerpSpeed;
public bool WasRouletteGoingOn;
public bool GoalCaptured;
public bool GoalActive;
public bool PersistCarryActive;
public Vector3 StartPosition;
public Vector3 GoalDestination;
public float StuckTimer;
public float JumpAssistTimer;
public float SameGoalReapplyTimer;
}
private static readonly FieldInfo SpinnyFieldFollowForceGrabbedMultiplier = AccessTools.Field(typeof(EnemySpinny), "_followForceGrabbedMultiplier");
private static readonly FieldInfo SpinnyFieldLockLerpSpeed = AccessTools.Field(typeof(EnemySpinny), "lockLerpSpeed");
private static readonly FieldInfo EnemyRigidbodyFieldRb = AccessTools.Field(typeof(EnemyRigidbody), "rb");
private static readonly FieldInfo EnemyJumpFieldJumping = AccessTools.Field(typeof(EnemyJump), "jumping");
private static readonly MethodInfo SpinnyMethodJumpIfStuck = AccessTools.Method(typeof(EnemySpinny), "JumpIfStuck", new Type[1] { typeof(bool) }, (Type[])null);
private static readonly MethodInfo SpinnyMethodLockInPlayer = AccessTools.Method(typeof(EnemySpinny), "LockInPlayer", new Type[2]
{
typeof(bool),
typeof(bool)
}, (Type[])null);
private static readonly MethodInfo SpinnyMethodUpdateState = AccessTools.Method(typeof(EnemySpinny), "UpdateState", new Type[1] { typeof(State) }, (Type[])null);
private static readonly Dictionary<int, SpinnyRuntimeState> RuntimeStates = new Dictionary<int, SpinnyRuntimeState>();
internal static void PostUpdate(EnemySpinny spinny)
{
if (!CanControl(spinny))
{
RestoreAndDisable(spinny);
return;
}
SpinnyRuntimeState runtime = GetRuntime(spinny);
UpdateGoalState(spinny, runtime);
if (spinny.RouletteGoingOn())
{
spinny.spinDurationSeconds = Mathf.Clamp(GambitEnhancementsPlugin.RouletteDurationSeconds.Value, 0, 10);
}
if (ShouldMaintainGrab(spinny, runtime) && IsTargetTooFar(spinny))
{
ReleaseGrab(spinny, runtime);
}
if (ShouldMaintainGrab(spinny, runtime))
{
if (GambitEnhancementsPlugin.StrengthenPlayerLockDuringRoulette.Value)
{
ApplyGrabSettings(spinny, runtime);
}
}
else
{
RestoreGrabSettings(spinny, runtime);
}
if (spinny.RouletteGoingOn() && GambitEnhancementsPlugin.ImmuneToStunDuringRoulette.Value)
{
ClearStun(spinny);
}
if (ShouldMaintainMovement(spinny, runtime))
{
ApplyMovement(spinny, runtime);
}
}
internal static void PostFixedUpdate(EnemySpinny spinny)
{
if (!CanControl(spinny))
{
RestoreAndDisable(spinny);
return;
}
SpinnyRuntimeState runtime = GetRuntime(spinny);
UpdateGoalState(spinny, runtime);
if (ShouldMaintainGrab(spinny, runtime) && !IsTargetTooFar(spinny))
{
InvokeLockInPlayer(spinny, horizontalPull: false, fixedUpdate: true);
}
}
internal static bool ShouldBlockStun(EnemyStateStunned stunnedComponent)
{
if (!GambitEnhancementsPlugin.ModEnabled())
{
return false;
}
if (!GambitEnhancementsPlugin.BlockStunSetCallDuringRoulette.Value)
{
return false;
}
if (!SemiFunc.IsMasterClientOrSingleplayer())
{
return false;
}
EnemySpinny component = ((Component)stunnedComponent).GetComponent<EnemySpinny>();
if ((Object)(object)component == (Object)null)
{
return false;
}
return component.RouletteGoingOn();
}
private static void UpdateGoalState(EnemySpinny spinny, SpinnyRuntimeState runtime)
{
//IL_0057: Unknown result type (might be due to invalid IL or missing references)
//IL_005c: Unknown result type (might be due to invalid IL or missing references)
//IL_0063: Unknown result type (might be due to invalid IL or missing references)
//IL_0068: 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_00ae: Unknown result type (might be due to invalid IL or missing references)
//IL_019f: Unknown result type (might be due to invalid IL or missing references)
//IL_012f: Unknown result type (might be due to invalid IL or missing references)
if ((Object)(object)spinny.playerTarget == (Object)null || spinny.playerTarget.isDisabled)
{
runtime.GoalActive = false;
runtime.GoalCaptured = false;
runtime.PersistCarryActive = false;
return;
}
if (spinny.RouletteGoingOn() && !runtime.WasRouletteGoingOn)
{
runtime.StartPosition = GetCurrentPosition(spinny);
runtime.GoalDestination = GetFarthestPointFromPosition(runtime.StartPosition);
runtime.GoalActive = true;
runtime.GoalCaptured = true;
runtime.PersistCarryActive = false;
runtime.StuckTimer = 0f;
runtime.JumpAssistTimer = 0f;
runtime.SameGoalReapplyTimer = 0f;
GambitEnhancementsPlugin.Verbose($"[GambitEnhancements] Goal locked -> {runtime.GoalDestination}");
}
if (!spinny.RouletteGoingOn() && runtime.WasRouletteGoingOn)
{
if (runtime.GoalCaptured && GambitEnhancementsPlugin.ForceCarryToGoalAfterRoulette.Value && (Object)(object)spinny.playerTarget != (Object)null && !spinny.playerTarget.isDisabled && !IsGoalReached(spinny, runtime))
{
runtime.PersistCarryActive = true;
runtime.GoalActive = true;
GambitEnhancementsPlugin.Verbose($"[GambitEnhancements] Persist carry enabled -> {runtime.GoalDestination}");
}
else
{
runtime.PersistCarryActive = false;
}
}
if (runtime.GoalActive && IsGoalReached(spinny, runtime))
{
runtime.GoalActive = false;
runtime.PersistCarryActive = false;
runtime.StuckTimer = 0f;
runtime.JumpAssistTimer = 0f;
runtime.SameGoalReapplyTimer = 0f;
GambitEnhancementsPlugin.Verbose($"[GambitEnhancements] Goal reached -> {runtime.GoalDestination}");
}
runtime.WasRouletteGoingOn = spinny.RouletteGoingOn();
}
private static bool ShouldMaintainMovement(EnemySpinny spinny, SpinnyRuntimeState runtime)
{
if (!GambitEnhancementsPlugin.RunAwayDuringRoulette.Value)
{
return false;
}
if (spinny.RouletteGoingOn() && runtime.GoalActive)
{
return true;
}
if (runtime.PersistCarryActive && runtime.GoalActive)
{
return true;
}
return false;
}
private static bool ShouldMaintainGrab(EnemySpinny spinny, SpinnyRuntimeState runtime)
{
if (spinny.RouletteGoingOn())
{
return true;
}
if (runtime.PersistCarryActive && runtime.GoalActive)
{
return true;
}
return false;
}
private static void ApplyMovement(EnemySpinny spinny, SpinnyRuntimeState runtime)
{
//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_007b: Unknown result type (might be due to invalid IL or missing references)
//IL_00ca: Unknown result type (might be due to invalid IL or missing references)
//IL_014b: 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_01ea: Unknown result type (might be due to invalid IL or missing references)
//IL_01ed: Unknown result type (might be due to invalid IL or missing references)
Enemy component = ((Component)spinny).GetComponent<Enemy>();
EnemyNavMeshAgent component2 = ((Component)spinny).GetComponent<EnemyNavMeshAgent>();
EnemyRigidbody component3 = ((Component)spinny).GetComponent<EnemyRigidbody>();
EnemyJump component4 = ((Component)spinny).GetComponent<EnemyJump>();
if ((Object)(object)component == (Object)null || (Object)(object)component2 == (Object)null || !runtime.GoalActive)
{
return;
}
float num = Time.deltaTime;
if (num <= 0f)
{
num = 0.0166667f;
}
Vector3 currentPosition = GetCurrentPosition(spinny);
Rigidbody enemyRigidBody = GetEnemyRigidBody(component3);
component2.SetDestination(runtime.GoalDestination);
component2.OverrideAgent(GambitEnhancementsPlugin.RouletteRunSpeed.Value, GambitEnhancementsPlugin.RouletteRunAcceleration.Value, 0.25f);
if (runtime.SameGoalReapplyTimer > 0f)
{
runtime.SameGoalReapplyTimer -= num;
}
bool flag = IsLikelyStuck(currentPosition, enemyRigidBody, runtime);
if (flag)
{
runtime.StuckTimer += num;
}
else
{
runtime.StuckTimer = 0f;
}
if (GambitEnhancementsPlugin.InstantRepathWhenStuck.Value && flag && runtime.StuckTimer >= GambitEnhancementsPlugin.StuckRepathDelay.Value && runtime.SameGoalReapplyTimer <= 0f)
{
runtime.SameGoalReapplyTimer = GambitEnhancementsPlugin.SameGoalReapplyInterval.Value;
component2.SetDestination(runtime.GoalDestination);
component2.OverrideAgent(GambitEnhancementsPlugin.RouletteRunSpeed.Value, GambitEnhancementsPlugin.RouletteRunAcceleration.Value, 0.25f);
GambitEnhancementsPlugin.Verbose($"[GambitEnhancements] Reapply same goal -> {runtime.GoalDestination}");
}
if (!GambitEnhancementsPlugin.EnableJumpAssistDuringRoulette.Value)
{
return;
}
runtime.JumpAssistTimer -= num;
if (runtime.JumpAssistTimer <= 0f)
{
runtime.JumpAssistTimer = GambitEnhancementsPlugin.JumpAssistInterval.Value;
InvokeJumpIfStuck(spinny);
if (flag)
{
ForceStuckJump(component4, currentPosition, runtime.GoalDestination);
}
}
}
private static void ClearStun(EnemySpinny spinny)
{
//IL_003e: Unknown result type (might be due to invalid IL or missing references)
//IL_0045: Invalid comparison between Unknown and I4
//IL_0051: Unknown result type (might be due to invalid IL or missing references)
Enemy component = ((Component)spinny).GetComponent<Enemy>();
EnemyStateStunned component2 = ((Component)spinny).GetComponent<EnemyStateStunned>();
if (!((Object)(object)component2 == (Object)null))
{
component2.OverrideDisable(0.3f);
component2.stunTimer = 0f;
if ((Object)(object)component != (Object)null && (int)component.CurrentState == 9)
{
component.CurrentState = (EnemyState)2;
}
}
}
private static void ReleaseGrab(EnemySpinny spinny, SpinnyRuntimeState runtime)
{
RestoreGrabSettings(spinny, runtime);
runtime.GoalActive = false;
runtime.PersistCarryActive = false;
runtime.StuckTimer = 0f;
runtime.JumpAssistTimer = 0f;
runtime.SameGoalReapplyTimer = 0f;
spinny.playerTarget = null;
if (SpinnyMethodUpdateState != null)
{
try
{
SpinnyMethodUpdateState.Invoke(spinny, new object[1] { (object)(State)12 });
}
catch (Exception arg)
{
GambitEnhancementsPlugin.Verbose($"[GambitEnhancements] UpdateState invoke failed: {arg}");
}
}
GambitEnhancementsPlugin.Verbose("[GambitEnhancements] Grab released because target distance exceeded threshold");
}
private static bool IsTargetTooFar(EnemySpinny spinny)
{
//IL_001a: Unknown result type (might be due to invalid IL or missing references)
//IL_001f: Unknown result type (might be due to invalid IL or missing references)
//IL_002b: Unknown result type (might be due to invalid IL or missing references)
//IL_0030: Unknown result type (might be due to invalid IL or missing references)
//IL_003c: Unknown result type (might be due to invalid IL or missing references)
//IL_003d: Unknown result type (might be due to invalid IL or missing references)
//IL_003e: Unknown result type (might be due to invalid IL or missing references)
//IL_0043: Unknown result type (might be due to invalid IL or missing references)
if ((Object)(object)spinny.playerTarget == (Object)null)
{
return false;
}
Vector3 currentPosition = GetCurrentPosition(spinny);
Vector3 position = ((Component)spinny.playerTarget).transform.position;
float value = GambitEnhancementsPlugin.ReleaseGrabDistance.Value;
Vector3 val = currentPosition - position;
float sqrMagnitude = ((Vector3)(ref val)).sqrMagnitude;
return sqrMagnitude > value * value;
}
private static Vector3 GetFarthestPointFromPosition(Vector3 startPosition)
{
//IL_001b: 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)
//IL_0026: Unknown result type (might be due to invalid IL or missing references)
//IL_002b: Unknown result type (might be due to invalid IL or missing references)
//IL_0030: 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_00f4: Unknown result type (might be due to invalid IL or missing references)
//IL_00f5: 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_0104: Unknown result type (might be due to invalid IL or missing references)
//IL_0109: 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_00f0: Unknown result type (might be due to invalid IL or missing references)
//IL_008c: 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)
//IL_0099: Unknown result type (might be due to invalid IL or missing references)
//IL_009e: Unknown result type (might be due to invalid IL or missing references)
List<LevelPoint> list = SemiFunc.LevelPointsGetAll();
if (list == null || list.Count == 0)
{
return startPosition + Vector3.forward * 5f;
}
float num = -1f;
LevelPoint val = null;
foreach (LevelPoint item in list)
{
if (!((Object)(object)item == (Object)null) && (!((Object)(object)item.Room != (Object)null) || !item.Room.Truck))
{
Vector3 val2 = startPosition - ((Component)item).transform.position;
float sqrMagnitude = ((Vector3)(ref val2)).sqrMagnitude;
if (sqrMagnitude > num)
{
num = sqrMagnitude;
val = item;
}
}
}
if ((Object)(object)val != (Object)null)
{
return ((Component)val).transform.position;
}
return startPosition + Vector3.forward * 5f;
}
private static bool IsGoalReached(EnemySpinny spinny, SpinnyRuntimeState runtime)
{
//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_0013: Unknown result type (might be due to invalid IL or missing references)
//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)
//IL_001f: Unknown result type (might be due to invalid IL or missing references)
Vector3 currentPosition = GetCurrentPosition(spinny);
float value = GambitEnhancementsPlugin.GoalReachedDistance.Value;
Vector3 val = currentPosition - runtime.GoalDestination;
float sqrMagnitude = ((Vector3)(ref val)).sqrMagnitude;
return sqrMagnitude <= value * value;
}
private static Vector3 GetCurrentPosition(EnemySpinny spinny)
{
//IL_0051: Unknown result type (might be due to invalid IL or missing references)
//IL_0056: Unknown result type (might be due to invalid IL or missing references)
//IL_0043: Unknown result type (might be due to invalid IL or missing references)
//IL_0048: Unknown result type (might be due to invalid IL or missing references)
//IL_0059: Unknown result type (might be due to invalid IL or missing references)
Enemy component = ((Component)spinny).GetComponent<Enemy>();
if ((Object)(object)component != (Object)null && (Object)(object)component.Rigidbody != (Object)null && (Object)(object)((Component)component.Rigidbody).transform != (Object)null)
{
return ((Component)component.Rigidbody).transform.position;
}
return ((Component)spinny).transform.position;
}
private static void ApplyGrabSettings(EnemySpinny spinny, SpinnyRuntimeState runtime)
{
if (!runtime.GrabValuesStored)
{
runtime.OriginalFollowForceMultiplier = spinny._followForceMultiplier;
runtime.OriginalFollowForceGrabbedMultiplier = GetPrivateFloat(spinny, SpinnyFieldFollowForceGrabbedMultiplier, 0.025f);
runtime.OriginalLockLerpSpeed = GetPrivateFloat(spinny, SpinnyFieldLockLerpSpeed, 1f);
runtime.GrabValuesStored = true;
}
spinny._followForceMultiplier = GambitEnhancementsPlugin.RouletteFollowForceMultiplier.Value;
SetPrivateFloat(spinny, SpinnyFieldFollowForceGrabbedMultiplier, GambitEnhancementsPlugin.RouletteFollowForceGrabbedMultiplier.Value);
SetPrivateFloat(spinny, SpinnyFieldLockLerpSpeed, GambitEnhancementsPlugin.RouletteLockLerpSpeed.Value);
}
private static void RestoreGrabSettings(EnemySpinny spinny, SpinnyRuntimeState runtime)
{
if (runtime.GrabValuesStored)
{
spinny._followForceMultiplier = runtime.OriginalFollowForceMultiplier;
SetPrivateFloat(spinny, SpinnyFieldFollowForceGrabbedMultiplier, runtime.OriginalFollowForceGrabbedMultiplier);
SetPrivateFloat(spinny, SpinnyFieldLockLerpSpeed, runtime.OriginalLockLerpSpeed);
runtime.GrabValuesStored = false;
}
}
private static void InvokeJumpIfStuck(EnemySpinny spinny)
{
if (SpinnyMethodJumpIfStuck == null)
{
return;
}
try
{
SpinnyMethodJumpIfStuck.Invoke(spinny, new object[1] { true });
}
catch (Exception arg)
{
GambitEnhancementsPlugin.Verbose($"[GambitEnhancements] JumpIfStuck invoke failed: {arg}");
}
}
private static void InvokeLockInPlayer(EnemySpinny spinny, bool horizontalPull, bool fixedUpdate)
{
if (SpinnyMethodLockInPlayer == null)
{
return;
}
try
{
SpinnyMethodLockInPlayer.Invoke(spinny, new object[2] { horizontalPull, fixedUpdate });
}
catch (Exception arg)
{
GambitEnhancementsPlugin.Verbose($"[GambitEnhancements] LockInPlayer invoke failed: {arg}");
}
}
private static void ForceStuckJump(EnemyJump enemyJump, Vector3 currentPosition, Vector3 destination)
{
//IL_0022: Unknown result type (might be due to invalid IL or missing references)
//IL_0023: Unknown result type (might be due to invalid IL or missing references)
//IL_0024: Unknown result type (might be due to invalid IL or missing references)
//IL_0029: 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_0040: Unknown result type (might be due to invalid IL or missing references)
//IL_0045: Unknown result type (might be due to invalid IL or missing references)
if (!((Object)(object)enemyJump == (Object)null) && !GetPrivateBool(enemyJump, EnemyJumpFieldJumping, fallback: false))
{
Vector3 val = destination - currentPosition;
if (((Vector3)(ref val)).sqrMagnitude <= 0.0001f)
{
val = Vector3.forward;
}
enemyJump.StuckTrigger(((Vector3)(ref val)).normalized);
}
}
private static bool IsLikelyStuck(Vector3 currentPosition, Rigidbody rb, SpinnyRuntimeState runtime)
{
//IL_003a: Unknown result type (might be due to invalid IL or missing references)
//IL_003c: Unknown result type (might be due to invalid IL or missing references)
//IL_0041: Unknown result type (might be due to invalid IL or missing references)
//IL_0046: Unknown result type (might be due to invalid IL or missing references)
float value = GambitEnhancementsPlugin.StuckVelocityThreshold.Value;
float num = value * value;
float velocitySqrMagnitude = GetVelocitySqrMagnitude(rb);
if (velocitySqrMagnitude >= num)
{
return false;
}
float value2 = GambitEnhancementsPlugin.StuckDistanceThreshold.Value;
float num2 = value2 * value2;
Vector3 val = currentPosition - runtime.GoalDestination;
float sqrMagnitude = ((Vector3)(ref val)).sqrMagnitude;
return sqrMagnitude > num2;
}
private static Rigidbody GetEnemyRigidBody(EnemyRigidbody enemyRigidbody)
{
if ((Object)(object)enemyRigidbody == (Object)null || EnemyRigidbodyFieldRb == null)
{
return null;
}
try
{
object? value = EnemyRigidbodyFieldRb.GetValue(enemyRigidbody);
return (Rigidbody)((value is Rigidbody) ? value : null);
}
catch
{
return null;
}
}
private static float GetVelocitySqrMagnitude(Rigidbody rb)
{
//IL_0016: Unknown result type (might be due to invalid IL or missing references)
//IL_001b: Unknown result type (might be due to invalid IL or missing references)
if ((Object)(object)rb == (Object)null)
{
return 0f;
}
Vector3 velocity = rb.velocity;
return ((Vector3)(ref velocity)).sqrMagnitude;
}
private static bool CanControl(EnemySpinny spinny)
{
if (!GambitEnhancementsPlugin.ModEnabled())
{
return false;
}
if (!SemiFunc.IsMasterClientOrSingleplayer())
{
return false;
}
if ((Object)(object)spinny == (Object)null)
{
return false;
}
return true;
}
private static void RestoreAndDisable(EnemySpinny spinny)
{
if (RuntimeStates.TryGetValue(((Object)spinny).GetInstanceID(), out SpinnyRuntimeState value))
{
RestoreGrabSettings(spinny, value);
value.GoalActive = false;
value.GoalCaptured = false;
value.PersistCarryActive = false;
value.WasRouletteGoingOn = false;
value.StuckTimer = 0f;
value.JumpAssistTimer = 0f;
value.SameGoalReapplyTimer = 0f;
}
}
private static SpinnyRuntimeState GetRuntime(EnemySpinny spinny)
{
int instanceID = ((Object)spinny).GetInstanceID();
if (!RuntimeStates.TryGetValue(instanceID, out SpinnyRuntimeState value))
{
value = new SpinnyRuntimeState();
RuntimeStates[instanceID] = value;
}
return value;
}
private static float GetPrivateFloat(object instance, FieldInfo fieldInfo, float fallback)
{
if (instance == null || fieldInfo == null)
{
return fallback;
}
try
{
object value = fieldInfo.GetValue(instance);
if (value is float)
{
return (float)value;
}
}
catch
{
}
return fallback;
}
private static void SetPrivateFloat(object instance, FieldInfo fieldInfo, float value)
{
if (instance == null || fieldInfo == null)
{
return;
}
try
{
fieldInfo.SetValue(instance, value);
}
catch (Exception arg)
{
GambitEnhancementsPlugin.Verbose($"[GambitEnhancements] Failed to set private float: {arg}");
}
}
private static bool GetPrivateBool(object instance, FieldInfo fieldInfo, bool fallback)
{
if (instance == null || fieldInfo == null)
{
return fallback;
}
try
{
object value = fieldInfo.GetValue(instance);
if (value is bool)
{
return (bool)value;
}
}
catch
{
}
return fallback;
}
}
[HarmonyPatch(typeof(EnemySpinny), "Update")]
internal static class EnemySpinnyUpdatePatch
{
private static void Postfix(EnemySpinny __instance)
{
GambitEnhancementsCore.PostUpdate(__instance);
}
}
[HarmonyPatch(typeof(EnemySpinny), "FixedUpdate")]
internal static class EnemySpinnyFixedUpdatePatch
{
private static void Postfix(EnemySpinny __instance)
{
GambitEnhancementsCore.PostFixedUpdate(__instance);
}
}
[HarmonyPatch(typeof(EnemyStateStunned), "Set")]
internal static class EnemyStateStunnedSetPatch
{
private static bool Prefix(EnemyStateStunned __instance, float time)
{
if (!GambitEnhancementsCore.ShouldBlockStun(__instance))
{
return true;
}
__instance.OverrideDisable(Mathf.Max(0.3f, time));
__instance.stunTimer = 0f;
GambitEnhancementsPlugin.Verbose("[GambitEnhancements] Blocked stun Set() during roulette");
return false;
}
}
[HarmonyPatch(typeof(EnemyStateStunned), "Update")]
internal static class EnemyStateStunnedUpdatePatch
{
private static void Prefix(EnemyStateStunned __instance)
{
//IL_0039: Unknown result type (might be due to invalid IL or missing references)
//IL_0040: Invalid comparison between Unknown and I4
//IL_004c: Unknown result type (might be due to invalid IL or missing references)
if (GambitEnhancementsCore.ShouldBlockStun(__instance))
{
__instance.OverrideDisable(0.3f);
__instance.stunTimer = 0f;
Enemy component = ((Component)__instance).GetComponent<Enemy>();
if ((Object)(object)component != (Object)null && (int)component.CurrentState == 9)
{
component.CurrentState = (EnemyState)2;
}
}
}
}
}