Decompiled source of CiCisPioneersShotgun v0.4.3
plugins\ShotgunMod\ShotgunMod.dll
Decompiled a month ago
The result has been truncated due to the large size, download it to view full contents!
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