Decompiled source of CiCisPioneersShotgun v0.4.3

plugins\ShotgunMod\ShotgunMod.dll

Decompiled a month ago
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.Text;
using BepInEx;
using BepInEx.Logging;
using HarmonyLib;
using Microsoft.CodeAnalysis;
using TrinketAndBindingFramework;
using UnityEngine;
using UnityEngine.Events;
using UnityEngine.Rendering;
using UnityEngine.UI;

[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("ShotgunMod")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0")]
[assembly: AssemblyProduct("ShotgunMod")]
[assembly: AssemblyTitle("ShotgunMod")]
[assembly: AssemblyVersion("1.0.0.0")]
[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.Module, AllowMultiple = false, Inherited = false)]
	internal sealed class RefSafetyRulesAttribute : Attribute
	{
		public readonly int Version;

		public RefSafetyRulesAttribute(int P_0)
		{
			Version = P_0;
		}
	}
}
namespace ShotgunMod
{
	public class CiCi_ItemClickable : MonoBehaviour, Clickable
	{
	}
	public class EjectedShell : MonoBehaviour
	{
		public Sprite[] frames;

		public Vector3 velocity;

		public Vector3 gravityDir = Vector3.down;

		public float gravityAccel = 9.81f;

		public float lifetime = 1.5f;

		public float spinSpeedDeg = 540f;

		public bool useLocalSpace;

		private float _age;

		private SpriteRenderer _sr;

		private void Awake()
		{
			_sr = ((Component)this).GetComponent<SpriteRenderer>();
		}

		private void Update()
		{
			//IL_00a3: 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_00b9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00cd: 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_010f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0119: Unknown result type (might be due to invalid IL or missing references)
			//IL_011e: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e1: 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_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)
			_age += Time.deltaTime;
			if (_age >= lifetime)
			{
				Object.Destroy((Object)(object)((Component)this).gameObject);
				return;
			}
			if (frames != null && frames.Length != 0 && (Object)(object)_sr != (Object)null)
			{
				int num = Mathf.Clamp((int)(_age / lifetime * (float)frames.Length), 0, frames.Length - 1);
				if ((Object)(object)_sr.sprite != (Object)(object)frames[num])
				{
					_sr.sprite = frames[num];
				}
			}
			velocity += ((Vector3)(ref gravityDir)).normalized * gravityAccel * Time.deltaTime;
			if (useLocalSpace)
			{
				Transform transform = ((Component)this).transform;
				transform.localPosition += velocity * Time.deltaTime;
			}
			else
			{
				Transform transform2 = ((Component)this).transform;
				transform2.position += velocity * Time.deltaTime;
			}
			((Component)this).transform.Rotate(0f, 0f, spinSpeedDeg * Time.deltaTime);
		}
	}
	[BepInPlugin("com.cicismods.shotgunmod", "Shotgun Mod", "0.4.3")]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	public class Plugin : BaseUnityPlugin
	{
		public struct ShellVisuals
		{
			public string Letter;

			public Color Color;
		}

		public static GameObject ShotgunPrefab;

		public static Item_Object ShotgunTemplate;

		public static HandItem ShotgunHandItemTemplate;

		public static Item_Object ShotgunShellTemplate;

		public static HandItem ShellHandItemTemplate;

		public static ManualLogSource Log;

		public static AudioClip ShotgunFireClip;

		public static AudioClip ShotgunDryFireClip;

		public static AudioClip ShotgunReloadSingleClip;

		public static AudioClip ShotgunBreakOpenClip;

		public static AudioClip ShotgunBreakCloseClip;

		public static AudioClip ShotgunImpactClip;

		public static Material OutlineMaterial;

		public static Material ShellOutlineMaterial;

		public static Material ShellOutlineReverse;

		public static Material ShellOutlineRebar;

		public static Material ShellShimmerSpriteMaterialReverse;

		public static Material ShellShimmerSpriteMaterialRebar;

		public static readonly Color ReverseBrandColor = new Color(0f, 1f, 1f, 1f);

		public static readonly Color RebarBrandColor = new Color(0.76862746f, 20f / 51f, 32f / 85f, 1f);

		public static Sprite SpriteLoaded;

		public static Sprite SpriteRecoil;

		public static Sprite SpriteEmpty;

		public static Sprite PioneersEdgeIcon;

		public static Sprite InfestationIcon;

		public static Sprite ShotgunVendingSprite;

		public static GameObject ShotgunMeshPrefab;

		public static GameObject ShellWorldMeshPrefab;

		public static readonly Dictionary<string, GameObject> ShellMeshByType = new Dictionary<string, GameObject>();

		public static Sprite[] ShellEjectedFrames;

		public static Sprite ShellHeldSprite;

		public static Sprite ShellEjectedSprite;

		public static readonly Dictionary<string, Sprite> ShellHeldSpritesByType = new Dictionary<string, Sprite>();

		public static readonly Dictionary<string, Sprite> ShellVendingSpritesByType = new Dictionary<string, Sprite>();

		public static readonly Dictionary<string, Sprite[]> ShellEjectedFramesByType = new Dictionary<string, Sprite[]>();

		public static readonly Vector3 OutlineHaloScale = new Vector3(1.095f, 1.005f, 1.01f);

		public static readonly Vector3 OutlineHaloOffset = Vector3.zero;

		public const string ShellTypeBuckshot = "buckshot";

		public const string ShellTypeSlug = "slug";

		public const string ShellTypeDragon = "dragon";

		public const string ShellTypeBlank = "blank";

		public const string ShellTypeReverse = "reverse";

		public const string ShellTypeRebar = "rebar";

		private const string BarrelTypeKey0 = "barrel0_type=";

		private const string BarrelTypeKey1 = "barrel1_type=";

		private const string ShellTypeKey = "shell_type=";

		public static readonly Dictionary<string, Item_Object> ShotgunShellTemplatesByType = new Dictionary<string, Item_Object>();

		public static readonly Dictionary<string, ShellVisuals> ShellTypeVisuals = new Dictionary<string, ShellVisuals>
		{
			["buckshot"] = new ShellVisuals
			{
				Letter = "B",
				Color = new Color(1f, 0.25f, 0.25f, 1f)
			},
			["slug"] = new ShellVisuals
			{
				Letter = "S",
				Color = new Color(0.55f, 0.55f, 0.6f, 1f)
			},
			["dragon"] = new ShellVisuals
			{
				Letter = "D",
				Color = new Color(1f, 0.55f, 0.1f, 1f)
			},
			["blank"] = new ShellVisuals
			{
				Letter = "X",
				Color = new Color(1f, 0.937f, 0.859f, 1f)
			},
			["reverse"] = new ShellVisuals
			{
				Letter = "R",
				Color = new Color(0.529f, 0.925f, 0.925f, 1f)
			},
			["rebar"] = new ShellVisuals
			{
				Letter = "#",
				Color = new Color(0.082f, 0.016f, 0.02f, 1f)
			}
		};

		private static Sprite _filledCircleSprite;

		private static Sprite _hollowCircleSprite;

		private Harmony _harmony;

		private static bool _cachedInfestationActive;

		private static bool _infestationCacheValid;

		private static readonly Dictionary<Mesh, Mesh> _invertedMeshCache = new Dictionary<Mesh, Mesh>();

		private static readonly Dictionary<string, Item_Object> _shellVendingTemplatesByType = new Dictionary<string, Item_Object>();

		private static readonly Dictionary<string, Purchase> _shellVendingPurchasesByType = new Dictionary<string, Purchase>();

		private static GameObject _shellVendingSpawnContainer;

		private static readonly Dictionary<string, int> ShellVendingWeights = new Dictionary<string, int>
		{
			{ "buckshot", 60 },
			{ "slug", 24 },
			{ "blank", 8 },
			{ "dragon", 7 },
			{ "reverse", 1 }
		};

		private static readonly Dictionary<string, int> ShellVendingPrices = new Dictionary<string, int>
		{
			{ "buckshot", 2 },
			{ "slug", 4 },
			{ "blank", 6 },
			{ "dragon", 7 },
			{ "reverse", 15 }
		};

		public static readonly Dictionary<string, int> ShellVendingStocksByType = new Dictionary<string, int>
		{
			{ "buckshot", 6 },
			{ "slug", 4 },
			{ "blank", 2 },
			{ "dragon", 2 },
			{ "reverse", 1 }
		};

		public static readonly Dictionary<ENV_VendingMachine, Dictionary<int, int>> ShellVendingSlotStocks = new Dictionary<ENV_VendingMachine, Dictionary<int, int>>();

		private static Purchase _shotgunVendingPurchase;

		public static Item_Object ShotgunVendingSpawnTemplate;

		private static GameObject _shotgunVendingSpawnContainer;

		private const float ShotgunPossessionCacheTtl = 0.5f;

		private static bool _cachedShotgunInPossession;

		private static float _shotgunPossessionCacheAt = -1000f;

		public static Vector3 ShellEjectAnchorOffset = new Vector3(0.007f, 0.021f, 0f);

		public static Vector3 ShellEjectAnchorBaseLocal;

		public static bool ShellEjectAnchorBaseCaptured;

		public static bool InfestationActive
		{
			get
			{
				if (!_infestationCacheValid)
				{
					RecomputeInfestation();
				}
				return _cachedInfestationActive;
			}
		}

		public static GameObject GetShellMeshForType(string shellType)
		{
			if (!string.IsNullOrEmpty(shellType) && ShellMeshByType.TryGetValue(shellType, out var value) && (Object)(object)value != (Object)null)
			{
				return value;
			}
			return ShellWorldMeshPrefab;
		}

		private static GameObject FindBundleMeshByExactName(GameObject[] gos, string exact)
		{
			if (gos == null)
			{
				return null;
			}
			foreach (GameObject val in gos)
			{
				if ((Object)(object)val != (Object)null && ((Object)val).name == exact)
				{
					return val;
				}
			}
			return null;
		}

		private static string NameOrNull(GameObject go)
		{
			if (!((Object)(object)go != (Object)null))
			{
				return "<null>";
			}
			return ((Object)go).name;
		}

		public static Sprite GetShellHeldSpriteForType(string type)
		{
			if (!string.IsNullOrEmpty(type) && ShellHeldSpritesByType.TryGetValue(type, out var value) && (Object)(object)value != (Object)null)
			{
				return value;
			}
			return ShellHeldSprite;
		}

		public static Sprite[] GetShellEjectedFramesForType(string type)
		{
			if (!string.IsNullOrEmpty(type) && ShellEjectedFramesByType.TryGetValue(type, out var value) && value != null && value.Length != 0)
			{
				return value;
			}
			return ShellEjectedFrames;
		}

		public static string GetShellType(Item item)
		{
			if (item?.data == null)
			{
				return "buckshot";
			}
			foreach (string datum in item.data)
			{
				if (datum != null && datum.StartsWith("shell_type="))
				{
					return datum.Substring("shell_type=".Length);
				}
			}
			return "buckshot";
		}

		public static void SetShellType(Item item, string type)
		{
			if (item == null)
			{
				return;
			}
			if (item.data == null)
			{
				item.data = new List<string>();
			}
			string text = "shell_type=" + type;
			for (int i = 0; i < item.data.Count; i++)
			{
				if (item.data[i] != null && item.data[i].StartsWith("shell_type="))
				{
					item.data[i] = text;
					return;
				}
			}
			item.data.Add(text);
		}

		public static string GetBarrelType(Item item, int barrelIndex)
		{
			if (item?.data == null)
			{
				return "";
			}
			string text = ((barrelIndex == 0) ? "barrel0_type=" : "barrel1_type=");
			foreach (string datum in item.data)
			{
				if (datum != null && datum.StartsWith(text))
				{
					return datum.Substring(text.Length);
				}
			}
			return "";
		}

		public static void SetBarrelType(Item item, int barrelIndex, string type)
		{
			if (item == null)
			{
				return;
			}
			if (item.data == null)
			{
				item.data = new List<string>();
			}
			string text = ((barrelIndex == 0) ? "barrel0_type=" : "barrel1_type=");
			string text2 = text + type;
			for (int i = 0; i < item.data.Count; i++)
			{
				if (item.data[i] != null && item.data[i].StartsWith(text))
				{
					item.data[i] = text2;
					return;
				}
			}
			item.data.Add(text2);
		}

		public static ShellVisuals GetShellVisuals(string type)
		{
			if (!string.IsNullOrEmpty(type) && ShellTypeVisuals.TryGetValue(type, out var value))
			{
				return value;
			}
			return ShellTypeVisuals["buckshot"];
		}

		public static Sprite GetFilledCircleSprite()
		{
			return _filledCircleSprite ?? (_filledCircleSprite = BuildCircleSpriteShared(hollow: false));
		}

		public static Sprite GetHollowCircleSprite()
		{
			return _hollowCircleSprite ?? (_hollowCircleSprite = BuildCircleSpriteShared(hollow: true));
		}

		private static Sprite BuildCircleSpriteShared(bool hollow)
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_000c: Expected O, but got Unknown
			//IL_013d: Unknown result type (might be due to invalid IL or missing references)
			//IL_014c: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ea: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ef: Unknown result type (might be due to invalid IL or missing references)
			Texture2D val = new Texture2D(64, 64, (TextureFormat)4, false);
			((Texture)val).wrapMode = (TextureWrapMode)1;
			((Texture)val).filterMode = (FilterMode)1;
			float num = 31.5f;
			float num2 = 31.5f;
			float num3 = 31f;
			float num4 = num3 - 7.68f;
			Color32[] array = (Color32[])(object)new Color32[4096];
			for (int i = 0; i < 64; i++)
			{
				for (int j = 0; j < 64; j++)
				{
					float num5 = Mathf.Sqrt(((float)j - num) * ((float)j - num) + ((float)i - num2) * ((float)i - num2));
					byte b;
					if (hollow)
					{
						float num6 = 1f - Mathf.Clamp01(num5 - num3 + 1f);
						float num7 = Mathf.Clamp01(num5 - num4 + 1f);
						b = (byte)(Mathf.Clamp01(num6 * num7) * 255f);
					}
					else
					{
						b = (byte)(Mathf.Clamp01(1f - Mathf.Clamp01(num5 - num3 + 1f)) * 255f);
					}
					array[i * 64 + j] = new Color32(byte.MaxValue, byte.MaxValue, byte.MaxValue, b);
				}
			}
			val.SetPixels32(array);
			val.Apply(false, true);
			Object.DontDestroyOnLoad((Object)(object)val);
			Sprite obj = Sprite.Create(val, new Rect(0f, 0f, 64f, 64f), new Vector2(0.5f, 0.5f), 100f);
			Object.DontDestroyOnLoad((Object)(object)obj);
			return obj;
		}

