using System;
using System.Collections.Generic;
using System.ComponentModel;
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 BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using HarmonyLib;
using Microsoft.CodeAnalysis;
using Pigeon.Math;
using Pigeon.Movement;
using Unity.Netcode;
using UnityEngine;
[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("Sparroh")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("1.0.2.0")]
[assembly: AssemblyInformationalVersion("1.0.2")]
[assembly: AssemblyProduct("BounceIndicatorPlus")]
[assembly: AssemblyTitle("BounceIndicatorPlus")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.0.2.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;
}
}
}
internal static class AllBounceIndicators
{
private const string SourceMaterialName = "BounceIndicatorPlus_Source";
private static readonly FieldInfo BounceLinePrefabField = AccessTools.Field(typeof(BounceShotgun), "bounceLinePrefab");
private static readonly string[] FallbackShaderNames = new string[5] { "Sprites/Default", "Universal Render Pipeline/Unlit", "Unlit/Color", "UI/Default", "Legacy Shaders/Particles/Alpha Blended Premultiply" };
internal static readonly Dictionary<Gun, List<LineRenderer>> BounceLines = new Dictionary<Gun, List<LineRenderer>>();
internal static LineRenderer BounceLinePrefab;
private static Material _sourceMaterial;
private static bool _loggedMissingMaterial;
private static bool _loggedMissingShader;
internal static LineRenderer CreateBounceLinePrefab()
{
//IL_000a: Unknown result type (might be due to invalid IL or missing references)
//IL_0010: Expected O, but got Unknown
//IL_004c: Unknown result type (might be due to invalid IL or missing references)
EnsureSourceMaterial();
GameObject val = new GameObject("BounceIndicatorPrefab");
Object.DontDestroyOnLoad((Object)(object)val);
LineRenderer obj = val.AddComponent<LineRenderer>();
obj.positionCount = 2;
obj.useWorldSpace = true;
obj.startWidth = 0.01f;
obj.endWidth = 0.01f;
((Renderer)obj).sharedMaterial = CreateLineMaterial();
ApplyColorToLine(obj, ConfigManager.GetSelectedColor());
val.SetActive(false);
return obj;
}
internal static void HideAll()
{
foreach (KeyValuePair<Gun, List<LineRenderer>> bounceLine in BounceLines)
{
List<LineRenderer> value = bounceLine.Value;
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.activeSelf)
{
((Component)value[i]).gameObject.SetActive(false);
}
}
}
}
internal static void ApplyColor(Color color)
{
//IL_0037: Unknown result type (might be due to invalid IL or missing references)
foreach (KeyValuePair<Gun, List<LineRenderer>> bounceLine in BounceLines)
{
List<LineRenderer> value = bounceLine.Value;
for (int i = 0; i < value.Count; i++)
{
if ((Object)(object)value[i] != (Object)null)
{
ApplyColorToLine(value[i], color);
}
}
}
if ((Object)(object)BounceLinePrefab != (Object)null)
{
Object.Destroy((Object)(object)((Component)BounceLinePrefab).gameObject);
BounceLinePrefab = null;
}
}
internal static void ApplyColorToLine(LineRenderer line, Color color)
{
//IL_0011: Unknown result type (might be due to invalid IL or missing references)
//IL_0018: Unknown result type (might be due to invalid IL or missing references)
//IL_0042: 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_0074: Unknown result type (might be due to invalid IL or missing references)
//IL_008d: Unknown result type (might be due to invalid IL or missing references)
//IL_00ae: 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_00c7: Unknown result type (might be due to invalid IL or missing references)
//IL_00cc: Unknown result type (might be due to invalid IL or missing references)
//IL_00df: Unknown result type (might be due to invalid IL or missing references)
if ((Object)(object)line == (Object)null)
{
return;
}
EnsureLineHasValidMaterial(line);
line.startColor = color;
line.endColor = color;
Material sharedMaterial = ((Renderer)line).sharedMaterial;
if (!((Object)(object)sharedMaterial == (Object)null))
{
if (sharedMaterial.HasProperty(Global._BaseColor))
{
sharedMaterial.SetColor(Global._BaseColor, color);
}
if (sharedMaterial.HasProperty(Global._Color))
{
sharedMaterial.SetColor(Global._Color, color);
}
if (sharedMaterial.HasProperty(Global._MainColor))
{
sharedMaterial.SetColor(Global._MainColor, color);
}
if (sharedMaterial.HasProperty("_TintColor"))
{
sharedMaterial.SetColor("_TintColor", color);
}
if (sharedMaterial.HasProperty(Global._Color) || sharedMaterial.HasProperty("_Color"))
{
sharedMaterial.color = color;
}
if (sharedMaterial.HasProperty("_EmissionColor"))
{
Color val = color * 0.5f;
val.a = 1f;
sharedMaterial.SetColor("_EmissionColor", val);
}
}
}
internal static void CleanupGun(Gun gun)
{
if (!BounceLines.TryGetValue(gun, out var value))
{
return;
}
for (int i = 0; i < value.Count; i++)
{
if ((Object)(object)value[i] != (Object)null)
{
Object.Destroy((Object)(object)((Component)value[i]).gameObject);
}
}
BounceLines.Remove(gun);
}
internal static void HideGun(Gun gun)
{
if (!BounceLines.TryGetValue(gun, out var value))
{
return;
}
for (int i = 0; i < value.Count; i++)
{
if ((Object)(object)value[i] != (Object)null && ((Component)value[i]).gameObject.activeSelf)
{
((Component)value[i]).gameObject.SetActive(false);
}
}
}
internal static void TryCaptureMaterialFromGun(Gun gun)
{
//IL_0078: Unknown result type (might be due to invalid IL or missing references)
//IL_007d: Unknown result type (might be due to invalid IL or missing references)
//IL_008d: Expected O, but got Unknown
//IL_00bb: Unknown result type (might be due to invalid IL or missing references)
if ((Object)(object)_sourceMaterial != (Object)null || (Object)(object)gun == (Object)null)
{
return;
}
BounceShotgun val = (BounceShotgun)(object)((gun is BounceShotgun) ? gun : null);
if (val == null || BounceLinePrefabField == null)
{
return;
}
object? value = BounceLinePrefabField.GetValue(val);
LineRenderer val2 = (LineRenderer)((value is LineRenderer) ? value : null);
if (!((Object)(object)val2 == (Object)null))
{
Material sharedMaterial = ((Renderer)val2).sharedMaterial;
if (!((Object)(object)sharedMaterial == (Object)null) && !((Object)(object)sharedMaterial.shader == (Object)null) && !IsErrorShader(sharedMaterial.shader))
{
_sourceMaterial = new Material(sharedMaterial)
{
name = "BounceIndicatorPlus_Source"
};
Object.DontDestroyOnLoad((Object)(object)_sourceMaterial);
BounceIndicatorPlusPlugin.Logger.LogInfo((object)("Captured bounce line material from BounceShotgun (shader: " + ((Object)sharedMaterial.shader).name + ")."));
ApplyColor(ConfigManager.GetSelectedColor());
}
}
}
internal static Material CreateUniqueLineMaterial()
{
return CreateLineMaterial();
}
private static void EnsureSourceMaterial()
{
if ((Object)(object)_sourceMaterial != (Object)null)
{
return;
}
BounceShotgun[] array = Object.FindObjectsOfType<BounceShotgun>(true);
for (int i = 0; i < array.Length; i++)
{
TryCaptureMaterialFromGun((Gun)(object)array[i]);
if ((Object)(object)_sourceMaterial != (Object)null)
{
break;
}
}
}
private static Material CreateLineMaterial()
{
//IL_0012: Unknown result type (might be due to invalid IL or missing references)
//IL_0017: Unknown result type (might be due to invalid IL or missing references)
//IL_0023: Expected O, but got Unknown
//IL_0033: Unknown result type (might be due to invalid IL or missing references)
//IL_0038: Unknown result type (might be due to invalid IL or missing references)
//IL_0044: Expected O, but got Unknown
//IL_0077: Unknown result type (might be due to invalid IL or missing references)
//IL_007c: Unknown result type (might be due to invalid IL or missing references)
//IL_0088: Expected O, but got Unknown
if ((Object)(object)_sourceMaterial != (Object)null)
{
return new Material(_sourceMaterial)
{
name = "BounceIndicatorPlus_Source"
};
}
Shader val = FindFallbackShader();
if ((Object)(object)val != (Object)null)
{
return new Material(val)
{
name = "BounceIndicatorPlus_Fallback"
};
}
if (!_loggedMissingMaterial)
{
_loggedMissingMaterial = true;
BounceIndicatorPlusPlugin.Logger.LogError((object)"Could not resolve a bounce line material/shader. Lines may render magenta.");
}
Shader val2 = Shader.Find("Hidden/InternalErrorShader");
if (!((Object)(object)val2 != (Object)null))
{
return null;
}
return new Material(val2)
{
name = "BounceIndicatorPlus_Error"
};
}
private static void EnsureLineHasValidMaterial(LineRenderer line)
{
Material sharedMaterial = ((Renderer)line).sharedMaterial;
bool flag = (Object)(object)sharedMaterial == (Object)null || (Object)(object)sharedMaterial.shader == (Object)null || IsErrorShader(sharedMaterial.shader);
bool flag2 = (Object)(object)_sourceMaterial != (Object)null && !IsFromSource(sharedMaterial) && (flag || IsLikelyFallback(sharedMaterial));
if (flag || flag2)
{
((Renderer)line).sharedMaterial = CreateLineMaterial();
}
}
private static bool IsFromSource(Material mat)
{
if ((Object)(object)mat == (Object)null || ((Object)mat).name == null)
{
return false;
}
return ((Object)mat).name.StartsWith("BounceIndicatorPlus_Source");
}
private static bool IsLikelyFallback(Material mat)
{
if ((Object)(object)mat == (Object)null || (Object)(object)mat.shader == (Object)null)
{
return true;
}
string name = ((Object)mat.shader).name;
for (int i = 0; i < FallbackShaderNames.Length; i++)
{
if (name == FallbackShaderNames[i])
{
return true;
}
}
if (((Object)mat).name != null && (((Object)mat).name.StartsWith("BounceIndicatorPlus_Fallback") || ((Object)mat).name.StartsWith("BounceIndicatorPlus_Error")))
{
return true;
}
return false;
}
private static bool IsErrorShader(Shader shader)
{
if ((Object)(object)shader == (Object)null)
{
return true;
}
string name = ((Object)shader).name;
if (!(name == "Hidden/InternalErrorShader"))
{
return name.Contains("InternalError");
}
return true;
}
private static Shader FindFallbackShader()
{
for (int i = 0; i < FallbackShaderNames.Length; i++)
{
Shader val = Shader.Find(FallbackShaderNames[i]);
if ((Object)(object)val != (Object)null)
{
return val;
}
}
if (!_loggedMissingShader)
{
_loggedMissingShader = true;
BounceIndicatorPlusPlugin.Logger.LogWarning((object)"No fallback line shader found via Shader.Find. Waiting for BounceShotgun material.");
}
return null;
}
}
public enum BounceIndicatorColor
{
[Description("Standard orange color (highest priority, default)")]
Orange,
[Description("Clean white color")]
White,
[Description("Bright green color")]
Green,
[Description("Deep blue color")]
Blue,
[Description("Vibrant red color")]
Red,
[Description("Sunny yellow color")]
Yellow,
[Description("Royal purple color")]
Purple,
[Description("Aqua cyan color")]
Cyan,
[Description("Use a custom color specified by hex code")]
Custom
}
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> EnableAllBounceIndicators { get; private set; }
public static ConfigEntry<BounceIndicatorColor> LineColor { get; private set; }
public static ConfigEntry<string> LineCustomColor { get; private set; }
public static void Initialize(ConfigFile configFile, ManualLogSource log)
{
config = configFile;
logger = log;
EnableAllBounceIndicators = config.Bind<bool>("Bounce Indicators", "Enable Bounce Lines", true, "Show bounce/ricochet prediction lines for all weapons with bounces >= 1.");
LineColor = config.Bind<BounceIndicatorColor>("Bounce Indicators", "Line Color", BounceIndicatorColor.Orange, "Select the color for bounce/ricochet prediction lines");
LineCustomColor = config.Bind<string>("Bounce Indicators", "Line Custom Color", "#FF8000", "Hex color code when 'Custom' is selected (format: #RRGGBB or RRGGBB)");
EnableAllBounceIndicators.SettingChanged += OnEnableChanged;
LineColor.SettingChanged += OnColorChanged;
LineCustomColor.SettingChanged += OnCustomColorChanged;
try
{
SetupFileWatcher();
}
catch (Exception ex)
{
logger.LogError((object)("Error setting up config file watcher: " + ex.Message));
}
}
public static void Tick()
{
if (!reloadPending || Time.unscaledTime - lastReloadTime < 0.25f)
{
return;
}
reloadPending = false;
lastReloadTime = Time.unscaledTime;
try
{
config.Reload();
logger.LogInfo((object)"Config reloaded from disk.");
}
catch (Exception ex)
{
logger.LogError((object)("Error reloading config: " + ex.Message));
}
}
public static void Dispose()
{
if (EnableAllBounceIndicators != null)
{
EnableAllBounceIndicators.SettingChanged -= OnEnableChanged;
}
if (LineColor != null)
{
LineColor.SettingChanged -= OnColorChanged;
}
if (LineCustomColor != null)
{
LineCustomColor.SettingChanged -= OnCustomColorChanged;
}
if (configWatcher != null)
{
configWatcher.EnableRaisingEvents = false;
configWatcher.Changed -= OnConfigFileChanged;
configWatcher.Created -= OnConfigFileChanged;
configWatcher.Renamed -= OnConfigFileChanged;
configWatcher.Dispose();
configWatcher = null;
}
}
public static Color GetSelectedColor()
{
//IL_0049: Unknown result type (might be due to invalid IL or missing references)
//IL_005e: Unknown result type (might be due to invalid IL or missing references)
//IL_0073: Unknown result type (might be due to invalid IL or missing references)
//IL_0088: Unknown result type (might be due to invalid IL or missing references)
//IL_009d: Unknown result type (might be due to invalid IL or missing references)
//IL_00b2: 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_00dc: Unknown result type (might be due to invalid IL or missing references)
//IL_0136: Unknown result type (might be due to invalid IL or missing references)
//IL_0121: Unknown result type (might be due to invalid IL or missing references)
//IL_0110: Unknown result type (might be due to invalid IL or missing references)
switch (LineColor.Value)
{
case BounceIndicatorColor.Orange:
return new Color(1f, 0.5f, 0f);
case BounceIndicatorColor.White:
return new Color(1f, 1f, 1f);
case BounceIndicatorColor.Green:
return new Color(0f, 1f, 0f);
case BounceIndicatorColor.Blue:
return new Color(0f, 0f, 1f);
case BounceIndicatorColor.Red:
return new Color(1f, 0f, 0f);
case BounceIndicatorColor.Yellow:
return new Color(1f, 1f, 0f);
case BounceIndicatorColor.Purple:
return new Color(0.6f, 0.2f, 0.85f);
case BounceIndicatorColor.Cyan:
return new Color(0f, 1f, 1f);
case BounceIndicatorColor.Custom:
{
string text = LineCustomColor.Value;
if (!text.StartsWith("#"))
{
text = "#" + text;
}
Color result = default(Color);
if (ColorUtility.TryParseHtmlString(text, ref result))
{
return result;
}
return new Color(1f, 0f, 0f);
}
default:
return new Color(1f, 0f, 0f);
}
}
private static void SetupFileWatcher()
{
configWatcher = new FileSystemWatcher(Paths.ConfigPath, "sparroh.bounceindicatorplus.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;
}
private static void OnEnableChanged(object sender, EventArgs e)
{
if (!EnableAllBounceIndicators.Value)
{
AllBounceIndicators.HideAll();
}
}
private static void OnColorChanged(object sender, EventArgs e)
{
//IL_0000: Unknown result type (might be due to invalid IL or missing references)
AllBounceIndicators.ApplyColor(GetSelectedColor());
}
private static void OnCustomColorChanged(object sender, EventArgs e)
{
//IL_000d: Unknown result type (might be due to invalid IL or missing references)
if (LineColor.Value == BounceIndicatorColor.Custom)
{
AllBounceIndicators.ApplyColor(GetSelectedColor());
}
}
}
[HarmonyPatch]
public static class GunBouncePatches
{
private static readonly FieldInfo FireDataField = AccessTools.Field(typeof(Gun), "fireData");
private static readonly FieldInfo ShotsFiredField = AccessTools.Field(typeof(Gun), "shotsFiredSinceStartedFiring");
private static readonly Vector3[] PositionsBuffer = (Vector3[])(object)new Vector3[2];
[HarmonyPostfix]
[HarmonyPatch(typeof(Gun), "Update")]
public static void Update_Postfix(Gun __instance)
{
try
{
if (((NetworkBehaviour)__instance).IsOwner && __instance.Active)
{
HandleBounceIndicators(__instance);
}
}
catch (Exception ex)
{
BounceIndicatorPlusPlugin.Logger.LogError((object)("Update postfix failed: " + ex.Message));
}
}
[HarmonyPostfix]
[HarmonyPatch(typeof(Gun), "Disable")]
public static void Disable_Postfix(Gun __instance)
{
AllBounceIndicators.HideGun(__instance);
}
[HarmonyPostfix]
[HarmonyPatch(typeof(Gun), "OnDestroy")]
public static void OnDestroy_Postfix(Gun __instance)
{
AllBounceIndicators.CleanupGun(__instance);
}
private static void HandleBounceIndicators(Gun gun)
{
//IL_008c: Unknown result type (might be due to invalid IL or missing references)
if (!ConfigManager.EnableAllBounceIndicators.Value)
{
return;
}
AllBounceIndicators.TryCaptureMaterialFromGun(gun);
ref GunData gunData = ref gun.GunData;
int maxBounces = gunData.maxBounces;
if (maxBounces >= 1)
{
if (!AllBounceIndicators.BounceLines.TryGetValue(gun, out var value))
{
value = new List<LineRenderer>();
AllBounceIndicators.BounceLines[gun] = value;
}
if ((Object)(object)AllBounceIndicators.BounceLinePrefab == (Object)null)
{
AllBounceIndicators.BounceLinePrefab = AllBounceIndicators.CreateBounceLinePrefab();
}
int num = Mathf.Max(1, gunData.bulletsPerShot);
int num2 = num * maxBounces;
while (value.Count < num2)
{
LineRenderer val = Object.Instantiate<LineRenderer>(AllBounceIndicators.BounceLinePrefab);
((Renderer)val).sharedMaterial = AllBounceIndicators.CreateUniqueLineMaterial();
AllBounceIndicators.ApplyColorToLine(val, ConfigManager.GetSelectedColor());
value.Add(val);
}
Player player = gun.Player;
if ((Object)(object)player != (Object)null && (player.IsSprinting || player.IsFireLocked))
{
AllBounceIndicators.HideGun(gun);
}
else
{
UpdateBounceLines(gun, value, maxBounces, num);
}
}
}
private static void UpdateBounceLines(Gun gun, List<LineRenderer> bounceLines, int maxBounces, int bulletsPerShot)
{
//IL_020b: 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_008c: Unknown result type (might be due to invalid IL or missing references)
//IL_0097: Unknown result type (might be due to invalid IL or missing references)
//IL_00a8: Unknown result type (might be due to invalid IL or missing references)
//IL_00ad: Unknown result type (might be due to invalid IL or missing references)
//IL_00b7: 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_00bd: Unknown result type (might be due to invalid IL or missing references)
//IL_00c5: Unknown result type (might be due to invalid IL or missing references)
//IL_00ca: Unknown result type (might be due to invalid IL or missing references)
//IL_00cc: Unknown result type (might be due to invalid IL or missing references)
//IL_00ce: Unknown result type (might be due to invalid IL or missing references)
//IL_00e6: Unknown result type (might be due to invalid IL or missing references)
//IL_00eb: Unknown result type (might be due to invalid IL or missing references)
//IL_00ed: 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_00f6: 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_0105: Unknown result type (might be due to invalid IL or missing references)
//IL_0107: Unknown result type (might be due to invalid IL or missing references)
//IL_0109: Unknown result type (might be due to invalid IL or missing references)
//IL_010b: Unknown result type (might be due to invalid IL or missing references)
//IL_0189: Unknown result type (might be due to invalid IL or missing references)
//IL_018b: Unknown result type (might be due to invalid IL or missing references)
//IL_0196: Unknown result type (might be due to invalid IL or missing references)
//IL_0198: Unknown result type (might be due to invalid IL or missing references)
//IL_019c: Unknown result type (might be due to invalid IL or missing references)
//IL_01a1: Unknown result type (might be due to invalid IL or missing references)
//IL_01a6: Unknown result type (might be due to invalid IL or missing references)
//IL_0124: Unknown result type (might be due to invalid IL or missing references)
//IL_0126: Unknown result type (might be due to invalid IL or missing references)
//IL_0133: Unknown result type (might be due to invalid IL or missing references)
//IL_0138: Unknown result type (might be due to invalid IL or missing references)
//IL_0164: 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_016b: Unknown result type (might be due to invalid IL or missing references)
//IL_016f: Unknown result type (might be due to invalid IL or missing references)
//IL_0174: Unknown result type (might be due to invalid IL or missing references)
//IL_0179: Unknown result type (might be due to invalid IL or missing references)
try
{
gun.PrepareFireData();
if (FireDataField == null)
{
return;
}
FireData fireData = (FireData)FireDataField.GetValue(gun);
ref GunData gunData = ref gun.GunData;
bool isFirstShot = ShotsFiredField == null || (int)ShotsFiredField.GetValue(gun) == 0;
float num = gunData.rangeData.maxDamageRange;
if (num <= 0f)
{
num = 50f;
}
float num2 = gunData.rangeData.falloffStartDistance;
if (num2 <= 0f)
{
num2 = 15f;
}
int num3 = LayerMask.op_Implicit(gunData.surfaceCollisionMask) | LayerMask.op_Implicit(gunData.targetCollisionMask);
int i = 0;
Random saved = SpreadDirectionHelper.CaptureSpreadRandom(gun);
try
{
RaycastHit val = default(RaycastHit);
RaycastHit val3 = default(RaycastHit);
for (int j = 0; j < bulletsPerShot; j++)
{
if (i >= bounceLines.Count)
{
break;
}
Vector3 firePosition = fireData.firePosition;
Vector3 direction = SpreadDirectionHelper.GetDirection(gun, in fireData, j, isFirstShot);
if (!IBullet.RaycastForBullet(firePosition, direction, num, num3, 0f, ref val))
{
continue;
}
firePosition = ((RaycastHit)(ref val)).point;
direction = Vector3.Reflect(direction, ((RaycastHit)(ref val)).normal);
for (int k = 0; k < maxBounces; k++)
{
if (i >= bounceLines.Count)
{
break;
}
Vector3 val2 = firePosition;
if (IBullet.RaycastForBullet(firePosition, direction, num, num3, 0f, ref val3))
{
PositionsBuffer[0] = val2;
PositionsBuffer[1] = ((RaycastHit)(ref val3)).point;
bounceLines[i].SetPositions(PositionsBuffer);
((Component)bounceLines[i]).gameObject.SetActive(true);
firePosition = ((RaycastHit)(ref val3)).point;
direction = Vector3.Reflect(direction, ((RaycastHit)(ref val3)).normal);
i++;
continue;
}
PositionsBuffer[0] = val2;
PositionsBuffer[1] = firePosition + direction * num2;
bounceLines[i].SetPositions(PositionsBuffer);
((Component)bounceLines[i]).gameObject.SetActive(true);
i++;
break;
}
}
}
finally
{
SpreadDirectionHelper.RestoreSpreadRandom(gun, saved);
}
for (; i < bounceLines.Count; i++)
{
if (((Component)bounceLines[i]).gameObject.activeSelf)
{
((Component)bounceLines[i]).gameObject.SetActive(false);
}
}
}
catch (Exception ex)
{
BounceIndicatorPlusPlugin.Logger.LogError((object)("UpdateBounceLines failed: " + ex.Message));
}
}
}
[BepInPlugin("sparroh.bounceindicatorplus", "BounceIndicatorPlus", "1.0.2")]
[MycoMod(/*Could not decode attribute arguments.*/)]
public class BounceIndicatorPlusPlugin : BaseUnityPlugin
{
public const string PluginGUID = "sparroh.bounceindicatorplus";
public const string PluginName = "BounceIndicatorPlus";
public const string PluginVersion = "1.0.2";
internal static ManualLogSource Logger;
private Harmony harmony;
private void Awake()
{
//IL_0021: Unknown result type (might be due to invalid IL or missing references)
//IL_002b: Expected O, but got Unknown
Logger = ((BaseUnityPlugin)this).Logger;
ConfigManager.Initialize(((BaseUnityPlugin)this).Config, Logger);
harmony = new Harmony("sparroh.bounceindicatorplus");
try
{
harmony.PatchAll(typeof(GunBouncePatches));
Logger.LogInfo((object)"Harmony patches applied.");
}
catch (Exception ex)
{
Logger.LogError((object)("Error applying patches: " + ex.Message));
}
Logger.LogInfo((object)"BounceIndicatorPlus v1.0.2 loaded successfully.");
}
private void Update()
{
ConfigManager.Tick();
}
private void OnDestroy()
{
ConfigManager.Dispose();
Harmony obj = harmony;
if (obj != null)
{
obj.UnpatchSelf();
}
}
}
internal static class SpreadDirectionHelper
{
public static Random CaptureSpreadRandom(Gun gun)
{
//IL_000b: Unknown result type (might be due to invalid IL or missing references)
return gun.GunData.spreadData.spreadRandom;
}
public static void RestoreSpreadRandom(Gun gun, Random saved)
{
//IL_000b: Unknown result type (might be due to invalid IL or missing references)
//IL_000c: Unknown result type (might be due to invalid IL or missing references)
gun.GunData.spreadData.spreadRandom = saved;
}
public static Vector3 GetDirection(Gun gun, in FireData fireData, int shotIndex, bool isFirstShot)
{
//IL_0008: Unknown result type (might be due to invalid IL or missing references)
//IL_000d: 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_0015: Unknown result type (might be due to invalid IL or missing references)
//IL_0018: Unknown result type (might be due to invalid IL or missing references)
//IL_001d: 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_0048: Unknown result type (might be due to invalid IL or missing references)
//IL_0050: Unknown result type (might be due to invalid IL or missing references)
//IL_0051: Unknown result type (might be due to invalid IL or missing references)
//IL_0056: Unknown result type (might be due to invalid IL or missing references)
//IL_005b: Unknown result type (might be due to invalid IL or missing references)
//IL_0021: 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_002d: Unknown result type (might be due to invalid IL or missing references)
ref GunData gunData = ref gun.GunData;
Quaternion bulletRotation = fireData.bulletRotation;
Vector3 eulerAngles = ((Quaternion)(ref bulletRotation)).eulerAngles;
Vector2 val = gun.GetSpread(shotIndex);
if (isFirstShot)
{
val *= gunData.firstShotSpreadMultiplier;
}
eulerAngles.y += val.x;
eulerAngles.x += val.y;
return Quaternion.Euler(eulerAngles) * Vector3.forward;
}
}
namespace BounceIndicatorPlus
{
public static class MyPluginInfo
{
public const string PLUGIN_GUID = "BounceIndicatorPlus";
public const string PLUGIN_NAME = "BounceIndicatorPlus";
public const string PLUGIN_VERSION = "1.0.2";
}
}
namespace System.Runtime.CompilerServices
{
[AttributeUsage(AttributeTargets.Assembly, AllowMultiple = true)]
internal sealed class IgnoresAccessChecksToAttribute : Attribute
{
public IgnoresAccessChecksToAttribute(string assemblyName)
{
}
}
}