Decompiled source of VoltasBand v0.3.1

plugins/VoltasBand.dll

Decompiled 13 hours ago
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Reflection;
using System.Runtime.CompilerServices;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using Microsoft.CodeAnalysis;
using R2API;
using R2API.Utils;
using RoR2;
using RoR2.Orbs;
using UnityEngine;
using UnityEngine.AddressableAssets;
using UnityEngine.Networking;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: AssemblyVersion("0.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 VoltasBand
{
	internal static class Balance
	{
		internal const float Cooldown = 10f;

		internal const float FirstStrikeDelay = 0.1f;

		internal const float StrikeInterval = 0.5f;

		internal const float BlastRadius = 5f;

		internal static float DamageMultiplier(int stacks)
		{
			if (stacks > 0)
			{
				return 1.5f * (float)stacks;
			}
			return 0f;
		}

		internal static bool HeavyHit(float damage, float baseDamage, float procCoefficient)
		{
			if (Finite(damage) && Finite(baseDamage) && Finite(procCoefficient) && baseDamage > 0f && procCoefficient > 0f)
			{
				return (double)damage / (double)baseDamage >= 4.0;
			}
			return false;
		}

		private static bool Finite(float value)
		{
			if (!float.IsNaN(value))
			{
				return !float.IsInfinity(value);
			}
			return false;
		}
	}
	internal static class ChainEffect
	{
		internal static bool Apply(DamageReport report, ItemDef item, BuffDef cooldown)
		{
			//IL_007f: 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_008d: 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_00ab: Invalid comparison between Unknown and I4
			//IL_012d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0132: Unknown result type (might be due to invalid IL or missing references)
			//IL_0169: Unknown result type (might be due to invalid IL or missing references)
			//IL_016e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0181: Unknown result type (might be due to invalid IL or missing references)
			//IL_0186: Unknown result type (might be due to invalid IL or missing references)
			//IL_019f: 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)
			if (!NetworkServer.active || report?.damageInfo == null || !Object.op_Implicit((Object)(object)item) || !Object.op_Implicit((Object)(object)cooldown))
			{
				return false;
			}
			DamageInfo damageInfo = report.damageInfo;
			CharacterBody attackerBody = report.attackerBody;
			if (!Object.op_Implicit((Object)(object)attackerBody) || !Object.op_Implicit((Object)(object)attackerBody.inventory) || !Object.op_Implicit((Object)(object)report.victim) || !Object.op_Implicit((Object)(object)report.victimBody) || (Object)(object)attackerBody == (Object)(object)report.victimBody || report.attackerTeamIndex == report.victimTeamIndex || (int)report.victimTeamIndex == 0 || damageInfo.rejected || damageInfo.delayedDamageSecondHalf || (int)damageInfo.dotIndex != -1 || !(report.damageDealt > 0f) || ((ProcChainMask)(ref damageInfo.procChainMask)).HasProc((ProcType)12) || !Balance.HeavyHit(damageInfo.damage, attackerBody.damage, damageInfo.procCoefficient) || attackerBody.HasBuff(cooldown) || !Object.op_Implicit((Object)(object)OrbManager.instance))
			{
				return false;
			}
			int itemCountEffective = attackerBody.inventory.GetItemCountEffective(item);
			if (itemCountEffective <= 0)
			{
				return false;
			}
			float num = damageInfo.damage * Balance.DamageMultiplier(itemCountEffective);
			if (float.IsNaN(num) || float.IsInfinity(num))
			{
				return false;
			}
			ProcChainMask procChainMask = damageInfo.procChainMask;
			((ProcChainMask)(ref procChainMask)).AddProc((ProcType)12);
			for (int i = 1; i <= 10; i++)
			{
				attackerBody.AddTimedBuff(cooldown, (float)i);
			}
			for (int j = 0; j < 2; j++)
			{
				OrbManager.instance.AddOrb((Orb)(object)new StormStrikeOrb
				{
					origin = damageInfo.position,
					attacker = ((Component)attackerBody).gameObject,
					team = report.attackerTeamIndex,
					damage = num,
					crit = damageInfo.crit,
					mask = procChainMask,
					delay = 0.1f + (float)j * 0.5f
				});
			}
			return true;
		}
	}
	internal static class ChargeEffects
	{
		internal static GameObject Strike;

		internal static GameObject Burst;

		internal static string ThunderEvent;

		private static Transform storage;

		internal static void Register()
		{
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			//IL_000a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0011: Unknown result type (might be due to invalid IL or missing references)
			//IL_0017: Expected O, but got Unknown
			GameObject val = new GameObject("VoltaChargeEffectTemplates");
			val.SetActive(false);
			Object.DontDestroyOnLoad((Object)val);
			storage = val.transform;
			Strike = Clone("RoR2/Base/LightningStrikeOnHit/SimpleLightningStrikeOrbEffect.prefab", "VoltaStormBolt");
			OrbEffect component = Strike.GetComponent<OrbEffect>();
			if (Object.op_Implicit((Object)(object)component))
			{
				Object.DestroyImmediate((Object)(object)component);
			}
			Lifetime(Strike, 1f);
			Burst = Clone("RoR2/Base/LightningStrikeOnHit/SimpleLightningStrikeImpact.prefab", "VoltaStormImpact");
			EffectComponent component2 = Load("RoR2/Base/LightningStrikeOnHit/SimpleLightningStrikeImpact.prefab").GetComponent<EffectComponent>();
			ThunderEvent = (Object.op_Implicit((Object)(object)component2) ? component2.soundName : null);
			if (string.IsNullOrEmpty(ThunderEvent))
			{
				throw new InvalidOperationException("Charged Perforator impact sound is unavailable.");
			}
			Component(Burst).soundName = ThunderEvent;
			Lifetime(Burst, 3f);
			GameObject[] array = (GameObject[])(object)new GameObject[2] { Strike, Burst };
			foreach (GameObject val2 in array)
			{
				(val2.GetComponent<VFXAttributes>() ?? val2.AddComponent<VFXAttributes>()).DoNotPool = true;
				if (!ContentAddition.AddEffect(val2))
				{
					throw new InvalidOperationException("Cannot register " + ((Object)val2).name);
				}
			}
		}

		private static GameObject Load(string key)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			GameObject obj = Addressables.LoadAssetAsync<GameObject>((object)key).WaitForCompletion();
			if (!Object.op_Implicit((Object)(object)obj))
			{
				throw new InvalidOperationException("Missing native effect: " + key);
			}
			return obj;
		}

		private static GameObject Clone(string key, string name)
		{
			GameObject val = Object.Instantiate<GameObject>(Load(key), storage);
			((Object)val).name = name;
			val.SetActive(true);
			EffectComponent[] componentsInChildren = val.GetComponentsInChildren<EffectComponent>(true);
			for (int i = 0; i < componentsInChildren.Length; i++)
			{
				componentsInChildren[i].soundName = "";
			}
			AkEvent[] componentsInChildren2 = val.GetComponentsInChildren<AkEvent>(true);
			for (int i = 0; i < componentsInChildren2.Length; i++)
			{
				Object.DestroyImmediate((Object)(object)componentsInChildren2[i]);
			}
			Component(val).soundName = "";
			return val;
		}

		private static EffectComponent Component(GameObject obj)
		{
			return obj.GetComponent<EffectComponent>() ?? obj.AddComponent<EffectComponent>();
		}

		private static void Lifetime(GameObject obj, float seconds)
		{
			(obj.GetComponent<DestroyOnTimer>() ?? obj.AddComponent<DestroyOnTimer>()).duration = seconds;
		}

		internal static void Emit(GameObject prefab, EffectData data)
		{
			if (Object.op_Implicit((Object)(object)prefab))
			{
				EffectManager.SpawnEffect(prefab, data, true);
			}
		}
	}
	internal sealed class StormStrikeOrb : Orb
	{
		internal GameObject attacker;

		internal TeamIndex team;

		internal float damage;

		internal float delay;

		internal bool crit;

		internal ProcChainMask mask;

		private bool struck;

		public override void Begin()
		{
			((Orb)this).duration = delay;
		}

		public override void OnArrival()
		{
			//IL_0029: Unknown result type (might be due to invalid IL or missing references)
			//IL_002e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0030: Unknown result type (might be due to invalid IL or missing references)
			//IL_003a: Unknown result type (might be due to invalid IL or missing references)
			//IL_004a: Expected O, but got Unknown
			//IL_004f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0054: Unknown result type (might be due to invalid IL or missing references)
			//IL_0056: Unknown result type (might be due to invalid IL or missing references)
			//IL_0060: Unknown result type (might be due to invalid IL or missing references)
			//IL_0070: Expected O, but got Unknown
			//IL_0070: Unknown result type (might be due to invalid IL or missing references)
			//IL_0075: Unknown result type (might be due to invalid IL or missing references)
			//IL_0081: Unknown result type (might be due to invalid IL or missing references)
			//IL_008d: Unknown result type (might be due to invalid IL or missing references)
			//IL_008f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0094: Unknown result type (might be due to invalid IL or missing references)
			//IL_0099: Unknown result type (might be due to invalid IL or missing references)
			//IL_009b: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ac: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b7: 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_00ce: Unknown result type (might be due to invalid IL or missing references)
			//IL_00da: Unknown result type (might be due to invalid IL or missing references)
			//IL_00dc: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ec: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f8: 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_0108: Unknown result type (might be due to invalid IL or missing references)
			//IL_010a: Unknown result type (might be due to invalid IL or missing references)
			//IL_010f: Unknown result type (might be due to invalid IL or missing references)
			if (!struck && NetworkServer.active && Object.op_Implicit((Object)(object)attacker))
			{
				struck = true;
				ChargeEffects.Emit(ChargeEffects.Strike, new EffectData
				{
					origin = base.origin,
					scale = 1f
				});
				ChargeEffects.Emit(ChargeEffects.Burst, new EffectData
				{
					origin = base.origin,
					scale = 1f
				});
				new BlastAttack
				{
					attacker = attacker,
					inflictor = attacker,
					teamIndex = team,
					attackerFiltering = (AttackerFiltering)2,
					position = base.origin,
					radius = 5f,
					baseDamage = damage,
					baseForce = 0f,
					crit = crit,
					damageColorIndex = (DamageColorIndex)3,
					damageType = DamageTypeCombo.op_Implicit((DamageTypeExtended)8192),
					procChainMask = mask,
					procCoefficient = 0f,
					falloffModel = (FalloffModel)0
				}.Fire();
			}
		}
	}
	[BepInPlugin("wreckzog.voltasband", "Volta's Band", "0.3.1")]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[NetworkCompatibility(/*Could not decode attribute arguments.*/)]
	public sealed class Plugin : BaseUnityPlugin
	{
		public const string PluginGuid = "wreckzog.voltasband";

		public const string Version = "0.3.1";

		internal static ItemDef Item;

		internal static ItemDef SourceItem;

		internal static BuffDef Cooldown;

		private ConfigEntry<bool> logProcs;

		private void Awake()
		{
			//IL_00ed: 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_01b7: 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)
			logProcs = ((BaseUnityPlugin)this).Config.Bind<bool>("Debug", "LogActivations", false, "Log each activation for gameplay verification.");
			ChargeEffects.Register();
			((BaseUnityPlugin)this).Logger.LogInfo((object)("Charged Perforator sound: " + ChargeEffects.ThunderEvent));
			SourceItem = Visuals.Load<ItemDef>((object)"RoR2/Base/ElementalRings/IceRing.asset");
			Sprite pickupIconSprite = Visuals.LightningIcon(Visuals.Load<Sprite>(((AssetReference)SourceItem.pickupIconSpriteReference).RuntimeKey));
			Item = ScriptableObject.CreateInstance<ItemDef>();
			((Object)Item).name = "VoltasBand";
			Item.nameToken = "VOLTAS_BAND_NAME";
			Item.pickupToken = "VOLTAS_BAND_PICKUP";
			Item.descriptionToken = "VOLTAS_BAND_DESCRIPTION";
			Item.loreToken = "VOLTAS_BAND_LORE";
			FieldInfo? field = typeof(ItemDef).GetField("_itemTierDef", BindingFlags.Instance | BindingFlags.NonPublic);
			if (field == null)
			{
				throw new MissingFieldException("ItemDef._itemTierDef");
			}
			ItemTierDef val = Addressables.LoadAssetAsync<ItemTierDef>((object)"RoR2/Base/Common/Tier2Def.asset").WaitForCompletion();
			if (!Object.op_Implicit((Object)(object)val))
			{
				throw new InvalidOperationException("Green item tier asset missing.");
			}
			field.SetValue(Item, val);
			Item.canRemove = true;
			Item.hidden = false;
			Item.tags = (ItemTag[])(object)new ItemTag[1] { (ItemTag)1 };
			Item.pickupIconSprite = pickupIconSprite;
			Item.pickupModelPrefab = Visuals.LightningPrefab(Visuals.Load<GameObject>(((AssetReference)SourceItem.pickupModelReference).RuntimeKey), "PickupVoltasBand");
			Cooldown = ScriptableObject.CreateInstance<BuffDef>();
			((Object)Cooldown).name = "VoltasBandCooldown";
			Cooldown.iconSprite = Visuals.LoadIcon();
			Cooldown.buffColor = new Color(0.3f, 0.85f, 1f);
			Cooldown.canStack = true;
			Cooldown.isDebuff = false;
			Cooldown.isCooldown = true;
			Cooldown.ignoreGrowthNectar = true;
			Cooldown.itemAssociation = (ItemDef[])(object)new ItemDef[1] { Item };
			if (!ContentAddition.AddItemDef(Item) || !ContentAddition.AddBuffDef(Cooldown))
			{
				throw new InvalidOperationException("Volta's Band content registration failed.");
			}
			LanguageAPI.Add(Item.nameToken, "Volta's Band");
			LanguageAPI.Add(Item.pickupToken, "High damage hits call down two storm strikes. Recharges over time.");
			LanguageAPI.Add(Item.descriptionToken, "Hits that deal <style=cIsDamage>400% damage or more</style> call down <style=cIsDamage>two storm strikes</style> at the impact point, <style=cIsUtility>0.5 seconds</style> apart. Each strike deals <style=cIsDamage>150%</style> <style=cStack>(+150% per stack)</style> TOTAL damage within <style=cIsDamage>5m</style>. Recharges every <style=cIsUtility>10 seconds</style>.");
			LanguageAPI.Add(Item.loreToken, "The ring was cold when they found it.\n\nVolta held it to the light and watched a pale thread leap between its broken edges. Across the room, every compass turned.\n\n\"Distance,\" she wrote, \"is only a question of what stands between.\"");
			GlobalEventManager.onServerDamageDealt += OnDamage;
			RoR2Application.onLoad = (Action)Delegate.Combine(RoR2Application.onLoad, new Action(VerifyCatalog));
			((BaseUnityPlugin)this).Logger.LogInfo((object)"Volta's Band 0.3.1 loaded: green, two fixed storm strikes 0.5s apart, 5m blasts, 150% (+150%) per strike, 10s cooldown.");
		}

		private void VerifyCatalog()
		{
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			//IL_000b: Invalid comparison between Unknown and I4
			//IL_0012: Unknown result type (might be due to invalid IL or missing references)
			//IL_0018: Invalid comparison between Unknown and I4
			//IL_001f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0025: Invalid comparison between Unknown and I4
			//IL_0059: 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_007c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0081: Unknown result type (might be due to invalid IL or missing references)
			//IL_009f: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a4: Unknown result type (might be due to invalid IL or missing references)
			if ((int)Item.itemIndex == -1 || (int)Cooldown.buffIndex == -1 || (int)Item.tier != 1)
			{
				((BaseUnityPlugin)this).Logger.LogError((object)"Volta's Band is missing from a content catalog.");
				return;
			}
			int num = Visuals.AddDisplays();
			((BaseUnityPlugin)this).Logger.LogInfo((object)("Catalog ready: VoltasBand=" + ((object)Item.itemIndex/*cast due to .constrained prefix*/).ToString() + "; tier=" + ((object)Item.tier/*cast due to .constrained prefix*/).ToString() + "; cooldown=" + ((object)Cooldown.buffIndex/*cast due to .constrained prefix*/).ToString() + "; native band display rule sets=" + num));
		}

		private unsafe void OnDamage(DamageReport report)
		{
			//IL_0040: Unknown result type (might be due to invalid IL or missing references)
			//IL_0045: Unknown result type (might be due to invalid IL or missing references)
			if (ChainEffect.Apply(report, Item, Cooldown) && logProcs.Value)
			{
				ManualLogSource logger = ((BaseUnityPlugin)this).Logger;
				string name = ((Object)report.attackerBody).name;
				Vector3 position = report.damageInfo.position;
				logger.LogInfo((object)("Volta's Band activated by " + name + " at " + ((object)(*(Vector3*)(&position))/*cast due to .constrained prefix*/).ToString()));
			}
		}

		private void OnDestroy()
		{
			GlobalEventManager.onServerDamageDealt -= OnDamage;
			RoR2Application.onLoad = (Action)Delegate.Remove(RoR2Application.onLoad, new Action(VerifyCatalog));
		}
	}
	internal static class Visuals
	{
		private static readonly Dictionary<Texture, Texture2D> textures = new Dictionary<Texture, Texture2D>();

		private static readonly Dictionary<Texture, Texture2D> blueTextures = new Dictionary<Texture, Texture2D>();

		private static readonly Dictionary<Texture, Texture2D> icons = new Dictionary<Texture, Texture2D>();

		private static readonly Dictionary<Material, Material> materials = new Dictionary<Material, Material>();

		private static readonly Dictionary<GameObject, GameObject> displays = new Dictionary<GameObject, GameObject>();

		internal static readonly Color Lightning = new Color(0.06f, 0.22f, 0.72f);

		internal static T Load<T>(object key) where T : Object
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			T val = Addressables.LoadAssetAsync<T>(key).WaitForCompletion();
			if (!Object.op_Implicit((Object)(object)val))
			{
				throw new InvalidOperationException("Missing native band asset: " + key);
			}
			return val;
		}

		internal static Sprite LoadIcon(string resource = "VoltasBand.Cooldown.png")
		{
			//IL_002b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0031: Expected O, but got Unknown
			//IL_0063: Unknown result type (might be due to invalid IL or missing references)
			//IL_0072: Unknown result type (might be due to invalid IL or missing references)
			using Stream stream = Assembly.GetExecutingAssembly().GetManifestResourceStream(resource);
			using MemoryStream memoryStream = new MemoryStream();
			if (stream == null)
			{
				throw new InvalidOperationException("Embedded cooldown icon missing.");
			}
			stream.CopyTo(memoryStream);
			Texture2D val = new Texture2D(2, 2, (TextureFormat)4, false);
			if (!ImageConversion.LoadImage(val, memoryStream.ToArray()))
			{
				throw new InvalidOperationException("Invalid cooldown icon.");
			}
			return Sprite.Create(val, new Rect(0f, 0f, (float)((Texture)val).width, (float)((Texture)val).height), new Vector2(0.5f, 0.5f));
		}

		internal static bool IsRarityGreen(Color32 p)
		{
			//IL_0000: 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)
			//IL_0016: Unknown result type (might be due to invalid IL or missing references)
			//IL_001d: Unknown result type (might be due to invalid IL or missing references)
			if ((float)(int)p.g > (float)(int)p.r * 1.15f)
			{
				return (float)(int)p.g > (float)(int)p.b * 1.1f;
			}
			return false;
		}

		internal static Texture2D LightningTexture(Texture source, bool icon = false, bool blue = false)
		{
			//IL_0031: Unknown result type (might be due to invalid IL or missing references)
			//IL_0037: Invalid comparison between Unknown and I4
			//IL_007a: Unknown result type (might be due to invalid IL or missing references)
			//IL_007f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0095: 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_00a1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00af: Expected O, but got Unknown
			//IL_00c9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ea: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ef: Unknown result type (might be due to invalid IL or missing references)
			//IL_0100: Unknown result type (might be due to invalid IL or missing references)
			//IL_0107: Unknown result type (might be due to invalid IL or missing references)
			//IL_010e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0142: Unknown result type (might be due to invalid IL or missing references)
			//IL_018a: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f4: Unknown result type (might be due to invalid IL or missing references)
			//IL_022a: Unknown result type (might be due to invalid IL or missing references)
			//IL_022c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0230: Unknown result type (might be due to invalid IL or missing references)
			//IL_0235: Unknown result type (might be due to invalid IL or missing references)
			//IL_023a: Unknown result type (might be due to invalid IL or missing references)
			if (!Object.op_Implicit((Object)(object)source))
			{
				return null;
			}
			Dictionary<Texture, Texture2D> dictionary = (icon ? icons : (blue ? blueTextures : textures));
			if (dictionary.TryGetValue(source, out var value))
			{
				return value;
			}
			if ((int)SystemInfo.graphicsDeviceType == 4)
			{
				return (Texture2D)(object)((source is Texture2D) ? source : null);
			}
			RenderTexture active = RenderTexture.active;
			RenderTexture temporary = RenderTexture.GetTemporary(source.width, source.height, 0, (RenderTextureFormat)0, (RenderTextureReadWrite)2);
			Texture2D val = null;
			try
			{
				Graphics.Blit(source, temporary);
				RenderTexture.active = temporary;
				val = new Texture2D(source.width, source.height, (TextureFormat)4, true, false)
				{
					name = "Volta_" + ((Object)source).name,
					filterMode = source.filterMode,
					wrapMode = source.wrapMode
				};
				val.ReadPixels(new Rect(0f, 0f, (float)source.width, (float)source.height), 0, 0);
				Color32[] pixels = val.GetPixels32();
				Color val3 = default(Color);
				Color val4 = default(Color);
				for (int i = 0; i < pixels.Length; i++)
				{
					Color32 val2 = pixels[i];
					if (!icon || !IsRarityGreen(val2))
					{
						float num = (float)Mathf.Max((int)val2.r, Mathf.Max((int)val2.g, (int)val2.b)) / 255f;
						((Color)(ref val3))..ctor(num * 0.62f, num * 0.64f, num * 0.68f, (float)(int)val2.a / 255f);
						((Color)(ref val4))..ctor(num * (0.055f + 0.025f * num), num * (0.16f + 0.15f * num), num * (0.52f + 0.25f * num), (float)(int)val2.a / 255f);
						float num2 = (blue ? 1f : 0f);
						if (icon)
						{
							float u = ((float)(i % source.width) + 0.5f) / (float)source.width;
							float v = ((float)(i / source.width) + 0.5f) / (float)source.height;
							num2 = Mathf.Max(GemFace(u, v, 0.435f, 0.191f, 0.075f, 0.065f), GemFace(u, v, 0.908f, 0.638f, 0.018f, 0.039f));
						}
						pixels[i] = Color32.op_Implicit(Color.Lerp(val3, val4, num2));
					}
				}
				val.SetPixels32(pixels);
				val.Apply(true, false);
				dictionary.Add(source, val);
				return val;
			}
			catch
			{
				if (Object.op_Implicit((Object)(object)val))
				{
					Object.Destroy((Object)(object)val);
				}
				throw;
			}
			finally
			{
				RenderTexture.active = active;
				RenderTexture.ReleaseTemporary(temporary);
			}
		}

		private static float GemFace(float u, float v, float x, float y, float rx, float ry)
		{
			float num = (u - x) / rx;
			float num2 = (v - y) / ry;
			return 1f - Mathf.SmoothStep(0f, 1f, Mathf.InverseLerp(0.8f, 1.1f, Mathf.Sqrt(num * num + num2 * num2)));
		}

		internal static Sprite LightningIcon(Sprite source)
		{
			//IL_0021: Unknown result type (might be due to invalid IL or missing references)
			//IL_0027: Unknown result type (might be due to invalid IL or missing references)
			//IL_0032: Unknown result type (might be due to invalid IL or missing references)
			//IL_0037: Unknown result type (might be due to invalid IL or missing references)
			//IL_0041: Unknown result type (might be due to invalid IL or missing references)
			//IL_004c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0051: Unknown result type (might be due to invalid IL or missing references)
			//IL_005a: Unknown result type (might be due to invalid IL or missing references)
			if (!Object.op_Implicit((Object)(object)source))
			{
				throw new InvalidOperationException("Native band icon missing.");
			}
			Texture2D obj = LightningTexture((Texture)(object)source.texture, icon: true);
			Rect rect = source.rect;
			float x = source.pivot.x;
			Rect rect2 = source.rect;
			float num = x / ((Rect)(ref rect2)).width;
			float y = source.pivot.y;
			rect2 = source.rect;
			Sprite obj2 = Sprite.Create(obj, rect, new Vector2(num, y / ((Rect)(ref rect2)).height), source.pixelsPerUnit);
			((Object)obj2).name = "Volta_" + ((Object)source).name;
			return obj2;
		}

		private static Material LightningMaterial(Material source)
		{
			//IL_0031: Unknown result type (might be due to invalid IL or missing references)
			//IL_0036: Unknown result type (might be due to invalid IL or missing references)
			//IL_004d: Expected O, but got Unknown
			//IL_0145: Unknown result type (might be due to invalid IL or missing references)
			//IL_014a: Unknown result type (might be due to invalid IL or missing references)
			//IL_014c: 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_015a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0179: Unknown result type (might be due to invalid IL or missing references)
			//IL_0172: Unknown result type (might be due to invalid IL or missing references)
			//IL_017e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0183: 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_0197: 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_01a8: Unknown result type (might be due to invalid IL or missing references)
			//IL_025f: Unknown result type (might be due to invalid IL or missing references)
			if (!Object.op_Implicit((Object)(object)source))
			{
				return null;
			}
			if (((Object)source).name.StartsWith("Volta_", StringComparison.Ordinal))
			{
				return source;
			}
			if (materials.TryGetValue(source, out var value))
			{
				return value;
			}
			Material val = new Material(source)
			{
				name = "Volta_" + ((Object)source).name
			};
			bool flag = ((Object)source).name.IndexOf("Gemstone", StringComparison.OrdinalIgnoreCase) >= 0;
			bool flag2 = ((Object)source).name.IndexOf("Runes", StringComparison.OrdinalIgnoreCase) >= 0;
			string[] array = new string[6] { "_MainTex", "_EmTex", "_EmissionMap", "_RemapTex", "_FlowHeightRamp", "_FresnelRamp" };
			foreach (string text in array)
			{
				if (val.HasProperty(text) && Object.op_Implicit((Object)(object)val.GetTexture(text)))
				{
					val.SetTexture(text, (Texture)(object)LightningTexture(val.GetTexture(text), icon: false, flag || flag2));
				}
			}
			array = new string[4] { "_Color", "_TintColor", "_EmColor", "_EmissionColor" };
			foreach (string text2 in array)
			{
				if (val.HasProperty(text2))
				{
					Color color = val.GetColor(text2);
					float num = Mathf.Max(color.r, Mathf.Max(color.g, color.b));
					Color val2 = ((flag || flag2) ? Lightning : Color.white);
					val.SetColor(text2, new Color(val2.r * num, val2.g * num, val2.b * num, color.a));
				}
			}
			if (flag)
			{
				if (val.HasProperty("_FresnelBoost"))
				{
					val.SetFloat("_FresnelBoost", 2.2f);
				}
				if (val.HasProperty("_FlowDiffuseStrength"))
				{
					val.SetFloat("_FlowDiffuseStrength", 0.8f);
				}
				if (val.HasProperty("_FlowEmissionStrength"))
				{
					val.SetFloat("_FlowEmissionStrength", 1.3f);
				}
				if (val.HasProperty("_EmTex"))
				{
					val.SetTexture("_EmTex", (Texture)(object)Texture2D.whiteTexture);
				}
				if (val.HasProperty("_EmColor"))
				{
					val.SetColor("_EmColor", new Color(0.015f, 0.08f, 0.6f));
				}
				if (val.HasProperty("_EmPower"))
				{
					val.SetFloat("_EmPower", 2.5f);
				}
				val.EnableKeyword("EMISSION");
			}
			materials.Add(source, val);
			return val;
		}

		internal static GameObject LightningPrefab(GameObject source, string name)
		{
			//IL_0162: Unknown result type (might be due to invalid IL or missing references)
			if (!Object.op_Implicit((Object)(object)source))
			{
				throw new InvalidOperationException("Native band model missing.");
			}
			GameObject val = PrefabAPI.InstantiateClone(source, name, false);
			Renderer[] componentsInChildren = val.GetComponentsInChildren<Renderer>(true);
			foreach (Renderer val2 in componentsInChildren)
			{
				Material[] sharedMaterials = val2.sharedMaterials;
				for (int j = 0; j < sharedMaterials.Length; j++)
				{
					sharedMaterials[j] = LightningMaterial(sharedMaterials[j]);
				}
				val2.sharedMaterials = sharedMaterials;
			}
			ItemDisplay[] componentsInChildren2 = val.GetComponentsInChildren<ItemDisplay>(true);
			foreach (ItemDisplay val3 in componentsInChildren2)
			{
				if (val3.rendererInfos == null)
				{
					continue;
				}
				RendererInfo[] array = (RendererInfo[])val3.rendererInfos.Clone();
				for (int k = 0; k < array.Length; k++)
				{
					Material val4 = array[k].defaultMaterial;
					if (!Object.op_Implicit((Object)(object)val4) && array[k].defaultMaterialAddress != null && ((AssetReference)array[k].defaultMaterialAddress).RuntimeKeyIsValid())
					{
						val4 = Visuals.Load<Material>(((AssetReference)array[k].defaultMaterialAddress).RuntimeKey);
					}
					array[k].defaultMaterial = LightningMaterial(val4);
					array[k].defaultMaterialAddress = null;
				}
				val3.rendererInfos = array;
				val3.canBeEliteRecolored = false;
			}
			Light[] componentsInChildren3 = val.GetComponentsInChildren<Light>(true);
			for (int i = 0; i < componentsInChildren3.Length; i++)
			{
				componentsInChildren3[i].color = Lightning;
			}
			return val;
		}

		internal static int AddDisplays()
		{
			//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_0062: Unknown result type (might be due to invalid IL or missing references)
			//IL_0064: Unknown result type (might be due to invalid IL or missing references)
			//IL_0070: Unknown result type (might be due to invalid IL or missing references)
			//IL_007d: Unknown result type (might be due to invalid IL or missing references)
			//IL_016a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0179: Unknown result type (might be due to invalid IL or missing references)
			int num = 0;
			HashSet<ItemDisplayRuleSet> hashSet = new HashSet<ItemDisplayRuleSet>();
			foreach (GameObject allBodyPrefab in BodyCatalog.allBodyPrefabs)
			{
				CharacterModel[] componentsInChildren = allBodyPrefab.GetComponentsInChildren<CharacterModel>(true);
				for (int i = 0; i < componentsInChildren.Length; i++)
				{
					ItemDisplayRuleSet itemDisplayRuleSet = componentsInChildren[i].itemDisplayRuleSet;
					if (!Object.op_Implicit((Object)(object)itemDisplayRuleSet) || !hashSet.Add(itemDisplayRuleSet))
					{
						continue;
					}
					DisplayRuleGroup itemDisplayRuleGroup = itemDisplayRuleSet.GetItemDisplayRuleGroup(Plugin.SourceItem.itemIndex);
					if (itemDisplayRuleGroup.rules == null || itemDisplayRuleGroup.rules.Length == 0)
					{
						continue;
					}
					ItemDisplayRule[] array = (ItemDisplayRule[])itemDisplayRuleGroup.rules.Clone();
					for (int j = 0; j < array.Length; j++)
					{
						GameObject val = array[j].followerPrefab;
						if (!Object.op_Implicit((Object)(object)val) && array[j].followerPrefabAddress != null && ((AssetReference)array[j].followerPrefabAddress).RuntimeKeyIsValid())
						{
							val = Visuals.Load<GameObject>(((AssetReference)array[j].followerPrefabAddress).RuntimeKey);
						}
						if (Object.op_Implicit((Object)(object)val))
						{
							if (!displays.TryGetValue(val, out var value))
							{
								value = LightningPrefab(val, "DisplayVolta_" + ((Object)val).name);
								displays.Add(val, value);
							}
							array[j].followerPrefab = value;
							array[j].followerPrefabAddress = null;
						}
					}
					itemDisplayRuleSet.SetDisplayRuleGroup((Object)(object)Plugin.Item, new DisplayRuleGroup
					{
						rules = array
					});
					itemDisplayRuleSet.GenerateRuntimeValues();
					num++;
				}
			}
			return num;
		}
	}
}