Decompiled source of MoreShotgunShells v1.0.0

MoreShotgunShells.dll

Decompiled 5 hours ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using CSync.Extensions;
using CSync.Lib;
using GameNetcodeStuff;
using HarmonyLib;
using LethalLib.Modules;
using Microsoft.CodeAnalysis;
using ShotgunPlus;
using Unity.Netcode;
using UnityEngine;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")]
[assembly: AssemblyCompany("MoreShotgunShells")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0")]
[assembly: AssemblyProduct("MoreShotgunShells")]
[assembly: AssemblyTitle("MoreShotgunShells")]
[assembly: AssemblyVersion("1.0.0.0")]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[Embedded]
	[AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)]
	internal sealed class RefSafetyRulesAttribute : Attribute
	{
		public readonly int Version;

		public RefSafetyRulesAttribute(int P_0)
		{
			Version = P_0;
		}
	}
}
namespace MoreShotgunShells
{
	internal static class Burn
	{
		private class Runner : MonoBehaviour
		{
		}

		private static Runner runner;

		private static Runner R
		{
			get
			{
				//IL_0012: Unknown result type (might be due to invalid IL or missing references)
				//IL_0017: Unknown result type (might be due to invalid IL or missing references)
				//IL_001d: Expected O, but got Unknown
				//IL_001d: Unknown result type (might be due to invalid IL or missing references)
				if ((Object)(object)runner == (Object)null)
				{
					GameObject val = new GameObject("MoreShotgunShells Fire");
					Object.DontDestroyOnLoad((Object)val);
					((Object)val).hideFlags = (HideFlags)61;
					runner = val.AddComponent<Runner>();
				}
				return runner;
			}
		}

		private static float Seconds => Mathf.Clamp(Plugin.Cfg.DragonBurnSeconds.Value, 0.1f, 30f);

		internal static void Damage(ShotgunItem gun, EnemyAI ai, IHittable hit)
		{
			if ((Object)(object)ai == (Object)null || ai.isEnemyDead)
			{
				return;
			}
			if (ai is ForestGiantAI)
			{
				if (Plugin.Cfg.DragonBurnsGiants.Value)
				{
					ShellRegistry.HitFromExplosionEverywhere(ai);
				}
				return;
			}
			int num = Mathf.Clamp(Plugin.Cfg.DragonBurnDamage.Value, 0, 20);
			if (num > 0)
			{
				((MonoBehaviour)R).StartCoroutine(Tick(hit, ai, ((Object)(object)gun != (Object)null) ? ((GrabbableObject)gun).playerHeldBy : null, num, Seconds));
			}
		}

		private static IEnumerator Tick(IHittable hit, EnemyAI ai, PlayerControllerB by, int dmg, float seconds)
		{
			float step = seconds / (float)dmg;
			for (int i = 0; i < dmg; i++)
			{
				yield return (object)new WaitForSeconds(step);
				if ((Object)(object)ai == (Object)null || ai.isEnemyDead || hit == null)
				{
					break;
				}
				try
				{
					hit.Hit(1, Vector3.up, by, false, -1);
				}
				catch (Exception ex)
				{
					Plugin.Log.LogWarning((object)("Burn: " + ex.Message));
					break;
				}
			}
		}

