Decompiled source of ReturnsArtifacts v1.0.0

BepInEx/plugins/ReturnsArtifacts.dll

Decompiled 4 months ago
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
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 Microsoft.CodeAnalysis;
using On.RoR2;
using On.RoR2.UI;
using R2API;
using ReturnsArtifacts.Scripts.Artifacts;
using RiskOfOptions;
using RiskOfOptions.OptionConfigs;
using RiskOfOptions.Options;
using RoR2;
using RoR2.Artifacts;
using RoR2.Skills;
using RoR2.UI;
using UnityEngine;
using UnityEngine.AddressableAssets;
using UnityEngine.Networking;
using UnityEngine.UI;

[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.0", FrameworkDisplayName = ".NET Standard 2.0")]
[assembly: AssemblyCompany("ReturnsArtifacts")]
[assembly: AssemblyConfiguration("Debug")]
[assembly: AssemblyDescription("My first plugin")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0")]
[assembly: AssemblyProduct("ReturnsArtifacts")]
[assembly: AssemblyTitle("ReturnsArtifacts")]
[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 ReturnsArtifacts
{
	public static class PluginInfo
	{
		public const string PLUGIN_GUID = "ReturnsArtifacts";

		public const string PLUGIN_NAME = "ReturnsArtifacts";

		public const string PLUGIN_VERSION = "1.0.0";
	}
}
namespace ReturnsArtifacts.Scripts
{
	internal static class ExtensionMethods
	{
		public static IEnumerable<Type> GetTypesOfType<T>(this Assembly assembly)
		{
			return from type in assembly.GetTypes()
				where !type.IsAbstract && type.IsSubclassOf(typeof(T))
				select type;
		}

		public static bool IsMountainShrine(this SpawnCard spawnCard)
		{
			return ((Object)spawnCard).name.ToLower().Contains(InteractableNames.ShrineOftheMountain);
		}

		public static T[] Shuffled<T>(this T[] collection)
		{
			for (int i = 0; i < collection.Length - 1; i++)
			{
				int num = Random.Range(i, collection.Length);
				int num2 = num;
				int num3 = i;
				T val = collection[i];
				T val2 = collection[num];
				collection[num2] = val;
				collection[num3] = val2;
			}
			return collection;
		}

		public static bool IndexOfInventory(this List<TemporaryInventory> inventories, Inventory inventory, out int index)
		{
			index = inventories.FindIndex((TemporaryInventory x) => (Object)(object)x.inventory == (Object)(object)inventory);
			return index != -1;
		}
	}
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[BepInPlugin("ReturnsArtifacts", "Returns Artifacts", "1.0.0")]
	public class Plugin : BaseUnityPlugin
	{
		private static float? previousGameTime;

		public static AssetBundle Assets { get; private set; }

		public static ManualLogSource Log { get; private set; }

		public static ConfigFile ConfigFile { get; private set; }

		public static event Action<float> onGameTimeChanged;

		private void Awake()
		{
			Log = ((BaseUnityPlugin)this).Logger;
			ConfigFile = ((BaseUnityPlugin)this).Config;
			Assembly executingAssembly = Assembly.GetExecutingAssembly();
			using (Stream stream = executingAssembly.GetManifestResourceStream("ReturnsArtifacts.Resources.returnsartifactsbundle"))
			{
				Assets = AssetBundle.LoadFromStream(stream);
			}
			foreach (Type item in executingAssembly.GetTypesOfType<ArtifactBase>())
			{
				ArtifactBase artifactBase = (ArtifactBase)Activator.CreateInstance(item);
				artifactBase.Init();
			}
			if (Chainloader.PluginInfos.ContainsKey("com.rune580.riskofoptions"))
			{
				AddConfigOptions();
			}
			((BaseUnityPlugin)this).Logger.LogInfo((object)"Plugin ReturnsArtifacts is loaded!");
		}

		private void FixedUpdate()
		{
			if ((Object)(object)Run.instance != (Object)null)
			{
				float runStopwatch = Run.instance.GetRunStopwatch();
				if (runStopwatch != previousGameTime)
				{
					Plugin.onGameTimeChanged?.Invoke(runStopwatch);
					previousGameTime = runStopwatch;
				}
			}
		}

		private void AddConfigOptions()
		{
			//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_002f: 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_0047: Expected O, but got Unknown
			//IL_0042: Unknown result type (might be due to invalid IL or missing references)
			//IL_004c: Expected O, but got Unknown
			//IL_0052: Unknown result type (might be due to invalid IL or missing references)
			//IL_0057: 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_0072: Expected O, but got Unknown
			//IL_006d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0077: Expected O, but got Unknown
			//IL_007d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0082: Unknown result type (might be due to invalid IL or missing references)
			//IL_0089: Unknown result type (might be due to invalid IL or missing references)
			//IL_0095: Expected O, but got Unknown
			//IL_0090: Unknown result type (might be due to invalid IL or missing references)
			//IL_009a: Expected O, but got Unknown
			//IL_00a0: 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_00ac: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b8: Expected O, but got Unknown
			//IL_00b3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bd: Expected O, but got Unknown
			//IL_00c3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00cd: Expected O, but got Unknown
			//IL_00d3: 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_00e0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f0: Expected O, but got Unknown
			//IL_00eb: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f5: Expected O, but got Unknown
			//IL_00fb: 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_0114: Expected O, but got Unknown
			//IL_010f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0119: Expected O, but got Unknown
			//IL_011f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0124: 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_0137: Expected O, but got Unknown
			//IL_0132: Unknown result type (might be due to invalid IL or missing references)
			//IL_013c: Expected O, but got Unknown
			//IL_0142: Unknown result type (might be due to invalid IL or missing references)
			//IL_0147: 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_015a: Expected O, but got Unknown
			//IL_0155: Unknown result type (might be due to invalid IL or missing references)
			//IL_015f: Expected O, but got Unknown
			ModSettingsManager.AddOption((BaseOption)new IntSliderOption(ArtifactOfCognation.cloneLifespan, new IntSliderConfig
			{
				min = 5,
				max = 60
			}));
			ModSettingsManager.AddOption((BaseOption)new IntSliderOption(ArtifactOfDistortion.cycleDuration, new IntSliderConfig
			{
				min = 20,
				max = 300
			}));
			ModSettingsManager.AddOption((BaseOption)new SliderOption(ArtifactOfDistortion.cooldownReduction, new SliderConfig
			{
				min = 0f,
				max = 100f
			}));
			ModSettingsManager.AddOption((BaseOption)new IntSliderOption(ArtifactOfDistortion.skillsToLock, new IntSliderConfig
			{
				min = 1,
				max = 3
			}));
			ModSettingsManager.AddOption((BaseOption)new IntSliderOption(ArtifactOfPrestige.numMountainShrinesToSpawn, new IntSliderConfig
			{
				min = 0,
				max = 5
			}));
			ModSettingsManager.AddOption((BaseOption)new ColorOption(ArtifactOfPrestige.shrineSymbolColor));
			ModSettingsManager.AddOption((BaseOption)new IntSliderOption(ArtifactOfTempus.itemLifespan, new IntSliderConfig
			{
				min = 30,
				max = 600
			}));
			ModSettingsManager.AddOption((BaseOption)new IntSliderOption(ArtifactOfTempus.baseNumStacks, new IntSliderConfig
			{
				min = 1,
				max = 10
			}));
			ModSettingsManager.AddOption((BaseOption)new IntSliderOption(ArtifactOfTempus.bonusNumStacks, new IntSliderConfig
			{
				min = 0,
				max = 5
			}));
			ModSettingsManager.AddOption((BaseOption)new IntSliderOption(ArtifactOfTempus.stagesPerBonusStacks, new IntSliderConfig
			{
				min = 1,
				max = 5
			}));
		}

		public static void LogDebug(object data)
		{
			Log.LogDebug(data);
		}

		public static void LogError(object data)
		{
			Log.LogError(data);
		}
	}
	internal class TemporaryInventory
	{
		private readonly Dictionary<ItemIndex, float> itemsRemainingTime = new Dictionary<ItemIndex, float>();

		private readonly Dictionary<ItemIndex, Image> temporaryItemIndicators = new Dictionary<ItemIndex, Image>();

		public Inventory inventory { get; private set; }

		public TemporaryInventory(Inventory inventory)
		{
			this.inventory = inventory;
			Plugin.onGameTimeChanged += OnGameTimeChanged;
		}

		private void OnGameTimeChanged(float time)
		{
			//IL_001d: 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_0054: 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_0042: 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_009c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0073: Unknown result type (might be due to invalid IL or missing references)
			ItemIndex[] array = itemsRemainingTime.Keys.ToArray();
			foreach (ItemIndex val in array)
			{
				float num = itemsRemainingTime[val] - Time.fixedDeltaTime;
				if (num > 0f)
				{
					SetItemTime(val, num);
					continue;
				}
				inventory.RemoveItem(val, 1);
				if (inventory.GetItemCount(val) > 0)
				{
					SetItemTime(val, ArtifactOfTempus.itemLifespan.Value);
					continue;
				}
				itemsRemainingTime.Remove(val);
				temporaryItemIndicators.Remove(val);
			}
		}

		private void SetItemTime(ItemIndex itemIndex, float newRemainingTime)
		{
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_0015: Unknown result type (might be due to invalid IL or missing references)
			itemsRemainingTime[itemIndex] = newRemainingTime;
			temporaryItemIndicators.TryGetValue(itemIndex, out var value);
			if ((Object)(object)value != (Object)null)
			{
				value.fillAmount = newRemainingTime / (float)ArtifactOfTempus.itemLifespan.Value;
			}
		}

		public void AddItem(ItemIndex itemIndex)
		{
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_001a: Unknown result type (might be due to invalid IL or missing references)
			if (!itemsRemainingTime.ContainsKey(itemIndex))
			{
				itemsRemainingTime.Add(itemIndex, ArtifactOfTempus.itemLifespan.Value);
			}
		}

		public void AddTemporaryItemIndicator(ItemIndex itemIndex, Image temporaryItemIndicator)
		{
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_001a: Unknown result type (might be due to invalid IL or missing references)
			if (!temporaryItemIndicators.ContainsKey(itemIndex))
			{
				temporaryItemIndicators.Add(itemIndex, temporaryItemIndicator);
			}
		}

		public void ResetIndicators()
		{
			temporaryItemIndicators.Clear();
		}
	}
	internal class UnavailableSkill : SkillDef
	{
		public string tokenName => "DISTORTION_UNAVAILABLE";

		public override bool CanExecute(GenericSkill skillSlot)
		{
			return false;
		}

		public override bool IsReady(GenericSkill skillSlot)
		{
			return false;
		}
	}
}
namespace ReturnsArtifacts.Scripts.Artifacts
{
	public abstract class ArtifactBase
	{
		public ArtifactDef ArtifactDef;

		public abstract string ArtifactName { get; }

		public abstract string ArtifactLangTokenName { get; }

		public abstract string ArtifactDescription { get; }

		public abstract Sprite ArtifactEnabledIcon { get; }

		public abstract Sprite ArtifactDisabledIcon { get; }

		public bool ArtifactEnabled => RunArtifactManager.instance.IsArtifactEnabled(ArtifactDef);

		public virtual void Init(ConfigFile config)
		{
			Init();
		}

		public abstract void Init();

		protected void CreateLang()
		{
			LanguageAPI.Add("ARTIFACT_" + ArtifactLangTokenName + "_NAME", ArtifactName);
			LanguageAPI.Add("ARTIFACT_" + ArtifactLangTokenName + "_DESCRIPTION", ArtifactDescription);
		}

		protected void CreateArtifact()
		{
			ArtifactDef = ScriptableObject.CreateInstance<ArtifactDef>();
			ArtifactDef.cachedName = "ARTIFACT_" + ArtifactLangTokenName;
			ArtifactDef.nameToken = "ARTIFACT_" + ArtifactLangTokenName + "_NAME";
			ArtifactDef.descriptionToken = "ARTIFACT_" + ArtifactLangTokenName + "_DESCRIPTION";
			ArtifactDef.smallIconSelectedSprite = ArtifactEnabledIcon;
			ArtifactDef.smallIconDeselectedSprite = ArtifactDisabledIcon;
			ContentAddition.AddArtifactDef(ArtifactDef);
		}

		public abstract void Hooks();
	}
	internal class ArtifactOfCognation : ArtifactBase
	{
		public static readonly ConfigEntry<int> cloneLifespan = Plugin.ConfigFile.Bind<int>("Cognation", "CloneLifespan", 10, "The lifespan of clones spawned by the Artifact of Cognation");

		public override string ArtifactName => "Artifact of Cognation";

		public override string ArtifactLangTokenName => "ARTIFACT_OF_COGNATION";

		public override string ArtifactDescription => "Enemies create a temporary clone on death.";

		public override Sprite ArtifactEnabledIcon => Plugin.Assets.LoadAsset<Sprite>("ArtifactOfCognationEnabled.png");

		public override Sprite ArtifactDisabledIcon => Plugin.Assets.LoadAsset<Sprite>("ArtifactOfCognationDisabled.png");

		public override void Init()
		{
			CreateLang();
			CreateArtifact();
			Hooks();
		}

		public override void Hooks()
		{
			GlobalEventManager.onCharacterDeathGlobal += SpawnMonsterClone;
		}

		private void SpawnMonsterClone(DamageReport damageReport)
		{
			//IL_0021: Unknown result type (might be due to invalid IL or missing references)
			//IL_0027: Invalid comparison between Unknown and I4
			if (NetworkClient.active && base.ArtifactEnabled && damageReport != null && Object.op_Implicit((Object)(object)damageReport.victimBody) && (int)damageReport.victimTeamIndex != 1 && damageReport.victimBody.inventory.GetItemCount(Items.Ghost) == 0)
			{
				CharacterBody val = Util.TryToCreateGhost(damageReport.victimBody, damageReport.victimBody, cloneLifespan.Value);
				val.master.onBodyStart += delegate(CharacterBody charBody)
				{
					charBody.inventory.RemoveItem(Items.BoostDamage, 150);
				};
			}
		}
	}
	internal class ArtifactOfDistortion : ArtifactBase
	{
		public static readonly ConfigEntry<int> cycleDuration = Plugin.ConfigFile.Bind<int>("Distortion", "CycleDuration", 60, "How many seconds it takes to change locked skill(s)");

		public static readonly ConfigEntry<float> cooldownReduction = Plugin.ConfigFile.Bind<float>("Distortion", "CooldownReduction", 25f, "Percentage of cooldown reduction to apply to non-locked skills");

		public static readonly ConfigEntry<int> skillsToLock = Plugin.ConfigFile.Bind<int>("Distortion", "SkillsToLock", 1, "How many skills to lock each cycle");

		private static UnavailableSkill unavailableSkill;

		private static int[] skillIndexes = new int[4] { 0, 1, 2, 3 };

		public override string ArtifactName => "Artifact of Distortion";

		public override string ArtifactLangTokenName => "ARTIFACT_OF_DISTORTION";

		public override string ArtifactDescription => "Lock a random skill every minute, but skills have decreased cooldowns.";

		public override Sprite ArtifactEnabledIcon => Plugin.Assets.LoadAsset<Sprite>("ArtifactOfDistortionEnabled.png");

		public override Sprite ArtifactDisabledIcon => Plugin.Assets.LoadAsset<Sprite>("ArtifactOfDistortionDisabled.png");

		private static event Action onCyclePassed;

		public override void Init()
		{
			CreateLang();
			CreateArtifact();
			unavailableSkill = InitSkill();
			Plugin.onGameTimeChanged += OnGameTimeChanged;
			Hooks();
		}

		private UnavailableSkill InitSkill()
		{
			//IL_000d: 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)
			UnavailableSkill unavailableSkill = ScriptableObject.CreateInstance<UnavailableSkill>();
			((SkillDef)unavailableSkill).icon = Addressables.LoadAssetAsync<Sprite>((object)"RoR2/Base/UI/texGenericSkillIcons.png").WaitForCompletion();
			((SkillDef)unavailableSkill).skillName = "SKILL_" + unavailableSkill.tokenName;
			((SkillDef)unavailableSkill).skillNameToken = "SKILL_" + unavailableSkill.tokenName + "_NAME";
			((SkillDef)unavailableSkill).skillDescriptionToken = "SKILL_" + unavailableSkill.tokenName + "_DESCRIPTION";
			LanguageAPI.Add("SKILL_DISTORTION_UNAVAILABLE_NAME", "Unavailable");
			LanguageAPI.Add("SKILL_DISTORTION_UNAVAILABLE_DESCRIPTION", "It's unavailable, at least for now...");
			return unavailableSkill;
		}

		public override void Hooks()
		{
			//IL_002c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0036: Expected O, but got Unknown
			Run.onRunStartGlobal += delegate
			{
				if (base.ArtifactEnabled)
				{
					ArtifactOfDistortion.onCyclePassed = null;
					skillIndexes = skillIndexes.Shuffled();
					onCyclePassed += delegate
					{
						skillIndexes = skillIndexes.Shuffled();
					};
				}
			};
			CharacterBody.onBodyStartGlobal += CharacterBody_onBodyStartGlobal;
			RecalculateStatsAPI.GetStatCoefficients += new StatHookEventHandler(ReduceCooldown);
		}

		private void OnGameTimeChanged(float time)
		{
			if (GetTimeCycle(time) != GetTimeCycle(time - Time.fixedDeltaTime))
			{
				ArtifactOfDistortion.onCyclePassed?.Invoke();
			}
		}

		private int GetTimeCycle(float time)
		{
			return (int)(time / (float)cycleDuration.Value);
		}

		private void ReduceCooldown(CharacterBody sender, StatHookEventArgs args)
		{
			if (base.ArtifactEnabled)
			{
				args.cooldownMultAdd -= cooldownReduction.Value / 100f;
			}
		}

		private void CharacterBody_onBodyStartGlobal(CharacterBody body)
		{
			if (base.ArtifactEnabled && body.isPlayerControlled)
			{
				SetUnavailableSkill(body);
				onCyclePassed += action;
			}
			void action()
			{
				if ((Object)(object)body == (Object)null)
				{
					onCyclePassed -= action;
				}
				else
				{
					GenericSkill[] allSkills = body.skillLocator.allSkills;
					foreach (GenericSkill val in allSkills)
					{
						val.UnsetSkillOverride((object)this, (SkillDef)(object)unavailableSkill, (SkillOverridePriority)3);
					}
					SetUnavailableSkill(body);
				}
			}
		}

		private void SetUnavailableSkill(CharacterBody body)
		{
			for (int i = 0; i < skillsToLock.Value; i++)
			{
				switch (skillIndexes[i])
				{
				case 0:
					SetSkillOverride(body.skillLocator.primary);
					break;
				case 1:
					SetSkillOverride(body.skillLocator.secondary);
					break;
				case 2:
					SetSkillOverride(body.skillLocator.utility);
					break;
				case 3:
					SetSkillOverride(body.skillLocator.special);
					break;
				}
			}
		}

		private void SetSkillOverride(GenericSkill skill)
		{
			skill.SetSkillOverride((object)this, (SkillDef)(object)unavailableSkill, (SkillOverridePriority)3);
		}
	}
	internal class ArtifactOfPrestige : ArtifactBase
	{
		private InteractableSpawnCard[] mountainShrineSpawnCards = (InteractableSpawnCard[])(object)new InteractableSpawnCard[3]
		{
			Addressables.LoadAssetAsync<InteractableSpawnCard>((object)"RoR2/Base/ShrineBoss/iscShrineBoss.asset").WaitForCompletion(),
			Addressables.LoadAssetAsync<InteractableSpawnCard>((object)"RoR2/Base/ShrineBoss/iscShrineBossSandy.asset").WaitForCompletion(),
			Addressables.LoadAssetAsync<InteractableSpawnCard>((object)"RoR2/Base/ShrineBoss/iscShrineBossSnowy.asset").WaitForCompletion()
		};

		public static readonly ConfigEntry<int> numMountainShrinesToSpawn = Plugin.ConfigFile.Bind<int>("Prestige", "MountainShrinesToSpawn", 1, "Number of Shrines of the Mountain to spawn each stage");

		public static readonly ConfigEntry<Color> shrineSymbolColor = Plugin.ConfigFile.Bind<Color>("Prestige", "ShrineSymbolColor", new Color(0.8f, 0.2f, 0.8f), "Color of the Shrine of the Mountain symbol");

		private static int shrineStacks;

		public override string ArtifactName => "Artifact of Prestige";

		public override string ArtifactLangTokenName => "ARTIFACT_OF_PRESTIGE";

		public override string ArtifactDescription => "At least one Shrine of the Mountain spawns every stage. Shrine of the Mountain effects are permanent.";

		public override Sprite ArtifactEnabledIcon => Plugin.Assets.LoadAsset<Sprite>("ArtifactOfPrestigeEnabled.png");

		public override Sprite ArtifactDisabledIcon => Plugin.Assets.LoadAsset<Sprite>("ArtifactOfPrestigeDisabled.png");

		public override void Init()
		{
			CreateLang();
			CreateArtifact();
			Hooks();
		}

		public override void Hooks()
		{
			//IL_0050: Unknown result type (might be due to invalid IL or missing references)
			//IL_005a: Expected O, but got Unknown
			SceneDirector.onGenerateInteractableCardSelection += SpawnMountainShrine;
			SpawnCard.onSpawnedServerGlobal += ConvertSpawnedMountainShrines;
			Run.onRunStartGlobal += delegate
			{
				if (!base.ArtifactEnabled || NetworkServer.active)
				{
					shrineStacks = 0;
				}
			};
			Stage.onServerStageBegin += delegate
			{
				//IL_0066: Unknown result type (might be due to invalid IL or missing references)
				if (base.ArtifactEnabled && !((Object)(object)TeleporterInteraction.instance == (Object)null))
				{
					for (int i = 0; i < shrineStacks; i++)
					{
						TeleporterInteraction.instance.AddShrineStack();
					}
					((Renderer)((Component)((Component)TeleporterInteraction.instance).transform.Find("TeleporterBaseMesh/BossShrineSymbol")).GetComponent<MeshRenderer>()).material.SetColor("_TintColor", shrineSymbolColor.Value);
				}
			};
			ShrineBossBehavior.AddShrineStack += new hook_AddShrineStack(OnAddShrineStack);
		}

		private void ConvertSpawnedMountainShrines(SpawnResult result)
		{
			//IL_0009: 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_002c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0057: Unknown result type (might be due to invalid IL or missing references)
			if (base.ArtifactEnabled && result.success && result.spawnRequest.spawnCard.IsMountainShrine())
			{
				GameObject spawnedInstance = result.spawnedInstance;
				((Renderer)((Component)spawnedInstance.transform.Find("Symbol")).GetComponent<MeshRenderer>()).material.SetColor("_TintColor", shrineSymbolColor.Value);
				spawnedInstance.GetComponent<PurchaseInteraction>().setUnavailableOnTeleporterActivated = false;
			}
		}

		private void SpawnMountainShrine(SceneDirector director, DirectorCardCategorySelection selection)
		{
			//IL_002f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0034: 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_0046: Expected O, but got Unknown
			//IL_0041: Unknown result type (might be due to invalid IL or missing references)
			//IL_004b: Expected O, but got Unknown
			if (!base.ArtifactEnabled)
			{
				return;
			}
			InteractableSpawnCard mountainShrine = GetMountainShrine();
			if ((Object)(object)mountainShrine == (Object)null)
			{
				return;
			}
			int num = 0;
			while (num < numMountainShrinesToSpawn.Value)
			{
				GameObject val = DirectorCore.instance.TrySpawnObject(new DirectorSpawnRequest((SpawnCard)(object)mountainShrine, new DirectorPlacementRule
				{
					placementMode = (PlacementMode)4
				}, director.rng));
				if ((Object)(object)val != (Object)null)
				{
					num++;
				}
			}
		}

		private void OnAddShrineStack(orig_AddShrineStack orig, ShrineBossBehavior self, Interactor interactor)
		{
			shrineStacks++;
			orig.Invoke(self, interactor);
		}

		private InteractableSpawnCard GetMountainShrine()
		{
			//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_000c: Unknown result type (might be due to invalid IL or missing references)
			//IL_000d: Unknown result type (might be due to invalid IL or missing references)
			//IL_000e: Unknown result type (might be due to invalid IL or missing references)
			//IL_000f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0010: Unknown result type (might be due to invalid IL or missing references)
			//IL_0013: Invalid comparison between Unknown and I4
			//IL_0043: Unknown result type (might be due to invalid IL or missing references)
			//IL_0049: Invalid comparison between Unknown and I4
			//IL_0015: Unknown result type (might be due to invalid IL or missing references)
			//IL_0017: Invalid comparison between Unknown and I4
			//IL_0069: Unknown result type (might be due to invalid IL or missing references)
			//IL_006f: Invalid comparison between Unknown and I4
			//IL_004b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0051: Invalid comparison between Unknown and I4
			//IL_002e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0031: Invalid comparison between Unknown and I4
			//IL_0019: Unknown result type (might be due to invalid IL or missing references)
			//IL_001b: Invalid comparison between Unknown and I4
			//IL_0085: Unknown result type (might be due to invalid IL or missing references)
			//IL_008b: Invalid comparison between Unknown and I4
			//IL_0071: Unknown result type (might be due to invalid IL or missing references)
			//IL_0077: Invalid comparison between Unknown and I4
			//IL_0055: Unknown result type (might be due to invalid IL or missing references)
			//IL_005b: Invalid comparison between Unknown and I4
			//IL_0035: Unknown result type (might be due to invalid IL or missing references)
			//IL_0038: Invalid comparison between Unknown and I4
			//IL_001f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0021: Invalid comparison between Unknown and I4
			//IL_008f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0095: Invalid comparison between Unknown and I4
			//IL_007b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0081: Invalid comparison between Unknown and I4
			//IL_005f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0065: Invalid comparison between Unknown and I4
			//IL_003c: Unknown result type (might be due to invalid IL or missing references)
			//IL_003f: Invalid comparison between Unknown and I4
			//IL_0025: Unknown result type (might be due to invalid IL or missing references)
			//IL_0027: Invalid comparison between Unknown and I4
			Stage stageEnumFromSceneDef = DirectorAPI.GetStageEnumFromSceneDef(SceneCatalog.GetSceneDefForCurrentScene());
			Stage val = stageEnumFromSceneDef;
			Stage val2 = val;
			if ((int)val2 <= 64)
			{
				if ((int)val2 <= 8)
				{
					if ((int)val2 == 2 || (int)val2 == 4 || (int)val2 == 8)
					{
						goto IL_0099;
					}
				}
				else
				{
					if ((int)val2 == 16)
					{
						return mountainShrineSpawnCards[1];
					}
					if ((int)val2 == 32)
					{
						goto IL_00af;
					}
					if ((int)val2 == 64)
					{
						goto IL_0099;
					}
				}
			}
			else if ((int)val2 <= 16384)
			{
				if ((int)val2 == 128 || (int)val2 == 256 || (int)val2 == 16384)
				{
					goto IL_0099;
				}
			}
			else if ((int)val2 <= 262144)
			{
				if ((int)val2 == 131072 || (int)val2 == 262144)
				{
					goto IL_0099;
				}
			}
			else
			{
				if ((int)val2 == 67108864)
				{
					goto IL_00af;
				}
				if ((int)val2 == 134217728)
				{
					goto IL_0099;
				}
			}
			return null;
			IL_0099:
			return mountainShrineSpawnCards[0];
			IL_00af:
			return mountainShrineSpawnCards[2];
		}
	}
	internal class ArtifactOfSpirit : ArtifactBase
	{
		private static float minPercentageChange = 0.05f;

		private float healthSegments = 1f / minPercentageChange;

		public override string ArtifactName => "Artifact of Spirit";

		public override string ArtifactLangTokenName => "ARTIFACT_OF_SPIRIT";

		public override string ArtifactDescription => "Characters run faster at lower health, including enemies.";

		public override Sprite ArtifactEnabledIcon => Plugin.Assets.LoadAsset<Sprite>("ArtifactOfSpiritEnabled.png");

		public override Sprite ArtifactDisabledIcon => Plugin.Assets.LoadAsset<Sprite>("ArtifactOfSpiritDisabled.png");

		public override void Init()
		{
			CreateLang();
			CreateArtifact();
			Hooks();
		}

		private int getSegment(float health)
		{
			return (int)(health * healthSegments);
		}

		public override void Hooks()
		{
			//IL_0008: Unknown result type (might be due to invalid IL or missing references)
			//IL_0012: 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_002c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0036: Expected O, but got Unknown
			HealthComponent.Heal += new hook_Heal(OnHeal);
			HealthComponent.TakeDamage += new hook_TakeDamage(OnDamage);
			RecalculateStatsAPI.GetStatCoefficients += new StatHookEventHandler(RecalculateSpeed);
		}

		private void OnDamage(orig_TakeDamage orig, HealthComponent self, DamageInfo damageInfo)
		{
			float combinedHealthFraction = self.combinedHealthFraction;
			orig.Invoke(self, damageInfo);
			float combinedHealthFraction2 = self.combinedHealthFraction;
			CheckHealthChanged(self, combinedHealthFraction, combinedHealthFraction2);
		}

		private float OnHeal(orig_Heal orig, HealthComponent self, float amount, ProcChainMask procChainMask, bool nonRegen)
		{
			//IL_000b: Unknown result type (might be due to invalid IL or missing references)
			float combinedHealthFraction = self.combinedHealthFraction;
			float result = orig.Invoke(self, amount, procChainMask, nonRegen);
			float combinedHealthFraction2 = self.combinedHealthFraction;
			CheckHealthChanged(self, combinedHealthFraction, combinedHealthFraction2);
			return result;
		}

		private void CheckHealthChanged(HealthComponent health, float oldHealth, float newHealth)
		{
			if (NetworkClient.active && base.ArtifactEnabled && getSegment(oldHealth) != getSegment(newHealth))
			{
				health.body.MarkAllStatsDirty();
			}
		}

		private void RecalculateSpeed(CharacterBody sender, StatHookEventArgs args)
		{
			if (NetworkClient.active && base.ArtifactEnabled && sender.healthComponent.alive && !(sender.healthComponent.fullCombinedHealth < sender.healthComponent.combinedHealth))
			{
				float num = (float)getSegment(sender.healthComponent.combinedHealthFraction) / healthSegments;
				float num2 = (float)Math.Pow(1f - num, 2.0);
				args.moveSpeedMultAdd += num2;
			}
		}
	}
	internal class ArtifactOfTempus : ArtifactBase
	{
		[Serializable]
		[CompilerGenerated]
		private sealed class <>c
		{
			public static readonly <>c <>9 = new <>c();

			public static hook_UpdateDisplay <>9__20_2;

			internal void <Hooks>b__20_2(orig_UpdateDisplay orig, ItemInventoryDisplay self)
			{
				playerInventory?.ResetIndicators();
				orig.Invoke(self);
			}
		}

		public static GameObject temporaryItemUI = Plugin.Assets.LoadAsset<GameObject>("TemporaryItemIndicatorUI.prefab");

		private static TemporaryInventory playerInventory;

		private static bool giveMoreStacks = true;

		public static readonly ConfigEntry<int> itemLifespan = Plugin.ConfigFile.Bind<int>("Tempus", "ItemLifespan", 120, "How many seconds a temporary item lasts");

		public static readonly ConfigEntry<int> baseNumStacks = Plugin.ConfigFile.Bind<int>("Tempus", "BaseNumStacks", 3, "Base number of stacks to give to the player\n\nThe formula for the total amount of stacks is as follows:\nBaseNumStacks + BonusNumStacks * (StagesCleared / StagesPerBonusStacks)");

		public static readonly ConfigEntry<int> bonusNumStacks = Plugin.ConfigFile.Bind<int>("Tempus", "BonusNumStacks", 1, "Bonus number of stacks to give to the player");

		public static readonly ConfigEntry<int> stagesPerBonusStacks = Plugin.ConfigFile.Bind<int>("Tempus", "StagesPerBonusStacks", 1, "Number of cleared stages needed for the bonus stacks");

		public override string ArtifactName => "Artifact of Tempus";

		public override string ArtifactLangTokenName => "ARTIFACT_OF_TEMPUS";

		public override string ArtifactDescription => "Items are worth multiple stacks. All items are temporary.";

		public override Sprite ArtifactEnabledIcon => Plugin.Assets.LoadAsset<Sprite>("ArtifactOfTempusEnabled.png");

		public override Sprite ArtifactDisabledIcon => Plugin.Assets.LoadAsset<Sprite>("ArtifactOfTempusDisabled.png");

		private static int totalStacks => baseNumStacks.Value + bonusNumStacks.Value * (Run.instance.stageClearCount / stagesPerBonusStacks.Value);

		public override void Init()
		{
			CreateLang();
			CreateArtifact();
			Hooks();
		}

		public override void Hooks()
		{
			//IL_003e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0048: Expected O, but got Unknown
			//IL_0050: Unknown result type (might be due to invalid IL or missing references)
			//IL_005a: Expected O, but got Unknown
			//IL_0087: Unknown result type (might be due to invalid IL or missing references)
			//IL_0091: Expected O, but got Unknown
			//IL_006f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0074: Unknown result type (might be due to invalid IL or missing references)
			//IL_007a: Expected O, but got Unknown
			Inventory.onServerItemGiven += Inventory_onServerItemGiven;
			CharacterBody.onBodyStartGlobal += CharacterBody_onBodyStartGlobal;
			SceneDirector.onGenerateInteractableCardSelection += delegate(SceneDirector sceneDirector, DirectorCardCategorySelection dccs)
			{
				if (base.ArtifactEnabled)
				{
					CommandArtifactManager.OnGenerateInteractableCardSelection(sceneDirector, dccs);
				}
			};
			PurchaseInteraction.CanBeAffordedByInteractor += new hook_CanBeAffordedByInteractor(PurchaseInteraction_CanBeAffordedByInteractor);
			ItemIcon.Awake += (hook_Awake)delegate(orig_Awake orig, ItemIcon self)
			{
				orig.Invoke(self);
				if (base.ArtifactEnabled)
				{
					Object.Instantiate<GameObject>(temporaryItemUI, (Transform)(object)self.rectTransform, false);
				}
			};
			object obj = <>c.<>9__20_2;
			if (obj == null)
			{
				hook_UpdateDisplay val = delegate(orig_UpdateDisplay orig, ItemInventoryDisplay self)
				{
					playerInventory?.ResetIndicators();
					orig.Invoke(self);
				};
				<>c.<>9__20_2 = val;
				obj = (object)val;
			}
			ItemInventoryDisplay.UpdateDisplay += (hook_UpdateDisplay)obj;
			ItemIcon.SetItemIndex += (hook_SetItemIndex)delegate(orig_SetItemIndex orig, ItemIcon self, ItemIndex newItemIndex, int newItemCount)
			{
				//IL_0003: Unknown result type (might be due to invalid IL or missing references)
				//IL_002c: 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_0038: Invalid comparison between Unknown and I4
				//IL_0062: Unknown result type (might be due to invalid IL or missing references)
				orig.Invoke(self, newItemIndex, newItemCount);
				if (base.ArtifactEnabled)
				{
					Transform val2 = ((Component)self).transform.Find("TemporaryItemIndicatorUI(Clone)");
					if ((int)ItemCatalog.GetItemDef(newItemIndex).tier == 5)
					{
						((Component)val2).gameObject.SetActive(false);
					}
					else
					{
						((Component)val2).gameObject.SetActive(true);
						playerInventory.AddTemporaryItemIndicator(newItemIndex, ((Component)val2).GetComponent<Image>());
					}
				}
			};
		}

		private bool PurchaseInteraction_CanBeAffordedByInteractor(orig_CanBeAffordedByInteractor orig, PurchaseInteraction self, Interactor activator)
		{
			//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_0012: Unknown result type (might be due to invalid IL or missing references)
			//IL_0013: Unknown result type (might be due to invalid IL or missing references)
			//IL_0014: 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_0018: Invalid comparison between Unknown and I4
			//IL_001c: Unknown result type (might be due to invalid IL or missing references)
			//IL_001f: Invalid comparison between Unknown and I4
			if (base.ArtifactEnabled)
			{
				CostTypeIndex costType = self.costType;
				CostTypeIndex val = costType;
				if (val - 4 <= 2 || (int)val == 10)
				{
					return false;
				}
			}
			return orig.Invoke(self, activator);
		}

		private void CharacterBody_onBodyStartGlobal(CharacterBody body)
		{
			if (base.ArtifactEnabled && body.isPlayerControlled && (Object)(object)body.inventory != (Object)(object)playerInventory?.inventory)
			{
				playerInventory = new TemporaryInventory(body.inventory);
			}
		}

		private void Inventory_onServerItemGiven(Inventory inventory, ItemIndex index, int count)
		{
			//IL_0039: 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_0051: Invalid comparison between Unknown and I4
			//IL_005e: Unknown result type (might be due to invalid IL or missing references)
			//IL_006b: Unknown result type (might be due to invalid IL or missing references)
			if (!base.ArtifactEnabled || (Object)(object)inventory != (Object)(object)playerInventory?.inventory)
			{
				return;
			}
			if (giveMoreStacks)
			{
				giveMoreStacks = false;
				ItemDef itemDef = ItemCatalog.GetItemDef(index);
				int num = (totalStacks - 1) * count;
				if ((int)itemDef.tier != 5)
				{
					inventory.GiveItem(index, num);
					playerInventory.AddItem(index);
				}
			}
			else
			{
				giveMoreStacks = true;
			}
		}
	}
}