		private void Awake()
		{
			//IL_002f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0039: Expected O, but got Unknown
			//IL_0049: Unknown result type (might be due to invalid IL or missing references)
			//IL_004e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0056: Unknown result type (might be due to invalid IL or missing references)
			//IL_005c: Expected O, but got Unknown
			//IL_005c: 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)
			Log = ((BaseUnityPlugin)this).Logger;
			LoadAssetBundle();
			LoadShellBundle();
			LoadCustomAudio();
			LoadTrinketIcons();
			LoadShellVariantSprites();
			_harmony = new Harmony("com.cicismods.shotgunmod");
			_harmony.PatchAll();
			GameObject val = new GameObject("ShotgunMod_Handler")
			{
				hideFlags = (HideFlags)61
			};
			Object.DontDestroyOnLoad((Object)val);
			val.AddComponent<ShotgunModHandler>();
			val.AddComponent<ShotgunAmmoHudHandler>();
			val.AddComponent<TeethHealthBarHandler>();
			TrinketRegistry.RegisterTrinket("cici_pioneers_edge", "Sawed-Off", "(Suggested to play with the Infestation Binding)\nStart with a double-barrel shotgun loaded with buckshot. As long as it's in your possession you gain these benefits:\n- Shells have a chance to spawn instead of pitons and rebar across the superstructure.\n- Vending machines have a higher chance to stock shells of various types.\n- Kills with the shotgun have a chance to fill your bag with shells if you're lucky.\n- Hammer kills have a low chance to give you a free shell.\n<color=#80C4FF>Hold R to change ammo type.</color>", "Some climbs demand a second opinion.", 1, 0f, 0f, PioneersEdgeIcon, (Func<List<Item_Object>>)delegate
			{
				try
				{
					EnsureShotgunTemplate();
				}
				catch
				{
				}
				try
				{
					EnsureShotgunHandItemTemplate();
				}
				catch
				{
				}
				try
				{
					EnsureShotgunShellTemplate();
				}
				catch
				{
				}
				try
				{
					EnsureTypedShellTemplates();
				}
				catch
				{
				}
				List<Item_Object> list = new List<Item_Object>();
				if ((Object)(object)ShotgunTemplate != (Object)null)
				{
					list.Add(ShotgunTemplate);
				}
				return list;
			}, (Func<List<Perk>>)null, 0);
			TrinketRegistry.RegisterBinding("cici_infestation", "Infestation", "The superstructure is overrun. Bloodbugs, hoppers, and barnacles are everywhere. Patrol drones sweep the halls trying to suppress the swarm — but they can't keep up.\n<color=#FFA040>(Performance note: heavy spawn load may cause stutter on lower-end systems.)</color>", "Where am I...? How long has it been...?", 1, 0.5f, 0f, InfestationIcon, (Func<List<Item_Object>>)null, (Func<List<Perk>>)null, 0);
		}

		public static void InvalidateInfestationCache()
		{
			_infestationCacheValid = false;
		}

		private static void RecomputeInfestation()
		{
			_cachedInfestationActive = IsInfestationActiveNow();
			_infestationCacheValid = true;
		}

		private static bool IsInfestationActiveNow()
		{
			try
			{
				M_Gamemode currentGamemode = CL_GameManager.GetCurrentGamemode();
				if ((Object)(object)currentGamemode == (Object)null)
				{
					return false;
				}
				SaveData saveData = StatManager.saveData;
				List<string> list = ((saveData != null) ? saveData.GetGamemodeTrinkets(currentGamemode.GetGamemodeName(true)) : null);
				if (list == null)
				{
					return false;
				}
				foreach (string item in list)
				{
					if (!string.IsNullOrEmpty(item) && item.ToLowerInvariant().Contains("cici_infestation"))
					{
						return true;
					}
				}
			}
			catch
			{
			}
			return false;
		}

		public static Material TryBuildGameOutlineMaterial()
		{
			//IL_0014: Unknown result type (might be due to invalid IL or missing references)
			return TryBuildGameOutlineMaterial(new Color(0.2f, 1f, 0.25f, 1f), "ShotgunMod_RuntimeOutline");
		}

		public static Material TryBuildGameOutlineMaterial(Color tint, string name)
		{
			//IL_0017: Unknown result type (might be due to invalid IL or missing references)
			//IL_001c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0024: Expected O, but got Unknown
			//IL_0037: Unknown result type (might be due to invalid IL or missing references)
			Shader val = Shader.Find("Dark Machine/SHDR_Outline");
			if ((Object)(object)val == (Object)null)
			{
				return null;
			}
			Material val2 = new Material(val)
			{
				name = name
			};
			if (val2.HasProperty("_Color"))
			{
				val2.SetColor("_Color", tint);
			}
			if (val2.HasProperty("_Brightness"))
			{
				val2.SetFloat("_Brightness", 1f);
			}
			Object.DontDestroyOnLoad((Object)(object)val2);
			return val2;
		}

		public static Material PickShellOutlineMaterial(string shellType)
		{
			//IL_001a: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a3: 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)
			if (shellType == "reverse")
			{
				if ((Object)(object)ShellOutlineReverse == (Object)null)
				{
					ShellOutlineReverse = TryBuildGameOutlineMaterial(ReverseBrandColor, "ShotgunMod_ShellOutline_Reverse");
				}
				if ((Object)(object)ShellOutlineReverse != (Object)null)
				{
					return ShellOutlineReverse;
				}
			}
			else if (shellType == "rebar")
			{
				if ((Object)(object)ShellOutlineRebar == (Object)null)
				{
					ShellOutlineRebar = TryBuildGameOutlineMaterial(RebarBrandColor, "ShotgunMod_ShellOutline_Rebar");
				}
				if ((Object)(object)ShellOutlineRebar != (Object)null)
				{
					return ShellOutlineRebar;
				}
			}
			if ((Object)(object)ShellOutlineMaterial == (Object)null)
			{
				ShellOutlineMaterial = TryBuildGameOutlineMaterial(new Color(1f, 0.2f, 0.2f, 1f), "ShotgunMod_ShellOutline");
			}
			return ShellOutlineMaterial;
		}

		public static Material EnsureShellShimmerSpriteMaterial(string shellType)
		{
			//IL_0025: Unknown result type (might be due to invalid IL or missing references)
			//IL_005f: Unknown result type (might be due to invalid IL or missing references)
			if (shellType == "reverse")
			{
				if ((Object)(object)ShellShimmerSpriteMaterialReverse != (Object)null)
				{
					return ShellShimmerSpriteMaterialReverse;
				}
				ShellShimmerSpriteMaterialReverse = BuildShellShimmerMaterial("ShotgunMod_ShellShimmer_Reverse", ReverseBrandColor);
				return ShellShimmerSpriteMaterialReverse;
			}
			if (shellType == "rebar")
			{
				if ((Object)(object)ShellShimmerSpriteMaterialRebar != (Object)null)
				{
					return ShellShimmerSpriteMaterialRebar;
				}
				ShellShimmerSpriteMaterialRebar = BuildShellShimmerMaterial("ShotgunMod_ShellShimmer_Rebar", RebarBrandColor);
				return ShellShimmerSpriteMaterialRebar;
			}
			return null;
		}

		private static Material BuildShellShimmerMaterial(string name, Color shimmerTint)
		{
			//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_0040: Expected O, but got Unknown
			//IL_00c7: Unknown result type (might be due to invalid IL or missing references)
			//IL_0185: Unknown result type (might be due to invalid IL or missing references)
			Shader val = Shader.Find("Dark Machine/SHDR_Base_Inventory") ?? Shader.Find("Dark Machine/SHDR_Base") ?? Shader.Find("Sprites/Default");
			if ((Object)(object)val == (Object)null)
			{
				return null;
			}
			Material val2 = new Material(val)
			{
				name = name
			};
			if (val2.HasProperty("_Shimmer"))
			{
				val2.SetFloat("_Shimmer", 2.5f);
			}
			if (val2.HasProperty("_ShimmerFrequency"))
			{
				val2.SetFloat("_ShimmerFrequency", 1f);
			}
			if (val2.HasProperty("_ShimmerSpeed"))
			{
				val2.SetFloat("_ShimmerSpeed", 1f);
			}
			if (val2.HasProperty("_ShimmerOffset"))
			{
				val2.SetFloat("_ShimmerOffset", 0f);
			}
			if (val2.HasProperty("_ShimmerColor"))
			{
				val2.SetColor("_ShimmerColor", shimmerTint);
			}
			if (val2.HasProperty("_Brightness"))
			{
				val2.SetFloat("_Brightness", 0f);
			}
			if (val2.HasProperty("_DitherAmount"))
			{
				val2.SetFloat("_DitherAmount", 0.2f);
			}
			if (val2.HasProperty("_ROUNDMULT"))
			{
				val2.SetFloat("_ROUNDMULT", 1f);
			}
			if (val2.HasProperty("_WiggleFreq"))
			{
				val2.SetFloat("_WiggleFreq", 2f);
			}
			if (val2.HasProperty("_WiggleSpeed"))
			{
				val2.SetFloat("_WiggleSpeed", 5f);
			}
			if (val2.HasProperty("_Color"))
			{
				val2.SetColor("_Color", new Color(0.85f, 0.85f, 0.85f, 1f));
			}
			Object.DontDestroyOnLoad((Object)(object)val2);
			return val2;
		}

		public static Mesh GetInvertedHullMesh(Mesh source)
		{
			//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_0074: Expected O, but got Unknown
			//IL_0076: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)source == (Object)null)
			{
				return null;
			}
			if (_invertedMeshCache.TryGetValue(source, out var value))
			{
				return value;
			}
			if (!source.isReadable)
			{
				ManualLogSource log = Log;
				if (log != null)
				{
					log.LogWarning((object)("[Outline] Mesh '" + ((Object)source).name + "' is not readable (Read/Write disabled at import). Halo skipped for this mesh. Enable Read/Write on the FBX and rebuild the bundle to get the outline glow."));
				}
				_invertedMeshCache[source] = null;
				return null;
			}
			try
			{
				Mesh val = new Mesh
				{
					name = ((Object)source).name + "_Inverted"
				};
				val.indexFormat = source.indexFormat;
				val.vertices = source.vertices;
				val.normals = source.normals;
				val.uv = source.uv;
				val.subMeshCount = source.subMeshCount;
				for (int i = 0; i < source.subMeshCount; i++)
				{
					int[] triangles = source.GetTriangles(i);
					for (int j = 0; j < triangles.Length; j += 3)
					{
						int num = triangles[j + 1];
						triangles[j + 1] = triangles[j + 2];
						triangles[j + 2] = num;
					}
					val.SetTriangles(triangles, i);
				}
				val.RecalculateBounds();
				Object.DontDestroyOnLoad((Object)(object)val);
				_invertedMeshCache[source] = val;
				return val;
			}
			catch (Exception ex)
			{
				ManualLogSource log2 = Log;
				if (log2 != null)
				{
					log2.LogWarning((object)("[Outline] Failed to invert mesh '" + ((Object)source).name + "': " + ex.Message + ". Halo skipped."));
				}
				_invertedMeshCache[source] = null;
				return null;
			}
		}