		internal static void Fx(ShotgunItem gun, EnemyAI ai)
		{
			//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_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_009c: 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_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_00fd: 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_00ae: 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_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_017b: 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_01be: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c3: Unknown result type (might be due to invalid IL or missing references)
			//IL_01cd: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d2: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)ai == (Object)null || ai is ForestGiantAI || !ShellRegistry.EffectsOn || (Object)(object)gun == (Object)null || (Object)(object)gun.gunShootParticle == (Object)null)
			{
				return;
			}
			try
			{
				ParticleSystem val = null;
				ParticleSystem[] componentsInChildren = ((Component)gun.gunShootParticle).GetComponentsInChildren<ParticleSystem>(true);
				foreach (ParticleSystem val2 in componentsInChildren)
				{
					if ((Object)(object)val2 != (Object)(object)gun.gunShootParticle)
					{
						val = val2;
						break;
					}
				}
				if (!((Object)(object)val == (Object)null))
				{
					Vector3 val3 = ((Component)ai).transform.position + Vector3.up * 0.8f;
					Collider componentInChildren = ((Component)ai).GetComponentInChildren<Collider>();
					if ((Object)(object)componentInChildren != (Object)null)
					{
						Bounds bounds = componentInChildren.bounds;
						val3 = ((Bounds)(ref bounds)).center;
					}
					GameObject val4 = Object.Instantiate<GameObject>(((Component)val).gameObject, val3, Quaternion.LookRotation(Vector3.up));
					((Object)val4).name = "MoreShotgunShells Fire";
					val4.transform.SetParent(((Component)ai).transform, true);
					val4.transform.localScale = ((Component)val).transform.lossyScale * 0.6f;
					Light[] componentsInChildren2 = val4.GetComponentsInChildren<Light>(true);
					for (int i = 0; i < componentsInChildren2.Length; i++)
					{
						((Behaviour)componentsInChildren2[i]).enabled = false;
					}
					MonoBehaviour[] componentsInChildren3 = val4.GetComponentsInChildren<MonoBehaviour>(true);
					for (int i = 0; i < componentsInChildren3.Length; i++)
					{
						((Behaviour)componentsInChildren3[i]).enabled = false;
					}
					componentsInChildren = val4.GetComponentsInChildren<ParticleSystem>(true);
					foreach (ParticleSystem obj in componentsInChildren)
					{
						obj.Stop(true, (ParticleSystemStopBehavior)0);
						MainModule main = obj.main;
						((MainModule)(ref main)).loop = true;
						((MainModule)(ref main)).duration = 0.25f;
						((MainModule)(ref main)).scalingMode = (ParticleSystemScalingMode)0;
						((MainModule)(ref main)).startSpeedMultiplier = ((MainModule)(ref main)).startSpeedMultiplier * 0.15f;
						((MainModule)(ref main)).gravityModifierMultiplier = -0.3f;
						CollisionModule collision = obj.collision;
						((CollisionModule)(ref collision)).enabled = false;
						SubEmittersModule subEmitters = obj.subEmitters;
						((SubEmittersModule)(ref subEmitters)).enabled = false;
					}
					val4.GetComponent<ParticleSystem>().Play(true);
					((MonoBehaviour)R).StartCoroutine(StopFire(val4, Seconds));
				}
			}
			catch (Exception ex)
			{
				Plugin.Log.LogWarning((object)("Fire effect: " + ex.Message));
			}
		}

		private static IEnumerator StopFire(GameObject fire, float seconds)
		{
			yield return (object)new WaitForSeconds(seconds);
			if (!((Object)(object)fire == (Object)null))
			{
				ParticleSystem[] componentsInChildren = fire.GetComponentsInChildren<ParticleSystem>(true);
				for (int i = 0; i < componentsInChildren.Length; i++)
				{
					componentsInChildren[i].Stop(true, (ParticleSystemStopBehavior)1);
				}
				Object.Destroy((Object)(object)fire, 1.5f);
			}
		}
	}
	internal static class Nutcracker
	{
		private static readonly FieldRef<NutcrackerEnemyAI, ShotgunItem> gun = AccessTools.FieldRefAccess<NutcrackerEnemyAI, ShotgunItem>("gun");

		private static readonly FieldRef<NutcrackerEnemyAI, GameObject> shellPrefab = AccessTools.FieldRefAccess<NutcrackerEnemyAI, GameObject>("shotgunShellPrefab");

		private static bool Roll(int percent)
		{
			if (percent > 0)
			{
				return Random.Range(0, 100) < percent;
			}
			return false;
		}

		[HarmonyPatch(typeof(NutcrackerEnemyAI), "ReloadGunClientRpc")]
		[HarmonyPostfix]
		[HarmonyPriority(200)]
		private static void Reloaded(NutcrackerEnemyAI __instance)
		{
			if ((Object)(object)NetworkManager.Singleton == (Object)null || !NetworkManager.Singleton.IsServer)
			{
				return;
			}
			ShotgunItem val = gun.Invoke(__instance);
			if (!((Object)(object)val == (Object)null) && Roll(Plugin.Cfg.NutLoadChance.Value))
			{
				Shells.Entry entry = Shells.Pick();
				if (entry != null)
				{
					ShellRegistry.LoadGun(val, entry.Def, entry.Def);
				}
			}
		}

