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(); } 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 ShellMeshByType = new Dictionary(); public static Sprite[] ShellEjectedFrames; public static Sprite ShellHeldSprite; public static Sprite ShellEjectedSprite; public static readonly Dictionary ShellHeldSpritesByType = new Dictionary(); public static readonly Dictionary ShellVendingSpritesByType = new Dictionary(); public static readonly Dictionary ShellEjectedFramesByType = new Dictionary(); 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 ShotgunShellTemplatesByType = new Dictionary(); public static readonly Dictionary ShellTypeVisuals = new Dictionary { ["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 _invertedMeshCache = new Dictionary(); private static readonly Dictionary _shellVendingTemplatesByType = new Dictionary(); private static readonly Dictionary _shellVendingPurchasesByType = new Dictionary(); private static GameObject _shellVendingSpawnContainer; private static readonly Dictionary ShellVendingWeights = new Dictionary { { "buckshot", 60 }, { "slug", 24 }, { "blank", 8 }, { "dragon", 7 }, { "reverse", 1 } }; private static readonly Dictionary ShellVendingPrices = new Dictionary { { "buckshot", 2 }, { "slug", 4 }, { "blank", 6 }, { "dragon", 7 }, { "reverse", 15 } }; public static readonly Dictionary ShellVendingStocksByType = new Dictionary { { "buckshot", 6 }, { "slug", 4 }, { "blank", 2 }, { "dragon", 2 }, { "reverse", 1 } }; public static readonly Dictionary> ShellVendingSlotStocks = new Dictionary>(); 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 ""; } 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 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 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(); val.AddComponent(); val.AddComponent(); 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.\nHold R to change ammo type.", "Some climbs demand a second opinion.", 1, 0f, 0f, PioneersEdgeIcon, (Func>)delegate { try { EnsureShotgunTemplate(); } catch { } try { EnsureShotgunHandItemTemplate(); } catch { } try { EnsureShotgunShellTemplate(); } catch { } try { EnsureTypedShellTemplates(); } catch { } List list = new List(); if ((Object)(object)ShotgunTemplate != (Object)null) { list.Add(ShotgunTemplate); } return list; }, (Func>)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(Performance note: heavy spawn load may cause stutter on lower-end systems.)", "Where am I...? How long has it been...?", 1, 0.5f, 0f, InfestationIcon, (Func>)null, (Func>)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 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(ShotgunPrefab); val.SetActive(false); ((Object)val).name = "cici_shotgun"; ((Object)val).hideFlags = (HideFlags)61; Object.DontDestroyOnLoad((Object)(object)val); if (val.GetComponentsInChildren(true).Length == 0 && (Object)(object)ShotgunMeshPrefab != (Object)null) { GameObject obj = Object.Instantiate(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()); 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 { "weapon", "shotgun" }, prefabName = "Item_Shotgun", upDirection = Vector3.up, pocketable = true, pouchable = true, worth = 56, inventoryScale = 1f, itemWeight = 1f, data = new List(), dataModules = new List(), dataModuleSaves = new List(), pickupSounds = new List(), executionModules = new List(), 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(); ((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(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(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(true); for (int i = 0; i < componentsInChildren.Length; i++) { ((Component)componentsInChildren[i]).gameObject.layer = 10; } try { val.tag = "Pickupable"; } catch { } ObjectTagger val2 = val.GetComponent(); if ((Object)(object)val2 == (Object)null) { val2 = val.AddComponent(); } if (val2.tags == null) { val2.tags = new List(); } if (!val2.tags.Contains("Pickupable")) { val2.tags.Add("Pickupable"); } if (!val2.tags.Contains("Item")) { val2.tags.Add("Item"); } if ((Object)(object)val.GetComponentInChildren() == (Object)null) { Renderer[] componentsInChildren2 = val.GetComponentsInChildren(); 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(); obj2.center = val.transform.InverseTransformPoint(((Bounds)(ref bounds)).center); obj2.size = ((Bounds)(ref bounds)).size; } else { val.AddComponent().size = new Vector3(0.05f, 0.1f, 0.05f); } } Rigidbody val3 = val.GetComponent(); if ((Object)(object)val3 == (Object)null) { val3 = val.AddComponent(); } val3.mass = 0.05f; if (val.GetComponent() == null) { val.AddComponent(); } Item_Object val4 = val.GetComponent(); if ((Object)(object)val4 == (Object)null) { val4 = val.AddComponent(); } ShotgunShellTemplate = val4; ObjectTagger val5 = val.GetComponent(); if ((Object)(object)val5 == (Object)null) { val5 = val.AddComponent(); } val5.AddTag("RecycleFit"); EnsureShellHandItemTemplate(); Item val6 = null; try { GameObject assetGameObject = CL_AssetManager.GetAssetGameObject("Item_Flaregun_Ammo", ""); val6 = ((assetGameObject == null) ? null : assetGameObject.GetComponent()?.itemData); } catch { } val4.itemData = new Item { itemName = "Shotgun Shell", itemTag = "shotgun_shell", itemTags = new List { "ammo", "shotgun_shell" }, prefabName = "Item_ShotgunShell", upDirection = Vector3.up, pocketable = true, pouchable = true, worth = 2, inventoryScale = 1f, itemWeight = 0.05f, data = new List(), dataModules = new List(), dataModuleSaves = new List(), pickupSounds = (val6?.pickupSounds ?? new List()), executionModules = new List(), 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(((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(true); MeshRenderer componentInChildren2 = shellMeshForType.GetComponentInChildren(true); if ((Object)(object)((componentInChildren != null) ? componentInChildren.sharedMesh : null) != (Object)null) { MeshFilter[] componentsInChildren = val.GetComponentsInChildren(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(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(); if ((Object)(object)val4 == (Object)null) { val4 = val.AddComponent(); } 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) : ""); 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(((Component)value2).gameObject, _shellVendingSpawnContainer.transform); obj.SetActive(true); ((Object)obj).name = "ShotgunShell_VendingSpawnTemplate_" + shellType; Item_Object component = obj.GetComponent(); 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(), 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(((Component)ShotgunTemplate).gameObject, _shotgunVendingSpawnContainer.transform); obj.SetActive(true); ((Object)obj).name = "Shotgun_VendingSpawnTemplate"; Item_Object component = obj.GetComponent(); 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(), price = 28, purchaseSprite = ShotgunVendingSprite, requiredItemTag = "", ignoreUnlocked = true }; return _shotgunVendingPurchase; } public static string PickWeightedVendingShellType() { int num = 0; foreach (KeyValuePair shellVendingWeight in ShellVendingWeights) { num += shellVendingWeight.Value; } if (num <= 0) { return null; } int num2 = Random.Range(0, num); int num3 = 0; foreach (KeyValuePair 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() : 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(((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(); 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(true); foreach (SpriteRenderer val3 in componentsInChildren) { if ((Object)(object)val3 == (Object)null || (Object)(object)((Component)val3).GetComponent() != (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 : "") + ")")); } } 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 { "ammo", "shotgun_shell" }, prefabName = "Item_ShotgunShell", upDirection = Vector3.up, pocketable = true, pouchable = true, worth = 2, inventoryScale = 1f, itemWeight = 0.05f, data = new List(), dataModules = new List(), dataModuleSaves = new List(), pickupSounds = new List(), executionModules = new List() }; 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() : 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(((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(); 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(); ((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(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(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(true); SpriteRenderer val10 = null; List list = new List(); 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(true); foreach (Transform val in componentsInChildren) { if ((Object)(object)val == (Object)null || ((Object)val).name != "Effect_Eject") { continue; } ParticleSystem component = ((Component)val).GetComponent(); 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(); 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(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(); if (array == null || array.Length == 0) { Log.LogError((object)"No GameObject assets found in bundle"); return; } ShotgunPrefab = val.LoadAsset("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() != (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 : "") + "'")); } OutlineMaterial = TryBuildGameOutlineMaterial(); Sprite[] array3 = val.LoadAllAssets(); 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(); 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(); 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 : "") + " held=" + (((Object)(object)ShellHeldSprite != (Object)null) ? ((Object)ShellHeldSprite).name : "") + " ejected=" + (((Object)(object)ShellEjectedSprite != (Object)null) ? ((Object)ShellEjectedSprite).name : ""))); } 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 { "weapon", "shotgun" }, prefabName = "Item_Shotgun", upDirection = Vector3.up, pocketable = true, pouchable = true, worth = 56, inventoryScale = 1f, itemWeight = 1f, data = new List(), dataModules = new List(), dataModuleSaves = new List(), pickupSounds = new List(), executionModules = new List() }; 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() : 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 = "Trinket: " + __instance.title + ". " + __instance.description + "\n" + __instance.flavorText + ""; 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(true); foreach (SpriteRenderer val2 in componentsInChildren) { if ((Object)(object)val2 == (Object)null || (Object)(object)((Component)val2).GetComponent() != (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(); try { SpawnTable[] array = Resources.FindObjectsOfTypeAll(); 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() != (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() != (Object)null && (Object)(object)prefab.GetComponent() == (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() != (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() != (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() != (Object)null && (!flag || (Object)(object)BarnacleHarpoon == (Object)null)) { BarnacleHarpoon = prefab; } if (((Object)(object)HopperExplosive == (Object)null || ((Object)HopperExplosive).name.Contains(".")) && (Object)(object)prefab.GetComponent() != (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((Func)((string n) => n.Contains("bloodbug")), (Func)null, preferClean: true); } if ((Object)(object)Barnacle == (Object)null) { Barnacle = FindFirstDenizenByName((Func)((string n) => n.Contains("barnacle") && !n.Contains("screecher") && !n.Contains("harpoon") && !n.Contains("holiday") && !n.Contains("christmas")), (Func)((GameObject go) => (Object)(object)go.GetComponent() != (Object)null), preferClean: true); } if ((Object)(object)Hopper == (Object)null) { Hopper = FindFirstDenizenByName((Func)((string n) => n.Contains("hopper") && !n.Contains("breeder") && !n.Contains("spawner") && !n.Contains("explosive") && !n.Contains("holiday") && !n.Contains("christmas")), (Func)null, preferClean: true); } if ((Object)(object)Drone == (Object)null) { Drone = FindFirstDenizenByName((Func)((string n) => n.Contains("drone") && !n.Contains("buddy")), (Func)null, preferClean: true); } if ((Object)(object)BarnacleHarpoon == (Object)null) { BarnacleHarpoon = FindFirstDenizenByName((Func)((string n) => true), (Func)null, preferClean: true); } if ((Object)(object)BarnacleHarpoon == (Object)null) { BarnacleHarpoon = FindFirstDenizenByName((Func)((string n) => n.Contains("harpoon")), (Func)null, preferClean: true); } if ((Object)(object)BarnacleHarpoon == (Object)null) { GameObject[] array2 = Resources.FindObjectsOfTypeAll(); 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((Func)((string n) => n.Contains("hopper") && n.Contains("explosive") && !n.Contains("breeder") && !n.Contains("spawner")), (Func)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 list = new List(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 list2 = new List(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(), prefabs = new List { 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(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(Func nameMatches, Func extraReject = null, bool preferClean = true) where T : Component { GameObject val = null; GameObject val2 = null; T[] array = Resources.FindObjectsOfTypeAll(); 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 _cache = new Dictionary(); 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") || text.Contains("crate") || text.Contains("loot") || text.Contains("drop") || text.Contains("treasure") || text.Contains("reward") || text.Contains("vending") || text.Contains("perk")) { _cache[table] = tableKind; return tableKind; } bool flag = false; bool flag2 = false; if (table.spawnList != null) { foreach (SpawnTableAsset spawn in table.spawnList) { if (spawn?.prefabs == null) { continue; } foreach (GameObject prefab in spawn.prefabs) { if ((Object)(object)prefab == (Object)null) { continue; } if ((Object)(object)prefab.GetComponent() != (Object)null) { tableKind.IsEnemy = true; flag = true; if ((Object)(object)prefab.GetComponent() == (Object)null) { flag2 = true; } } if ((Object)(object)prefab.GetComponent() != (Object)null) { tableKind.HasFlier = true; } } } } if (flag && !flag2) { tableKind.IsEnemy = false; } _cache[table] = tableKind; return tableKind; } public static bool IsEnemyTable(SpawnTable table) { return Classify(table).IsEnemy; } public static bool IsFlierTable(SpawnTable table) { return Classify(table).HasFlier; } } [HarmonyPatch(typeof(M_Gamemode), "StartFreshGamemode")] public static class InfestationCacheInvalidateOnStartPatch { [HarmonyPostfix] public static void Postfix() { Plugin.InvalidateInfestationCache(); } } [HarmonyPatch(typeof(UI_TrinketPicker), "SelectTrinket")] public static class InfestationCacheInvalidateOnSelectPatch { [HarmonyPostfix] public static void Postfix() { Plugin.InvalidateInfestationCache(); } } [HarmonyPatch(typeof(SpawnTable), "GetRandomSpawnObject")] public static class InfestationSpawnTablePatch { private const float SubstitutionChance = 0.8f; [HarmonyPostfix] public static void Postfix(SpawnTable __instance, ref SpawnTableAsset __result) { if (!Plugin.InfestationActive) { return; } InfestationPrefabs.TryResolveOnce(); InfestationTableFilter.TableKind tableKind = InfestationTableFilter.Classify(__instance); if (!tableKind.IsEnemy || Random.value > 0.8f) { return; } SpawnTableAsset val = InfestationPrefabs.PickRandom(tableKind.HasFlier); if (val == null || val.prefabs == null || val.prefabs.Count == 0) { return; } bool flag = false; for (int i = 0; i < val.prefabs.Count; i++) { if ((Object)(object)val.prefabs[i] != (Object)null) { flag = true; break; } } if (flag) { __result = val; } } } public class InfestationSpawnedBarnacleMarker : MonoBehaviour { } [HarmonyPatch(typeof(DEN_Barnacle), "Start")] public static class InfestationBarnacleStartTagPatch { [HarmonyPostfix] public static void Postfix(DEN_Barnacle __instance) { if (!((Object)(object)__instance == (Object)null) && Plugin.InfestationActive && !((Object)(object)((Component)__instance).gameObject.GetComponent() != (Object)null)) { ((Component)__instance).gameObject.AddComponent(); } } } [HarmonyPatch(typeof(DEN_Barnacle), "Kill")] public static class InfestationBarnacleCorpseDespawnPatch { private const float CorpseDespawnDelaySec = 4f; [HarmonyPostfix] public static void Postfix(DEN_Barnacle __instance) { if (!((Object)(object)__instance == (Object)null) && !((Object)(object)((Component)__instance).GetComponent() == (Object)null)) { Object.Destroy((Object)(object)((Component)__instance).gameObject, 4f); } } } [HarmonyPatch(typeof(UT_SPT_Spawner), "Spawn")] public static class InfestationSPTSpawnerCountPatch { [HarmonyPrefix] public static void Prefix(UT_SPT_Spawner __instance, out (int, int) __state) { __state = InfestationCountHelper.Boost((MonoBehaviour)(object)__instance); } [HarmonyPostfix] public static void Postfix(UT_SPT_Spawner __instance, (int, int) __state) { InfestationCountHelper.Restore((MonoBehaviour)(object)__instance, __state); } } [HarmonyPatch(typeof(UT_RadiusSpawner), "Spawn")] public static class InfestationRadiusSpawnerCountPatch { [HarmonyPrefix] public static void Prefix(UT_RadiusSpawner __instance, out (int, int) __state) { __state = InfestationCountHelper.Boost((MonoBehaviour)(object)__instance); } [HarmonyPostfix] public static void Postfix(UT_RadiusSpawner __instance, (int, int) __state) { InfestationCountHelper.Restore((MonoBehaviour)(object)__instance, __state); } } public static class InfestationCountHelper { private static readonly Dictionary _fieldsByType = new Dictionary(); private static readonly Dictionary _tableFieldByType = new Dictionary(); private static (FieldInfo, FieldInfo) GetFields(Type t) { if (_fieldsByType.TryGetValue(t, out (FieldInfo, FieldInfo) value)) { return value; } FieldInfo item = AccessTools.Field(t, "minSpawnAmount"); FieldInfo item2 = AccessTools.Field(t, "maxSpawnAmount"); _fieldsByType[t] = (item, item2); return (item, item2); } private static SpawnTable GetSpawnTable(MonoBehaviour spawner) { Type type = ((object)spawner).GetType(); if (!_tableFieldByType.TryGetValue(type, out var value)) { value = AccessTools.Field(type, "spawnTable"); _tableFieldByType[type] = value; } object? obj = value?.GetValue(spawner); return (SpawnTable)((obj is SpawnTable) ? obj : null); } public static (int, int) Boost(MonoBehaviour spawner) { if (!Plugin.InfestationActive) { return (0, 0); } if (!InfestationTableFilter.IsEnemyTable(GetSpawnTable(spawner))) { return (0, 0); } var (fieldInfo, fieldInfo2) = GetFields(((object)spawner).GetType()); if (fieldInfo == null || fieldInfo2 == null) { return (0, 0); } try { int num = (int)fieldInfo.GetValue(spawner); int num2 = (int)fieldInfo2.GetValue(spawner); fieldInfo.SetValue(spawner, Mathf.Min(num + 2, 10)); fieldInfo2.SetValue(spawner, Mathf.Min(num2 + 4, 10)); return (num, num2); } catch { return (0, 0); } } public static void Restore(MonoBehaviour spawner, (int, int) state) { if (state.Item1 == 0 && state.Item2 == 0) { return; } var (fieldInfo, fieldInfo2) = GetFields(((object)spawner).GetType()); if (fieldInfo == null || fieldInfo2 == null) { return; } try { fieldInfo.SetValue(spawner, state.Item1); fieldInfo2.SetValue(spawner, state.Item2); } catch { } } } [HarmonyPatch(typeof(Item_Object), "Start")] public static class CiciShotgunItemObjectStartPatch { private static readonly HashSet FlarePrefabs = new HashSet { "Item_Flaregun", "Item_Flaregun_Ammo" }; private static readonly HashSet PitonRebarPrefabs = new HashSet { "Item_Piton", "Item_Rebar" }; private static readonly HashSet HandScannerPrefabs = new HashSet { "Item_HandScanner" }; private static readonly string[] EverydayShells = new string[4] { "buckshot", "slug", "dragon", "blank" }; public const float PitonRebarReplaceChance = 0.25f; public const float HandScannerToShotgunChance = 0.1f; internal static readonly string[] EverydayShellsInternal = EverydayShells; [HarmonyPostfix] public static void Postfix(Item_Object __instance) { //IL_00d2: 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_00df: Unknown result type (might be due to invalid IL or missing references) //IL_00e4: Unknown result type (might be due to invalid IL or missing references) //IL_00fa: Unknown result type (might be due to invalid IL or missing references) //IL_00fc: 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_0175: Unknown result type (might be due to invalid IL or missing references) //IL_017d: Unknown result type (might be due to invalid IL or missing references) //IL_0182: Unknown result type (might be due to invalid IL or missing references) //IL_0198: Unknown result type (might be due to invalid IL or missing references) //IL_019a: Unknown result type (might be due to invalid IL or missing references) if (__instance?.itemData == null) { return; } try { ShotgunModHandler.OnItemObjectStartedForHalo(__instance); } catch (Exception ex) { ManualLogSource log = Plugin.Log; if (log != null) { log.LogWarning((object)("[Halo] OnItemObjectStartedForHalo failed: " + ex.Message)); } } string prefabName = __instance.itemData.prefabName; if (string.IsNullOrEmpty(prefabName)) { return; } if (HandScannerPrefabs.Contains(prefabName)) { if (Random.value < 0.1f) { TryReplaceWithLoadedShotgun(__instance); } return; } bool flag = FlarePrefabs.Contains(prefabName); bool flag2 = !flag && PitonRebarPrefabs.Contains(prefabName); if ((!flag && !flag2) || !Plugin.IsShotgunHeldOrInBag()) { return; } if (flag) { try { Item_Object val = Plugin.EnsureShellVendingSpawnTemplateForType(EverydayShells[Random.Range(0, EverydayShells.Length)]); if (!((Object)(object)val == (Object)null)) { Vector3 position = ((Component)__instance).transform.position; Quaternion rotation = ((Component)__instance).transform.rotation; Transform parent = ((Component)__instance).transform.parent; Object.Instantiate(((Component)val).gameObject, position, rotation, parent).SetActive(true); Object.Destroy((Object)(object)((Component)__instance).gameObject); } return; } catch (Exception ex2) { ManualLogSource log2 = Plugin.Log; if (log2 != null) { log2.LogWarning((object)("[FlareReplace] failed for " + prefabName + ": " + ex2.Message)); } return; } } if (Random.value >= 0.25f) { return; } try { Item_Object val2 = Plugin.EnsureShellVendingSpawnTemplateForType(PickReplacementShellType()); if (!((Object)(object)val2 == (Object)null)) { Vector3 position2 = ((Component)__instance).transform.position; Quaternion rotation2 = ((Component)__instance).transform.rotation; Transform parent2 = ((Component)__instance).transform.parent; Object.Instantiate(((Component)val2).gameObject, position2, rotation2, parent2).SetActive(true); Object.Destroy((Object)(object)((Component)__instance).gameObject); } } catch (Exception ex3) { ManualLogSource log3 = Plugin.Log; if (log3 != null) { log3.LogWarning((object)("[PitonReplace] failed for " + prefabName + ": " + ex3.Message)); } } } private static void TryReplaceWithLoadedShotgun(Item_Object source) { //IL_001f: Unknown result type (might be due to invalid IL or missing references) //IL_0024: Unknown result type (might be due to invalid IL or missing references) //IL_002b: Unknown result type (might be due to invalid IL or missing references) //IL_0030: Unknown result type (might be due to invalid IL or missing references) //IL_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) try { Plugin.EnsureShotgunVendingSpawnTemplate(); Item_Object shotgunVendingSpawnTemplate = Plugin.ShotgunVendingSpawnTemplate; if (!((Object)(object)shotgunVendingSpawnTemplate == (Object)null)) { Vector3 position = ((Component)source).transform.position; Quaternion rotation = ((Component)source).transform.rotation; Transform parent = ((Component)source).transform.parent; GameObject obj = Object.Instantiate(((Component)shotgunVendingSpawnTemplate).gameObject, position, rotation, parent); obj.SetActive(true); Item_Object component = obj.GetComponent(); if ((Object)(object)component != (Object)null && component.itemData != null) { component.itemData = component.itemData.GetClone((Item)null); string type = EverydayShells[Random.Range(0, EverydayShells.Length)]; string type2 = EverydayShells[Random.Range(0, EverydayShells.Length)]; Plugin.SetBarrelType(component.itemData, 0, type); Plugin.SetBarrelType(component.itemData, 1, type2); component.itemData.SetFirstDataStringsofType("ammo", "2"); } Object.Destroy((Object)(object)((Component)source).gameObject); } } catch (Exception ex) { ManualLogSource log = Plugin.Log; if (log != null) { log.LogWarning((object)("[HandScannerReplace] failed: " + ex.Message)); } } } private static string PickReplacementShellType() { float value = Random.value; if (value < 0.0001f) { return "rebar"; } if (value < 0.0011f) { return "reverse"; } if (value < 0.0111f) { return "slug"; } if (value < 0.0211f) { return "dragon"; } if (value < 0.0311f) { return "blank"; } return "buckshot"; } internal static string PickReplacementShellTypeInternal() { return PickReplacementShellType(); } } [HarmonyPatch(typeof(PerkModule_ItemAdder), "AddModule")] public static class CiciPerkItemAdderShellReplacePatch { private static readonly HashSet ReplaceablePrefabs = new HashSet { "Item_Flaregun", "Item_Flaregun_Ammo", "Item_Rebar" }; private static readonly FieldInfo _perkField = AccessTools.Field(typeof(PerkModule), "perk"); private static readonly MethodInfo _loadItemsIntoBag = AccessTools.Method(typeof(Inventory), "LoadItemsIntoBag", (Type[])null, (Type[])null); private static readonly MethodInfo _removeModule = AccessTools.Method(typeof(Perk), "RemoveModule", (Type[])null, (Type[])null); [HarmonyPrefix] public static bool Prefix(PerkModule_ItemAdder __instance, int amount, bool firstTime) { //IL_0134: Unknown result type (might be due to invalid IL or missing references) //IL_0139: Unknown result type (might be due to invalid IL or missing references) //IL_0143: Unknown result type (might be due to invalid IL or missing references) //IL_0148: Unknown result type (might be due to invalid IL or missing references) //IL_014d: Unknown result type (might be due to invalid IL or missing references) //IL_0156: Unknown result type (might be due to invalid IL or missing references) //IL_015b: Unknown result type (might be due to invalid IL or missing references) //IL_0160: Unknown result type (might be due to invalid IL or missing references) if (!firstTime) { return true; } if (__instance == null || __instance.itemsToAdd == null) { return true; } if (!Plugin.IsShotgunHeldOrInBag()) { return true; } bool flag = false; foreach (Item_Object item in __instance.itemsToAdd) { if (!((Object)(object)item == (Object)null) && item.itemData != null && ReplaceablePrefabs.Contains(item.itemData.prefabName)) { flag = true; break; } } if (!flag) { return true; } try { List list = new List(); foreach (Item_Object item2 in __instance.itemsToAdd) { if ((Object)(object)item2 == (Object)null || item2.itemData == null) { continue; } Item_Object val = item2; string prefabName = item2.itemData.prefabName; if (ReplaceablePrefabs.Contains(prefabName)) { Item_Object val2 = Plugin.EnsureShellVendingSpawnTemplateForType((prefabName == "Item_Rebar") ? CiciShotgunItemObjectStartPatch.PickReplacementShellTypeInternal() : CiciShotgunItemObjectStartPatch.EverydayShellsInternal[Random.Range(0, CiciShotgunItemObjectStartPatch.EverydayShellsInternal.Length)]); if ((Object)(object)val2 != (Object)null) { val = val2; } } Item clone = val.itemData.GetClone((Item)null); clone.bagPosition = new Vector3(0f, 0f, 1f) + Random.insideUnitSphere * 0.01f; clone.bagRotation = Quaternion.LookRotation(clone.upDirection); list.Add(clone); } _loadItemsIntoBag?.Invoke(Inventory.instance, new object[1] { list }); try { object? obj = _perkField?.GetValue(__instance); Perk val3 = (Perk)((obj is Perk) ? obj : null); if ((Object)(object)val3 != (Object)null) { _removeModule?.Invoke(val3, new object[1] { __instance }); } } catch { } return false; } catch (Exception ex) { ManualLogSource log = Plugin.Log; if (log != null) { log.LogWarning((object)("[PerkShellReplace] failed: " + ex.Message + " — falling back to vanilla")); } return true; } } } [HarmonyPatch(typeof(UT_DamageTrigger), "FixedUpdate")] public static class CiciSilenceUTDamageTriggerNREPatch { private static int _swallowed; private static float _nextReportTime; [HarmonyFinalizer] public static Exception Finalizer(Exception __exception) { if (__exception == null) { return null; } if (!(__exception is NullReferenceException) && !(__exception is MissingReferenceException)) { return __exception; } _swallowed++; if (Time.unscaledTime >= _nextReportTime) { _nextReportTime = Time.unscaledTime + 60f; ManualLogSource log = Plugin.Log; if (log != null) { log.LogInfo((object)$"[UTTriggerNREGuard] swallowed {_swallowed} NRE(s) from UT_DamageTrigger.FixedUpdate in the last minute"); } _swallowed = 0; } return null; } } [HarmonyPatch(typeof(CL_AssetManager), "GetFullCombinedAssetDatabase")] public static class ShotgunSpawnItemDatabasePatch { [HarmonyPostfix] public static void Postfix(WKAssetDatabase __result) { if ((Object)(object)__result == (Object)null) { return; } if (__result.itemPrefabs == null) { __result.itemPrefabs = new List(); } try { Plugin.EnsureShotgunTemplate(); } catch { } try { Plugin.EnsureShotgunShellTemplate(); } catch { } try { Plugin.EnsureTypedShellTemplates(); } catch { } List itemPrefabs = __result.itemPrefabs; Item_Object shotgunTemplate = Plugin.ShotgunTemplate; AddIfMissing(itemPrefabs, (shotgunTemplate != null) ? ((Component)shotgunTemplate).gameObject : null); foreach (KeyValuePair item in Plugin.ShotgunShellTemplatesByType) { List itemPrefabs2 = __result.itemPrefabs; Item_Object value = item.Value; AddIfMissing(itemPrefabs2, (value != null) ? ((Component)value).gameObject : null); } } private static void AddIfMissing(List list, GameObject go) { if ((Object)(object)go == (Object)null) { return; } for (int i = 0; i < list.Count; i++) { if ((Object)(object)list[i] == (Object)(object)go) { return; } } list.Add(go); } } [HarmonyPatch(typeof(CL_AssetManager), "GetAssetGameObject")] public static class ShotgunShellAssetLookupPatch { [HarmonyPostfix] public static void Postfix(string name, ref GameObject __result) { if (!((Object)(object)__result != (Object)null) && !(name != "Item_ShotgunShell")) { try { Plugin.EnsureShotgunShellTemplate(); } catch { } if ((Object)(object)Plugin.ShotgunShellTemplate != (Object)null) { __result = ((Component)Plugin.ShotgunShellTemplate).gameObject; } } } } [HarmonyPatch(typeof(ENV_VendingMachine), "GenerateOptions")] public static class CiciShotgunShellVendingInjectPatch { public const float ShellVendingChanceBase = 0.05f; public const float ShellSlotChanceWithGun = 0.3f; [HarmonyPostfix] public static void Postfix(ENV_VendingMachine __instance) { if ((Object)(object)__instance == (Object)null || __instance.buttons == null || __instance.buttons.Length == 0) { return; } bool num = Plugin.IsShotgunHeldOrInBag(); int num2 = 0; if (num) { for (int i = 0; i < __instance.buttons.Length; i++) { string text = __instance.buttons[i].purchase?.name; if ((text == null || !text.StartsWith("cici_")) && !(Random.value > 0.3f) && TryInjectShellAt(__instance, i)) { num2++; } } } else if (Random.value <= 0.05f) { int slot = Random.Range(0, __instance.buttons.Length); if (TryInjectShellAt(__instance, slot)) { num2++; } } } private static bool TryInjectShellAt(ENV_VendingMachine machine, int slot) { string text = Plugin.PickWeightedVendingShellType(); if (string.IsNullOrEmpty(text)) { return false; } Purchase orBuildShellVendingPurchaseForType = Plugin.GetOrBuildShellVendingPurchaseForType(text); if (orBuildShellVendingPurchaseForType == null) { return false; } machine.buttons[slot].purchase = orBuildShellVendingPurchaseForType; machine.buttons[slot].available = true; int shellVendingStockForType = Plugin.GetShellVendingStockForType(text); if (!Plugin.ShellVendingSlotStocks.TryGetValue(machine, out var value)) { value = new Dictionary(); Plugin.ShellVendingSlotStocks[machine] = value; } value[slot] = shellVendingStockForType; return true; } } [HarmonyPatch(typeof(ENV_VendingMachine), "GenerateOptions")] public static class CiciShotgunVendingInjectPatch { public const float ShotgunVendingChance = 1f / 33f; [HarmonyPostfix] public static void Postfix(ENV_VendingMachine __instance) { if (!((Object)(object)__instance == (Object)null) && __instance.buttons != null && __instance.buttons.Length != 0 && !(Random.value > 1f / 33f)) { Purchase orBuildShotgunVendingPurchase = Plugin.GetOrBuildShotgunVendingPurchase(); if (orBuildShotgunVendingPurchase != null) { int num = Random.Range(0, __instance.buttons.Length); __instance.buttons[num].purchase = orBuildShotgunVendingPurchase; __instance.buttons[num].available = true; } } } } [HarmonyPatch(typeof(ENV_VendingMachine), "Buy", new Type[] { typeof(int), typeof(bool), typeof(bool) })] public static class CiciShotgunShellMultiBuyPatch { private static readonly MethodInfo _updateButtons = AccessTools.Method(typeof(ENV_VendingMachine), "UpdateButtons", (Type[])null, (Type[])null); [HarmonyPostfix] public static void Postfix(ENV_VendingMachine __instance, int i, bool force, bool free) { if (__instance?.buttons == null || i < 0 || i >= __instance.buttons.Length) { return; } Purchase purchase = __instance.buttons[i].purchase; if (purchase == null || purchase.name == null || !purchase.name.StartsWith("cici_shotgun_shell_") || !Plugin.ShellVendingSlotStocks.TryGetValue(__instance, out var value) || !value.TryGetValue(i, out var value2)) { return; } value2 = (value[i] = value2 - 1); if (value2 <= 0) { return; } __instance.buttons[i].available = true; try { _updateButtons?.Invoke(__instance, null); } catch { } } } [HarmonyPatch(typeof(Item), "GetClone")] public static class ShotgunPreserveItemTagPatch { [HarmonyPostfix] public static void Postfix(Item __instance, Item __result) { if (__instance != null && __result != null) { __result.itemTag = __instance.itemTag; } } } [HarmonyPatch(typeof(Item), "CopyNonDataFromItemAsset")] public static class ShotgunSaveMigrationPatch { [HarmonyPrefix] public static void Prefix(Item __instance) { if (__instance == null) { return; } bool num = __instance.itemTag == "shotgun" || (__instance.itemTags != null && __instance.itemTags.Contains("shotgun")) || __instance.itemName == "Shotgun"; bool flag = __instance.itemTag == "shotgun_shell" || (__instance.itemTags != null && __instance.itemTags.Contains("shotgun_shell")) || __instance.itemName == "Shotgun Shell"; if (num) { if (__instance.itemTag != "shotgun") { __instance.itemTag = "shotgun"; } if (__instance.itemTags == null) { __instance.itemTags = new List(); } if (!__instance.itemTags.Contains("shotgun")) { __instance.itemTags.Add("shotgun"); } if (!__instance.itemTags.Contains("weapon")) { __instance.itemTags.Add("weapon"); } if (__instance.prefabName != "Item_Shotgun") { __instance.prefabName = "Item_Shotgun"; } } else if (flag) { if (__instance.itemTag != "shotgun_shell") { __instance.itemTag = "shotgun_shell"; } if (__instance.itemTags == null) { __instance.itemTags = new List(); } if (!__instance.itemTags.Contains("ammo")) { __instance.itemTags.Add("ammo"); } if (!__instance.itemTags.Contains("shotgun_shell")) { __instance.itemTags.Add("shotgun_shell"); } if (__instance.prefabName != "Item_ShotgunShell") { __instance.prefabName = "Item_ShotgunShell"; } } } [HarmonyPostfix] public static void Postfix(Item __instance) { if (__instance == null) { return; } bool num = __instance.itemTag == "shotgun" || (__instance.itemTags != null && __instance.itemTags.Contains("shotgun")) || __instance.itemName == "Shotgun"; bool flag = __instance.itemTag == "shotgun_shell" || (__instance.itemTags != null && __instance.itemTags.Contains("shotgun_shell")) || __instance.itemName == "Shotgun Shell"; if (num) { try { Plugin.EnsureShotgunTemplate(); } catch { } if ((Object)(object)Plugin.ShotgunTemplate != (Object)null) { __instance.itemAsset = Plugin.ShotgunTemplate; } } else { if (!flag) { return; } try { Plugin.EnsureShotgunShellTemplate(); } catch { } if ((Object)(object)Plugin.ShotgunShellTemplate != (Object)null) { __instance.itemAsset = Plugin.ShotgunShellTemplate; if ((Object)(object)Plugin.ShellHandItemTemplate != (Object)null) { __instance.handItemAsset = Plugin.ShellHandItemTemplate; } } } } } public static class ShotgunShellDropHelper { public const float DROP_CHANCE = 0.5f; public const float HAMMER_DROP_CHANCE = 0.05f; public static bool KilledByShotgun(DamageInfo info) { if (info == null) { return false; } if (info.tags == null) { return false; } if (!info.tags.Contains("Shotgun")) { return info.tags.Contains("buckshot"); } return true; } public static void TryDropShell(DamageInfo info) { if (KilledByShotgun(info) && !(Random.value > 0.5f)) { int num = RollShellCount(); for (int i = 0; i < num; i++) { GiveShellToPlayer(); } } } private static int RollShellCount() { float num = Random.value * 4f; if (num < 1f) { return 1; } if (num < 3f) { return 2; } return 3; } private static void GiveShellToPlayer() { try { Plugin.EnsureShotgunShellTemplate(); } catch { } if (!((Object)(object)Plugin.ShotgunShellTemplate == (Object)null) && !((Object)(object)Inventory.instance == (Object)null) && Plugin.ShotgunShellTemplate.itemData != null) { Item clone = Plugin.ShotgunShellTemplate.itemData.GetClone((Item)null); if (clone != null) { Inventory.instance.AddItemToInventoryCenter(clone); } } } public static bool KilledByHammer(DamageInfo info) { if (info?.tags == null) { return false; } return info.tags.Contains("hammer"); } public static void TryDropHammerKill(DamageInfo info) { if (KilledByHammer(info) && Plugin.IsShotgunHeldOrInBag() && !(Random.value >= 0.05f)) { GiveShellToPlayer(); } } public static void TryDropSpecificShell(DamageInfo info, string shellType, float chance) { if (!KilledByShotgun(info) || Random.value >= chance) { return; } try { Plugin.EnsureTypedShellTemplates(); } catch { } if (Plugin.ShotgunShellTemplatesByType.TryGetValue(shellType, out var value) && value?.itemData != null && !((Object)(object)Inventory.instance == (Object)null)) { Item clone = value.itemData.GetClone((Item)null); if (clone != null) { Inventory.instance.AddItemToInventoryCenter(clone); } } } } [HarmonyPatch(typeof(CL_AchievementManager), "SetAchievementValue")] public static class SilenceAchievementSpamPatch { [HarmonyPrefix] public static bool Prefix() { if ((Object)(object)CL_GameManager.gamemode != (Object)null && !CL_GameManager.AreAchievementsAllowed()) { return false; } return true; } } [HarmonyPatch(typeof(DEN_BasicDenizen), "Damage")] public static class BloodbugFlierShellDropPatch { [HarmonyPrefix] public static void Prefix(DEN_BasicDenizen __instance, out bool __state) { __state = (Object)(object)__instance != (Object)null && ((GameEntity)__instance).dead; } [HarmonyPostfix] public static void Postfix(DEN_BasicDenizen __instance, DamageInfo info, bool __state) { if ((Object)(object)__instance == (Object)null || __state || !((GameEntity)__instance).dead) { return; } string text = (((Object)((Component)__instance).gameObject).name ?? "").ToLower(); if (text.Contains("bloodbug")) { ShotgunShellDropHelper.TryDropShell(info); } else if (text.Contains("hopper")) { if (text.Contains("explosive")) { ShotgunShellDropHelper.TryDropSpecificShell(info, "dragon", 0.75f); } else { ShotgunShellDropHelper.TryDropSpecificShell(info, "buckshot", 0.05f); } } } } [HarmonyPatch(typeof(DEN_Barnacle), "Kill")] public static class BarnacleShellDropPatch { [HarmonyPostfix] public static void Postfix(DEN_Barnacle __instance, string type, DamageInfo damageInfo) { if (!((Object)(object)__instance == (Object)null)) { if ((Object)(object)((Component)__instance).gameObject.GetComponent() != (Object)null) { ShotgunShellDropHelper.TryDropSpecificShell(damageInfo, "slug", 0.75f); } else { ShotgunShellDropHelper.TryDropShell(damageInfo); } } } } internal static class TeethAggressionScaler { private struct Baseline { public float AggressionMult; public float WalkSpeed; public float ChargeSpeed; } private static readonly Dictionary _baselines = new Dictionary(); private static readonly FieldInfo _aggressionMultField = AccessTools.Field(typeof(DEN_Teeth), "aggressionMult"); private static readonly FieldInfo _walkSpeedField = AccessTools.Field(typeof(DEN_Teeth), "walkSpeed"); private static readonly FieldInfo _chargeSpeedField = AccessTools.Field(typeof(DEN_Teeth), "chargeSpeed"); public static void ApplyScale(DEN_Teeth t, float scale) { if (!((Object)(object)t == (Object)null)) { if (!_baselines.TryGetValue(t, out var value)) { Baseline baseline = default(Baseline); baseline.AggressionMult = TryGetFloat(_aggressionMultField, t, 1f); baseline.WalkSpeed = TryGetFloat(_walkSpeedField, t, 7f); baseline.ChargeSpeed = TryGetFloat(_chargeSpeedField, t, 43f); value = baseline; _baselines[t] = value; } TrySetFloat(_aggressionMultField, t, value.AggressionMult * scale); TrySetFloat(_walkSpeedField, t, value.WalkSpeed * scale); TrySetFloat(_chargeSpeedField, t, value.ChargeSpeed * scale); } } public static void ForgetBaseline(DEN_Teeth t) { if ((Object)(object)t != (Object)null) { _baselines.Remove(t); } } private static float TryGetFloat(FieldInfo f, object inst, float fallback) { if (f == null) { return fallback; } try { return (float)f.GetValue(inst); } catch { return fallback; } } private static void TrySetFloat(FieldInfo f, object inst, float value) { if (f == null) { return; } try { f.SetValue(inst, value); } catch { } } } internal static class TeethRetreat { [CompilerGenerated] private sealed class d__7 : IEnumerator, IEnumerator, IDisposable { private int <>1__state; private object <>2__current; public float seconds; public DEN_Teeth t; object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public d__7(int <>1__state) { this.<>1__state = <>1__state; } [DebuggerHidden] void IDisposable.Dispose() { <>1__state = -2; } private bool MoveNext() { //IL_001e: Unknown result type (might be due to invalid IL or missing references) //IL_0028: Expected O, but got Unknown switch (<>1__state) { default: return false; case 0: <>1__state = -1; <>2__current = (object)new WaitForSeconds(seconds); <>1__state = 1; return true; case 1: <>1__state = -1; if ((Object)(object)t == (Object)null) { return false; } TryDespawn(t); return false; } } bool IEnumerator.MoveNext() { //ILSpy generated this explicit interface implementation from .override directive in MoveNext return this.MoveNext(); } [DebuggerHidden] void IEnumerator.Reset() { throw new NotSupportedException(); } } private const float RetreatDespawnDelay = 2f; private static readonly FieldInfo _currentStateField = AccessTools.Field(typeof(AIGameEntity), "currentState"); private static readonly FieldInfo _aiStatesField = AccessTools.Field(typeof(AIGameEntity), "aiStates"); private static readonly FieldInfo _disableAIField = AccessTools.Field(typeof(DEN_Teeth), "disableAI"); private static readonly FieldInfo _lockAIField = AccessTools.Field(typeof(DEN_Teeth), "lockAI"); public static void TriggerRetreat(DEN_Teeth t) { if ((Object)(object)t == (Object)null) { return; } bool flag = false; if (_currentStateField != null && _aiStatesField != null && _aiStatesField.GetValue(t) is IList list) { for (int i = 0; i < list.Count; i++) { object obj = list[i]; if (obj != null && string.Equals(obj.GetType().GetField("name")?.GetValue(obj) as string, "retreat", StringComparison.OrdinalIgnoreCase)) { _currentStateField.SetValue(t, obj); flag = true; ManualLogSource log = Plugin.Log; if (log != null) { log.LogInfo((object)"[Teeth] retreat state forced — flee animation playing"); } break; } } } if (!flag) { ManualLogSource log2 = Plugin.Log; if (log2 != null) { log2.LogWarning((object)"[Teeth] no 'retreat' AIStateComponent found — despawning immediately"); } TryDespawn(t); return; } try { _disableAIField?.SetValue(t, true); } catch { } try { _lockAIField?.SetValue(t, true); } catch { } ScheduleDespawn(t, 2f); } private static void ScheduleDespawn(DEN_Teeth t, float seconds) { TeethHealthBarHandler teethHealthBarHandler = Object.FindObjectOfType(); if ((Object)(object)teethHealthBarHandler == (Object)null) { ManualLogSource log = Plugin.Log; if (log != null) { log.LogWarning((object)"[Teeth] no runner found — despawning immediately"); } TryDespawn(t); } else { ((MonoBehaviour)teethHealthBarHandler).StartCoroutine(DespawnAfter(t, seconds)); } } [IteratorStateMachine(typeof(d__7))] private static IEnumerator DespawnAfter(DEN_Teeth t, float seconds) { //yield-return decompiler failed: Unexpected instruction in Iterator.Dispose() return new d__7(0) { t = t, seconds = seconds }; } private static void TryDespawn(DEN_Teeth t) { try { t.Despawn(); } catch (Exception ex) { ManualLogSource log = Plugin.Log; if (log != null) { log.LogWarning((object)("[Teeth] despawn failed: " + ex.Message)); } } } } public static class TeethKillState { public const string DeadFlag = "cici_teeth_killed"; public const float TeethDeathDamage = 150f; public const float MaxAggressionScale = 1.5f; private static readonly Dictionary _accumDamage = new Dictionary(); private static readonly string[] EverydayShells = new string[4] { "buckshot", "slug", "dragon", "blank" }; private static List _artifactCache; public static void AddDamage(DEN_Teeth t, float amount) { if (!((Object)(object)t == (Object)null)) { _accumDamage.TryGetValue(t, out var value); value += amount; _accumDamage[t] = value; } } public static float GetDamage(DEN_Teeth t) { if ((Object)(object)t == (Object)null) { return 0f; } _accumDamage.TryGetValue(t, out var value); return value; } public static void Reset(DEN_Teeth t) { if ((Object)(object)t != (Object)null) { _accumDamage.Remove(t); } } public static bool IsDeadForRun() { try { return CL_GameManager.HasActiveFlag("cici_teeth_killed", false); } catch { return false; } } public static void MarkDeadForRun() { try { CL_GameManager.SetGameFlag("cici_teeth_killed", true, "", false, false); } catch { } } public static void OnTeethKilled(DEN_Teeth t) { if ((Object)(object)t == (Object)null) { return; } MarkDeadForRun(); try { GiveShellsToInventory(4); GiveArtifactToInventory(); } catch (Exception ex) { ManualLogSource log = Plugin.Log; if (log != null) { log.LogWarning((object)("[Teeth] award failed: " + ex.Message)); } } try { TeethRetreat.TriggerRetreat(t); } catch (Exception ex2) { ManualLogSource log2 = Plugin.Log; if (log2 != null) { log2.LogWarning((object)("[Teeth] retreat trigger failed: " + ex2.Message)); } } } private static void GiveShellsToInventory(int count) { Inventory instance = Inventory.instance; if ((Object)(object)instance == (Object)null) { return; } try { Plugin.EnsureTypedShellTemplates(); } catch { } for (int i = 0; i < count; i++) { string key = EverydayShells[Random.Range(0, EverydayShells.Length)]; if (Plugin.ShotgunShellTemplatesByType.TryGetValue(key, out var value) && value?.itemData != null) { Item clone = value.itemData.GetClone((Item)null); if (clone != null) { instance.AddItemToInventoryCenter(clone); } } } } private static List GetArtifactPool() { if (_artifactCache != null && _artifactCache.Count > 0) { return _artifactCache; } List list = new List(); ENV_ArtifactDevice[] array = Resources.FindObjectsOfTypeAll(); foreach (ENV_ArtifactDevice val in array) { if (val?.artifacts == null) { continue; } foreach (Item_Object artifact in val.artifacts) { if ((Object)(object)artifact != (Object)null && !list.Contains(artifact)) { list.Add(artifact); } } if (list.Count > 0) { break; } } _artifactCache = list; return list; } private static void GiveArtifactToInventory() { List artifactPool = GetArtifactPool(); if (artifactPool.Count == 0) { ManualLogSource log = Plugin.Log; if (log != null) { log.LogWarning((object)"[Teeth] no artifact pool found"); } return; } Inventory instance = Inventory.instance; if ((Object)(object)instance == (Object)null) { return; } Item_Object val = artifactPool[Random.Range(0, artifactPool.Count)]; if (val?.itemData != null) { Item clone = val.itemData.GetClone((Item)null); if (clone != null) { instance.AddItemToInventoryCenter(clone); } } } } public class TeethHealthBarHandler : MonoBehaviour { private Canvas _canvas; private RectTransform _container; private RectTransform _labelRt; private Text _label; private Outline _labelOutline; private static readonly Color CalmColor = Color.white; private static readonly Color AngryColor = new Color(1f, 0.18f, 0.18f, 1f); private static readonly Color DeadFlagText = new Color(0.3f, 0.85f, 0.4f, 1f); private const float MaxShakePixels = 10f; private const float ShakeHz = 32f; private bool _hasShownNotification; private float _notificationStart; private const float NotificationSeconds = 4f; private void Start() { //IL_0005: Unknown result type (might be due to invalid IL or missing references) //IL_000b: Expected O, but got Unknown //IL_005a: 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_0079: Expected O, but got Unknown //IL_00a7: Unknown result type (might be due to invalid IL or missing references) //IL_00c1: Unknown result type (might be due to invalid IL or missing references) //IL_00db: Unknown result type (might be due to invalid IL or missing references) //IL_00f5: 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_011e: Unknown result type (might be due to invalid IL or missing references) //IL_0124: Expected O, but got Unknown //IL_0148: Unknown result type (might be due to invalid IL or missing references) //IL_0158: Unknown result type (might be due to invalid IL or missing references) //IL_0168: Unknown result type (might be due to invalid IL or missing references) //IL_0178: Unknown result type (might be due to invalid IL or missing references) //IL_01dc: Unknown result type (might be due to invalid IL or missing references) //IL_021c: Unknown result type (might be due to invalid IL or missing references) //IL_0236: Unknown result type (might be due to invalid IL or missing references) GameObject val = new GameObject("ShotgunMod_TeethPatience_Canvas"); val.transform.SetParent(((Component)this).transform, false); _canvas = val.AddComponent(); _canvas.renderMode = (RenderMode)0; _canvas.sortingOrder = 90; CanvasScaler obj = val.AddComponent(); obj.uiScaleMode = (ScaleMode)1; obj.referenceResolution = new Vector2(1920f, 1080f); obj.matchWidthOrHeight = 1f; GameObject val2 = new GameObject("TeethPatience"); val2.transform.SetParent(val.transform, false); _container = val2.AddComponent(); _container.anchorMin = new Vector2(0.5f, 1f); _container.anchorMax = new Vector2(0.5f, 1f); _container.pivot = new Vector2(0.5f, 1f); _container.sizeDelta = new Vector2(560f, 42f); _container.anchoredPosition = new Vector2(0f, -32f); GameObject val3 = new GameObject("Label"); val3.transform.SetParent((Transform)(object)_container, false); _labelRt = val3.AddComponent(); _labelRt.anchorMin = Vector2.zero; _labelRt.anchorMax = Vector2.one; _labelRt.offsetMin = Vector2.zero; _labelRt.offsetMax = Vector2.zero; _label = val3.AddComponent(); _label.font = Resources.GetBuiltinResource("LegacyRuntime.ttf") ?? Resources.GetBuiltinResource("Arial.ttf"); _label.fontSize = 28; _label.fontStyle = (FontStyle)1; _label.alignment = (TextAnchor)4; ((Graphic)_label).color = CalmColor; _label.text = "TEETH"; _labelOutline = val3.AddComponent(); ((Shadow)_labelOutline).effectColor = new Color(0f, 0f, 0f, 0.95f); ((Shadow)_labelOutline).effectDistance = new Vector2(2f, -2f); ((Component)_container).gameObject.SetActive(false); } private void LateUpdate() { //IL_011e: 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_0129: Unknown result type (might be due to invalid IL or missing references) //IL_018c: Unknown result type (might be due to invalid IL or missing references) //IL_007b: Unknown result type (might be due to invalid IL or missing references) //IL_008b: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)_container == (Object)null || (Object)(object)_label == (Object)null) { return; } if (TeethKillState.IsDeadForRun()) { if (!_hasShownNotification) { _hasShownNotification = true; _notificationStart = Time.time; } if (Time.time - _notificationStart < 4f) { ((Component)_container).gameObject.SetActive(true); _label.text = "My bag became heavier."; ((Graphic)_label).color = DeadFlagText; _labelRt.anchoredPosition = Vector2.zero; } else { ((Component)_container).gameObject.SetActive(false); } return; } DEN_Teeth instance = DEN_Teeth.instance; if ((Object)(object)instance == (Object)null) { ((Component)_container).gameObject.SetActive(false); return; } float damage = TeethKillState.GetDamage(instance); if (damage <= 0f) { ((Component)_container).gameObject.SetActive(false); return; } ((Component)_container).gameObject.SetActive(true); float num = Mathf.Clamp01(damage / 150f); _label.text = "TEETH"; ((Graphic)_label).color = Color.Lerp(CalmColor, AngryColor, num); float num2 = 10f * num * num; float num3 = Time.unscaledTime * 32f; float num4 = (Mathf.PerlinNoise(num3, 0f) - 0.5f) * 2f; float num5 = (Mathf.PerlinNoise(0f, num3) - 0.5f) * 2f; _labelRt.anchoredPosition = new Vector2(num4 * num2, num5 * num2); } } [HarmonyPatch(typeof(DEN_Teeth), "Damage")] public static class CiciTeethKillablePatch { private static readonly FieldInfo _currentStateField = AccessTools.Field(typeof(AIGameEntity), "currentState"); private static readonly Func _currentStateNameFn = delegate(DEN_Teeth t) { if ((Object)(object)t == (Object)null || _currentStateField == null) { return null; } try { object value = _currentStateField.GetValue(t); return value?.GetType().GetField("name")?.GetValue(value) as string; } catch { return null; } }; [HarmonyPostfix] public static void Postfix(DEN_Teeth __instance, DamageInfo info, bool __result) { if ((Object)(object)__instance == (Object)null || info == null || TeethKillState.IsDeadForRun()) { return; } try { if (_currentStateNameFn?.Invoke(__instance) == "retreat") { return; } } catch { } float num = info.amount; if (info.HasTag("hammer")) { num /= 8f; } else if (info.HasTag("dragon")) { num *= 4.5f; } TeethKillState.AddDamage(__instance, num); float damage = TeethKillState.GetDamage(__instance); if (damage >= 150f) { TeethKillState.Reset(__instance); TeethAggressionScaler.ForgetBaseline(__instance); TeethKillState.OnTeethKilled(__instance); } else { float num2 = Mathf.Clamp01(damage / 150f); float scale = Mathf.Lerp(1f, 1.5f, num2); TeethAggressionScaler.ApplyScale(__instance, scale); } } } [HarmonyPatch(typeof(DEN_Teeth), "OnEnable")] public static class CiciTeethDeadOnEnablePatch { [HarmonyPostfix] public static void Postfix(DEN_Teeth __instance) { if ((Object)(object)__instance == (Object)null || !TeethKillState.IsDeadForRun()) { return; } try { __instance.Despawn(); } catch (Exception ex) { ManualLogSource log = Plugin.Log; if (log != null) { log.LogWarning((object)("[Teeth] OnEnable despawn failed: " + ex.Message)); } } } } [HarmonyPatch(typeof(DEN_Drone), "Kill")] public static class DroneShellDropPatch { [HarmonyPostfix] public static void Postfix(DEN_Drone __instance, string type, DamageInfo damageInfo) { if (!((Object)(object)__instance == (Object)null)) { ShotgunShellDropHelper.TryDropSpecificShell(damageInfo, "slug", 0.25f); ShotgunShellDropHelper.TryDropSpecificShell(damageInfo, "dragon", 0.05f); ShotgunShellDropHelper.TryDropHammerKill(damageInfo); } } } [HarmonyPatch(typeof(Denizen), "Kill")] public static class DenizenHammerKillDropPatch { [HarmonyPostfix] public static void Postfix(Denizen __instance, string type, DamageInfo info) { if (!((Object)(object)__instance == (Object)null)) { ShotgunShellDropHelper.TryDropHammerKill(info); } } } [HarmonyPatch(typeof(HandItem_Shoot), "Shoot")] public static class ShotgunBuckshotPatch { private const int PelletCount = 8; private const float SpreadDeg = 5f; private const float MaxRange = 30f; private const float DamagePerPellet = 2f; private const float SlugDamage = 24f; private const int DragonPelletCount = 8; private const float DragonSpreadDeg = 4f; private const float DragonDamagePerPellet = 0.75f; private const float DragonFireSeconds = 3f; public const float DragonVsTeethMultiplier = 4.5f; private const float BlankRecoilMultiplier = 3f; internal static readonly Dictionary _blankRecoilBackup = new Dictionary(); private const float ReversePullSpeed = 3f; private const float ReverseMaxRange = 60f; private const float ReverseDamage = 24f; private const int RebarPelletCount = 25; private const float RebarSpreadDeg = 6f; private const float RebarDamagePerPellet = 3f; internal static readonly Dictionary _firingShellType = new Dictionary(); internal static readonly Dictionary> _recentFiredTypes = new Dictionary>(); internal static readonly FieldInfo _playerVelField = AccessTools.Field(typeof(ENT_Player), "vel"); internal static readonly Dictionary _pendingBuckshotAt = new Dictionary(); private const float BuckshotFallbackWindow = 0.3f; private const float RebarLaunchSpeed = 50f; private static GameObject _rebarProjectilePrefab; private static float _rebarShootSpeed; private static LayerMask _rebarAimMask; private static bool _rebarResolved; private static Sprite _pixelSprite; [HarmonyPrefix] public static void Prefix(HandItem_Shoot __instance, out GameObject __state) { __state = null; if (!(((HandItem)(__instance?)).item?.itemTag == "shotgun")) { return; } __state = __instance.projectile; __instance.projectile = null; string text = "buckshot"; if (((HandItem)__instance).item != null) { string barrelType = Plugin.GetBarrelType(((HandItem)__instance).item, 0); if (!string.IsNullOrEmpty(barrelType)) { text = barrelType; Plugin.SetBarrelType(((HandItem)__instance).item, 0, ""); } else { string barrelType2 = Plugin.GetBarrelType(((HandItem)__instance).item, 1); if (!string.IsNullOrEmpty(barrelType2)) { text = barrelType2; Plugin.SetBarrelType(((HandItem)__instance).item, 1, ""); } } } _firingShellType[__instance] = text; if (text == "blank") { _blankRecoilBackup[__instance] = (__instance.recoil, __instance.maxRecoilMagnitude); __instance.recoil *= 3f; __instance.maxRecoilMagnitude *= 3f; } if (!_recentFiredTypes.TryGetValue(__instance, out var value)) { value = new Queue(); _recentFiredTypes[__instance] = value; } value.Enqueue(text); while (value.Count > 2) { value.Dequeue(); } } [HarmonyPostfix] public static void Postfix(HandItem_Shoot __instance, GameObject __state) { if (((HandItem)(__instance?)).item?.itemTag != "shotgun") { return; } if ((Object)(object)__state != (Object)null) { __instance.projectile = __state; } if (_blankRecoilBackup.TryGetValue(__instance, out (float, float) value)) { (__instance.recoil, __instance.maxRecoilMagnitude) = value; _blankRecoilBackup.Remove(__instance); } FireShellOnce(__instance); bool flag = __instance.GetAmmo() > 0; ShotgunModHandler.QueueSnapBack(__instance, 0.7f, flag); if (!flag && (Object)(object)Plugin.ShotgunBreakOpenClip != (Object)null) { object? obj = AccessTools.Field(typeof(HandItem_Shoot), "clipHandler")?.GetValue(__instance); UT_AudioClipHandler val = (UT_AudioClipHandler)((obj is UT_AudioClipHandler) ? obj : null); ShotgunModHandler.QueueDelayedAudio(((Object)(object)val != (Object)null) ? ((Component)val).GetComponent() : null, ((Component)__instance).transform, Plugin.ShotgunBreakOpenClip, 0.2f); } if (!flag) { int count = 2; if (_recentFiredTypes.TryGetValue(__instance, out var value2)) { count = Mathf.Clamp(value2.Count, 1, 2); } ShotgunModHandler.QueueShellEject(__instance, 0.55f, count); } } internal static void FireShellOnce(HandItem_Shoot shooter) { if (!((Object)(object)shooter == (Object)null)) { _pendingBuckshotAt.Remove(shooter); string text = "buckshot"; if (_firingShellType.TryGetValue(shooter, out var value)) { text = value; } _firingShellType.Remove(shooter); switch (text) { case "slug": FireSlug(shooter); break; case "dragon": FireDragonBreath(shooter); break; case "blank": FireBlank(shooter); break; case "reverse": FireReverse(shooter); break; case "rebar": FireRebar(shooter); break; default: FireBuckshot(shooter); break; } } } internal static void FireBuckshotOnce(HandItem_Shoot shooter) { FireShellOnce(shooter); } private static void FireBuckshot(HandItem_Shoot shooter) { FireConeShell(shooter, 8, 5f, 2f, new List { "Shotgun", "buckshot" }); } private static void FireSlug(HandItem_Shoot shooter) { FireConeShell(shooter, 1, 0f, 24f, new List { "Shotgun", "slug" }, ShellFxStyle.Slug, null, null, 30f, penetrating: true); } private static void FireDragonBreath(HandItem_Shoot shooter) { SpawnDragonBreathCone(); FireConeShell(shooter, 8, 4f, 0.75f, new List { "Shotgun", "dragon", "fire", "burn" }, ShellFxStyle.Dragon, delegate(Damageable target, RaycastHit hit, Vector3 dir) { GameEntity val = (GameEntity)(object)((target is GameEntity) ? target : null); if ((Object)(object)val != (Object)null) { val.AddEffect("fire", 3f); } }); } private static void SpawnDragonBreathCone() { //IL_0051: Unknown result type (might be due to invalid IL or missing references) //IL_0056: Unknown result type (might be due to invalid IL or missing references) //IL_0062: Unknown result type (might be due to invalid IL or missing references) //IL_0078: Unknown result type (might be due to invalid IL or missing references) //IL_0083: 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_0092: Unknown result type (might be due to invalid IL or missing references) //IL_0097: Unknown result type (might be due to invalid IL or missing references) //IL_00a3: Unknown result type (might be due to invalid IL or missing references) //IL_00a8: Unknown result type (might be due to invalid IL or missing references) //IL_00b4: 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_00c4: 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_001c: Unknown result type (might be due to invalid IL or missing references) //IL_0027: 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_0036: Unknown result type (might be due to invalid IL or missing references) Camera main = Camera.main; if (!((Object)(object)main == (Object)null)) { try { FXManager.PlayParticleWithRadius("fire-small", ((Component)main).transform.position + ((Component)main).transform.forward * 0.4f, 0.6f, 10); } catch { } GameObject val = new GameObject("ShotgunMod_DragonBreath"); val.transform.position = ((Component)main).transform.position; DragonBreathEmitter dragonBreathEmitter = val.AddComponent(); dragonBreathEmitter.Origin = ((Component)main).transform.position + ((Component)main).transform.forward * 0.5f; dragonBreathEmitter.Forward = ((Component)main).transform.forward; dragonBreathEmitter.Up = ((Component)main).transform.up; dragonBreathEmitter.Right = ((Component)main).transform.right; } } private static void FireBlank(HandItem_Shoot shooter) { Camera main = Camera.main; if (!((Object)(object)main == (Object)null)) { SpawnMuzzleFlash(main); SpawnBlankFireball(main); } } private static void SpawnBlankFireball(Camera cam) { //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_0011: 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_0020: Unknown result type (might be due to invalid IL or missing references) //IL_0025: Unknown result type (might be due to invalid IL or missing references) //IL_002b: Unknown result type (might be due to invalid IL or missing references) Vector3 val = ((Component)cam).transform.position + ((Component)cam).transform.forward * 0.5f; try { FXManager.PlayParticleWithRadius("fire-small", val, 0.35f, 6); } catch { } } private static void FireReverse(HandItem_Shoot shooter) { FireConeShell(shooter, 1, 0f, 24f, new List { "Shotgun", "reverse" }, ShellFxStyle.Reverse, delegate(Damageable dmg, RaycastHit hit, Vector3 dir) { //IL_0002: Unknown result type (might be due to invalid IL or missing references) StartReversePull(((RaycastHit)(ref hit)).point); }, delegate(RaycastHit hit, Vector3 dir) { //IL_0002: Unknown result type (might be due to invalid IL or missing references) StartReversePull(((RaycastHit)(ref hit)).point); }, 60f); } private static void StartReversePull(Vector3 target) { //IL_0013: Unknown result type (might be due to invalid IL or missing references) //IL_0018: Unknown result type (might be due to invalid IL or missing references) //IL_001e: Expected O, but got Unknown //IL_0024: Unknown result type (might be due to invalid IL or missing references) //IL_0025: Unknown result type (might be due to invalid IL or missing references) if (!((Object)(object)ENT_Player.playerObject == (Object)null)) { GameObject val = new GameObject("ShotgunMod_ReversePull"); Object.DontDestroyOnLoad((Object)val); PlayerPull playerPull = val.AddComponent(); playerPull.target = target; playerPull.totalSpeed = 3f; playerPull.duration = 0.6f; playerPull.arriveDist = 1.5f; } } private static void FireRebar(HandItem_Shoot shooter) { //IL_0034: Unknown result type (might be due to invalid IL or missing references) //IL_003f: Unknown result type (might be due to invalid IL or missing references) //IL_0049: Unknown result type (might be due to invalid IL or missing references) //IL_004e: 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_005a: 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) //IL_008e: 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_00a0: 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_00aa: Unknown result type (might be due to invalid IL or missing references) //IL_00af: 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_00b5: 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_00d2: 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_00e2: Unknown result type (might be due to invalid IL or missing references) //IL_00f6: Unknown result type (might be due to invalid IL or missing references) //IL_00fb: Unknown result type (might be due to invalid IL or missing references) //IL_0100: Unknown result type (might be due to invalid IL or missing references) //IL_0107: Unknown result type (might be due to invalid IL or missing references) //IL_0109: Unknown result type (might be due to invalid IL or missing references) //IL_010b: Unknown result type (might be due to invalid IL or missing references) //IL_014a: Unknown result type (might be due to invalid IL or missing references) //IL_0151: Unknown result type (might be due to invalid IL or missing references) if (!ResolveRebarShoot()) { return; } Camera main = Camera.main; if ((Object)(object)main == (Object)null) { return; } ENT_Player playerObject = ENT_Player.playerObject; if ((Object)(object)playerObject == (Object)null) { return; } SpawnMuzzleFlash(main); Vector3 val = ((Component)main).transform.position + ((Component)main).transform.forward * 0.4f; Vector3 forward = ((Component)main).transform.forward; for (int i = 0; i < 25; i++) { float num = Random.Range(-6f, 6f); float num2 = Random.Range(-6f, 6f); Vector3 val2 = Quaternion.AngleAxis(num, ((Component)main).transform.right) * Quaternion.AngleAxis(num2, ((Component)main).transform.up) * forward; Vector3 val3 = val + ((Component)main).transform.right * Random.Range(-0.18f, 0.18f) + ((Component)main).transform.up * Random.Range(-0.18f, 0.18f); try { GameObject val4 = Object.Instantiate(_rebarProjectilePrefab, val3, Quaternion.LookRotation(val2)); Projectile component = val4.GetComponent(); if ((Object)(object)component == (Object)null) { ManualLogSource log = Plugin.Log; if (log != null) { log.LogWarning((object)"[Rebar] spawned projectile lacks Projectile component"); } Object.Destroy((Object)(object)val4); } else { component.Initialize(val2 * 50f, (GameEntity)(object)playerObject); } } catch (Exception ex) { ManualLogSource log2 = Plugin.Log; if (log2 != null) { log2.LogWarning((object)("[Rebar] launch failed: " + ex.Message)); } } } } private static bool ResolveRebarShoot() { //IL_0098: Unknown result type (might be due to invalid IL or missing references) //IL_009d: Unknown result type (might be due to invalid IL or missing references) if (_rebarResolved && (Object)(object)_rebarProjectilePrefab != (Object)null) { return true; } _rebarResolved = true; try { GameObject assetGameObject = CL_AssetManager.GetAssetGameObject("Item_Rebar", ""); HandItem obj = (((Object)(object)assetGameObject != (Object)null) ? assetGameObject.GetComponent() : null)?.itemData?.handItemAsset; HandItem_Shoot val = (HandItem_Shoot)(object)((obj is HandItem_Shoot) ? obj : null); if ((Object)(object)val == (Object)null) { ManualLogSource log = Plugin.Log; if (log != null) { log.LogWarning((object)"[Rebar] Item_Rebar's HandItem_Shoot not found"); } return false; } _rebarProjectilePrefab = val.projectile; _rebarShootSpeed = val.shootSpeed; _rebarAimMask = val.aimMask; if ((Object)(object)_rebarProjectilePrefab == (Object)null) { ManualLogSource log2 = Plugin.Log; if (log2 != null) { log2.LogWarning((object)"[Rebar] HandItem_Shoot.projectile is null"); } return false; } ManualLogSource log3 = Plugin.Log; if (log3 != null) { log3.LogInfo((object)$"[Rebar] resolved projectile='{((Object)_rebarProjectilePrefab).name}' shootSpeed={_rebarShootSpeed}"); } return true; } catch (Exception ex) { ManualLogSource log4 = Plugin.Log; if (log4 != null) { log4.LogWarning((object)("[Rebar] resolve failed: " + ex.Message)); } return false; } } private static void FireConeShell(HandItem_Shoot shooter, int pelletCount, float spreadDeg, float dmgPerPellet, List damageTags, ShellFxStyle fxStyle = ShellFxStyle.Buckshot, Action onDamagedHit = null, Action onSurfaceHit = null, float maxRange = 30f, bool penetrating = false) { //IL_0016: 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_0022: Unknown result type (might be due to invalid IL or missing references) //IL_0027: Unknown result type (might be due to invalid IL or missing references) //IL_0039: Unknown result type (might be due to invalid IL or missing references) //IL_003a: Unknown result type (might be due to invalid IL or missing references) //IL_0085: Unknown result type (might be due to invalid IL or missing references) //IL_0086: Unknown result type (might be due to invalid IL or missing references) //IL_005c: Unknown result type (might be due to invalid IL or missing references) //IL_0061: Unknown result type (might be due to invalid IL or missing references) //IL_006e: 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_0078: Unknown result type (might be due to invalid IL or missing references) //IL_007d: Unknown result type (might be due to invalid IL or missing references) //IL_007e: Unknown result type (might be due to invalid IL or missing references) //IL_0083: Unknown result type (might be due to invalid IL or missing references) //IL_00e7: Unknown result type (might be due to invalid IL or missing references) //IL_00ec: Unknown result type (might be due to invalid IL or missing references) //IL_01f1: Unknown result type (might be due to invalid IL or missing references) //IL_01f6: Unknown result type (might be due to invalid IL or missing references) //IL_01fa: Unknown result type (might be due to invalid IL or missing references) //IL_0201: Unknown result type (might be due to invalid IL or missing references) //IL_0206: Unknown result type (might be due to invalid IL or missing references) //IL_020a: Unknown result type (might be due to invalid IL or missing references) //IL_012a: Unknown result type (might be due to invalid IL or missing references) //IL_0131: Unknown result type (might be due to invalid IL or missing references) //IL_0156: Unknown result type (might be due to invalid IL or missing references) //IL_015b: Unknown result type (might be due to invalid IL or missing references) //IL_0162: Unknown result type (might be due to invalid IL or missing references) //IL_0169: Unknown result type (might be due to invalid IL or missing references) //IL_016e: Unknown result type (might be due to invalid IL or missing references) //IL_022b: Unknown result type (might be due to invalid IL or missing references) //IL_0230: Unknown result type (might be due to invalid IL or missing references) //IL_0284: Unknown result type (might be due to invalid IL or missing references) //IL_0289: Unknown result type (might be due to invalid IL or missing references) //IL_01c9: 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) //IL_0187: Unknown result type (might be due to invalid IL or missing references) //IL_02b8: Unknown result type (might be due to invalid IL or missing references) //IL_0327: Unknown result type (might be due to invalid IL or missing references) //IL_032c: Unknown result type (might be due to invalid IL or missing references) //IL_0330: Unknown result type (might be due to invalid IL or missing references) //IL_0337: Unknown result type (might be due to invalid IL or missing references) //IL_033c: Unknown result type (might be due to invalid IL or missing references) //IL_0340: Unknown result type (might be due to invalid IL or missing references) //IL_02db: Unknown result type (might be due to invalid IL or missing references) //IL_0370: Unknown result type (might be due to invalid IL or missing references) //IL_0375: Unknown result type (might be due to invalid IL or missing references) //IL_0379: Unknown result type (might be due to invalid IL or missing references) //IL_037e: Unknown result type (might be due to invalid IL or missing references) //IL_0385: Unknown result type (might be due to invalid IL or missing references) //IL_038c: Unknown result type (might be due to invalid IL or missing references) //IL_0391: Unknown result type (might be due to invalid IL or missing references) //IL_03ee: Unknown result type (might be due to invalid IL or missing references) //IL_03f3: Unknown result type (might be due to invalid IL or missing references) //IL_03aa: Unknown result type (might be due to invalid IL or missing references) //IL_03af: Unknown result type (might be due to invalid IL or missing references) Camera main = Camera.main; if ((Object)(object)main == (Object)null) { return; } Vector3 position = ((Component)main).transform.position; Vector3 forward = ((Component)main).transform.forward; SpawnMuzzleFlash(main); int num = -5; for (int i = 0; i < pelletCount; i++) { Vector3 val = forward; if (spreadDeg > 0f) { float num2 = Random.Range(0f - spreadDeg, spreadDeg); float num3 = Random.Range(0f - spreadDeg, spreadDeg); val = Quaternion.AngleAxis(num2, ((Component)main).transform.right) * Quaternion.AngleAxis(num3, ((Component)main).transform.up) * forward; } RaycastHit[] array = Physics.RaycastAll(position, val, maxRange, num, (QueryTriggerInteraction)2); if (array.Length == 0) { continue; } Array.Sort(array, (RaycastHit a, RaycastHit b) => ((RaycastHit)(ref a)).distance.CompareTo(((RaycastHit)(ref b)).distance)); RaycastHit value; RaycastHit[] array2; if (penetrating) { HashSet hashSet = new HashSet(); RaycastHit? val2 = null; array2 = array; for (int j = 0; j < array2.Length; j++) { RaycastHit val3 = array2[j]; if ((Object)(object)((Component)((RaycastHit)(ref val3)).collider).GetComponentInParent() != (Object)null) { continue; } Damageable componentInParent = ((Component)((RaycastHit)(ref val3)).collider).GetComponentInParent(); if (componentInParent != null && hashSet.Add(componentInParent)) { SpawnHitFx(((RaycastHit)(ref val3)).point, ((RaycastHit)(ref val3)).normal, leavePrint: false, fxStyle); DamageInfo val4 = DamageInfo.CreateDamageInfo(dmgPerPellet, "Shotgun", damageTags, (GameEntity)(object)ENT_Player.playerObject); val4.position = ((RaycastHit)(ref val3)).point; val4.force = val * 5f; componentInParent.Damage(val4); try { onDamagedHit?.Invoke(componentInParent, val3, val); } catch (Exception ex) { ManualLogSource log = Plugin.Log; if (log != null) { log.LogWarning((object)("[Shell] onDamagedHit failed: " + ex.Message)); } } } else if (componentInParent == null && !((RaycastHit)(ref val3)).collider.isTrigger) { val2 = val3; break; } } if (!val2.HasValue) { continue; } value = val2.Value; Vector3 point = ((RaycastHit)(ref value)).point; value = val2.Value; SpawnHitFx(point, ((RaycastHit)(ref value)).normal, leavePrint: true, fxStyle); if (hashSet.Count != 0) { continue; } try { onSurfaceHit?.Invoke(val2.Value, val); } catch (Exception ex2) { ManualLogSource log2 = Plugin.Log; if (log2 != null) { log2.LogWarning((object)("[Shell] onSurfaceHit failed: " + ex2.Message)); } } continue; } RaycastHit? val5 = null; RaycastHit? val6 = null; Damageable val7 = null; array2 = array; for (int j = 0; j < array2.Length; j++) { RaycastHit value2 = array2[j]; if ((Object)(object)((Component)((RaycastHit)(ref value2)).collider).GetComponentInParent() != (Object)null) { continue; } if (!((RaycastHit)(ref value2)).collider.isTrigger && !val5.HasValue) { val5 = value2; } if (val7 == null) { Damageable componentInParent2 = ((Component)((RaycastHit)(ref value2)).collider).GetComponentInParent(); if (componentInParent2 != null) { val7 = componentInParent2; val6 = value2; } } if (val5.HasValue && val7 != null) { break; } } RaycastHit? val8 = val6 ?? val5; if (!val8.HasValue) { continue; } bool flag = val7 != null; value = val8.Value; Vector3 point2 = ((RaycastHit)(ref value)).point; value = val8.Value; SpawnHitFx(point2, ((RaycastHit)(ref value)).normal, !flag, fxStyle); if (val7 != null) { DamageInfo val9 = DamageInfo.CreateDamageInfo(dmgPerPellet, "Shotgun", damageTags, (GameEntity)(object)ENT_Player.playerObject); value = val6.Value; val9.position = ((RaycastHit)(ref value)).point; val9.force = val * 5f; val7.Damage(val9); try { onDamagedHit?.Invoke(val7, val6.Value, val); } catch (Exception ex3) { ManualLogSource log3 = Plugin.Log; if (log3 != null) { log3.LogWarning((object)("[Shell] onDamagedHit failed: " + ex3.Message)); } } } else { if (!val5.HasValue) { continue; } try { onSurfaceHit?.Invoke(val5.Value, val); } catch (Exception ex4) { ManualLogSource log4 = Plugin.Log; if (log4 != null) { log4.LogWarning((object)("[Shell] onSurfaceHit failed: " + ex4.Message)); } } } } } private static void AddPlayerVelocity(Vector3 delta) { //IL_0029: Unknown result type (might be due to invalid IL or missing references) //IL_002e: Unknown result type (might be due to invalid IL or missing references) //IL_0035: Unknown result type (might be due to invalid IL or missing references) //IL_0036: Unknown result type (might be due to invalid IL or missing references) //IL_0037: Unknown result type (might be due to invalid IL or missing references) ENT_Player playerObject = ENT_Player.playerObject; if ((Object)(object)playerObject == (Object)null || _playerVelField == null) { return; } try { Vector3 val = (Vector3)_playerVelField.GetValue(playerObject); _playerVelField.SetValue(playerObject, val + delta); } catch (Exception ex) { ManualLogSource log = Plugin.Log; if (log != null) { log.LogWarning((object)("[Shell] vel add failed: " + ex.Message)); } } } private static void SetPlayerVelocity(Vector3 vel) { //IL_0024: Unknown result type (might be due to invalid IL or missing references) ENT_Player playerObject = ENT_Player.playerObject; if ((Object)(object)playerObject == (Object)null || _playerVelField == null) { return; } try { _playerVelField.SetValue(playerObject, vel); } catch (Exception ex) { ManualLogSource log = Plugin.Log; if (log != null) { log.LogWarning((object)("[Shell] vel set failed: " + ex.Message)); } } } private static void SpawnMuzzleFlash(Camera cam) { SpawnTintFlash(); SpawnEnvironmentalLight(cam); } private static void SpawnTintFlash() { //IL_0005: Unknown result type (might be due to invalid IL or missing references) //IL_000b: Expected O, but got Unknown //IL_0027: Unknown result type (might be due to invalid IL or missing references) //IL_002c: Unknown result type (might be due to invalid IL or missing references) //IL_0058: 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_0088: Unknown result type (might be due to invalid IL or missing references) GameObject val = new GameObject("ShotgunMod_MuzzleFlash_Tint"); Canvas obj = val.AddComponent(); obj.renderMode = (RenderMode)0; obj.sortingOrder = 32767; GameObject val2 = new GameObject("Tint"); val2.transform.SetParent(val.transform, false); Image obj2 = val2.AddComponent(); ((Graphic)obj2).color = new Color(1f, 0.85f, 0.3f, 0.35f); RectTransform rectTransform = ((Graphic)obj2).rectTransform; rectTransform.anchorMin = Vector2.zero; rectTransform.anchorMax = Vector2.one; rectTransform.offsetMin = Vector2.zero; rectTransform.offsetMax = Vector2.zero; val.AddComponent(); } private static void SpawnEnvironmentalLight(Camera cam) { //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_0016: Unknown result type (might be due to invalid IL or missing references) //IL_0021: Unknown result type (might be due to invalid IL or missing references) //IL_002b: Unknown result type (might be due to invalid IL or missing references) //IL_0030: Unknown result type (might be due to invalid IL or missing references) //IL_003a: 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_008e: Expected O, but got Unknown GameObject val = new GameObject("ShotgunMod_MuzzleFlash_Light"); val.transform.position = ((Component)cam).transform.position + ((Component)cam).transform.forward * 0.8f; Light obj = val.AddComponent(); obj.type = (LightType)2; obj.color = new Color(1f, 0.85f, 0.4f); obj.intensity = 30f; obj.range = 25f; obj.shadows = (LightShadows)0; obj.renderMode = (LightRenderMode)1; Object.Destroy((Object)val, 0.2f); } private static Sprite GetPixelSprite() { //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_0023: 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_0030: Unknown result type (might be due to invalid IL or missing references) //IL_004a: Unknown result type (might be due to invalid IL or missing references) //IL_0059: Unknown result type (might be due to invalid IL or missing references) //IL_0068: Expected O, but got Unknown if ((Object)(object)_pixelSprite != (Object)null) { return _pixelSprite; } Texture2D val = new Texture2D(1, 1, (TextureFormat)4, false) { filterMode = (FilterMode)0 }; val.SetPixel(0, 0, Color.white); val.Apply(); _pixelSprite = Sprite.Create(val, new Rect(0f, 0f, 1f, 1f), new Vector2(0.5f, 0.5f), 1f); return _pixelSprite; } private static void SpawnHitFx(Vector3 point, Vector3 normal, bool leavePrint = true, ShellFxStyle style = ShellFxStyle.Buckshot) { //IL_0017: Unknown result type (might be due to invalid IL or missing references) //IL_00f2: Unknown result type (might be due to invalid IL or missing references) //IL_00f3: Unknown result type (might be due to invalid IL or missing references) //IL_00f5: Unknown result type (might be due to invalid IL or missing references) //IL_00fb: Unknown result type (might be due to invalid IL or missing references) //IL_0223: Unknown result type (might be due to invalid IL or missing references) //IL_0228: Unknown result type (might be due to invalid IL or missing references) //IL_022e: Unknown result type (might be due to invalid IL or missing references) //IL_022f: Unknown result type (might be due to invalid IL or missing references) //IL_0235: Unknown result type (might be due to invalid IL or missing references) //IL_023a: Unknown result type (might be due to invalid IL or missing references) //IL_0244: Unknown result type (might be due to invalid IL or missing references) //IL_024a: Unknown result type (might be due to invalid IL or missing references) //IL_0251: Unknown result type (might be due to invalid IL or missing references) //IL_025b: Unknown result type (might be due to invalid IL or missing references) //IL_026a: Unknown result type (might be due to invalid IL or missing references) //IL_026b: Unknown result type (might be due to invalid IL or missing references) //IL_0272: Unknown result type (might be due to invalid IL or missing references) //IL_0283: Unknown result type (might be due to invalid IL or missing references) //IL_0297: Unknown result type (might be due to invalid IL or missing references) //IL_0298: Unknown result type (might be due to invalid IL or missing references) //IL_02a2: Unknown result type (might be due to invalid IL or missing references) //IL_02a7: Unknown result type (might be due to invalid IL or missing references) //IL_02ac: Unknown result type (might be due to invalid IL or missing references) //IL_02b0: Unknown result type (might be due to invalid IL or missing references) //IL_02b5: Unknown result type (might be due to invalid IL or missing references) //IL_02b7: Unknown result type (might be due to invalid IL or missing references) //IL_02c2: Unknown result type (might be due to invalid IL or missing references) //IL_02cc: Unknown result type (might be due to invalid IL or missing references) //IL_02dd: Expected O, but got Unknown //IL_02f5: Unknown result type (might be due to invalid IL or missing references) //IL_02f6: Unknown result type (might be due to invalid IL or missing references) //IL_02fc: Unknown result type (might be due to invalid IL or missing references) //IL_0301: Unknown result type (might be due to invalid IL or missing references) if (style == ShellFxStyle.Rebar) { return; } if ((Object)(object)Plugin.ShotgunImpactClip != (Object)null) { AudioSource.PlayClipAtPoint(Plugin.ShotgunImpactClip, point, 0.3f); } float scale = 0.08f; Color value = default(Color); ((Color)(ref value))..ctor(1f, 0.85f, 0.2f, 1f); Color value2 = default(Color); ((Color)(ref value2))..ctor(0f, 0f, 0f, 1f); switch (style) { case ShellFxStyle.Slug: scale = 0.22f; break; case ShellFxStyle.Dragon: scale = 0.1f; ((Color)(ref value))..ctor(1f, 0.45f, 0.1f, 1f); ((Color)(ref value2))..ctor(0.1f, 0f, 0f, 1f); break; case ShellFxStyle.Reverse: scale = 0.4f; ((Color)(ref value))..ctor(0.55f, 1f, 1f, 1f); ((Color)(ref value2))..ctor(0f, 0.2f, 0.3f, 1f); break; } if (leavePrint) { HitPrintHelper.SpawnPrint(point, normal, scale, value, value2); } Color val = default(Color); ((Color)(ref val))..ctor(1f, 0.85f, 0.2f); Color val2 = default(Color); ((Color)(ref val2))..ctor(1f, 0.55f, 0.1f); int num = 5; float num2 = 0.05f; float num3 = 2.5f; float num4 = 5.5f; switch (style) { case ShellFxStyle.Slug: num2 = 0.09f; num = 8; ((Color)(ref val))..ctor(1f, 0.95f, 0.6f); ((Color)(ref val2))..ctor(1f, 0.7f, 0.2f); break; case ShellFxStyle.Dragon: num = 10; num2 = 0.06f; ((Color)(ref val))..ctor(1f, 0.45f, 0.1f); ((Color)(ref val2))..ctor(0.95f, 0.15f, 0.05f); num3 = 1.5f; num4 = 4f; break; case ShellFxStyle.Reverse: num = 10; num2 = 0.1f; ((Color)(ref val))..ctor(0.55f, 1f, 1f); ((Color)(ref val2))..ctor(0.15f, 0.7f, 1f); break; } Sprite pixelSprite = GetPixelSprite(); for (int i = 0; i < num; i++) { GameObject val3 = new GameObject("ShotgunSpark"); val3.transform.position = point + normal * 0.02f; val3.transform.localScale = Vector3.one * num2; SpriteRenderer obj = val3.AddComponent(); obj.sprite = pixelSprite; obj.color = Color.Lerp(val, val2, Random.value); ((Renderer)obj).sortingOrder = 100; Rigidbody obj2 = val3.AddComponent(); obj2.useGravity = true; obj2.freezeRotation = true; Vector3 val4 = normal + Random.insideUnitSphere * 0.8f; Vector3 normalized = ((Vector3)(ref val4)).normalized; obj2.velocity = normalized * Random.Range(num3, num4); val3.AddComponent(); Object.Destroy((Object)val3, 0.5f); } if (style != ShellFxStyle.Dragon) { return; } try { FXManager.PlayParticleWithRadius("fire-small", point + normal * 0.05f, 0.4f, 3); } catch { } } } public enum ShellFxStyle { Buckshot, Slug, Dragon, Rebar, Reverse } public class DragonBreathEmitter : MonoBehaviour { public Vector3 Origin; public Vector3 Forward; public Vector3 Up; public Vector3 Right; private float _t; private const float Duration = 0.35f; private const float MaxDistance = 12f; private const float ConeRadiusAtMax = 3f; private const int BurstsPerFrame = 3; private const float IgniteSeconds = 3f; private static readonly Collider[] _igniteBuffer = (Collider[])(object)new Collider[32]; private void Update() { //IL_0099: 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_00a6: Unknown result type (might be due to invalid IL or missing references) //IL_00ab: Unknown result type (might be due to invalid IL or missing references) //IL_00b1: Unknown result type (might be due to invalid IL or missing references) //IL_00b8: Unknown result type (might be due to invalid IL or missing references) //IL_00bd: Unknown result type (might be due to invalid IL or missing references) //IL_00c3: Unknown result type (might be due to invalid IL or missing references) //IL_00ca: Unknown result type (might be due to invalid IL or missing references) //IL_00cf: Unknown result type (might be due to invalid IL or missing references) //IL_00d4: Unknown result type (might be due to invalid IL or missing references) //IL_011f: Unknown result type (might be due to invalid IL or missing references) //IL_0125: Unknown result type (might be due to invalid IL or missing references) //IL_012b: Unknown result type (might be due to invalid IL or missing references) //IL_0130: Unknown result type (might be due to invalid IL or missing references) //IL_00e4: Unknown result type (might be due to invalid IL or missing references) _t += Time.deltaTime; if (_t >= 0.35f) { Object.Destroy((Object)(object)((Component)this).gameObject); return; } float num = Mathf.Clamp01(_t / 0.35f); float num2 = Mathf.Lerp(0.5f, 4f, num); float num3 = Mathf.Lerp(4f, 12f, num); for (int i = 0; i < 3; i++) { float num4 = Random.Range(num2, num3); float num5 = num4 / 12f * 3f; float num6 = Random.Range(0f - num5, num5); float num7 = Random.Range(0f - num5, num5); Vector3 val = Origin + Forward * num4 + Right * num6 + Up * num7; int num8 = Random.Range(2, 5); try { FXManager.PlayParticleWithRadius("fire-small", val, 0.3f, num8); } catch { } } float num9 = (num2 + num3) * 0.5f; float num10 = num9 / 12f * 3f; int num11 = Physics.OverlapSphereNonAlloc(Origin + Forward * num9, num10, _igniteBuffer, -1, (QueryTriggerInteraction)2); for (int j = 0; j < num11; j++) { Collider val2 = _igniteBuffer[j]; if ((Object)(object)val2 == (Object)null || (Object)(object)((Component)val2).GetComponentInParent() != (Object)null) { continue; } GameEntity componentInParent = ((Component)val2).GetComponentInParent(); if (!((Object)(object)componentInParent == (Object)null)) { try { componentInParent.AddEffect("fire", 3f); } catch { } } } } } public class PlayerPush : MonoBehaviour { public Vector3 direction; public float totalSpeed = 10f; public float duration = 0.35f; private float _t; private float _applied; private void Update() { //IL_0092: Unknown result type (might be due to invalid IL or missing references) //IL_0097: Unknown result type (might be due to invalid IL or missing references) //IL_009b: Unknown result type (might be due to invalid IL or missing references) //IL_009e: Unknown result type (might be due to invalid IL or missing references) //IL_00a4: 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) FieldInfo playerVelField = ShotgunBuckshotPatch._playerVelField; if (playerVelField == null) { Object.Destroy((Object)(object)((Component)this).gameObject); return; } ENT_Player playerObject = ENT_Player.playerObject; if ((Object)(object)playerObject == (Object)null) { Object.Destroy((Object)(object)((Component)this).gameObject); return; } float deltaTime = Time.deltaTime; if (deltaTime <= 0f) { return; } _t += deltaTime; if (_t >= duration) { Object.Destroy((Object)(object)((Component)this).gameObject); return; } float num = totalSpeed * (deltaTime / duration); _applied += num; try { Vector3 val = (Vector3)playerVelField.GetValue(playerObject); playerVelField.SetValue(playerObject, val + direction * num); } catch (Exception ex) { ManualLogSource log = Plugin.Log; if (log != null) { log.LogWarning((object)("[PlayerPush] vel apply failed: " + ex.Message)); } Object.Destroy((Object)(object)((Component)this).gameObject); } } } public class PlayerPull : MonoBehaviour { public Vector3 target; public float totalSpeed = 24f; public float duration = 0.6f; public float arriveDist = 1.5f; private float _t; private void Update() { //IL_006e: Unknown result type (might be due to invalid IL or missing references) //IL_0079: 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_0083: 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_00a6: Unknown result type (might be due to invalid IL or missing references) //IL_00ab: Unknown result type (might be due to invalid IL or missing references) //IL_00b4: 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_00bb: Unknown result type (might be due to invalid IL or missing references) //IL_00bd: Unknown result type (might be due to invalid IL or missing references) //IL_00f5: 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_00fb: Unknown result type (might be due to invalid IL or missing references) //IL_0100: Unknown result type (might be due to invalid IL or missing references) FieldInfo playerVelField = ShotgunBuckshotPatch._playerVelField; if (playerVelField == null) { Object.Destroy((Object)(object)((Component)this).gameObject); return; } ENT_Player playerObject = ENT_Player.playerObject; if ((Object)(object)playerObject == (Object)null) { Object.Destroy((Object)(object)((Component)this).gameObject); return; } float deltaTime = Time.deltaTime; if (deltaTime <= 0f) { return; } _t += deltaTime; if (_t >= duration) { Object.Destroy((Object)(object)((Component)this).gameObject); return; } Vector3 val = target - ((Component)playerObject).transform.position; float magnitude = ((Vector3)(ref val)).magnitude; if (magnitude <= arriveDist) { Object.Destroy((Object)(object)((Component)this).gameObject); return; } Vector3 val2 = val / magnitude; try { Vector3 val3 = (Vector3)playerVelField.GetValue(playerObject); float num = Vector3.Dot(val3, val2); float num2 = Mathf.Max(0f, totalSpeed - num); float num3 = Mathf.Min(totalSpeed * deltaTime / duration, num2); playerVelField.SetValue(playerObject, val3 + val2 * num3); } catch (Exception ex) { ManualLogSource log = Plugin.Log; if (log != null) { log.LogWarning((object)("[PlayerPull] vel apply failed: " + ex.Message)); } Object.Destroy((Object)(object)((Component)this).gameObject); } } } public class SparkBillboard : MonoBehaviour { private void LateUpdate() { //IL_001b: Unknown result type (might be due to invalid IL or missing references) Camera main = Camera.main; if ((Object)(object)main != (Object)null) { ((Component)this).transform.rotation = ((Component)main).transform.rotation; } } } public static class HitPrintHelper { private static Sprite _printSprite; private static Sprite GetPrintSprite() { //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_0023: 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_0030: Unknown result type (might be due to invalid IL or missing references) //IL_004a: Unknown result type (might be due to invalid IL or missing references) //IL_0059: Unknown result type (might be due to invalid IL or missing references) //IL_0068: Expected O, but got Unknown if ((Object)(object)_printSprite != (Object)null) { return _printSprite; } Texture2D val = new Texture2D(1, 1, (TextureFormat)4, false) { filterMode = (FilterMode)0 }; val.SetPixel(0, 0, Color.white); val.Apply(); _printSprite = Sprite.Create(val, new Rect(0f, 0f, 1f, 1f), new Vector2(0.5f, 0.5f), 1f); return _printSprite; } public static void SpawnPrint(Vector3 point, Vector3 normal, float scale = 0.08f, Color? fromColor = null, Color? toColor = null) { //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_0010: Unknown result type (might be due to invalid IL or missing references) //IL_0011: Unknown result type (might be due to invalid IL or missing references) //IL_0017: Unknown result type (might be due to invalid IL or missing references) //IL_001c: 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_002c: Unknown result type (might be due to invalid IL or missing references) //IL_002d: Unknown result type (might be due to invalid IL or missing references) //IL_0032: 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_0042: 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_0052: Unknown result type (might be due to invalid IL or missing references) //IL_008b: 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_0090: Unknown result type (might be due to invalid IL or missing references) //IL_0092: 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_00a6: Unknown result type (might be due to invalid IL or missing references) //IL_00d4: Unknown result type (might be due to invalid IL or missing references) //IL_00cb: Unknown result type (might be due to invalid IL or missing references) //IL_00d9: Unknown result type (might be due to invalid IL or missing references) GameObject val = new GameObject("ShotgunHitPrint"); val.transform.position = point + normal * 0.01f; val.transform.rotation = Quaternion.LookRotation(-normal); val.transform.localScale = Vector3.one * scale; SpriteRenderer obj = val.AddComponent(); obj.sprite = GetPrintSprite(); Color from = (obj.color = (Color)(((??)fromColor) ?? new Color(1f, 0.85f, 0.2f, 1f))); ((Renderer)obj).sortingOrder = 90; HitPrintFader hitPrintFader = val.AddComponent(); hitPrintFader.From = from; hitPrintFader.To = (Color)(((??)toColor) ?? new Color(0f, 0f, 0f, 1f)); } } public class HitPrintFader : MonoBehaviour { private const float Duration = 4f; private float _t; private SpriteRenderer _sr; public Color From = new Color(1f, 0.85f, 0.2f, 1f); public Color To = new Color(0f, 0f, 0f, 1f); private void Start() { _sr = ((Component)this).GetComponent(); } private void Update() { //IL_0039: Unknown result type (might be due to invalid IL or missing references) //IL_003f: Unknown result type (might be due to invalid IL or missing references) //IL_0045: Unknown result type (might be due to invalid IL or missing references) _t += Time.deltaTime; if ((Object)(object)_sr != (Object)null) { float num = Mathf.Clamp01(_t / 4f); _sr.color = Color.Lerp(From, To, num); } if (_t >= 4f) { Object.Destroy((Object)(object)((Component)this).gameObject); } } } public class MuzzleFlashFader : MonoBehaviour { private float _t; private const float Duration = 0.12f; private Image _img; private void Start() { _img = ((Component)this).GetComponentInChildren(); } private void Update() { //IL_0042: Unknown result type (might be due to invalid IL or missing references) //IL_0047: Unknown result type (might be due to invalid IL or missing references) //IL_0056: Unknown result type (might be due to invalid IL or missing references) _t += Time.deltaTime; if ((Object)(object)_img != (Object)null) { float a = Mathf.Lerp(0.35f, 0f, _t / 0.12f); Color color = ((Graphic)_img).color; color.a = a; ((Graphic)_img).color = color; } if (_t >= 0.12f) { Object.Destroy((Object)(object)((Component)this).gameObject); } } } [HarmonyPatch(typeof(UT_AudioClipHandler), "PlaySound", new Type[] { typeof(string) })] public static class ShotgunSoundPatch { [HarmonyPrefix] public static bool Prefix(UT_AudioClipHandler __instance, string sound) { HandItem_Shoot component = ((Component)__instance).GetComponent(); if ((Object)(object)component == (Object)null || ((HandItem)component).item == null || ((HandItem)component).item.itemTag != "shotgun") { return true; } ((Component)__instance).GetComponent(); AudioClip val = null; bool flag = false; switch (sound) { case "item:use": flag = true; break; case "item:noAmmo": val = Plugin.ShotgunDryFireClip; break; case "item:reload": case "item:reloadtwohand": val = Plugin.ShotgunReloadSingleClip; break; } if (!flag && (Object)(object)val == (Object)null) { return true; } if ((Object)(object)val != (Object)null) { ShotgunModHandler.PlayGunSound(val); } return false; } } public static class WavLoader { public static AudioClip LoadFromFile(string path) { byte[] array = File.ReadAllBytes(path); if (array.Length < 44 || array[0] != 82 || array[1] != 73 || array[2] != 70 || array[3] != 70) { throw new Exception("Not a RIFF file"); } if (array[8] != 87 || array[9] != 65 || array[10] != 86 || array[11] != 69) { throw new Exception("Not a WAVE file"); } int i = 12; int num = 0; int num2 = 0; int num3 = 0; int num4 = -1; int num5 = -1; int num6; for (; i < array.Length - 8; i += 8 + num6) { string @string = Encoding.ASCII.GetString(array, i, 4); num6 = BitConverter.ToInt32(array, i + 4); if (@string == "fmt ") { num = BitConverter.ToInt16(array, i + 10); num2 = BitConverter.ToInt32(array, i + 12); num3 = BitConverter.ToInt16(array, i + 22); } else if (@string == "data") { num4 = i + 8; num5 = num6; break; } } if (num4 < 0) { throw new Exception("No data chunk found"); } int num7 = num3 / 8; int num8 = num5 / num7; float[] array2 = new float[num8]; switch (num3) { case 16: { for (int m = 0; m < num8; m++) { short num12 = BitConverter.ToInt16(array, num4 + m * 2); array2[m] = (float)num12 / 32768f; } break; } case 24: { for (int k = 0; k < num8; k++) { int num9 = array[num4 + k * 3]; int num10 = array[num4 + k * 3 + 1]; int num11 = ((sbyte)array[num4 + k * 3 + 2] << 16) | (num10 << 8) | num9; array2[k] = (float)num11 / 8388608f; } break; } case 32: { for (int l = 0; l < num8; l++) { array2[l] = BitConverter.ToSingle(array, num4 + l * 4); } break; } case 8: { for (int j = 0; j < num8; j++) { array2[j] = (float)(array[num4 + j] - 128) / 128f; } break; } default: throw new Exception($"Unsupported bit depth: {num3}"); } AudioClip obj = AudioClip.Create("shotgun_fire_custom", num8 / num, num, num2, false); obj.SetData(array2, 0); return obj; } } [HarmonyPatch(typeof(UT_EventController), "PlayEvent", new Type[] { typeof(string) })] public static class ShotgunEventPatch { [HarmonyPrefix] public static bool Prefix(UT_EventController __instance, string eventName) { if (((HandItem)(((Component)__instance).GetComponentInParent()?)).item?.itemTag != "shotgun") { return true; } if (eventName == "eject") { return false; } if (eventName == "shoot" && (Object)(object)Plugin.ShotgunFireClip != (Object)null) { ShotgunModHandler.PlayGunSound(Plugin.ShotgunFireClip, 0.55f); return false; } return true; } } [HarmonyPatch(typeof(HandItem_Shoot), "FinishReload")] [HarmonyPatch(typeof(UT_DamageTrigger), "Damage", new Type[] { typeof(Damageable) })] public static class DamageTriggerNullGuardPatch { [HarmonyPrefix] public static bool Prefix(Damageable damageable) { if (damageable == null) { return false; } try { GameObject gameObject = damageable.GetGameObject(); if ((Object)(object)gameObject == (Object)null) { return false; } if (!gameObject.activeInHierarchy) { return false; } } catch { return false; } return true; } } [HarmonyPatch(typeof(HandItem_Shoot), "FinishReload")] public static class ShotgunReloadPatch { internal static readonly Dictionary _pendingFirstShellType = new Dictionary(); [HarmonyPrefix] public static bool Prefix(HandItem_Shoot __instance) { if (((HandItem)(__instance?)).item?.itemTag != "shotgun") { return true; } int num = 1; string text = ""; if (_pendingFirstShellType.TryGetValue(__instance, out var value)) { text = value; _pendingFirstShellType.Remove(__instance); } string text2 = ""; if ((Object)(object)Inventory.instance != (Object)null && !string.IsNullOrEmpty(__instance.ammoTag)) { Inventory instance = Inventory.instance; List list = new List(); if (instance.itemHands != null) { ItemHand[] itemHands = instance.itemHands; foreach (ItemHand val in itemHands) { if (val?.currentItem != null && val.currentItem.HasTag(__instance.ammoTag)) { list.Add(val.currentItem); } } } if (instance.bagItems != null) { foreach (Item bagItem in instance.bagItems) { if (bagItem != null && bagItem.HasTag(__instance.ammoTag)) { list.Add(bagItem); } } } if (list.Count > 0) { Item obj = list[Random.Range(0, list.Count)]; text2 = Plugin.GetShellType(obj); obj.DestroyItem(); num = 2; } } __instance.Recharge(num); int ammo = __instance.GetAmmo(); if (((HandItem)__instance).item != null) { string type = ((ammo < 1) ? "" : ((!string.IsNullOrEmpty(text)) ? text : "buckshot")); string type2 = ((ammo < 2) ? "" : ((!string.IsNullOrEmpty(text2)) ? text2 : "buckshot")); Plugin.SetBarrelType(((HandItem)__instance).item, 0, type); Plugin.SetBarrelType(((HandItem)__instance).item, 1, type2); } FieldInfo usedField = AccessTools.Field(typeof(HandItem), "used"); Animator anim = default(Animator); ref Animator reference = ref anim; object? obj2 = AccessTools.Field(typeof(HandItem), "anim")?.GetValue(__instance); reference = (Animator)((obj2 is Animator) ? obj2 : null); Action finalize = delegate { if (usedField != null) { usedField.SetValue(__instance, false); } if ((Object)(object)anim != (Object)null && __instance.loadedAnimationState) { anim.SetBool("Loaded", __instance.GetAmmo() > 0); } UnityEvent reloadEvent = __instance.reloadEvent; if (reloadEvent != null) { reloadEvent.Invoke(); } }; if (num == 2 && (Object)(object)anim != (Object)null) { anim.speed = 0f; float delay = 0.6f; ShotgunModHandler.QueueDelayedAction(delegate { if ((Object)(object)anim != (Object)null) { anim.speed = 1f; } finalize(); }, delay); } else { if ((Object)(object)anim != (Object)null) { anim.speed = 1f; } finalize(); } object? obj3 = AccessTools.Field(typeof(HandItem_Shoot), "clipHandler")?.GetValue(__instance); UT_AudioClipHandler val2 = (UT_AudioClipHandler)((obj3 is UT_AudioClipHandler) ? obj3 : null); AudioSource src = (((Object)(object)val2 != (Object)null) ? ((Component)val2).GetComponent() : null); Transform transform = ((Component)__instance).transform; float delay2 = 0.1f; if (num == 2 && (Object)(object)Plugin.ShotgunReloadSingleClip != (Object)null) { ShotgunModHandler.QueueDelayedAudio(src, transform, Plugin.ShotgunReloadSingleClip, 0f); delay2 = 0.35f; } if ((Object)(object)Plugin.ShotgunBreakCloseClip != (Object)null) { ShotgunModHandler.QueueDelayedAudio(src, transform, Plugin.ShotgunBreakCloseClip, delay2); } return false; } } [HarmonyPatch(typeof(Item), "InitializeInHand")] public static class ShotgunEquipTimingPatch { private static bool _logged; private static Stopwatch _sw; private static string _what; [HarmonyPrefix] public static void Prefix(Item __instance) { if (!_logged && __instance != null && (!(__instance.itemTag != "shotgun") || !(__instance.itemTag != "shotgun_shell"))) { _sw = Stopwatch.StartNew(); _what = __instance.itemTag; } } [HarmonyPostfix] public static void Postfix(Item __instance) { if (!_logged && _sw != null && __instance != null && !(__instance.itemTag != _what)) { _sw.Stop(); _logged = true; ManualLogSource log = Plugin.Log; if (log != null) { log.LogInfo((object)$"[EquipTiming] Item.InitializeInHand (first {_what}) took {_sw.ElapsedMilliseconds}ms"); } } } } [HarmonyPatch(typeof(HandItem_Shoot), "Initialize")] public static class ShotgunMaxAmmoPatch { private static bool _initTimingLogged; private static Stopwatch _initWatch; [HarmonyPrefix] public static void Prefix(HandItem_Shoot __instance, Item i, Hand h) { if (i == null || i.itemTag != "shotgun") { return; } if (!_initTimingLogged) { _initWatch = Stopwatch.StartNew(); } string text = null; try { text = i.GetFirstDataStringByType("ammo", false); } catch { } if (string.IsNullOrEmpty(text)) { try { i.SetFirstDataStringsofType("ammo", "2"); } catch { } Plugin.SetBarrelType(i, 0, "buckshot"); Plugin.SetBarrelType(i, 1, "buckshot"); return; } int result = 0; int.TryParse(text, out result); int num = 0; if (!string.IsNullOrEmpty(Plugin.GetBarrelType(i, 0))) { num++; } if (!string.IsNullOrEmpty(Plugin.GetBarrelType(i, 1))) { num++; } int num2 = result - num; for (int j = 0; j < 2; j++) { if (num2 <= 0) { break; } if (string.IsNullOrEmpty(Plugin.GetBarrelType(i, j))) { Plugin.SetBarrelType(i, j, "buckshot"); num2--; } } } [HarmonyPostfix] public static void Postfix(HandItem_Shoot __instance, Item i, Hand h) { if (i == null || i.itemTag != "shotgun") { return; } __instance.maxAmmo = 2; if (!_initTimingLogged && _initWatch != null) { _initTimingLogged = true; _initWatch.Stop(); ManualLogSource log = Plugin.Log; if (log != null) { log.LogInfo((object)$"[EquipTiming] HandItem_Shoot.Initialize (shotgun, first) took {_initWatch.ElapsedMilliseconds}ms"); } } } } [HarmonyPatch(typeof(HandItem_Shoot), "StartShoot")] public static class ShotgunStartShootPatch { internal static readonly Dictionary _cooldownUntil = new Dictionary(); private const float ShotgunCooldown = 1f; [HarmonyPrefix] public static bool Prefix(HandItem_Shoot __instance, out bool __state) { __state = false; if (((HandItem)(__instance?)).item?.itemTag != "shotgun") { return true; } if (ShotgunModHandler.IsBrokenOpen(__instance)) { return false; } if (_cooldownUntil.TryGetValue(__instance, out var value) && Time.time < value) { return false; } FieldInfo fieldInfo = AccessTools.Field(typeof(HandItem), "used"); if (fieldInfo != null && (bool)fieldInfo.GetValue(__instance)) { return true; } if (__instance.GetAmmo() <= 0) { Inventory instance = Inventory.instance; if ((Object)(object)instance != (Object)null && !string.IsNullOrEmpty(__instance.ammoTag)) { List list = new List(); if (instance.itemHands != null) { ItemHand[] itemHands = instance.itemHands; foreach (ItemHand val in itemHands) { if (val?.currentItem != null && val.currentItem.HasTag(__instance.ammoTag)) { list.Add(val.currentItem); } } } if (instance.bagItems != null) { foreach (Item bagItem in instance.bagItems) { if (bagItem != null && bagItem.HasTag(__instance.ammoTag)) { list.Add(bagItem); } } } if (list.Count > 0) { Item val2 = list[Random.Range(0, list.Count)]; ShotgunReloadPatch._pendingFirstShellType[__instance] = Plugin.GetShellType(val2); val2.DestroyItem(); __instance.StartReload(); return false; } } ShotgunReloadPatch._pendingFirstShellType[__instance] = ""; return true; } __state = true; _cooldownUntil[__instance] = Time.time + 1f; return true; } [HarmonyPostfix] public static void Postfix(HandItem_Shoot __instance, bool __state) { if (__state) { ShotgunModHandler.RecordShotTime(__instance); ShotgunBuckshotPatch._pendingBuckshotAt[__instance] = Time.time; } } } [DefaultExecutionOrder(-100)] public class ShotgunModHandler : MonoBehaviour { private struct ShellEjectCache { public Transform Anchor; public ParticleSystem Ps; public int BodyLayerId; public int MaxBodyOrder; } private class CachedHandItemLists { public HandItem HandItem; public readonly List SpriteRenderers = new List(16); public readonly List HandSpriteControllers = new List(4); } public class ReloadTrayFollower : MonoBehaviour { public Vector3 WorldOffsetFromPlayer; private void LateUpdate() { //IL_001c: Unknown result type (might be due to invalid IL or missing references) //IL_0022: Unknown result type (might be due to invalid IL or missing references) //IL_0027: Unknown result type (might be due to invalid IL or missing references) //IL_0046: Unknown result type (might be due to invalid IL or missing references) //IL_0051: Unknown result type (might be due to invalid IL or missing references) //IL_0056: Unknown result type (might be due to invalid IL or missing references) //IL_005b: Unknown result type (might be due to invalid IL or missing references) //IL_0070: Unknown result type (might be due to invalid IL or missing references) //IL_0071: Unknown result type (might be due to invalid IL or missing references) ENT_Player playerObject = ENT_Player.playerObject; if ((Object)(object)playerObject == (Object)null) { return; } ((Component)this).transform.position = ((Component)playerObject).transform.position + WorldOffsetFromPlayer; Camera main = Camera.main; if ((Object)(object)main != (Object)null) { Vector3 val = ((Component)this).transform.position - ((Component)main).transform.position; if (((Vector3)(ref val)).sqrMagnitude > 0.0001f) { ((Component)this).transform.rotation = Quaternion.LookRotation(val); } } } } public class ReloadSlot : MonoBehaviour { public HandItem_Shoot Shotgun; public int BarrelIndex; public SpriteRenderer Bg; public Color BgBaseColor; public bool IsHovered; } [CompilerGenerated] private sealed class d__42 : IEnumerator, IEnumerator, IDisposable { private int <>1__state; private object <>2__current; private int 5__2; object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public d__42(int <>1__state) { this.<>1__state = <>1__state; } [DebuggerHidden] void IDisposable.Dispose() { <>1__state = -2; } private bool MoveNext() { int num = <>1__state; if (num != 0) { if (num != 1) { return false; } <>1__state = -1; } else { <>1__state = -1; if (_startupWarmupDone) { return false; } 5__2 = 0; } GameObject val = null; try { val = CL_AssetManager.GetAssetGameObject("Item_Flaregun", ""); } catch { } if (!((Object)(object)val != (Object)null)) { 5__2++; <>2__current = null; <>1__state = 1; return true; } try { Plugin.EnsureShotgunHandItemTemplate(); } catch { } try { Plugin.EnsureShellHandItemTemplate(); } catch { } if ((Object)(object)Plugin.ShotgunHandItemTemplate == (Object)null || (Object)(object)Plugin.ShellHandItemTemplate == (Object)null) { ManualLogSource log = Plugin.Log; if (log != null) { log.LogWarning((object)$"[Shotgun] Template build failed after flare became available (waited {5__2} frames) — equip lag may persist."); } } else { ManualLogSource log2 = Plugin.Log; if (log2 != null) { log2.LogInfo((object)$"[Shotgun] HandItem templates resolved after {5__2} frames — running deep warmup"); } } DoStartupWarmup(); return false; } bool IEnumerator.MoveNext() { //ILSpy generated this explicit interface implementation from .override directive in MoveNext return this.MoveNext(); } [DebuggerHidden] void IEnumerator.Reset() { throw new NotSupportedException(); } } private static readonly List<(float time, HandItem_Shoot target, bool loaded)> _pendingSnapBacks = new List<(float, HandItem_Shoot, bool)>(); private static readonly List<(float time, HandItem_Shoot target)> _pendingAudioRestores = new List<(float, HandItem_Shoot)>(); private static readonly List<(float time, AudioSource src, Transform xform, AudioClip clip)> _pendingAudio = new List<(float, AudioSource, Transform, AudioClip)>(); private static readonly List<(float time, HandItem_Shoot hi, int count)> _pendingShellEjects = new List<(float, HandItem_Shoot, int)>(); private static readonly Dictionary _ejectCache = new Dictionary(); private static AudioSource _followSource; private static readonly List<(float time, Action action)> _pendingActions = new List<(float, Action)>(); internal static Sprite _targetForegroundHand; internal static Sprite _targetBackgroundHand; internal static Sprite _targetForegroundHandDefault; internal static Sprite _targetBackgroundHandDefault; private static int _handSpriteLookupAttempts; private static Dictionary _weaponBaseline = new Dictionary(); private static readonly Dictionary _handItemListCache = new Dictionary(); private static readonly Dictionary _ownAtlasCache = new Dictionary(); private static Dictionary _lastShotTime = new Dictionary(); private static bool _startupWarmupDone; private static readonly HashSet _openShotguns = new HashSet(); private static readonly Dictionary _openTrays = new Dictionary(); private static GameObject _reloadVignette; public const float ReloadLookAwayThresholdDeg = 75f; public const float BreakOpenCloseCooldownSec = 0.5f; private static float _lastBreakOpenCloseTime = -10f; private const float SlotHoverColorMultiplier = 1.4f; private static ReloadSlot _hoveredSlot; private static readonly FieldInfo _handItemShootAmmoField = AccessTools.Field(typeof(HandItem_Shoot), "ammo"); private static readonly string[] ShellCycleOrder = new string[6] { "buckshot", "slug", "dragon", "blank", "reverse", "rebar" }; private static readonly HashSet _pendingHalo = new HashSet(); private void Start() { ((MonoBehaviour)this).StartCoroutine(StartupWarmupCoroutine()); } public static void QueueSnapBack(HandItem_Shoot instance, float delay, bool loaded = true) { _pendingSnapBacks.Add((Time.time + delay, instance, loaded)); } public static void QueueAudioRestore(HandItem_Shoot instance, float delay) { _pendingAudioRestores.Add((Time.time + delay, instance)); } public static void QueueDelayedAudio(AudioSource src, Transform xform, AudioClip clip, float delay) { if (!((Object)(object)clip == (Object)null)) { _pendingAudio.Add((Time.time + delay, src, xform, clip)); } } public static void QueueShellEject(HandItem_Shoot hi, float delay, int count) { if (!((Object)(object)hi == (Object)null) && count > 0) { _pendingShellEjects.Add((Time.time + delay, hi, count)); } } private static bool TryGetEjectCache(HandItem_Shoot hi, out ShellEjectCache cache) { if ((Object)(object)hi == (Object)null) { cache = default(ShellEjectCache); return false; } if (_ejectCache.TryGetValue(hi, out cache) && (Object)(object)cache.Anchor != (Object)null) { return true; } cache = default(ShellEjectCache); Transform[] componentsInChildren = ((Component)hi).GetComponentsInChildren(true); foreach (Transform val in componentsInChildren) { if ((Object)(object)val != (Object)null && ((Object)val).name == "Effect_Eject") { cache.Anchor = val; cache.Ps = ((Component)val).GetComponent(); break; } } if ((Object)(object)cache.Anchor == (Object)null || (Object)(object)cache.Ps == (Object)null) { ManualLogSource log = Plugin.Log; if (log != null) { log.LogWarning((object)"[ShellEject] Effect_Eject not found on HandItem"); } return false; } int bodyLayerId = 0; int num = 0; SpriteRenderer[] componentsInChildren2 = ((Component)hi).GetComponentsInChildren(true); foreach (SpriteRenderer val2 in componentsInChildren2) { if ((Object)(object)val2 == (Object)null || (Object)(object)((Component)val2).GetComponent() != (Object)null) { continue; } if ((Object)(object)val2.sprite != (Object)null) { string name = ((Object)val2.sprite).name; if (name.StartsWith("HND_F") || name.StartsWith("HND_B")) { continue; } } if (((Renderer)val2).sortingOrder >= num) { num = ((Renderer)val2).sortingOrder; bodyLayerId = ((Renderer)val2).sortingLayerID; } } cache.BodyLayerId = bodyLayerId; cache.MaxBodyOrder = num; _ejectCache[hi] = cache; return true; } private void ProcessShellEjects() { //IL_0076: Unknown result type (might be due to invalid IL or missing references) //IL_007b: Unknown result type (might be due to invalid IL or missing references) //IL_0080: 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) if (_pendingShellEjects.Count == 0) { return; } Vector3 perShellOffset = default(Vector3); for (int num = _pendingShellEjects.Count - 1; num >= 0; num--) { (float, HandItem_Shoot, int) tuple = _pendingShellEjects[num]; if (!(Time.time < tuple.Item1)) { _pendingShellEjects.RemoveAt(num); if (!((Object)(object)tuple.Item2 == (Object)null) && TryGetEjectCache(tuple.Item2, out var cache)) { if (Plugin.ShellEjectAnchorBaseCaptured) { cache.Anchor.localPosition = Plugin.ShellEjectAnchorBaseLocal + Plugin.ShellEjectAnchorOffset; } ShotgunBuckshotPatch._recentFiredTypes.TryGetValue(tuple.Item2, out var value); bool ejectLeft = ((Hand_Base)tuple.Item2).hand != null && ((Hand_Base)tuple.Item2).hand.id == 0; for (int i = 0; i < tuple.Item3; i++) { string type = ""; if (value != null && value.Count > 0) { type = value.Dequeue(); } Sprite[] shellEjectedFramesForType = Plugin.GetShellEjectedFramesForType(type); ((Vector3)(ref perShellOffset))..ctor(0f, (i == 0) ? 0.03f : (-0.03f), 0f); SpawnEjectOverlay(cache.Anchor, cache.BodyLayerId, cache.MaxBodyOrder + 100, ejectLeft, perShellOffset, shellEjectedFramesForType); } } } } } private static void SpawnEjectOverlay(Transform anchor, int sortingLayerId, int sortingOrder, bool ejectLeft, Vector3 perShellOffset, Sprite[] frames = null) { //IL_001a: Unknown result type (might be due to invalid IL or missing references) //IL_002a: Unknown result type (might be due to invalid IL or missing references) //IL_0054: 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_006f: Unknown result type (might be due to invalid IL or missing references) //IL_0062: Unknown result type (might be due to invalid IL or missing references) //IL_0074: Unknown result type (might be due to invalid IL or missing references) //IL_008b: 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_0090: Unknown result type (might be due to invalid IL or missing references) //IL_0091: Unknown result type (might be due to invalid IL or missing references) //IL_0098: Unknown result type (might be due to invalid IL or missing references) //IL_009d: Unknown result type (might be due to invalid IL or missing references) //IL_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_00aa: Unknown result type (might be due to invalid IL or missing references) //IL_00af: 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_00bc: Unknown result type (might be due to invalid IL or missing references) //IL_00c1: Unknown result type (might be due to invalid IL or missing references) //IL_00c3: Unknown result type (might be due to invalid IL or missing references) //IL_00ca: Unknown result type (might be due to invalid IL or missing references) //IL_00cf: Unknown result type (might be due to invalid IL or missing references) //IL_00d1: Unknown result type (might be due to invalid IL or missing references) //IL_00db: 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_00eb: 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_00fb: Unknown result type (might be due to invalid IL or missing references) //IL_0105: Unknown result type (might be due to invalid IL or missing references) //IL_018e: Unknown result type (might be due to invalid IL or missing references) //IL_0180: Unknown result type (might be due to invalid IL or missing references) //IL_0193: Unknown result type (might be due to invalid IL or missing references) //IL_01ad: Unknown result type (might be due to invalid IL or missing references) //IL_019f: 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_01cc: Unknown result type (might be due to invalid IL or missing references) //IL_01be: Unknown result type (might be due to invalid IL or missing references) //IL_01d1: Unknown result type (might be due to invalid IL or missing references) //IL_01e5: Unknown result type (might be due to invalid IL or missing references) //IL_01f6: Unknown result type (might be due to invalid IL or missing references) //IL_01fd: Unknown result type (might be due to invalid IL or missing references) //IL_0202: Unknown result type (might be due to invalid IL or missing references) //IL_0213: Unknown result type (might be due to invalid IL or missing references) //IL_0218: Unknown result type (might be due to invalid IL or missing references) //IL_021d: Unknown result type (might be due to invalid IL or missing references) //IL_022e: Unknown result type (might be due to invalid IL or missing references) //IL_0233: Unknown result type (might be due to invalid IL or missing references) //IL_0238: Unknown result type (might be due to invalid IL or missing references) //IL_023e: Unknown result type (might be due to invalid IL or missing references) //IL_0240: Unknown result type (might be due to invalid IL or missing references) //IL_0245: Unknown result type (might be due to invalid IL or missing references) if (frames == null) { frames = Plugin.ShellEjectedFrames; } if (frames != null && frames.Length != 0) { GameObject val = new GameObject("ShotgunMod_EjectOverlay"); int num = LayerMask.NameToLayer("Player"); val.layer = ((num >= 0) ? num : 8); Camera main = Camera.main; Vector3 val2 = (((Object)(object)main != (Object)null) ? ((Component)main).transform.right : Vector3.right); Vector3 val3 = (((Object)(object)main != (Object)null) ? ((Component)main).transform.up : Vector3.up); Vector3 val4 = (((Object)(object)main != (Object)null) ? ((Component)main).transform.forward : Vector3.forward); Vector3 val5 = val2 * perShellOffset.x + val3 * perShellOffset.y + val4 * perShellOffset.z; val.transform.position = anchor.position + val5; val.transform.rotation = Quaternion.identity; val.transform.localScale = Vector3.one * 0.4f; SpriteRenderer obj = val.AddComponent(); obj.sprite = frames[0]; ((Renderer)obj).sortingLayerID = sortingLayerId; ((Renderer)obj).sortingOrder = sortingOrder; EjectedShell ejectedShell = val.AddComponent(); ejectedShell.frames = frames; ejectedShell.lifetime = 1f; ejectedShell.spinSpeedDeg = Random.Range(360f, 720f) * ((Random.value < 0.5f) ? (-1f) : 1f); ejectedShell.useLocalSpace = false; Camera main2 = Camera.main; Vector3 val6 = (((Object)(object)main2 != (Object)null) ? ((Component)main2).transform.right : Vector3.right); Vector3 val7 = (((Object)(object)main2 != (Object)null) ? ((Component)main2).transform.up : Vector3.up); Vector3 val8 = (((Object)(object)main2 != (Object)null) ? ((Component)main2).transform.forward : Vector3.forward); float num2 = (ejectLeft ? (-1f) : 1f); ejectedShell.velocity = val6 * Random.Range(2f, 3f) * num2 + val7 * Random.Range(-0.2f, 0.3f) + val8 * Random.Range(-0.2f, 0.2f); ejectedShell.gravityDir = -val7; ejectedShell.gravityAccel = 6f; } } public static AudioSource GetFollowSource() { //IL_0029: Unknown result type (might be due to invalid IL or missing references) //IL_002e: Unknown result type (might be due to invalid IL or missing references) //IL_0040: Unknown result type (might be due to invalid IL or missing references) //IL_0046: Unknown result type (might be due to invalid IL or missing references) //IL_0050: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)_followSource != (Object)null) { return _followSource; } Camera main = Camera.main; if ((Object)(object)main == (Object)null) { return null; } GameObject val = new GameObject("ShotgunMod_2DAudio"); val.transform.SetParent(((Component)main).transform, false); val.transform.localPosition = Vector3.zero; ((Object)val).hideFlags = (HideFlags)61; AudioSource obj = val.AddComponent(); obj.spatialBlend = 0f; obj.playOnAwake = false; obj.volume = 1f; _followSource = obj; return obj; } public static void PlayGunSound(AudioClip clip, float volume = 1f) { //IL_0041: Unknown result type (might be due to invalid IL or missing references) //IL_0030: Unknown result type (might be due to invalid IL or missing references) if (!((Object)(object)clip == (Object)null)) { AudioSource followSource = GetFollowSource(); if ((Object)(object)followSource != (Object)null) { followSource.PlayOneShot(clip, volume); } else { AudioSource.PlayClipAtPoint(clip, ((Object)(object)Camera.main != (Object)null) ? ((Component)Camera.main).transform.position : Vector3.zero, volume); } } } public static void QueueDelayedAction(Action action, float delay) { if (action != null) { _pendingActions.Add((Time.time + delay, action)); } } private void OverrideShotgunSpriteIfLoaded() { //IL_01d0: Unknown result type (might be due to invalid IL or missing references) //IL_01dc: Unknown result type (might be due to invalid IL or missing references) //IL_020a: Unknown result type (might be due to invalid IL or missing references) //IL_021d: Unknown result type (might be due to invalid IL or missing references) ENT_Player playerObject = ENT_Player.playerObject; if ((Object)(object)playerObject == (Object)null || playerObject.hands == null) { return; } Hand[] hands = playerObject.hands; foreach (Hand val in hands) { if (val == null) { continue; } HandItem handItem = val.GetHandItem(); HandItem_Shoot val2 = (HandItem_Shoot)(object)((handItem is HandItem_Shoot) ? handItem : null); if ((Object)(object)val2 == (Object)null || ((HandItem)val2).item == null || ((HandItem)val2).item.itemTag != "shotgun") { continue; } float value; float num = (_lastShotTime.TryGetValue(val2, out value) ? (Time.time - value) : float.MaxValue); bool flag = num < 0.25f; bool flag2 = num >= 0.25f && num < 0.55f; Sprite val3 = (IsBrokenOpen(val2) ? Plugin.SpriteEmpty : (flag2 ? Plugin.SpriteRecoil : (flag ? Plugin.SpriteLoaded : ((val2.GetAmmo() > 0) ? Plugin.SpriteLoaded : Plugin.SpriteEmpty)))); if ((Object)(object)val3 == (Object)null) { continue; } List spriteRenderers = GetHandItemLists((HandItem)(object)val2).SpriteRenderers; for (int j = 0; j < spriteRenderers.Count; j++) { SpriteRenderer val4 = spriteRenderers[j]; if (!((Object)(object)val4 == (Object)null) && ((Object)((Component)val4).gameObject).name == "Item_Hands_Flaregun" && (Object)(object)((Component)val4).transform.parent != (Object)null && ((Object)((Component)val4).transform.parent).name == "Root_Placement") { if ((Object)(object)val4.sprite != (Object)(object)val3) { val4.sprite = val3; } bool flag3 = num >= 0.55f && num < 1.5f; (Vector3, Quaternion) value2; if (num > 2f) { _weaponBaseline[val4] = (((Component)val4).transform.localPosition, ((Component)val4).transform.localRotation); } else if (flag3 && _weaponBaseline.TryGetValue(val4, out value2)) { ((Component)val4).transform.localPosition = value2.Item1; ((Component)val4).transform.localRotation = value2.Item2; } } } } } private void OverrideShotgunHandSpritesIfLoaded() { ENT_Player playerObject = ENT_Player.playerObject; if ((Object)(object)playerObject == (Object)null || playerObject.hands == null) { return; } if (_handSpriteLookupAttempts < 60) { _handSpriteLookupAttempts++; if ((Object)(object)_targetForegroundHand == (Object)null) { _targetForegroundHand = LoadHandSpriteFromOwnPng("Hands_Foreground_Library_03.png", "HND_F3D1"); } if ((Object)(object)_targetBackgroundHand == (Object)null) { _targetBackgroundHand = LoadHandSpriteFromOwnPng("Hands_Background_Library_03.png", "HND_B3D1"); } if ((Object)(object)_targetForegroundHandDefault == (Object)null) { _targetForegroundHandDefault = _targetForegroundHand; } if ((Object)(object)_targetBackgroundHandDefault == (Object)null) { _targetBackgroundHandDefault = _targetBackgroundHand; } } if ((Object)(object)_targetForegroundHand == (Object)null && (Object)(object)_targetBackgroundHand == (Object)null && (Object)(object)_targetForegroundHandDefault == (Object)null && (Object)(object)_targetBackgroundHandDefault == (Object)null) { return; } for (int i = 0; i < playerObject.hands.Length; i++) { Hand val = playerObject.hands[i]; if (val == null) { continue; } HandItem handItem = val.GetHandItem(); HandItem_Shoot val2 = (HandItem_Shoot)(object)((handItem is HandItem_Shoot) ? handItem : null); if ((Object)(object)val2 == (Object)null || ((HandItem)val2).item == null || ((HandItem)val2).item.itemTag != "shotgun") { continue; } Sprite targetForegroundHand = _targetForegroundHand; Sprite targetBackgroundHand = _targetBackgroundHand; if ((Object)(object)targetForegroundHand == (Object)null && (Object)(object)targetBackgroundHand == (Object)null) { continue; } List handSpriteControllers = GetHandItemLists((HandItem)(object)val2).HandSpriteControllers; for (int j = 0; j < handSpriteControllers.Count; j++) { Hand_SpriteController val3 = handSpriteControllers[j]; if ((Object)(object)val3 == (Object)null) { continue; } SpriteRenderer component = ((Component)val3).GetComponent(); if (!((Object)(object)component == (Object)null) && !((Object)(object)component.sprite == (Object)null)) { string name = ((Object)component.sprite).name; Sprite val4 = null; if (name.StartsWith("HND_F") && (Object)(object)targetForegroundHand != (Object)null) { val4 = targetForegroundHand; } else if (name.StartsWith("HND_B") && (Object)(object)targetBackgroundHand != (Object)null) { val4 = targetBackgroundHand; } if ((Object)(object)val4 != (Object)null && (Object)(object)component.sprite != (Object)(object)val4) { component.sprite = val4; } } } } } private void ProcessBuckshotFallback() { if (ShotgunBuckshotPatch._pendingBuckshotAt.Count == 0) { return; } List list = new List(); foreach (KeyValuePair item in ShotgunBuckshotPatch._pendingBuckshotAt) { if (Time.time - item.Value > 0.3f) { list.Add(item.Key); } } foreach (HandItem_Shoot item2 in list) { ShotgunBuckshotPatch._pendingBuckshotAt.Remove(item2); if (!((Object)(object)item2 == (Object)null)) { ManualLogSource log = Plugin.Log; if (log != null) { log.LogWarning((object)"[ShotgunBuckshotPatch] Shoot() animation event missed — firing buckshot via fallback."); } ShotgunBuckshotPatch.FireBuckshotOnce(item2); bool flag = item2.GetAmmo() > 0; QueueSnapBack(item2, 0.7f, flag); if (!flag && (Object)(object)Plugin.ShotgunBreakOpenClip != (Object)null) { object? obj = AccessTools.Field(typeof(HandItem_Shoot), "clipHandler")?.GetValue(item2); UT_AudioClipHandler val = (UT_AudioClipHandler)((obj is UT_AudioClipHandler) ? obj : null); QueueDelayedAudio(((Object)(object)val != (Object)null) ? ((Component)val).GetComponent() : null, ((Component)item2).transform, Plugin.ShotgunBreakOpenClip, 0.2f); } } } } private void ProcessSnapBacks() { for (int num = _pendingSnapBacks.Count - 1; num >= 0; num--) { if (Time.time >= _pendingSnapBacks[num].time) { HandItem_Shoot item = _pendingSnapBacks[num].target; bool item2 = _pendingSnapBacks[num].loaded; _pendingSnapBacks.RemoveAt(num); if (!((Object)(object)item == (Object)null)) { try { object? obj = AccessTools.Field(typeof(HandItem), "anim")?.GetValue(item); Animator val = (Animator)((obj is Animator) ? obj : null); if ((Object)(object)val != (Object)null) { val.SetBool("Loaded", item2); val.Play(item2 ? "Item_Flaregun_Idle_loaded" : "Item_Flaregun_Idle", 0, 0f); val.Update(0f); } item.ResetUsedState(); } catch (Exception ex) { ManualLogSource log = Plugin.Log; if (log != null) { log.LogWarning((object)("Snap-back failed: " + ex.Message)); } } } } } for (int num2 = _pendingActions.Count - 1; num2 >= 0; num2--) { if (Time.time >= _pendingActions[num2].time) { Action item3 = _pendingActions[num2].action; _pendingActions.RemoveAt(num2); try { item3?.Invoke(); } catch (Exception ex2) { ManualLogSource log2 = Plugin.Log; if (log2 != null) { log2.LogWarning((object)("Queued action failed: " + ex2.Message)); } } } } for (int num3 = _pendingAudio.Count - 1; num3 >= 0; num3--) { if (Time.time >= _pendingAudio[num3].time) { (float, AudioSource, Transform, AudioClip) tuple = _pendingAudio[num3]; _pendingAudio.RemoveAt(num3); if (!((Object)(object)tuple.Item4 == (Object)null)) { try { PlayGunSound(tuple.Item4); } catch (Exception ex3) { ManualLogSource log3 = Plugin.Log; if (log3 != null) { log3.LogWarning((object)("Queued audio play failed: " + ex3.Message)); } } } } } for (int num4 = _pendingAudioRestores.Count - 1; num4 >= 0; num4--) { if (Time.time >= _pendingAudioRestores[num4].time) { HandItem_Shoot item4 = _pendingAudioRestores[num4].target; _pendingAudioRestores.RemoveAt(num4); if (!((Object)(object)item4 == (Object)null)) { try { AudioSource[] componentsInChildren = ((Component)item4).GetComponentsInChildren(true); foreach (AudioSource val2 in componentsInChildren) { if ((Object)(object)val2 != (Object)null) { val2.volume = 1f; } } } catch { } } } } } private static CachedHandItemLists GetHandItemLists(HandItem hi) { int instanceID = ((Object)hi).GetInstanceID(); if (_handItemListCache.TryGetValue(instanceID, out var value) && (Object)(object)value.HandItem == (Object)(object)hi) { return value; } value = new CachedHandItemLists { HandItem = hi }; ((Component)hi).GetComponentsInChildren(true, value.SpriteRenderers); ((Component)hi).GetComponentsInChildren(true, value.HandSpriteControllers); _handItemListCache[instanceID] = value; if (_handItemListCache.Count > 16) { PruneHandItemListCache(); } return value; } private static void PruneHandItemListCache() { List list = null; foreach (KeyValuePair item in _handItemListCache) { if ((Object)(object)item.Value.HandItem == (Object)null) { (list ?? (list = new List())).Add(item.Key); } } if (list == null) { return; } foreach (int item2 in list) { _handItemListCache.Remove(item2); } } private static Sprite FindLoadedSpriteByName(string name) { Sprite[] array = Resources.FindObjectsOfTypeAll(); Sprite val = null; Sprite[] array2 = array; foreach (Sprite val2 in array2) { if (!((Object)(object)val2 == (Object)null) && !(((Object)val2).name != name)) { if ((Object)(object)val2.texture != (Object)null) { return val2; } val = val ?? val2; } } return val; } internal static Sprite LoadHandSpriteFromOwnPng(string pngFilename, string spriteName) { //IL_00d4: Unknown result type (might be due to invalid IL or missing references) //IL_00d5: Unknown result type (might be due to invalid IL or missing references) //IL_0063: Unknown result type (might be due to invalid IL or missing references) //IL_0069: Expected O, but got Unknown try { if (!_ownAtlasCache.TryGetValue(pngFilename, out var value)) { string text = Path.Combine(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location), pngFilename); if (!File.Exists(text)) { ManualLogSource log = Plugin.Log; if (log != null) { log.LogWarning((object)("[OwnAtlas] PNG not found at " + text)); } return null; } byte[] array = File.ReadAllBytes(text); value = new Texture2D(2, 2, (TextureFormat)4, false); ImageConversion.LoadImage(value, array); ((Texture)value).filterMode = (FilterMode)0; ((Texture)value).wrapMode = (TextureWrapMode)1; ((Object)value).name = pngFilename; _ownAtlasCache[pngFilename] = value; } float num = (float)((Texture)value).width / 4f; float num2 = (float)((Texture)value).height / 4f; Rect val = default(Rect); ((Rect)(ref val))..ctor(0f, 0f, num, num2); Vector2 val2 = default(Vector2); ((Vector2)(ref val2))..ctor(0.5f, 0.5f); Sprite obj = Sprite.Create(value, val, val2, 100f, 0u, (SpriteMeshType)0); ((Object)obj).name = spriteName; return obj; } catch (Exception ex) { ManualLogSource log2 = Plugin.Log; if (log2 != null) { log2.LogWarning((object)("[OwnAtlas] failed for " + pngFilename + ": " + ex.Message)); } return null; } } private static Sprite BuildCustomD1Sprite(string atlasTexName, string referenceCellSpriteName) { //IL_0073: Unknown result type (might be due to invalid IL or missing references) //IL_0078: 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_00d2: Unknown result type (might be due to invalid IL or missing references) //IL_00df: Unknown result type (might be due to invalid IL or missing references) //IL_00ec: Unknown result type (might be due to invalid IL or missing references) //IL_00c0: Unknown result type (might be due to invalid IL or missing references) //IL_0102: Unknown result type (might be due to invalid IL or missing references) //IL_0105: Unknown result type (might be due to invalid IL or missing references) //IL_0107: Unknown result type (might be due to invalid IL or missing references) //IL_00fd: Unknown result type (might be due to invalid IL or missing references) Texture2D val = FindLoadedTextureByName(atlasTexName); if ((Object)(object)val == (Object)null) { ManualLogSource log = Plugin.Log; if (log != null) { log.LogWarning((object)("[CustomSprite] atlas '" + atlasTexName + "' not found")); } return null; } Sprite val2 = FindLoadedSpriteByName(referenceCellSpriteName); if ((Object)(object)val2 == (Object)null || (Object)(object)val2.texture == (Object)null) { ManualLogSource log2 = Plugin.Log; if (log2 != null) { log2.LogWarning((object)("[CustomSprite] reference '" + referenceCellSpriteName + "' not found or untextured")); } return null; } Rect rect = val2.rect; float width = ((Rect)(ref rect)).width; float height = ((Rect)(ref rect)).height; float num = 3f * width; float num2 = (float)((Texture)val).height - height; Rect val3 = default(Rect); ((Rect)(ref val3))..ctor(num, num2, width, height); Vector2 val4 = ((val2.pivot.x == 0f && val2.pivot.y == 0f) ? new Vector2(0.5f, 0.5f) : new Vector2(val2.pivot.x / width, val2.pivot.y / height)); Sprite val5 = Sprite.Create(val, val3, val4, val2.pixelsPerUnit, 0u, (SpriteMeshType)0); ((Object)val5).name = referenceCellSpriteName.Replace("A4", "D1") + "_custom"; ManualLogSource log3 = Plugin.Log; if (log3 != null) { log3.LogWarning((object)$"[CustomSprite] built '{((Object)val5).name}' on '{((Object)val).name}' rect=({((Rect)(ref val3)).x},{((Rect)(ref val3)).y},{((Rect)(ref val3)).width}x{((Rect)(ref val3)).height})"); } return val5; } private static Texture2D FindLoadedTextureByName(string name) { Texture2D[] array = Resources.FindObjectsOfTypeAll(); foreach (Texture2D val in array) { if ((Object)(object)val != (Object)null && ((Object)val).name == name) { return val; } } return null; } private static Sprite CreateSpriteFromTexture(string textureName, int x, int y, int w, int h, Vector2 pivot) { //IL_003c: Unknown result type (might be due to invalid IL or missing references) //IL_0041: Unknown result type (might be due to invalid IL or missing references) Texture2D val = FindLoadedTextureByName(textureName); if ((Object)(object)val == (Object)null) { ManualLogSource log = Plugin.Log; if (log != null) { log.LogWarning((object)("Texture '" + textureName + "' not found in loaded assets")); } return null; } return Sprite.Create(val, new Rect((float)x, (float)y, (float)w, (float)h), pivot, 100f); } public static void RecordShotTime(HandItem_Shoot instance) { _lastShotTime[instance] = Time.time; } [IteratorStateMachine(typeof(d__42))] internal static IEnumerator StartupWarmupCoroutine() { //yield-return decompiler failed: Unexpected instruction in Iterator.Dispose() return new d__42(0); } private static void DoStartupWarmup() { //IL_0023: Unknown result type (might be due to invalid IL or missing references) //IL_002d: Unknown result type (might be due to invalid IL or missing references) //IL_0032: 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_003e: Expected O, but got Unknown //IL_0057: Unknown result type (might be due to invalid IL or missing references) //IL_005c: Unknown result type (might be due to invalid IL or missing references) //IL_0087: Unknown result type (might be due to invalid IL or missing references) //IL_01f6: Unknown result type (might be due to invalid IL or missing references) //IL_01fb: Unknown result type (might be due to invalid IL or missing references) //IL_0201: Unknown result type (might be due to invalid IL or missing references) //IL_0207: Unknown result type (might be due to invalid IL or missing references) //IL_0233: Expected O, but got Unknown //IL_025b: Unknown result type (might be due to invalid IL or missing references) //IL_025c: Unknown result type (might be due to invalid IL or missing references) //IL_00d9: Unknown result type (might be due to invalid IL or missing references) //IL_0126: Unknown result type (might be due to invalid IL or missing references) if (_startupWarmupDone) { return; } _startupWarmupDone = true; ManualLogSource log = Plugin.Log; if (log != null) { log.LogInfo((object)"[Shotgun] Startup warmup running"); } Vector3 val = Vector3.down * 1000f; try { GameObject val2 = new GameObject("ShotgunWarmup_Canvas"); ((Object)val2).hideFlags = (HideFlags)61; val2.AddComponent().renderMode = (RenderMode)0; GameObject val3 = new GameObject("WarmupImg"); val3.transform.SetParent(val2.transform, false); ((Graphic)val3.AddComponent()).color = new Color(0f, 0f, 0f, 0f); Object.Destroy((Object)(object)val2); } catch (Exception ex) { ManualLogSource log2 = Plugin.Log; if (log2 != null) { log2.LogWarning((object)("[Shotgun] Warmup canvas: " + ex.Message)); } } try { Plugin.EnsureShotgunHandItemTemplate(); if ((Object)(object)Plugin.ShotgunHandItemTemplate != (Object)null) { WarmupHandItemInstance(((Component)Plugin.ShotgunHandItemTemplate).gameObject, val, "Shotgun"); } } catch (Exception ex2) { ManualLogSource log3 = Plugin.Log; if (log3 != null) { log3.LogWarning((object)("[Shotgun] Warmup HandItem: " + ex2.Message)); } } try { Plugin.EnsureShellHandItemTemplate(); if ((Object)(object)Plugin.ShellHandItemTemplate != (Object)null) { WarmupHandItemInstance(((Component)Plugin.ShellHandItemTemplate).gameObject, val, "Shell"); } } catch (Exception ex3) { ManualLogSource log4 = Plugin.Log; if (log4 != null) { log4.LogWarning((object)("[Shotgun] Warmup shell HandItem: " + ex3.Message)); } } try { if ((Object)(object)_targetForegroundHand == (Object)null) { _targetForegroundHand = LoadHandSpriteFromOwnPng("Hands_Foreground_Library_03.png", "HND_F3D1"); } if ((Object)(object)_targetBackgroundHand == (Object)null) { _targetBackgroundHand = LoadHandSpriteFromOwnPng("Hands_Background_Library_03.png", "HND_B3D1"); } if ((Object)(object)_targetForegroundHandDefault == (Object)null) { _targetForegroundHandDefault = _targetForegroundHand; } if ((Object)(object)_targetBackgroundHandDefault == (Object)null) { _targetBackgroundHandDefault = _targetBackgroundHand; } } catch (Exception ex4) { ManualLogSource log5 = Plugin.Log; if (log5 != null) { log5.LogWarning((object)("[Shotgun] Warmup hand atlas: " + ex4.Message)); } } try { GameObject val4 = new GameObject("ShotgunWarmup_Light"); val4.transform.position = val; Light obj = val4.AddComponent(); obj.type = (LightType)2; obj.range = 1f; obj.intensity = 0.01f; Object.Destroy((Object)val4, 0.05f); } catch (Exception ex5) { ManualLogSource log6 = Plugin.Log; if (log6 != null) { log6.LogWarning((object)("[Shotgun] Warmup light: " + ex5.Message)); } } try { HitPrintHelper.SpawnPrint(val, Vector3.up); } catch (Exception ex6) { ManualLogSource log7 = Plugin.Log; if (log7 != null) { log7.LogWarning((object)("[Shotgun] Warmup print: " + ex6.Message)); } } ManualLogSource log8 = Plugin.Log; if (log8 != null) { log8.LogInfo((object)"[Shotgun] Startup warmup complete"); } } private static void WarmupHandItemInstance(GameObject prefab, Vector3 hiddenPos, string tag) { //IL_009e: 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_0063: Unknown result type (might be due to invalid IL or missing references) //IL_006d: Unknown result type (might be due to invalid IL or missing references) //IL_0072: 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_008c: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)prefab == (Object)null) { return; } GameObject val = Object.Instantiate(prefab); HandItem[] componentsInChildren = val.GetComponentsInChildren(true); foreach (HandItem val2 in componentsInChildren) { if ((Object)(object)val2 != (Object)null) { Object.DestroyImmediate((Object)(object)val2); } } Camera main = Camera.main; if ((Object)(object)main != (Object)null) { val.transform.position = ((Component)main).transform.position + ((Component)main).transform.forward * 0.5f; val.transform.localScale = Vector3.one * 0.01f; } else { val.transform.position = hiddenPos; } val.SetActive(true); Renderer[] componentsInChildren2 = val.GetComponentsInChildren(true); foreach (Renderer val3 in componentsInChildren2) { if (!((Object)(object)val3 == (Object)null)) { try { _ = val3.material; } catch { } } } componentsInChildren2 = val.GetComponentsInChildren(true); foreach (Renderer val4 in componentsInChildren2) { if ((Object)(object)val4 == (Object)null) { continue; } Material[] sharedMaterials = val4.sharedMaterials; if (sharedMaterials == null) { continue; } foreach (Material val5 in sharedMaterials) { if (!((Object)(object)val5 == (Object)null) && !((Object)(object)val5.shader == (Object)null)) { try { val5.SetPass(0); } catch { } } } } ParticleSystem[] componentsInChildren3 = val.GetComponentsInChildren(true); foreach (ParticleSystem val6 in componentsInChildren3) { if (!((Object)(object)val6 == (Object)null)) { try { val6.Emit(1); val6.Clear(); } catch { } } } Animator[] componentsInChildren4 = val.GetComponentsInChildren(true); foreach (Animator val7 in componentsInChildren4) { if (!((Object)(object)val7 == (Object)null)) { try { val7.Update(0f); } catch { } } } AudioSource[] componentsInChildren5 = val.GetComponentsInChildren(true); foreach (AudioSource val8 in componentsInChildren5) { if ((Object)(object)val8 == (Object)null) { continue; } try { val8.mute = true; if ((Object)(object)val8.clip != (Object)null) { val8.Play(); val8.Stop(); } val8.mute = false; } catch { } } val.SetActive(false); Object.Destroy((Object)(object)val); ManualLogSource log = Plugin.Log; if (log != null) { log.LogInfo((object)("[Shotgun] Warmup HandItem instance (" + tag + ") done")); } } public static bool IsBrokenOpen(HandItem_Shoot hi) { if ((Object)(object)hi != (Object)null) { return _openShotguns.Contains(hi); } return false; } public static void SetBrokenOpenForAllHeldShotguns(bool open) { ENT_Player playerObject = ENT_Player.playerObject; if (playerObject?.hands == null) { return; } if (!open) { CloseAllTrays(); SyncVignette(); return; } for (int i = 0; i < playerObject.hands.Length; i++) { Hand obj = playerObject.hands[i]; HandItem obj2 = ((obj != null) ? obj.GetHandItem() : null); HandItem_Shoot val = (HandItem_Shoot)(object)((obj2 is HandItem_Shoot) ? obj2 : null); if (!(((HandItem)(val?)).item?.itemTag != "shotgun")) { _openShotguns.Add(val); EnsureReloadTray(val, i); } } SyncVignette(); } public static bool AnyShotgunOpen() { return _openShotguns.Count > 0; } private static void EnsureReloadTray(HandItem_Shoot hi, int handIndex) { //IL_0034: Unknown result type (might be due to invalid IL or missing references) //IL_0039: Unknown result type (might be due to invalid IL or missing references) //IL_005b: Unknown result type (might be due to invalid IL or missing references) //IL_0060: Unknown result type (might be due to invalid IL or missing references) //IL_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_0078: Unknown result type (might be due to invalid IL or missing references) //IL_007d: Unknown result type (might be due to invalid IL or missing references) //IL_0083: 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_008d: Unknown result type (might be due to invalid IL or missing references) //IL_0096: Unknown result type (might be due to invalid IL or missing references) //IL_009b: Unknown result type (might be due to invalid IL or missing references) //IL_00a0: Unknown result type (might be due to invalid IL or missing references) //IL_00a2: 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_00af: Unknown result type (might be due to invalid IL or missing references) //IL_00b4: Unknown result type (might be due to invalid IL or missing references) //IL_00c6: Unknown result type (might be due to invalid IL or missing references) //IL_00cd: Expected O, but got Unknown //IL_00d4: Unknown result type (might be due to invalid IL or missing references) //IL_00e2: Unknown result type (might be due to invalid IL or missing references) //IL_00e3: Unknown result type (might be due to invalid IL or missing references) //IL_00e8: Unknown result type (might be due to invalid IL or missing references) //IL_00f9: Unknown result type (might be due to invalid IL or missing references) //IL_00fb: Unknown result type (might be due to invalid IL or missing references) //IL_0120: Unknown result type (might be due to invalid IL or missing references) //IL_0125: Unknown result type (might be due to invalid IL or missing references) //IL_0138: Unknown result type (might be due to invalid IL or missing references) //IL_0157: 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_0178: Unknown result type (might be due to invalid IL or missing references) //IL_01ae: Expected O, but got Unknown if (_openTrays.ContainsKey(hi)) { return; } ENT_Player playerObject = ENT_Player.playerObject; if ((Object)(object)playerObject == (Object)null) { return; } Camera main = Camera.main; if (!((Object)(object)main == (Object)null)) { Vector3 forward = ((Component)main).transform.forward; if (((Vector3)(ref forward)).sqrMagnitude < 0.0001f) { forward = Vector3.forward; } ((Vector3)(ref forward)).Normalize(); Vector3 right = ((Component)main).transform.right; float num = ((handIndex == 0) ? (-1f) : 1f); Vector3 val = ((Component)main).transform.position + forward * 1f + right * (num * 0.45f); Vector3 worldOffsetFromPlayer = val - ((Component)playerObject).transform.position; GameObject val2 = new GameObject($"ShotgunReloadTray_Hand{handIndex}"); val2.transform.position = val; val2.transform.rotation = Quaternion.LookRotation(-forward); val2.AddComponent().WorldOffsetFromPlayer = worldOffsetFromPlayer; Object.DontDestroyOnLoad((Object)(object)val2); for (int i = 0; i < 2; i++) { GameObject val3 = new GameObject($"Slot{i}"); val3.transform.SetParent(val2.transform, false); val3.transform.localPosition = new Vector3(((float)i - 0.5f) * 0.45f, 0f, 0f); SphereCollider obj = val3.AddComponent(); obj.radius = 0.21f; ((Collider)obj).isTrigger = true; ReloadSlot reloadSlot = val3.AddComponent(); reloadSlot.Shotgun = hi; reloadSlot.BarrelIndex = i; BuildSlotVisual(val3, ((Object)(object)hi != (Object)null) ? Plugin.GetBarrelType(((HandItem)hi).item, i) : ""); } _openTrays[hi] = val2; } } private void ProcessReloadSlotInteraction() { //IL_002a: Unknown result type (might be due to invalid IL or missing references) //IL_0035: Unknown result type (might be due to invalid IL or missing references) //IL_003a: 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_0092: Unknown result type (might be due to invalid IL or missing references) //IL_0099: 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_00bb: Unknown result type (might be due to invalid IL or missing references) //IL_00cc: Unknown result type (might be due to invalid IL or missing references) //IL_00d2: Unknown result type (might be due to invalid IL or missing references) if (_openTrays.Count == 0) { ClearHoverHighlight(); return; } Camera main = Camera.main; if ((Object)(object)main == (Object)null) { return; } ReloadSlot reloadSlot = null; RaycastHit val = default(RaycastHit); if (Physics.Raycast(new Ray(((Component)main).transform.position, ((Component)main).transform.forward), ref val, 5f, -1, (QueryTriggerInteraction)2)) { reloadSlot = ((Component)((RaycastHit)(ref val)).collider).GetComponent(); } if ((Object)(object)reloadSlot != (Object)(object)_hoveredSlot) { ClearHoverHighlight(); if ((Object)(object)reloadSlot != (Object)null) { reloadSlot.IsHovered = true; if ((Object)(object)reloadSlot.Bg != (Object)null) { Color bgBaseColor = reloadSlot.BgBaseColor; reloadSlot.Bg.color = new Color(Mathf.Clamp01(bgBaseColor.r * 1.4f), Mathf.Clamp01(bgBaseColor.g * 1.4f), Mathf.Clamp01(bgBaseColor.b * 1.4f), bgBaseColor.a); } } _hoveredSlot = reloadSlot; } if ((Object)(object)_hoveredSlot != (Object)null && Input.GetMouseButtonDown(0)) { HandleSlotClick(_hoveredSlot); } } private static void ClearHoverHighlight() { //IL_002f: Unknown result type (might be due to invalid IL or missing references) if (!((Object)(object)_hoveredSlot == (Object)null)) { if ((Object)(object)_hoveredSlot.Bg != (Object)null) { _hoveredSlot.Bg.color = _hoveredSlot.BgBaseColor; } _hoveredSlot.IsHovered = false; _hoveredSlot = null; } } private static void AddShellToInventory(string shellType) { Inventory instance = Inventory.instance; if ((Object)(object)instance == (Object)null) { return; } if (!Plugin.ShotgunShellTemplatesByType.TryGetValue(shellType, out var value) || (Object)(object)value == (Object)null) { value = Plugin.ShotgunShellTemplate; } if ((Object)(object)value == (Object)null) { return; } Item val = null; try { Item itemData = value.itemData; val = ((itemData != null) ? itemData.GetClone((Item)null) : null); } catch { } if (val == null) { return; } Plugin.SetShellType(val, shellType); try { instance.AddItemToInventoryCenter(val); } catch (Exception ex) { ManualLogSource log = Plugin.Log; if (log != null) { log.LogWarning((object)("[Reload] AddShellToInventory failed: " + ex.Message)); } } } private static bool TryConsumeShellFromInventory(string shellType) { Inventory instance = Inventory.instance; if (instance?.bagItems == null) { return false; } Item val = null; foreach (Item bagItem in instance.bagItems) { if (bagItem != null && !(bagItem.itemTag != "shotgun_shell") && !(Plugin.GetShellType(bagItem) != shellType)) { val = bagItem; break; } } if (val == null) { return false; } try { val.DestroyItem(); } catch (Exception ex) { ManualLogSource log = Plugin.Log; if (log != null) { log.LogWarning((object)("[Reload] TryConsumeShell failed: " + ex.Message)); } return false; } return true; } private static int CountShellsOfTypeInBag(string shellType) { Inventory instance = Inventory.instance; if (instance?.bagItems == null) { return 0; } int num = 0; foreach (Item bagItem in instance.bagItems) { if (bagItem != null && !(bagItem.itemTag != "shotgun_shell") && Plugin.GetShellType(bagItem) == shellType) { num++; } } return num; } private static void LogBagShellSummary() { Inventory instance = Inventory.instance; if (instance?.bagItems == null) { ManualLogSource log = Plugin.Log; if (log != null) { log.LogInfo((object)"[ShellBag] (no inventory)"); } return; } int num = 0; Dictionary dictionary = new Dictionary(); foreach (Item bagItem in instance.bagItems) { if (bagItem != null && !(bagItem.itemTag != "shotgun_shell")) { num++; string shellType = Plugin.GetShellType(bagItem); dictionary[shellType] = ((!dictionary.TryGetValue(shellType, out var value)) ? 1 : (value + 1)); } } List list = new List(); foreach (KeyValuePair item in dictionary) { list.Add($"{item.Key}×{item.Value}"); } ManualLogSource log2 = Plugin.Log; if (log2 != null) { log2.LogInfo((object)string.Format("[ShellBag] total={0} types={1}", num, string.Join(", ", list))); } } private static string FindFirstAvailableType() { for (int i = 0; i < ShellCycleOrder.Length; i++) { if (CountShellsOfTypeInBag(ShellCycleOrder[i]) > 0) { return ShellCycleOrder[i]; } } return ""; } private static string FindNextAvailableTypeAfter(string currentType) { int num = -1; for (int i = 0; i < ShellCycleOrder.Length; i++) { if (ShellCycleOrder[i] == currentType) { num = i; break; } } num = (num + 1) % ShellCycleOrder.Length; for (int j = 0; j < ShellCycleOrder.Length; j++) { string text = ShellCycleOrder[(num + j) % ShellCycleOrder.Length]; if (!(text == currentType) && CountShellsOfTypeInBag(text) > 0) { return text; } } return ""; } private static void HandleSlotClick(ReloadSlot slot) { if (((HandItem)(slot?.Shotgun?)).item == null) { return; } string barrelType = Plugin.GetBarrelType(((HandItem)slot.Shotgun).item, slot.BarrelIndex); int num = -1; for (int i = 0; i < ShellCycleOrder.Length; i++) { if (ShellCycleOrder[i] == barrelType) { num = i; break; } } string text = ""; int num2 = ShellCycleOrder.Length + 1; for (int j = 1; j <= num2; j++) { int num3 = (num + j) % num2; if (num == -1) { num3 = (j - 1) % num2; } if (num3 == ShellCycleOrder.Length) { text = ""; break; } string text2 = ShellCycleOrder[num3]; if (CountShellsOfTypeInBag(text2) > 0) { text = text2; break; } } if (!string.IsNullOrEmpty(barrelType)) { AddShellToInventory(barrelType); } if (!string.IsNullOrEmpty(text) && !TryConsumeShellFromInventory(text)) { text = ""; } Plugin.SetBarrelType(((HandItem)slot.Shotgun).item, slot.BarrelIndex, text); int num4 = 0; if (!string.IsNullOrEmpty(Plugin.GetBarrelType(((HandItem)slot.Shotgun).item, 0))) { num4++; } if (!string.IsNullOrEmpty(Plugin.GetBarrelType(((HandItem)slot.Shotgun).item, 1))) { num4++; } if (_handItemShootAmmoField != null) { try { _handItemShootAmmoField.SetValue(slot.Shotgun, num4); } catch { } } try { ((HandItem)slot.Shotgun).item.SetFirstDataStringsofType("ammo", num4.ToString()); } catch { } BuildSlotVisual(((Component)slot).gameObject, text); _hoveredSlot = null; if ((Object)(object)Plugin.ShotgunReloadSingleClip != (Object)null) { PlayGunSound(Plugin.ShotgunReloadSingleClip, 0.8f); } } private static void BuildSlotVisual(GameObject slot, string barrelType) { //IL_0038: Unknown result type (might be due to invalid IL or missing references) //IL_003d: 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_0055: 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) //IL_0065: 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_0075: Unknown result type (might be due to invalid IL or missing references) //IL_007f: Unknown result type (might be due to invalid IL or missing references) //IL_00d0: Unknown result type (might be due to invalid IL or missing references) //IL_00d5: 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_00f5: Unknown result type (might be due to invalid IL or missing references) //IL_00f6: Unknown result type (might be due to invalid IL or missing references) //IL_0139: Unknown result type (might be due to invalid IL or missing references) //IL_0159: Unknown result type (might be due to invalid IL or missing references) //IL_016a: Unknown result type (might be due to invalid IL or missing references) //IL_0174: Unknown result type (might be due to invalid IL or missing references) for (int num = slot.transform.childCount - 1; num >= 0; num--) { Object.Destroy((Object)(object)((Component)slot.transform.GetChild(num)).gameObject); } GameObject val = new GameObject("CircleBg"); val.transform.SetParent(slot.transform, false); val.transform.localPosition = Vector3.zero; val.transform.localRotation = Quaternion.identity; val.transform.localScale = Vector3.one * 0.42f; SpriteRenderer val2 = val.AddComponent(); Color color = default(Color); if (string.IsNullOrEmpty(barrelType)) { val2.sprite = Plugin.GetHollowCircleSprite(); ((Color)(ref color))..ctor(0.75f, 0.75f, 0.75f, 0.9f); } else { Plugin.ShellVisuals shellVisuals = Plugin.GetShellVisuals(barrelType); val2.sprite = Plugin.GetFilledCircleSprite(); color = shellVisuals.Color; } val2.color = color; ReloadSlot component = slot.GetComponent(); if ((Object)(object)component != (Object)null) { component.Bg = val2; component.BgBaseColor = color; } if (string.IsNullOrEmpty(barrelType)) { return; } GameObject shellMeshForType = Plugin.GetShellMeshForType(barrelType); if (!((Object)(object)shellMeshForType == (Object)null)) { GameObject val3 = Object.Instantiate(shellMeshForType, slot.transform); val3.transform.localPosition = new Vector3(0f, 0f, -0.04f); val3.transform.localRotation = Quaternion.Euler(-90f, 0f, 0f); val3.transform.localScale = Vector3.one * 1.6f; Plugin.ApplyGameShader(val3); Material val4 = Plugin.PickShellOutlineMaterial(barrelType); if ((Object)(object)val4 != (Object)null) { EnsureHaloOnGameObject(val3, val4); } } } private static void DestroyReloadTray(HandItem_Shoot hi) { if (hi != null && _openTrays.TryGetValue(hi, out var value)) { if ((Object)(object)value != (Object)null) { Object.Destroy((Object)(object)value); } _openTrays.Remove(hi); } } private static void CloseAllTrays() { foreach (KeyValuePair openTray in _openTrays) { if ((Object)(object)openTray.Value != (Object)null) { Object.Destroy((Object)(object)openTray.Value); } } _openTrays.Clear(); _openShotguns.Clear(); } private static void SyncVignette() { bool flag = AnyShotgunOpen(); if (flag && (Object)(object)_reloadVignette == (Object)null) { _reloadVignette = BuildVignette(); } else if (!flag && (Object)(object)_reloadVignette != (Object)null) { Object.Destroy((Object)(object)_reloadVignette); _reloadVignette = null; } } private static GameObject BuildVignette() { //IL_0005: Unknown result type (might be due to invalid IL or missing references) //IL_000b: Expected O, but got Unknown //IL_003c: Unknown result type (might be due to invalid IL or missing references) //IL_004b: Unknown result type (might be due to invalid IL or missing references) //IL_0050: Unknown result type (might be due to invalid IL or missing references) //IL_0062: Unknown result type (might be due to invalid IL or missing references) //IL_0069: Unknown result type (might be due to invalid IL or missing references) //IL_0074: Unknown result type (might be due to invalid IL or missing references) //IL_007f: 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_00ad: Unknown result type (might be due to invalid IL or missing references) GameObject val = new GameObject("ShotgunReloadVignette"); Object.DontDestroyOnLoad((Object)(object)val); Canvas obj = val.AddComponent(); obj.renderMode = (RenderMode)0; obj.sortingOrder = 50; CanvasScaler obj2 = val.AddComponent(); obj2.uiScaleMode = (ScaleMode)1; obj2.referenceResolution = new Vector2(1920f, 1080f); GameObject val2 = new GameObject("Dim"); val2.transform.SetParent(val.transform, false); RectTransform obj3 = val2.AddComponent(); obj3.anchorMin = Vector2.zero; obj3.anchorMax = Vector2.one; obj3.offsetMin = Vector2.zero; obj3.offsetMax = Vector2.zero; Image obj4 = val2.AddComponent(); ((Graphic)obj4).color = new Color(0f, 0f, 0f, 0.55f); ((Graphic)obj4).raycastTarget = false; return val; } private void Update() { ProcessSnapBacks(); ProcessShellEjects(); ProcessBuckshotFallback(); ProcessBrokenOpenInput(); ProcessReloadSlotInteraction(); } private void ProcessBrokenOpenInput() { //IL_002a: Unknown result type (might be due to invalid IL or missing references) //IL_002f: Unknown result type (might be due to invalid IL or missing references) //IL_006a: Unknown result type (might be due to invalid IL or missing references) //IL_0079: 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_0083: 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_0095: Unknown result type (might be due to invalid IL or missing references) if (_openTrays.Count > 0 && (Object)(object)Camera.main != (Object)null) { Vector3 forward = ((Component)Camera.main).transform.forward; float num = 0f; foreach (KeyValuePair openTray in _openTrays) { if ((Object)(object)openTray.Value == (Object)null) { continue; } Vector3 val = openTray.Value.transform.position - ((Component)Camera.main).transform.position; if (!(((Vector3)(ref val)).sqrMagnitude < 0.0001f)) { float num2 = Vector3.Angle(forward, val); if (num2 > num) { num = num2; } } } if (num > 75f) { TryTransitionBrokenOpen(open: false); } } if (_openShotguns.Count > 0) { List list = null; foreach (HandItem_Shoot openShotgun in _openShotguns) { if ((Object)(object)openShotgun == (Object)null) { (list ?? (list = new List())).Add(openShotgun); } } if (list != null) { foreach (HandItem_Shoot item in list) { _openShotguns.Remove(item); DestroyReloadTray(item); } SyncVignette(); } } if (_openTrays.Count > 0) { foreach (KeyValuePair openTray2 in _openTrays) { HandItem_Shoot key = openTray2.Key; GameObject value = openTray2.Value; if (((HandItem)(key?)).item != null && !((Object)(object)value == (Object)null)) { for (int i = 0; i < 2; i++) { _ = (Object)(object)value.transform.Find($"Slot{i}") == (Object)null; } } } } bool keyDown = Input.GetKeyDown((KeyCode)114); bool key2 = Input.GetKey((KeyCode)114); ENT_Player playerObject = ENT_Player.playerObject; if (playerObject?.hands == null) { return; } bool flag = false; Hand[] hands = playerObject.hands; foreach (Hand obj in hands) { HandItem obj2 = ((obj != null) ? obj.GetHandItem() : null); if (((obj2 is HandItem_Shoot) ? obj2 : null)?.item?.itemTag == "shotgun") { flag = true; break; } } if (keyDown && flag && _openShotguns.Count == 0) { TryTransitionBrokenOpen(open: true); } else if (!key2 && _openShotguns.Count > 0) { TryTransitionBrokenOpen(open: false); } } private void TryTransitionBrokenOpen(bool open) { if (Time.unscaledTime - _lastBreakOpenCloseTime < 0.5f) { return; } _lastBreakOpenCloseTime = Time.unscaledTime; bool flag = AnyHeldShotgunLoaded(); SetBrokenOpenForAllHeldShotguns(open); if (open) { if (flag && (Object)(object)Plugin.ShotgunBreakOpenClip != (Object)null) { PlayGunSound(Plugin.ShotgunBreakOpenClip, 0.9f); } } else if (flag && (Object)(object)Plugin.ShotgunBreakCloseClip != (Object)null) { PlayGunSound(Plugin.ShotgunBreakCloseClip, 0.9f); } } private static bool AnyHeldShotgunLoaded() { ENT_Player playerObject = ENT_Player.playerObject; if (playerObject?.hands == null) { return false; } Hand[] hands = playerObject.hands; foreach (Hand obj in hands) { HandItem obj2 = ((obj != null) ? obj.GetHandItem() : null); HandItem_Shoot val = (HandItem_Shoot)(object)((obj2 is HandItem_Shoot) ? obj2 : null); if (((HandItem)(val?)).item?.itemTag == "shotgun" && val.GetAmmo() > 0) { return true; } } return false; } private void LateUpdate() { OverrideShotgunSpriteIfLoaded(); OverrideShotgunHandSpritesIfLoaded(); if (_pendingHalo.Count > 0) { DrainPendingHalo(); } } public static void OnItemObjectStartedForHalo(Item_Object io) { if (io?.itemData != null) { string itemTag = io.itemData.itemTag; if ((!(itemTag != "shotgun") || !(itemTag != "shotgun_shell")) && !TryAttachHaloNow(io)) { _pendingHalo.Add(io); } } } private static bool TryAttachHaloNow(Item_Object io) { if ((Object)(object)io == (Object)null || (Object)(object)((Component)io).gameObject == (Object)null) { return true; } string text = io.itemData?.itemTag; if (text == "shotgun") { if ((Object)(object)Plugin.OutlineMaterial == (Object)null) { Plugin.OutlineMaterial = Plugin.TryBuildGameOutlineMaterial(); } if ((Object)(object)Plugin.OutlineMaterial == (Object)null) { return false; } EnsureHaloOnGameObject(((Component)io).gameObject, Plugin.OutlineMaterial); return true; } if (text == "shotgun_shell") { Material val = Plugin.PickShellOutlineMaterial(Plugin.GetShellType(io.itemData)); if ((Object)(object)val == (Object)null) { return false; } EnsureHaloOnGameObject(((Component)io).gameObject, val); return true; } return true; } private void DrainPendingHalo() { List list = null; foreach (Item_Object item in _pendingHalo) { if ((Object)(object)item == (Object)null || (Object)(object)((Component)item).gameObject == (Object)null) { (list ?? (list = new List())).Add(item); } else if (TryAttachHaloNow(item)) { (list ?? (list = new List())).Add(item); } } if (list == null) { return; } foreach (Item_Object item2 in list) { _pendingHalo.Remove(item2); } } public static void EnsureHaloOnGameObject(GameObject go, Material outlineMat = null) { //IL_0070: Unknown result type (might be due to invalid IL or missing references) //IL_0077: Expected O, but got Unknown //IL_01a0: Unknown result type (might be due to invalid IL or missing references) //IL_01a5: Unknown result type (might be due to invalid IL or missing references) //IL_01b6: Unknown result type (might be due to invalid IL or missing references) //IL_01c8: Unknown result type (might be due to invalid IL or missing references) //IL_01ce: Unknown result type (might be due to invalid IL or missing references) //IL_01d8: Unknown result type (might be due to invalid IL or missing references) //IL_01de: Unknown result type (might be due to invalid IL or missing references) //IL_01e8: Unknown result type (might be due to invalid IL or missing references) //IL_01ee: Unknown result type (might be due to invalid IL or missing references) //IL_01f8: Unknown result type (might be due to invalid IL or missing references) Material val = outlineMat ?? Plugin.OutlineMaterial; if ((Object)(object)go == (Object)null || (Object)(object)val == (Object)null) { return; } MeshRenderer[] componentsInChildren = go.GetComponentsInChildren(true); foreach (MeshRenderer val2 in componentsInChildren) { if ((Object)(object)val2 == (Object)null || ((Object)((Component)val2).gameObject).name.StartsWith("ShotgunHalo_")) { continue; } Transform val3 = null; foreach (Transform item in ((Component)val2).transform) { Transform val4 = item; if (((Object)val4).name.StartsWith("ShotgunHalo_")) { val3 = val4; break; } } MeshFilter component = ((Component)val2).GetComponent(); if ((Object)(object)component == (Object)null || (Object)(object)component.sharedMesh == (Object)null) { if ((Object)(object)val3 != (Object)null) { Object.Destroy((Object)(object)((Component)val3).gameObject); } continue; } Mesh invertedHullMesh = Plugin.GetInvertedHullMesh(component.sharedMesh); if ((Object)(object)invertedHullMesh == (Object)null) { if ((Object)(object)val3 != (Object)null) { Object.Destroy((Object)(object)((Component)val3).gameObject); } } else if ((Object)(object)val3 != (Object)null) { MeshFilter component2 = ((Component)val3).GetComponent(); if ((Object)(object)component2 != (Object)null && (Object)(object)component2.sharedMesh != (Object)(object)invertedHullMesh) { component2.sharedMesh = invertedHullMesh; } MeshRenderer component3 = ((Component)val3).GetComponent(); if ((Object)(object)component3 != (Object)null && (Object)(object)((Renderer)component3).sharedMaterial != (Object)(object)val) { ((Renderer)component3).sharedMaterial = val; } } else { GameObject val5 = new GameObject("ShotgunHalo_" + ((Object)val2).name) { layer = ((Component)val2).gameObject.layer }; val5.transform.SetParent(((Component)val2).transform, false); val5.transform.localPosition = Plugin.OutlineHaloOffset; val5.transform.localRotation = Quaternion.identity; val5.transform.localScale = Plugin.OutlineHaloScale; val5.AddComponent().sharedMesh = invertedHullMesh; MeshRenderer obj = val5.AddComponent(); ((Renderer)obj).sharedMaterial = val; ((Renderer)obj).shadowCastingMode = (ShadowCastingMode)0; ((Renderer)obj).receiveShadows = false; ((Renderer)obj).lightProbeUsage = (LightProbeUsage)0; ((Renderer)obj).reflectionProbeUsage = (ReflectionProbeUsage)0; } } } public static void ConfigureAsPickup(GameObject shotgun) { //IL_01a1: Unknown result type (might be due to invalid IL or missing references) //IL_012e: Unknown result type (might be due to invalid IL or missing references) //IL_0133: Unknown result type (might be due to invalid IL or missing references) //IL_0246: Unknown result type (might be due to invalid IL or missing references) //IL_0250: Expected O, but got Unknown //IL_0251: Unknown result type (might be due to invalid IL or missing references) //IL_025b: Expected O, but got Unknown //IL_025c: Unknown result type (might be due to invalid IL or missing references) //IL_0266: Expected O, but got Unknown //IL_0267: Unknown result type (might be due to invalid IL or missing references) //IL_0271: Expected O, but got Unknown //IL_0145: Unknown result type (might be due to invalid IL or missing references) //IL_016f: Unknown result type (might be due to invalid IL or missing references) //IL_0174: Unknown result type (might be due to invalid IL or missing references) //IL_0180: Unknown result type (might be due to invalid IL or missing references) shotgun.layer = 10; Transform[] componentsInChildren = shotgun.GetComponentsInChildren(true); for (int i = 0; i < componentsInChildren.Length; i++) { ((Component)componentsInChildren[i]).gameObject.layer = 10; } try { shotgun.tag = "Pickupable"; } catch { } ObjectTagger val = shotgun.GetComponent(); if ((Object)(object)val == (Object)null) { val = shotgun.AddComponent(); } if (val.tags == null) { val.tags = new List(); } if (!val.tags.Contains("Pickupable")) { val.tags.Add("Pickupable"); } if (!val.tags.Contains("Item")) { val.tags.Add("Item"); } if ((Object)(object)shotgun.GetComponentInChildren() == (Object)null) { Renderer[] componentsInChildren2 = shotgun.GetComponentsInChildren(); List list = new List(componentsInChildren2.Length); Renderer[] array = componentsInChildren2; foreach (Renderer val2 in array) { if ((Object)(object)val2 != (Object)null && !((Object)((Component)val2).gameObject).name.StartsWith("ShotgunHalo_")) { list.Add(val2); } } if (list.Count > 0) { Bounds bounds = list[0].bounds; for (int j = 1; j < list.Count; j++) { ((Bounds)(ref bounds)).Encapsulate(list[j].bounds); } BoxCollider obj2 = shotgun.AddComponent(); obj2.center = shotgun.transform.InverseTransformPoint(((Bounds)(ref bounds)).center); obj2.size = ((Bounds)(ref bounds)).size; } else { shotgun.AddComponent().size = new Vector3(1.5f, 0.3f, 0.3f); } } if ((Object)(object)Plugin.OutlineMaterial == (Object)null) { Plugin.OutlineMaterial = Plugin.TryBuildGameOutlineMaterial(); } EnsureHaloOnGameObject(shotgun); if ((Object)(object)Plugin.OutlineMaterial == (Object)null) { ManualLogSource log = Plugin.Log; if (log != null) { log.LogWarning((object)"[Outline] Could not build runtime outline material — Dark Machine/SHDR_Outline not found yet. Will retry on next sweep."); } } Rigidbody val3 = shotgun.GetComponent(); if ((Object)(object)val3 == (Object)null) { val3 = shotgun.AddComponent(); } val3.mass = 0.5f; if (shotgun.GetComponent() == null) { shotgun.AddComponent(); } Item_Object val4 = shotgun.GetComponent(); if ((Object)(object)val4 == (Object)null) { val4 = shotgun.AddComponent(); } val4.itemData = Plugin.CreateShotgunItem(); val4.canPickup = true; val4.pickupEvent = new UnityEvent(); val4.onDrop = new UnityEvent(); val4.onPlaceInInventory = new UnityEvent(); val4.onPlaceInWorld = new UnityEvent(); CL_Prop val5 = shotgun.GetComponent(); if ((Object)(object)val5 == (Object)null) { val5 = shotgun.AddComponent(); } if (val5.hitSounds == null) { val5.hitSounds = new List(); } if (val5.dragSounds == null) { val5.dragSounds = new List(); } if (val5.breakSounds == null) { val5.breakSounds = new List(); } if (val5.unstickSounds == null) { val5.unstickSounds = new List(); } if (val5.damageSounds == null) { val5.damageSounds = new List(); } } } public class ShotgunAmmoHudHandler : MonoBehaviour { private class ReloadPanelWidgets { public RectTransform PanelRect; public Image[] SlotImages; public Text[] SlotLetters; public Button[] SlotButtons; public int HandIndex; } private class SlotWidgets { public RectTransform GroupRect; public Image[] SlotImages; public Text[] SlotLetters; public GameObject[] ArrowObjects; public string[] LastBarrelType = new string[2]; public bool[] LastArrowVisible = new bool[2]; public float LastAnchoredX = float.NaN; } [CompilerGenerated] private sealed class d__25 : IEnumerator, IEnumerator, IDisposable { private int <>1__state; private object <>2__current; public ShotgunAmmoHudHandler <>4__this; private RectTransform 5__2; private Vector2 5__3; object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public d__25(int <>1__state) { this.<>1__state = <>1__state; } [DebuggerHidden] void IDisposable.Dispose() { 5__2 = null; <>1__state = -2; } private bool MoveNext() { //IL_0067: Unknown result type (might be due to invalid IL or missing references) //IL_005a: Unknown result type (might be due to invalid IL or missing references) //IL_01ba: 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_008f: Unknown result type (might be due to invalid IL or missing references) int num = <>1__state; ShotgunAmmoHudHandler shotgunAmmoHudHandler = <>4__this; switch (num) { default: return false; case 0: <>1__state = -1; 5__2 = (((Object)(object)shotgunAmmoHudHandler._canvas != (Object)null) ? ((Component)shotgunAmmoHudHandler._canvas).GetComponent() : null); 5__3 = (((Object)(object)5__2 != (Object)null) ? 5__2.anchoredPosition : Vector2.zero); if ((Object)(object)5__2 != (Object)null) { 5__2.anchoredPosition = new Vector2(-99999f, -99999f); } if (shotgunAmmoHudHandler._groupRoots != null) { for (int k = 0; k < shotgunAmmoHudHandler._groupRoots.Length; k++) { SetWidgetVisible(shotgunAmmoHudHandler._groupRoots[k], visible: true); } } SetWidgetVisible(shotgunAmmoHudHandler._separator, visible: true); SetWidgetVisible(shotgunAmmoHudHandler._hintLabel, visible: true); if (shotgunAmmoHudHandler._reloadPanels != null) { for (int l = 0; l < shotgunAmmoHudHandler._reloadPanels.Length; l++) { SetWidgetVisible(shotgunAmmoHudHandler._reloadPanels[l], visible: true); } } <>2__current = null; <>1__state = 1; return true; case 1: <>1__state = -1; <>2__current = null; <>1__state = 2; return true; case 2: <>1__state = -1; if (shotgunAmmoHudHandler._groupRoots != null) { for (int i = 0; i < shotgunAmmoHudHandler._groupRoots.Length; i++) { SetWidgetVisible(shotgunAmmoHudHandler._groupRoots[i], visible: false); } } SetWidgetVisible(shotgunAmmoHudHandler._separator, visible: false); SetWidgetVisible(shotgunAmmoHudHandler._hintLabel, visible: false); if (shotgunAmmoHudHandler._reloadPanels != null) { for (int j = 0; j < shotgunAmmoHudHandler._reloadPanels.Length; j++) { SetWidgetVisible(shotgunAmmoHudHandler._reloadPanels[j], visible: false); } } if ((Object)(object)5__2 != (Object)null) { 5__2.anchoredPosition = 5__3; } return false; } } bool IEnumerator.MoveNext() { //ILSpy generated this explicit interface implementation from .override directive in MoveNext return this.MoveNext(); } [DebuggerHidden] void IEnumerator.Reset() { throw new NotSupportedException(); } } private const float SlotSize = 56f; private const float SlotGap = 6f; private const float GroupGap = 28f; private const float ArrowHeight = 28f; private const float ArrowGap = 4f; private const float MarginRight = 32f; private const float MarginBottom = 32f; private const float SeparatorWidth = 4f; private Canvas _canvas; private Texture2D _filledTex; private Texture2D _hollowTex; private Sprite _filledSprite; private Sprite _hollowSprite; private GameObject[] _groupRoots; private SlotWidgets[] _groupSlots; private GameObject _separator; private GameObject _hintLabel; private RectTransform _hintLabelRect; private GameObject[] _reloadPanels; private ReloadPanelWidgets[] _reloadPanelWidgets; private readonly bool[] _hasShotgunScratch = new bool[2]; private readonly string[][] _barrelTypeScratch = new string[2][] { new string[2], new string[2] }; private readonly HandItem_Shoot[] _heldShotgunsScratch = (HandItem_Shoot[])(object)new HandItem_Shoot[2]; private void Start() { BuildHud(); ((MonoBehaviour)this).StartCoroutine(PrerenderHudOnce()); } [IteratorStateMachine(typeof(d__25))] private IEnumerator PrerenderHudOnce() { //yield-return decompiler failed: Unexpected instruction in Iterator.Dispose() return new d__25(0) { <>4__this = this }; } private void BuildHud() { //IL_0037: Unknown result type (might be due to invalid IL or missing references) //IL_0046: Unknown result type (might be due to invalid IL or missing references) //IL_0075: Unknown result type (might be due to invalid IL or missing references) //IL_0084: Unknown result type (might be due to invalid IL or missing references) //IL_00b3: Unknown result type (might be due to invalid IL or missing references) //IL_00b9: Expected O, but got Unknown //IL_0108: Unknown result type (might be due to invalid IL or missing references) _filledTex = MakeCircleTexture(64, hollow: false); _hollowTex = MakeCircleTexture(64, hollow: true); _filledSprite = Sprite.Create(_filledTex, new Rect(0f, 0f, 64f, 64f), new Vector2(0.5f, 0.5f), 100f); _hollowSprite = Sprite.Create(_hollowTex, new Rect(0f, 0f, 64f, 64f), new Vector2(0.5f, 0.5f), 100f); Object.DontDestroyOnLoad((Object)(object)_filledSprite); Object.DontDestroyOnLoad((Object)(object)_hollowSprite); GameObject val = new GameObject("ShotgunAmmoHud_Canvas"); val.transform.SetParent(((Component)this).transform, false); _canvas = val.AddComponent(); _canvas.renderMode = (RenderMode)0; _canvas.sortingOrder = 100; CanvasScaler obj = val.AddComponent(); obj.uiScaleMode = (ScaleMode)1; obj.referenceResolution = new Vector2(1920f, 1080f); obj.matchWidthOrHeight = 1f; val.AddComponent(); _groupRoots = (GameObject[])(object)new GameObject[2]; _groupSlots = new SlotWidgets[2]; for (int i = 0; i < 2; i++) { _groupRoots[i] = BuildShotgunGroup(val.transform, i); EnsureWidgetCanvasGroup(_groupRoots[i]).alpha = 0f; } _separator = BuildSeparator(val.transform); EnsureWidgetCanvasGroup(_separator).alpha = 0f; _reloadPanels = (GameObject[])(object)new GameObject[2]; _reloadPanelWidgets = new ReloadPanelWidgets[2]; for (int j = 0; j < 2; j++) { _reloadPanels[j] = BuildReloadPanel(val.transform, j); EnsureWidgetCanvasGroup(_reloadPanels[j]).alpha = 0f; } BuildHintLabel(val.transform); if ((Object)(object)_hintLabel != (Object)null) { EnsureWidgetCanvasGroup(_hintLabel).alpha = 0f; } } private static CanvasGroup EnsureWidgetCanvasGroup(GameObject go) { if ((Object)(object)go == (Object)null) { return null; } CanvasGroup val = go.GetComponent(); if ((Object)(object)val == (Object)null) { val = go.AddComponent(); } return val; } private static void SetWidgetVisible(GameObject go, bool visible) { if (!((Object)(object)go == (Object)null)) { CanvasGroup val = EnsureWidgetCanvasGroup(go); float num = (visible ? 1f : 0f); if (val.alpha != num) { val.alpha = num; val.interactable = visible; val.blocksRaycasts = visible; } } } private void BuildHintLabel(Transform parent) { //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_0010: Expected O, but got Unknown //IL_0043: 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_0077: Unknown result type (might be due to invalid IL or missing references) //IL_0091: Unknown result type (might be due to invalid IL or missing references) //IL_00ab: Unknown result type (might be due to invalid IL or missing references) //IL_0114: Unknown result type (might be due to invalid IL or missing references) //IL_014b: Unknown result type (might be due to invalid IL or missing references) //IL_015f: Unknown result type (might be due to invalid IL or missing references) _hintLabel = new GameObject("ShotgunAmmoHud_Hint"); _hintLabel.transform.SetParent(parent, false); _hintLabelRect = _hintLabel.AddComponent(); _hintLabelRect.anchorMin = new Vector2(1f, 0f); _hintLabelRect.anchorMax = new Vector2(1f, 0f); _hintLabelRect.pivot = new Vector2(1f, 0f); _hintLabelRect.sizeDelta = new Vector2(360f, 28f); _hintLabelRect.anchoredPosition = new Vector2(-32f, 126f); Text obj = _hintLabel.AddComponent(); obj.text = "Hold R to change ammo type"; obj.font = Resources.GetBuiltinResource("LegacyRuntime.ttf") ?? Resources.GetBuiltinResource("Arial.ttf"); obj.fontSize = 18; obj.fontStyle = (FontStyle)1; obj.alignment = (TextAnchor)5; ((Graphic)obj).color = new Color(0.95f, 0.2f, 0.2f, 1f); obj.horizontalOverflow = (HorizontalWrapMode)1; obj.verticalOverflow = (VerticalWrapMode)1; Outline obj2 = _hintLabel.AddComponent(); ((Shadow)obj2).effectColor = new Color(0f, 0f, 0f, 0.85f); ((Shadow)obj2).effectDistance = new Vector2(1.2f, -1.2f); _hintLabel.SetActive(false); } private GameObject BuildReloadPanel(Transform parent, int handIndex) { //IL_0020: Unknown result type (might be due to invalid IL or missing references) //IL_0026: Expected O, but got Unknown //IL_0041: 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_0067: Unknown result type (might be due to invalid IL or missing references) //IL_007c: Unknown result type (might be due to invalid IL or missing references) //IL_0087: Unknown result type (might be due to invalid IL or missing references) //IL_00ac: Unknown result type (might be due to invalid IL or missing references) //IL_0171: Unknown result type (might be due to invalid IL or missing references) //IL_017b: Expected O, but got Unknown float num = ((handIndex == 0) ? 0.78f : 0.22f); GameObject val = new GameObject($"ReloadPanel_Hand{handIndex}"); val.transform.SetParent(parent, false); RectTransform val2 = val.AddComponent(); val2.anchorMin = new Vector2(num, 0.5f); val2.anchorMax = new Vector2(num, 0.5f); val2.pivot = new Vector2(0.5f, 0.5f); val2.sizeDelta = new Vector2(272f, 152f); val2.anchoredPosition = Vector2.zero; Image obj = val.AddComponent(); ((Graphic)obj).color = new Color(0f, 0f, 0f, 0.55f); ((Graphic)obj).raycastTarget = true; ReloadPanelWidgets reloadPanelWidgets = new ReloadPanelWidgets { PanelRect = val2, SlotImages = (Image[])(object)new Image[2], SlotLetters = (Text[])(object)new Text[2], SlotButtons = (Button[])(object)new Button[2], HandIndex = handIndex }; for (int i = 0; i < 2; i++) { float xLocal = ((float)i - 0.5f) * 120f; reloadPanelWidgets.SlotButtons[i] = BuildReloadSlot(val.transform, xLocal, 96f, out reloadPanelWidgets.SlotImages[i], out reloadPanelWidgets.SlotLetters[i]); int capturedBarrel = i; int capturedHand = handIndex; ((UnityEvent)reloadPanelWidgets.SlotButtons[i].onClick).AddListener((UnityAction)delegate { ManualLogSource log = Plugin.Log; if (log != null) { log.LogInfo((object)$"[ReloadPanel] hand={capturedHand} barrel={capturedBarrel} clicked"); } }); } _reloadPanelWidgets[handIndex] = reloadPanelWidgets; return val; } private Button BuildReloadSlot(Transform parent, float xLocal, float size, out Image slotImage, out Text letterText) { //IL_0005: Unknown result type (might be due to invalid IL or missing references) //IL_000b: Expected O, but got Unknown //IL_0029: Unknown result type (might be due to invalid IL or missing references) //IL_003e: Unknown result type (might be due to invalid IL or missing references) //IL_0053: 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_0070: Unknown result type (might be due to invalid IL or missing references) //IL_00a8: Unknown result type (might be due to invalid IL or missing references) //IL_00cb: Unknown result type (might be due to invalid IL or missing references) //IL_00d0: Unknown result type (might be due to invalid IL or missing references) //IL_00d3: Unknown result type (might be due to invalid IL or missing references) //IL_00f3: Unknown result type (might be due to invalid IL or missing references) //IL_0113: Unknown result type (might be due to invalid IL or missing references) //IL_011f: Unknown result type (might be due to invalid IL or missing references) //IL_013f: Unknown result type (might be due to invalid IL or missing references) //IL_0162: Unknown result type (might be due to invalid IL or missing references) //IL_0174: Unknown result type (might be due to invalid IL or missing references) //IL_017a: Expected O, but got Unknown //IL_0193: Unknown result type (might be due to invalid IL or missing references) //IL_019e: Unknown result type (might be due to invalid IL or missing references) //IL_01a9: Unknown result type (might be due to invalid IL or missing references) //IL_01b3: Unknown result type (might be due to invalid IL or missing references) //IL_0216: Unknown result type (might be due to invalid IL or missing references) GameObject val = new GameObject("ReloadSlot"); val.transform.SetParent(parent, false); RectTransform obj = val.AddComponent(); obj.anchorMin = new Vector2(0.5f, 0.5f); obj.anchorMax = new Vector2(0.5f, 0.5f); obj.pivot = new Vector2(0.5f, 0.5f); obj.anchoredPosition = new Vector2(xLocal, 0f); obj.sizeDelta = new Vector2(size, size); slotImage = val.AddComponent(); slotImage.sprite = _hollowSprite; ((Graphic)slotImage).color = new Color(0.7f, 0.7f, 0.7f, 0.85f); ((Graphic)slotImage).raycastTarget = true; Button obj2 = val.AddComponent