		public static void EnsureShotgunTemplate()
		{
			//IL_008a: 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_00a9: Unknown result type (might be due to invalid IL or missing references)
			//IL_0108: Unknown result type (might be due to invalid IL or missing references)
			//IL_010d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0118: Unknown result type (might be due to invalid IL or missing references)
			//IL_0123: Unknown result type (might be due to invalid IL or missing references)
			//IL_0144: 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_0150: Unknown result type (might be due to invalid IL or missing references)
			//IL_0155: Unknown result type (might be due to invalid IL or missing references)
			//IL_015a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0161: Unknown result type (might be due to invalid IL or missing references)
			//IL_0168: Unknown result type (might be due to invalid IL or missing references)
			//IL_0170: Unknown result type (might be due to invalid IL or missing references)
			//IL_017b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0186: Unknown result type (might be due to invalid IL or missing references)
			//IL_0191: 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_01a7: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b2: Unknown result type (might be due to invalid IL or missing references)
			//IL_01bd: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c4: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d4: Expected O, but got Unknown
			if ((Object)(object)ShotgunTemplate != (Object)null || (Object)(object)ShotgunPrefab == (Object)null)
			{
				return;
			}
			GameObject val = Object.Instantiate<GameObject>(ShotgunPrefab);
			val.SetActive(false);
			((Object)val).name = "cici_shotgun";
			((Object)val).hideFlags = (HideFlags)61;
			Object.DontDestroyOnLoad((Object)(object)val);
			if (val.GetComponentsInChildren<Renderer>(true).Length == 0 && (Object)(object)ShotgunMeshPrefab != (Object)null)
			{
				GameObject obj = Object.Instantiate<GameObject>(ShotgunMeshPrefab);
				((Object)obj).name = "ShotgunMod_ShotgunMesh";
				obj.transform.SetParent(val.transform, false);
				obj.transform.localPosition = Vector3.zero;
				obj.transform.localRotation = Quaternion.identity;
				obj.transform.localScale = Vector3.one;
			}
			Item_Object val2 = (ShotgunTemplate = val.AddComponent<Item_Object>());
			ShotgunModHandler.ConfigureAsPickup(val);
			ApplyGameShader(val);
			try
			{
				PrewarmShotgunShaders(val);
			}
			catch (Exception ex)
			{
				ManualLogSource log = Log;
				if (log != null)
				{
					log.LogWarning((object)("[Shotgun] shader prewarm: " + ex.Message));
				}
			}
			if (val2.itemData == null)
			{
				EnsureShotgunHandItemTemplate();
				val2.itemData = new Item
				{
					itemName = "Shotgun",
					itemTag = "shotgun",
					itemTags = new List<string> { "weapon", "shotgun" },
					prefabName = "Item_Shotgun",
					upDirection = Vector3.up,
					pocketable = true,
					pouchable = true,
					worth = 56,
					inventoryScale = 1f,
					itemWeight = 1f,
					data = new List<string>(),
					dataModules = new List<Item_Data>(),
					dataModuleSaves = new List<DataModuleSave>(),
					pickupSounds = new List<AudioClip>(),
					executionModules = new List<ItemExecutionModule>(),
					itemAsset = val2,
					handItemAsset = ShotgunHandItemTemplate
				};
			}
		}

		private static void PrewarmShotgunShaders(GameObject template)
		{
			//IL_000f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0015: Expected O, but got Unknown
			//IL_003a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0060: Unknown result type (might be due to invalid IL or missing references)
			//IL_0065: Unknown result type (might be due to invalid IL or missing references)
			//IL_006e: Expected O, but got Unknown
			//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_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_00a9: 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_00d7: 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_00f7: Unknown result type (might be due to invalid IL or missing references)
			//IL_0197: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a4: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b1: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)template == (Object)null)
			{
				return;
			}
			GameObject val = new GameObject("ShotgunMod_PrewarmCam");
			((Object)val).hideFlags = (HideFlags)61;
			Camera val2 = val.AddComponent<Camera>();
			((Behaviour)val2).enabled = false;
			val2.cullingMask = -1;
			val2.clearFlags = (CameraClearFlags)2;
			val2.backgroundColor = Color.black;
			val2.nearClipPlane = 0.01f;
			val2.farClipPlane = 100f;
			RenderTexture val4 = (val2.targetTexture = new RenderTexture(64, 64, 16)
			{
				hideFlags = (HideFlags)61
			});
			bool activeSelf = template.activeSelf;
			Transform parent = template.transform.parent;
			Vector3 localPosition = template.transform.localPosition;
			Quaternion localRotation = template.transform.localRotation;
			Vector3 localScale = template.transform.localScale;
			template.transform.SetParent(val.transform, false);
			template.transform.localPosition = new Vector3(0f, 0f, 1f);
			template.transform.localRotation = Quaternion.identity;
			template.transform.localScale = Vector3.one;
			template.SetActive(true);
			Component[] componentsInChildren = template.GetComponentsInChildren<Component>(true);
			foreach (Component val5 in componentsInChildren)
			{
				if ((Object)(object)val5 == (Object)null)
				{
					continue;
				}
				Renderer val6 = (Renderer)(object)((val5 is Renderer) ? val5 : null);
				if (val6 != null)
				{
					val6.enabled = true;
					_ = val6.material;
					continue;
				}
				ParticleSystem val7 = (ParticleSystem)(object)((val5 is ParticleSystem) ? val5 : null);
				if (val7 != null)
				{
					val7.Emit(1);
					val7.Clear();
				}
			}
			try
			{
				val2.Render();
			}
			catch
			{
			}
			template.SetActive(activeSelf);
			template.transform.SetParent(parent, false);
			template.transform.localPosition = localPosition;
			template.transform.localRotation = localRotation;
			template.transform.localScale = localScale;
			val2.targetTexture = null;
			Object.Destroy((Object)(object)val);
			Object.Destroy((Object)(object)val4);
			ManualLogSource log = Log;
			if (log != null)
			{
				log.LogInfo((object)("[Shotgun] shader prewarm complete for '" + ((Object)template).name + "'"));
			}
		}

		public static void EnsureShotgunShellTemplate()
		{
			//IL_0252: Unknown result type (might be due to invalid IL or missing references)
			//IL_0257: Unknown result type (might be due to invalid IL or missing references)
			//IL_0262: Unknown result type (might be due to invalid IL or missing references)
			//IL_026d: Unknown result type (might be due to invalid IL or missing references)
			//IL_028e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0299: Unknown result type (might be due to invalid IL or missing references)
			//IL_029a: Unknown result type (might be due to invalid IL or missing references)
			//IL_029f: Unknown result type (might be due to invalid IL or missing references)
			//IL_02a4: Unknown result type (might be due to invalid IL or missing references)
			//IL_02ab: Unknown result type (might be due to invalid IL or missing references)
			//IL_02b2: Unknown result type (might be due to invalid IL or missing references)
			//IL_02b9: Unknown result type (might be due to invalid IL or missing references)
			//IL_02c4: Unknown result type (might be due to invalid IL or missing references)
			//IL_02cf: Unknown result type (might be due to invalid IL or missing references)
			//IL_02da: Unknown result type (might be due to invalid IL or missing references)
			//IL_02e5: Unknown result type (might be due to invalid IL or missing references)
			//IL_02f0: Unknown result type (might be due to invalid IL or missing references)
			//IL_030d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0318: Unknown result type (might be due to invalid IL or missing references)
			//IL_031f: Unknown result type (might be due to invalid IL or missing references)
			//IL_034c: Expected O, but got Unknown
			//IL_0354: Unknown result type (might be due to invalid IL or missing references)
			//IL_035e: Expected O, but got Unknown
			//IL_035f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0369: Expected O, but got Unknown
			//IL_019d: 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_0136: Unknown result type (might be due to invalid IL or missing references)
			//IL_0390: Unknown result type (might be due to invalid IL or missing references)
			//IL_0144: 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_0170: Unknown result type (might be due to invalid IL or missing references)
			//IL_017c: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)ShotgunShellTemplate != (Object)null)
			{
				return;
			}
			if ((Object)(object)ShellWorldMeshPrefab == (Object)null)
			{
				ManualLogSource log = Log;
				if (log != null)
				{
					log.LogWarning((object)"[Shell] ShellWorldMeshPrefab not loaded — shell template deferred");
				}
				return;
			}
			GameObject val = Object.Instantiate<GameObject>(ShellWorldMeshPrefab);
			val.SetActive(false);
			((Object)val).name = "cici_shell_buckshot";
			((Object)val).hideFlags = (HideFlags)61;
			Object.DontDestroyOnLoad((Object)(object)val);
			val.layer = 10;
			Transform[] componentsInChildren = val.GetComponentsInChildren<Transform>(true);
			for (int i = 0; i < componentsInChildren.Length; i++)
			{
				((Component)componentsInChildren[i]).gameObject.layer = 10;
			}
			try
			{
				val.tag = "Pickupable";
			}
			catch
			{
			}
			ObjectTagger val2 = val.GetComponent<ObjectTagger>();
			if ((Object)(object)val2 == (Object)null)
			{
				val2 = val.AddComponent<ObjectTagger>();
			}
			if (val2.tags == null)
			{
				val2.tags = new List<string>();
			}
			if (!val2.tags.Contains("Pickupable"))
			{
				val2.tags.Add("Pickupable");
			}
			if (!val2.tags.Contains("Item"))
			{
				val2.tags.Add("Item");
			}
			if ((Object)(object)val.GetComponentInChildren<Collider>() == (Object)null)
			{
				Renderer[] componentsInChildren2 = val.GetComponentsInChildren<Renderer>();
				if (componentsInChildren2.Length != 0)
				{
					Bounds bounds = componentsInChildren2[0].bounds;
					for (int j = 1; j < componentsInChildren2.Length; j++)
					{
						((Bounds)(ref bounds)).Encapsulate(componentsInChildren2[j].bounds);
					}
					BoxCollider obj2 = val.AddComponent<BoxCollider>();
					obj2.center = val.transform.InverseTransformPoint(((Bounds)(ref bounds)).center);
					obj2.size = ((Bounds)(ref bounds)).size;
				}
				else
				{
					val.AddComponent<BoxCollider>().size = new Vector3(0.05f, 0.1f, 0.05f);
				}
			}
			Rigidbody val3 = val.GetComponent<Rigidbody>();
			if ((Object)(object)val3 == (Object)null)
			{
				val3 = val.AddComponent<Rigidbody>();
			}
			val3.mass = 0.05f;
			if (val.GetComponent<Clickable>() == null)
			{
				val.AddComponent<CiCi_ItemClickable>();
			}
			Item_Object val4 = val.GetComponent<Item_Object>();
			if ((Object)(object)val4 == (Object)null)
			{
				val4 = val.AddComponent<Item_Object>();
			}
			ShotgunShellTemplate = val4;
			ObjectTagger val5 = val.GetComponent<ObjectTagger>();
			if ((Object)(object)val5 == (Object)null)
			{
				val5 = val.AddComponent<ObjectTagger>();
			}
			val5.AddTag("RecycleFit");
			EnsureShellHandItemTemplate();
			Item val6 = null;
			try
			{
				GameObject assetGameObject = CL_AssetManager.GetAssetGameObject("Item_Flaregun_Ammo", "");
				val6 = ((assetGameObject == null) ? null : assetGameObject.GetComponent<Item_Object>()?.itemData);
			}
			catch
			{
			}
			val4.itemData = new Item
			{
				itemName = "Shotgun Shell",
				itemTag = "shotgun_shell",
				itemTags = new List<string> { "ammo", "shotgun_shell" },
				prefabName = "Item_ShotgunShell",
				upDirection = Vector3.up,
				pocketable = true,
				pouchable = true,
				worth = 2,
				inventoryScale = 1f,
				itemWeight = 0.05f,
				data = new List<string>(),
				dataModules = new List<Item_Data>(),
				dataModuleSaves = new List<DataModuleSave>(),
				pickupSounds = (val6?.pickupSounds ?? new List<AudioClip>()),
				executionModules = new List<ItemExecutionModule>(),
				itemAsset = val4,
				handItemAsset = (((Object)(object)ShellHandItemTemplate != (Object)null) ? ShellHandItemTemplate : val6?.handItemAsset)
			};
			val4.canPickup = true;
			val4.pickupEvent = new UnityEvent();
			val4.onDrop = new UnityEvent();
			ApplyGameShader(val);
			if ((Object)(object)ShellOutlineMaterial == (Object)null)
			{
				ShellOutlineMaterial = TryBuildGameOutlineMaterial(new Color(1f, 0.2f, 0.2f, 1f), "ShotgunMod_ShellOutline");
			}
			ShotgunModHandler.EnsureHaloOnGameObject(val, ShellOutlineMaterial);
			ManualLogSource log2 = Log;
			if (log2 != null)
			{
				log2.LogInfo((object)("[Shell] ShotgunShellTemplate built from prefab '" + ((Object)ShellWorldMeshPrefab).name + "'"));
			}
			ShotgunShellTemplatesByType["buckshot"] = ShotgunShellTemplate;
		}