		[HarmonyPatch(typeof(NutcrackerEnemyAI), "SpawnShotgunShells")]
		[HarmonyPrefix]
		private static bool Drop(NutcrackerEnemyAI __instance)
		{
			//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_0065: 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_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_009c: 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_0101: Unknown result type (might be due to invalid IL or missing references)
			if (!((NetworkBehaviour)__instance).IsOwner || Plugin.Cfg.NutDropChance.Value <= 0 || Shells.Pick() == null)
			{
				return true;
			}
			GameObject val = shellPrefab.Invoke(__instance);
			if ((Object)(object)val == (Object)null || (Object)(object)RoundManager.Instance == (Object)null)
			{
				return true;
			}
			try
			{
				for (int i = 0; i < 2; i++)
				{
					Vector3 val2 = ((Component)__instance).transform.position + Vector3.up * 0.6f + new Vector3(Random.Range(-0.8f, 0.8f), 0f, Random.Range(-0.8f, 0.8f));
					GameObject val3 = val;
					if (Roll(Plugin.Cfg.NutDropChance.Value))
					{
						Shells.Entry entry = Shells.Pick();
						if (entry != null && (Object)(object)entry.Def.Item != (Object)null && (Object)(object)entry.Def.Item.spawnPrefab != (Object)null)
						{
							val3 = entry.Def.Item.spawnPrefab;
						}
					}
					GameObject obj = Object.Instantiate<GameObject>(val3, val2, Quaternion.identity, RoundManager.Instance.spawnedScrapContainer);
					obj.GetComponent<GrabbableObject>().fallTime = 0f;
					obj.GetComponent<NetworkObject>().Spawn(false);
				}
			}
			catch (Exception ex)
			{
				Plugin.Log.LogWarning((object)("Nutcracker shells: " + ex.Message));
			}
			return false;
		}
	}
	[BepInPlugin("Miles.MoreShotgunShells", "MoreShotgunShells", "1.0.0")]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[BepInDependency("com.sigurd.csync", "5.0.0")]
	public class Plugin : BaseUnityPlugin
	{
		public const string Guid = "Miles.MoreShotgunShells";

		public const string Name = "MoreShotgunShells";

		public const string Version = "1.0.0";

		internal static ManualLogSource Log;

		internal static ShellsConfig Cfg;

		private void Awake()
		{
			//IL_0069: 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)
			Log = ((BaseUnityPlugin)this).Logger;
			Cfg = new ShellsConfig(((BaseUnityPlugin)this).Config);
			((SyncedConfig2<ShellsConfig>)Cfg).InitialSyncCompleted += delegate
			{
				Shells.ApplyPrices("config synced from host");
			};
			ShellRegistry.Registering += Shells.Register;
			Harmony val = new Harmony("Miles.MoreShotgunShells");
			val.PatchAll(typeof(Shells));
			val.PatchAll(typeof(Nutcracker));
			Log.LogInfo((object)"MoreShotgunShells 1.0.0 loaded.");
		}
	}
	internal static class Shells
	{
		internal class Entry
		{
			public string Short;

			public Color32 Hud;

			public Color32 Hull;

			public string Info;

			public Func<bool> On;

			public Func<int> Price;

			public Func<int> Rarity;

			public ShellDef Def;
		}

		internal static readonly List<Entry> All = new List<Entry>();

		internal const int MinValue = 15;

		internal const int MaxValue = 25;

		private static int Scaled(int hits, float perPellet)
		{
			return Mathf.Max(1, Mathf.RoundToInt((float)hits * Mathf.Max(perPellet, 0f)));
		}

