Please disclose if any significant portion of your mod was created using AI tools by adding the 'AI Generated' category. Failing to do so may result in the mod being removed from Thunderstore.
Decompiled source of MoreShotgunShells v1.0.0
MoreShotgunShells.dll
Decompiled 5 hours agousing 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); } } }