		public static void EnsureTypedShellTemplates()
		{
			EnsureShotgunShellTemplate();
			if ((Object)(object)ShotgunShellTemplate == (Object)null)
			{
				return;
			}
			string[] array = new string[5] { "slug", "dragon", "blank", "reverse", "rebar" };
			foreach (string text in array)
			{
				if (ShotgunShellTemplatesByType.ContainsKey(text))
				{
					continue;
				}
				GameObject val = Object.Instantiate<GameObject>(((Component)ShotgunShellTemplate).gameObject);
				val.SetActive(false);
				((Object)val).name = "cici_shell_" + text;
				((Object)val).hideFlags = (HideFlags)61;
				Object.DontDestroyOnLoad((Object)(object)val);
				GameObject shellMeshForType = GetShellMeshForType(text);
				if ((Object)(object)shellMeshForType != (Object)null && (Object)(object)shellMeshForType != (Object)(object)ShellWorldMeshPrefab)
				{
					MeshFilter componentInChildren = shellMeshForType.GetComponentInChildren<MeshFilter>(true);
					MeshRenderer componentInChildren2 = shellMeshForType.GetComponentInChildren<MeshRenderer>(true);
					if ((Object)(object)((componentInChildren != null) ? componentInChildren.sharedMesh : null) != (Object)null)
					{
						MeshFilter[] componentsInChildren = val.GetComponentsInChildren<MeshFilter>(true);
						foreach (MeshFilter val2 in componentsInChildren)
						{
							if (!((Object)((Component)val2).gameObject).name.StartsWith("ShotgunHalo_"))
							{
								val2.sharedMesh = componentInChildren.sharedMesh;
							}
						}
					}
					if ((Object)(object)componentInChildren2 != (Object)null)
					{
						MeshRenderer[] componentsInChildren2 = val.GetComponentsInChildren<MeshRenderer>(true);
						foreach (MeshRenderer val3 in componentsInChildren2)
						{
							if (!((Object)((Component)val3).gameObject).name.StartsWith("ShotgunHalo_"))
							{
								((Renderer)val3).sharedMaterials = ((Renderer)componentInChildren2).sharedMaterials;
							}
						}
					}
				}
				Item_Object val4 = val.GetComponent<Item_Object>();
				if ((Object)(object)val4 == (Object)null)
				{
					val4 = val.AddComponent<Item_Object>();
				}
				Item clone = ShotgunShellTemplate.itemData.GetClone((Item)null);
				SetShellType(clone, text);
				clone.itemName = "Shotgun Shell (" + text + ")";
				clone.itemAsset = val4;
				if (ShellVendingPrices.TryGetValue(text, out var value))
				{
					clone.worth = value;
				}
				val4.itemData = clone;
				ApplyGameShader(val);
				Material val5 = PickShellOutlineMaterial(text);
				if ((Object)(object)val5 != (Object)null)
				{
					ShotgunModHandler.EnsureHaloOnGameObject(val, val5);
				}
				ShotgunShellTemplatesByType[text] = val4;
				string text2 = ((clone.data != null) ? string.Join(",", clone.data) : "<null>");
				ManualLogSource log = Log;
				if (log != null)
				{
					log.LogInfo((object)("[Shell] typed template built: " + text + " → " + ((Object)val).name + " (itemData.data=[" + text2 + "])"));
				}
			}
		}

		public static Item_Object EnsureShellVendingSpawnTemplateForType(string shellType)
		{
			//IL_0059: Unknown result type (might be due to invalid IL or missing references)
			//IL_0063: Expected O, but got Unknown
			if (_shellVendingTemplatesByType.TryGetValue(shellType, out var value) && (Object)(object)value != (Object)null && (Object)(object)((Component)value).gameObject != (Object)null)
			{
				return value;
			}
			EnsureTypedShellTemplates();
			if (!ShotgunShellTemplatesByType.TryGetValue(shellType, out var value2) || (Object)(object)value2 == (Object)null)
			{
				return null;
			}
			if ((Object)(object)_shellVendingSpawnContainer == (Object)null)
			{
				_shellVendingSpawnContainer = new GameObject("CiCiShellVendingSpawnContainer");
				_shellVendingSpawnContainer.SetActive(false);
				((Object)_shellVendingSpawnContainer).hideFlags = (HideFlags)61;
				Object.DontDestroyOnLoad((Object)(object)_shellVendingSpawnContainer);
			}
			GameObject obj = Object.Instantiate<GameObject>(((Component)value2).gameObject, _shellVendingSpawnContainer.transform);
			obj.SetActive(true);
			((Object)obj).name = "ShotgunShell_VendingSpawnTemplate_" + shellType;
			Item_Object component = obj.GetComponent<Item_Object>();
			if ((Object)(object)component != (Object)null && component.itemData == null)
			{
				component.itemData = value2.itemData;
			}
			_shellVendingTemplatesByType[shellType] = component;
			return component;
		}

		public static Purchase GetOrBuildShellVendingPurchaseForType(string shellType)
		{
			//IL_0072: Unknown result type (might be due to invalid IL or missing references)
			//IL_0077: 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_0093: 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_009e: Expected O, but got Unknown
			//IL_009e: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b0: 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_00be: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d2: Expected O, but got Unknown
			if (_shellVendingPurchasesByType.TryGetValue(shellType, out var value) && (Object)(object)value?.itemObject != (Object)null)
			{
				return value;
			}
			Item_Object val = EnsureShellVendingSpawnTemplateForType(shellType);
			if ((Object)(object)val == (Object)null)
			{
				return null;
			}
			ShellVendingSpritesByType.TryGetValue(shellType, out var value2);
			if ((Object)(object)value2 == (Object)null)
			{
				value2 = GetShellHeldSpriteForType(shellType) ?? ShellHeldSprite;
			}
			ShellVendingPrices.TryGetValue(shellType, out var value3);
			if (value3 <= 0)
			{
				value3 = 4;
			}
			Purchase val2 = new Purchase
			{
				name = "cici_shotgun_shell_" + shellType,
				chance = 1f,
				spawnSettings = new SpawnSettings(),
				itemObject = val,
				spawnAssets = new List<GameObject>(),
				price = value3,
				purchaseSprite = value2,
				requiredItemTag = "",
				ignoreUnlocked = true
			};
			_shellVendingPurchasesByType[shellType] = val2;
			return val2;
		}

		public static int GetShellVendingStockForType(string shellType)
		{
			if (!ShellVendingStocksByType.TryGetValue(shellType, out var value))
			{
				return 1;
			}
			return value;
		}

		public static void EnsureShotgunVendingSpawnTemplate()
		{
			//IL_0045: Unknown result type (might be due to invalid IL or missing references)
			//IL_004f: Expected O, but got Unknown
			if ((Object)(object)ShotgunVendingSpawnTemplate != (Object)null && (Object)(object)((Component)ShotgunVendingSpawnTemplate).gameObject != (Object)null)
			{
				return;
			}
			EnsureShotgunTemplate();
			if (!((Object)(object)ShotgunTemplate == (Object)null))
			{
				if ((Object)(object)_shotgunVendingSpawnContainer == (Object)null)
				{
					_shotgunVendingSpawnContainer = new GameObject("CiCiShotgunVendingSpawnContainer");
					_shotgunVendingSpawnContainer.SetActive(false);
					((Object)_shotgunVendingSpawnContainer).hideFlags = (HideFlags)61;
					Object.DontDestroyOnLoad((Object)(object)_shotgunVendingSpawnContainer);
				}
				GameObject obj = Object.Instantiate<GameObject>(((Component)ShotgunTemplate).gameObject, _shotgunVendingSpawnContainer.transform);
				obj.SetActive(true);
				((Object)obj).name = "Shotgun_VendingSpawnTemplate";
				Item_Object component = obj.GetComponent<Item_Object>();
				if ((Object)(object)component != (Object)null && component.itemData == null)
				{
					component.itemData = ShotgunTemplate.itemData;
				}
				ShotgunVendingSpawnTemplate = component;
			}
		}

		public static Purchase GetOrBuildShotgunVendingPurchase()
		{
			//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_0043: 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_004f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0059: Expected O, but got Unknown
			//IL_0059: Unknown result type (might be due to invalid IL or missing references)
			//IL_0064: Unknown result type (might be due to invalid IL or missing references)
			//IL_006f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0077: Unknown result type (might be due to invalid IL or missing references)
			//IL_0082: Unknown result type (might be due to invalid IL or missing references)
			//IL_008d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0099: Expected O, but got Unknown
			if (_shotgunVendingPurchase != null && (Object)(object)_shotgunVendingPurchase.itemObject != (Object)null)
			{
				return _shotgunVendingPurchase;
			}
			EnsureShotgunVendingSpawnTemplate();
			if ((Object)(object)ShotgunVendingSpawnTemplate == (Object)null)
			{
				return null;
			}
			_shotgunVendingPurchase = new Purchase
			{
				name = "cici_shotgun",
				chance = 1f,
				spawnSettings = new SpawnSettings(),
				itemObject = ShotgunVendingSpawnTemplate,
				spawnAssets = new List<GameObject>(),
				price = 28,
				purchaseSprite = ShotgunVendingSprite,
				requiredItemTag = "",
				ignoreUnlocked = true
			};
			return _shotgunVendingPurchase;
		}

		public static string PickWeightedVendingShellType()
		{
			int num = 0;
			foreach (KeyValuePair<string, int> shellVendingWeight in ShellVendingWeights)
			{
				num += shellVendingWeight.Value;
			}
			if (num <= 0)
			{
				return null;
			}
			int num2 = Random.Range(0, num);
			int num3 = 0;
			foreach (KeyValuePair<string, int> shellVendingWeight2 in ShellVendingWeights)
			{
				num3 += shellVendingWeight2.Value;
				if (num2 < num3)
				{
					return shellVendingWeight2.Key;
				}
			}
			return "buckshot";
		}

		public static bool IsShotgunHeldOrInBag()
		{
			float unscaledTime = Time.unscaledTime;
			if (unscaledTime - _shotgunPossessionCacheAt < 0.5f)
			{
				return _cachedShotgunInPossession;
			}
			_shotgunPossessionCacheAt = unscaledTime;
			_cachedShotgunInPossession = ComputeShotgunInPossession();
			return _cachedShotgunInPossession;
		}

		private static bool ComputeShotgunInPossession()
		{
			try
			{
				ENT_Player playerObject = ENT_Player.playerObject;
				if (playerObject?.hands != null)
				{
					Hand[] hands = playerObject.hands;
					foreach (Hand obj in hands)
					{
						if (((obj != null) ? obj.GetHandItem() : null)?.item?.itemTag == "shotgun")
						{
							return true;
						}
					}
				}
				Inventory instance = Inventory.instance;
				if (instance?.bagItems != null)
				{
					foreach (Item bagItem in instance.bagItems)
					{
						if (bagItem?.itemTag == "shotgun")
						{
							return true;
						}
					}
				}
			}
			catch
			{
			}
			return false;
		}

		public static void EnsureShellHandItemTemplate()
		{
			if ((Object)(object)ShellHandItemTemplate != (Object)null)
			{
				return;
			}
			HandItem val = null;
			try
			{
				GameObject assetGameObject = CL_AssetManager.GetAssetGameObject("Item_Flaregun_Ammo", "");
				val = (((Object)(object)assetGameObject != (Object)null) ? assetGameObject.GetComponent<Item_Object>() : null)?.itemData?.handItemAsset;
			}
			catch (Exception ex)
			{
				ManualLogSource log = Log;
				if (log != null)
				{
					log.LogWarning((object)("Flare ammo HandItem lookup failed during shell clone: " + ex.Message));
				}
				return;
			}
			if ((Object)(object)val == (Object)null)
			{
				ManualLogSource log2 = Log;
				if (log2 != null)
				{
					log2.LogWarning((object)"Flare ammo HandItem prefab not found — shell HandItem clone deferred");
				}
				return;
			}
			GameObject val2 = Object.Instantiate<GameObject>(((Component)val).gameObject);
			((Object)val2).name = "ShotgunMod_ShellHandItem";
			val2.SetActive(false);
			((Object)val2).hideFlags = (HideFlags)61;
			Object.DontDestroyOnLoad((Object)(object)val2);
			HandItem component = val2.GetComponent<HandItem>();
			if ((Object)(object)component == (Object)null)
			{
				ManualLogSource log3 = Log;
				if (log3 != null)
				{
					log3.LogWarning((object)"Cloned flare-ammo HandItem prefab has no HandItem component — skipping adoption");
				}
				Object.Destroy((Object)(object)val2);
				return;
			}
			if ((Object)(object)ShellHeldSprite != (Object)null)
			{
				SpriteRenderer[] componentsInChildren = val2.GetComponentsInChildren<SpriteRenderer>(true);
				foreach (SpriteRenderer val3 in componentsInChildren)
				{
					if ((Object)(object)val3 == (Object)null || (Object)(object)((Component)val3).GetComponent<Hand_SpriteController>() != (Object)null)
					{
						continue;
					}
					if ((Object)(object)val3.sprite != (Object)null)
					{
						string text = ((Object)val3.sprite).name ?? "";
						if (text.StartsWith("HND_F") || text.StartsWith("HND_B"))
						{
							continue;
						}
					}
					val3.sprite = ShellHeldSprite;
				}
			}
			ShellHandItemTemplate = component;
			ManualLogSource log4 = Log;
			if (log4 != null)
			{
				log4.LogInfo((object)("[Shell] HandItem cloned from '" + ((Object)val).name + "' as '" + ((Object)val2).name + "' (sprite=" + (((Object)(object)ShellHeldSprite != (Object)null) ? ((Object)ShellHeldSprite).name : "<unchanged>") + ")"));
			}
		}

