using System;
using System.Diagnostics;
using System.IO;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using HarmonyLib;
using Microsoft.CodeAnalysis;
using Pigeon.Movement;
using UnityEngine;
[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETFramework,Version=v4.7.2", FrameworkDisplayName = ".NET Framework 4.7.2")]
[assembly: AssemblyCompany("Coruscnium")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyDescription("Controller aim assist for Mycopunk: COD-Zombies-style tracking magnetism plus a lighter slowdown-only mode.")]
[assembly: AssemblyFileVersion("1.0.1.0")]
[assembly: AssemblyInformationalVersion("1.0.1.0")]
[assembly: AssemblyProduct("AimAssist")]
[assembly: AssemblyTitle("AimAssist")]
[assembly: AssemblyVersion("1.0.1.0")]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
[CompilerGenerated]
[Embedded]
internal sealed class EmbeddedAttribute : Attribute
{
}
}
namespace System.Runtime.CompilerServices
{
[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 AimAssist
{
[BepInPlugin("coruscnium.aimassist", "AimAssist", "1.0.1.0")]
[BepInProcess("Mycopunk.exe")]
[BepInDependency(/*Could not decode attribute arguments.*/)]
[MycoMod(/*Could not decode attribute arguments.*/)]
public class Plugin : BaseUnityPlugin
{
internal static ManualLogSource Logger;
private static ConfigEntry<bool> _enabledCfg;
private static ConfigEntry<float> _strengthCfg;
private static ConfigEntry<float> _distanceCfg;
private static bool _enabled = true;
private static float _strength = 100f;
private static float _distance = 60f;
private const float SlowdownStrengthFull = 70f;
private const float TrackStrengthFull = 50f;
private const float SnapStrengthFull = 40f;
private const float SlowdownCone = 7f;
private const float SnapCone = 8f;
private const float MaxTrackGain = 10f;
private const float MaxSnapGain = 30f;
private const float SnapDuration = 0.18f;
private const float TrackReleaseDuration = 0.35f;
private const float FullStrengthRangeFraction = 0.5f;
private const float SlowdownEngageRate = 25f;
private const float SlowdownReleaseRate = 7f;
private const float MaxAssistDegPerSec = 60f;
private const float AssistFloorDeg = 2f;
private const float AssistDeadzoneDeg = 0.5f;
private static FieldInfo _playerMovementField;
private static bool _targetMaskResolved;
private static int _targetMask = -5;
private static bool _prevAimPressed;
private static ISelectable _snapTarget;
private static float _snapElapsed;
private static float _slowFactor = 1f;
private static int _slowFrame = -1;
private static ISelectable _trackTarget;
private static float _trackEngage;
private static Vector3 _trackLastPoint;
private static readonly Collider[] _overlapBuffer = (Collider[])(object)new Collider[64];
private static FileSystemWatcher _configWatcher;
private static volatile bool _pendingConfigReload;
private void Awake()
{
//IL_0068: Unknown result type (might be due to invalid IL or missing references)
//IL_0072: Expected O, but got Unknown
//IL_00a5: Unknown result type (might be due to invalid IL or missing references)
//IL_00af: Expected O, but got Unknown
Logger = ((BaseUnityPlugin)this).Logger;
Logger.LogInfo((object)"AimAssist loading...");
_enabledCfg = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "Enabled", true, "Master on/off for controller aim assist (gamepad only). When on, it combines look-speed slowdown near a target with COD-Zombies-style magnetism (tracking once your reticle is on a target, plus an eased snap when you press Aim).");
_strengthCfg = ((BaseUnityPlugin)this).Config.Bind<float>("General", "Strength", 100f, new ConfigDescription("Overall aim-assist strength, as a percent of the default feel (100 = default, lower = gentler, 0 = effectively off). Cones and the slowdown/tracking/snap balance are fixed at sensible defaults.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 100f), Array.Empty<object>()));
_distanceCfg = ((BaseUnityPlugin)this).Config.Bind<float>("General", "Distance", 60f, new ConfigDescription("Range (metres) the assist reaches. Targets beyond this get no help; the assist is full-strength up close and tapers to nothing at this distance. Higher = pushes the taper further out.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(10f, 150f), Array.Empty<object>()));
CacheConfig();
((BaseUnityPlugin)this).Config.Save();
_enabledCfg.SettingChanged += delegate
{
CacheConfig();
};
_strengthCfg.SettingChanged += delegate
{
CacheConfig();
};
_distanceCfg.SettingChanged += delegate
{
CacheConfig();
};
Harmony.CreateAndPatchAll(typeof(Plugin), (string)null);
try
{
_configWatcher = new FileSystemWatcher(Paths.ConfigPath, "coruscnium.aimassist.cfg")
{
NotifyFilter = (NotifyFilters.FileName | NotifyFilters.Size | NotifyFilters.LastWrite),
EnableRaisingEvents = true
};
_configWatcher.Changed += OnConfigFileChanged;
_configWatcher.Created += OnConfigFileChanged;
_configWatcher.Renamed += OnConfigFileChanged;
}
catch (Exception ex)
{
Logger.LogWarning((object)("Could not start config file watcher: " + ex.Message));
}
Logger.LogInfo((object)$"AimAssist loaded. Enabled: {_enabled}");
}
private static void CacheConfig()
{
_enabled = _enabledCfg.Value;
_strength = _strengthCfg.Value;
_distance = _distanceCfg.Value;
}
private void OnConfigFileChanged(object sender, FileSystemEventArgs e)
{
_pendingConfigReload = true;
}
private void Update()
{
if (_pendingConfigReload)
{
_pendingConfigReload = false;
try
{
((BaseUnityPlugin)this).Config.Reload();
}
catch (Exception ex)
{
Logger.LogError((object)("Config reload failed: " + ex.Message));
}
CacheConfig();
}
}
private void OnDestroy()
{
if (_configWatcher != null)
{
_configWatcher.EnableRaisingEvents = false;
_configWatcher.Dispose();
_configWatcher = null;
}
}
private static bool GamepadActiveAndPlaying()
{
//IL_0000: Unknown result type (might be due to invalid IL or missing references)
if ((int)PlayerInput.Device == 0)
{
return false;
}
if (!PlayerInput.IsPlayerEnabled)
{
return false;
}
Player localPlayer = Player.LocalPlayer;
if ((Object)(object)localPlayer != (Object)null)
{
return localPlayer.IsAlive;
}
return false;
}
private static int TargetMask()
{
//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)
if (_targetMaskResolved)
{
return _targetMask;
}
_targetMaskResolved = true;
try
{
Highlighter instance = Highlighter.Instance;
if ((Object)(object)instance != (Object)null)
{
FieldInfo fieldInfo = AccessTools.Field(typeof(Highlighter), "targetLayerMask");
if (fieldInfo != null && fieldInfo.GetValue(instance) is LayerMask val)
{
_targetMask = ((LayerMask)(ref val)).value;
}
}
}
catch (Exception ex)
{
Logger.LogWarning((object)("targetLayerMask reflection failed, using default: " + ex.Message));
}
return _targetMask;
}
private static bool TryGetAimPoint(ISelectable sel, out Vector3 point)
{
//IL_0001: Unknown result type (might be due to invalid IL or missing references)
//IL_0031: Unknown result type (might be due to invalid IL or missing references)
//IL_0036: Unknown result type (might be due to invalid IL or missing references)
//IL_0039: Unknown result type (might be due to invalid IL or missing references)
//IL_003e: 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_0069: 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_006e: Unknown result type (might be due to invalid IL or missing references)
point = default(Vector3);
if (sel == null || (Object)(object)sel.transform == (Object)null)
{
return false;
}
Collider componentInChildren = ((Component)sel.transform).GetComponentInChildren<Collider>();
if ((Object)(object)componentInChildren != (Object)null)
{
Bounds bounds = componentInChildren.bounds;
point = ((Bounds)(ref bounds)).center;
return true;
}
IFollowable val = (IFollowable)(object)((sel is IFollowable) ? sel : null);
point = ((val != null) ? sel.transform.TransformPoint(val.HealthbarPosition) : sel.transform.position);
return true;
}
private static bool IsLiveTarget(ISelectable sel)
{
if (sel != null)
{
ITarget val = (ITarget)(object)((sel is ITarget) ? sel : null);
if (val != null && val.IsAlive)
{
return !(sel is Player);
}
}
return false;
}
private static float DistanceFalloff(float dist)
{
if (dist >= _distance)
{
return 0f;
}
float num = _distance * 0.5f;
if (dist <= num)
{
return 1f;
}
float num2 = (dist - num) / (_distance - num);
return 1f - Mathf.SmoothStep(0f, 1f, num2);
}
private static float PrecisionGate(float errorAngle)
{
if (errorAngle <= 0.5f)
{
return 0f;
}
if (errorAngle >= 2f)
{
return 1f;
}
return Mathf.SmoothStep(0f, 1f, (errorAngle - 0.5f) / 1.5f);
}
private static bool TryFindTargetInCone(Vector3 camPos, Vector3 camFwd, float coneDeg, float range, out ISelectable best, out Vector3 bestPoint)
{
//IL_0006: Unknown result type (might be due to invalid IL or missing references)
//IL_0012: Unknown result type (might be due to invalid IL or missing references)
//IL_005d: Unknown result type (might be due to invalid IL or missing references)
//IL_005f: Unknown result type (might be due to invalid IL or missing references)
//IL_0060: Unknown result type (might be due to invalid IL or missing references)
//IL_0065: Unknown result type (might be due to invalid IL or missing references)
//IL_007e: 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_008d: Unknown result type (might be due to invalid IL or missing references)
//IL_008e: Unknown result type (might be due to invalid IL or missing references)
//IL_00c7: Unknown result type (might be due to invalid IL or missing references)
//IL_00c9: Unknown result type (might be due to invalid IL or missing references)
best = null;
bestPoint = default(Vector3);
int num = TargetMask();
int num2 = Physics.OverlapSphereNonAlloc(camPos, range, _overlapBuffer, num, (QueryTriggerInteraction)2);
float num3 = coneDeg;
RaycastHit val3 = default(RaycastHit);
for (int i = 0; i < num2; i++)
{
Collider val = _overlapBuffer[i];
if ((Object)(object)val == (Object)null)
{
continue;
}
ISelectable selectable = IDamageSource.GetSelectable((Component)(object)val);
if (!IsLiveTarget(selectable) || !TryGetAimPoint(selectable, out var point))
{
continue;
}
Vector3 val2 = point - camPos;
float magnitude = ((Vector3)(ref val2)).magnitude;
if (!(magnitude < 0.01f) && !(magnitude > range))
{
float num4 = Vector3.Angle(camFwd, val2);
if (!(num4 >= num3) && (!Physics.Linecast(camPos, point, ref val3, -5, (QueryTriggerInteraction)1) || IDamageSource.GetSelectable((Component)(object)((RaycastHit)(ref val3)).collider) == selectable || !(((RaycastHit)(ref val3)).distance < magnitude - 0.5f)))
{
num3 = num4;
best = selectable;
bestPoint = point;
}
}
}
return best != null;
}
private static void AimError(Vector3 camPos, Vector3 camFwd, Vector3 target, out float yawErr, out float pitchDeltaXLook, out float errorAngle)
{
//IL_0017: Unknown result type (might be due to invalid IL or missing references)
//IL_0018: Unknown result type (might be due to invalid IL or missing references)
//IL_0019: Unknown result type (might be due to invalid IL or missing references)
//IL_001e: 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_0032: Unknown result type (might be due to invalid IL or missing references)
//IL_0037: Unknown result type (might be due to invalid IL or missing references)
//IL_003a: Unknown result type (might be due to invalid IL or missing references)
//IL_003b: Unknown result type (might be due to invalid IL or missing references)
//IL_0044: Unknown result type (might be due to invalid IL or missing references)
//IL_004f: 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_0067: Unknown result type (might be due to invalid IL or missing references)
//IL_009c: 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_008f: Unknown result type (might be due to invalid IL or missing references)
//IL_0090: Unknown result type (might be due to invalid IL or missing references)
//IL_0091: Unknown result type (might be due to invalid IL or missing references)
yawErr = 0f;
pitchDeltaXLook = 0f;
errorAngle = 0f;
Vector3 val = target - camPos;
float magnitude = ((Vector3)(ref val)).magnitude;
if (!(magnitude < 0.0001f))
{
val /= magnitude;
errorAngle = Vector3.Angle(camFwd, val);
Vector3 val2 = default(Vector3);
((Vector3)(ref val2))..ctor(camFwd.x, 0f, camFwd.z);
Vector3 val3 = default(Vector3);
((Vector3)(ref val3))..ctor(val.x, 0f, val.z);
if (((Vector3)(ref val2)).sqrMagnitude > 1E-06f && ((Vector3)(ref val3)).sqrMagnitude > 1E-06f)
{
yawErr = Vector3.SignedAngle(val2, val3, Vector3.up);
}
float num = Mathf.Asin(Mathf.Clamp(camFwd.y, -1f, 1f)) * 57.29578f;
float num2 = Mathf.Asin(Mathf.Clamp(val.y, -1f, 1f)) * 57.29578f;
pitchDeltaXLook = num - num2;
}
}
private static Transform PlayerMovementTransform(PlayerLook look)
{
if (_playerMovementField == null)
{
_playerMovementField = AccessTools.Field(typeof(PlayerLook), "playerMovement");
}
object? obj = _playerMovementField?.GetValue(look);
object? obj2 = ((obj is Component) ? obj : null);
if (obj2 == null)
{
return null;
}
return ((Component)obj2).transform;
}
[HarmonyPatch(typeof(PlayerLook), "SlowGamepadLookSpeed")]
[HarmonyPrefix]
private static bool SlowGamepadLookSpeed_Prefix(ref bool __result)
{
if (_enabled && _strength > 0f)
{
__result = false;
return false;
}
return true;
}
[HarmonyPatch(typeof(PlayerLook), "GetMouseDelta")]
[HarmonyPostfix]
private static void GetMouseDelta_Postfix(PlayerLook __instance, ref Vector2 __result)
{
//IL_0117: Unknown result type (might be due to invalid IL or missing references)
//IL_0121: 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_005d: 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_007e: Unknown result type (might be due to invalid IL or missing references)
//IL_0083: 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)
if (!_enabled || _strength <= 0f || !GamepadActiveAndPlaying())
{
_slowFactor = 1f;
return;
}
Camera camera = __instance.Camera;
if ((Object)(object)camera == (Object)null)
{
return;
}
if (Time.frameCount != _slowFrame)
{
_slowFrame = Time.frameCount;
Transform transform = ((Component)camera).transform;
float num = 1f;
if (TryFindTargetInCone(transform.position, transform.forward, 7f, _distance, out var _, out var bestPoint))
{
float num2 = Vector3.Angle(transform.forward, bestPoint - transform.position);
float num3 = Mathf.Clamp01(1f - num2 / 7f);
float num4 = 0.7f * (_strength / 100f);
num = 1f - num4 * num3;
}
float num5 = Mathf.Min(Time.unscaledDeltaTime, 0.1f);
float num6 = ((num < _slowFactor) ? 25f : 7f);
_slowFactor += (num - _slowFactor) * (1f - Mathf.Exp((0f - num6) * num5));
}
__result *= _slowFactor;
}
[HarmonyPatch(typeof(PlayerLook), "HandleCameraControl")]
[HarmonyPostfix]
private static void HandleCameraControl_Postfix(PlayerLook __instance)
{
//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_0049: Unknown result type (might be due to invalid IL or missing references)
//IL_004e: Unknown result type (might be due to invalid IL or missing references)
//IL_0071: Unknown result type (might be due to invalid IL or missing references)
//IL_0076: 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_009c: Unknown result type (might be due to invalid IL or missing references)
//IL_0136: Unknown result type (might be due to invalid IL or missing references)
//IL_0137: 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_0166: Unknown result type (might be due to invalid IL or missing references)
//IL_0167: Unknown result type (might be due to invalid IL or missing references)
//IL_0344: Unknown result type (might be due to invalid IL or missing references)
//IL_0355: Unknown result type (might be due to invalid IL or missing references)
//IL_035a: Unknown result type (might be due to invalid IL or missing references)
//IL_0266: Unknown result type (might be due to invalid IL or missing references)
//IL_0267: Unknown result type (might be due to invalid IL or missing references)
//IL_02a4: Unknown result type (might be due to invalid IL or missing references)
//IL_02a5: Unknown result type (might be due to invalid IL or missing references)
//IL_02a6: Unknown result type (might be due to invalid IL or missing references)
//IL_025f: Unknown result type (might be due to invalid IL or missing references)
//IL_0261: Unknown result type (might be due to invalid IL or missing references)
if (!_enabled || !GamepadActiveAndPlaying())
{
_prevAimPressed = false;
_snapTarget = null;
_trackTarget = null;
_trackEngage = 0f;
return;
}
Camera camera = __instance.Camera;
if ((Object)(object)camera == (Object)null)
{
return;
}
Transform transform = ((Component)camera).transform;
Vector3 position = transform.position;
Vector3 forward = transform.forward;
float num = Mathf.Min(Time.deltaTime, 0.1f);
float num2 = _strength / 100f;
PlayerActions player = PlayerInput.Controls.Player;
bool flag = ((PlayerActions)(ref player)).Aim.IsPressed();
if (num2 > 0f && flag && !_prevAimPressed && TryFindTargetInCone(position, forward, 8f, _distance, out var best, out var _))
{
_snapTarget = best;
_snapElapsed = 0f;
}
_prevAimPressed = flag;
float num3 = 0f;
float num4 = 0f;
bool flag2 = false;
if (_snapTarget != null)
{
if (IsLiveTarget(_snapTarget) && TryGetAimPoint(_snapTarget, out var point))
{
_snapElapsed += num;
float num5 = Mathf.Clamp01(_snapElapsed / 0.18f);
float num6 = Mathf.SmoothStep(0f, 1f, num5);
float num7 = DistanceFalloff(Vector3.Distance(position, point));
float num8 = 12f * num2 * num7 * num6;
float num9 = 1f - Mathf.Exp((0f - num8) * num);
AimError(position, forward, point, out var yawErr, out var pitchDeltaXLook, out var errorAngle);
float num10 = num9 * PrecisionGate(errorAngle);
num3 += yawErr * num10;
num4 += pitchDeltaXLook * num10;
flag2 = true;
if (num5 >= 1f)
{
_snapTarget = null;
}
}
else
{
_snapTarget = null;
}
}
if (!flag2 && num2 > 0f)
{
ISelectable val = (((Object)(object)Highlighter.Instance != (Object)null) ? Highlighter.Instance.SelectedTarget : null);
if (IsLiveTarget(val))
{
_trackTarget = val;
_trackEngage = 1f;
}
else if (_trackTarget != null)
{
_trackEngage -= num / 0.35f;
if (_trackEngage <= 0f)
{
_trackTarget = null;
_trackEngage = 0f;
}
}
if (_trackTarget != null && _trackEngage > 0f)
{
if (IsLiveTarget(_trackTarget) && TryGetAimPoint(_trackTarget, out var point2))
{
_trackLastPoint = point2;
}
float num11 = DistanceFalloff(Vector3.Distance(position, _trackLastPoint));
if (num11 > 0f)
{
float num12 = 5f * num2 * num11 * _trackEngage;
float num13 = 1f - Mathf.Exp((0f - num12) * num);
AimError(position, forward, _trackLastPoint, out var yawErr2, out var pitchDeltaXLook2, out var errorAngle2);
float num14 = num13 * PrecisionGate(errorAngle2);
num3 += yawErr2 * num14;
num4 += pitchDeltaXLook2 * num14;
}
}
}
if (num3 == 0f && num4 == 0f)
{
return;
}
float num15 = 60f * num;
float num16 = Mathf.Sqrt(num3 * num3 + num4 * num4);
if (num16 > num15 && num16 > 1E-06f)
{
float num17 = num15 / num16;
num3 *= num17;
num4 *= num17;
}
if (num3 != 0f)
{
Transform val2 = PlayerMovementTransform(__instance);
if ((Object)(object)val2 != (Object)null)
{
val2.localRotation *= Quaternion.Euler(0f, num3, 0f);
}
}
if (num4 != 0f)
{
__instance.XLookRotation = Mathf.Clamp(__instance.XLookRotation + num4, -89f, 89f);
}
}
}
}