		private static void Build()
		{
			//IL_003f: 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_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_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)
			//IL_00ce: 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_00e0: 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_0109: Expected O, but got Unknown
			//IL_0135: Unknown result type (might be due to invalid IL or missing references)
			//IL_013a: Unknown result type (might be due to invalid IL or missing references)
			//IL_014e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0153: 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)
			//IL_019f: 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)
			//IL_01bc: 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_01e5: Expected O, but got Unknown
			//IL_0214: Unknown result type (might be due to invalid IL or missing references)
			//IL_0219: 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_027f: 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_0296: Unknown result type (might be due to invalid IL or missing references)
			//IL_02a1: Unknown result type (might be due to invalid IL or missing references)
			//IL_02b3: Unknown result type (might be due to invalid IL or missing references)
			//IL_02ca: Expected O, but got Unknown
			//IL_02f6: Unknown result type (might be due to invalid IL or missing references)
			//IL_02fb: Unknown result type (might be due to invalid IL or missing references)
			//IL_030f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0314: Unknown result type (might be due to invalid IL or missing references)
			//IL_035b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0360: Unknown result type (might be due to invalid IL or missing references)
			//IL_0372: Unknown result type (might be due to invalid IL or missing references)
			//IL_037d: Unknown result type (might be due to invalid IL or missing references)
			//IL_038f: Unknown result type (might be due to invalid IL or missing references)
			//IL_03a1: Unknown result type (might be due to invalid IL or missing references)
			//IL_03b6: Unknown result type (might be due to invalid IL or missing references)
			//IL_03c5: Unknown result type (might be due to invalid IL or missing references)
			//IL_03e6: Unknown result type (might be due to invalid IL or missing references)
			//IL_040c: Expected O, but got Unknown
			ShellsConfig c = Plugin.Cfg;
			All.Clear();
			All.Add(new Entry
			{
				Short = "Slug",
				Hud = new Color32((byte)90, (byte)220, (byte)100, byte.MaxValue),
				Hull = new Color32((byte)45, (byte)150, (byte)55, byte.MaxValue),
				Info = "One precise shot instead of a spread. Hits hard at any range.",
				On = () => c.SlugOn.Value,
				Price = () => c.SlugPrice.Value,
				Rarity = () => c.SlugRarity.Value,
				Def = new ShellDef
				{
					Pellets = () => 1,
					Spread = 0f,
					Choke = false,
					EnemyDamage = (int hits) => Scaled(hits, c.SlugDamage.Value),
					PlayerDamagePerPellet = () => c.SlugPlayerDamage.Value
				}
			});
			All.Add(new Entry
			{
				Short = "Bird",
				Hud = new Color32((byte)185, (byte)110, byte.MaxValue, byte.MaxValue),
				Hull = new Color32((byte)120, (byte)50, (byte)175, byte.MaxValue),
				Info = "20 small pellets with a wide spread. Weaker per pellet, but deadly up close.",
				On = () => c.BirdOn.Value,
				Price = () => c.BirdPrice.Value,
				Rarity = () => c.BirdRarity.Value,
				Def = new ShellDef
				{
					Pellets = () => c.BirdPellets.Value,
					Spread = 16f,
					EnemyDamage = (int hits) => Scaled(hits, c.BirdDamage.Value),
					PlayerDamagePerPellet = () => c.BirdPlayerDamage.Value
				}
			});
			All.Add(new Entry
			{
				Short = "Magnum",
				Hud = new Color32((byte)205, (byte)210, (byte)218, byte.MaxValue),
				Hull = new Color32((byte)178, (byte)182, (byte)190, byte.MaxValue),
				Info = "6 heavy, high-power pellets. Enough to drop an Eyeless Dog in one shot.",
				On = () => c.MagnumOn.Value,
				Price = () => c.MagnumPrice.Value,
				Rarity = () => c.MagnumRarity.Value,
				Def = new ShellDef
				{
					Pellets = () => c.MagnumPellets.Value,
					Spread = 8f,
					EnemyDamage = (int hits) => Scaled(hits, c.MagnumDamage.Value),
					PlayerDamagePerPellet = () => c.MagnumPlayerDamage.Value
				}
			});
			All.Add(new Entry
			{
				Short = "Dragon",
				Hud = new Color32(byte.MaxValue, (byte)140, (byte)35, byte.MaxValue),
				Hull = new Color32((byte)225, (byte)100, (byte)20, byte.MaxValue),
				Info = "8 incendiary pellets. Sets what it hits on fire. Forest Keepers burn.",
				On = () => c.DragonOn.Value,
				Price = () => c.DragonPrice.Value,
				Rarity = () => c.DragonRarity.Value,
				Def = new ShellDef
				{
					Pellets = () => c.DragonPellets.Value,
					Spread = 13f,
					EnemyDamage = (int hits) => Scaled(hits, c.DragonDamage.Value),
					PlayerDamagePerPellet = () => c.DragonPlayerDamage.Value,
					TracerColor = new Color(1f, 0.38f, 0.05f, 1f),
					OnEnemyHit = Burn.Damage,
					OnEnemyHitSeen = Burn.Fx
				}
			});
		}

		internal static string Name(Entry e)
		{
			return e.Short + " Shell";
		}

		internal static int Price(Entry e)
		{
			if (!e.On())
			{
				return -1;
			}
			return e.Price();
		}

		internal static int Rarity(Entry e)
		{
			if (!e.On())
			{
				return 0;
			}
			return Mathf.Max(e.Rarity(), 0);
		}