		public static Item CreateShotgunShellItem()
		{
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			//IL_000a: 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_0020: 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_004c: Unknown result type (might be due to invalid IL or missing references)
			//IL_004d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0052: Unknown result type (might be due to invalid IL or missing references)
			//IL_0057: 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_0065: Unknown result type (might be due to invalid IL or missing references)
			//IL_006c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0077: Unknown result type (might be due to invalid IL or missing references)
			//IL_0082: Unknown result type (might be due to invalid IL or missing references)
			//IL_008d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0098: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a3: 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_00ba: Expected O, but got Unknown
			EnsureShotgunShellTemplate();
			Item val = new Item
			{
				itemName = "Shotgun Shell",
				itemTag = "shotgun_shell",
				itemTags = new List<string> { "ammo", "shotgun_shell" },
				prefabName = "Item_ShotgunShell",
				upDirection = Vector3.up,
				pocketable = true,
				pouchable = true,
				worth = 2,
				inventoryScale = 1f,
				itemWeight = 0.05f,
				data = new List<string>(),
				dataModules = new List<Item_Data>(),
				dataModuleSaves = new List<DataModuleSave>(),
				pickupSounds = new List<AudioClip>(),
				executionModules = new List<ItemExecutionModule>()
			};
			if ((Object)(object)ShotgunShellTemplate != (Object)null)
			{
				val.itemAsset = ShotgunShellTemplate;
			}
			return val;
		}

		public static void EnsureShotgunHandItemTemplate()
		{
			if ((Object)(object)ShotgunHandItemTemplate != (Object)null)
			{
				return;
			}
			HandItem val = null;
			try
			{
				GameObject assetGameObject = CL_AssetManager.GetAssetGameObject("Item_Flaregun", "");
				val = (((Object)(object)assetGameObject != (Object)null) ? assetGameObject.GetComponent<Item_Object>() : null)?.itemData?.handItemAsset;
			}
			catch (Exception ex)
			{
				ManualLogSource log = Log;
				if (log != null)
				{
					log.LogWarning((object)("Flare HandItem lookup failed during clone: " + ex.Message));
				}
				return;
			}
			if ((Object)(object)val == (Object)null)
			{
				ManualLogSource log2 = Log;
				if (log2 != null)
				{
					log2.LogWarning((object)"Flare HandItem_Shoot prefab not found — shotgun HandItem decouple deferred");
				}
				return;
			}
			GameObject val2 = Object.Instantiate<GameObject>(((Component)val).gameObject);
			((Object)val2).name = "ShotgunMod_HandItem";
			val2.SetActive(false);
			((Object)val2).hideFlags = (HideFlags)61;
			Object.DontDestroyOnLoad((Object)(object)val2);
			HandItem component = val2.GetComponent<HandItem>();
			if ((Object)(object)component == (Object)null)
			{
				ManualLogSource log3 = Log;
				if (log3 != null)
				{
					log3.LogWarning((object)"Cloned flare HandItem prefab has no HandItem component — skipping adoption");
				}
				Object.Destroy((Object)(object)val2);
				return;
			}
			HandItem_Shoot val3 = (HandItem_Shoot)(object)((component is HandItem_Shoot) ? component : null);
			if ((Object)(object)val3 != (Object)null)
			{
				val3.ammoTag = "shotgun_shell";
			}
			ConfigureShellEjectionVisual(val2);
			ShotgunHandItemTemplate = component;
			ManualLogSource log4 = Log;
			if (log4 != null)
			{
				log4.LogInfo((object)("[Decouple] ShotgunHandItemTemplate cloned from '" + ((Object)val).name + "' as '" + ((Object)val2).name + "' (ammoTag=shotgun_shell)"));
			}
			try
			{
				PrewarmShotgunShaders(val2);
			}
			catch (Exception ex2)
			{
				ManualLogSource log5 = Log;
				if (log5 != null)
				{
					log5.LogWarning((object)("[Decouple] HandItem shader prewarm: " + ex2.Message));
				}
			}
			try
			{
				PrewarmInstantiateLifecycle(val2);
			}
			catch (Exception ex3)
			{
				ManualLogSource log6 = Log;
				if (log6 != null)
				{
					log6.LogWarning((object)("[Decouple] HandItem lifecycle prewarm: " + ex3.Message));
				}
			}
		}

		private static void PrewarmInstantiateLifecycle(GameObject template)
		{
			//IL_000f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0015: Expected O, but got Unknown
			//IL_003a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0060: Unknown result type (might be due to invalid IL or missing references)
			//IL_0065: Unknown result type (might be due to invalid IL or missing references)
			//IL_006e: Expected O, but got Unknown
			//IL_00cc: Unknown result type (might be due to invalid IL or missing references)
			//IL_00dd: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ee: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)template == (Object)null)
			{
				return;
			}
			GameObject val = new GameObject("ShotgunMod_LifecyclePrewarmCam");
			((Object)val).hideFlags = (HideFlags)61;
			Camera val2 = val.AddComponent<Camera>();
			((Behaviour)val2).enabled = false;
			val2.cullingMask = -1;
			val2.clearFlags = (CameraClearFlags)2;
			val2.backgroundColor = Color.black;
			val2.nearClipPlane = 0.01f;
			val2.farClipPlane = 100f;
			RenderTexture val4 = (val2.targetTexture = new RenderTexture(64, 64, 16)
			{
				hideFlags = (HideFlags)61
			});
			bool activeSelf = template.activeSelf;
			if (activeSelf)
			{
				template.SetActive(false);
			}
			GameObject val5 = Object.Instantiate<GameObject>(template);
			((Object)val5).name = "ShotgunMod_LifecycleDummy";
			((Object)val5).hideFlags = (HideFlags)61;
			val5.transform.SetParent(val.transform, false);
			val5.transform.localPosition = new Vector3(0f, 0f, 1f);
			val5.transform.localRotation = Quaternion.identity;
			val5.transform.localScale = Vector3.one;
			val5.SetActive(true);
			Component[] componentsInChildren = val5.GetComponentsInChildren<Component>(true);
			foreach (Component val6 in componentsInChildren)
			{
				if ((Object)(object)val6 == (Object)null)
				{
					continue;
				}
				Renderer val7 = (Renderer)(object)((val6 is Renderer) ? val6 : null);
				if (val7 != null)
				{
					val7.enabled = true;
					_ = val7.material;
					continue;
				}
				ParticleSystem val8 = (ParticleSystem)(object)((val6 is ParticleSystem) ? val6 : null);
				if (val8 != null)
				{
					val8.Emit(1);
					val8.Clear();
					continue;
				}
				Animator val9 = (Animator)(object)((val6 is Animator) ? val6 : null);
				if (val9 != null)
				{
					((Behaviour)val9).enabled = true;
					val9.Update(0f);
				}
			}
			try
			{
				val2.Render();
			}
			catch
			{
			}
			SpriteRenderer[] componentsInChildren2 = val5.GetComponentsInChildren<SpriteRenderer>(true);
			SpriteRenderer val10 = null;
			List<SpriteRenderer> list = new List<SpriteRenderer>();
			foreach (SpriteRenderer val11 in componentsInChildren2)
			{
				if ((Object)(object)val11 == (Object)null)
				{
					continue;
				}
				if ((Object)(object)val11.sprite != (Object)null)
				{
					string text = ((Object)val11.sprite).name ?? "";
					if (text.StartsWith("HND_F") || text.StartsWith("HND_B"))
					{
						list.Add(val11);
						continue;
					}
				}
				if (((Object)((Component)val11).gameObject).name == "Item_Hands_Flaregun" && (Object)(object)val10 == (Object)null)
				{
					val10 = val11;
				}
			}
			if ((Object)(object)val10 != (Object)null)
			{
				CyclePrewarmSprite(val10, SpriteLoaded, val2);
				CyclePrewarmSprite(val10, SpriteRecoil, val2);
				CyclePrewarmSprite(val10, SpriteEmpty, val2);
			}
			if (list.Count > 0)
			{
				if ((Object)(object)ShotgunModHandler._targetForegroundHand == (Object)null)
				{
					ShotgunModHandler._targetForegroundHand = ShotgunModHandler.LoadHandSpriteFromOwnPng("Hands_Foreground_Library_03.png", "HND_F3D1");
				}
				if ((Object)(object)ShotgunModHandler._targetBackgroundHand == (Object)null)
				{
					ShotgunModHandler._targetBackgroundHand = ShotgunModHandler.LoadHandSpriteFromOwnPng("Hands_Background_Library_03.png", "HND_B3D1");
				}
				for (int k = 0; k < list.Count; k++)
				{
					SpriteRenderer val12 = list[k];
					if (!((Object)(object)val12 == (Object)null) && !((Object)(object)val12.sprite == (Object)null))
					{
						string name = ((Object)val12.sprite).name;
						Sprite val13 = null;
						if (name.StartsWith("HND_F"))
						{
							val13 = ShotgunModHandler._targetForegroundHand;
						}
						else if (name.StartsWith("HND_B"))
						{
							val13 = ShotgunModHandler._targetBackgroundHand;
						}
						if ((Object)(object)val13 != (Object)null)
						{
							CyclePrewarmSprite(val12, val13, val2);
						}
					}
				}
			}
			template.SetActive(activeSelf);
			Object.Destroy((Object)(object)val5);
			val2.targetTexture = null;
			Object.Destroy((Object)(object)val);
			Object.Destroy((Object)(object)val4);
			ManualLogSource log = Log;
			if (log != null)
			{
				log.LogInfo((object)$"[Shotgun] lifecycle prewarm complete for '{((Object)template).name}' (body+{list.Count} hands cycled)");
			}
		}

		private static void CyclePrewarmSprite(SpriteRenderer sr, Sprite sp, Camera cam)
		{
			if ((Object)(object)sr == (Object)null || (Object)(object)sp == (Object)null || (Object)(object)cam == (Object)null)
			{
				return;
			}
			try
			{
				sr.sprite = sp;
				cam.Render();
			}
			catch
			{
			}
		}

		private static void ConfigureShellEjectionVisual(GameObject handItemRoot)
		{
			//IL_0088: 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_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_0073: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)handItemRoot == (Object)null)
			{
				return;
			}
			Transform[] componentsInChildren = handItemRoot.GetComponentsInChildren<Transform>(true);
			foreach (Transform val in componentsInChildren)
			{
				if ((Object)(object)val == (Object)null || ((Object)val).name != "Effect_Eject")
				{
					continue;
				}
				ParticleSystem component = ((Component)val).GetComponent<ParticleSystem>();
				if ((Object)(object)component == (Object)null)
				{
					continue;
				}
				if (!ShellEjectAnchorBaseCaptured)
				{
					ShellEjectAnchorBaseLocal = val.localPosition;
					ShellEjectAnchorBaseCaptured = true;
					ManualLogSource log = Log;
					if (log != null)
					{
						log.LogInfo((object)$"[ShellEject] Captured base Effect_Eject localPosition = {ShellEjectAnchorBaseLocal}");
					}
				}
				EmissionModule emission = component.emission;
				((EmissionModule)(ref emission)).enabled = false;
				ParticleSystemRenderer component2 = ((Component)component).GetComponent<ParticleSystemRenderer>();
				if ((Object)(object)component2 != (Object)null)
				{
					((Renderer)component2).enabled = false;
				}
			}
		}

		public static void ApplyGameShader(GameObject target)
		{
			string[] obj = new string[1] { "Dark Machine/SHDR_Base" };
			Shader val = null;
			string[] array = obj;
			for (int i = 0; i < array.Length; i++)
			{
				val = Shader.Find(array[i]);
				if ((Object)(object)val != (Object)null)
				{
					break;
				}
			}
			if ((Object)(object)val == (Object)null)
			{
				ManualLogSource log = Log;
				if (log != null)
				{
					log.LogWarning((object)"No game shader found, falling back to Unlit/Texture");
				}
				val = Shader.Find("Unlit/Texture");
			}
			if ((Object)(object)val == (Object)null)
			{
				return;
			}
			Renderer[] componentsInChildren = target.GetComponentsInChildren<Renderer>(true);
			foreach (Renderer val2 in componentsInChildren)
			{
				if (((Object)((Component)val2).gameObject).name.StartsWith("ShotgunHalo_"))
				{
					continue;
				}
				Material[] materials = val2.materials;
				for (int j = 0; j < materials.Length; j++)
				{
					if (!((Object)(object)materials[j] == (Object)null))
					{
						Texture val3 = (materials[j].HasProperty("_MainTex") ? materials[j].GetTexture("_MainTex") : null);
						materials[j].shader = val;
						if ((Object)(object)val3 != (Object)null && materials[j].HasProperty("_MainTex"))
						{
							materials[j].SetTexture("_MainTex", val3);
						}
						ApplyItemShimmer(materials[j], val3);
					}
				}
				val2.materials = materials;
			}
		}

