Decompiled source of DualFungus v1.2.2

BepInEx/plugins/DualFungus/DaulFungus.dll

Decompiled 2 weeks ago
using System;
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.Logging;
using Microsoft.CodeAnalysis;
using On.RoR2.Items;
using R2API;
using RoR2;
using RoR2.Items;
using UnityEngine;
using UnityEngine.AddressableAssets;
using UnityEngine.Networking;

[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("DualFungus - Copy")]
[assembly: AssemblyConfiguration("Debug")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0")]
[assembly: AssemblyProduct("DualFungus - Copy")]
[assembly: AssemblyTitle("DualFungus - Copy")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.0.0.0")]
[module: UnverifiableCode]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	[AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)]
	internal sealed class RefSafetyRulesAttribute : Attribute
	{
		public readonly int Version;

		public RefSafetyRulesAttribute(int P_0)
		{
			Version = P_0;
		}
	}
}
namespace ExamplePlugin
{
	internal static class Log
	{
		private static ManualLogSource _logSource;

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

		private static string Format(object data, string file, int line)
		{
			string fileName = Path.GetFileName(file);
			return $"[{fileName}:{line}] {data}";
		}

		internal static void Debug(object data, [CallerFilePath] string file = "", [CallerLineNumber] int line = 0)
		{
			_logSource.LogDebug((object)Format(data, file, line));
		}

		internal static void Error(object data, [CallerFilePath] string file = "", [CallerLineNumber] int line = 0)
		{
			_logSource.LogError((object)Format(data, file, line));
		}

		internal static void Fatal(object data, [CallerFilePath] string file = "", [CallerLineNumber] int line = 0)
		{
			_logSource.LogFatal((object)Format(data, file, line));
		}

		internal static void Info(object data, [CallerFilePath] string file = "", [CallerLineNumber] int line = 0)
		{
			_logSource.LogInfo((object)Format(data, file, line));
		}

		internal static void Message(object data, [CallerFilePath] string file = "", [CallerLineNumber] int line = 0)
		{
			_logSource.LogMessage((object)Format(data, file, line));
		}

		internal static void Warning(object data, [CallerFilePath] string file = "", [CallerLineNumber] int line = 0)
		{
			_logSource.LogWarning((object)Format(data, file, line));
		}
	}
}
namespace DualFungusMod
{
	[BepInPlugin("com.yourname.DualFungus", "Dual Fungus Pack", "1.1.0")]
	[BepInDependency("com.bepis.r2api", "5.3.0")]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[BepInProcess("Risk of Rain 2.exe")]
	public class DualFungus : BaseUnityPlugin
	{
		public static ItemDef surgingItem;

		public static ItemDef cataclysmicItem;

		private static bool inBungusPatch;

		public void Awake()
		{
			CreateItems();
			AddHooks();
			RoR2Application.onLoad = (Action)Delegate.Combine(RoR2Application.onLoad, new Action(AttachDisplayRules));
			((BaseUnityPlugin)this).Logger.LogInfo((object)"[Dual Fungus] Loaded.");
		}