		internal static void Register(Item ammo)
		{
			//IL_0045: Unknown result type (might be due to invalid IL or missing references)
			//IL_018d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0192: Unknown result type (might be due to invalid IL or missing references)
			Build();
			Material vanillaShellMaterial = ShellRegistry.VanillaShellMaterial;
			Texture src = (((Object)(object)vanillaShellMaterial != (Object)null) ? vanillaShellMaterial.GetTexture("_BaseColorMap") : null);
			foreach (Entry item2 in All)
			{
				try
				{
					Material val = Recolor(vanillaShellMaterial, src, item2.Hull, item2.Short);
					GameObject val2 = NetworkPrefabs.CloneNetworkPrefab(ammo.spawnPrefab, "MoreShotgunShells" + item2.Short + "Shell");
					Item item = Object.Instantiate<Item>(ammo);
					((Object)item).name = "MoreShotgunShells" + item2.Short + "Shell";
					item.itemName = Name(item2);
					item.spawnPrefab = val2;
					item.isScrap = false;
					GrabbableObject[] componentsInChildren = val2.GetComponentsInChildren<GrabbableObject>(true);
					for (int i = 0; i < componentsInChildren.Length; i++)
					{
						componentsInChildren[i].itemProperties = item;
					}
					ScanNodeProperties[] componentsInChildren2 = val2.GetComponentsInChildren<ScanNodeProperties>(true);
					for (int i = 0; i < componentsInChildren2.Length; i++)
					{
						componentsInChildren2[i].headerText = Name(item2);
					}
					if ((Object)(object)val != (Object)null)
					{
						MeshRenderer[] componentsInChildren3 = val2.GetComponentsInChildren<MeshRenderer>(true);
						foreach (MeshRenderer val3 in componentsInChildren3)
						{
							if ((Object)(object)((Renderer)val3).sharedMaterial == (Object)(object)vanillaShellMaterial)
							{
								((Renderer)val3).sharedMaterial = val;
							}
						}
					}
					item2.Def.ShortName = item2.Short;
					item2.Def.HudColor = item2.Hud;
					item2.Def.Item = item;
					item2.Def.Material = val;
					item2.Def.Enabled = item2.On;
					if (ShellRegistry.Register(item2.Def) == null)
					{
						continue;
					}
					TerminalNode val4 = ScriptableObject.CreateInstance<TerminalNode>();
					((Object)val4).name = ((Object)item).name + "Info";
					val4.displayText = Name(item2) + "\n\n" + item2.Info + "\n\n";
					val4.clearPreviousText = true;
					val4.maxCharactersToType = 25;
					Items.RegisterShopItem(item, (TerminalNode)null, (TerminalNode)null, val4, Mathf.Max(Price(item2), 0));
					Items.RegisterScrap(item, Rarity(item2), (LevelTypes)(-1));
					Item val5 = ((IEnumerable<ScrapItem>)Items.scrapItems).FirstOrDefault((Func<ScrapItem, bool>)((ScrapItem s) => (Object)(object)s.origItem == (Object)(object)item || (Object)(object)s.item == (Object)(object)item))?.item;
					if ((Object)(object)val5 != (Object)null && (Object)(object)val5 != (Object)(object)item)
					{
						ShellRegistry.Map(val5, item2.Def);
					}
					Item[] array = (Item[])(object)new Item[2] { item, val5 };
					foreach (Item val6 in array)
					{
						if ((Object)(object)val6 != (Object)null)
						{
							val6.minValue = 37;
							val6.maxValue = 62;
						}
					}
				}
				catch (Exception arg)
				{
					Plugin.Log.LogError((object)$"{Name(item2)} could not be made: {arg}");
				}
			}
			Plugin.Log.LogInfo((object)("Shells registered: " + string.Join(", ", All.Select((Entry e) => Name(e) + (e.On() ? $" (on, rarity {Rarity(e)})" : " (off)")))));
		}

		internal static void ApplyPrices(string reason)
		{
			try
			{
				foreach (Entry item in All)
				{
					if ((Object)(object)item.Def.Item != (Object)null)
					{
						ShellRegistry.SetStorePrice(item.Def.Item, Price(item));
					}
				}
				Plugin.Log.LogInfo((object)("Store prices (" + reason + "): " + string.Join(", ", All.Select((Entry e) => Name(e) + " " + Price(e)))));
			}
			catch (Exception arg)
			{
				Plugin.Log.LogError((object)$"Store prices ({reason}) failed: {arg}");
			}
		}

		[HarmonyPatch(typeof(StartOfRound), "Start")]
		[HarmonyPostfix]
		[HarmonyPriority(200)]
		private static void LobbyStart()
		{
			if ((Object)(object)NetworkManager.Singleton != (Object)null && NetworkManager.Singleton.IsServer)
			{
				ApplyPrices("host lobby start");
			}
		}

		[HarmonyPatch(typeof(GrabbableObject), "Start")]
		[HarmonyPostfix]
		private static void BuckScanName(GrabbableObject __instance)
		{
			if (__instance is GunAmmo && ShellRegistry.Of(__instance) == ShellRegistry.Buck)
			{
				ScanNodeProperties[] componentsInChildren = ((Component)__instance).GetComponentsInChildren<ScanNodeProperties>(true);
				for (int i = 0; i < componentsInChildren.Length; i++)
				{
					componentsInChildren[i].headerText = "Buck Shell";
				}
			}
		}

