Decompiled source of CustomSwarms v1.0.0

CustomSwarms.dll

Decompiled a day ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using BepInEx;
using BepInEx.Bootstrap;
using BepInEx.Configuration;
using BepInEx.Logging;
using IL.RoR2;
using IL.RoR2.Artifacts;
using Microsoft.CodeAnalysis;
using Mono.Cecil.Cil;
using MonoMod.Cil;
using R2API;
using RiskOfOptions;
using RiskOfOptions.OptionConfigs;
using RiskOfOptions.Options;
using RoR2;
using RoR2.Artifacts;
using RoR2.ContentManagement;
using RoR2BepInExPack.GameAssetPaths.Version_1_39_0;
using UnityEngine;
using UnityEngine.AddressableAssets;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)]
[assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")]
[assembly: AssemblyCompany("CustomSwarms")]
[assembly: AssemblyConfiguration("Debug")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0+05f30cde21f9c2adc66e629aa85f73b5e936f21b")]
[assembly: AssemblyProduct("CustomSwarms")]
[assembly: AssemblyTitle("CustomSwarms")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.0.0.0")]
[module: UnverifiableCode]
[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 CustomSwarms
{
	public static class Assets
	{
		public static AssetBundle assetBundle;

		public static void Init()
		{
			GetAssetBundle();
		}

		private static void GetAssetBundle()
		{
			using Stream stream = Assembly.GetExecutingAssembly().GetManifestResourceStream("CustomSwarms.mwmwcustomswarms");
			if (stream != null)
			{
				assetBundle = AssetBundle.LoadFromStream(stream);
			}
		}
	}
	internal class ContentPacks : IContentPackProvider
	{
		internal ContentPack contentPack = new ContentPack();

		public static List<ItemDef> itemDefs = new List<ItemDef>();

		public string identifier => "Miyowi.CustomSwarms";

		public void Init()
		{
			//IL_0008: Unknown result type (might be due to invalid IL or missing references)
			//IL_0012: Expected O, but got Unknown
			ContentManager.collectContentPackProviders += new CollectContentPackProvidersDelegate(ContentManager_collectContentPackProviders);
		}

		private void ContentManager_collectContentPackProviders(AddContentPackProviderDelegate addContentPackProvider)
		{
			addContentPackProvider.Invoke((IContentPackProvider)(object)this);
		}

		public IEnumerator LoadStaticContentAsync(LoadStaticContentAsyncArgs args)
		{
			contentPack.identifier = identifier;
			contentPack.itemDefs.Add(itemDefs.ToArray());
			args.ReportProgress(1f);
			yield break;
		}

		public IEnumerator GenerateContentPackAsync(GetContentPackAsyncArgs args)
		{
			ContentPack.Copy(contentPack, args.output);
			args.ReportProgress(1f);
			yield break;
		}

		public IEnumerator FinalizeAsync(FinalizeAsyncArgs args)
		{
			args.ReportProgress(1f);
			yield break;
		}
	}
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[BepInPlugin("Miyowi.CustomSwarms", "CustomSwarms", "1.0.0")]
	public class CustomSwarms : BaseUnityPlugin
	{
		public static CustomSwarms instance;

		public const string PluginGUID = "Miyowi.CustomSwarms";

		public const string PluginAuthor = "Miyowi";

		public const string PluginName = "CustomSwarms";

		public const string PluginVersion = "1.0.0";

		public static PluginInfo pluginInfo;

		public static ConfigFile config;

		public static ItemDef CutOnePercentageHP;

		public void Awake()
		{
			//IL_004d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0057: Expected O, but got Unknown
			//IL_005f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0069: Expected O, but got Unknown
			//IL_0071: Unknown result type (might be due to invalid IL or missing references)
			//IL_007b: Expected O, but got Unknown
			//IL_0083: Unknown result type (might be due to invalid IL or missing references)
			//IL_008d: Expected O, but got Unknown
			instance = this;
			pluginInfo = ((BaseUnityPlugin)this).Info;
			config = ((BaseUnityPlugin)this).Config;
			Log.Init(((BaseUnityPlugin)this).Logger);
			Assets.Init();
			Options.Init();
			CreateItem();
			new ContentPacks().Init();
			RecalculateStatsAPI.GetStatCoefficients += new StatHookEventHandler(MaxHPDecrease);
			CharacterMaster.GetDeployableSameSlotLimit += new Manipulator(ModifySwarmsAllies);
			MasterSummon.Perform += new Manipulator(ModifyMasterSummonCutHP);
			SwarmsArtifactManager.OnSpawnCardOnSpawnedServerGlobal += new Manipulator(ModifySpawnResult);
		}

		private void ModifySpawnResult(ILContext il)
		{
			//IL_0052: Unknown result type (might be due to invalid IL or missing references)
			//IL_0059: Expected O, but got Unknown
			//IL_00bd: Unknown result type (might be due to invalid IL or missing references)
			//IL_013d: 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)
			Action<CharacterMaster> action = delegate(CharacterMaster master)
			{
				if (Object.op_Implicit((Object)(object)master))
				{
					master.inventory.GiveItemPermanent(CutOnePercentageHP, GetCutOnePercentageHPCount());
				}
			};
			int spawnValue = 0;
			uint expReward = 0u;
			uint goldReward = 0u;
			Action<DeathRewards> action2 = delegate(DeathRewards deathRewards)
			{
				if (Object.op_Implicit((Object)(object)deathRewards))
				{
					if (Options.customSpawnValueReward.Value)
					{
						spawnValue = (int)Mathf.Max(1f, (float)deathRewards.spawnValue / (float)Options.customSpawnValueRewardCount.Value);
					}
					else
					{
						spawnValue = (int)Mathf.Max(1f, (float)deathRewards.spawnValue / (float)Options.swarmsMultiplier.Value);
					}
					if (Options.customEXPReward.Value)
					{
						expReward = (uint)Mathf.Ceil((float)deathRewards.expReward / (float)Options.customEXPRewardCount.Value);
					}
					else
					{
						expReward = (uint)Mathf.Ceil((float)deathRewards.expReward / (float)Options.swarmsMultiplier.Value);
					}
					if (Options.customGoldReward.Value)
					{
						goldReward = (uint)Mathf.Ceil((float)deathRewards.goldReward / (float)Options.customGoldRewardCount.Value);
					}
					else
					{
						goldReward = (uint)Mathf.Ceil((float)deathRewards.goldReward / (float)Options.swarmsMultiplier.Value);
					}
				}
			};
			Action<DeathRewards> action3 = delegate(DeathRewards deathRewards)
			{
				if (Object.op_Implicit((Object)(object)deathRewards))
				{
					deathRewards.spawnValue = spawnValue;
					deathRewards.expReward = expReward;
					deathRewards.goldReward = goldReward;
				}
			};
			int masterLoc = 0;
			ILCursor val = new ILCursor(il);
			if (val.TryGotoNext(new Func<Instruction, bool>[1]
			{
				(Instruction x) => ILPatternMatchingExt.MatchCallOrCallvirt<Inventory>(x, "GiveItemPermanent")
			}) && val.TryGotoNext((MoveType)2, new Func<Instruction, bool>[1]
			{
				(Instruction x) => ILPatternMatchingExt.MatchLdloc(x, ref masterLoc)
			}))
			{
				val.Emit(OpCodes.Ldloc, masterLoc);
				val.EmitDelegate<Action<CharacterMaster>>(action);
				int deathRewardsLoc = 0;
				if (val.TryGotoNext(new Func<Instruction, bool>[1]
				{
					(Instruction x) => ILPatternMatchingExt.MatchCallOrCallvirt<GameObject>(x, "GetComponent")
				}) && val.TryGotoNext((MoveType)2, new Func<Instruction, bool>[1]
				{
					(Instruction x) => ILPatternMatchingExt.MatchStloc(x, ref deathRewardsLoc)
				}))
				{
					val.Emit(OpCodes.Ldloc, deathRewardsLoc);
					val.EmitDelegate<Action<DeathRewards>>(action2);
					if (val.TryGotoNext((MoveType)0, new Func<Instruction, bool>[1]
					{
						(Instruction x) => ILPatternMatchingExt.MatchLdsfld(x, typeof(SwarmsArtifactManager), "inSpawn")
					}))
					{
						val.Emit(OpCodes.Ldloc, deathRewardsLoc);
						val.EmitDelegate<Action<DeathRewards>>(action3);
					}
					else
					{
						Log.Error("Part 3 of ModifySpawnResult ILHook failed! Enemies will have their death rewards unchanged!");
					}
				}
				else
				{
					Log.Error("Part 2 of ModifySpawnResult ILHook failed! Enemies will have their death rewards unchanged!");
				}
			}
			else
			{
				Log.Error("Part 1 of ModifySpawnResult ILHook failed! Enemies will have their death rewards and HP unchanged!");
			}
		}

		private int GetCutOnePercentageHPCount()
		{
			int value = Options.swarmsMultiplier.Value;
			if (Options.customHPCut.Value)
			{
				value = Options.customHPCutCount.Value;
			}
			return (int)(100f - 100f / (float)value * 2f + 0.5f);
		}

		private void MaxHPDecrease(CharacterBody sender, StatHookEventArgs args)
		{
			//IL_0030: Unknown result type (might be due to invalid IL or missing references)
			if (Object.op_Implicit((Object)(object)sender) && Object.op_Implicit((Object)(object)sender.inventory))
			{
				args.healthTotalMult *= (float)(100 - sender.inventory.GetItemCountEffective(CutOnePercentageHP.itemIndex)) / 100f;
			}
		}

		private void ModifySwarmsAllies(ILContext il)
		{
			//IL_0022: Unknown result type (might be due to invalid IL or missing references)
			//IL_0028: Expected O, but got Unknown
			Func<int, int> func = (int _) => Options.swarmsMultiplier.Value;
			ILCursor val = new ILCursor(il);
			ILLabel val2 = default(ILLabel);
			int num = default(int);
			if (val.TryGotoNext(new Func<Instruction, bool>[1]
			{
				(Instruction x) => ILPatternMatchingExt.MatchCallOrCallvirt<RunArtifactManager>(x, "IsArtifactEnabled")
			}) && val.TryGotoNext(new Func<Instruction, bool>[1]
			{
				(Instruction x) => ILPatternMatchingExt.MatchBrfalse(x, ref val2)
			}) && val.TryGotoNext((MoveType)2, new Func<Instruction, bool>[1]
			{
				(Instruction x) => ILPatternMatchingExt.MatchLdcI4(x, ref num)
			}))
			{
				val.EmitDelegate<Func<int, int>>(func);
			}
			else
			{
				Log.Error("ModifySwarmsAllies ILHook failed! Certain deployable ally counts are unchanged!");
			}
		}

		private void ModifyMasterSummonCutHP(ILContext il)
		{
			//IL_0023: Unknown result type (might be due to invalid IL or missing references)
			//IL_0029: Expected O, but got Unknown
			//IL_00de: Unknown result type (might be due to invalid IL or missing references)
			Action<CharacterMaster> action = delegate(CharacterMaster master)
			{
				master.inventory.GiveItemPermanent(CutOnePercentageHP, GetCutOnePercentageHPCount());
			};
			int masterLoc = 0;
			ILCursor val = new ILCursor(il);
			if (val.TryGotoNext(new Func<Instruction, bool>[1]
			{
				(Instruction x) => ILPatternMatchingExt.MatchCallOrCallvirt<RunArtifactManager>(x, "IsArtifactEnabled")
			}) && val.TryGotoNext(new Func<Instruction, bool>[1]
			{
				(Instruction x) => ILPatternMatchingExt.MatchLdloc(x, ref masterLoc)
			}) && val.TryGotoNext(new Func<Instruction, bool>[1]
			{
				(Instruction x) => ILPatternMatchingExt.MatchLdsfld(x, typeof(Items), "CutHp")
			}) && val.TryGotoNext((MoveType)2, new Func<Instruction, bool>[1]
			{
				(Instruction x) => ILPatternMatchingExt.MatchCallOrCallvirt<Inventory>(x, "GiveItemPermanent")
			}))
			{
				val.Emit(OpCodes.Ldloc, masterLoc);
				val.EmitDelegate<Action<CharacterMaster>>(action);
			}
			else
			{
				Log.Error("ModifyMasterSummonCutHP ILHook failed! Certain entities will have their HP unchanged!");
			}
		}

		private static void CreateItem()
		{
			//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)
			//IL_00aa: 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_00c6: Unknown result type (might be due to invalid IL or missing references)
			string text = "CUSTOMSWARMS_CUTHP";
			CutOnePercentageHP = ScriptableObject.CreateInstance<ItemDef>();
			((Object)CutOnePercentageHP).name = text + "_NAME";
			CutOnePercentageHP.nameToken = text + "_NAME";
			CutOnePercentageHP.pickupToken = text + "_PICKUP";
			CutOnePercentageHP.descriptionToken = text + "_DESC";
			CutOnePercentageHP.loreToken = text + "_LORE";
			CutOnePercentageHP.tags = (ItemTag[])(object)new ItemTag[1] { (ItemTag)9 };
			CutOnePercentageHP.deprecatedTier = (ItemTier)5;
			CutOnePercentageHP.pickupIconSprite = Addressables.LoadAssetAsync<Sprite>((object)RoR2_Base_Common_MiscIcons.texMysteryIcon_png).WaitForCompletion();
			CutOnePercentageHP.pickupModelPrefab = Addressables.LoadAssetAsync<GameObject>((object)RoR2_Base_Mystery.PickupMystery_prefab).WaitForCompletion();
			CutOnePercentageHP.hidden = true;
			ContentPacks.itemDefs.Add(CutOnePercentageHP);
		}
	}
	internal static class Log
	{
		private static ManualLogSource _logSource;

		internal static void Init(ManualLogSource logSource)
		{
			_logSource = logSource;
		}

		internal static void Debug(object data)
		{
			_logSource.LogDebug(data);
		}

		internal static void Error(object data)
		{
			_logSource.LogError(data);
		}

		internal static void Fatal(object data)
		{
			_logSource.LogFatal(data);
		}

		internal static void Info(object data)
		{
			_logSource.LogInfo(data);
		}

		internal static void Message(object data)
		{
			_logSource.LogMessage(data);
		}

		internal static void Warning(object data)
		{
			_logSource.LogWarning(data);
		}
	}
	public class Options
	{
		private static bool? _rooEnabled;

		public static bool rooEnabled
		{
			get
			{
				if (!_rooEnabled.HasValue)
				{
					_rooEnabled = Chainloader.PluginInfos.ContainsKey("com.rune580.riskofoptions");
				}
				return _rooEnabled.Value;
			}
		}

		public static ConfigEntry<int> swarmsMultiplier { get; set; }

		public static ConfigEntry<bool> customHPCut { get; set; }

		public static ConfigEntry<int> customHPCutCount { get; set; }

		public static ConfigEntry<bool> customGoldReward { get; set; }

		public static ConfigEntry<int> customGoldRewardCount { get; set; }

		public static ConfigEntry<bool> customSpawnValueReward { get; set; }

		public static ConfigEntry<int> customSpawnValueRewardCount { get; set; }

		public static ConfigEntry<bool> customEXPReward { get; set; }

		public static ConfigEntry<int> customEXPRewardCount { get; set; }

		private static void ModifySwarmsSpawnCount()
		{
			SwarmsArtifactManager.swarmSpawnCount = swarmsMultiplier.Value;
		}

		public static void Init()
		{
			swarmsMultiplier = CustomSwarms.config.Bind<int>("Artifact of Swarms", "Swarms Multiplier", 2, "The number of enemies and health/rewards division spawned by the Artifact of Swarms.");
			swarmsMultiplier.SettingChanged += delegate
			{
				ModifySwarmsSpawnCount();
			};
			customHPCut = CustomSwarms.config.Bind<bool>("Artifact of Swarms", "Use Custom HP Cut", false, "Whether or not the health of enemies is affected by the Swarms Multiplier option, or the below custom option.");
			customHPCutCount = CustomSwarms.config.Bind<int>("Artifact of Swarms", "Custom HP Cut Effective Swarms Multiplier", 2, "The value that swarms enemies get their HP divided by if the above option is ticked.");
			customGoldReward = CustomSwarms.config.Bind<bool>("Artifact of Swarms", "Use Custom Gold Reward", false, "Whether or not the gold reward of enemies is affected by the Swarms Multiplier option, or the below custom option.");
			customGoldRewardCount = CustomSwarms.config.Bind<int>("Artifact of Swarms", "Custom Gold Reward Effective Swarms Multiplier", 2, "The value that swarms enemies get their gold reward divided by if the above option is ticked.");
			customSpawnValueReward = CustomSwarms.config.Bind<bool>("Artifact of Swarms", "Use Custom Spawn Value", false, "Whether or not the spawn value of enemies is affected by the Swarms Multiplier option, or the below custom option.");
			customSpawnValueRewardCount = CustomSwarms.config.Bind<int>("Artifact of Swarms", "Custom Spawn Value Effective Swarms Multiplier", 2, "The value that swarms enemies get their spawn value divided by if the above option is ticked (spawn value is the chance to drop items in certain contexts, e.g. artifact keys, artifact of sacrifice items).");
			customEXPReward = CustomSwarms.config.Bind<bool>("Artifact of Swarms", "Use Custom EXP Reward", false, "Whether or not the EXP reward of enemies is affected by the Swarms Multiplier option, or the below custom option.");
			customEXPRewardCount = CustomSwarms.config.Bind<int>("Artifact of Swarms", "Custom EXP Reward Effective Swarms Multiplier", 2, "The value that swarms enemies get their EXP reward divided by if the above option is ticked.");
			if (rooEnabled)
			{
				RoOInit();
			}
			ModifySwarmsSpawnCount();
		}

		private static void RoOInit()
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_000b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0012: Unknown result type (might be due to invalid IL or missing references)
			//IL_001f: Expected O, but got Unknown
			//IL_001a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0024: Expected O, but got Unknown
			//IL_002a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0034: Expected O, but got Unknown
			//IL_002f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0039: Expected O, but got Unknown
			//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_004b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0058: Expected O, but got Unknown
			//IL_0053: Unknown result type (might be due to invalid IL or missing references)
			//IL_005d: Expected O, but got Unknown
			//IL_0063: Unknown result type (might be due to invalid IL or missing references)
			//IL_006d: Expected O, but got Unknown
			//IL_0068: Unknown result type (might be due to invalid IL or missing references)
			//IL_0072: Expected O, but got Unknown
			//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_0084: Unknown result type (might be due to invalid IL or missing references)
			//IL_0091: Expected O, but got Unknown
			//IL_008c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0096: Expected O, but got Unknown
			//IL_009c: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a6: Expected O, but got Unknown
			//IL_00a1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ab: Expected O, but got Unknown
			//IL_00b1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b6: 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_00ca: Expected O, but got Unknown
			//IL_00c5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00cf: Expected O, but got Unknown
			//IL_00d5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00df: Expected O, but got Unknown
			//IL_00da: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e4: Expected O, but got Unknown
			//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)
			//IL_00f6: Unknown result type (might be due to invalid IL or missing references)
			//IL_0103: Expected O, but got Unknown
			//IL_00fe: Unknown result type (might be due to invalid IL or missing references)
			//IL_0108: Expected O, but got Unknown
			ModSettingsManager.AddOption((BaseOption)new IntSliderOption(swarmsMultiplier, new IntSliderConfig
			{
				min = 2,
				max = 50
			}));
			ModSettingsManager.AddOption((BaseOption)new CheckBoxOption(customHPCut, new CheckBoxConfig()));
			ModSettingsManager.AddOption((BaseOption)new IntSliderOption(customHPCutCount, new IntSliderConfig
			{
				min = 2,
				max = 50
			}));
			ModSettingsManager.AddOption((BaseOption)new CheckBoxOption(customGoldReward, new CheckBoxConfig()));
			ModSettingsManager.AddOption((BaseOption)new IntSliderOption(customGoldRewardCount, new IntSliderConfig
			{
				min = 1,
				max = 50
			}));
			ModSettingsManager.AddOption((BaseOption)new CheckBoxOption(customSpawnValueReward, new CheckBoxConfig()));
			ModSettingsManager.AddOption((BaseOption)new IntSliderOption(customSpawnValueRewardCount, new IntSliderConfig
			{
				min = 1,
				max = 50
			}));
			ModSettingsManager.AddOption((BaseOption)new CheckBoxOption(customEXPReward, new CheckBoxConfig()));
			ModSettingsManager.AddOption((BaseOption)new IntSliderOption(customEXPRewardCount, new IntSliderConfig
			{
				min = 1,
				max = 50
			}));
			ModSettingsManager.SetModDescription("Config options relating to the CustomSwarms mod.");
			ModSettingsManager.SetModIcon(Assets.assetBundle.LoadAsset<Sprite>("icon"));
		}
	}
}