		private void AttachDisplayRules()
		{
			//IL_00f2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f7: Unknown result type (might be due to invalid IL or missing references)
			//IL_011a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0126: Unknown result type (might be due to invalid IL or missing references)
			//IL_012b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0138: Unknown result type (might be due to invalid IL or missing references)
			//IL_0144: Unknown result type (might be due to invalid IL or missing references)
			//IL_0149: Unknown result type (might be due to invalid IL or missing references)
			ItemDef mushroom = Items.Mushroom;
			HashSet<ItemDisplayRuleSet> hashSet = new HashSet<ItemDisplayRuleSet>();
			foreach (GameObject allBodyPrefab in BodyCatalog.allBodyPrefabs)
			{
				if ((Object)(object)allBodyPrefab == (Object)null)
				{
					continue;
				}
				CharacterModel componentInChildren = allBodyPrefab.GetComponentInChildren<CharacterModel>();
				if ((Object)(object)componentInChildren == (Object)null || (Object)(object)componentInChildren.itemDisplayRuleSet == (Object)null || !hashSet.Add(componentInChildren.itemDisplayRuleSet))
				{
					continue;
				}
				ItemDisplayRuleSet itemDisplayRuleSet = componentInChildren.itemDisplayRuleSet;
				KeyAssetRuleGroup[] keyAssetRuleGroups = itemDisplayRuleSet.keyAssetRuleGroups;
				if (keyAssetRuleGroups == null)
				{
					continue;
				}
				int num = -1;
				for (int i = 0; i < keyAssetRuleGroups.Length; i++)
				{
					if (keyAssetRuleGroups[i].keyAsset == (Object)(object)mushroom)
					{
						num = i;
						break;
					}
				}
				if (num >= 0)
				{
					KeyAssetRuleGroup template = keyAssetRuleGroups[num];
					KeyAssetRuleGroup[] array = (KeyAssetRuleGroup[])(object)new KeyAssetRuleGroup[keyAssetRuleGroups.Length + 2];
					Array.Copy(keyAssetRuleGroups, array, keyAssetRuleGroups.Length);
					array[keyAssetRuleGroups.Length] = CloneGroup(template, surgingItem, 1.4f);
					array[keyAssetRuleGroups.Length + 1] = CloneGroup(template, cataclysmicItem, 2f);
					itemDisplayRuleSet.keyAssetRuleGroups = array;
					itemDisplayRuleSet.GenerateRuntimeValues();
				}
			}
		}

		private static KeyAssetRuleGroup CloneGroup(KeyAssetRuleGroup template, ItemDef newItem, float scaleMul)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			//IL_0025: Unknown result type (might be due to invalid IL or missing references)
			//IL_002a: Unknown result type (might be due to invalid IL or missing references)
			//IL_003d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0043: Unknown result type (might be due to invalid IL or missing references)
			//IL_0048: Unknown result type (might be due to invalid IL or missing references)
			//IL_005e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0070: Unknown result type (might be due to invalid IL or missing references)
			//IL_007e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0080: Unknown result type (might be due to invalid IL or missing references)
			//IL_0085: Unknown result type (might be due to invalid IL or missing references)
			//IL_0087: Unknown result type (might be due to invalid IL or missing references)
			//IL_008b: Unknown result type (might be due to invalid IL or missing references)
			ItemDisplayRule[] rules = template.displayRuleGroup.rules;
			ItemDisplayRule[] array = (ItemDisplayRule[])(object)new ItemDisplayRule[(rules != null) ? rules.Length : 0];
			for (int i = 0; i < array.Length; i++)
			{
				array[i] = rules[i];
				array[i].localScale = rules[i].localScale * scaleMul;
			}
			KeyAssetRuleGroup result = default(KeyAssetRuleGroup);
			result.keyAsset = (Object)(object)newItem;
			result.displayRuleGroup = new DisplayRuleGroup
			{
				rules = array
			};
			return result;
		}