		internal static Entry Pick()
		{
			List<Entry> list = All.Where((Entry e) => e.On() && (Object)(object)e.Def.Item != (Object)null).ToList();
			if (list.Count == 0)
			{
				return null;
			}
			int num = list.Sum((Entry e) => Mathf.Max(e.Rarity(), 0));
			if (num <= 0)
			{
				return list[Random.Range(0, list.Count)];
			}
			int num2 = Random.Range(0, num);
			foreach (Entry item in list)
			{
				num2 -= Mathf.Max(item.Rarity(), 0);
				if (num2 < 0)
				{
					return item;
				}
			}
			return list[list.Count - 1];
		}

		private static Material Recolor(Material baseMat, Texture src, Color32 hull, string label)
		{
			//IL_0269: 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_000c: 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_0023: Expected O, but got Unknown
			//IL_0032: Unknown result type (might be due to invalid IL or missing references)
			//IL_0033: Unknown result type (might be due to invalid IL or missing references)
			//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_0088: Expected O, but got Unknown
			//IL_00a1: Unknown result type (might be due to invalid IL or missing references)
			//IL_0110: Unknown result type (might be due to invalid IL or missing references)
			//IL_0115: Unknown result type (might be due to invalid IL or missing references)
			//IL_0117: Unknown result type (might be due to invalid IL or missing references)
			//IL_0125: Unknown result type (might be due to invalid IL or missing references)
			//IL_012d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0140: 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_0158: Unknown result type (might be due to invalid IL or missing references)
			//IL_0177: 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_01a1: 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)
			//IL_01b8: 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)
			if ((Object)(object)baseMat == (Object)null)
			{
				return null;
			}
			Material val = new Material(baseMat)
			{
				name = "MoreShotgunShells " + label
			};
			if ((Object)(object)src == (Object)null)
			{
				val.SetColor("_BaseColor", Color32.op_Implicit(hull));
				return val;
			}
			RenderTexture active = RenderTexture.active;
			RenderTexture temporary = RenderTexture.GetTemporary(src.width, src.height, 0, (RenderTextureFormat)0, (RenderTextureReadWrite)2);
			try
			{
				Graphics.Blit(src, temporary);
				RenderTexture.active = temporary;
				Texture2D val2 = new Texture2D(src.width, src.height, (TextureFormat)4, true, false)
				{
					name = ((Object)val).name
				};
				val2.ReadPixels(new Rect(0f, 0f, (float)src.width, (float)src.height), 0, 0);
				Color32[] pixels = val2.GetPixels32();
				int width = src.width;
				int height = src.height;
				int num = (int)(0.395f * (float)width);
				int num2 = (int)(0.537f * (float)width);
				int num3 = (int)(0.105f * (float)height);
				int num4 = (int)(0.288f * (float)height);
				int num5 = 0;
				for (int i = num3; i < num4; i++)
				{
					for (int j = num; j < num2; j++)
					{
						Color32 val3 = pixels[i * width + j];
						if (val3.r >= 50 && !((float)(int)val3.r < (float)(int)val3.g * 1.8f) && !((float)(int)val3.r < (float)(int)val3.b * 1.8f))
						{
							float num6 = (float)(int)val3.r / 160f;
							pixels[i * width + j] = new Color32((byte)Mathf.Min(255f, (float)(int)hull.r * num6), (byte)Mathf.Min(255f, (float)(int)hull.g * num6), (byte)Mathf.Min(255f, (float)(int)hull.b * num6), val3.a);
							num5++;
						}
					}
				}
				val2.SetPixels32(pixels);
				val2.Apply(true);
				val2.Compress(true);
				val2.Apply(false, true);
				val.SetTexture("_BaseColorMap", (Texture)(object)val2);
				val.SetTexture("_MainTex", (Texture)(object)val2);
				if (num5 < 100)
				{
					Plugin.Log.LogWarning((object)$"{label} Shell: the shell's colour area looked different than expected ({num5} pixels recoloured).");
				}
			}
			catch (Exception ex)
			{
				Plugin.Log.LogWarning((object)(label + " Shell: recolour failed (" + ex.Message + "), using a tint."));
				val.SetColor("_BaseColor", Color32.op_Implicit(hull));
			}
			finally
			{
				RenderTexture.active = active;
				RenderTexture.ReleaseTemporary(temporary);
			}
			return val;
		}
	}
	public class ShellsConfig : SyncedConfig2<ShellsConfig>
	{
		[field: SyncedEntryField]
		public SyncedEntry<bool> SlugOn { get; private set; }

		[field: SyncedEntryField]
		public SyncedEntry<int> SlugPrice { get; private set; }

		[field: SyncedEntryField]
		public SyncedEntry<int> SlugRarity { get; private set; }

		[field: SyncedEntryField]
		public SyncedEntry<float> SlugDamage { get; private set; }

