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 System.Text.RegularExpressions;
using BepInEx;
using BepInEx.Bootstrap;
using BepInEx.Configuration;
using BepInEx.Logging;
using EntityStates;
using EntityStates.Drifter;
using EntityStates.Drifter.Bag;
using HarmonyLib;
using Microsoft.CodeAnalysis;
using RiskOfOptions;
using RiskOfOptions.Options;
using RoR2;
using RoR2.Projectile;
using UnityEngine;
using UnityEngine.AddressableAssets;
using UnityEngine.Networking;
using UnityEngine.SceneManagement;
[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")]
[assembly: AssemblyCompany("com.pwdcat.CleanupSnatcher")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("1.0.2.0")]
[assembly: AssemblyInformationalVersion("1.0.2")]
[assembly: AssemblyProduct("com.pwdcat.CleanupSnatcher")]
[assembly: AssemblyTitle("CleanupSnatcher")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.0.2.0")]
[module: UnverifiableCode]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
[CompilerGenerated]
[Microsoft.CodeAnalysis.Embedded]
internal sealed class EmbeddedAttribute : Attribute
{
}
}
namespace System.Runtime.CompilerServices
{
[CompilerGenerated]
[Microsoft.CodeAnalysis.Embedded]
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Parameter | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter, AllowMultiple = false, Inherited = false)]
internal sealed class NullableAttribute : Attribute
{
public readonly byte[] NullableFlags;
public NullableAttribute(byte P_0)
{
NullableFlags = new byte[1] { P_0 };
}
public NullableAttribute(byte[] P_0)
{
NullableFlags = P_0;
}
}
[CompilerGenerated]
[Microsoft.CodeAnalysis.Embedded]
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Method | AttributeTargets.Interface | AttributeTargets.Delegate, AllowMultiple = false, Inherited = false)]
internal sealed class NullableContextAttribute : Attribute
{
public readonly byte Flag;
public NullableContextAttribute(byte P_0)
{
Flag = P_0;
}
}
[CompilerGenerated]
[Microsoft.CodeAnalysis.Embedded]
[AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)]
internal sealed class RefSafetyRulesAttribute : Attribute
{
public readonly int Version;
public RefSafetyRulesAttribute(int P_0)
{
Version = P_0;
}
}
}
namespace BepInEx
{
[AttributeUsage(AttributeTargets.Class, Inherited = false, AllowMultiple = false)]
[Conditional("CodeGeneration")]
internal sealed class BepInAutoPluginAttribute : Attribute
{
public BepInAutoPluginAttribute(string? id = null, string? name = null, string? version = null)
{
}
}
}
namespace BepInEx.Preloader.Core.Patching
{
[AttributeUsage(AttributeTargets.Class, Inherited = false, AllowMultiple = false)]
[Conditional("CodeGeneration")]
internal sealed class PatcherAutoPluginAttribute : Attribute
{
public PatcherAutoPluginAttribute(string? id = null, string? name = null, string? version = null)
{
}
}
}
namespace CleanupSnatcher
{
internal static class Constants
{
public const string LogPrefix = "[CleanupSnatcher]";
public const string PluginGuid = "pwdcat.CleanupSnatcher";
public const string PluginName = "CleanupSnatcher";
public const string PluginVersion = "1.0.0";
}
internal static class Log
{
private static ManualLogSource? _logSource;
private const string ERROR_PREFIX = "[ERROR] ";
private const string FATAL_PREFIX = "[FATAL] ";
private const string INFO_PREFIX = "[INFO] ";
private const string WARNING_PREFIX = "[WARNING] ";
internal static bool EnableDebugLogs { get; set; }
internal static void Init(ManualLogSource logSource)
{
_logSource = logSource;
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
internal static void Error(object data)
{
ManualLogSource? logSource = _logSource;
if (logSource != null)
{
logSource.LogMessage((object)("[ERROR] " + data));
}
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
internal static void Fatal(object data)
{
ManualLogSource? logSource = _logSource;
if (logSource != null)
{
logSource.LogMessage((object)("[FATAL] " + data));
}
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
internal static void Info(object data)
{
if (EnableDebugLogs)
{
ManualLogSource? logSource = _logSource;
if (logSource != null)
{
logSource.LogMessage((object)("[INFO] " + data));
}
}
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
internal static void Message(object data)
{
ManualLogSource? logSource = _logSource;
if (logSource != null)
{
logSource.LogMessage(data);
}
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
internal static void Warning(object data)
{
ManualLogSource? logSource = _logSource;
if (logSource != null)
{
logSource.LogMessage((object)("[WARNING] " + data));
}
}
}
[BepInPlugin("pwdcat.CleanupSnatcher", "CleanupSnatcher", "1.0.0")]
public class CleanupSnatcherPlugin : BaseUnityPlugin
{
private EventHandler debugLogsHandler;
private EventHandler projectileGrabbingHandler;
public static CleanupSnatcherPlugin Instance { get; private set; }
public static bool RooInstalled => Chainloader.PluginInfos.ContainsKey("com.rune580.riskofoptions");
public string DirectoryName => Path.GetDirectoryName(((BaseUnityPlugin)this).Info.Location);
public void Awake()
{
Instance = this;
Log.Init(((BaseUnityPlugin)this).Logger);
Log.Info("[CleanupSnatcher] CleanupSnatcherPlugin.Awake() called");
PluginConfig.Init(((BaseUnityPlugin)this).Config);
Log.EnableDebugLogs = PluginConfig.EnableDebugLogs.Value;
Log.Info(string.Format("{0} Debug logs enabled: {1}", "[CleanupSnatcher]", Log.EnableDebugLogs));
SetupConfigurationEventHandlers();
ApplyHarmonyPatches();
RegisterGameEvents();
Log.Info("[CleanupSnatcher] Plugin initialization complete");
}
public void OnDestroy()
{
PluginConfig.RemoveEventHandlers(debugLogsHandler, projectileGrabbingHandler);
}
public void Start()
{
SetupRiskOfOptions();
}
private void SetupConfigurationEventHandlers()
{
debugLogsHandler = delegate
{
Log.EnableDebugLogs = PluginConfig.EnableDebugLogs.Value;
};
PluginConfig.EnableDebugLogs.SettingChanged += debugLogsHandler;
projectileGrabbingHandler = delegate
{
};
PluginConfig.EnableProjectileGrabbing.SettingChanged += projectileGrabbingHandler;
}
private void ApplyHarmonyPatches()
{
//IL_0005: Unknown result type (might be due to invalid IL or missing references)
//IL_000b: Expected O, but got Unknown
Harmony val = new Harmony("pwdcat.CleanupSnatcher");
val.PatchAll();
}
private void RegisterGameEvents()
{
SceneManager.activeSceneChanged += OnSceneChanged;
}
private static void OnSceneChanged(Scene oldScene, Scene newScene)
{
if (PluginConfig.EnableDebugLogs.Value)
{
Log.Info("[CleanupSnatcher] Scene changed from " + ((Scene)(ref oldScene)).name + " to " + ((Scene)(ref newScene)).name);
}
}
private void SetupRiskOfOptions()
{
//IL_003c: Unknown result type (might be due to invalid IL or missing references)
//IL_0042: Expected O, but got Unknown
//IL_005f: 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)
if (RooInstalled)
{
ModSettingsManager.SetModDescription("Allows Drifter to grab projectiles from their Cleanup ability.", "pwdcat.CleanupSnatcher", "CleanupSnatcher");
try
{
byte[] array = File.ReadAllBytes(Path.Combine(DirectoryName, "icon.png"));
Texture2D val = new Texture2D(256, 256);
ImageConversion.LoadImage(val, array);
ModSettingsManager.SetModIcon(Sprite.Create(val, new Rect(0f, 0f, 256f, 256f), new Vector2(0.5f, 0.5f)));
}
catch (Exception)
{
}
AddConfigurationOptions();
}
}
private void AddConfigurationOptions()
{
//IL_000d: Unknown result type (might be due to invalid IL or missing references)
//IL_0017: Expected O, but got Unknown
//IL_001c: Unknown result type (might be due to invalid IL or missing references)
//IL_0026: Expected O, but got Unknown
if (RooInstalled)
{
ModSettingsManager.AddOption((BaseOption)new CheckBoxOption(PluginConfig.EnableProjectileGrabbing));
ModSettingsManager.AddOption((BaseOption)new CheckBoxOption(PluginConfig.EnableDebugLogs));
}
}
}
public static class PluginConfig
{
public static ConfigEntry<bool> EnableProjectileGrabbing { get; private set; }
public static ConfigEntry<bool> EnableDebugLogs { get; private set; }
public static void Init(ConfigFile cfg)
{
EnableProjectileGrabbing = cfg.Bind<bool>("General", "EnableProjectileGrabbing", true, "Enable grabbing of projectiles from Drifter's Cleanup ability");
EnableDebugLogs = cfg.Bind<bool>("General", "EnableDebugLogs", false, "Enable debug logging for projectile grabbing operations");
}
public static void RemoveEventHandlers(EventHandler debugLogsHandler, EventHandler projectileGrabbingHandler)
{
EnableDebugLogs.SettingChanged -= debugLogsHandler;
EnableProjectileGrabbing.SettingChanged -= projectileGrabbingHandler;
}
}
}
namespace CleanupSnatcher.Patches
{
public static class ProjectilePatches
{
[HarmonyPatch(typeof(DrifterCleanupController), "ToggleVisuals")]
public class DrifterCleanupController_ToggleVisuals_Patch
{
[HarmonyPrefix]
public static void Prefix(DrifterCleanupController __instance, GameObject target, bool enabled, float duration)
{
if (PluginConfig.EnableDebugLogs.Value)
{
Log.Info(string.Format("{0} ToggleVisuals called - target: {1}, enabled: {2}, duration: {3}", "[CleanupSnatcher]", (target != null) ? ((Object)target).name : null, enabled, duration));
}
_isToggleVisualsDisplayActive = enabled;
if (!enabled)
{
_shouldMakeNextProjectilesGrabbable = false;
if (PluginConfig.EnableDebugLogs.Value)
{
Log.Info("[CleanupSnatcher] Display disabled - clearing grab flag");
}
}
}
}
[HarmonyPatch(typeof(ProjectileManager), "FireProjectileServer", new Type[]
{
typeof(FireProjectileInfo),
typeof(NetworkConnection),
typeof(ushort),
typeof(double)
})]
public class ProjectileManager_FireProjectileServer_Patch
{
[HarmonyPostfix]
public static void Postfix(FireProjectileInfo fireProjectileInfo)
{
//IL_0021: 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_0037: 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_0086: Unknown result type (might be due to invalid IL or missing references)
if (PluginConfig.EnableDebugLogs.Value)
{
object[] obj = new object[4] { "[CleanupSnatcher]", null, null, null };
GameObject projectilePrefab = fireProjectileInfo.projectilePrefab;
obj[1] = ((projectilePrefab != null) ? ((Object)projectilePrefab).name : null);
obj[2] = fireProjectileInfo.position;
GameObject owner = fireProjectileInfo.owner;
obj[3] = ((owner != null) ? ((Object)owner).name : null);
Log.Info(string.Format("{0} ProjectileManager.FireProjectileServer - prefab: {1}, position: {2}, owner: {3}", obj));
}
if (PluginConfig.EnableProjectileGrabbing.Value && _shouldMakeNextProjectilesGrabbable)
{
if (PluginConfig.EnableDebugLogs.Value)
{
GameObject projectilePrefab2 = fireProjectileInfo.projectilePrefab;
Log.Info("[CleanupSnatcher] ProjectileManager.FireProjectileServer - flag set for projectile: " + ((projectilePrefab2 != null) ? ((Object)projectilePrefab2).name : null));
}
_shouldMakeNextProjectilesGrabbable = false;
}
}
}
[HarmonyPatch(typeof(NetworkServer), "Spawn", new Type[] { typeof(GameObject) })]
public class NetworkServer_Spawn_Patch
{
[HarmonyPostfix]
public static void Postfix(GameObject obj)
{
if (PluginConfig.EnableProjectileGrabbing.Value && _shouldMakeNextProjectilesGrabbable && !((Object)(object)obj == (Object)null) && (Object)(object)obj.GetComponent<ProjectileController>() != (Object)null)
{
if (PluginConfig.EnableDebugLogs.Value)
{
Log.Info("[CleanupSnatcher] NetworkServer.Spawn - making projectile grabbable: " + ((Object)obj).name);
}
AddSpecialObjectAttributesToProjectile(obj);
_activeProjectile = obj;
if (PluginConfig.EnableDebugLogs.Value)
{
Log.Info("[CleanupSnatcher] Set active projectile: " + ((Object)obj).name);
}
}
}
}
[HarmonyPatch(typeof(GenericSkill), "ExecuteIfReady")]
public class GenericSkill_ExecuteIfReady_Patch
{
[HarmonyPrefix]
public static bool Prefix(GenericSkill __instance, ref bool __result)
{
//IL_060a: Unknown result type (might be due to invalid IL or missing references)
//IL_061b: Unknown result type (might be due to invalid IL or missing references)
//IL_061d: Unknown result type (might be due to invalid IL or missing references)
//IL_0624: Unknown result type (might be due to invalid IL or missing references)
//IL_0626: Unknown result type (might be due to invalid IL or missing references)
//IL_062b: Unknown result type (might be due to invalid IL or missing references)
//IL_0630: Unknown result type (might be due to invalid IL or missing references)
//IL_0661: Unknown result type (might be due to invalid IL or missing references)
//IL_0677: Unknown result type (might be due to invalid IL or missing references)
//IL_0679: Unknown result type (might be due to invalid IL or missing references)
//IL_0680: Unknown result type (might be due to invalid IL or missing references)
//IL_05f0: Unknown result type (might be due to invalid IL or missing references)
//IL_05f7: Unknown result type (might be due to invalid IL or missing references)
//IL_048f: Unknown result type (might be due to invalid IL or missing references)
//IL_049b: Unknown result type (might be due to invalid IL or missing references)
//IL_04a5: Unknown result type (might be due to invalid IL or missing references)
//IL_04aa: Unknown result type (might be due to invalid IL or missing references)
//IL_04af: Unknown result type (might be due to invalid IL or missing references)
//IL_04b9: Unknown result type (might be due to invalid IL or missing references)
//IL_04be: Unknown result type (might be due to invalid IL or missing references)
//IL_04c3: Unknown result type (might be due to invalid IL or missing references)
//IL_04cc: Unknown result type (might be due to invalid IL or missing references)
//IL_04d1: Unknown result type (might be due to invalid IL or missing references)
//IL_03d5: Unknown result type (might be due to invalid IL or missing references)
//IL_03fa: Unknown result type (might be due to invalid IL or missing references)
//IL_0432: Unknown result type (might be due to invalid IL or missing references)
//IL_0538: Unknown result type (might be due to invalid IL or missing references)
//IL_053d: Unknown result type (might be due to invalid IL or missing references)
//IL_0541: Unknown result type (might be due to invalid IL or missing references)
//IL_0546: Unknown result type (might be due to invalid IL or missing references)
//IL_054a: Unknown result type (might be due to invalid IL or missing references)
//IL_054f: Unknown result type (might be due to invalid IL or missing references)
//IL_046f: Unknown result type (might be due to invalid IL or missing references)
//IL_0567: Unknown result type (might be due to invalid IL or missing references)
//IL_056e: Unknown result type (might be due to invalid IL or missing references)
if (PluginConfig.EnableDebugLogs.Value)
{
Log.Info("[CleanupSnatcher] ExecuteIfReady called for skill: " + __instance.skillDef?.skillName);
}
if (!PluginConfig.EnableProjectileGrabbing.Value)
{
return true;
}
GameObject value;
float value2;
float value3;
float value4;
GameObject gameObject;
Vector3 val5;
Vector3 val6;
if (__instance.skillDef?.skillName == "Repossess" && _isToggleVisualsDisplayActive)
{
if (!__instance.CanExecute())
{
if (PluginConfig.EnableDebugLogs.Value)
{
Log.Info("[CleanupSnatcher] Repossess pressed but skill is not ready (cooldown) - skipping projectile spawn");
}
return true;
}
if (PluginConfig.EnableDebugLogs.Value)
{
Log.Info("[CleanupSnatcher] Repossess pressed while ToggleVisuals display is ACTIVE - spawning projectile directly");
}
SkillLocator component = ((Component)__instance).GetComponent<SkillLocator>();
if ((Object)(object)component != (Object)null && (Object)(object)component.secondary != (Object)null)
{
GenericSkill secondary = component.secondary;
EntityStateMachine val = EntityStateMachine.FindByCustomName(((Component)component).gameObject, "Bag");
if ((Object)(object)val != (Object)null && val.state is BaggedObject)
{
if (PluginConfig.EnableDebugLogs.Value)
{
Log.Info("[CleanupSnatcher] Bag is already full, skipping projectile spawn");
}
return true;
}
DrifterCleanupController component2 = ((Component)component).gameObject.GetComponent<DrifterCleanupController>();
if ((Object)(object)component2 != (Object)null)
{
if (PluginConfig.EnableDebugLogs.Value)
{
Log.Info("[CleanupSnatcher] Manually cycling projectile index in DrifterCleanupController");
}
FieldInfo field = typeof(DrifterCleanupController).GetField("prefabIndex", BindingFlags.Instance | BindingFlags.NonPublic);
if (field != null)
{
try
{
FieldInfo field2 = typeof(DrifterCleanupController).GetField("projectileCandidateSelection", BindingFlags.Instance | BindingFlags.NonPublic);
if (field2 != null)
{
if (field2.GetValue(component2) is WeightedSelection<Candidate> val2)
{
int num = (int)field.GetValue(component2);
int num2 = Math.Abs(num);
int num3 = (num2 + 1) % val2.Count;
if (num < 0)
{
num3 = -num3;
}
field.SetValue(component2, num3);
if (PluginConfig.EnableDebugLogs.Value)
{
Log.Info(string.Format("{0} Cycled prefabIndex from {1} to {2} (total candidates: {3})", "[CleanupSnatcher]", num, num3, val2.Count));
}
}
else if (PluginConfig.EnableDebugLogs.Value)
{
Log.Info("[CleanupSnatcher] Could not get projectile candidate selection");
}
}
else
{
int num4 = (int)field.GetValue(component2);
int num5 = Math.Abs(num4);
int num6 = (num5 + 1) % 3;
if (num4 < 0)
{
num6 = -num6;
}
field.SetValue(component2, num6);
if (PluginConfig.EnableDebugLogs.Value)
{
Log.Info(string.Format("{0} Fallback cycling prefabIndex from {1} to {2}", "[CleanupSnatcher]", num4, num6));
}
}
}
catch (Exception ex)
{
if (PluginConfig.EnableDebugLogs.Value)
{
Log.Info("[CleanupSnatcher] Failed to cycle prefabIndex: " + ex.Message);
}
}
}
else if (PluginConfig.EnableDebugLogs.Value)
{
Log.Info("[CleanupSnatcher] Could not find prefabIndex field in DrifterCleanupController");
}
}
else if (PluginConfig.EnableDebugLogs.Value)
{
Log.Info("[CleanupSnatcher] Could not find DrifterCleanupController for manual cycling");
}
if ((Object)(object)secondary.stateMachine != (Object)null)
{
EntityState state = secondary.stateMachine.state;
AimMagicBag val3 = (AimMagicBag)(object)((state is AimMagicBag) ? state : null);
if (val3 != null)
{
Traverse val4 = Traverse.Create((object)val3);
value = val4.Field("projectilePrefab").GetValue<GameObject>();
if ((Object)(object)value != (Object)null)
{
if (PluginConfig.EnableDebugLogs.Value)
{
Log.Info("[CleanupSnatcher] Spawning cycled projectile: " + ((Object)value).name);
}
_shouldMakeNextProjectilesGrabbable = true;
value2 = val4.Field("damageCoefficient").GetValue<float>();
value3 = val4.Field("force").GetValue<float>();
value4 = val4.Field("damageStat").GetValue<float>();
gameObject = ((Component)component).gameObject;
if (PluginConfig.EnableDebugLogs.Value)
{
Log.Info(string.Format("{0} Drifter position: {1}", "[CleanupSnatcher]", gameObject.transform.position));
Log.Info(string.Format("{0} Drifter forward: {1}", "[CleanupSnatcher]", gameObject.transform.forward));
Camera main = Camera.main;
Log.Info(string.Format("{0} Camera position: {1}", "[CleanupSnatcher]", (main != null) ? new Vector3?(((Component)main).transform.position) : null));
Camera main2 = Camera.main;
Log.Info(string.Format("{0} Camera forward: {1}", "[CleanupSnatcher]", (main2 != null) ? new Vector3?(((Component)main2).transform.forward) : null));
}
val5 = gameObject.transform.position + gameObject.transform.forward * 2f + Vector3.up * 1f;
val6 = gameObject.transform.forward;
if ((Object)(object)secondary.stateMachine != (Object)null)
{
EntityState state2 = secondary.stateMachine.state;
AimMagicBag val7 = (AimMagicBag)(object)((state2 is AimMagicBag) ? state2 : null);
if (val7 != null)
{
Traverse val8 = Traverse.Create((object)val7);
object value5 = val8.Field("currentTrajectoryInfo").GetValue();
if (value5 != null)
{
try
{
Ray val9 = (Ray)value5.GetType().GetField("finalRay").GetValue(value5);
val5 = ((Ray)(ref val9)).origin;
val6 = ((Ray)(ref val9)).direction;
if (PluginConfig.EnableDebugLogs.Value)
{
Log.Info(string.Format("{0} Using AimMagicBag trajectory - position: {1}, direction: {2}", "[CleanupSnatcher]", val5, val6));
}
}
catch (Exception ex2)
{
if (PluginConfig.EnableDebugLogs.Value)
{
Log.Info("[CleanupSnatcher] Failed to get trajectory data: " + ex2.Message + ", using fallback");
}
}
}
else if (PluginConfig.EnableDebugLogs.Value)
{
Log.Info("[CleanupSnatcher] No trajectory info available, using fallback values");
}
goto IL_05da;
}
}
if (PluginConfig.EnableDebugLogs.Value)
{
Log.Info("[CleanupSnatcher] Could not find AimMagicBag state, using fallback values");
}
goto IL_05da;
}
if (PluginConfig.EnableDebugLogs.Value)
{
Log.Info("[CleanupSnatcher] No projectile prefab found after Cleanup execution");
}
goto IL_06e5;
}
}
if (PluginConfig.EnableDebugLogs.Value)
{
Log.Info("[CleanupSnatcher] Could not find AimMagicBag state after Cleanup execution");
}
}
else if (PluginConfig.EnableDebugLogs.Value)
{
Log.Info("[CleanupSnatcher] Could not find SkillLocator or Cleanup skill");
}
goto IL_06e5;
}
return true;
IL_05da:
if (PluginConfig.EnableDebugLogs.Value)
{
Log.Info(string.Format("{0} Final spawn position: {1}, direction: {2}", "[CleanupSnatcher]", val5, val6));
}
FireProjectileInfo val10 = default(FireProjectileInfo);
val10.projectilePrefab = value;
val10.position = val5;
val10.rotation = Util.QuaternionSafeLookRotation(val6, Vector3.up);
((FireProjectileInfo)(ref val10)).speedOverride = 0f;
val10.damage = value2 * value4;
val10.owner = gameObject;
val10.crit = false;
val10.damageColorIndex = (DamageColorIndex)0;
val10.force = value3;
val10.target = null;
FireProjectileInfo val11 = val10;
ProjectileManager.instance.FireProjectile(val11);
if (PluginConfig.EnableDebugLogs.Value)
{
Log.Info("[CleanupSnatcher] Cycled projectile spawned for Repossess grab");
}
goto IL_06e5;
IL_06e5:
return true;
}
}
[HarmonyPatch(typeof(BaggedObject), "OnEnter")]
public class BaggedObject_OnEnter_Patch
{
[HarmonyPostfix]
public static void Postfix(BaggedObject __instance)
{
if ((Object)(object)_activeProjectile != (Object)null)
{
Traverse val = Traverse.Create((object)__instance);
GameObject value = val.Field("targetObject").GetValue<GameObject>();
if ((Object)(object)value == (Object)(object)_activeProjectile)
{
Log.Info("[CleanupSnatcher] Active projectile grabbed: " + ((Object)_activeProjectile).name);
_activeProjectile = null;
}
}
}
}
[HarmonyPatch(typeof(ThrownObjectProjectileController), "ImpactBehavior")]
public class ThrownObjectProjectileController_ImpactBehavior_Patch
{
[HarmonyPostfix]
public static void Postfix(ThrownObjectProjectileController __instance)
{
if ((Object)(object)_activeProjectile != (Object)null && (Object)(object)((Component)__instance).gameObject == (Object)(object)_activeProjectile)
{
Log.Info("[CleanupSnatcher] Active projectile impacted: " + ((Object)_activeProjectile).name);
_activeProjectile = null;
}
}
}
[HarmonyPatch(typeof(Object), "Destroy", new Type[] { typeof(Object) })]
public class Object_Destroy_Patch
{
[HarmonyPrefix]
public static void Prefix(Object obj)
{
if ((Object)(object)_activeProjectile != (Object)null)
{
GameObject val = (GameObject)(object)((obj is GameObject) ? obj : null);
if (val != null && (Object)(object)val == (Object)(object)_activeProjectile)
{
Log.Info("[CleanupSnatcher] Active projectile destroyed: " + ((Object)_activeProjectile).name);
_activeProjectile = null;
}
}
}
}
[HarmonyPatch(typeof(RepossessBullseyeSearch), "GetResults")]
public class RepossessBullseyeSearch_GetResults_Patch
{
[HarmonyPostfix]
public static void Postfix(ref IEnumerable<GameObject> __result)
{
if ((Object)(object)_activeProjectile != (Object)null)
{
List<GameObject> list = new List<GameObject>(__result);
if (!list.Contains(_activeProjectile))
{
list.Insert(0, _activeProjectile);
Log.Info("[CleanupSnatcher] Force-added active projectile to repossess results: " + ((Object)_activeProjectile).name);
}
else
{
list.Remove(_activeProjectile);
list.Insert(0, _activeProjectile);
Log.Info("[CleanupSnatcher] Moved active projectile to front of repossess results: " + ((Object)_activeProjectile).name);
}
__result = list;
}
}
}
private static bool _shouldMakeNextProjectilesGrabbable;
private static bool _isToggleVisualsDisplayActive;
private static GameObject _activeProjectile;
private static Texture GetProjectileIcon(string projectileName)
{
//IL_01bb: Unknown result type (might be due to invalid IL or missing references)
//IL_01c0: Unknown result type (might be due to invalid IL or missing references)
string text = projectileName switch
{
"DrifterGrenade" => "RoR2/Base/StickyBomb/texStickyBombIcon.png",
"DrifterJunkBall" => "RoR2/DLC3/Items/texJunkIcon.png",
"DrifterToolbotCrate" => "RoR2/DLC3/Items/PowerCube/texPowerCubeIcon.png",
"DrifterHotSauce" => "RoR2/DLC1/Molotov/texMolotovIcon.png",
"DrifterKnife" => "RoR2/Base/Dagger/texDaggerIcon.png",
"DrifterBubbleShield" => "RoR2/Junk/Engi/texEngiShieldSpriteCrosshair.png",
"DrifterGeode" => "RoR2/DLC2/texAFUIChunkIcon.png",
"DrifterBarrel" => "RoR2/Base/Common/MiscIcons/texBarrelIcon.png",
"DrifterBrokenDrone" => "RoR2/Base/Drones/texDrone2Icon.png",
"DrifterBrokenHAND" => "RoR2/Base/Toolbot/texToolbotIcon.png",
"DrifterEvilSkull" => "RoR2/Base/AltarSkeleton/texAltarSkeletonBody.png",
_ => "RoR2/Base/Common/MiscIcons/texMysteryIcon.png",
};
if (!string.IsNullOrEmpty(text))
{
try
{
Texture2D val = Addressables.LoadAssetAsync<Texture2D>((object)text).WaitForCompletion();
if ((Object)(object)val != (Object)null)
{
if (PluginConfig.EnableDebugLogs.Value)
{
Log.Info("[CleanupSnatcher] Loaded icon via Addressables: " + text);
}
return (Texture)(object)val;
}
}
catch (Exception ex)
{
if (PluginConfig.EnableDebugLogs.Value)
{
Log.Info("[CleanupSnatcher] Failed to load via Addressables " + text + ": " + ex.Message + ", falling back to LegacyResourcesAPI");
}
}
}
return null;
}
private static void AddSpecialObjectAttributesToProjectile(GameObject obj)
{
//IL_019e: Unknown result type (might be due to invalid IL or missing references)
//IL_02e1: Unknown result type (might be due to invalid IL or missing references)
//IL_00bf: Unknown result type (might be due to invalid IL or missing references)
//IL_0117: Unknown result type (might be due to invalid IL or missing references)
//IL_054f: Unknown result type (might be due to invalid IL or missing references)
//IL_0559: Unknown result type (might be due to invalid IL or missing references)
//IL_055a: Unknown result type (might be due to invalid IL or missing references)
if ((Object)(object)obj == (Object)null)
{
return;
}
string text = ((Object)obj).name;
string text2 = text.ToLowerInvariant();
if (string.IsNullOrEmpty(text))
{
string text4 = (((Object)obj).name = "Projectile_" + ((Object)obj).GetInstanceID());
text = text4;
text2 = text.ToLowerInvariant();
}
if (PluginConfig.EnableDebugLogs.Value)
{
Log.Info("[CleanupSnatcher] Using projectile object " + ((Object)obj).name + " for SpecialObjectAttributes (original: " + text + ")");
}
NetworkIdentity component = obj.GetComponent<NetworkIdentity>();
if ((Object)(object)component != (Object)null)
{
if (PluginConfig.EnableDebugLogs.Value)
{
Log.Info(string.Format("{0} Target {1} already has NetworkIdentity: netId = {2}", "[CleanupSnatcher]", ((Object)obj).name, component.netId));
}
}
else
{
component = obj.AddComponent<NetworkIdentity>();
component.serverOnly = false;
component.localPlayerAuthority = false;
try
{
if (NetworkServer.active)
{
NetworkServer.Spawn(obj);
if (PluginConfig.EnableDebugLogs.Value)
{
Log.Info(string.Format("{0} Successfully spawned projectile {1} on network with netId = {2}", "[CleanupSnatcher]", ((Object)obj).name, component.netId));
}
}
else if (PluginConfig.EnableDebugLogs.Value)
{
Log.Info("[CleanupSnatcher] NetworkServer not active, cannot spawn projectile " + ((Object)obj).name);
}
}
catch (Exception ex)
{
if (PluginConfig.EnableDebugLogs.Value)
{
Log.Info("[CleanupSnatcher] Failed to spawn projectile " + ((Object)obj).name + " on network: " + ex.Message);
}
}
if (PluginConfig.EnableDebugLogs.Value)
{
Log.Info(string.Format("{0} Added NetworkIdentity to projectile {1}: netId = {2}", "[CleanupSnatcher]", ((Object)obj).name, component.netId));
}
}
SpecialObjectAttributes component2 = obj.GetComponent<SpecialObjectAttributes>();
if ((Object)(object)component2 != (Object)null)
{
if (!component2.grabbable || string.IsNullOrEmpty(component2.breakoutStateMachineName))
{
component2.grabbable = true;
component2.breakoutStateMachineName = "";
component2.orientToFloor = true;
if (PluginConfig.EnableDebugLogs.Value)
{
Log.Info("[CleanupSnatcher] Updated existing SpecialObjectAttributes on projectile " + ((Object)obj).name);
}
}
return;
}
SpecialObjectAttributes val = obj.AddComponent<SpecialObjectAttributes>();
val.renderersToDisable = new List<Renderer>();
val.behavioursToDisable = new List<MonoBehaviour>();
val.collisionToDisable = new List<GameObject>();
val.childObjectsToDisable = new List<GameObject>();
val.pickupDisplaysToDisable = new List<PickupDisplay>();
val.lightsToDisable = new List<Light>();
val.objectsToDetach = new List<GameObject>();
val.childSpecialObjectAttributes = new List<SpecialObjectAttributes>();
val.skillHighlightRenderers = new List<Renderer>();
val.soundEventsToStop = new List<AkEvent>();
val.soundEventsToPlay = new List<AkEvent>();
(float massOverride, int maxDurability) tuple = CalculateScaledAttributes(obj, text);
float item = tuple.massOverride;
int item2 = tuple.maxDurability;
val.grabbable = true;
val.massOverride = item;
val.maxDurability = item2;
val.durability = item2;
val.hullClassification = (HullClassification)0;
val.breakoutStateMachineName = "";
val.orientToFloor = true;
string input = text.Replace("(Clone)", "");
Regex regex = new Regex("\\s*\\(\\d+\\)$");
input = (val.bestName = regex.Replace(input, ""));
val.isVoid = text2.Contains("void");
if (PluginConfig.EnableDebugLogs.Value && val.isVoid)
{
Log.Info("[CleanupSnatcher] Marked projectile " + text + " as void object");
}
val.portraitIcon = GetProjectileIcon(input);
if (PluginConfig.EnableDebugLogs.Value && (Object)(object)val.portraitIcon != (Object)null)
{
Log.Info("[CleanupSnatcher] Set icon for projectile " + text);
}
Renderer[] componentsInChildren = obj.GetComponentsInChildren<Renderer>(false);
Renderer[] array = componentsInChildren;
foreach (Renderer item3 in array)
{
val.renderersToDisable.Add(item3);
}
Collider[] componentsInChildren2 = obj.GetComponentsInChildren<Collider>(false);
Collider[] array2 = componentsInChildren2;
foreach (Collider val2 in array2)
{
val.collisionToDisable.Add(((Component)val2).gameObject);
}
Light[] componentsInChildren3 = obj.GetComponentsInChildren<Light>(false);
Light[] array3 = componentsInChildren3;
foreach (Light item4 in array3)
{
val.lightsToDisable.Add(item4);
}
PickupDisplay[] componentsInChildren4 = obj.GetComponentsInChildren<PickupDisplay>(false);
PickupDisplay[] array4 = componentsInChildren4;
foreach (PickupDisplay item5 in array4)
{
val.pickupDisplaysToDisable.Add(item5);
}
MonoBehaviour[] componentsInChildren5 = obj.GetComponentsInChildren<MonoBehaviour>(true);
MonoBehaviour[] array5 = componentsInChildren5;
foreach (MonoBehaviour val3 in array5)
{
if ((Object)(object)val3 == (Object)null || !((Behaviour)val3).enabled)
{
continue;
}
Type type = ((object)val3).GetType();
if (!(type == typeof(NetworkIdentity)) && !(type == typeof(SpecialObjectAttributes)) && !(type == typeof(CharacterBody)))
{
val.behavioursToDisable.Add(val3);
if (PluginConfig.EnableDebugLogs.Value)
{
Log.Info("[CleanupSnatcher] Disabled behavior: " + type.Name + " on " + text);
}
}
}
CharacterBody component3 = obj.GetComponent<CharacterBody>();
if (!((Object)(object)component3 != (Object)null))
{
return;
}
try
{
component3.bodyFlags = (BodyFlags)(component3.bodyFlags & -524289);
if (PluginConfig.EnableDebugLogs.Value)
{
Log.Info("[CleanupSnatcher] Cleared Ungrabbable flag on CharacterBody for projectile " + text);
}
}
catch (Exception ex2)
{
if (PluginConfig.EnableDebugLogs.Value)
{
Log.Info("[CleanupSnatcher] Failed to clear Ungrabbable flag on CharacterBody for projectile " + text + ": " + ex2.Message);
}
}
}
private static (float massOverride, int maxDurability) CalculateScaledAttributes(GameObject obj, string objName)
{
float num = CalculateObjectSizeMetric(obj);
float num2 = Mathf.Clamp(num / 10f, 0.5f, 5f);
float num3 = 100f * num2;
int num4 = Mathf.RoundToInt(8f * num2);
num3 = Mathf.Max(num3, 25f);
num4 = Mathf.Max(num4, 3);
if (PluginConfig.EnableDebugLogs.Value)
{
Log.Info(string.Format("{0} Size scaling for {1}: sizeMetric={2:F2}, scaleFactor={3:F2}, mass={4:F0}, durability={5}", "[CleanupSnatcher]", objName, num, num2, num3, num4));
}
return (num3, num4);
}
private static float CalculateObjectSizeMetric(GameObject obj)
{
//IL_0053: 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_005b: Unknown result type (might be due to invalid IL or missing references)
//IL_0062: Unknown result type (might be due to invalid IL or missing references)
//IL_006a: Unknown result type (might be due to invalid IL or missing references)
//IL_00e3: Unknown result type (might be due to invalid IL or missing references)
//IL_00e8: 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_00f9: Unknown result type (might be due to invalid IL or missing references)
//IL_0106: Unknown result type (might be due to invalid IL or missing references)
if ((Object)(object)obj == (Object)null)
{
return 1f;
}
float num = 0f;
Collider[] componentsInChildren = obj.GetComponentsInChildren<Collider>(false);
Collider[] array = componentsInChildren;
foreach (Collider val in array)
{
if ((Object)(object)val == (Object)null || !val.enabled)
{
continue;
}
BoxCollider val2 = (BoxCollider)(object)((val is BoxCollider) ? val : null);
if (val2 != null)
{
Vector3 size = val2.size;
num += size.x * size.y * size.z;
continue;
}
SphereCollider val3 = (SphereCollider)(object)((val is SphereCollider) ? val : null);
if (val3 != null)
{
float radius = val3.radius;
num += 4.1887903f * radius * radius * radius;
continue;
}
CapsuleCollider val4 = (CapsuleCollider)(object)((val is CapsuleCollider) ? val : null);
if (val4 != null)
{
float radius2 = val4.radius;
float height = val4.height;
num += MathF.PI * radius2 * radius2 * height;
continue;
}
MeshCollider val5 = (MeshCollider)(object)((val is MeshCollider) ? val : null);
if (val5 != null)
{
Bounds bounds = ((Collider)val5).bounds;
num += ((Bounds)(ref bounds)).size.x * ((Bounds)(ref bounds)).size.y * ((Bounds)(ref bounds)).size.z;
}
}
return Mathf.Max(num, 0.1f);
}
}
}
namespace System.Runtime.CompilerServices
{
[AttributeUsage(AttributeTargets.Assembly, AllowMultiple = true)]
internal sealed class IgnoresAccessChecksToAttribute : Attribute
{
public IgnoresAccessChecksToAttribute(string assemblyName)
{
}
}
}