using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using System.Text;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using HarmonyLib;
using Microsoft.CodeAnalysis;
using Pigeon.Movement;
using Pigeon.UI;
using Unity.Netcode;
using UnityEngine;
using UnityEngine.EventSystems;
using UnityEngine.Events;
using UnityEngine.InputSystem;
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("HeavyIntegration")]
[assembly: AssemblyTitle("HeavyIntegration")]
[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;
}
}
}
namespace HeavyIntegration
{
public static class ConfigManager
{
private const float DebounceSeconds = 0.25f;
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> LoadoutEnabled { get; private set; }
public static ConfigEntry<int> HeavyGearId { get; private set; }
public static ConfigEntry<bool> ReapplyAfterDrop { get; private set; }
public static ConfigEntry<bool> AmmoRegenEnabled { get; private set; }
public static ConfigEntry<float> RegenMultiplier { get; private set; }
public static ConfigEntry<bool> PlayAmmoSound { get; private set; }
public static ConfigEntry<bool> HeavyFocusEnabled { get; private set; }
public static ConfigEntry<bool> SelectionUiEnabled { get; private set; }
public static void Initialize(ConfigFile configFile, ManualLogSource log)
{
config = configFile;
logger = log;
LoadoutEnabled = config.Bind<bool>("Loadout", "Enabled", true, "When enabled, the selected heavy weapon is kept in your stored (heavy) loadout slot.");
HeavyGearId = config.Bind<int>("Loadout", "Heavy Gear Id", 0, "GearInfo.ID of the loadout heavy weapon. 0 = none (empty). Prefer selecting in the gear menu.");
ReapplyAfterDrop = config.Bind<bool>("Loadout", "Reapply After Drop", true, "When true, dropping or clearing a temporary stored pickup restores your loadout heavy.");
AmmoRegenEnabled = config.Bind<bool>("Ammo Regen", "Enable Feature", true, "When enabled, heavy weapons gain magazine ammo from damage dealt by your other main weapon.");
RegenMultiplier = config.Bind<float>("Ammo Regen", "Regen Multiplier", 1f, "Multiplier on vanilla damage-to-ammo conversion density for the heavy magazine. 1.0 = same density primaries use; raise if regen feels weak.");
PlayAmmoSound = config.Bind<bool>("Ammo Regen", "Play Ammo Sound", false, "Play the ammo refund sound when heavy magazine ammo is restored from damage.");
HeavyFocusEnabled = config.Bind<bool>("Focus", "Enable Heavy Focus", true, "When enabled, unlocked heavies can be Focused in the gear menu (Favorite bind), skewing upgrade drops toward that heavy like primaries.");
SelectionUiEnabled = config.Bind<bool>("Selection UI", "Enable Feature", true, "When enabled, the heavy crate picker lays out extra slots and scrolls when many heavies are unlocked.");
try
{
SetupFileWatcher();
}
catch (Exception ex)
{
logger.LogError((object)("Error setting up config file watcher: " + ex.Message));
}
}
public static void SetHeavyGearId(int id)
{
if (HeavyGearId != null && HeavyGearId.Value != id)
{
HeavyGearId.Value = id;
config.Save();
}
}
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 from disk.");
HeavyLoadoutService.OnConfigReloaded();
}
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.heavyintegration.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;
}
}
public static class HeavyAmmoRegenPatch
{
private const float VanillaConversionFactor = 0.015f;
private static bool loggedLoadout;
private static bool loggedGrant;
public static void Apply(Harmony harmony, ManualLogSource log)
{
//IL_003f: Unknown result type (might be due to invalid IL or missing references)
//IL_004c: Expected O, but got Unknown
MethodInfo methodInfo = AccessTools.Method(typeof(Player), "OnDamagedTarget", (Type[])null, (Type[])null);
if (methodInfo == null)
{
log.LogError((object)"Could not find Player.OnDamagedTarget — heavy ammo regen disabled.");
return;
}
harmony.Patch((MethodBase)methodInfo, (HarmonyMethod)null, new HarmonyMethod(typeof(HeavyAmmoRegenPatch), "OnDamagedTargetPostfix", (Type[])null), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
log.LogInfo((object)("Patched " + methodInfo.DeclaringType.Name + "." + methodInfo.Name + " for heavy ammo regen."));
}
private static void OnDamagedTargetPostfix(Player __instance, DamageCallbackData data)
{
//IL_0036: 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_003f: Unknown result type (might be due to invalid IL or missing references)
//IL_00aa: Unknown result type (might be due to invalid IL or missing references)
//IL_009a: 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_0104: 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)
try
{
if (ConfigManager.AmmoRegenEnabled == null || !ConfigManager.AmmoRegenEnabled.Value || (Object)(object)__instance == (Object)null || !Object.op_Implicit((Object)(object)__instance) || !((NetworkBehaviour)__instance).IsOwner || data.source == null || data.damageData.damage <= 0f)
{
return;
}
float num = ConfigManager.RegenMultiplier?.Value ?? 1f;
if (num <= 0f)
{
return;
}
IGear[] gear = __instance.Gear;
if (gear == null || gear.Length == 0)
{
return;
}
if (!loggedLoadout)
{
loggedLoadout = true;
LogFullLoadout(__instance, gear, data.damageData.damage);
}
IWeapon val = ResolveWeapon(data.source);
if (val == null || !IsPlayerLoadoutWeapon(__instance, gear, val))
{
return;
}
float num2 = __instance.upgradeVariables.ammoConversionMultiplier;
if (num2 <= 0f)
{
num2 = 1f;
}
float num3 = val.GunData.ammoGenerationEfficiency;
if (num3 <= 0f)
{
num3 = 1f;
}
float num4 = data.damageData.damage * num3 * 0.015f * num2 * num;
float num5 = 3f * num2 * num;
if (num4 > num5)
{
num4 = num5;
}
if (num4 <= 0f)
{
return;
}
foreach (IGear obj in gear)
{
Gun val2 = (Gun)(object)((obj is Gun) ? obj : null);
if (val2 != null && IsHeavy((IGear)(object)val2) && !IsSameWeapon((IGear)(object)val2, val))
{
TryGrantMagAmmo(val2, num4);
}
}
IGear heldGear = __instance.HeldGear;
Gun val3 = (Gun)(object)((heldGear is Gun) ? heldGear : null);
if (val3 != null && IsHeavy((IGear)(object)val3) && !IsSameWeapon((IGear)(object)val3, val))
{
TryGrantMagAmmo(val3, num4);
}
}
catch (Exception arg)
{
HeavyIntegrationPlugin.Log.LogError((object)$"Heavy ammo regen error: {arg}");
}
}
internal static bool IsHeavy(IGear gear)
{
//IL_0006: Unknown result type (might be due to invalid IL or missing references)
//IL_000c: Invalid comparison between Unknown and I4
//IL_001e: Unknown result type (might be due to invalid IL or missing references)
//IL_0024: Invalid comparison between Unknown and I4
if (gear == null)
{
return false;
}
if ((int)((IUpgradable)gear).GearType == 1)
{
return true;
}
if (((IUpgradable)gear).Prefab != null && (int)((IUpgradable)gear).Prefab.GearType == 1)
{
return true;
}
return false;
}
private static IWeapon ResolveWeapon(IDamageSource source)
{
for (IDamageSource val = source; val != null; val = val.ParentSource)
{
IWeapon val2 = (IWeapon)(object)((val is IWeapon) ? val : null);
if (val2 != null)
{
return val2;
}
}
return null;
}
private static bool IsPlayerLoadoutWeapon(Player player, IGear[] gear, IWeapon weapon)
{
if (weapon == null)
{
return false;
}
for (int i = 0; i < gear.Length; i++)
{
if (IsSameWeapon(gear[i], weapon))
{
return true;
}
}
if (IsSameWeapon(player.HeldGear, weapon))
{
return true;
}
IDamageSource val = (IDamageSource)(object)((weapon is IDamageSource) ? weapon : null);
if (val != null)
{
IDamageSource val2 = val.GetBase();
if ((object)val2 == player || val2 is Player)
{
return true;
}
}
return false;
}
private static bool IsSameWeapon(IGear gear, IWeapon weapon)
{
if (gear == null || weapon == null)
{
return false;
}
if ((object)gear == weapon)
{
return true;
}
IWeapon val = (IWeapon)(object)((gear is IWeapon) ? gear : null);
if (val != null && val == weapon)
{
return true;
}
return false;
}
private static void TryGrantMagAmmo(Gun heavy, float density)
{
//IL_00c9: Unknown result type (might be due to invalid IL or missing references)
if ((Object)(object)heavy == (Object)null || !Object.op_Implicit((Object)(object)heavy) || !((NetworkBehaviour)heavy).IsOwner)
{
return;
}
float remainingAmmo = heavy.RemainingAmmo;
float num = heavy.GunData.magazineSize;
if (num <= 0f || remainingAmmo >= num)
{
return;
}
float num2 = Mathf.Min(density, num - remainingAmmo);
if (!(num2 <= 0f))
{
heavy.RemainingAmmo = remainingAmmo + num2;
if (ConfigManager.PlayAmmoSound != null && ConfigManager.PlayAmmoSound.Value && heavy.RemainingAmmo > remainingAmmo)
{
heavy.InvokeOnAmmoRefunded(heavy.RemainingAmmo - remainingAmmo);
}
if (!loggedGrant && heavy.RemainingAmmo > remainingAmmo)
{
loggedGrant = true;
HeavyIntegrationPlugin.Log.LogInfo((object)($"Heavy ammo regen OK: +{heavy.RemainingAmmo - remainingAmmo:0.##} on {NameOf((IGear)(object)heavy)} " + $"(GearType={heavy.GearType}, dens={density:0.###}, mag={heavy.RemainingAmmo:0.#}/{num})."));
}
}
}
private static void LogFullLoadout(Player player, IGear[] gear, float sampleDamage)
{
StringBuilder stringBuilder = new StringBuilder(256);
stringBuilder.Append("Full loadout (heavy detect = GearType.Heavy):");
for (int i = 0; i < gear.Length; i++)
{
stringBuilder.Append(" [").Append(i).Append("]=")
.Append(Describe(gear[i]));
}
if (player.HeldGear != null)
{
stringBuilder.Append(" held=").Append(Describe(player.HeldGear));
}
stringBuilder.Append(" sampleDmg=").Append(sampleDamage.ToString("0.#"));
HeavyIntegrationPlugin.Log.LogInfo((object)stringBuilder.ToString());
}
private static string Describe(IGear gear)
{
//IL_0027: 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 (gear == null)
{
return "null";
}
Gun val = (Gun)(object)((gear is Gun) ? gear : null);
if (val == null || !Object.op_Implicit((Object)(object)val))
{
return $"{NameOf(gear)} type={((IUpgradable)gear).GearType} (not Gun)";
}
return $"{NameOf((IGear)(object)val)} type={val.GearType} heavy={IsHeavy((IGear)(object)val)} " + $"limited={val.GunData.hasLimitedAmmo} noMagRefill={val.dontRefillMagFromDamage} " + $"eff={val.GunData.ammoGenerationEfficiency} mag={val.RemainingAmmo:0.#}/{val.GunData.magazineSize}";
}
private static string NameOf(IGear gear)
{
if ((Object)(object)((gear != null) ? ((IUpgradable)gear).Info : null) != (Object)null && !string.IsNullOrEmpty(((IUpgradable)gear).Info.APIName))
{
return ((IUpgradable)gear).Info.APIName;
}
Component val = (Component)(object)((gear is Component) ? gear : null);
if (val == null || !((Object)(object)val != (Object)null))
{
return ((object)gear)?.GetType().Name ?? "null";
}
return ((Object)val).name;
}
}
[HarmonyPatch(typeof(GearSlot))]
internal static class HeavyFocusPatch
{
private static readonly FieldInfo WindowField = AccessTools.Field(typeof(GearSlot), "window");
[HarmonyPatch("GetAdditionalBinding")]
[HarmonyPostfix]
private static void GetAdditionalBindingPostfix(GearSlot __instance, int index, ref InputAction __result, ref string label, ref bool bold)
{
//IL_0030: Unknown result type (might be due to invalid IL or missing references)
//IL_0036: Invalid comparison between Unknown and I4
//IL_00b0: Unknown result type (might be due to invalid IL or missing references)
//IL_00b5: Unknown result type (might be due to invalid IL or missing references)
if (ConfigManager.HeavyFocusEnabled == null || !ConfigManager.HeavyFocusEnabled.Value || __result != null || ((__instance != null) ? __instance.Gear : null) == null)
{
return;
}
IUpgradable gear = __instance.Gear;
if ((int)gear.GearType == 1 && LevelData.CanModifyGear && PlayerData.GetGearData(gear).IsUnlocked && PlayerData.GetPlayerLevel() >= 5)
{
object? obj = WindowField?.GetValue(__instance);
GearSelectionWindow val = (GearSelectionWindow)((obj is GearSelectionWindow) ? obj : null);
if (val != null && !(((object)val).GetType() == typeof(ShowcaseGearSelectWindow)) && gear.Info.HasWorldPoolUpgrades((Rarity)(-1)))
{
label = TextBlocks.GetString("focus");
bold = false;
MenuActions menu = PlayerInput.Controls.Menu;
__result = ((MenuActions)(ref menu)).Favorite;
}
}
}
}
internal static class HeavyLoadoutService
{
public const int StoredGearIndex = 5;
public const int StoredSelectedSlot = 6;
private static readonly FieldInfo GearHudsField = AccessTools.Field(typeof(Player), "gearHUDs");
private static bool applyInProgress;
private static int lastApplyFrame = -1;
private static Coroutine pendingApply;
internal static bool SuppressReapply;
private static int managedStoredId;
public static bool IsEnabled
{
get
{
if (ConfigManager.LoadoutEnabled != null)
{
return ConfigManager.LoadoutEnabled.Value;
}
return false;
}
}
public static int SelectedHeavyId => ConfigManager.HeavyGearId?.Value ?? 0;
public static bool HasSelection => SelectedHeavyId != 0;
public static void OnConfigReloaded()
{
Player localPlayer = Player.LocalPlayer;
if ((Object)(object)localPlayer != (Object)null && ((NetworkBehaviour)localPlayer).IsOwner && localPlayer.IsGearInitialized)
{
ScheduleApply(localPlayer);
}
}
public static IUpgradable ResolveSelectedHeavy()
{
int selectedHeavyId = SelectedHeavyId;
if (selectedHeavyId == 0)
{
return null;
}
return ResolveGearById(selectedHeavyId);
}
public static IUpgradable ResolveGearById(int id)
{
//IL_004c: Unknown result type (might be due to invalid IL or missing references)
//IL_0052: Invalid comparison between Unknown and I4
//IL_0085: Unknown result type (might be due to invalid IL or missing references)
//IL_008b: Invalid comparison between Unknown and I4
if (id == 0 || Global.Instance?.AllGear == null)
{
return null;
}
for (int i = 0; i < Global.Instance.AllGear.Length; i++)
{
IUpgradable val = Global.Instance.AllGear[i];
if ((Object)(object)((val != null) ? val.Info : null) != (Object)null && val.Info.ID == id && (int)val.GearType == 1)
{
return val;
}
}
try
{
GearData gearData = PlayerData.GetGearData(id);
if (((gearData != null) ? gearData.Gear : null) != null && (int)gearData.Gear.GearType == 1)
{
return gearData.Gear;
}
}
catch
{
}
return null;
}
public static bool IsLoadoutHeavy(IUpgradable gear)
{
if (gear == null || !HasSelection)
{
return false;
}
IUpgradable val = gear.GetPrefab() ?? gear;
if ((Object)(object)val.Info != (Object)null)
{
return val.Info.ID == SelectedHeavyId;
}
return false;
}
public static bool IsSamePrefab(IGear live, IUpgradable desired)
{
if (live == null || desired == null)
{
return false;
}
IUpgradable val = (IUpgradable)(((object)((IUpgradable)live).Prefab) ?? ((object)live));
IUpgradable val2 = desired.GetPrefab() ?? desired;
if (val == val2)
{
return true;
}
if ((Object)(object)((val != null) ? val.Info : null) != (Object)null && (Object)(object)((val2 != null) ? val2.Info : null) != (Object)null)
{
return val.Info.ID == val2.Info.ID;
}
return false;
}
private static int GetPrefabId(IGear gear)
{
if (gear == null)
{
return 0;
}
object obj = ((object)((IUpgradable)gear).Prefab) ?? ((object)gear);
int? obj2;
if (obj == null)
{
obj2 = null;
}
else
{
GearInfo info = ((IUpgradable)obj).Info;
obj2 = ((info != null) ? new int?(info.ID) : ((int?)null));
}
int? num = obj2;
return num.GetValueOrDefault();
}
public static void SelectOrToggleHeavy(IUpgradable gear)
{
//IL_000b: Unknown result type (might be due to invalid IL or missing references)
//IL_0011: Invalid comparison between Unknown and I4
if (!IsEnabled || gear == null || (int)gear.GearType != 1)
{
return;
}
if (!PlayerData.IsGearUnlocked(gear))
{
ManualLogSource log = HeavyIntegrationPlugin.Log;
if (log != null)
{
log.LogInfo((object)"Cannot set locked heavy as loadout heavy.");
}
return;
}
IUpgradable val = gear.GetPrefab() ?? gear;
GearInfo info = val.Info;
int num = ((info != null) ? info.ID : 0);
if (num == 0)
{
return;
}
if (SelectedHeavyId == num)
{
ConfigManager.SetHeavyGearId(0);
ManualLogSource log2 = HeavyIntegrationPlugin.Log;
if (log2 != null)
{
log2.LogInfo((object)"Cleared loadout heavy.");
}
}
else
{
ConfigManager.SetHeavyGearId(num);
ManualLogSource log3 = HeavyIntegrationPlugin.Log;
if (log3 != null)
{
GearInfo info2 = val.Info;
object obj = ((info2 != null) ? info2.APIName : null);
if (obj == null)
{
GearInfo info3 = val.Info;
obj = ((info3 != null) ? info3.Name : null);
}
log3.LogInfo((object)$"Loadout heavy set to '{obj}' (id={num}).");
}
}
Player localPlayer = Player.LocalPlayer;
if ((Object)(object)localPlayer != (Object)null && ((NetworkBehaviour)localPlayer).IsOwner && localPlayer.IsGearInitialized)
{
ScheduleApply(localPlayer);
}
}
public static void ScheduleApply(Player player, int delayFrames = 1)
{
if ((Object)(object)player == (Object)null || !((NetworkBehaviour)player).IsOwner)
{
return;
}
if (pendingApply != null)
{
try
{
((MonoBehaviour)player).StopCoroutine(pendingApply);
}
catch
{
}
pendingApply = null;
}
pendingApply = ((MonoBehaviour)player).StartCoroutine(ApplyAfterFrames(player, delayFrames));
}
private static IEnumerator ApplyAfterFrames(Player player, int delayFrames)
{
for (int i = 0; i < delayFrames; i++)
{
yield return null;
}
pendingApply = null;
TryApply(player);
}
public static void TryApply(Player player)
{
if (!IsEnabled || (Object)(object)player == (Object)null || !((NetworkBehaviour)player).IsOwner || !player.IsGearInitialized || applyInProgress || Time.frameCount == lastApplyFrame || Global.Instance?.AllGear == null || player.Gear == null || player.Gear.Length <= 5)
{
return;
}
applyInProgress = true;
lastApplyFrame = Time.frameCount;
try
{
IUpgradable val = ResolveSelectedHeavy();
IGear val2 = player.Gear[5];
int prefabId = GetPrefabId(val2);
if (val == null)
{
if (val2 != null && managedStoredId != 0 && prefabId == managedStoredId)
{
ClearStoredManaged(player);
}
else if (val2 == null)
{
managedStoredId = 0;
}
}
else if (!PlayerData.IsGearUnlocked(val))
{
ManualLogSource log = HeavyIntegrationPlugin.Log;
if (log != null)
{
log.LogWarning((object)$"Loadout heavy id={SelectedHeavyId} is not unlocked — skip apply.");
}
}
else
{
if (val2 != null && !IsSamePrefab(val2, val) && (managedStoredId == 0 || prefabId != managedStoredId))
{
return;
}
if (IsSamePrefab(val2, val))
{
managedStoredId = val.Info.ID;
EnsureStoredHudVisible(player, val2);
return;
}
int num = Array.IndexOf(Global.Instance.AllGear, val);
if (num < 0)
{
num = FindAllGearIndexById(val.Info.ID);
}
if (num < 0)
{
ManualLogSource log2 = HeavyIntegrationPlugin.Log;
if (log2 != null)
{
GearInfo info = val.Info;
log2.LogWarning((object)("Loadout heavy '" + ((info != null) ? info.APIName : null) + "' not found in AllGear."));
}
return;
}
bool flag = val2 != null;
SuppressReapply = true;
try
{
if (val2 != null)
{
bool flag2 = false;
try
{
flag2 = (Object)(object)val2.AsNetworkBehaviour() != (Object)null;
}
catch
{
flag2 = false;
}
if (!flag2)
{
try
{
player.DropStoredGear();
flag = false;
}
catch (Exception ex)
{
ManualLogSource log3 = HeavyIntegrationPlugin.Log;
if (log3 != null)
{
log3.LogWarning((object)("DropStoredGear before apply: " + ex.Message));
}
}
}
}
player.SpawnGear_ServerRpc(5, num, false, flag);
managedStoredId = val.Info.ID;
ManualLogSource log4 = HeavyIntegrationPlugin.Log;
if (log4 != null)
{
GearInfo info2 = val.Info;
log4.LogInfo((object)("Spawned loadout heavy '" + ((info2 != null) ? info2.APIName : null) + "' into stored slot."));
}
}
finally
{
SuppressReapply = false;
}
ScheduleHudRefresh(player);
}
}
catch (Exception arg)
{
ManualLogSource log5 = HeavyIntegrationPlugin.Log;
if (log5 != null)
{
log5.LogError((object)$"Apply loadout heavy failed: {arg}");
}
}
finally
{
applyInProgress = false;
}
}
public static void OnStoredCleared(Player player)
{
if (!SuppressReapply && IsEnabled)
{
managedStoredId = 0;
if (ConfigManager.ReapplyAfterDrop != null && ConfigManager.ReapplyAfterDrop.Value && !((Object)(object)player == (Object)null) && ((NetworkBehaviour)player).IsOwner && HasSelection)
{
ScheduleApply(player, 2);
}
}
}
public static void OnReplaceStored(Player player, IGear gear)
{
if (!((Object)(object)player == (Object)null) && ((NetworkBehaviour)player).IsOwner)
{
int prefabId = GetPrefabId(gear);
if (prefabId != 0 && prefabId == SelectedHeavyId)
{
managedStoredId = prefabId;
}
else
{
managedStoredId = 0;
}
}
}
private static void ClearStoredManaged(Player player)
{
SuppressReapply = true;
try
{
IGear val = player.Gear[5];
if (val != null)
{
bool flag = false;
try
{
flag = (Object)(object)val.AsNetworkBehaviour() != (Object)null;
}
catch
{
flag = false;
}
if (flag)
{
player.DespawnGear_ServerRpc(5);
}
else
{
player.DropStoredGear();
}
}
}
catch (Exception ex)
{
ManualLogSource log = HeavyIntegrationPlugin.Log;
if (log != null)
{
log.LogWarning((object)("Clear stored loadout heavy: " + ex.Message));
}
}
finally
{
managedStoredId = 0;
SuppressReapply = false;
}
SetStoredHudActive(player, active: false);
}
private static int FindAllGearIndexById(int id)
{
if (Global.Instance?.AllGear == null)
{
return -1;
}
for (int i = 0; i < Global.Instance.AllGear.Length; i++)
{
IUpgradable val = Global.Instance.AllGear[i];
if ((Object)(object)((val != null) ? val.Info : null) != (Object)null && val.Info.ID == id)
{
return i;
}
}
return -1;
}
private static void ScheduleHudRefresh(Player player)
{
((MonoBehaviour)player).StartCoroutine(HudRefreshNextFrame(player));
}
private static IEnumerator HudRefreshNextFrame(Player player)
{
yield return null;
yield return null;
if (!((Object)(object)player == (Object)null) && player.Gear != null && player.Gear.Length > 5)
{
IGear val = player.Gear[5];
if (val != null)
{
EnsureStoredHudVisible(player, val);
}
}
}
internal static void EnsureStoredHudVisible(Player player, IGear gear)
{
//IL_0060: Unknown result type (might be due to invalid IL or missing references)
if ((Object)(object)player == (Object)null || gear == null)
{
return;
}
try
{
if (GearHudsField?.GetValue(player) is EquippableHUDOverlay[] array && array.Length >= 3 && !((Object)(object)array[2] == (Object)null))
{
if (!((Component)array[2]).gameObject.activeSelf)
{
((Component)array[2]).gameObject.SetActive(true);
}
array[2].Setup(gear, array[2].BasePos);
}
}
catch (Exception ex)
{
ManualLogSource log = HeavyIntegrationPlugin.Log;
if (log != null)
{
log.LogWarning((object)("Stored HUD setup failed: " + ex.Message));
}
}
}
private static void SetStoredHudActive(Player player, bool active)
{
try
{
if (GearHudsField?.GetValue(player) is EquippableHUDOverlay[] array && array.Length >= 3 && !((Object)(object)array[2] == (Object)null))
{
((Component)array[2]).gameObject.SetActive(active);
}
}
catch
{
}
}
}
[HarmonyPatch(typeof(ScrollArea), "Scroll")]
internal static class ScrollAreaNullGuard
{
[HarmonyPrefix]
private static bool Prefix(ScrollArea __instance)
{
try
{
if ((Object)(object)__instance == (Object)null)
{
return false;
}
if ((Object)(object)Traverse.Create((object)__instance).Field("scrollBar").GetValue<ScrollBar>() == (Object)null)
{
return false;
}
return true;
}
catch
{
return false;
}
}
}
[HarmonyPatch(typeof(WeaponSelectWindow), "Setup")]
internal static class WeaponSelectWindowSetupPatch
{
[HarmonyPrefix]
private static bool Prefix(WeaponSelectWindow __instance, GearType type)
{
if (ConfigManager.SelectionUiEnabled == null || !ConfigManager.SelectionUiEnabled.Value)
{
return true;
}
try
{
if ((Object)(object)__instance == (Object)null)
{
return false;
}
List<GearSlot> value = Traverse.Create((object)__instance).Field("gearSlots").GetValue<List<GearSlot>>();
if (value == null || value.Count == 0 || (Object)(object)value[0] == (Object)null)
{
ManualLogSource log = HeavyIntegrationPlugin.Log;
if (log != null)
{
log.LogWarning((object)"WeaponSelectWindow has no gearSlots prefab — skipping Setup.");
}
return false;
}
return true;
}
catch (Exception ex)
{
ManualLogSource log2 = HeavyIntegrationPlugin.Log;
if (log2 != null)
{
log2.LogDebug((object)("WeaponSelectWindow Setup prefix: " + ex.Message));
}
return true;
}
}
[HarmonyPostfix]
private static void Postfix(WeaponSelectWindow __instance, GearType type)
{
//IL_0049: Unknown result type (might be due to invalid IL or missing references)
if (ConfigManager.SelectionUiEnabled == null || !ConfigManager.SelectionUiEnabled.Value)
{
return;
}
try
{
if ((Object)(object)__instance == (Object)null)
{
return;
}
List<GearSlot> value = Traverse.Create((object)__instance).Field("gearSlots").GetValue<List<GearSlot>>();
if (value == null || value.Count == 0)
{
return;
}
int num = CountUnlockedOfType(type);
if (num < 0)
{
return;
}
for (int i = 0; i < value.Count; i++)
{
if (!((Object)(object)value[i] == (Object)null) && !((Object)(object)((Component)value[i]).gameObject == (Object)null))
{
((Component)value[i]).gameObject.SetActive(i < num);
}
}
if (num > 0)
{
WeaponSelectOverflow.Apply(__instance, value, num);
}
}
catch (Exception ex)
{
ManualLogSource log = HeavyIntegrationPlugin.Log;
if (log != null)
{
log.LogDebug((object)("WeaponSelectWindow Setup postfix: " + ex.Message));
}
}
}
private static int CountUnlockedOfType(GearType type)
{
//IL_0009: 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)
try
{
List<IUpgradable> list = new List<IUpgradable>(16);
GearSelectionWindow.GetSortedUnlockedGear(list, type, false);
int num = 0;
for (int i = 0; i < list.Count; i++)
{
if (list[i] != null && list[i].GearType == type)
{
num++;
}
}
return num;
}
catch
{
return -1;
}
}
}
[HarmonyPatch(typeof(GearSlot))]
internal static class GearSlotClickPatch
{
private static readonly FieldInfo SlotField = AccessTools.Field(typeof(GearSlot), "slot");
private static readonly FieldInfo ButtonField = AccessTools.Field(typeof(GearSlot), "button");
[HarmonyPatch("OnClick")]
[HarmonyPrefix]
private static bool OnClickPrefix(GearSlot __instance)
{
//IL_001d: Unknown result type (might be due to invalid IL or missing references)
//IL_0023: Invalid comparison between Unknown and I4
//IL_006c: Unknown result type (might be due to invalid IL or missing references)
//IL_0072: Invalid comparison between Unknown and I4
//IL_0077: Unknown result type (might be due to invalid IL or missing references)
if (!HeavyLoadoutService.IsEnabled || (Object)(object)__instance == (Object)null)
{
return true;
}
IUpgradable gear = __instance.Gear;
if (gear == null || (int)gear.GearType != 1)
{
return true;
}
int num = ((SlotField != null) ? ((int)SlotField.GetValue(__instance)) : (-1));
object? obj = ButtonField?.GetValue(__instance);
DefaultButton val = (DefaultButton)((obj is DefaultButton) ? obj : null);
if ((Object)(object)val == (Object)null)
{
return true;
}
if ((int)((Button)val).LastPressButton == 1)
{
return true;
}
if ((int)((Button)val).LastPressButton != 0)
{
return true;
}
if (!PlayerData.GetGearData(gear).IsUnlocked && num < 0)
{
return true;
}
if (num < 0)
{
HeavyLoadoutService.SelectOrToggleHeavy(gear);
return false;
}
return true;
}
[HarmonyPatch("GetPrimaryBinding")]
[HarmonyPostfix]
private static void GetPrimaryBindingPostfix(GearSlot __instance, ref bool __result, ref InputAction binding, ref string label)
{
//IL_001c: Unknown result type (might be due to invalid IL or missing references)
//IL_0022: Invalid comparison between Unknown and I4
//IL_0062: 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)
if (HeavyLoadoutService.IsEnabled && ((__instance != null) ? __instance.Gear : null) != null && (int)__instance.Gear.GearType == 1 && ((SlotField != null) ? ((int)SlotField.GetValue(__instance)) : (-1)) < 0 && PlayerData.GetGearData(__instance.Gear).IsUnlocked)
{
MenuActions menu = PlayerInput.Controls.Menu;
binding = ((MenuActions)(ref menu)).Click;
bool flag = HeavyLoadoutService.IsLoadoutHeavy(__instance.Gear);
label = (flag ? "Clear" : TextBlocks.GetString("equip"));
if (string.IsNullOrEmpty(label) || label == "equip")
{
label = (flag ? "Clear" : "Equip");
}
__result = true;
}
}
}
[HarmonyPatch]
internal static class GearSelectionWindowPatch
{
[HarmonyPatch(typeof(GearSelectionWindow), "OnCloseCallback")]
[HarmonyPostfix]
private static void OnClosePostfix()
{
if (HeavyLoadoutService.IsEnabled)
{
Player localPlayer = Player.LocalPlayer;
if (!((Object)(object)localPlayer == (Object)null) && ((NetworkBehaviour)localPlayer).IsOwner && localPlayer.IsGearInitialized)
{
HeavyLoadoutService.ScheduleApply(localPlayer);
}
}
}
[HarmonyPatch(typeof(ShowcaseGearSelectWindow), "OnCloseCallback")]
[HarmonyPostfix]
private static void ShowcaseClosePostfix()
{
if (HeavyLoadoutService.IsEnabled)
{
Player localPlayer = Player.LocalPlayer;
if (!((Object)(object)localPlayer == (Object)null) && ((NetworkBehaviour)localPlayer).IsOwner && localPlayer.IsGearInitialized)
{
HeavyLoadoutService.ScheduleApply(localPlayer, 2);
}
}
}
}
[HarmonyPatch]
internal static class PlayerGearPatches
{
[HarmonyPatch(typeof(Player), "OnAllGearSpawned_ClientRpc")]
[HarmonyPostfix]
private static void OnAllGearSpawnedPostfix(Player __instance)
{
if (HeavyLoadoutService.IsEnabled && !((Object)(object)__instance == (Object)null) && ((NetworkBehaviour)__instance).IsOwner && __instance.IsGearInitialized)
{
HeavyLoadoutService.ScheduleApply(__instance, 2);
}
}
[HarmonyPatch(typeof(Player), "SpawnGear_ClientRpc")]
[HarmonyPostfix]
private static void SpawnGearClientPostfix(Player __instance, int slot)
{
if (HeavyLoadoutService.IsEnabled && !((Object)(object)__instance == (Object)null) && ((NetworkBehaviour)__instance).IsOwner && slot == 5 && __instance.Gear != null && slot < __instance.Gear.Length)
{
IGear val = __instance.Gear[slot];
if (val != null)
{
HeavyLoadoutService.EnsureStoredHudVisible(__instance, val);
}
}
}
[HarmonyPatch(typeof(Player), "DropStoredGear")]
[HarmonyPostfix]
private static void DropStoredPostfix(Player __instance)
{
if (!((Object)(object)__instance == (Object)null) && ((NetworkBehaviour)__instance).IsOwner)
{
HeavyLoadoutService.OnStoredCleared(__instance);
}
}
[HarmonyPatch(typeof(Player), "OnGearRemoved")]
[HarmonyPostfix]
private static void OnGearRemovedPostfix(Player __instance, IGear gear)
{
if (!((Object)(object)__instance == (Object)null) && ((NetworkBehaviour)__instance).IsOwner && gear != null && __instance.Gear != null && __instance.Gear.Length > 5 && __instance.Gear[5] == null)
{
HeavyLoadoutService.OnStoredCleared(__instance);
}
}
[HarmonyPatch(typeof(Player), "OnStoredGearRemoved")]
[HarmonyPostfix]
private static void OnStoredGearRemovedPostfix(Player __instance)
{
if (!((Object)(object)__instance == (Object)null) && ((NetworkBehaviour)__instance).IsOwner)
{
HeavyLoadoutService.OnStoredCleared(__instance);
}
}
[HarmonyPatch(typeof(Player), "ReplaceStoredGear")]
[HarmonyPostfix]
private static void ReplaceStoredPostfix(Player __instance, IGear gear)
{
if (!((Object)(object)__instance == (Object)null) && ((NetworkBehaviour)__instance).IsOwner)
{
HeavyLoadoutService.OnReplaceStored(__instance, gear);
}
}
}
[BepInPlugin("sparroh.heavyintegration", "HeavyIntegration", "1.0.0")]
[MycoMod(/*Could not decode attribute arguments.*/)]
public class HeavyIntegrationPlugin : BaseUnityPlugin
{
public const string PluginGUID = "sparroh.heavyintegration";
public const string PluginName = "HeavyIntegration";
public const string PluginVersion = "1.0.0";
internal static ManualLogSource Log;
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
Log = ((BaseUnityPlugin)this).Logger;
try
{
ConfigManager.Initialize(((BaseUnityPlugin)this).Config, Log);
_harmony = new Harmony("sparroh.heavyintegration");
_harmony.PatchAll(typeof(GearSlotClickPatch));
_harmony.PatchAll(typeof(GearSelectionWindowPatch));
_harmony.PatchAll(typeof(PlayerGearPatches));
_harmony.PatchAll(typeof(HeavyFocusPatch));
HeavyAmmoRegenPatch.Apply(_harmony, Log);
_harmony.PatchAll(typeof(ScrollAreaNullGuard));
_harmony.PatchAll(typeof(WeaponSelectWindowSetupPatch));
Log.LogInfo((object)"HeavyIntegration v1.0.0 loaded — loadout heavy, ammo regen, heavy focus, selection UI.");
}
catch (Exception arg)
{
Log.LogError((object)string.Format("Failed to initialize {0}: {1}", "HeavyIntegration", arg));
}
}
private void Update()
{
ConfigManager.Tick();
}
private void OnDestroy()
{
try
{
ConfigManager.Dispose();
Harmony harmony = _harmony;
if (harmony != null)
{
harmony.UnpatchSelf();
}
}
catch (Exception arg)
{
ManualLogSource log = Log;
if (log != null)
{
log.LogError((object)string.Format("Failed to tear down {0}: {1}", "HeavyIntegration", arg));
}
}
}
}
internal static class WeaponSelectOverflow
{
private const float FallbackPadding = 10f;
private const float TopPadding = 6f;
private const float MinStepFactor = 0.5f;
private static readonly Dictionary<int, Vector2> PrefabRest = new Dictionary<int, Vector2>(4);
private static RectTransform _boundContainer;
private static float _boundMaxScroll;
private static float _boundContentX;
private static float _boundRestY;
public static void Apply(WeaponSelectWindow window, List<GearSlot> slots, int activeCount)
{
//IL_02bc: 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_0055: 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)
//IL_0061: Unknown result type (might be due to invalid IL or missing references)
//IL_0152: Unknown result type (might be due to invalid IL or missing references)
//IL_0158: 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_0169: Unknown result type (might be due to invalid IL or missing references)
//IL_0113: Unknown result type (might be due to invalid IL or missing references)
//IL_02cb: Unknown result type (might be due to invalid IL or missing references)
//IL_0212: Unknown result type (might be due to invalid IL or missing references)
//IL_021e: Unknown result type (might be due to invalid IL or missing references)
//IL_027e: Unknown result type (might be due to invalid IL or missing references)
if ((Object)(object)window == (Object)null || slots == null || activeCount <= 0)
{
return;
}
GearSlot val = slots[0];
if ((Object)(object)val == (Object)null)
{
return;
}
Transform parent = ((Component)val).transform.parent;
RectTransform val2 = (RectTransform)(object)((parent is RectTransform) ? parent : null);
if ((Object)(object)val2 == (Object)null)
{
return;
}
int instanceID = ((Object)val2).GetInstanceID();
if (!PrefabRest.TryGetValue(instanceID, out var value))
{
value = val2.anchoredPosition;
PrefabRest[instanceID] = value;
}
val2.anchoredPosition = value;
if (!TryMeasureLayout(slots, activeCount, out var originX, out var originY, out var stepY, out var slotHeight))
{
return;
}
LayoutGroup component = ((Component)val2).GetComponent<LayoutGroup>();
if ((Object)(object)component != (Object)null)
{
((Behaviour)component).enabled = false;
}
float contentHeight = slotHeight + stepY * (float)Mathf.Max(activeCount - 1, 0);
RectTransform val3 = ResolveViewport(window, val2, contentHeight);
if ((Object)(object)val3 == (Object)null)
{
Transform transform = ((Component)window).transform;
val3 = (RectTransform)(object)((transform is RectTransform) ? transform : null);
}
EnsureRectMask(val3);
for (int i = 0; i < activeCount; i++)
{
GearSlot val4 = slots[i];
if ((Object)(object)val4 == (Object)null)
{
continue;
}
Transform transform2 = ((Component)val4).transform;
RectTransform val5 = (RectTransform)(object)((transform2 is RectTransform) ? transform2 : null);
if (!((Object)(object)val5 == (Object)null))
{
val5.anchoredPosition = new Vector2(originX, originY - stepY * (float)i);
if (!((Component)val4).gameObject.activeSelf)
{
((Component)val4).gameObject.SetActive(true);
}
}
}
Canvas.ForceUpdateCanvases();
Vector2 val6 = AlignFirstSlotToViewportTop(slots[0], val2, val3, value.x);
Canvas.ForceUpdateCanvases();
float num = ComputeMaxScroll(slots, activeCount, val3, val2, val6);
ScrollArea componentInChildren = ((Component)window).GetComponentInChildren<ScrollArea>(true);
ScrollBar val7 = (((Object)(object)componentInChildren != (Object)null) ? componentInChildren.ScrollBar : null);
if ((Object)(object)val7 == (Object)null)
{
val7 = ((Component)window).GetComponentInChildren<ScrollBar>(true);
}
if ((Object)(object)componentInChildren != (Object)null && (Object)(object)val7 != (Object)null)
{
try
{
componentInChildren.ItemContainer = val2;
Traverse.Create((object)componentInChildren).Field("autoScrollContainer").SetValue((object)val2);
val7.OnDrag.RemoveListener((UnityAction<Vector2>)OnExistingBarDrag);
_boundContainer = val2;
_boundMaxScroll = num;
_boundContentX = val6.x;
_boundRestY = val6.y;
val7.OnDrag.AddListener((UnityAction<Vector2>)OnExistingBarDrag);
if (num <= 0f)
{
val7.ScrollSpeed = 0f;
}
else
{
val7.ScrollSpeed = 475f / num * 0.001f;
}
val2.anchoredPosition = val6;
val7.SetScrollYNoInvoke(1f);
}
catch (Exception ex)
{
ManualLogSource log = HeavyIntegrationPlugin.Log;
if (log != null)
{
log.LogDebug((object)("ScrollArea wire failed: " + ex.Message));
}
AttachFallbackDriver(window, val3, val2, num, val6);
}
}
else
{
AttachFallbackDriver(window, val3, val2, num, val6);
}
EnsureRaycastTarget(val3);
}
private static void OnExistingBarDrag(Vector2 value)
{
//IL_001e: 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)
if (!((Object)(object)_boundContainer == (Object)null))
{
float num = Mathf.LerpUnclamped(_boundRestY + _boundMaxScroll, _boundRestY, value.y);
_boundContainer.anchoredPosition = new Vector2(_boundContentX, num);
}
}
private static bool TryMeasureLayout(List<GearSlot> slots, int activeCount, out float originX, out float originY, out float stepY, out float slotHeight)
{
//IL_003d: 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_0058: 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_0066: Unknown result type (might be due to invalid IL or missing references)
//IL_00c6: Unknown result type (might be due to invalid IL or missing references)
originX = 0f;
originY = 0f;
stepY = 0f;
slotHeight = 0f;
Transform transform = ((Component)slots[0]).transform;
RectTransform val = (RectTransform)(object)((transform is RectTransform) ? transform : null);
if ((Object)(object)val == (Object)null)
{
return false;
}
originX = val.anchoredPosition.x;
originY = val.anchoredPosition.y;
Rect rect = val.rect;
slotHeight = Mathf.Max(((Rect)(ref rect)).height, Mathf.Abs(val.sizeDelta.y));
if (slotHeight < 1f)
{
slotHeight = 80f;
}
stepY = 0f;
for (int i = 1; i < slots.Count && i < activeCount; i++)
{
if ((Object)(object)slots[i] == (Object)null)
{
continue;
}
Transform transform2 = ((Component)slots[i]).transform;
RectTransform val2 = (RectTransform)(object)((transform2 is RectTransform) ? transform2 : null);
if (!((Object)(object)val2 == (Object)null))
{
float num = originY - val2.anchoredPosition.y;
if (num > slotHeight * 0.5f)
{
stepY = num;
break;
}
}
}
if (stepY < 1f)
{
stepY = slotHeight + 10f;
}
return true;
}
private static Vector2 AlignFirstSlotToViewportTop(GearSlot first, RectTransform slotParent, RectTransform viewport, float contentX)
{
//IL_0001: Unknown result type (might be due to invalid IL or missing references)
//IL_0006: Unknown result type (might be due to invalid IL or missing references)
//IL_0010: Unknown result type (might be due to invalid IL or missing references)
//IL_0032: 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_004e: Unknown result type (might be due to invalid IL or missing references)
//IL_014f: Unknown result type (might be due to invalid IL or missing references)
//IL_0089: Unknown result type (might be due to invalid IL or missing references)
//IL_008e: Unknown result type (might be due to invalid IL or missing references)
//IL_0091: 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_00a1: 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_00b3: Unknown result type (might be due to invalid IL or missing references)
//IL_00b8: Unknown result type (might be due to invalid IL or missing references)
//IL_00bc: Unknown result type (might be due to invalid IL or missing references)
//IL_00c1: 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_00cf: 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_00e7: 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_00f1: 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_00f9: Unknown result type (might be due to invalid IL or missing references)
//IL_00fe: 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_010a: Unknown result type (might be due to invalid IL or missing references)
//IL_012c: Unknown result type (might be due to invalid IL or missing references)
//IL_0131: Unknown result type (might be due to invalid IL or missing references)
//IL_0148: Unknown result type (might be due to invalid IL or missing references)
Vector2 anchoredPosition = slotParent.anchoredPosition;
anchoredPosition.x = contentX;
slotParent.anchoredPosition = anchoredPosition;
if ((Object)(object)first == (Object)null || (Object)(object)viewport == (Object)null || (Object)(object)slotParent == (Object)(object)viewport)
{
return slotParent.anchoredPosition;
}
Transform transform = ((Component)first).transform;
RectTransform val = (RectTransform)(object)((transform is RectTransform) ? transform : null);
if ((Object)(object)val == (Object)null)
{
return slotParent.anchoredPosition;
}
Canvas.ForceUpdateCanvases();
float rectEdgeInOther = GetRectEdgeInOther(val, viewport, top: true);
Rect rect = viewport.rect;
if (Mathf.Abs(((Rect)(ref rect)).yMax - 6f - rectEdgeInOther) > 0.5f)
{
rect = val.rect;
float x = ((Rect)(ref rect)).center.x;
rect = val.rect;
Vector3 val2 = ((Transform)val).TransformPoint(new Vector3(x, ((Rect)(ref rect)).yMax, 0f));
rect = viewport.rect;
float x2 = ((Rect)(ref rect)).center.x;
rect = viewport.rect;
Vector3 val3 = ((Transform)viewport).TransformPoint(new Vector3(x2, ((Rect)(ref rect)).yMax - 6f, 0f)) - val2;
Vector3 up = ((Transform)slotParent).up;
float num = Vector3.Dot(val3, up);
float y = ((Transform)slotParent).lossyScale.y;
if (Mathf.Abs(y) > 0.0001f)
{
num /= y;
}
anchoredPosition = slotParent.anchoredPosition;
anchoredPosition.y += num;
anchoredPosition.x = contentX;
slotParent.anchoredPosition = anchoredPosition;
}
return slotParent.anchoredPosition;
}
private static float GetRectEdgeInOther(RectTransform source, RectTransform other, bool top)
{
//IL_0014: 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_0004: Unknown result type (might be due to invalid IL or missing references)
//IL_0009: 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_002c: Unknown result type (might be due to invalid IL or missing references)
//IL_003c: Unknown result type (might be due to invalid IL or missing references)
//IL_0041: Unknown result type (might be due to invalid IL or missing references)
//IL_0046: Unknown result type (might be due to invalid IL or missing references)
//IL_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)
Rect rect;
float num;
if (!top)
{
rect = source.rect;
num = ((Rect)(ref rect)).yMin;
}
else
{
rect = source.rect;
num = ((Rect)(ref rect)).yMax;
}
float num2 = num;
rect = source.rect;
Vector3 val = ((Transform)source).TransformPoint(new Vector3(((Rect)(ref rect)).center.x, num2, 0f));
return ((Transform)other).InverseTransformPoint(val).y;
}
private static float ComputeMaxScroll(List<GearSlot> slots, int activeCount, RectTransform viewport, RectTransform slotParent, Vector2 restPos)
{
//IL_0097: Unknown result type (might be due to invalid IL or missing references)
//IL_0125: Unknown result type (might be due to invalid IL or missing references)
//IL_012a: Unknown result type (might be due to invalid IL or missing references)
//IL_00b5: Unknown result type (might be due to invalid IL or missing references)
//IL_00ba: 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_00ec: Unknown result type (might be due to invalid IL or missing references)
//IL_00fb: 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)
if ((Object)(object)viewport == (Object)null || (Object)(object)slotParent == (Object)null || activeCount <= 0)
{
return 0f;
}
GearSlot val = null;
for (int num = activeCount - 1; num >= 0; num--)
{
if ((Object)(object)slots[num] != (Object)null && (Object)(object)((Component)slots[num]).gameObject != (Object)null && ((Component)slots[num]).gameObject.activeSelf)
{
val = slots[num];
break;
}
}
if ((Object)(object)val == (Object)null)
{
return 0f;
}
Transform transform = ((Component)val).transform;
RectTransform val2 = (RectTransform)(object)((transform is RectTransform) ? transform : null);
if ((Object)(object)val2 == (Object)null)
{
return 0f;
}
slotParent.anchoredPosition = restPos;
Canvas.ForceUpdateCanvases();
Rect rect;
if ((Object)(object)viewport == (Object)(object)slotParent)
{
float[] array = new float[3];
rect = val2.rect;
array[0] = ((Rect)(ref rect)).height;
array[1] = Mathf.Abs(val2.sizeDelta.y);
array[2] = 1f;
float num2 = Mathf.Max(array);
float num3 = 0f - val2.anchoredPosition.y + num2;
rect = viewport.rect;
return Mathf.Max(num3 - ((Rect)(ref rect)).height + 10f, 0f);
}
float rectEdgeInOther = GetRectEdgeInOther(val2, viewport, top: false);
rect = viewport.rect;
return Mathf.Max(((Rect)(ref rect)).yMin - rectEdgeInOther + 10f, 0f);
}
private static RectTransform ResolveViewport(WeaponSelectWindow window, RectTransform slotParent, float contentHeight)
{
//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_008f: 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_00ae: 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)
Transform val = (Transform)(object)slotParent;
int num = 0;
Rect rect;
while ((Object)(object)val != (Object)null && num < 10)
{
RectTransform val2 = (RectTransform)(object)((val is RectTransform) ? val : null);
if (val2 != null && (Object)(object)val != (Object)(object)slotParent)
{
rect = val2.rect;
if (((Rect)(ref rect)).height > 40f && ((Object)(object)((Component)val2).GetComponent<RectMask2D>() != (Object)null || (Object)(object)((Component)val2).GetComponent<Mask>() != (Object)null))
{
return val2;
}
}
if ((Object)(object)val == (Object)(object)((Component)window).transform)
{
break;
}
val = val.parent;
num++;
}
RectTransform val3 = null;
val = ((Transform)slotParent).parent;
num = 0;
while ((Object)(object)val != (Object)null && num < 8)
{
RectTransform val4 = (RectTransform)(object)((val is RectTransform) ? val : null);
if (val4 != null)
{
rect = val4.rect;
if (((Rect)(ref rect)).height > 40f)
{
if (contentHeight > 0f)
{
rect = val4.rect;
if (((Rect)(ref rect)).height + 1f < contentHeight)
{
return val4;
}
}
if ((Object)(object)val3 == (Object)null)
{
val3 = val4;
}
}
}
if ((Object)(object)val == (Object)(object)((Component)window).transform)
{
break;
}
val = val.parent;
num++;
}
if ((Object)(object)val3 != (Object)null)
{
return val3;
}
Transform transform = ((Component)window).transform;
return (RectTransform)(object)((transform is RectTransform) ? transform : null);
}
private static void EnsureRectMask(RectTransform viewport)
{
if (!((Object)(object)viewport == (Object)null) && (Object)(object)((Component)viewport).GetComponent<RectMask2D>() == (Object)null && (Object)(object)((Component)viewport).GetComponent<Mask>() == (Object)null)
{
((Component)viewport).gameObject.AddComponent<RectMask2D>();
}
}
private static void EnsureRaycastTarget(RectTransform viewport)
{
//IL_003a: Unknown result type (might be due to invalid IL or missing references)
if (!((Object)(object)viewport == (Object)null))
{
Graphic component = ((Component)viewport).GetComponent<Graphic>();
if ((Object)(object)component == (Object)null)
{
Image obj = ((Component)viewport).gameObject.AddComponent<Image>();
((Graphic)obj).color = new Color(0f, 0f, 0f, 0f);
((Graphic)obj).raycastTarget = true;
}
else
{
component.raycastTarget = true;
}
}
}
private static void AttachFallbackDriver(WeaponSelectWindow window, RectTransform viewport, RectTransform content, float maxScroll, Vector2 restPos)
{
//IL_0020: Unknown result type (might be due to invalid IL or missing references)
WeaponSelectScrollDriver weaponSelectScrollDriver = ((Component)window).GetComponent<WeaponSelectScrollDriver>();
if ((Object)(object)weaponSelectScrollDriver == (Object)null)
{
weaponSelectScrollDriver = ((Component)window).gameObject.AddComponent<WeaponSelectScrollDriver>();
}
weaponSelectScrollDriver.Configure(viewport, content, maxScroll, restPos);
}
}
internal sealed class WeaponSelectScrollDriver : MonoBehaviour, IPointerEnterHandler, IEventSystemHandler, IPointerExitHandler
{
private RectTransform _viewport;
private RectTransform _content;
private float _maxScroll;
private float _contentX;
private float _restY;
private float _normalized = 1f;
private bool _hovering;
private Action<CallbackContext> _onScrollCallback;
public void Configure(RectTransform viewport, RectTransform content, float maxScroll, Vector2 restPos)
{
//IL_0020: Unknown result type (might be due to invalid IL or missing references)
//IL_002d: Unknown result type (might be due to invalid IL or missing references)
_viewport = viewport;
_content = content;
_maxScroll = Mathf.Max(0f, maxScroll);
_contentX = restPos.x;
_restY = restPos.y;
_normalized = 1f;
ApplyPosition();
if ((Object)(object)_viewport != (Object)null)
{
WeaponSelectScrollViewportProxy weaponSelectScrollViewportProxy = ((Component)_viewport).GetComponent<WeaponSelectScrollViewportProxy>();
if ((Object)(object)weaponSelectScrollViewportProxy == (Object)null)
{
weaponSelectScrollViewportProxy = ((Component)_viewport).gameObject.AddComponent<WeaponSelectScrollViewportProxy>();
}
weaponSelectScrollViewportProxy.Bind(this);
}
}
public void OnPointerEnter(PointerEventData eventData)
{
SetHovering(hovering: true);
}
public void OnPointerExit(PointerEventData eventData)
{
SetHovering(hovering: false);
}
internal void SetHovering(bool hovering)
{
//IL_0042: Unknown result type (might be due to invalid IL or missing references)
//IL_0047: Unknown result type (might be due to invalid IL or missing references)
//IL_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)
if (_hovering != hovering)
{
_hovering = hovering;
EnsureScrollCallback();
MenuActions menu;
if (_hovering)
{
menu = PlayerInput.Controls.Menu;
((MenuActions)(ref menu)).ScrollWheel.performed += _onScrollCallback;
}
else
{
menu = PlayerInput.Controls.Menu;
((MenuActions)(ref menu)).ScrollWheel.performed -= _onScrollCallback;
}
}
}
private void OnDisable()
{
//IL_000d: 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)
if (_onScrollCallback != null)
{
MenuActions menu = PlayerInput.Controls.Menu;
((MenuActions)(ref menu)).ScrollWheel.performed -= _onScrollCallback;
}
_hovering = false;
}
private void OnDestroy()
{
//IL_000d: 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)
if (_onScrollCallback != null)
{
try
{
MenuActions menu = PlayerInput.Controls.Menu;
((MenuActions)(ref menu)).ScrollWheel.performed -= _onScrollCallback;
}
catch
{
}
}
}
private void EnsureScrollCallback()
{
if (_onScrollCallback == null)
{
_onScrollCallback = OnScrollPerformed;
}
}
private void OnScrollPerformed(CallbackContext context)
{
//IL_0016: Unknown result type (might be due to invalid IL or missing references)
//IL_0020: Unknown result type (might be due to invalid IL or missing references)
//IL_002a: Unknown result type (might be due to invalid IL or missing references)
//IL_002f: Unknown result type (might be due to invalid IL or missing references)
//IL_004a: Unknown result type (might be due to invalid IL or missing references)
if (_hovering && !(_maxScroll <= 0f) && (int)PlayerInput.Device == 0)
{
Vector2 val = ((CallbackContext)(ref context)).ReadValue<Vector2>() * 120f;
float num = 475f / _maxScroll * 0.001f;
_normalized = Mathf.Clamp01(_normalized + val.y * num);
ApplyPosition();
}
}
private void Update()
{
//IL_0016: 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_0028: 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_0035: 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_003f: 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_005b: 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_007b: Unknown result type (might be due to invalid IL or missing references)
if (_hovering && !(_maxScroll <= 0f) && (int)PlayerInput.Device != 0)
{
MenuActions menu = PlayerInput.Controls.Menu;
Vector2 val = ((MenuActions)(ref menu)).ScrollWheel.ReadValue<Vector2>();
if (!(val == default(Vector2)))
{
Vector2 val2 = val * (Time.unscaledDeltaTime * 1000f * 120f);
float num = 475f / _maxScroll * 0.001f;
_normalized = Mathf.Clamp01(_normalized + val2.y * num);
ApplyPosition();
}
}
}
private void ApplyPosition()
{
//IL_0050: Unknown result type (might be due to invalid IL or missing references)
if (!((Object)(object)_content == (Object)null))
{
float num = ((_maxScroll <= 0f) ? _restY : Mathf.LerpUnclamped(_restY + _maxScroll, _restY, _normalized));
_content.anchoredPosition = new Vector2(_contentX, num);
}
}
}
internal sealed class WeaponSelectScrollViewportProxy : MonoBehaviour, IPointerEnterHandler, IEventSystemHandler, IPointerExitHandler
{
private WeaponSelectScrollDriver _driver;
public void Bind(WeaponSelectScrollDriver driver)
{
_driver = driver;
}
public void OnPointerEnter(PointerEventData eventData)
{
_driver?.SetHovering(hovering: true);
}
public void OnPointerExit(PointerEventData eventData)
{
_driver?.SetHovering(hovering: false);
}
private void OnDisable()
{
_driver?.SetHovering(hovering: false);
}
}
public static class MyPluginInfo
{
public const string PLUGIN_GUID = "HeavyIntegration";
public const string PLUGIN_NAME = "HeavyIntegration";
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)
{
}
}
}