		public static void ApplyItemShimmer(Material m, Texture emissionMask)
		{
			//IL_00cb: Unknown result type (might be due to invalid IL or missing references)
			if (!((Object)(object)m == (Object)null))
			{
				if (m.HasProperty("_Shimmer"))
				{
					m.SetFloat("_Shimmer", 1f);
				}
				if (m.HasProperty("_ShimmerFrequency"))
				{
					m.SetFloat("_ShimmerFrequency", 1f);
				}
				if (m.HasProperty("_ShimmerSpeed"))
				{
					m.SetFloat("_ShimmerSpeed", 1f);
				}
				if (m.HasProperty("_ShimmerOver"))
				{
					m.SetFloat("_ShimmerOver", 0f);
				}
				if (m.HasProperty("_ShimmerOffset"))
				{
					m.SetFloat("_ShimmerOffset", 0f);
				}
				if (m.HasProperty("_ShimmerTextureMix"))
				{
					m.SetFloat("_ShimmerTextureMix", 1f);
				}
				if (m.HasProperty("_ShimmerColor"))
				{
					m.SetColor("_ShimmerColor", Color.white);
				}
				if (m.HasProperty("_Shading"))
				{
					m.SetFloat("_Shading", 0.96f);
				}
				if (m.HasProperty("_DitherAmount"))
				{
					m.SetFloat("_DitherAmount", 0.63f);
				}
				if (m.HasProperty("_ROUNDMULT"))
				{
					m.SetFloat("_ROUNDMULT", 1.27f);
				}
				if (m.HasProperty("_Wiggle"))
				{
					m.SetFloat("_Wiggle", 0.0003f);
				}
				if (m.HasProperty("_WiggleFreq"))
				{
					m.SetFloat("_WiggleFreq", 2f);
				}
				if (m.HasProperty("_WiggleSpeed"))
				{
					m.SetFloat("_WiggleSpeed", 5f);
				}
			}
		}