		private void CreateItems()
		{
			//IL_0191: Unknown result type (might be due to invalid IL or missing references)
			//IL_0196: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ca: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d4: Expected O, but got Unknown
			//IL_01cf: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d9: Expected O, but got Unknown
			//IL_01e4: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ee: Expected O, but got Unknown
			//IL_01e9: Unknown result type (might be due to invalid IL or missing references)
			//IL_01f3: Expected O, but got Unknown
			surgingItem = ScriptableObject.CreateInstance<ItemDef>();
			((Object)surgingItem).name = "ITEM_SURGINGFUNGUS";
			surgingItem.nameToken = "ITEM_SURGINGFUNGUS_NAME";
			surgingItem.pickupToken = "ITEM_SURGINGFUNGUS_PICKUP";
			surgingItem.descriptionToken = "ITEM_SURGINGFUNGUS_DESC";
			surgingItem.loreToken = "ITEM_SURGINGFUNGUS_LORE";
			SetTier(surgingItem, "RoR2/Base/Common/Tier2Def.asset");
			surgingItem.canRemove = true;
			surgingItem.pickupIconSprite = LoadSprite("surging_icon.png");
			cataclysmicItem = ScriptableObject.CreateInstance<ItemDef>();
			((Object)cataclysmicItem).name = "ITEM_CATACLYSMICFUNGUS";
			cataclysmicItem.nameToken = "ITEM_CATACLYSMICFUNGUS_NAME";
			cataclysmicItem.pickupToken = "ITEM_CATACLYSMICFUNGUS_PICKUP";
			cataclysmicItem.descriptionToken = "ITEM_CATACLYSMICFUNGUS_DESC";
			cataclysmicItem.loreToken = "ITEM_CATACLYSMICFUNGUS_LORE";
			SetTier(cataclysmicItem, "RoR2/Base/Common/Tier3Def.asset");
			cataclysmicItem.canRemove = true;
			cataclysmicItem.pickupIconSprite = LoadSprite("cataclysmic_icon.png");
			LanguageAPI.Add("ITEM_SURGINGFUNGUS_NAME", "Surging Fungus");
			LanguageAPI.Add("ITEM_SURGINGFUNGUS_PICKUP", "An energetic bundle of mushrooms.");
			LanguageAPI.Add("ITEM_SURGINGFUNGUS_DESC", "Acts as three <style=cIsHealing>Bustling Fungus</style> stacks. Stacks increase healing radius and rate.");
			LanguageAPI.Add("ITEM_SURGINGFUNGUS_LORE", "\"The mycelium hums with quiet energy.\"");
			LanguageAPI.Add("ITEM_CATACLYSMICFUNGUS_NAME", "Cataclysmic Fungus");
			LanguageAPI.Add("ITEM_CATACLYSMICFUNGUS_PICKUP", "A catastrophic mass of mushrooms.");
			LanguageAPI.Add("ITEM_CATACLYSMICFUNGUS_DESC", "Acts as five <style=cIsHealing>Bustling Fungus</style> stacks. Greatly increases healing radius and rate.");
			LanguageAPI.Add("ITEM_CATACLYSMICFUNGUS_LORE", "\"It grows where life ends and life begins again.\"");
			ItemDef val = Addressables.LoadAssetAsync<ItemDef>((object)"RoR2/Base/Mushroom/Mushroom.asset").WaitForCompletion();
			surgingItem.pickupModelPrefab = val.pickupModelPrefab;
			cataclysmicItem.pickupModelPrefab = val.pickupModelPrefab;
			ItemAPI.Add(new CustomItem(surgingItem, new ItemDisplayRuleDict(Array.Empty<ItemDisplayRule>())));
			ItemAPI.Add(new CustomItem(cataclysmicItem, new ItemDisplayRuleDict(Array.Empty<ItemDisplayRule>())));
		}

		private void AddHooks()
		{
			//IL_0008: Unknown result type (might be due to invalid IL or missing references)
			//IL_0012: Expected O, but got Unknown
			MushroomBodyBehavior.FixedUpdate += new hook_FixedUpdate(AugmentBungus);
			CharacterBody.onBodyStartGlobal += delegate(CharacterBody body)
			{
				if (!Object.op_Implicit((Object)(object)((Component)body).GetComponent<IndependentFungusBehavior>()))
				{
					((Component)body).gameObject.AddComponent<IndependentFungusBehavior>();
				}
			};
		}

		private void AugmentBungus(orig_FixedUpdate orig, MushroomBodyBehavior self)
		{
			if (inBungusPatch)
			{
				orig.Invoke(self);
				return;
			}
			inBungusPatch = true;
			try
			{
				int stack = ((BaseItemBodyBehavior)self).stack;
				Inventory inventory = ((BaseItemBodyBehavior)self).body.inventory;
				int num = ((inventory != null) ? inventory.GetItemCount(surgingItem) : 0);
				int num2 = ((inventory != null) ? inventory.GetItemCount(cataclysmicItem) : 0);
				int num3 = num * 3 + num2 * 15;
				if (num3 > 0)
				{
					((BaseItemBodyBehavior)self).stack = Mathf.Max(1, stack + num3);
				}
				orig.Invoke(self);
				((BaseItemBodyBehavior)self).stack = stack;
			}
			finally
			{
				inBungusPatch = false;
			}
		}