		[field: SyncedEntryField]
		public SyncedEntry<int> SlugPlayerDamage { get; private set; }

		[field: SyncedEntryField]
		public SyncedEntry<bool> BirdOn { get; private set; }

		[field: SyncedEntryField]
		public SyncedEntry<int> BirdPrice { get; private set; }

		[field: SyncedEntryField]
		public SyncedEntry<int> BirdRarity { get; private set; }

		[field: SyncedEntryField]
		public SyncedEntry<int> BirdPellets { get; private set; }

		[field: SyncedEntryField]
		public SyncedEntry<float> BirdDamage { get; private set; }

		[field: SyncedEntryField]
		public SyncedEntry<int> BirdPlayerDamage { get; private set; }

		[field: SyncedEntryField]
		public SyncedEntry<bool> MagnumOn { get; private set; }

		[field: SyncedEntryField]
		public SyncedEntry<int> MagnumPrice { get; private set; }

		[field: SyncedEntryField]
		public SyncedEntry<int> MagnumRarity { get; private set; }

		[field: SyncedEntryField]
		public SyncedEntry<int> MagnumPellets { get; private set; }

		[field: SyncedEntryField]
		public SyncedEntry<float> MagnumDamage { get; private set; }

		[field: SyncedEntryField]
		public SyncedEntry<int> MagnumPlayerDamage { get; private set; }

		[field: SyncedEntryField]
		public SyncedEntry<bool> DragonOn { get; private set; }

		[field: SyncedEntryField]
		public SyncedEntry<int> DragonPrice { get; private set; }

		[field: SyncedEntryField]
		public SyncedEntry<int> DragonRarity { get; private set; }

		[field: SyncedEntryField]
		public SyncedEntry<int> DragonPellets { get; private set; }

		[field: SyncedEntryField]
		public SyncedEntry<float> DragonDamage { get; private set; }

		[field: SyncedEntryField]
		public SyncedEntry<int> DragonPlayerDamage { get; private set; }

		[field: SyncedEntryField]
		public SyncedEntry<int> DragonBurnDamage { get; private set; }

		[field: SyncedEntryField]
		public SyncedEntry<float> DragonBurnSeconds { get; private set; }

		[field: SyncedEntryField]
		public SyncedEntry<bool> DragonBurnsGiants { get; private set; }

		[field: SyncedEntryField]
		public SyncedEntry<int> NutLoadChance { get; private set; }

		[field: SyncedEntryField]
		public SyncedEntry<int> NutDropChance { get; private set; }