		private void LoadCustomAudio()
		{
			string directoryName = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location);
			ShotgunFireClip = TryLoadWav(directoryName, "shotgun_fire.wav");
			ShotgunDryFireClip = TryLoadWav(directoryName, "shotgun_dryfire.wav");
			ShotgunReloadSingleClip = TryLoadWav(directoryName, "shotgun_reload_single.wav");
			ShotgunBreakOpenClip = TryLoadWav(directoryName, "shotgun_break_open.wav");
			ShotgunBreakCloseClip = TryLoadWav(directoryName, "shotgun_break_close.wav");
			ShotgunImpactClip = TryLoadWav(directoryName, "shotgun_impact.wav");
		}

		private void LoadTrinketIcons()
		{
			string directoryName = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location);
			PioneersEdgeIcon = TryLoadSpritePng(directoryName, "cici_pioneers_edge_icon.png");
			InfestationIcon = TryLoadSpritePng(directoryName, "Infestation_Icon.png");
			ShotgunVendingSprite = TryLoadSpritePng(directoryName, "Vending_Shotgun.png");
		}

		private void LoadShellVariantSprites()
		{
			string directoryName = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location);
			(string, string)[] obj = new(string, string)[6]
			{
				("buckshot", "buckshot_shell_hand_item.png"),
				("slug", "buckshot_shell_S_hand_item.png"),
				("dragon", "buckshot_shell_D_hand_item.png"),
				("blank", "buckshot_shell_B_hand_item.png"),
				("reverse", "buckshot_shell_Rev_hand_item.png"),
				("rebar", "buckshot_shell_Re_hand_item.png")
			};
			ShellHeldSpritesByType.Clear();
			(string, string)[] array = obj;
			for (int i = 0; i < array.Length; i++)
			{
				(string, string) tuple = array[i];
				string item = tuple.Item1;
				string item2 = tuple.Item2;
				Sprite val = TryLoadSpritePng(directoryName, item2);
				if ((Object)(object)val != (Object)null)
				{
					ShellHeldSpritesByType[item] = val;
				}
			}
			if (ShellHeldSpritesByType.TryGetValue("buckshot", out var value))
			{
				ShellHeldSprite = value;
			}
			(string, string)[] obj2 = new(string, string)[6]
			{
				("buckshot", "buckshot_shell_tumbling.png"),
				("slug", "buckshot_shell_tumbling_S.png"),
				("dragon", "buckshot_shell_tumbling_D.png"),
				("blank", "buckshot_shell_tumbling_B.png"),
				("reverse", "buckshot_shell_tumbling_Rev.png"),
				("rebar", "buckshot_shell_tumbling_Re.png")
			};
			ShellEjectedFramesByType.Clear();
			array = obj2;
			for (int i = 0; i < array.Length; i++)
			{
				(string, string) tuple2 = array[i];
				string item3 = tuple2.Item1;
				string item4 = tuple2.Item2;
				Sprite[] array2 = LoadTumblingSheet(directoryName, item4);
				if (array2 != null)
				{
					ShellEjectedFramesByType[item3] = array2;
				}
			}
			if (ShellEjectedFramesByType.TryGetValue("buckshot", out var value2))
			{
				ShellEjectedFrames = value2;
			}
			(string, string)[] obj3 = new(string, string)[5]
			{
				("buckshot", "Vending_Shotgun_Ammo.png"),
				("slug", "Vending_Shotgun_Ammo_S.png"),
				("blank", "Vending_Shotgun_Ammo_B.png"),
				("dragon", "Vending_Shotgun_Ammo_D.png"),
				("reverse", "Vending_Shotgun_Ammo_Rev.png")
			};
			ShellVendingSpritesByType.Clear();
			array = obj3;
			for (int i = 0; i < array.Length; i++)
			{
				(string, string) tuple3 = array[i];
				string item5 = tuple3.Item1;
				string item6 = tuple3.Item2;
				Sprite val2 = TryLoadSpritePng(directoryName, item6);
				if ((Object)(object)val2 != (Object)null)
				{
					ShellVendingSpritesByType[item5] = val2;
				}
			}
			ManualLogSource log = Log;
			if (log != null)
			{
				log.LogInfo((object)$"[ShellSprites] held variants loaded: {ShellHeldSpritesByType.Count}/6, ejected variants loaded: {ShellEjectedFramesByType.Count}/6, vending icons loaded: {ShellVendingSpritesByType.Count}/5");
			}
		}

		private Sprite[] LoadTumblingSheet(string dir, string filename)
		{
			//IL_001e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0024: Expected O, but got Unknown
			//IL_0080: 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)
			string path = Path.Combine(dir, filename);
			if (!File.Exists(path))
			{
				return null;
			}
			try
			{
				byte[] array = File.ReadAllBytes(path);
				Texture2D val = new Texture2D(2, 2, (TextureFormat)4, false);
				if (!ImageConversion.LoadImage(val, array))
				{
					return null;
				}
				((Texture)val).filterMode = (FilterMode)0;
				((Texture)val).wrapMode = (TextureWrapMode)1;
				Object.DontDestroyOnLoad((Object)(object)val);
				int num = Mathf.Max(1, ((Texture)val).width / 4);
				Sprite[] array2 = (Sprite[])(object)new Sprite[4];
				Rect val2 = default(Rect);
				for (int i = 0; i < 4; i++)
				{
					((Rect)(ref val2))..ctor((float)(i * num), 0f, (float)num, (float)((Texture)val).height);
					Sprite val3 = Sprite.Create(val, val2, new Vector2(0.5f, 0.5f), 100f);
					((Object)val3).name = $"{filename}_frame_{i}";
					Object.DontDestroyOnLoad((Object)(object)val3);
					array2[i] = val3;
				}
				return array2;
			}
			catch (Exception ex)
			{
				ManualLogSource log = Log;
				if (log != null)
				{
					log.LogWarning((object)("[ShellSprites] tumbling sheet load failed for " + filename + ": " + ex.Message));
				}
				return null;
			}
		}

		private Sprite TryLoadSpritePng(string dir, string filename)
		{
			//IL_0059: Unknown result type (might be due to invalid IL or missing references)
			//IL_005f: Expected O, but got Unknown
			//IL_0096: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a5: Unknown result type (might be due to invalid IL or missing references)
			string text = Path.Combine(dir, filename);
			if (!File.Exists(text))
			{
				ManualLogSource log = Log;
				if (log != null)
				{
					log.LogWarning((object)("Trinket icon not found: " + filename + " (at " + text + ") — will use vanilla fallback"));
				}
				return null;
			}
			try
			{
				byte[] array = File.ReadAllBytes(text);
				Texture2D val = new Texture2D(2, 2, (TextureFormat)4, false);
				if (!ImageConversion.LoadImage(val, array))
				{
					return null;
				}
				((Texture)val).filterMode = (FilterMode)0;
				((Texture)val).wrapMode = (TextureWrapMode)1;
				Sprite obj = Sprite.Create(val, new Rect(0f, 0f, (float)((Texture)val).width, (float)((Texture)val).height), new Vector2(0.5f, 0.5f), 100f);
				((Object)obj).name = filename;
				Object.DontDestroyOnLoad((Object)(object)obj);
				Object.DontDestroyOnLoad((Object)(object)val);
				return obj;
			}
			catch (Exception ex)
			{
				ManualLogSource log2 = Log;
				if (log2 != null)
				{
					log2.LogWarning((object)("Trinket icon load failed for " + filename + ": " + ex.Message));
				}
				return null;
			}
		}

		private AudioClip TryLoadWav(string dir, string filename)
		{
			string text = Path.Combine(dir, filename);
			if (!File.Exists(text))
			{
				Log.LogWarning((object)("Audio not found: " + filename + " (at " + text + ") — will fall back to game sound"));
				return null;
			}
			try
			{
				return WavLoader.LoadFromFile(text);
			}
			catch (Exception ex)
			{
				Log.LogError((object)("WAV load failed for " + filename + ": " + ex.Message));
				return null;
			}
		}

		private void LoadAssetBundle()
		{
			string text = Path.Combine(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location), "shotgunmod");
			if (!File.Exists(text))
			{
				Log.LogError((object)("Asset bundle not found at: " + text));
				return;
			}
			AssetBundle val = AssetBundle.LoadFromFile(text);
			if ((Object)(object)val == (Object)null)
			{
				Log.LogError((object)"Failed to load asset bundle (LoadFromFile returned null)");
				return;
			}
			val.GetAllAssetNames();
			GameObject[] array = val.LoadAllAssets<GameObject>();
			if (array == null || array.Length == 0)
			{
				Log.LogError((object)"No GameObject assets found in bundle");
				return;
			}
			ShotgunPrefab = val.LoadAsset<GameObject>("Assets/Shotgun.prefab");
			GameObject[] array2;
			if ((Object)(object)ShotgunPrefab == (Object)null)
			{
				array2 = array;
				foreach (GameObject val2 in array2)
				{
					if ((Object)(object)val2 != (Object)null && ((Object)val2).name == "Shotgun")
					{
						ShotgunPrefab = val2;
						break;
					}
				}
			}
			if ((Object)(object)ShotgunPrefab == (Object)null)
			{
				array2 = array;
				foreach (GameObject val3 in array2)
				{
					if (!((Object)(object)val3 == (Object)null) && (Object)(object)val3.GetComponent<Item_Object>() != (Object)null)
					{
						ShotgunPrefab = val3;
						break;
					}
				}
			}
			if ((Object)(object)ShotgunPrefab == (Object)null)
			{
				array2 = array;
				foreach (GameObject val4 in array2)
				{
					if (!((Object)(object)val4 == (Object)null) && (((Object)val4).name ?? "").Equals("shotgun_mesh", StringComparison.OrdinalIgnoreCase))
					{
						ShotgunPrefab = val4;
						break;
					}
				}
			}
			if ((Object)(object)ShotgunPrefab == (Object)null)
			{
				ManualLogSource log = Log;
				if (log != null)
				{
					log.LogError((object)"[ShotgunBundle] No Shotgun.prefab, no Item_Object, and no 'shotgun_mesh' in bundle — using gameObjects[0] as a last-resort fallback");
				}
				ShotgunPrefab = array[0];
			}
			array2 = array;
			foreach (GameObject val5 in array2)
			{
				if (!((Object)(object)val5 == (Object)null) && (((Object)val5).name ?? "").IndexOf("shotgun_mesh", StringComparison.OrdinalIgnoreCase) >= 0)
				{
					ShotgunMeshPrefab = val5;
					break;
				}
			}
			ManualLogSource log2 = Log;
			if (log2 != null)
			{
				log2.LogInfo((object)("[ShotgunBundle] picked '" + ((Object)ShotgunPrefab).name + "' as ShotgunPrefab, meshFallback='" + (((Object)(object)ShotgunMeshPrefab != (Object)null) ? ((Object)ShotgunMeshPrefab).name : "<none>") + "'"));
			}
			OutlineMaterial = TryBuildGameOutlineMaterial();
			Sprite[] array3 = val.LoadAllAssets<Sprite>();
			foreach (Sprite val6 in array3)
			{
				if (!((Object)(object)val6 == (Object)null))
				{
					if (((Object)val6).name.EndsWith("Loaded"))
					{
						SpriteLoaded = val6;
					}
					else if (((Object)val6).name.EndsWith("Recoil"))
					{
						SpriteRecoil = val6;
					}
					else if (((Object)val6).name.EndsWith("Empty"))
					{
						SpriteEmpty = val6;
					}
				}
			}
		}

		private void LoadShellBundle()
		{
			//IL_03bb: Unknown result type (might be due to invalid IL or missing references)
			//IL_03ca: Unknown result type (might be due to invalid IL or missing references)
			string text = Path.Combine(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location), "shell");
			if (!File.Exists(text))
			{
				Log.LogError((object)("Shell asset bundle not found at: " + text));
				return;
			}
			AssetBundle val = AssetBundle.LoadFromFile(text);
			if ((Object)(object)val == (Object)null)
			{
				Log.LogError((object)"Failed to load shell asset bundle (LoadFromFile returned null)");
				return;
			}
			GameObject[] array = val.LoadAllAssets<GameObject>();
			ShellWorldMeshPrefab = FindBundleMeshByExactName(array, "buckshot_shell_mesh") ?? FindBundleMeshByExactName(array, "shotgun_buckshot_mesh");
			ShellMeshByType.Clear();
			ShellMeshByType["buckshot"] = ShellWorldMeshPrefab;
			ShellMeshByType["blank"] = FindBundleMeshByExactName(array, "shotgun_buckshot_S_mesh");
			ShellMeshByType["slug"] = FindBundleMeshByExactName(array, "shotgun_buckshot_B_mesh");
			ShellMeshByType["dragon"] = FindBundleMeshByExactName(array, "shotgun_buckshot_D_mesh");
			ShellMeshByType["reverse"] = FindBundleMeshByExactName(array, "shotgun_buckshot_Rev_mesh");
			ShellMeshByType["rebar"] = FindBundleMeshByExactName(array, "shotgun_buckshot_Re_mesh");
			if ((Object)(object)ShellWorldMeshPrefab == (Object)null && array.Length != 0)
			{
				ShellWorldMeshPrefab = array[0];
				ShellMeshByType["buckshot"] = ShellWorldMeshPrefab;
				ManualLogSource log = Log;
				if (log != null)
				{
					log.LogWarning((object)("[ShellBundle] no recognized buckshot mesh name found — falling back to first GO '" + ((Object)ShellWorldMeshPrefab).name + "'"));
				}
			}
			ManualLogSource log2 = Log;
			if (log2 != null)
			{
				log2.LogInfo((object)("[ShellBundle] meshes: buckshot=" + NameOrNull(ShellMeshByType["buckshot"]) + " slug=" + NameOrNull(ShellMeshByType["slug"]) + " dragon=" + NameOrNull(ShellMeshByType["dragon"]) + " blank=" + NameOrNull(ShellMeshByType["blank"]) + " reverse=" + NameOrNull(ShellMeshByType["reverse"]) + " rebar=" + NameOrNull(ShellMeshByType["rebar"])));
			}
			Sprite[] array2 = val.LoadAllAssets<Sprite>();
			foreach (Sprite val2 in array2)
			{
				if (!((Object)(object)val2 == (Object)null))
				{
					if (((Object)val2).name.IndexOf("handheld", StringComparison.OrdinalIgnoreCase) >= 0)
					{
						ShellHeldSprite = val2;
					}
					else if (((Object)val2).name.IndexOf("tumbling", StringComparison.OrdinalIgnoreCase) >= 0)
					{
						ShellEjectedSprite = val2;
					}
				}
			}
			ManualLogSource log3 = Log;
			if (log3 != null)
			{
				log3.LogInfo((object)("[ShellBundle] picked: meshPrefab=" + (((Object)(object)ShellWorldMeshPrefab != (Object)null) ? ((Object)ShellWorldMeshPrefab).name : "<null>") + " held=" + (((Object)(object)ShellHeldSprite != (Object)null) ? ((Object)ShellHeldSprite).name : "<null>") + " ejected=" + (((Object)(object)ShellEjectedSprite != (Object)null) ? ((Object)ShellEjectedSprite).name : "<null>")));
			}
			if ((Object)(object)ShellEjectedSprite != (Object)null && (Object)(object)ShellEjectedSprite.texture != (Object)null)
			{
				Texture2D texture = ShellEjectedSprite.texture;
				int num = ((Texture)texture).width / 4;
				int height = ((Texture)texture).height;
				ShellEjectedFrames = (Sprite[])(object)new Sprite[4];
				for (int j = 0; j < 4; j++)
				{
					ShellEjectedFrames[j] = Sprite.Create(texture, new Rect((float)(j * num), 0f, (float)num, (float)height), new Vector2(0.5f, 0.5f), ShellEjectedSprite.pixelsPerUnit);
					((Object)ShellEjectedFrames[j]).name = $"buckshot_tumbling_frame_{j}";
				}
				ManualLogSource log4 = Log;
				if (log4 != null)
				{
					log4.LogInfo((object)$"[ShellBundle] sliced tumbling into 4 frames of {num}x{height}");
				}
			}
		}

		public static Item CreateShotgunItem()
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0005: 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_001b: 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_0047: 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_004d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0052: Unknown result type (might be due to invalid IL or missing references)
			//IL_0059: 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_0068: 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_007e: 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_0094: Unknown result type (might be due to invalid IL or missing references)
			//IL_009f: 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_00b6: Expected O, but got Unknown
			Item val = new Item
			{
				itemName = "Shotgun",
				itemTag = "shotgun",
				itemTags = new List<string> { "weapon", "shotgun" },
				prefabName = "Item_Shotgun",
				upDirection = Vector3.up,
				pocketable = true,
				pouchable = true,
				worth = 56,
				inventoryScale = 1f,
				itemWeight = 1f,
				data = new List<string>(),
				dataModules = new List<Item_Data>(),
				dataModuleSaves = new List<DataModuleSave>(),
				pickupSounds = new List<AudioClip>(),
				executionModules = new List<ItemExecutionModule>()
			};
			try
			{
				EnsureShotgunTemplate();
			}
			catch (Exception ex)
			{
				ManualLogSource log = Log;
				if (log != null)
				{
					log.LogWarning((object)("Template build deferred: " + ex.Message));
				}
			}
			if ((Object)(object)ShotgunTemplate != (Object)null)
			{
				val.itemAsset = ShotgunTemplate;
			}
			EnsureShotgunHandItemTemplate();
			if ((Object)(object)ShotgunHandItemTemplate != (Object)null)
			{
				val.handItemAsset = ShotgunHandItemTemplate;
			}
			else
			{
				try
				{
					GameObject assetGameObject = CL_AssetManager.GetAssetGameObject("Item_Flaregun", "");
					Item_Object val2 = (((Object)(object)assetGameObject != (Object)null) ? assetGameObject.GetComponent<Item_Object>() : null);
					if ((Object)(object)val2?.itemData?.handItemAsset != (Object)null)
					{
						val.handItemAsset = val2.itemData.handItemAsset;
					}
				}
				catch (Exception ex2)
				{
					ManualLogSource log2 = Log;
					if (log2 != null)
					{
						log2.LogWarning((object)("Flare hand fallback failed: " + ex2.Message));
					}
				}
			}
			return val;
		}
	}
	[HarmonyPatch(typeof(Trinket), "GetDescription")]
	public static class SawedOffDescriptionOverridePatch
	{
		[HarmonyPrefix]
		public static bool Prefix(Trinket __instance, ref string __result)
		{
			if ((Object)(object)__instance == (Object)null)
			{
				return true;
			}
			if (((Object)__instance).name == null || !((Object)__instance).name.Contains("cici_pioneers_edge"))
			{
				return true;
			}
			__result = "<color=grey>Trinket:</color> <color=#33FF40><shimmer s=0.1>" + __instance.title + "</shimmer>. </color>" + __instance.description + "\n<color=grey>" + __instance.flavorText + "</color>";
			return false;
		}
	}
	[HarmonyPatch(typeof(CL_AssetManager), "GetAssetGameObject")]
	public static class ShotgunAssetLookupPatch
	{
		[HarmonyPostfix]
		public static void Postfix(string name, ref GameObject __result)
		{
			if (!((Object)(object)__result != (Object)null) && !(name != "Item_Shotgun"))
			{
				try
				{
					Plugin.EnsureShotgunTemplate();
				}
				catch
				{
				}
				if ((Object)(object)Plugin.ShotgunTemplate != (Object)null)
				{
					__result = ((Component)Plugin.ShotgunTemplate).gameObject;
				}
			}
		}
	}
	[HarmonyPatch(typeof(HandItem), "Initialize")]
	public static class ShellPerTypeHeldSpritePatch
	{
		[HarmonyPostfix]
		public static void Postfix(HandItem __instance, Item i)
		{
			if (i?.itemTag != "shotgun_shell")
			{
				return;
			}
			string text = Plugin.GetShellType(i);
			if (string.IsNullOrEmpty(text))
			{
				text = "buckshot";
			}
			Sprite shellHeldSpriteForType = Plugin.GetShellHeldSpriteForType(text);
			if ((Object)(object)shellHeldSpriteForType == (Object)null)
			{
				return;
			}
			Material val = Plugin.EnsureShellShimmerSpriteMaterial(text);
			SpriteRenderer[] componentsInChildren = ((Component)__instance).GetComponentsInChildren<SpriteRenderer>(true);
			foreach (SpriteRenderer val2 in componentsInChildren)
			{
				if ((Object)(object)val2 == (Object)null || (Object)(object)((Component)val2).GetComponent<Hand_SpriteController>() != (Object)null)
				{
					continue;
				}
				if ((Object)(object)val2.sprite != (Object)null)
				{
					string text2 = ((Object)val2.sprite).name ?? "";
					if (text2.StartsWith("HND_F") || text2.StartsWith("HND_B"))
					{
						continue;
					}
				}
				if ((Object)(object)val2.sprite != (Object)(object)shellHeldSpriteForType)
				{
					val2.sprite = shellHeldSpriteForType;
				}
				if ((Object)(object)val != (Object)null && (Object)(object)((Renderer)val2).sharedMaterial != (Object)(object)val)
				{
					((Renderer)val2).sharedMaterial = val;
				}
			}
		}
	}
	public static class InfestationPrefabs
	{
		private const bool DebugLogs = false;

		public static GameObject Bloodbug;

		public static GameObject Barnacle;

		public static GameObject Hopper;

		public static GameObject Drone;

		public static GameObject BarnacleHarpoon;

		public static GameObject HopperExplosive;

		private static SpawnTableAsset[] _groundOnlyAssets;

		private static SpawnTableAsset _bloodbugAsset;

		private static SpawnTableAsset _barnacleAsset;

		private static SpawnTableAsset _hopperAsset;

		private static SpawnTableAsset _droneAsset;

		private static SpawnTableAsset _barnacleHarpoonAsset;

		private static SpawnTableAsset _hopperExplosiveAsset;

		public const float HarpoonChance = 0.1f;

		public const float ExplosiveChance = 0.1f;

		private static bool _attempted;

		public static SpawnTableAsset[] CachedAssets;

		private static GameObject _wrapperContainer;

		public static void TryResolveOnce()
		{
			if (_attempted)
			{
				return;
			}
			_attempted = true;
			new HashSet<string>();
			try
			{
				SpawnTable[] array = Resources.FindObjectsOfTypeAll<SpawnTable>();
				foreach (SpawnTable val in array)
				{
					if (val?.spawnList == null)
					{
						continue;
					}
					foreach (SpawnTableAsset spawn in val.spawnList)
					{
						if (spawn?.prefabs == null)
						{
							continue;
						}
						foreach (GameObject prefab in spawn.prefabs)
						{
							if (!((Object)(object)prefab == (Object)null))
							{
								string text = ((Object)prefab).name?.ToLower() ?? "";
								bool flag = ((Object)prefab).name.Contains(".");
								if (((Object)(object)Bloodbug == (Object)null || ((Object)Bloodbug).name.Contains(".")) && (Object)(object)prefab.GetComponent<DEN_BasicDenizen_Flier>() != (Object)null && text.Contains("bloodbug") && (!flag || (Object)(object)Bloodbug == (Object)null))
								{
									Bloodbug = prefab;
								}
								if (((Object)(object)Barnacle == (Object)null || ((Object)Barnacle).name.Contains(".")) && (Object)(object)prefab.GetComponent<DEN_Barnacle>() != (Object)null && (Object)(object)prefab.GetComponent<DEN_Barnacle_Harpoon>() == (Object)null && text.Contains("barnacle") && !text.Contains("screecher") && !text.Contains("harpoon") && !text.Contains("holiday") && !text.Contains("christmas") && (!flag || (Object)(object)Barnacle == (Object)null))
								{
									Barnacle = prefab;
								}
								if (((Object)(object)Hopper == (Object)null || ((Object)Hopper).name.Contains(".")) && (Object)(object)prefab.GetComponent<DEN_BasicDenizen>() != (Object)null && text.Contains("hopper") && !text.Contains("breeder") && !text.Contains("spawner") && !text.Contains("explosive") && !text.Contains("holiday") && !text.Contains("christmas") && (!flag || (Object)(object)Hopper == (Object)null))
								{
									Hopper = prefab;
								}
								if (((Object)(object)Drone == (Object)null || ((Object)Drone).name.Contains(".")) && (Object)(object)prefab.GetComponent<DEN_Drone>() != (Object)null && text.Contains("drone") && !text.Contains("buddy") && (!flag || (Object)(object)Drone == (Object)null))
								{
									Drone = prefab;
								}
								if (((Object)(object)BarnacleHarpoon == (Object)null || ((Object)BarnacleHarpoon).name.Contains(".")) && (Object)(object)prefab.GetComponent<DEN_Barnacle_Harpoon>() != (Object)null && (!flag || (Object)(object)BarnacleHarpoon == (Object)null))
								{
									BarnacleHarpoon = prefab;
								}
								if (((Object)(object)HopperExplosive == (Object)null || ((Object)HopperExplosive).name.Contains(".")) && (Object)(object)prefab.GetComponent<DEN_BasicDenizen>() != (Object)null && text.Contains("hopper") && text.Contains("explosive") && !text.Contains("breeder") && !text.Contains("spawner") && (!flag || (Object)(object)HopperExplosive == (Object)null))
								{
									HopperExplosive = prefab;
								}
							}
						}
					}
				}
			}
			catch (Exception ex)
			{
				ManualLogSource log = Plugin.Log;
				if (log != null)
				{
					log.LogWarning((object)("[Infestation] SpawnTable scan failed: " + ex.Message));
				}
			}
			try
			{
				if ((Object)(object)Bloodbug == (Object)null)
				{
					Bloodbug = FindFirstDenizenByName<DEN_BasicDenizen_Flier>((Func<string, bool>)((string n) => n.Contains("bloodbug")), (Func<GameObject, bool>)null, preferClean: true);
				}
				if ((Object)(object)Barnacle == (Object)null)
				{
					Barnacle = FindFirstDenizenByName<DEN_Barnacle>((Func<string, bool>)((string n) => n.Contains("barnacle") && !n.Contains("screecher") && !n.Contains("harpoon") && !n.Contains("holiday") && !n.Contains("christmas")), (Func<GameObject, bool>)((GameObject go) => (Object)(object)go.GetComponent<DEN_Barnacle_Harpoon>() != (Object)null), preferClean: true);
				}
				if ((Object)(object)Hopper == (Object)null)
				{
					Hopper = FindFirstDenizenByName<DEN_BasicDenizen>((Func<string, bool>)((string n) => n.Contains("hopper") && !n.Contains("breeder") && !n.Contains("spawner") && !n.Contains("explosive") && !n.Contains("holiday") && !n.Contains("christmas")), (Func<GameObject, bool>)null, preferClean: true);
				}
				if ((Object)(object)Drone == (Object)null)
				{
					Drone = FindFirstDenizenByName<DEN_Drone>((Func<string, bool>)((string n) => n.Contains("drone") && !n.Contains("buddy")), (Func<GameObject, bool>)null, preferClean: true);
				}
				if ((Object)(object)BarnacleHarpoon == (Object)null)
				{
					BarnacleHarpoon = FindFirstDenizenByName<DEN_Barnacle_Harpoon>((Func<string, bool>)((string n) => true), (Func<GameObject, bool>)null, preferClean: true);
				}
				if ((Object)(object)BarnacleHarpoon == (Object)null)
				{
					BarnacleHarpoon = FindFirstDenizenByName<DEN_Barnacle>((Func<string, bool>)((string n) => n.Contains("harpoon")), (Func<GameObject, bool>)null, preferClean: true);
				}
				if ((Object)(object)BarnacleHarpoon == (Object)null)
				{
					GameObject[] array2 = Resources.FindObjectsOfTypeAll<GameObject>();
					foreach (GameObject val2 in array2)
					{
						if (!((Object)(object)val2 == (Object)null))
						{
							string text2 = ((Object)val2).name?.ToLower() ?? "";
							if (text2.Contains("harpoon") && text2.Contains("barnacle"))
							{
								BarnacleHarpoon = val2;
								break;
							}
						}
					}
				}
				if ((Object)(object)HopperExplosive == (Object)null)
				{
					HopperExplosive = FindFirstDenizenByName<DEN_BasicDenizen>((Func<string, bool>)((string n) => n.Contains("hopper") && n.Contains("explosive") && !n.Contains("breeder") && !n.Contains("spawner")), (Func<GameObject, bool>)null, preferClean: true);
				}
			}
			catch (Exception ex2)
			{
				ManualLogSource log2 = Plugin.Log;
				if (log2 != null)
				{
					log2.LogWarning((object)("[Infestation] instance fallback failed: " + ex2.Message));
				}
			}
			ManualLogSource log3 = Plugin.Log;
			if (log3 != null)
			{
				log3.LogInfo((object)("[Infestation] resolve complete — Bloodbug=" + (((Object)(object)Bloodbug != (Object)null) ? ("'" + ((Object)Bloodbug).name + "'") : "MISSING") + " Barnacle=" + (((Object)(object)Barnacle != (Object)null) ? ("'" + ((Object)Barnacle).name + "'") : "MISSING") + " Hopper=" + (((Object)(object)Hopper != (Object)null) ? ("'" + ((Object)Hopper).name + "'") : "MISSING") + " Drone=" + (((Object)(object)Drone != (Object)null) ? ("'" + ((Object)Drone).name + "'") : "MISSING")));
			}
			Bloodbug = EnsureActiveClone(Bloodbug, "Bloodbug");
			Barnacle = EnsureActiveClone(Barnacle, "Barnacle");
			Hopper = EnsureActiveClone(Hopper, "Hopper");
			Drone = EnsureActiveClone(Drone, "Drone");
			BarnacleHarpoon = EnsureActiveClone(BarnacleHarpoon, "BarnacleHarpoon");
			HopperExplosive = EnsureActiveClone(HopperExplosive, "HopperExplosive");
			DumpComponents("Bloodbug", Bloodbug);
			DumpComponents("Barnacle", Barnacle);
			DumpComponents("Hopper", Hopper);
			DumpComponents("Drone", Drone);
			DumpComponents("BarnacleHarpoon", BarnacleHarpoon);
			DumpComponents("HopperExplosive", HopperExplosive);
			_bloodbugAsset = BuildAsset(Bloodbug);
			_barnacleAsset = BuildAsset(Barnacle);
			_hopperAsset = BuildAsset(Hopper);
			_droneAsset = BuildAsset(Drone);
			_barnacleHarpoonAsset = BuildAsset(BarnacleHarpoon);
			_hopperExplosiveAsset = BuildAsset(HopperExplosive);
			List<SpawnTableAsset> list = new List<SpawnTableAsset>(4);
			if (_bloodbugAsset != null)
			{
				list.Add(_bloodbugAsset);
			}
			if (_barnacleAsset != null)
			{
				list.Add(_barnacleAsset);
			}
			if (_hopperAsset != null)
			{
				list.Add(_hopperAsset);
			}
			if (_droneAsset != null)
			{
				list.Add(_droneAsset);
			}
			CachedAssets = list.ToArray();
			List<SpawnTableAsset> list2 = new List<SpawnTableAsset>(4);
			SpawnTableAsset[] cachedAssets = CachedAssets;
			foreach (SpawnTableAsset val3 in cachedAssets)
			{
				if (val3 != _bloodbugAsset)
				{
					list2.Add(val3);
				}
			}
			_groundOnlyAssets = list2.ToArray();
		}

		private static SpawnTableAsset BuildAsset(GameObject prefab)
		{
			//IL_000b: 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_0026: Unknown result type (might be due to invalid IL or missing references)
			//IL_0031: Unknown result type (might be due to invalid IL or missing references)
			//IL_0043: 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_0049: Unknown result type (might be due to invalid IL or missing references)
			//IL_0054: Unknown result type (might be due to invalid IL or missing references)
			//IL_0064: Expected O, but got Unknown
			//IL_0065: Expected O, but got Unknown
			if ((Object)(object)prefab == (Object)null)
			{
				return null;
			}
			return new SpawnTableAsset
			{
				name = "cici_infestation_" + ((Object)prefab).name,
				tags = new List<string>(),
				prefabs = new List<GameObject> { prefab },
				spawnSettings = new SpawnSettings
				{
					spawnChance = 1f,
					chanceMultiplier = 1f
				}
			};
		}

		private static GameObject EnsureActiveClone(GameObject source, string label)
		{
			//IL_0028: Unknown result type (might be due to invalid IL or missing references)
			//IL_0032: Expected O, but got Unknown
			if ((Object)(object)source == (Object)null)
			{
				return null;
			}
			if (source.activeSelf)
			{
				return source;
			}
			try
			{
				if ((Object)(object)_wrapperContainer == (Object)null)
				{
					_wrapperContainer = new GameObject("CiCi_InfestationWrappers");
					_wrapperContainer.SetActive(false);
					((Object)_wrapperContainer).hideFlags = (HideFlags)61;
					Object.DontDestroyOnLoad((Object)(object)_wrapperContainer);
				}
				GameObject val = Object.Instantiate<GameObject>(source, _wrapperContainer.transform);
				val.SetActive(true);
				((Object)val).name = "Infestation_" + label + "_ActiveWrapper";
				return val;
			}
			catch (Exception ex)
			{
				ManualLogSource log = Plugin.Log;
				if (log != null)
				{
					log.LogWarning((object)("[Infestation] EnsureActiveClone failed for " + label + ": " + ex.Message));
				}
				return source;
			}
		}

		private static void DumpComponents(string label, GameObject go)
		{
		}

		public static SpawnTableAsset PickRandom(bool allowFlier = true)
		{
			SpawnTableAsset[] array = (allowFlier ? CachedAssets : _groundOnlyAssets);
			if (array == null || array.Length == 0)
			{
				return null;
			}
			return MaybeUpgradeVariant(array[Random.Range(0, array.Length)]);
		}

		private static SpawnTableAsset MaybeUpgradeVariant(SpawnTableAsset asset)
		{
			if (asset == _barnacleAsset && _barnacleHarpoonAsset != null && Random.value < 0.1f)
			{
				return _barnacleHarpoonAsset;
			}
			if (asset == _hopperAsset && _hopperExplosiveAsset != null && Random.value < 0.1f)
			{
				return _hopperExplosiveAsset;
			}
			return asset;
		}

		private static GameObject FindFirstDenizenByName<T>(Func<string, bool> nameMatches, Func<GameObject, bool> extraReject = null, bool preferClean = true) where T : Component
		{
			GameObject val = null;
			GameObject val2 = null;
			T[] array = Resources.FindObjectsOfTypeAll<T>();
			foreach (T val3 in array)
			{
				object obj = val3;
				if ((Object)(object)((obj != null) ? ((Component)obj).gameObject : null) == (Object)null)
				{
					continue;
				}
				GameObject gameObject = ((Component)val3).gameObject;
				string arg = ((Object)gameObject).name?.ToLower() ?? "";
				if (nameMatches(arg) && (extraReject == null || !extraReject(gameObject)))
				{
					if (!((Object)gameObject).name.Contains("."))
					{
						val = gameObject;
						break;
					}
					if ((Object)(object)val2 == (Object)null)
					{
						val2 = gameObject;
					}
				}
			}
			return val ?? val2;
		}
	}
	public static class InfestationTableFilter
	{
		public struct TableKind
		{
			public bool IsEnemy;

			public bool HasFlier;
		}

		private static readonly Dictionary<SpawnTable, TableKind> _cache = new Dictionary<SpawnTable, TableKind>();

		public static TableKind Classify(SpawnTable table)
		{
			if ((Object)(object)table == (Object)null)
			{
				return default(TableKind);
			}
			if (_cache.TryGetValue(table, out var value))
			{
				return value;
			}
			TableKind tableKind = default(TableKind);
			string text = ((Object)table).name?.ToLower() ?? "";
			if (text.Contains("supplycrate") || text.Contains("supply_crate") || tex