		private static void SetTier(ItemDef item, string tierAddress)
		{
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			ItemTierDef value = Addressables.LoadAssetAsync<ItemTierDef>((object)tierAddress).WaitForCompletion();
			FieldInfo field = typeof(ItemDef).GetField("_itemTierDef", BindingFlags.Instance | BindingFlags.NonPublic);
			field.SetValue(item, value);
		}

		private static Sprite LoadSprite(string fileName)
		{
			//IL_004e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0054: Expected O, but got Unknown
			//IL_0085: Unknown result type (might be due to invalid IL or missing references)
			//IL_0094: Unknown result type (might be due to invalid IL or missing references)
			try
			{
				string directoryName = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location);
				string text = Path.Combine(directoryName, fileName);
				if (!File.Exists(text))
				{
					Debug.LogWarning((object)("[Dual Fungus] Icon not found: " + text));
					return null;
				}
				byte[] array = File.ReadAllBytes(text);
				Texture2D val = new Texture2D(2, 2, (TextureFormat)4, false);
				ImageConversion.LoadImage(val, array);
				((Texture)val).filterMode = (FilterMode)1;
				((Texture)val).wrapMode = (TextureWrapMode)1;
				return Sprite.Create(val, new Rect(0f, 0f, (float)((Texture)val).width, (float)((Texture)val).height), new Vector2(0.5f, 0.5f));
			}
			catch (Exception ex)
			{
				Debug.LogError((object)("[Dual Fungus] Error loading " + fileName + ": " + ex));
				return null;
			}
		}
	}
	public class IndependentFungusBehavior : NetworkBehaviour
	{
		private CharacterBody body;

		private GameObject ward;

		private float stillTime;

		private const float StandStillTime = 2f;

		private const float baseHeal = 0.045f;

		private const float perStack = 0.0225f;

		private const float interval = 0.25f;

		private void Start()
		{
			body = ((Component)this).GetComponent<CharacterBody>();
		}

		private void FixedUpdate()
		{
			if (!NetworkServer.active || (Object)(object)body == (Object)null || (Object)(object)body.inventory == (Object)null)
			{
				return;
			}
			Inventory inventory = body.inventory;
			int itemCount = inventory.GetItemCount(Items.Mushroom);
			int itemCount2 = inventory.GetItemCount(DualFungus.surgingItem);
			int itemCount3 = inventory.GetItemCount(DualFungus.cataclysmicItem);
			int num = itemCount2 * 3 + itemCount3 * 15;
			if (num <= 0 || itemCount > 0)
			{
				DestroyWard();
				return;
			}
			CharacterMotor characterMotor = body.characterMotor;
			bool flag = Object.op_Implicit((Object)(object)characterMotor) && (((Vector3)(ref characterMotor.velocity)).sqrMagnitude > 0.04f || !characterMotor.isGrounded);
			stillTime = (flag ? 0f : (stillTime + Time.fixedDeltaTime));
			if (stillTime >= 2f)
			{
				CreateWard(num);
			}
			else
			{
				DestroyWard();
			}
		}

		private void CreateWard(int stacks)
		{
			//IL_00bc: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d8: Unknown result type (might be due to invalid IL or missing references)
			//IL_0023: Unknown result type (might be due to invalid IL or missing references)
			//IL_0028: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)ward == (Object)null)
			{
				ward = Object.Instantiate<GameObject>(LegacyResourcesAPI.Load<GameObject>("Prefabs/NetworkedObjects/MushroomWard"), body.footPosition, Quaternion.identity);
				NetworkServer.Spawn(ward);
			}
			HealingWard component = ward.GetComponent<HealingWard>();
			TeamFilter component2 = ward.GetComponent<TeamFilter>();
			component.interval = 0.25f;
			component.healFraction = (0.045f + 0.0225f * (float)(stacks - 1)) * component.interval;
			component.healPoints = 0f;
			component.Networkradius = body.radius + 1.5f + 1.5f * (float)stacks;
			component2.teamIndex = body.teamComponent.teamIndex;
			ward.transform.position = body.footPosition;
		}

		private void DestroyWard()
		{
			if (Object.op_Implicit((Object)(object)ward))
			{
				Object.Destroy((Object)(object)ward);
				ward = null;
				stillTime = 0f;
			}
		}

		private void OnDisable()
		{
			DestroyWard();
		}
	}
}