		public ShellsConfig(ConfigFile cfg)
			: base("Miles.MoreShotgunShells")
		{
			SlugOn = SyncedBindingExtensions.BindSyncedEntry<bool>(cfg, "Slug Shell", "Enabled", true, "Sell Slug Shells and let them spawn. A slug is one precise shot.");
			SlugPrice = SyncedBindingExtensions.BindSyncedEntry<int>(cfg, "Slug Shell", "Price", 70, "Store price of one Slug Shell (-1 = not sold).");
			SlugRarity = SyncedBindingExtensions.BindSyncedEntry<int>(cfg, "Slug Shell", "ScrapRarity", 6, "How often Slug Shells show up as scrap (0 = never). Uncommon (Buck Shell is 10). The shells' scrap rarities also decide which one a Nutcracker gets.");
			SlugDamage = SyncedBindingExtensions.BindSyncedEntry<float>(cfg, "Slug Shell", "Damage", 4f, "Enemy damage of the slug. Enemy damage is in shovel hits (an Eyeless Dog has 12 HP, a Thumper 4).");
			SlugPlayerDamage = SyncedBindingExtensions.BindSyncedEntry<int>(cfg, "Slug Shell", "PlayerDamage", 80, "Damage to a player hit by the slug (players have 100 HP).");
			BirdOn = SyncedBindingExtensions.BindSyncedEntry<bool>(cfg, "Bird Shell", "Enabled", true, "Sell Bird Shells and let them spawn. Lots of small pellets, wide spread: close to medium range.");
			BirdPrice = SyncedBindingExtensions.BindSyncedEntry<int>(cfg, "Bird Shell", "Price", 50, "Store price of one Bird Shell (-1 = not sold).");
			BirdRarity = SyncedBindingExtensions.BindSyncedEntry<int>(cfg, "Bird Shell", "ScrapRarity", 3, "How often Bird Shells show up as scrap (0 = never). Rare. The shells' scrap rarities also decide which one a Nutcracker gets.");
			BirdPellets = SyncedBindingExtensions.BindSyncedEntry<int>(cfg, "Bird Shell", "Pellets", 20, "Pellets per shot.");
			BirdDamage = SyncedBindingExtensions.BindSyncedEntry<float>(cfg, "Bird Shell", "DamagePerPellet", 0.4f, "Enemy damage per pellet (20 pellets x 0.4 = 8 if all hit). Enemy damage is in shovel hits (an Eyeless Dog has 12 HP, a Thumper 4).");
			BirdPlayerDamage = SyncedBindingExtensions.BindSyncedEntry<int>(cfg, "Bird Shell", "PlayerDamagePerPellet", 10, "Damage to a player per pellet.");
			MagnumOn = SyncedBindingExtensions.BindSyncedEntry<bool>(cfg, "Magnum Shell", "Enabled", true, "Sell Magnum Shells and let them spawn. Few heavy pellets.");
			MagnumPrice = SyncedBindingExtensions.BindSyncedEntry<int>(cfg, "Magnum Shell", "Price", 150, "Store price of one Magnum Shell (-1 = not sold).");
			MagnumRarity = SyncedBindingExtensions.BindSyncedEntry<int>(cfg, "Magnum Shell", "ScrapRarity", 1, "How often Magnum Shells show up as scrap (0 = never). Rarest. The shells' scrap rarities also decide which one a Nutcracker gets.");
			MagnumPellets = SyncedBindingExtensions.BindSyncedEntry<int>(cfg, "Magnum Shell", "Pellets", 6, "Pellets per shot.");
			MagnumDamage = SyncedBindingExtensions.BindSyncedEntry<float>(cfg, "Magnum Shell", "DamagePerPellet", 3f, "Enemy damage per pellet (4 of 6 pellets = 12 = a dead Eyeless Dog). Enemy damage is in shovel hits (an Eyeless Dog has 12 HP, a Thumper 4).");
			MagnumPlayerDamage = SyncedBindingExtensions.BindSyncedEntry<int>(cfg, "Magnum Shell", "PlayerDamagePerPellet", 40, "Damage to a player per pellet.");
			DragonOn = SyncedBindingExtensions.BindSyncedEntry<bool>(cfg, "Dragon Shell", "Enabled", true, "Sell Dragon Shells and let them spawn. Incendiary pellets that set enemies on fire.");
			DragonPrice = SyncedBindingExtensions.BindSyncedEntry<int>(cfg, "Dragon Shell", "Price", 150, "Store price of one Dragon Shell (-1 = not sold).");
			DragonRarity = SyncedBindingExtensions.BindSyncedEntry<int>(cfg, "Dragon Shell", "ScrapRarity", 1, "How often Dragon Shells show up as scrap (0 = never). Rarest. The shells' scrap rarities also decide which one a Nutcracker gets.");
			DragonPellets = SyncedBindingExtensions.BindSyncedEntry<int>(cfg, "Dragon Shell", "Pellets", 8, "Pellets per shot.");
			DragonDamage = SyncedBindingExtensions.BindSyncedEntry<float>(cfg, "Dragon Shell", "DamagePerPellet", 0.5f, "Enemy damage per pellet, before the burn. Enemy damage is in shovel hits (an Eyeless Dog has 12 HP, a Thumper 4).");
			DragonPlayerDamage = SyncedBindingExtensions.BindSyncedEntry<int>(cfg, "Dragon Shell", "PlayerDamagePerPellet", 15, "Damage to a player per pellet (players don't burn).");
			DragonBurnDamage = SyncedBindingExtensions.BindSyncedEntry<int>(cfg, "Dragon Shell", "BurnDamage", 2, "Total burn damage on an enemy that was hit (1 at a time, spread over the burn time).");
			DragonBurnSeconds = SyncedBindingExtensions.BindSyncedEntry<float>(cfg, "Dragon Shell", "BurnSeconds", 2f, "How long an enemy burns.");
			DragonBurnsGiants = SyncedBindingExtensions.BindSyncedEntry<bool>(cfg, "Dragon Shell", "BurnForestKeepers", true, "A Forest Keeper hit by a Dragon Shell catches fire like from an explosion, and burns to death (vanilla fire).");
			NutLoadChance = SyncedBindingExtensions.BindSyncedEntry<int>(cfg, "Nutcracker", "LoadChance", 10, "Percent chance that a Nutcracker loads one of the shells above (both barrels) when it reloads. 0 = always Buck. Only shells that are Enabled.");
			NutDropChance = SyncedBindingExtensions.BindSyncedEntry<int>(cfg, "Nutcracker", "DropChance", 10, "Percent chance for each of the 2 shells a dead Nutcracker drops to be one of the shells above. 0 = always Buck.");
			ConfigManager.Register<ShellsConfig>((SyncedConfig2<ShellsConfig>)this);
		}
	}
}