using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using Animancer;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using HarmonyLib;
using Microsoft.CodeAnalysis;
using Pigeon.Math;
using Pigeon.Movement;
using TMPro;
using Unity.Netcode;
using UnityEngine;
using UnityEngine.UI;
[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: IgnoresAccessChecksTo("Assembly-CSharp")]
[assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")]
[assembly: AssemblyCompany("Sparroh")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("1.1.0.0")]
[assembly: AssemblyInformationalVersion("1.1.0")]
[assembly: AssemblyProduct("AlwaysPracticeMakesPerfect")]
[assembly: AssemblyTitle("AlwaysPracticeMakesPerfect")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.1.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.Module, AllowMultiple = false, Inherited = false)]
internal sealed class RefSafetyRulesAttribute : Attribute
{
public readonly int Version;
public RefSafetyRulesAttribute(int P_0)
{
Version = P_0;
}
}
}
public static class ConfigManager
{
private const float DebounceSeconds = 0.25f;
private const float DefaultWindowDuration = 0.45f;
private const float DefaultReloadSpeedMultiplier = 2.5f;
private static ConfigFile config;
private static ManualLogSource logger;
private static FileSystemWatcher configWatcher;
private static volatile bool reloadPending;
private static float lastReloadTime;
public static ConfigEntry<bool> EnablePracticeMakesPerfect { get; private set; }
public static ConfigEntry<float> WindowDuration { get; private set; }
public static ConfigEntry<float> ReloadSpeedMultiplier { get; private set; }
public static void Initialize(ConfigFile configFile, ManualLogSource log)
{
config = configFile;
logger = log;
EnablePracticeMakesPerfect = config.Bind<bool>("General", "Enable Practice Makes Perfect", true, "Enables the Practice Makes Perfect reload timing mini-game on all weapons.");
WindowDuration = config.Bind<float>("General", "Window Duration", 0.45f, "Width of the timing window during reload (seconds of animation time). Vanilla upgrade uses a short window.");
ReloadSpeedMultiplier = config.Bind<float>("General", "Reload Speed Multiplier", 2.5f, "Reload animation speed multiplier applied when you press Fire inside the timing window.");
try
{
SetupFileWatcher();
}
catch (Exception ex)
{
logger.LogError((object)("Error setting up config file watcher: " + ex.Message));
}
}
public static void Tick()
{
if (!reloadPending || Time.unscaledTime - lastReloadTime < 0.25f)
{
return;
}
reloadPending = false;
lastReloadTime = Time.unscaledTime;
try
{
config.Reload();
logger.LogInfo((object)($"Config reloaded. Enable={EnablePracticeMakesPerfect.Value}, " + $"Window={WindowDuration.Value}, Speed={ReloadSpeedMultiplier.Value}"));
}
catch (Exception ex)
{
logger.LogError((object)("Error reloading config: " + ex.Message));
}
}
public static void Dispose()
{
if (configWatcher != null)
{
configWatcher.EnableRaisingEvents = false;
configWatcher.Changed -= OnConfigFileChanged;
configWatcher.Created -= OnConfigFileChanged;
configWatcher.Renamed -= OnConfigFileChanged;
configWatcher.Dispose();
configWatcher = null;
}
}
private static void SetupFileWatcher()
{
configWatcher = new FileSystemWatcher(Paths.ConfigPath, "sparroh.alwayspracticemakesperfect.cfg");
configWatcher.NotifyFilter = NotifyFilters.FileName | NotifyFilters.Size | NotifyFilters.LastWrite;
configWatcher.Changed += OnConfigFileChanged;
configWatcher.Created += OnConfigFileChanged;
configWatcher.Renamed += OnConfigFileChanged;
configWatcher.EnableRaisingEvents = true;
}
private static void OnConfigFileChanged(object sender, FileSystemEventArgs e)
{
reloadPending = true;
}
}
internal static class InstaReloadPatches
{
private enum FeedbackKind
{
None,
Success,
Miss
}
private sealed class GenericInstaReloadState
{
public Gun Gun;
public float WindowCenterNormalized;
public bool Active;
public bool Succeeded;
public int LastTickFrame;
}
private static class ListPool<T>
{
private static readonly Stack<List<T>> pool = new Stack<List<T>>();
public static List<T> Get()
{
if (pool.Count <= 0)
{
return new List<T>(8);
}
return pool.Pop();
}
public static void Release(List<T> list)
{
list.Clear();
pool.Push(list);
}
}
private static readonly FieldInfo animatorField = AccessTools.Field(typeof(Gun), "animator");
private static readonly FieldInfo reloadAnimationField = AccessTools.Field(typeof(Gun), "reloadAnimation");
private static readonly FieldInfo hudField = AccessTools.Field(typeof(Gun), "hud");
private static readonly FieldInfo instaReloadTimeField = AccessTools.Field(typeof(FastReloadShotgun), "instaReloadTime");
private static readonly Dictionary<int, GenericInstaReloadState> genericStates = new Dictionary<int, GenericInstaReloadState>();
private static GameObject sharedBarRoot;
private static RectTransform trackRt;
private static RectTransform sweetSpotRt;
private static Image sweetSpotImage;
private static RectTransform cursorRt;
private static Image cursorImage;
private static TextMeshProUGUI promptLabel;
private static bool barVisible;
private static float feedbackUntil;
private static FeedbackKind feedbackKind;
private static float lfProgress01;
private static float lfSweetMin01;
private static float lfSweetMax01;
private static bool lfInWindow;
private static bool lfBarArmed;
private static bool loggedMissingAnimator;
private static bool loggedFirstState;
private static bool loggedFirstTick;
private static bool loggedFirstWindow;
private const float BarWidth = 280f;
private const float BarHeight = 14f;
private const float CursorWidth = 3f;
private const float AnchorY = 0.3f;
private static readonly Color TrackColor = new Color(0.05f, 0.07f, 0.1f, 0.72f);
private static readonly Color SweetSpotIdle = new Color(0.98f, 0.82f, 0.35f, 0.45f);
private static readonly Color SweetSpotActive = new Color(0.98f, 0.82f, 0.35f, 0.92f);
private static readonly Color SweetSpotSuccess = new Color(0.2f, 0.9f, 0.45f, 0.95f);
private static readonly Color SweetSpotMiss = new Color(0.95f, 0.3f, 0.35f, 0.9f);
private static readonly Color CursorIdle = new Color(0.95f, 0.96f, 0.98f, 0.95f);
private static readonly Color CursorActive = new Color(1f, 0.92f, 0.35f, 1f);
private static readonly Color PromptColor = new Color(1f, 0.92f, 0.35f, 1f);
internal static void Cleanup()
{
HideBar();
genericStates.Clear();
if ((Object)(object)sharedBarRoot != (Object)null)
{
Object.Destroy((Object)(object)sharedBarRoot);
sharedBarRoot = null;
trackRt = null;
sweetSpotRt = null;
sweetSpotImage = null;
cursorRt = null;
cursorImage = null;
promptLabel = null;
}
}
internal static void TickTrackedGuns()
{
if (!ConfigManager.EnablePracticeMakesPerfect.Value)
{
if (genericStates.Count > 0)
{
genericStates.Clear();
HideBar();
}
return;
}
TickFeedbackExpiry();
if (genericStates.Count == 0)
{
return;
}
List<int> list = ListPool<int>.Get();
list.AddRange(genericStates.Keys);
for (int i = 0; i < list.Count; i++)
{
int key = list[i];
if (genericStates.TryGetValue(key, out var value) && value.Active && value.LastTickFrame != Time.frameCount)
{
Gun gun = value.Gun;
if ((Object)(object)gun == (Object)null)
{
genericStates.Remove(key);
}
else
{
TickGun(gun);
}
}
}
ListPool<int>.Release(list);
}
private static void TickFeedbackExpiry()
{
if (feedbackKind != FeedbackKind.None && !(Time.unscaledTime < feedbackUntil))
{
feedbackKind = FeedbackKind.None;
HideBar();
}
}
[HarmonyPatch(typeof(FastReloadShotgun), "OnUpgradesEnabled")]
[HarmonyPostfix]
private static void FastReloadShotgun_OnUpgradesEnabled_Postfix(FastReloadShotgun __instance)
{
if (ConfigManager.EnablePracticeMakesPerfect.Value && !((Object)(object)__instance == (Object)null) && ((NetworkBehaviour)__instance).IsOwner)
{
ref LeadFlingerData data = ref __instance.Data;
if (!(data.instaReloadDuration > 0f))
{
data.instaReloadDuration = Mathf.Max(0.01f, ConfigManager.WindowDuration.Value);
data.instaReloadSpeed = Mathf.Max(1f, ConfigManager.ReloadSpeedMultiplier.Value);
((Gun)__instance).SetUpgradeFlag_Owner((GearUpgradeFlags)268435456, true);
}
}
}
[HarmonyPatch(typeof(FastReloadShotgun), "OnReload")]
[HarmonyPostfix]
private static void FastReloadShotgun_OnReload_Postfix(FastReloadShotgun __instance)
{
if (ConfigManager.EnablePracticeMakesPerfect.Value && !((Object)(object)__instance == (Object)null) && ((NetworkBehaviour)__instance).IsOwner)
{
ref LeadFlingerData data = ref __instance.Data;
if (data.instaReloadDuration <= 0f)
{
data.instaReloadDuration = Mathf.Max(0.01f, ConfigManager.WindowDuration.Value);
data.instaReloadSpeed = Mathf.Max(1f, ConfigManager.ReloadSpeedMultiplier.Value);
}
if (!(instaReloadTimeField == null) && !((float)instaReloadTimeField.GetValue(__instance) > 0f))
{
float instaReloadDuration = data.instaReloadDuration;
float num = ((Random)(ref Random.shared)).NextFloat(instaReloadDuration * 0.7f, 0.7f);
instaReloadTimeField.SetValue(__instance, num);
}
}
}
[HarmonyPatch(typeof(FastReloadShotgun), "OnActiveUpdate")]
[HarmonyPrefix]
private static void FastReloadShotgun_OnActiveUpdate_Prefix(FastReloadShotgun __instance)
{
//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)
lfBarArmed = false;
if ((Object)(object)__instance == (Object)null || !((NetworkBehaviour)__instance).IsOwner || !ConfigManager.EnablePracticeMakesPerfect.Value)
{
return;
}
ref LeadFlingerData data = ref __instance.Data;
if (data.instaReloadDuration <= 0f || instaReloadTimeField == null || !((Gun)__instance).Reloading || !((Gun)__instance).Active)
{
return;
}
float num = (float)instaReloadTimeField.GetValue(__instance);
if (num <= 0f)
{
return;
}
object? obj = animatorField?.GetValue(__instance);
PlayerAnimation val = (PlayerAnimation)((obj is PlayerAnimation) ? obj : null);
if ((Object)(object)val == (Object)null)
{
return;
}
AnimancerState currentState = val.CurrentState;
if (currentState == null)
{
return;
}
object obj2 = reloadAnimationField?.GetValue(__instance);
if ((obj2 != null && object.Equals(currentState.Key, obj2)) || !(currentState.NormalizedTime <= 0f) || !(currentState.Time <= 0f))
{
float num2 = currentState.Duration;
if (num2 <= 0.001f)
{
num2 = Mathf.Max(currentState.Length, 0.01f);
}
float time = currentState.Time;
float num3 = data.instaReloadDuration * 0.5f;
float num4 = num2 * num;
lfProgress01 = Mathf.Clamp01(time / num2);
lfSweetMin01 = Mathf.Clamp01((num4 - num3) / num2);
lfSweetMax01 = Mathf.Clamp01((num4 + num3) / num2);
lfInWindow = time >= num4 - num3 && time <= num4 + num3;
lfBarArmed = true;
bool flag = false;
try
{
PlayerActions player = PlayerInput.Controls.Player;
flag = ((PlayerActions)(ref player)).Fire.WasPressedThisFrame();
}
catch
{
}
if (flag)
{
FlashFeedback(lfInWindow ? FeedbackKind.Success : FeedbackKind.Miss);
}
}
}
[HarmonyPatch(typeof(FastReloadShotgun), "OnActiveUpdate")]
[HarmonyPostfix]
private static void FastReloadShotgun_OnActiveUpdate_Postfix(FastReloadShotgun __instance)
{
if ((Object)(object)__instance == (Object)null || !((NetworkBehaviour)__instance).IsOwner)
{
return;
}
SuppressVanillaPopup(__instance);
if (!ConfigManager.EnablePracticeMakesPerfect.Value)
{
if (barVisible && feedbackKind == FeedbackKind.None)
{
HideBar();
}
}
else if (feedbackKind != FeedbackKind.None)
{
UpdateBarVisual(lfProgress01, lfSweetMin01, lfSweetMax01, lfInWindow);
}
else if (!lfBarArmed)
{
if (barVisible)
{
HideBar();
}
}
else
{
UpdateBarVisual(lfProgress01, lfSweetMin01, lfSweetMax01, lfInWindow);
}
}
private static void SuppressVanillaPopup(FastReloadShotgun gun)
{
if (!ConfigManager.EnablePracticeMakesPerfect.Value)
{
return;
}
try
{
object? obj = hudField?.GetValue(gun);
FastShotgunHUD val = (FastShotgunHUD)((obj is FastShotgunHUD) ? obj : null);
if ((Object)(object)val?.InstaReloadPopup != (Object)null && val.InstaReloadPopup.activeSelf)
{
val.InstaReloadPopup.SetActive(false);
}
}
catch
{
}
}
[HarmonyPatch(typeof(Gun), "ForceStartReload")]
[HarmonyPostfix]
private static void Gun_ForceStartReload_Postfix(Gun __instance)
{
if (ConfigManager.EnablePracticeMakesPerfect.Value && !((Object)(object)__instance == (Object)null) && ((NetworkBehaviour)__instance).IsOwner && !(__instance is FastReloadShotgun) && __instance.Reloading)
{
float num = Mathf.Max(0.01f, ConfigManager.WindowDuration.Value);
float num2 = ((Random)(ref Random.shared)).NextFloat(num * 0.7f, 0.7f);
int instanceID = ((Object)__instance).GetInstanceID();
genericStates[instanceID] = new GenericInstaReloadState
{
Gun = __instance,
WindowCenterNormalized = num2,
Active = true,
Succeeded = false,
LastTickFrame = -1
};
feedbackKind = FeedbackKind.None;
if (!loggedFirstState)
{
loggedFirstState = true;
SparrohPlugin.Logger.LogInfo((object)("[PMPA] Generic insta-reload armed for " + ((object)__instance).GetType().Name + " " + $"(center={num2:F3}, window={num:F3})."));
}
}
}
[HarmonyPatch(typeof(Gun), "Update")]
[HarmonyPostfix]
private static void Gun_Update_Postfix(Gun __instance)
{
if (!((Object)(object)__instance == (Object)null) && ((NetworkBehaviour)__instance).IsOwner && !(__instance is FastReloadShotgun) && __instance.Active)
{
TickGun(__instance);
}
}
[HarmonyPatch(typeof(Gun), "Disable")]
[HarmonyPostfix]
private static void Gun_Disable_Postfix(Gun __instance)
{
if (!((Object)(object)__instance == (Object)null))
{
genericStates.Remove(((Object)__instance).GetInstanceID());
if (feedbackKind == FeedbackKind.None)
{
HideBar();
}
}
}
[HarmonyPatch(typeof(Gun), "OnDestroy")]
[HarmonyPrefix]
private static void Gun_OnDestroy_Prefix(Gun __instance)
{
if (!((Object)(object)__instance == (Object)null))
{
genericStates.Remove(((Object)__instance).GetInstanceID());
if (feedbackKind == FeedbackKind.None)
{
HideBar();
}
}
}
private static void TickGun(Gun gun)
{
//IL_01f2: Unknown result type (might be due to invalid IL or missing references)
//IL_01f7: Unknown result type (might be due to invalid IL or missing references)
if ((Object)(object)gun == (Object)null || gun is FastReloadShotgun)
{
return;
}
int instanceID = ((Object)gun).GetInstanceID();
if (!ConfigManager.EnablePracticeMakesPerfect.Value)
{
if (genericStates.Remove(instanceID))
{
HideBar();
}
}
else
{
if (!genericStates.TryGetValue(instanceID, out var value) || !value.Active || value.LastTickFrame == Time.frameCount)
{
return;
}
value.LastTickFrame = Time.frameCount;
if (!loggedFirstTick)
{
loggedFirstTick = true;
SparrohPlugin.Logger.LogInfo((object)("[PMPA] First generic tick on " + ((object)gun).GetType().Name + "."));
}
if (!gun.Reloading || !gun.Active)
{
genericStates.Remove(instanceID);
if (feedbackKind == FeedbackKind.None)
{
HideBar();
}
return;
}
if (value.Succeeded)
{
if (feedbackKind == FeedbackKind.None)
{
HideBar();
}
return;
}
object? obj = animatorField?.GetValue(gun);
PlayerAnimation val = (PlayerAnimation)((obj is PlayerAnimation) ? obj : null);
if ((Object)(object)val == (Object)null)
{
if (!loggedMissingAnimator)
{
loggedMissingAnimator = true;
SparrohPlugin.Logger.LogWarning((object)"[PMPA] Could not access Gun.animator.");
}
return;
}
AnimancerState currentState = val.CurrentState;
if (currentState == null)
{
if (feedbackKind == FeedbackKind.None)
{
HideBar();
}
return;
}
object obj2 = reloadAnimationField?.GetValue(gun);
if ((obj2 == null || !object.Equals(currentState.Key, obj2)) && currentState.NormalizedTime <= 0f && currentState.Time <= 0f)
{
if (feedbackKind == FeedbackKind.None)
{
HideBar();
}
return;
}
float num = Mathf.Max(0.01f, ConfigManager.WindowDuration.Value) * 0.5f;
float num2 = currentState.Duration;
if (num2 <= 0.001f)
{
num2 = Mathf.Max(currentState.Length, 0.01f);
}
float time = currentState.Time;
float num3 = num2 * value.WindowCenterNormalized;
bool flag = time >= num3 - num && time <= num3 + num;
bool flag2 = false;
try
{
PlayerActions player = PlayerInput.Controls.Player;
flag2 = ((PlayerActions)(ref player)).Fire.WasPressedThisFrame();
}
catch
{
}
float progress = Mathf.Clamp01(time / num2);
float sweetMin = Mathf.Clamp01((num3 - num) / num2);
float sweetMax = Mathf.Clamp01((num3 + num) / num2);
if (flag)
{
if (!loggedFirstWindow)
{
loggedFirstWindow = true;
SparrohPlugin.Logger.LogInfo((object)("[PMPA] Timing window open on " + ((object)gun).GetType().Name + " " + $"(t={time:F3}, center={num3:F3}, half={num:F3})."));
}
if (flag2)
{
value.Succeeded = true;
value.Active = false;
((AnimancerNode)currentState).Speed = ((AnimancerNode)currentState).Speed * Mathf.Max(1f, ConfigManager.ReloadSpeedMultiplier.Value);
FlashFeedback(FeedbackKind.Success);
TryTriggerReloadEffect(gun);
SparrohPlugin.Logger.LogInfo((object)$"[PMPA] Success on {((object)gun).GetType().Name}; speed now {((AnimancerNode)currentState).Speed:F2}.");
}
}
else if (flag2)
{
value.Active = false;
genericStates.Remove(instanceID);
FlashFeedback(FeedbackKind.Miss);
}
_ = feedbackKind;
UpdateBarVisual(progress, sweetMin, sweetMax, flag);
}
}
private static void EnsureBar()
{
//IL_0013: Unknown result type (might be due to invalid IL or missing references)
//IL_001d: Expected O, but got Unknown
//IL_005e: Unknown result type (might be due to invalid IL or missing references)
//IL_0082: Unknown result type (might be due to invalid IL or missing references)
//IL_0088: Expected O, but got Unknown
//IL_00af: 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_00d9: Unknown result type (might be due to invalid IL or missing references)
//IL_00ed: Unknown result type (might be due to invalid IL or missing references)
//IL_00fc: Unknown result type (might be due to invalid IL or missing references)
//IL_0102: Expected O, but got Unknown
//IL_012e: Unknown result type (might be due to invalid IL or missing references)
//IL_0147: Unknown result type (might be due to invalid IL or missing references)
//IL_0160: Unknown result type (might be due to invalid IL or missing references)
//IL_0179: Unknown result type (might be due to invalid IL or missing references)
//IL_018a: 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_01a4: Unknown result type (might be due to invalid IL or missing references)
//IL_01b6: Unknown result type (might be due to invalid IL or missing references)
//IL_01c7: Unknown result type (might be due to invalid IL or missing references)
//IL_01dc: Unknown result type (might be due to invalid IL or missing references)
//IL_01f1: Unknown result type (might be due to invalid IL or missing references)
//IL_0206: 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_0245: Unknown result type (might be due to invalid IL or missing references)
//IL_024a: Unknown result type (might be due to invalid IL or missing references)
//IL_025c: Unknown result type (might be due to invalid IL or missing references)
//IL_0276: Unknown result type (might be due to invalid IL or missing references)
//IL_028f: Unknown result type (might be due to invalid IL or missing references)
//IL_02a8: Unknown result type (might be due to invalid IL or missing references)
//IL_02b7: Unknown result type (might be due to invalid IL or missing references)
//IL_02d0: Unknown result type (might be due to invalid IL or missing references)
//IL_02e9: Unknown result type (might be due to invalid IL or missing references)
//IL_0303: Unknown result type (might be due to invalid IL or missing references)
//IL_0308: Unknown result type (might be due to invalid IL or missing references)
//IL_031a: Unknown result type (might be due to invalid IL or missing references)
//IL_0334: Unknown result type (might be due to invalid IL or missing references)
//IL_034d: Unknown result type (might be due to invalid IL or missing references)
//IL_0366: Unknown result type (might be due to invalid IL or missing references)
//IL_037f: Unknown result type (might be due to invalid IL or missing references)
//IL_038e: Unknown result type (might be due to invalid IL or missing references)
//IL_03a7: Unknown result type (might be due to invalid IL or missing references)
//IL_03c1: Unknown result type (might be due to invalid IL or missing references)
//IL_03c6: Unknown result type (might be due to invalid IL or missing references)
//IL_03d8: Unknown result type (might be due to invalid IL or missing references)
//IL_03e9: Unknown result type (might be due to invalid IL or missing references)
//IL_03fe: Unknown result type (might be due to invalid IL or missing references)
//IL_0413: Unknown result type (might be due to invalid IL or missing references)
//IL_0428: Unknown result type (might be due to invalid IL or missing references)
//IL_043c: Unknown result type (might be due to invalid IL or missing references)
//IL_048d: Unknown result type (might be due to invalid IL or missing references)
if (!((Object)(object)sharedBarRoot != (Object)null))
{
sharedBarRoot = new GameObject("AlwaysPracticeMakesPerfect_ReloadBar");
Object.DontDestroyOnLoad((Object)(object)sharedBarRoot);
Canvas obj = sharedBarRoot.AddComponent<Canvas>();
obj.renderMode = (RenderMode)0;
obj.sortingOrder = 9000;
CanvasScaler obj2 = sharedBarRoot.AddComponent<CanvasScaler>();
obj2.uiScaleMode = (ScaleMode)1;
obj2.referenceResolution = new Vector2(1920f, 1080f);
obj2.matchWidthOrHeight = 0.5f;
sharedBarRoot.AddComponent<GraphicRaycaster>();
GameObject val = new GameObject("Container");
val.transform.SetParent(sharedBarRoot.transform, false);
RectTransform obj3 = val.AddComponent<RectTransform>();
obj3.anchorMin = new Vector2(0.5f, 0.3f);
obj3.anchorMax = new Vector2(0.5f, 0.3f);
obj3.pivot = new Vector2(0.5f, 0.5f);
obj3.sizeDelta = new Vector2(304f, 54f);
GameObject val2 = new GameObject("Track");
val2.transform.SetParent(val.transform, false);
trackRt = val2.AddComponent<RectTransform>();
trackRt.anchorMin = new Vector2(0.5f, 0.5f);
trackRt.anchorMax = new Vector2(0.5f, 0.5f);
trackRt.pivot = new Vector2(0.5f, 0.5f);
trackRt.sizeDelta = new Vector2(280f, 14f);
Image obj4 = val2.AddComponent<Image>();
((Graphic)obj4).color = TrackColor;
((Graphic)obj4).raycastTarget = false;
GameObject val3 = new GameObject("Outline");
val3.transform.SetParent(val.transform, false);
RectTransform obj5 = val3.AddComponent<RectTransform>();
obj5.anchorMin = new Vector2(0.5f, 0.5f);
obj5.anchorMax = new Vector2(0.5f, 0.5f);
obj5.pivot = new Vector2(0.5f, 0.5f);
obj5.sizeDelta = new Vector2(284f, 18f);
((Transform)obj5).SetSiblingIndex(0);
Image obj6 = val3.AddComponent<Image>();
((Graphic)obj6).color = new Color(0.25f, 0.4f, 0.5f, 0.55f);
((Graphic)obj6).raycastTarget = false;
GameObject val4 = new GameObject("SweetSpot");
val4.transform.SetParent(val2.transform, false);
sweetSpotRt = val4.AddComponent<RectTransform>();
sweetSpotRt.anchorMin = new Vector2(0f, 0f);
sweetSpotRt.anchorMax = new Vector2(0f, 1f);
sweetSpotRt.pivot = new Vector2(0f, 0.5f);
sweetSpotRt.anchoredPosition = Vector2.zero;
sweetSpotRt.sizeDelta = new Vector2(20f, 0f);
sweetSpotImage = val4.AddComponent<Image>();
((Graphic)sweetSpotImage).color = SweetSpotIdle;
((Graphic)sweetSpotImage).raycastTarget = false;
GameObject val5 = new GameObject("Cursor");
val5.transform.SetParent(val2.transform, false);
cursorRt = val5.AddComponent<RectTransform>();
cursorRt.anchorMin = new Vector2(0f, 0.5f);
cursorRt.anchorMax = new Vector2(0f, 0.5f);
cursorRt.pivot = new Vector2(0.5f, 0.5f);
cursorRt.sizeDelta = new Vector2(3f, 24f);
cursorRt.anchoredPosition = Vector2.zero;
cursorImage = val5.AddComponent<Image>();
((Graphic)cursorImage).color = CursorIdle;
((Graphic)cursorImage).raycastTarget = false;
GameObject val6 = new GameObject("Prompt");
val6.transform.SetParent(val.transform, false);
RectTransform obj7 = val6.AddComponent<RectTransform>();
obj7.anchorMin = new Vector2(0.5f, 0.5f);
obj7.anchorMax = new Vector2(0.5f, 0.5f);
obj7.pivot = new Vector2(0.5f, 0f);
obj7.anchoredPosition = new Vector2(0f, 13f);
obj7.sizeDelta = new Vector2(280f, 28f);
promptLabel = val6.AddComponent<TextMeshProUGUI>();
((TMP_Text)promptLabel).text = "FIRE";
((TMP_Text)promptLabel).alignment = (TextAlignmentOptions)514;
((TMP_Text)promptLabel).fontSize = 22f;
((TMP_Text)promptLabel).fontStyle = (FontStyles)1;
((Graphic)promptLabel).color = PromptColor;
((Graphic)promptLabel).raycastTarget = false;
if ((Object)(object)TMP_Settings.defaultFontAsset != (Object)null)
{
((TMP_Text)promptLabel).font = TMP_Settings.defaultFontAsset;
}
((Component)promptLabel).gameObject.SetActive(false);
sharedBarRoot.SetActive(false);
barVisible = false;
}
}
private static void UpdateBarVisual(float progress01, float sweetMin01, float sweetMax01, bool inWindow)
{
//IL_0050: 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_0080: Unknown result type (might be due to invalid IL or missing references)
//IL_0097: Unknown result type (might be due to invalid IL or missing references)
//IL_00a6: Unknown result type (might be due to invalid IL or missing references)
//IL_0100: Unknown result type (might be due to invalid IL or missing references)
//IL_010f: Unknown result type (might be due to invalid IL or missing references)
//IL_00d4: 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)
//IL_01fc: Unknown result type (might be due to invalid IL or missing references)
//IL_017f: Unknown result type (might be due to invalid IL or missing references)
//IL_0184: Unknown result type (might be due to invalid IL or missing references)
//IL_0196: Unknown result type (might be due to invalid IL or missing references)
//IL_01a1: Unknown result type (might be due to invalid IL or missing references)
//IL_013d: Unknown result type (might be due to invalid IL or missing references)
//IL_01cc: Unknown result type (might be due to invalid IL or missing references)
EnsureBar();
progress01 = Mathf.Clamp01(progress01);
sweetMin01 = Mathf.Clamp01(sweetMin01);
sweetMax01 = Mathf.Clamp01(Mathf.Max(sweetMax01, sweetMin01 + 0.01f));
float num = sweetMin01 * 280f;
float num2 = Mathf.Max(4f, (sweetMax01 - sweetMin01) * 280f);
sweetSpotRt.anchoredPosition = new Vector2(num, 0f);
sweetSpotRt.sizeDelta = new Vector2(num2, 0f);
cursorRt.anchoredPosition = new Vector2(progress01 * 280f, 0f);
if (feedbackKind == FeedbackKind.Success)
{
((Graphic)sweetSpotImage).color = SweetSpotSuccess;
((Graphic)cursorImage).color = SweetSpotSuccess;
if ((Object)(object)promptLabel != (Object)null)
{
((TMP_Text)promptLabel).text = "NICE";
((Graphic)promptLabel).color = SweetSpotSuccess;
((Component)promptLabel).gameObject.SetActive(true);
}
}
else if (feedbackKind == FeedbackKind.Miss)
{
((Graphic)sweetSpotImage).color = SweetSpotMiss;
((Graphic)cursorImage).color = SweetSpotMiss;
if ((Object)(object)promptLabel != (Object)null)
{
((TMP_Text)promptLabel).text = "MISS";
((Graphic)promptLabel).color = SweetSpotMiss;
((Component)promptLabel).gameObject.SetActive(true);
}
}
else if (inWindow)
{
float num3 = 0.85f + 0.15f * Mathf.Sin(Time.unscaledTime * 14f);
Color sweetSpotActive = SweetSpotActive;
sweetSpotActive.a *= num3;
((Graphic)sweetSpotImage).color = sweetSpotActive;
((Graphic)cursorImage).color = CursorActive;
if ((Object)(object)promptLabel != (Object)null)
{
((TMP_Text)promptLabel).text = "FIRE";
((Graphic)promptLabel).color = PromptColor;
((Component)promptLabel).gameObject.SetActive(true);
}
}
else
{
((Graphic)sweetSpotImage).color = SweetSpotIdle;
((Graphic)cursorImage).color = CursorIdle;
if ((Object)(object)promptLabel != (Object)null)
{
((Component)promptLabel).gameObject.SetActive(false);
}
}
if (!sharedBarRoot.activeSelf)
{
sharedBarRoot.SetActive(true);
}
barVisible = true;
}
private static void FlashFeedback(FeedbackKind kind)
{
feedbackKind = kind;
feedbackUntil = Time.unscaledTime + 0.35f;
}
private static void HideBar()
{
feedbackKind = FeedbackKind.None;
if ((Object)(object)sharedBarRoot != (Object)null && sharedBarRoot.activeSelf)
{
sharedBarRoot.SetActive(false);
}
barVisible = false;
}
private static void TryTriggerReloadEffect(Gun gun)
{
try
{
(AccessTools.Method(((object)gun).GetType(), "TriggerEffectReload", (Type[])null, (Type[])null) ?? AccessTools.Method(typeof(Gun), "TriggerEffectReload", (Type[])null, (Type[])null))?.Invoke(gun, null);
}
catch
{
}
}
}
[BepInPlugin("sparroh.alwayspracticemakesperfect", "AlwaysPracticeMakesPerfect", "1.1.0")]
[MycoMod(/*Could not decode attribute arguments.*/)]
public class SparrohPlugin : BaseUnityPlugin
{
public const string PluginGUID = "sparroh.alwayspracticemakesperfect";
public const string PluginName = "AlwaysPracticeMakesPerfect";
public const string PluginVersion = "1.1.0";
internal static ManualLogSource Logger;
private Harmony harmony;
private void Awake()
{
//IL_0021: Unknown result type (might be due to invalid IL or missing references)
//IL_002b: Expected O, but got Unknown
Logger = ((BaseUnityPlugin)this).Logger;
ConfigManager.Initialize(((BaseUnityPlugin)this).Config, Logger);
harmony = new Harmony("sparroh.alwayspracticemakesperfect");
try
{
harmony.PatchAll(typeof(InstaReloadPatches));
Logger.LogInfo((object)"Harmony patches applied.");
}
catch (Exception ex)
{
Logger.LogError((object)("Error applying patches: " + ex.Message));
}
Logger.LogInfo((object)"AlwaysPracticeMakesPerfect v1.1.0 loaded successfully.");
}
private void Update()
{
ConfigManager.Tick();
try
{
InstaReloadPatches.TickTrackedGuns();
}
catch (Exception ex)
{
Logger.LogError((object)("Error in insta-reload tick: " + ex.Message));
}
}
private void OnDestroy()
{
InstaReloadPatches.Cleanup();
ConfigManager.Dispose();
Harmony obj = harmony;
if (obj != null)
{
obj.UnpatchSelf();
}
}
}
namespace AlwaysPracticeMakesPerfect
{
public static class MyPluginInfo
{
public const string PLUGIN_GUID = "AlwaysPracticeMakesPerfect";
public const string PLUGIN_NAME = "AlwaysPracticeMakesPerfect";
public const string PLUGIN_VERSION = "1.1.0";
}
}
namespace System.Runtime.CompilerServices
{
[AttributeUsage(AttributeTargets.Assembly, AllowMultiple = true)]
internal sealed class IgnoresAccessChecksToAttribute : Attribute
{
public IgnoresAccessChecksToAttribute(string assemblyName)
{
}
}
}