Decompiled source of Utility Sorcery v0.6.20

BepInEx/plugins/Reddeq-UtilitySorcery/UtilitySorcery/UtilitySorcery.dll

Decompiled 11 hours ago
#define TRACE
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Diagnostics;
using System.Globalization;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Reflection.Emit;
using System.Runtime.CompilerServices;
using System.Runtime.Serialization;
using System.Runtime.Serialization.Json;
using System.Runtime.Versioning;
using System.Text;
using System.Threading;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using HarmonyLib;
using Jotunn;
using Jotunn.Configs;
using Jotunn.Entities;
using Jotunn.Managers;
using Jotunn.Utils;
using Microsoft.CodeAnalysis;
using ReddeqsUtilitySorcery.Abilities;
using ReddeqsUtilitySorcery.Abilities.Shift;
using ReddeqsUtilitySorcery.Abilities.Telekinesis;
using ReddeqsUtilitySorcery.Audio;
using ReddeqsUtilitySorcery.Core;
using ReddeqsUtilitySorcery.Creatures;
using ReddeqsUtilitySorcery.Debugging;
using ReddeqsUtilitySorcery.Dreams;
using ReddeqsUtilitySorcery.Effects;
using ReddeqsUtilitySorcery.Equipment;
using ReddeqsUtilitySorcery.Input;
using ReddeqsUtilitySorcery.Items;
using ReddeqsUtilitySorcery.Localization;
using ReddeqsUtilitySorcery.Progression;
using ReddeqsUtilitySorcery.Skills;
using ReddeqsUtilitySorcery.UI;
using UnityEngine;
using UnityEngine.Audio;
using UnityEngine.EventSystems;
using UnityEngine.Events;
using UnityEngine.Rendering;
using UnityEngine.UI;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: InternalsVisibleTo("FrameworkChecks")]
[assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")]
[assembly: AssemblyCompany("Reddeq")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("0.6.20.0")]
[assembly: AssemblyInformationalVersion("0.6.20+823b73d4a73f3a863c5a23f0cde7361655040be9")]
[assembly: AssemblyProduct("Utility Sorcery")]
[assembly: AssemblyTitle("Utility Sorcery")]
[assembly: AssemblyVersion("0.6.20.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 ReddeqsUtilitySorcery
{
	[BepInPlugin("reddeq.utilitysorcery", "Utility Sorcery", "0.6.20")]
	[BepInDependency("com.jotunn.jotunn", "2.30.2")]
	[NetworkCompatibility(/*Could not decode attribute arguments.*/)]
	public sealed class Plugin : BaseUnityPlugin
	{
		private SorceryInput input;

		private SorceryEffectSystem sorceryEffects;

		private TelekinesisNetworkManager telekinesisNetwork;

		private ImpulseService impulse;

		private WeaponProjectileLaunch weaponLaunch;

		private RecallVfxNotifications recallVfx;

		private RecallService recall;

		private QuickThrowService quickThrow;

		private SuspensionService suspension;

		private ShiftEffectsSystem shiftEffects;

		private DefensiveShiftService defensiveShifts;

		private OffensiveShiftBuffService offensiveBuff;

		private SorceryAwakeningService awakening;

		private SorceryDust sorceryDust;

		private DreamManager dreams;

		private DreamPotion dreamPotion;

		private SorceryUI sorceryUI;

		private TranceAssetRegistry skillIcons;

		private TranceAudioController tranceAudio;

		private ProgressionDebugNetwork progressionDebug;

		private SorcerersMarkVisualAssets markVisualAssets;

		private ConfigReloadService configReload;

		private EarlyProgressionItems earlyItems;

		private RunicDeerContent runicDeer;

		private RunicDeerDebug deerDebug;

		private RunicBearContent runicBear;

		private RunicBearDebug bearDebug;

		private void Awake()
		{
			//IL_0087: 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_00af: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ed: Unknown result type (might be due to invalid IL or missing references)
			//IL_0101: Unknown result type (might be due to invalid IL or missing references)
			//IL_019c: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a2: Invalid comparison between Unknown and I4
			//IL_08c2: Unknown result type (might be due to invalid IL or missing references)
			//IL_08c8: Invalid comparison between Unknown and I4
			//IL_0955: Unknown result type (might be due to invalid IL or missing references)
			((BaseUnityPlugin)this).Logger.LogInfo((object)"Initializing Utility Sorcery 0.6.20");
			try
			{
				ModConfig config = new ModConfig(((BaseUnityPlugin)this).Config);
				EarlyProgressionConfig config2 = new EarlyProgressionConfig(((BaseUnityPlugin)this).Config);
				RunicDeerConfig config3 = new RunicDeerConfig(((BaseUnityPlugin)this).Config);
				RunicBearConfig config4 = new RunicBearConfig(((BaseUnityPlugin)this).Config);
				AbilityEffectEvents.Log = ((BaseUnityPlugin)this).Logger;
				SorceryEffectConfig sorceryEffectConfig = new SorceryEffectConfig(((BaseUnityPlugin)this).Config);
				SorceryEffectRegistry sorceryEffectRegistry = new SorceryEffectRegistry();
				sorceryEffectRegistry.Register("shift", new AbilityEffectDefinition(new Color(0.6431373f, 39f / 85f, 1f), new Color(0.8f, 0.65f, 1f), new Color(0.9f, 0.8f, 1f), "ReddeqsUtilitySorcery.Assets.shift.png"));
				sorceryEffectRegistry.Register("telekinesis", new AbilityEffectDefinition(new Color(1f / 3f, 69f / 85f, 1f), new Color(0.1f, 0.35f, 1f), new Color(0.8f, 0.95f, 1f), "ReddeqsUtilitySorcery.Assets.telekinesis.png"));
				SorceryLocalization.Initialize(((BaseUnityPlugin)this).Logger);
				DreamConfig dreamConfig = new DreamConfig(((BaseUnityPlugin)this).Config);
				dreams = ((Component)this).gameObject.AddComponent<DreamManager>();
				dreams.Initialize(dreamConfig, ((BaseUnityPlugin)this).Logger);
				dreamPotion = new DreamPotion(dreamConfig, ((BaseUnityPlugin)this).Logger);
				AbilityRegistry abilityRegistry = new AbilityRegistry(delegate(string message)
				{
					((BaseUnityPlugin)this).Logger.LogError((object)message);
				});
				shiftEffects = new ShiftEffectsSystem(config, ((BaseUnityPlugin)this).Logger, abilityRegistry);
				if ((int)SystemInfo.graphicsDeviceType != 4 && (!Object.op_Implicit((Object)(object)ZNet.instance) || !ZNet.instance.IsDedicated()))
				{
					skillIcons = new TranceAssetRegistry(((BaseUnityPlugin)this).Logger, sorceryEffectRegistry, bakeRuneColors: true);
				}
				SkillService skillService = AbilitySkills.Register((skillIcons != null) ? new Func<string, Sprite>(skillIcons.Rune) : null);
				SorceryPersistence sorceryPersistence = new SorceryPersistence(((BaseUnityPlugin)this).Logger);
				awakening = new SorceryAwakeningService(sorceryPersistence, config);
				DefensiveShiftConfig defenseConfig = new DefensiveShiftConfig(((BaseUnityPlugin)this).Config);
				defensiveShifts = new DefensiveShiftService(defenseConfig, config, skillService, awakening, sorceryPersistence, shiftEffects, ((BaseUnityPlugin)this).Logger);
				markVisualAssets = new SorcerersMarkVisualAssets(((BaseUnityPlugin)this).Logger, ((BaseUnityPlugin)this).Config, sorceryPersistence, sorceryEffectRegistry, sorceryEffectConfig);
				markVisualAssets.Runes.Register("shift", sorceryEffectRegistry.Resolve("shift").RuneResource);
				markVisualAssets.Runes.Register("telekinesis", sorceryEffectRegistry.Resolve("telekinesis").RuneResource);
				SorceryPlayerHooks.Install(awakening, markVisualAssets, ((BaseUnityPlugin)this).Logger);
				OffensiveShiftConfig offensiveConfig = new OffensiveShiftConfig(((BaseUnityPlugin)this).Config);
				offensiveBuff = new OffensiveShiftBuffService(offensiveConfig, () => skillIcons?.Modifier("shift", "offensiveShift"), ((BaseUnityPlugin)this).Logger);
				abilityRegistry.Register(new ShiftAbility(config, sorceryPersistence, ((BaseUnityPlugin)this).Logger, shiftEffects, offensiveConfig, offensiveBuff));
				TelekinesisConfig telekinesisConfig = new TelekinesisConfig(((BaseUnityPlugin)this).Config);
				QuickThrowConfig quickThrowConfig = new QuickThrowConfig(((BaseUnityPlugin)this).Config);
				quickThrow = new QuickThrowService(quickThrowConfig, sorceryPersistence);
				ImpulseConfig impulseConfig = new ImpulseConfig(((BaseUnityPlugin)this).Config);
				weaponLaunch = new WeaponProjectileLaunch(((BaseUnityPlugin)this).Logger);
				try
				{
					impulse = new ImpulseService(impulseConfig, sorceryPersistence, skillService, ((BaseUnityPlugin)this).Logger);
				}
				catch (Exception ex)
				{
					((BaseUnityPlugin)this).Logger.LogError((object)("Impulse initialization failed; Recall and other abilities remain available: " + ex));
				}
				RecallConfig recallConfig = new RecallConfig(((BaseUnityPlugin)this).Config);
				recall = new RecallService(recallConfig, sorceryPersistence, awakening, skillService, ((BaseUnityPlugin)this).Logger);
				recallVfx = ((Component)this).gameObject.AddComponent<RecallVfxNotifications>();
				telekinesisNetwork = ((Component)this).gameObject.AddComponent<TelekinesisNetworkManager>();
				telekinesisNetwork.Initialize(telekinesisConfig, ((BaseUnityPlugin)this).Logger);
				SuspensionConfig suspensionConfig = new SuspensionConfig(((BaseUnityPlugin)this).Config);
				suspension = ((Component)this).gameObject.AddComponent<SuspensionService>();
				suspension.Initialize(suspensionConfig, telekinesisConfig, sorceryPersistence, awakening, skillService, ((BaseUnityPlugin)this).Logger);
				abilityRegistry.Register(new TelekinesisAbility(telekinesisConfig));
				if (config.DebugAbilityCount.Value > 0)
				{
					abilityRegistry.Register(new DebugAbility(reject: false, ((BaseUnityPlugin)this).Logger));
				}
				if (config.DebugAbilityCount.Value > 1)
				{
					abilityRegistry.Register(new DebugAbility(reject: true, ((BaseUnityPlugin)this).Logger));
				}
				TranceAccessService access = new TranceAccessService(sorceryPersistence, config);
				ProgressionService progressionService = new ProgressionService(sorceryPersistence, abilityRegistry, config);
				ResourceProgressionService resourceProgressionService = new ResourceProgressionService(sorceryPersistence, progressionService, access, config2, ((BaseUnityPlugin)this).Logger);
				resourceProgressionService.Register(new ResourceProgressionService.Requirement
				{
					Ability = "telekinesis",
					Modifier = "suspension",
					Item = "ReddeqUS_WeightlessDust",
					Amount = () => suspensionConfig.UnlockCost.Value,
					Prerequisite = (PlayerSorceryData data) => data.FirstAwakeningCompleted && SorceryProgression.FindAbility(data, "telekinesis") != null
				});
				resourceProgressionService.Register(new ResourceProgressionService.Requirement
				{
					Ability = "telekinesis",
					Modifier = "quickThrow",
					Item = "ReddeqUS_WeightlessDust",
					Amount = () => quickThrowConfig.UnlockCost.Value,
					Prerequisite = (PlayerSorceryData data) => data.FirstAwakeningCompleted && SorceryProgression.FindAbility(data, "telekinesis") != null
				});
				resourceProgressionService.Register(new ResourceProgressionService.Requirement
				{
					Ability = "telekinesis",
					Modifier = "recall",
					Item = "ReddeqUS_WeightlessDust",
					Amount = () => recallConfig.UnlockCost.Value,
					Prerequisite = (PlayerSorceryData data) => data.FirstAwakeningCompleted && SorceryProgression.FindAbility(data, "telekinesis") != null
				});
				resourceProgressionService.Register(new ResourceProgressionService.Requirement
				{
					Ability = "telekinesis",
					Modifier = "impulse",
					Item = "ReddeqUS_WeightlessDust",
					Amount = () => impulseConfig.UnlockCost.Value,
					Prerequisite = (PlayerSorceryData data) => data.FirstAwakeningCompleted && SorceryProgression.FindAbility(data, "telekinesis") != null
				});
				string[] array = new string[2] { "activeDefensiveShift", "passiveDefensiveShift" };
				foreach (string text in array)
				{
					resourceProgressionService.Register(new ResourceProgressionService.Requirement
					{
						Ability = "shift",
						Modifier = text,
						Item = "ReddeqUS_TremblingDust",
						Amount = ((text == "activeDefensiveShift") ? ((Func<int>)(() => defenseConfig.ActiveDefensiveShiftUnlockCost.Value)) : ((Func<int>)(() => defenseConfig.PassiveDefensiveShiftUnlockCost.Value))),
						Prerequisite = (PlayerSorceryData data) => SorceryProgression.FindAbility(data, "shift") != null
					});
				}
				resourceProgressionService.Register(new ResourceProgressionService.Requirement
				{
					Ability = "shift",
					Modifier = "offensiveShift",
					Item = "ReddeqUS_TremblingDust",
					Amount = () => offensiveConfig.UnlockCost.Value,
					Prerequisite = (PlayerSorceryData data) => SorceryProgression.FindAbility(data, "shift") != null
				});
				earlyItems = new EarlyProgressionItems(config2, ((BaseUnityPlugin)this).Logger, sorceryEffectRegistry);
				runicDeer = new RunicDeerContent(config3, ((BaseUnityPlugin)this).Logger, shiftEffects);
				runicBear = new RunicBearContent(config4, ((BaseUnityPlugin)this).Logger, sorceryEffectRegistry, () => config.DebugMode.Value);
				deerDebug = ((Component)this).gameObject.AddComponent<RunicDeerDebug>();
				deerDebug.Initialize(config, runicDeer);
				bearDebug = ((Component)this).gameObject.AddComponent<RunicBearDebug>();
				bearDebug.Initialize(config, runicBear);
				progressionDebug = ((Component)this).gameObject.AddComponent<ProgressionDebugNetwork>();
				progressionDebug.Initialize(config, progressionService, ((BaseUnityPlugin)this).Logger);
				CommandManager.Instance.AddConsoleCommand((ConsoleCommand)(object)new DebugSkillCommand(skillService, ((BaseUnityPlugin)this).Logger, sorceryPersistence, progressionService, () => config.EnableDebugCommands.Value));
				if ((int)SystemInfo.graphicsDeviceType != 4 && (!Object.op_Implicit((Object)(object)ZNet.instance) || !ZNet.instance.IsDedicated()))
				{
					sorceryEffects = ((Component)this).gameObject.AddComponent<SorceryEffectSystem>();
					sorceryEffects.Initialize(sorceryEffectConfig, sorceryEffectRegistry, ((BaseUnityPlugin)this).Logger);
					ImpulseService impulseService = impulse;
					if (impulseService != null && impulseService.Ready)
					{
						impulse.Visuals = ((Component)this).gameObject.AddComponent<ImpulseVfx>();
						impulse.Visuals.Initialize(((BaseUnityPlugin)this).Logger, sorceryEffectRegistry.Resolve("telekinesis").Primary);
					}
					sorceryUI = ((Component)this).gameObject.AddComponent<SorceryUI>();
					sorceryUI.Initialize(sorceryPersistence, abilityRegistry, awakening, access, progressionService, resourceProgressionService, ((BaseUnityPlugin)this).Logger, sorceryEffectRegistry, new AbilityStatsProvider(skillService, config, defenseConfig, offensiveConfig, telekinesisConfig, quickThrowConfig, impulseConfig, recallConfig, suspensionConfig));
					tranceAudio = ((Component)this).gameObject.AddComponent<TranceAudioController>();
					tranceAudio.Initialize(sorceryUI, ((BaseUnityPlugin)this).Config, ((BaseUnityPlugin)this).Logger);
					input = ((Component)this).gameObject.AddComponent<SorceryInput>();
					input.Initialize(config, abilityRegistry, skillService, awakening, sorceryPersistence, sorceryUI, ((BaseUnityPlugin)this).Logger);
				}
				sorceryDust = new SorceryDust(((BaseUnityPlugin)this).Logger, resourceProgressionService);
				configReload = new ConfigReloadService(((BaseUnityPlugin)this).Config, ((BaseUnityPlugin)this).Logger, delegate(IReadOnlyCollection<ConfigDefinition> changed)
				{
					if (Object.op_Implicit((Object)(object)sorceryUI))
					{
						sorceryUI.RefreshConfiguration();
					}
					if (changed.Contains(((ConfigEntryBase)dreamConfig.Duration).Definition))
					{
						dreamPotion.ApplyConfiguration();
					}
					if (changed.Any((ConfigDefinition key) => key.Section == "SorcerersMarkVisual"))
					{
						markVisualAssets.ApplyConfiguration();
					}
					if (changed.Any((ConfigDefinition key) => key.Section == "Food"))
					{
						earlyItems.ApplyConfiguration();
					}
					if (changed.Any((ConfigDefinition key) => key.Section == "RunicDeer"))
					{
						runicDeer.ApplyConfiguration();
					}
					if (changed.Any((ConfigDefinition key) => key.Section == "RunicBear"))
					{
						runicBear.ApplyConfiguration();
					}
				});
				CommandManager.Instance.AddConsoleCommand((ConsoleCommand)(object)new ConfigReloadCommand(configReload, deerDebug, bearDebug));
				((BaseUnityPlugin)this).Logger.LogInfo((object)("Registered native skills reddeq.utilitysorcery.skill.shift, reddeq.utilitysorcery.skill.telekinesis; abilities=" + abilityRegistry.OrderedIds.Count));
			}
			catch (Exception ex2)
			{
				Shutdown();
				((Behaviour)this).enabled = false;
				((BaseUnityPlugin)this).Logger.LogError((object)("Utility Sorcery initialization failed: " + ex2));
			}
		}

		private void Start()
		{
			SorceryLocalization.Refresh();
		}

		private void OnDestroy()
		{
			Shutdown();
		}

		private void Update()
		{
			configReload?.Tick();
		}

		private void Shutdown()
		{
			configReload?.Dispose();
			if (Object.op_Implicit((Object)(object)input))
			{
				((Behaviour)input).enabled = false;
				Object.Destroy((Object)(object)input);
			}
			if (Object.op_Implicit((Object)(object)tranceAudio))
			{
				((Behaviour)tranceAudio).enabled = false;
				Object.Destroy((Object)(object)tranceAudio);
			}
			if (Object.op_Implicit((Object)(object)sorceryUI))
			{
				sorceryUI.Close();
				Object.Destroy((Object)(object)sorceryUI);
			}
			if (Object.op_Implicit((Object)(object)progressionDebug))
			{
				((Behaviour)progressionDebug).enabled = false;
				Object.Destroy((Object)(object)progressionDebug);
			}
			sorceryDust?.Dispose();
			earlyItems?.Dispose();
			runicDeer?.Dispose();
			runicBear?.Dispose();
			if (Object.op_Implicit((Object)(object)bearDebug))
			{
				((Behaviour)bearDebug).enabled = false;
				Object.Destroy((Object)(object)bearDebug);
			}
			if (Object.op_Implicit((Object)(object)deerDebug))
			{
				((Behaviour)deerDebug).enabled = false;
				Object.Destroy((Object)(object)deerDebug);
			}
			dreamPotion?.Dispose();
			if (Object.op_Implicit((Object)(object)dreams))
			{
				((Behaviour)dreams).enabled = false;
				Object.Destroy((Object)(object)dreams);
			}
			TelekinesisImpactHandler.StopAll();
			impulse?.Dispose();
			recall?.Dispose();
			recall = null;
			quickThrow?.Dispose();
			quickThrow = null;
			if (Object.op_Implicit((Object)(object)suspension))
			{
				suspension.Shutdown();
				Object.Destroy((Object)(object)suspension);
			}
			if (Object.op_Implicit((Object)(object)recallVfx))
			{
				((Behaviour)recallVfx).enabled = false;
				Object.Destroy((Object)(object)recallVfx);
			}
			weaponLaunch?.Dispose();
			weaponLaunch = null;
			impulse = null;
			if (Object.op_Implicit((Object)(object)telekinesisNetwork))
			{
				telekinesisNetwork.Shutdown();
				Object.Destroy((Object)(object)telekinesisNetwork);
			}
			if (Object.op_Implicit((Object)(object)sorceryEffects))
			{
				sorceryEffects.Shutdown();
				Object.Destroy((Object)(object)sorceryEffects);
			}
			AbilityEffectEvents.Log = null;
			OffensiveShiftFacing.Clear();
			offensiveBuff?.Dispose();
			offensiveBuff = null;
			defensiveShifts?.Dispose();
			defensiveShifts = null;
			SorceryPlayerHooks.Uninstall();
			awakening?.Dispose();
			awakening = null;
			shiftEffects?.Dispose();
			markVisualAssets?.Dispose();
			skillIcons?.Dispose();
			skillIcons = null;
			SorceryLocalization.Shutdown();
		}
	}
}
namespace ReddeqsUtilitySorcery.UI
{
	internal static class AbilityStatsFormatting
	{
		internal static string Number(float value, CultureInfo culture, bool signed = false)
		{
			if (float.IsNaN(value) || float.IsInfinity(value))
			{
				throw new ArgumentOutOfRangeException("value");
			}
			float num = Math.Abs(value);
			string text = value.ToString((num > 0f && num < 0.1f) ? "G2" : "0.#", culture);
			if (!signed || !(value > 0f))
			{
				return text;
			}
			return "+" + text;
		}

		internal static string Value(AbilityStat row)
		{
			string text = Number(row.Value, CultureInfo.CurrentCulture, row.Unit == AbilityStatUnit.PercentBonus);
			string text2 = SorceryLocalization.Format(UnitToken(row.Unit), text);
			if (row.State != null)
			{
				return SorceryLocalization.Format("$reddequs_ui_stats_value_state", text2, SorceryLocalization.Translate(row.State));
			}
			return text2;
		}

		internal static string UnitToken(AbilityStatUnit unit)
		{
			return unit switch
			{
				AbilityStatUnit.Eitr => "$reddequs_ui_stats_unit_eitr", 
				AbilityStatUnit.EitrPerSecond => "$reddequs_ui_stats_unit_eitr_per_second", 
				AbilityStatUnit.Metres => "$reddequs_ui_stats_unit_metres", 
				AbilityStatUnit.Seconds => "$reddequs_ui_stats_unit_seconds", 
				AbilityStatUnit.MetresPerSecond => "$reddequs_ui_stats_unit_speed", 
				AbilityStatUnit.PercentBonus => "$reddequs_ui_stats_unit_percent", 
				_ => throw new ArgumentOutOfRangeException("unit"), 
			};
		}
	}
	internal enum AbilityStatUnit
	{
		Eitr,
		EitrPerSecond,
		Metres,
		Seconds,
		MetresPerSecond,
		PercentBonus
	}
	internal readonly struct AbilityStat
	{
		internal readonly string Label;

		internal readonly string State;

		internal readonly float Value;

		internal readonly AbilityStatUnit Unit;

		internal AbilityStat(string label, float value, AbilityStatUnit unit, string state = null)
		{
			Label = label;
			Value = value;
			Unit = unit;
			State = state;
		}
	}
	internal sealed class AbilityStats
	{
		internal static readonly AbilityStats Empty = new AbilityStats(null, Array.Empty<AbilityStat>());

		internal readonly float? SkillLevel;

		internal readonly IReadOnlyList<AbilityStat> Rows;

		internal AbilityStats(float? skillLevel, IReadOnlyList<AbilityStat> rows)
		{
			SkillLevel = skillLevel;
			Rows = rows;
		}

		internal bool SameAs(AbilityStats other)
		{
			if (other == null || SkillLevel != other.SkillLevel || Rows.Count != other.Rows.Count)
			{
				return false;
			}
			for (int i = 0; i < Rows.Count; i++)
			{
				AbilityStat abilityStat = Rows[i];
				AbilityStat abilityStat2 = other.Rows[i];
				if (abilityStat.Label != abilityStat2.Label || abilityStat.Value != abilityStat2.Value || abilityStat.Unit != abilityStat2.Unit || abilityStat.State != abilityStat2.State)
				{
					return false;
				}
			}
			return true;
		}
	}
	internal sealed class AbilityStatsProvider
	{
		private readonly SkillService skills;

		private readonly ModConfig shift;

		private readonly DefensiveShiftConfig defense;

		private readonly OffensiveShiftConfig offense;

		private readonly TelekinesisConfig telekinesis;

		private readonly QuickThrowConfig quick;

		private readonly ImpulseConfig impulse;

		private readonly RecallConfig recall;

		private readonly SuspensionConfig suspension;

		internal AbilityStatsProvider(SkillService skills, ModConfig shift, DefensiveShiftConfig defense, OffensiveShiftConfig offense, TelekinesisConfig telekinesis, QuickThrowConfig quick, ImpulseConfig impulse, RecallConfig recall, SuspensionConfig suspension)
		{
			this.skills = skills;
			this.shift = shift;
			this.defense = defense;
			this.offense = offense;
			this.telekinesis = telekinesis;
			this.quick = quick;
			this.impulse = impulse;
			this.recall = recall;
			this.suspension = suspension;
		}

		internal AbilityStats Get(Player player, string ability, string modifier)
		{
			//IL_0025: Unknown result type (might be due to invalid IL or missing references)
			if (!Object.op_Implicit((Object)(object)player) || skills == null || (Object)(object)((Character)player).GetSkills() == (Object)null || (int)skills.GetSkillType(ability) == 0)
			{
				return AbilityStats.Empty;
			}
			string reserveState = null;
			float? reserved = null;
			ZNetView component = ((Component)player).GetComponent<ZNetView>();
			if (Object.op_Implicit((Object)(object)component) && component.IsValid())
			{
				ZDO zDO = component.GetZDO();
				if (ability == "shift" && modifier == "passiveDefensiveShift" && DefensiveShiftService.Current != null)
				{
					int num = zDO.GetInt("reddeq.utilitysorcery.zdo.defensive_shift.passive_indicator", 0);
					reserveState = ReserveState((num == 1) ? 2 : ((num == 3) ? 1 : 0));
				}
				else if (ability == "telekinesis" && modifier == "recall" && RecallService.Current != null)
				{
					reserveState = ReserveState(zDO.GetInt("reddeq.utilitysorcery.zdo.recall.indicator", 0));
				}
				else if (ability == "telekinesis" && modifier == "suspension" && Object.op_Implicit((Object)(object)SuspensionService.Current))
				{
					reserved = SuspensionService.Current.ReservedEitr(player);
				}
			}
			return Calculate(ability, modifier, skills.GetLevel(player, ability), Game.m_eitrRate, reserveState, reserved);
		}

		internal AbilityStats Calculate(string ability, string modifier, float level, float eitrRate, string reserveState = null, float? reserved = null)
		{
			if (!TelekinesisBalance.Finite(level) || level < 0f || level > 100f)
			{
				return AbilityStats.Empty;
			}
			List<AbilityStat> rows = new List<AbilityStat>();
			if (ability == "shift")
			{
				if (modifier == null && shift != null)
				{
					if (Valid(shift.ShiftBaseEitrCost.Value) && Valid(shift.ShiftMinEitrCost.Value))
					{
						Cost("$reddequs_ui_stats_cost", shift.ShiftCost(level));
					}
					if (Valid(shift.ShiftBaseDistance.Value) && Valid(shift.ShiftMaxDistance.Value))
					{
						Add("$reddequs_ui_stats_range", shift.ShiftRange(level), AbilityStatUnit.Metres);
					}
					if (shift.ShiftCooldown.Value > 0f)
					{
						Add("$reddequs_ui_stats_cooldown", shift.ShiftCooldown.Value, AbilityStatUnit.Seconds);
					}
				}
				else if (modifier == "activeDefensiveShift" && defense != null)
				{
					Add("$reddequs_ui_stats_cost", defense.ActiveCost(level), AbilityStatUnit.Eitr);
				}
				else if (modifier == "passiveDefensiveShift" && defense != null)
				{
					Add("$reddequs_ui_stats_reserve", defense.PassiveDefensiveShiftEitrReserve.Value, AbilityStatUnit.Eitr, reserveState);
					if (defense.PassiveCooldown(level) > 0f)
					{
						Add("$reddequs_ui_stats_cooldown", defense.PassiveCooldown(level), AbilityStatUnit.Seconds);
					}
				}
				else if (modifier == "offensiveShift" && offense != null && Valid(offense.DamageBonusAtSkill0.Value) && Valid(offense.DamageBonusAtSkill100.Value))
				{
					Add("$reddequs_ui_stats_damage_bonus", offense.Bonus(level), AbilityStatUnit.PercentBonus);
				}
			}
			else if (ability == "telekinesis")
			{
				if (modifier == null && telekinesis != null)
				{
					Add("$reddequs_ui_stats_drain", (TelekinesisBalance.Finite(eitrRate) && eitrRate >= 0f) ? (telekinesis.Cost(level) * eitrRate) : float.NaN, AbilityStatUnit.EitrPerSecond);
					Add("$reddequs_ui_stats_capture_hold_range", telekinesis.Range(level), AbilityStatUnit.Metres);
					Cost("$reddequs_ui_stats_throw_cost", telekinesis.ThrowCost(level));
				}
				else if (modifier == "quickThrow" && quick != null)
				{
					Add("$reddequs_ui_stats_cost", QuickThrowSelection.ActualCost(quick.Cost(level), eitrRate), AbilityStatUnit.Eitr);
					Add("$reddequs_ui_stats_throw_power", quick.Power(level), AbilityStatUnit.MetresPerSecond);
					Add("$reddequs_ui_stats_speed_limit", quick.MaximumLaunchSpeed.Value, AbilityStatUnit.MetresPerSecond);
				}
				else if (modifier == "impulse" && impulse != null)
				{
					Cost("$reddequs_ui_stats_cost", impulse.Cost(level));
					Add("$reddequs_ui_stats_speed_bonus", (impulse.Velocity(level) - 1f) * 100f, AbilityStatUnit.PercentBonus);
					Add("$reddequs_ui_stats_direct_damage_bonus", (impulse.DamageMultiplier(level) - 1f) * 100f, AbilityStatUnit.PercentBonus);
				}
				else if (modifier == "recall" && recall != null)
				{
					Add("$reddequs_ui_stats_reserve", recall.EitrReserve.Value, AbilityStatUnit.Eitr, reserveState);
					Add("$reddequs_ui_stats_return_speed", recall.Speed(level), AbilityStatUnit.MetresPerSecond);
				}
				else if (modifier == "suspension" && suspension != null)
				{
					Add("$reddequs_ui_stats_reserve_per_object", suspension.EitrReservePerObject.Value, AbilityStatUnit.Eitr);
					if (reserved.HasValue)
					{
						Add("$reddequs_ui_stats_active_reserve", reserved.Value, AbilityStatUnit.Eitr);
					}
					if (telekinesis != null)
					{
						Add("$reddequs_ui_stats_range", telekinesis.Range(level), AbilityStatUnit.Metres);
					}
				}
			}
			if (rows.Count != 0)
			{
				return new AbilityStats(level, rows.ToArray());
			}
			return AbilityStats.Empty;
			void Add(string label, float value, AbilityStatUnit unit, string state = null)
			{
				if (TelekinesisBalance.Finite(value) && (value >= 0f || unit == AbilityStatUnit.PercentBonus))
				{
					rows.Add(new AbilityStat(label, value, unit, state));
				}
			}
			void Cost(string label, float value)
			{
				Add(label, (TelekinesisBalance.Finite(eitrRate) && eitrRate >= 0f) ? (value * eitrRate) : float.NaN, AbilityStatUnit.Eitr);
			}
		}

		private static bool Valid(float value)
		{
			if (TelekinesisBalance.Finite(value))
			{
				return value >= 0f;
			}
			return false;
		}

		internal static string ReserveState(int state)
		{
			return state switch
			{
				1 => "$reddequs_ui_stats_reserve_unavailable", 
				2 => "$reddequs_ui_stats_reserve_active", 
				_ => "$reddequs_ui_stats_reserve_inactive", 
			};
		}
	}
	[DisallowMultipleComponent]
	internal sealed class SorceryUI : MonoBehaviour
	{
		private SorceryPersistence persistence;

		private AbilityRegistry registry;

		private SorceryAwakeningService awakening;

		private TranceAccessService access;

		private ProgressionService progression;

		private ResourceProgressionService resources;

		private bool lastDebugPermission;

		private ManualLogSource logger;

		private Player owner;

		private GameObject overlay;

		private GameObject fadingOverlay;

		private TranceMistVfx mist;

		private GameObject panel;

		private bool blocked;

		private bool opening;

		private static bool inputBlocked;

		private static int lastCloseFrame = -1;

		private string abilityPage;

		private string modifierPage;

		private string assigningAbility;

		private string flashKey;

		private int? slotPage;

		private TranceAssetRegistry assets;

		private TranceRuneCircleView circle;

		private TranceInfoPanelView info;

		private Vector2 previousSize;

		private float inventoryRefreshAt;

		private int displayedOwned = -1;

		private string displayedAbility;

		private string displayedModifier;

		private int? displayedSlot;

		private bool rebuilding;

		private int lastActionFrame = -1;

		private readonly TranceNodeClicks nodeClicks = new TranceNodeClicks();

		private string status;

		private bool localizationChanged;

		private bool configurationChanged;

		private AbilityStatsProvider statsProvider;

		private AbilityStats displayedStats = AbilityStats.Empty;

		internal bool CanManageProgression
		{
			get
			{
				if (progression != null)
				{
					return progression.CanDebug(owner);
				}
				return false;
			}
		}

		internal bool IsOpen => blocked;

		internal static bool GameplayBlocked
		{
			get
			{
				if (!inputBlocked)
				{
					return lastCloseFrame == Time.frameCount;
				}
				return true;
			}
		}

		internal event Action<Player> TranceStarted;

		internal event Action TranceEnded;

		internal void Initialize(SorceryPersistence persistence, AbilityRegistry registry, SorceryAwakeningService awakening, TranceAccessService access, ProgressionService progression, ResourceProgressionService resources, ManualLogSource logger, SorceryEffectRegistry effects, AbilityStatsProvider statsProvider)
		{
			this.statsProvider = statsProvider;
			this.persistence = persistence;
			this.registry = registry;
			this.awakening = awakening;
			this.access = access;
			this.progression = progression;
			this.resources = resources;
			persistence.Changed += OnProgressionChanged;
			progression.DebugCompleted += OnDebugCompleted;
			this.logger = logger;
			assets = new TranceAssetRegistry(logger, effects);
			_ = GUIManager.Instance;
			GUIManager.OnCustomGUIAvailable += OnSceneGUIAvailable;
			LocalizationManager.OnLocalizationAdded += OnLocalizationAdded;
		}

		private void OnLocalizationAdded()
		{
			localizationChanged = true;
		}

		internal void RefreshConfiguration()
		{
			configurationChanged = true;
		}

		private void OnProgressionChanged(Player player)
		{
			if ((Object)(object)player == (Object)(object)owner)
			{
				localizationChanged = true;
			}
		}

		private void OnDebugCompleted(Player player, bool success)
		{
			if (!((Object)(object)player != (Object)(object)owner))
			{
				status = (success ? null : "$reddequs_ui_progression_operation_unavailable");
				if (success && abilityPage != null)
				{
					flashKey = abilityPage + ((modifierPage == null) ? "" : ("/" + modifierPage));
				}
				localizationChanged = true;
			}
		}

		private void OnSceneGUIAvailable()
		{
			Close(immediate: true);
		}

		private bool CanRemainOpen(Player player)
		{
			if (access != null)
			{
				return access.CanOpenTrance(player);
			}
			return false;
		}

		internal bool CanOpen(Player player)
		{
			if (((Behaviour)this).isActiveAndEnabled && !IsOpen && !opening && CanRemainOpen(player) && SorceryInput.AllowsGameplayInput && persistence != null && persistence.CanWrite(player))
			{
				return Object.op_Implicit((Object)(object)GUIManager.CustomGUIFront);
			}
			return false;
		}

		internal bool Open(Player player)
		{
			if (!CanOpen(player))
			{
				if (!IsOpen && !opening && PlayerAuthority.IsLocalOwner(player) && ((Character)player).IsSitting())
				{
					AbilityEffectEvents.Failure(player, persistence.SelectedAbility(player), AbilityResult.Failed(AbilityFailure.Rejected, "$reddequs_ui_trance_locked"));
				}
				return false;
			}
			opening = true;
			try
			{
				owner = player;
				((Component)player).GetComponent<AbilityController>()?.ReleaseForTrance();
				abilityPage = null;
				status = null;
				CreateOverlay();
				Render();
				GUIManager.BlockInput(true);
				blocked = true;
				inputBlocked = true;
				this.TranceStarted?.Invoke(owner);
				return true;
			}
			catch (Exception ex)
			{
				logger.LogError((object)("Cannot open Sorcery trance UI: " + ex));
				Close();
				return false;
			}
			finally
			{
				opening = false;
			}
		}

		private void CreateOverlay()
		{
			//IL_002c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0036: Expected O, but got Unknown
			//IL_007b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0086: Unknown result type (might be due to invalid IL or missing references)
			//IL_0091: 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_00c4: Unknown result type (might be due to invalid IL or missing references)
			DestroyFadingOverlay();
			overlay = new GameObject("UtilitySorceryTrance", new Type[2]
			{
				typeof(RectTransform),
				typeof(Image)
			});
			overlay.layer = 5;
			overlay.AddComponent<TranceBackgroundClick>().Initialize(delegate
			{
				Invoke(ReturnToMark);
			});
			RectTransform component = overlay.GetComponent<RectTransform>();
			((Transform)component).SetParent(GUIManager.CustomGUIFront.transform, false);
			component.anchorMin = Vector2.zero;
			component.anchorMax = Vector2.one;
			component.offsetMin = Vector2.zero;
			component.offsetMax = Vector2.zero;
			((Graphic)overlay.GetComponent<Image>()).color = new Color(0f, 0f, 0f, 0.7f);
			mist = TranceMistVfx.Create(overlay.transform, logger);
		}

		private void Render()
		{
			//IL_00be: Unknown result type (might be due to invalid IL or missing references)
			//IL_00cd: Unknown result type (might be due to invalid IL or missing references)
			localizationChanged = (configurationChanged = false);
			lastDebugPermission = CanManageProgression;
			PlayerSorceryData playerSorceryData = persistence.Snapshot(owner);
			if (playerSorceryData == null || playerSorceryData.version != 3)
			{
				Close();
				return;
			}
			if (assigningAbility != null && (SorceryProgression.FindAbility(playerSorceryData, assigningAbility) == null || playerSorceryData.slots.Count == 0))
			{
				assigningAbility = null;
			}
			if (slotPage.HasValue && !playerSorceryData.slots.Exists((AbilitySlotState s) => s.id == slotPage))
			{
				slotPage = null;
			}
			if (!Object.op_Implicit((Object)(object)panel))
			{
				panel = ((Component)TranceWidgets.Rect("TranceScreen", overlay.transform, Vector2.zero, new Vector2(1500f, 900f))).gameObject;
				CanvasGroup val = panel.AddComponent<CanvasGroup>();
				circle = new TranceRuneCircleView(panel.transform, assets);
				info = new TranceInfoPanelView(panel.transform, assets, Invoke, Close);
				panel.AddComponent<TranceAnimation>().Initialize(val);
				Fit();
			}
			rebuilding = true;
			try
			{
				circle.Render(registry, playerSorceryData, abilityPage, modifierPage, slotPage, assigningAbility != null, SelectNode, Preview, InvokeNode, flashKey);
				flashKey = null;
				ShowInfo(abilityPage, modifierPage, slotPage);
			}
			finally
			{
				rebuilding = false;
			}
		}

		private void Fit()
		{
			//IL_0027: 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_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_0044: Unknown result type (might be due to invalid IL or missing references)
			//IL_0067: Unknown result type (might be due to invalid IL or missing references)
			if (Object.op_Implicit((Object)(object)panel) && Object.op_Implicit((Object)(object)overlay))
			{
				Rect rect = overlay.GetComponent<RectTransform>().rect;
				previousSize = ((Rect)(ref rect)).size;
				panel.transform.localScale = Vector3.one * (float)TranceLayout.Scale(previousSize.x, previousSize.y);
			}
		}

		private void SelectNode(string ability, string modifier, int? slot)
		{
			bool num = nodeClicks.Register(ability, modifier, slot, Time.unscaledTime);
			Select(ability, modifier, slot);
			if (!num || !registry.TryGet(ability, out var ability2))
			{
				return;
			}
			PlayerSorceryData playerSorceryData = persistence.Snapshot(owner);
			if (playerSorceryData == null)
			{
				return;
			}
			bool flag = SorceryProgression.FindAbility(playerSorceryData, ability) != null;
			if (modifier == null)
			{
				if (!flag)
				{
					Purchase(ability, null);
				}
				else
				{
					ToggleAssignment(ability);
				}
				return;
			}
			foreach (AbilityParameterDefinition parameter in ability2.Definition.Parameters)
			{
				if (parameter.Id == modifier)
				{
					if (!SorceryProgression.ModifierLearned(playerSorceryData, ability, modifier))
					{
						Purchase(ability, modifier);
					}
					else if (flag)
					{
						ToggleModifier(ability, modifier);
					}
					break;
				}
			}
		}

		private void ToggleModifier(string abilityId, string modifierId)
		{
			PlayerSorceryData playerSorceryData = persistence.Snapshot(owner);
			if (playerSorceryData != null)
			{
				bool flag = progression.SetModifier(owner, abilityId, modifierId, !SorceryProgression.Parameter(playerSorceryData, abilityId, modifierId));
				status = (flag ? null : "$reddequs_ui_progression_unavailable");
				if (flag)
				{
					flashKey = abilityId + "/" + modifierId;
				}
			}
		}

		private void ToggleAssignment(string abilityId)
		{
			PlayerSorceryData playerSorceryData = persistence.Snapshot(owner);
			if (playerSorceryData == null || SorceryProgression.FindAbility(playerSorceryData, abilityId) == null)
			{
				return;
			}
			if (playerSorceryData.slots.Count == 0)
			{
				status = "$reddequs_ui_trance_no_slots";
				return;
			}
			if (!playerSorceryData.slots.Exists((AbilitySlotState slot) => slot.abilityId == abilityId))
			{
				assigningAbility = abilityId;
				status = null;
				return;
			}
			bool flag = true;
			foreach (AbilitySlotState slot in playerSorceryData.slots)
			{
				if (slot.abilityId == abilityId)
				{
					flag &= progression.AssignSlot(owner, slot.id, null);
				}
			}
			status = (flag ? "$reddequs_ui_trance_removed" : "$reddequs_ui_progression_unavailable");
		}

		private void Select(string ability, string modifier, int? slot)
		{
			if (slot.HasValue && assigningAbility != null)
			{
				if (progression.AssignSlot(owner, slot.Value, assigningAbility))
				{
					flashKey = "slot/" + slot.Value;
					status = "$reddequs_ui_trance_assigned";
					assigningAbility = null;
				}
				else
				{
					status = "$reddequs_ui_progression_unavailable";
				}
			}
			else if (!slot.HasValue)
			{
				assigningAbility = null;
			}
			abilityPage = ability;
			modifierPage = modifier;
			slotPage = slot;
		}

		private void ReturnToMark()
		{
			abilityPage = (modifierPage = (assigningAbility = null));
			slotPage = null;
			status = (flashKey = null);
		}

		private void Preview(string ability, string modifier, int? slot, bool hover)
		{
			if (IsOpen && !rebuilding && assigningAbility == null)
			{
				if (hover)
				{
					ShowInfo(ability, modifier, slot);
				}
				else
				{
					ShowInfo(abilityPage, modifierPage, slotPage);
				}
			}
		}

		private void ShowInfo(string abilityId, string modifierId, int? slotId)
		{
			//IL_01c6: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b2: Unknown result type (might be due to invalid IL or missing references)
			//IL_02af: Unknown result type (might be due to invalid IL or missing references)
			//IL_029b: Unknown result type (might be due to invalid IL or missing references)
			//IL_02ff: Unknown result type (might be due to invalid IL or missing references)
			//IL_04fb: Unknown result type (might be due to invalid IL or missing references)
			//IL_055a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0616: Unknown result type (might be due to invalid IL or missing references)
			//IL_05de: Unknown result type (might be due to invalid IL or missing references)
			//IL_0767: Unknown result type (might be due to invalid IL or missing references)
			//IL_0751: Unknown result type (might be due to invalid IL or missing references)
			if (info == null || !Object.op_Implicit((Object)(object)owner))
			{
				return;
			}
			PlayerSorceryData playerSorceryData = persistence.Snapshot(owner);
			if (playerSorceryData == null)
			{
				return;
			}
			displayedAbility = abilityId;
			displayedModifier = modifierId;
			displayedSlot = slotId;
			displayedStats = ((assigningAbility != null || slotId.HasValue) ? AbilityStats.Empty : (statsProvider?.Get(owner, abilityId, modifierId) ?? AbilityStats.Empty));
			configurationChanged = false;
			resources.Inspect(owner, abilityId, modifierId, out var _, out displayedOwned, out var _);
			bool flag = abilityId == null && !slotId.HasValue;
			TranceInfoPanelView tranceInfoPanelView = info;
			string[] obj = new string[5] { abilityId, "/", modifierId, "/", null };
			int? num = slotId;
			obj[4] = num.ToString();
			tranceInfoPanelView.Begin(string.Concat(obj), (flag || (slotId.HasValue && assigningAbility == null)) ? null : status);
			IUtilityAbility ability3;
			if (assigningAbility != null)
			{
				info.Illustration(assets.Rune(assigningAbility), registry.TryGet(assigningAbility, out var ability) ? assets.Color(ability.Definition) : Color.white);
				info.Label("$reddequs_ui_trance_choose_slot", 27);
				info.Label("$reddequs_ui_trance_assign_hint", 20);
				info.Action("$reddequs_ui_trance_cancel", delegate
				{
					assigningAbility = null;
				});
			}
			else if (slotId.HasValue)
			{
				AbilitySlotState abilitySlotState = playerSorceryData.slots.Find((AbilitySlotState s) => s.id == slotId.Value);
				if (abilitySlotState == null)
				{
					return;
				}
				IUtilityAbility ability2;
				bool flag2 = registry.TryGet(abilitySlotState.abilityId, out ability2);
				info.Illustration(flag2 ? assets.Rune(abilitySlotState.abilityId) : assets.BaseRune, flag2 ? assets.Color(ability2.Definition) : TranceWidgets.Bronze);
				if (!flag2)
				{
					info.Label("$reddequs_ui_common_empty", 29);
				}
				else
				{
					info.Label(ability2.Definition.NameToken, 29, assets.Color(ability2.Definition));
					foreach (AbilityParameterDefinition parameter2 in ability2.Definition.Parameters)
					{
						if (SorceryProgression.Parameter(playerSorceryData, abilitySlotState.abilityId, parameter2.Id))
						{
							info.Label(parameter2.NameToken);
						}
					}
				}
			}
			else if (abilityId != null && registry.TryGet(abilityId, out ability3))
			{
				AbilityDefinition definition = ability3.Definition;
				AbilityParameterDefinition parameter = null;
				foreach (AbilityParameterDefinition parameter3 in definition.Parameters)
				{
					if (parameter3.Id == modifierId)
					{
						parameter = parameter3;
					}
				}
				bool flag3 = SorceryProgression.FindAbility(playerSorceryData, abilityId) != null;
				bool learned = ((parameter == null) ? flag3 : SorceryProgression.ModifierLearned(playerSorceryData, abilityId, modifierId));
				bool flag4 = ((parameter == null) ? playerSorceryData.slots.Exists((AbilitySlotState s) => s.abilityId == abilityId) : (flag3 && SorceryProgression.Parameter(playerSorceryData, abilityId, modifierId)));
				info.Illustration((parameter == null) ? assets.Rune(abilityId) : assets.Modifier(abilityId, modifierId), assets.Color(definition));
				info.Label(parameter?.NameToken ?? definition.NameToken, 30);
				if (parameter != null)
				{
					info.Label(definition.NameToken, 18, assets.Color(definition));
				}
				info.Label(learned ? "$reddequs_ui_ability_learned" : "$reddequs_ui_ability_unlearned", 20);
				if (learned)
				{
					info.Label((!flag4) ? "$reddequs_ui_trance_inactive" : ((parameter == null) ? "$reddequs_ui_trance_in_slot" : "$reddequs_ui_trance_enabled"), 19, flag4 ? new Color?(assets.Color(definition)) : ((Color?)null));
				}
				if (parameter != null && !flag3)
				{
					info.Label("$reddequs_ui_trance_requires_ability", 19, (Color?)new Color(0.77f, 0.53f, 0.4f));
				}
				info.Separator();
				info.Label(parameter?.DescriptionToken ?? definition.DescriptionToken);
				info.Statistics(displayedStats);
				info.Separator();
				if (!learned)
				{
					int required2;
					int owned;
					bool prerequisites2;
					bool num2 = resources.Inspect(owner, abilityId, modifierId, out required2, out owned, out prerequisites2);
					displayedOwned = owned;
					info.Label("$reddequs_ui_trance_unlock_cost", 19);
					if (num2)
					{
						info.Label(SorceryLocalization.Format("$reddequs_ui_trance_resource_count", Localize(resources.ItemName(abilityId, modifierId)), owned, required2), 21, (Color?)((owned >= required2) ? new Color(0.56f, 0.73f, 0.6f) : new Color(0.84f, 0.54f, 0.4f)));
						bool flag5 = prerequisites2 && owned >= required2;
						info.Label(flag5 ? "$reddequs_ui_trance_requirements_met" : "$reddequs_ui_trance_requirements_missing", 18);
						if (!CanManageProgression)
						{
							info.Action("$reddequs_ui_trance_learn", delegate
							{
								Purchase(abilityId, modifierId);
							}, flag5);
						}
					}
					else
					{
						info.Label("$reddequs_ui_trance_no_unlock", 19);
					}
				}
				else if (parameter != null && flag3)
				{
					info.Action(flag4 ? "$reddequs_ui_trance_disable" : "$reddequs_ui_trance_enable", delegate
					{
						ToggleModifier(abilityId, modifierId);
					});
				}
				else if (parameter == null)
				{
					info.Action(flag4 ? "$reddequs_ui_trance_unassign" : "$reddequs_ui_trance_assign", delegate
					{
						ToggleAssignment(abilityId);
					}, playerSorceryData.slots.Count > 0);
					if (playerSorceryData.slots.Count == 0)
					{
						info.Label("$reddequs_ui_trance_no_slots", 19);
					}
				}
				if (parameter == null && definition.Parameters.Count > 0)
				{
					info.Separator();
					info.Label("$reddequs_ui_trance_modifiers", 18);
					foreach (AbilityParameterDefinition parameter4 in definition.Parameters)
					{
						string token = ((!SorceryProgression.ModifierLearned(playerSorceryData, abilityId, parameter4.Id)) ? "$reddequs_ui_ability_unlearned" : (SorceryProgression.Parameter(playerSorceryData, abilityId, parameter4.Id) ? "$reddequs_ui_trance_enabled" : "$reddequs_ui_trance_inactive"));
						info.Label(SorceryLocalization.Format("$reddequs_ui_parameter_state", Localize(parameter4.NameToken), Localize(token)), 18);
					}
				}
				if (CanManageProgression)
				{
					info.Separator();
					info.Label("$reddequs_ui_progression_debug", 17);
					info.DetailAction((!learned) ? ((parameter == null) ? "$reddequs_ui_progression_grant_ability" : "$reddequs_ui_progression_grant_modifier") : ((parameter == null) ? "$reddequs_ui_progression_revoke_ability" : "$reddequs_ui_progression_revoke_modifier"), delegate
					{
						DebugOperation((parameter != null) ? (learned ? DebugProgressionOperation.RevokeModifier : DebugProgressionOperation.UnlockModifier) : (learned ? DebugProgressionOperation.RevokeAbility : DebugProgressionOperation.UnlockAbility), abilityId, modifierId ?? "");
					}, parameter == null || flag3 || learned);
				}
			}
			if (assigningAbility == null && flag)
			{
				RenderMark(playerSorceryData);
			}
			info.End();
		}

		private void RenderMark(PlayerSorceryData data)
		{
			//IL_0018: Unknown result type (might be due to invalid IL or missing references)
			int highestUnlockedMarkTier = data.highestUnlockedMarkTier;
			info.Illustration(assets.BaseRune, TranceWidgets.Bronze);
			info.Label(SorceryLocalization.Format("$reddequs_ui_mark_heading", highestUnlockedMarkTier), 26);
			bool flag = awakening.IsAwakened(owner);
			info.Label(flag ? "$reddequs_ui_mark_awakened" : "$reddequs_ui_mark_dormant", 20);
			info.Label(SorceryLocalization.Format("$reddequs_ui_mark_eitr_bonus", awakening.GetMarkEitrBonus(owner)), 20);
			info.VisibilityToggle("$reddequs_ui_mark_visible", data.MarkVisible ?? true, delegate(bool visible)
			{
				awakening.SetMarkVisible(owner, visible);
			}, flag);
			RenderDebugSlots(data);
		}

		private void RenderDebugSlots(PlayerSorceryData data)
		{
			if (CanManageProgression)
			{
				info.Separator();
				info.Label("$reddequs_ui_progression_debug", 17);
				info.DetailAction("$reddequs_ui_progression_add_slot", delegate
				{
					DebugOperation(DebugProgressionOperation.AddSlot);
				}, data.slots.Count < 3);
				info.DetailAction("$reddequs_ui_progression_remove_slot", delegate
				{
					DebugOperation(DebugProgressionOperation.RemoveSlot);
				}, data.slots.Count > 0);
			}
		}

		private void Purchase(string abilityId, string modifierId)
		{
			if (!resources.Inspect(owner, abilityId, modifierId, out var required, out var owned, out var prerequisites))
			{
				status = "$reddequs_ui_trance_no_unlock";
				return;
			}
			if (!prerequisites)
			{
				status = "$reddequs_ui_trance_requirements_missing";
				return;
			}
			if (owned < required)
			{
				status = "$reddequs_message_progression_resources_missing";
				return;
			}
			bool flag = resources.Purchase(owner, abilityId, modifierId);
			status = (flag ? "$reddequs_ui_trance_learn_success" : "$reddequs_ui_progression_unavailable");
			if (flag)
			{
				flashKey = abilityId + ((modifierId == null) ? "" : ("/" + modifierId));
			}
		}

		private void DebugOperation(DebugProgressionOperation operation, string abilityId = "", string modifierId = "")
		{
			status = "$reddequs_ui_trance_pending";
			if (!progression.RequestDebug(owner, operation, abilityId, modifierId))
			{
				status = "$reddequs_ui_progression_operation_unavailable";
			}
		}

		internal static string Localize(string token)
		{
			return SorceryLocalization.Translate(token);
		}

		private void Invoke(Action action)
		{
			Invoke(action, resetClicks: true);
		}

		private void InvokeNode(Action action)
		{
			Invoke(action, resetClicks: false);
		}

		private void Invoke(Action action, bool resetClicks)
		{
			if (!IsOpen || lastActionFrame == Time.frameCount)
			{
				return;
			}
			if (!CanRemainOpen(owner))
			{
				Close();
				return;
			}
			if (resetClicks)
			{
				nodeClicks.Reset();
			}
			lastActionFrame = Time.frameCount;
			try
			{
				action();
				if (IsOpen)
				{
					Render();
				}
			}
			catch (Exception ex)
			{
				logger.LogError((object)("Sorcery UI action failed: " + ex));
				Close();
			}
		}

		private void Update()
		{
			//IL_0044: Unknown result type (might be due to invalid IL or missing references)
			//IL_0049: 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_0052: Unknown result type (might be due to invalid IL or missing references)
			if (!IsOpen)
			{
				return;
			}
			if (!Object.op_Implicit((Object)(object)overlay) || !CanRemainOpen(owner) || UnityInput.Current.GetKeyDown((KeyCode)27))
			{
				Close();
				return;
			}
			Rect rect = overlay.GetComponent<RectTransform>().rect;
			if (((Rect)(ref rect)).size != previousSize)
			{
				Fit();
			}
			if (localizationChanged || lastDebugPermission != CanManageProgression)
			{
				Render();
			}
			else if (Time.unscaledTime >= inventoryRefreshAt && !UnityInput.Current.GetMouseButton(0))
			{
				inventoryRefreshAt = Time.unscaledTime + 0.5f;
				resources.Inspect(owner, displayedAbility, displayedModifier, out var _, out var owned, out var _);
				AbilityStats abilityStats = ((assigningAbility != null || displayedSlot.HasValue) ? AbilityStats.Empty : (statsProvider?.Get(owner, displayedAbility, displayedModifier) ?? AbilityStats.Empty));
				if (configurationChanged || owned != displayedOwned || !abilityStats.SameAs(displayedStats))
				{
					ShowInfo(displayedAbility, displayedModifier, displayedSlot);
				}
			}
		}

		internal void Close()
		{
			Close(immediate: false);
		}

		private void Close(bool immediate)
		{
			nodeClicks.Reset();
			bool flag = blocked;
			if (immediate)
			{
				DestroyFadingOverlay();
			}
			if (Object.op_Implicit((Object)(object)overlay))
			{
				if (!immediate && flag)
				{
					if (Object.op_Implicit((Object)(object)panel))
					{
						panel.GetComponent<CanvasGroup>().blocksRaycasts = false;
						panel.GetComponent<TranceAnimation>().Close();
					}
					((Graphic)overlay.GetComponent<Image>()).raycastTarget = false;
					if (Object.op_Implicit((Object)(object)mist))
					{
						mist.FadeOut(overlay);
					}
					else
					{
						TranceAnimation tranceAnimation = overlay.AddComponent<TranceAnimation>();
						tranceAnimation.Initialize(overlay.AddComponent<CanvasGroup>());
						tranceAnimation.Close();
					}
					fadingOverlay = overlay;
				}
				else
				{
					overlay.SetActive(false);
					Object.Destroy((Object)(object)overlay);
				}
			}
			overlay = null;
			mist = null;
			panel = null;
			circle = null;
			info = null;
			modifierPage = (assigningAbility = null);
			slotPage = null;
			owner = null;
			abilityPage = null;
			if (blocked)
			{
				blocked = false;
				inputBlocked = false;
				lastCloseFrame = Time.frameCount;
				GUIManager.BlockInput(false);
			}
			if (flag)
			{
				this.TranceEnded?.Invoke();
			}
		}

		private void DestroyFadingOverlay()
		{
			if (Object.op_Implicit((Object)(object)fadingOverlay))
			{
				fadingOverlay.SetActive(false);
				Object.Destroy((Object)(object)fadingOverlay);
			}
			fadingOverlay = null;
		}

		private void OnDisable()
		{
			Close(immediate: true);
		}

		private void OnDestroy()
		{
			if (persistence != null)
			{
				persistence.Changed -= OnProgressionChanged;
			}
			if (progression != null)
			{
				progression.DebugCompleted -= OnDebugCompleted;
			}
			GUIManager.OnCustomGUIAvailable -= OnSceneGUIAvailable;
			LocalizationManager.OnLocalizationAdded -= OnLocalizationAdded;
			Close(immediate: true);
			assets?.Dispose();
		}
	}
	internal sealed class TranceAssetRegistry : IDisposable
	{
		private readonly Dictionary<string, Sprite> sprites = new Dictionary<string, Sprite>(StringComparer.Ordinal);

		private readonly ManualLogSource log;

		private readonly bool bakeRuneColors;

		private readonly SorceryEffectRegistry effects;

		private readonly string folder = Path.Combine(Path.GetDirectoryName(typeof(TranceAssetRegistry).Assembly.Location), "assets", "ui", "trance");

		private readonly HashSet<string> missingModifiers = new HashSet<string>(StringComparer.Ordinal);

		internal Sprite BaseRune => Load("runes/berkano.png", "ReddeqsUtilitySorcery.Assets.sorcerers_mark_t1.png");

		internal TranceAssetRegistry(ManualLogSource log, SorceryEffectRegistry effects, bool bakeRuneColors = false)
		{
			this.log = log;
			this.effects = effects;
			this.bakeRuneColors = bakeRuneColors;
		}

		internal Color Color(AbilityDefinition definition)
		{
			//IL_0042: Unknown result type (might be due to invalid IL or missing references)
			//IL_003c: 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)
			return (Color)(((??)effects.Resolve(definition.Id)?.Primary) ?? ((??)definition.ActivationColor) ?? new Color(0.7f, 0.7f, 0.8f));
		}

		internal Sprite Rune(string id)
		{
			//IL_005c: Unknown result type (might be due to invalid IL or missing references)
			return Load("runes/" + Safe(id) + ".png", effects.Resolve(id)?.RuneResource, (!bakeRuneColors) ? ((Color?)null) : effects.Resolve(id)?.Primary) ?? BaseRune;
		}

		internal Sprite Modifier(string ability, string id)
		{
			Sprite val = Get("modifiers/" + Safe(ability) + "/" + SorceryAssets.ModifierTextureFile(Safe(id)));
			if (!Object.op_Implicit((Object)(object)val))
			{
				switch (id)
				{
				case "impulse":
				case "recall":
				case "quickThrow":
				case "suspension":
					if (missingModifiers.Add(id))
					{
						log.LogError((object)(id + " icon unavailable in both external assets and embedded resources."));
					}
					break;
				}
			}
			if (!Object.op_Implicit((Object)(object)val))
			{
				return Get("modifiers/unknown.png");
			}
			return val;
		}

		internal Sprite Get(string file)
		{
			return Load(file, "ReddeqsUtilitySorcery.Trance." + file.Replace('/', '.'));
		}

		private static string Safe(string id)
		{
			if (string.IsNullOrEmpty(id))
			{
				return "unknown";
			}
			foreach (char c in id)
			{
				if (!char.IsLetterOrDigit(c) && c != '_' && c != '-' && c != '.')
				{
					return "unknown";
				}
			}
			return id;
		}

		private Sprite Load(string file, string resource, Color? tint = null)
		{
			//IL_002e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0033: Unknown result type (might be due to invalid IL or missing references)
			//IL_003a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0042: Expected O, but got Unknown
			//IL_00d3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e2: Unknown result type (might be due to invalid IL or missing references)
			//IL_0086: 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_0092: Unknown result type (might be due to invalid IL or missing references)
			//IL_0097: Unknown result type (might be due to invalid IL or missing references)
			if (sprites.TryGetValue(file, out var value))
			{
				return value;
			}
			Texture2D val = null;
			Sprite val2 = null;
			try
			{
				byte[] array = ReadAssetBytes(folder, file, resource);
				if (array != null)
				{
					val = new Texture2D(2, 2, (TextureFormat)4, false)
					{
						name = file,
						wrapMode = (TextureWrapMode)1
					};
					if (!ImageConversion.LoadImage(val, array, !tint.HasValue))
					{
						throw new InvalidDataException("Invalid PNG: " + file);
					}
					if (tint.HasValue)
					{
						Color[] pixels = val.GetPixels();
						for (int i = 0; i < pixels.Length; i++)
						{
							ref Color reference = ref pixels[i];
							reference *= tint.Value;
						}
						val.SetPixels(pixels);
						val.Apply(false, true);
					}
					val2 = Sprite.Create(val, new Rect(0f, 0f, (float)((Texture)val).width, (float)((Texture)val).height), new Vector2(0.5f, 0.5f), 100f);
				}
			}
			catch (Exception ex)
			{
				if (Object.op_Implicit((Object)(object)val))
				{
					Object.Destroy((Object)(object)val);
				}
				log.LogWarning((object)("Trance asset unavailable: " + file + ": " + ex.Message));
			}
			sprites.Add(file, val2);
			return val2;
		}

		internal static byte[] ReadAssetBytes(string folder, string file, string resource)
		{
			string path = Path.Combine(folder, file.Replace('/', Path.DirectorySeparatorChar));
			if (File.Exists(path))
			{
				return File.ReadAllBytes(path);
			}
			if (resource != null)
			{
				using Stream stream = Assembly.GetExecutingAssembly().GetManifestResourceStream(resource);
				if (stream != null)
				{
					using (MemoryStream memoryStream = new MemoryStream())
					{
						stream.CopyTo(memoryStream);
						return memoryStream.ToArray();
					}
				}
			}
			return null;
		}

		public void Dispose()
		{
			foreach (Sprite value in sprites.Values)
			{
				if (Object.op_Implicit((Object)(object)value))
				{
					Object.Destroy((Object)(object)value.texture);
					Object.Destroy((Object)(object)value);
				}
			}
			sprites.Clear();
		}
	}
	internal sealed class TranceBackgroundClick : MonoBehaviour, IPointerClickHandler, IEventSystemHandler
	{
		private Action reset;

		internal void Initialize(Action reset)
		{
			this.reset = reset;
		}

		public void OnPointerClick(PointerEventData data)
		{
			//IL_0001: 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)
			//IL_001f: Unknown result type (might be due to invalid IL or missing references)
			if ((int)data.button != 0 || data.dragging || !data.eligibleForClick)
			{
				return;
			}
			RaycastResult pointerCurrentRaycast = data.pointerCurrentRaycast;
			GameObject gameObject = ((RaycastResult)(ref pointerCurrentRaycast)).gameObject;
			if (Object.op_Implicit((Object)(object)gameObject) && !Object.op_Implicit((Object)(object)gameObject.GetComponentInParent<Selectable>()))
			{
				Text component = gameObject.GetComponent<Text>();
				if (!Object.op_Implicit((Object)(object)component) || string.IsNullOrWhiteSpace(component.text))
				{
					reset?.Invoke();
				}
			}
		}
	}
	internal sealed class TranceInfoPanelView
	{
		private readonly RectTransform details;

		private readonly RectTransform actions;

		private readonly ScrollRect scroll;

		private readonly Text notice;

		private readonly TranceAssetRegistry assets;

		private readonly Action<Action> invoke;

		private float y;

		private int actionCount;

		private string key;

		internal TranceInfoPanelView(Transform parent, TranceAssetRegistry assets, Action<Action> invoke, Action close)
		{
			//IL_003e: Unknown result type (might be due to invalid IL or missing references)
			//IL_004d: 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_0064: 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_0085: 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)
			//IL_009b: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00db: 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_0107: Unknown result type (might be due to invalid IL or missing references)
			//IL_0139: Unknown result type (might be due to invalid IL or missing references)
			//IL_0140: Unknown result type (might be due to invalid IL or missing references)
			//IL_0142: Unknown result type (might be due to invalid IL or missing references)
			//IL_0143: 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_01b7: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c6: Unknown result type (might be due to invalid IL or missing references)
			//IL_01e0: Unknown result type (might be due to invalid IL or missing references)
			//IL_01fd: Unknown result type (might be due to invalid IL or missing references)
			//IL_0202: Unknown result type (might be due to invalid IL or missing references)
			//IL_0221: Unknown result type (might be due to invalid IL or missing references)
			//IL_0237: Unknown result type (might be due to invalid IL or missing references)
			//IL_0248: Unknown result type (might be due to invalid IL or missing references)
			//IL_024d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0253: Unknown result type (might be due to invalid IL or missing references)
			//IL_02a3: Unknown result type (might be due to invalid IL or missing references)
			//IL_02b1: Unknown result type (might be due to invalid IL or missing references)
			//IL_02ba: Unknown result type (might be due to invalid IL or missing references)
			//IL_02bf: Unknown result type (might be due to invalid IL or missing references)
			//IL_02d2: Unknown result type (might be due to invalid IL or missing references)
			//IL_02ed: Unknown result type (might be due to invalid IL or missing references)
			//IL_0308: Unknown result type (might be due to invalid IL or missing references)
			//IL_0314: Unknown result type (might be due to invalid IL or missing references)
			//IL_034c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0382: Unknown result type (might be due to invalid IL or missing references)
			//IL_0389: Unknown result type (might be due to invalid IL or missing references)
			//IL_03a5: Unknown result type (might be due to invalid IL or missing references)
			//IL_03c4: Unknown result type (might be due to invalid IL or missing references)
			//IL_03df: Unknown result type (might be due to invalid IL or missing references)
			//IL_03ee: Unknown result type (might be due to invalid IL or missing references)
			//IL_0430: Unknown result type (might be due to invalid IL or missing references)
			//IL_0449: Unknown result type (might be due to invalid IL or missing references)
			this.assets = assets;
			this.invoke = invoke;
			RectTransform val = TranceWidgets.Rect("InformationPanel", parent, new Vector2(490f, 0f), new Vector2(470f, 860f));
			TranceWidgets.Image("StonePanel", (Transform)(object)val, Vector2.zero, val.sizeDelta, assets.Get("backgrounds/panel.png"), Color.white);
			TranceWidgets.Image("CarvedFrame", (Transform)(object)val, Vector2.zero, val.sizeDelta, assets.Get("frames/panel.png"), Color.white);
			RectTransform val2 = TranceWidgets.Rect("DetailsViewport", (Transform)(object)val, new Vector2(-8f, 110f), new Vector2(408f, 590f));
			((Graphic)((Component)val2).gameObject.AddComponent<Image>()).color = Color.clear;
			((Component)val2).gameObject.AddComponent<RectMask2D>();
			details = TranceWidgets.Rect("Details", (Transform)(object)val2, Vector2.zero, new Vector2(400f, 590f));
			RectTransform obj = details;
			RectTransform obj2 = details;
			RectTransform obj3 = details;
			Vector2 val3 = default(Vector2);
			((Vector2)(ref val3))..ctor(0.5f, 1f);
			obj3.pivot = val3;
			Vector2 val4 = (obj.anchorMin = (obj2.anchorMax = val3));
			scroll = ((Component)val2).gameObject.AddComponent<ScrollRect>();
			scroll.viewport = val2;
			scroll.content = details;
			scroll.horizontal = false;
			scroll.movementType = (MovementType)2;
			scroll.scrollSensitivity = 32f;
			Image val7 = TranceWidgets.Image("DetailsScrollbar", (Transform)(object)val, new Vector2(210f, 110f), new Vector2(10f, 590f), null, new Color(0.16f, 0.14f, 0.1f, 0.95f));
			((Graphic)val7).raycastTarget = true;
			RectTransform val8 = TranceWidgets.Rect("SlidingArea", ((Component)val7).transform, Vector2.zero, Vector2.zero);
			TranceWidgets.Stretch(val8);
			val8.offsetMin = new Vector2(2f, 2f);
			val8.offsetMax = new Vector2(-2f, -2f);
			Image val9 = TranceWidgets.Image("Handle", (Transform)(object)val8, Vector2.zero, Vector2.zero, null, Color.white);
			TranceWidgets.Stretch(((Graphic)val9).rectTransform);
			((Graphic)val9).raycastTarget = true;
			Scrollbar val10 = ((Component)val7).gameObject.AddComponent<Scrollbar>();
			val10.handleRect = ((Graphic)val9).rectTransform;
			((Selectable)val10).targetGraphic = (Graphic)(object)val9;
			val10.direction = (Direction)2;
			Navigation navigation = default(Navigation);
			((Navigation)(ref navigation)).mode = (Mode)0;
			((Selectable)val10).navigation = navigation;
			ColorBlock colors = ((Selectable)val10).colors;
			((ColorBlock)(ref colors)).normalColor = new Color(0.6f, 0.5f, 0.33f);
			((ColorBlock)(ref colors)).highlightedColor = new Color(0.82f, 0.71f, 0.49f);
			((ColorBlock)(ref colors)).pressedColor = new Color(0.95f, 0.85f, 0.64f);
			((Selectable)val10).colors = colors;
			scroll.verticalScrollbar = val10;
			scroll.verticalScrollbarVisibility = (ScrollbarVisibility)0;
			notice = TranceWidgets.Text((Transform)(object)val, "", 17, new Color(0.86f, 0.69f, 0.44f));
			RectTransform rectTransform = ((Graphic)notice).rectTransform;
			RectTransform rectTransform2 = ((Graphic)notice).rectTransform;
			((Vector2)(ref val4))..ctor(0.5f, 0.5f);
			rectTransform2.anchorMax = val4;
			rectTransform.anchorMin = val4;
			((Graphic)notice).rectTransform.anchoredPosition = new Vector2(0f, -211f);
			((Graphic)notice).rectTransform.sizeDelta = new Vector2(400f, 58f);
			actions = TranceWidgets.Rect("Actions", (Transform)(object)val, new Vector2(0f, -326f), new Vector2(400f, 154f));
			Button obj4 = TranceWidgets.Button((Transform)(object)val, "$reddequs_ui_common_close", delegate
			{
				invoke(close);
			}, enabled: true, assets.Get("buttons/action.png"));
			((Component)obj4).GetComponent<RectTransform>().anchoredPosition = new Vector2(0f, -388f);
			((Component)obj4).GetComponent<RectTransform>().sizeDelta = new Vector2(400f, 30f);
		}

		internal void Begin(string selectionKey, string message)
		{
			//IL_001f: Unknown result type (might be due to invalid IL or missing references)
			if (key != selectionKey)
			{
				scroll.StopMovement();
				details.anchoredPosition = Vector2.zero;
			}
			key = selectionKey;
			TranceWidgets.Clear((Transform)(object)details);
			TranceWidgets.Clear((Transform)(object)actions);
			y = 0f;
			actionCount = 0;
			notice.text = SorceryUI.Localize(message);
		}

		internal void Illustration(Sprite sprite, Color color)
		{
			//IL_0015: 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)
			//IL_0024: Unknown result type (might be due to invalid IL or missing references)
			//IL_0039: Unknown result type (might be due to invalid IL or missing references)
			//IL_0061: Unknown result type (might be due to invalid IL or missing references)
			//IL_0067: 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_0091: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a6: 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_00b2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bd: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00eb: Unknown result type (might be due to invalid IL or missing references)
			//IL_0106: Unknown result type (might be due to invalid IL or missing references)
			//IL_010b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0115: Unknown result type (might be due to invalid IL or missing references)
			//IL_011b: Unknown result type (might be due to invalid IL or missing references)
			//IL_013f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0145: Unknown result type (might be due to invalid IL or missing references)
			Image val = TranceWidgets.Image("IllustrationSeal", (Transform)(object)details, new Vector2(0f, -84f), Vector2.one * 156f, assets.Get("rings/carved.png"), TranceWidgets.Bronze);
			RectTransform rectTransform = ((Graphic)val).rectTransform;
			RectTransform rectTransform2 = ((Graphic)val).rectTransform;
			Vector2 val2 = default(Vector2);
			((Vector2)(ref val2))..ctor(0.5f, 1f);
			rectTransform2.anchorMax = val2;
			rectTransform.anchorMin = val2;
			Image val3 = TranceWidgets.Image("IllustrationGlow", (Transform)(object)details, new Vector2(0f, -84f), new Vector2(245f, 170f), assets.Get("effects/glow.png"), new Color(color.r, color.g, color.b, 0.4f));
			RectTransform rectTransform3 = ((Graphic)val3).rectTransform;
			RectTransform rectTransform4 = ((Graphic)val3).rectTransform;
			((Vector2)(ref val2))..ctor(0.5f, 1f);
			rectTransform4.anchorMax = val2;
			rectTransform3.anchorMin = val2;
			Image val4 = TranceWidgets.Image("IllustrationRune", (Transform)(object)details, new Vector2(0f, -84f), Vector2.one * 100f, sprite, color);
			RectTransform rectTransform5 = ((Graphic)val4).rectTransform;
			RectTransform rectTransform6 = ((Graphic)val4).rectTransform;
			((Vector2)(ref val2))..ctor(0.5f, 1f);
			rectTransform6.anchorMax = val2;
			rectTransform5.anchorMin = val2;
			y = 178f;
		}

		internal void Label(string token, int size = 21, Color? color = null)
		{
			//IL_001c: 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_0037: Unknown result type (might be due to invalid IL or missing references)
			//IL_0053: 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)
			Text val = TranceWidgets.Text((Transform)(object)details, token, size, (Color)(((??)color) ?? TranceWidgets.Ink));
			((Graphic)val).rectTransform.pivot = new Vector2(0.5f, 1f);
			((Graphic)val).rectTransform.anchoredPosition = new Vector2(0f, 0f - y);
			float num = Math.Max(size + 9, val.preferredHeight + 9f);
			((Graphic)val).rectTransform.sizeDelta = new Vector2(400f, num);
			y += num + 10f;
		}

		internal void Statistics(AbilityStats stats)
		{
			//IL_0043: Unknown result type (might be due to invalid IL or missing references)
			if (stats == null || stats.Rows.Count == 0)
			{
				return;
			}
			Separator();
			Label(SorceryLocalization.Format("$reddequs_ui_stats_heading", AbilityStatsFormatting.Number(stats.SkillLevel.Value, CultureInfo.CurrentCulture)), 18, TranceWidgets.Bronze);
			foreach (AbilityStat row in stats.Rows)
			{
				Label(SorceryLocalization.Format("$reddequs_ui_stats_row", SorceryLocalization.Translate(row.Label), AbilityStatsFormatting.Value(row)), 19);
			}
		}

		internal void Separator()
		{
			//IL_0017: Unknown result type (might be due to invalid IL or missing references)
			//IL_0026: 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_0054: 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)
			Image val = TranceWidgets.Image("Divider", (Transform)(object)details, new Vector2(0f, 0f - y), new Vector2(400f, 1f), null, TranceWidgets.Bronze);
			RectTransform rectTransform = ((Graphic)val).rectTransform;
			RectTransform rectTransform2 = ((Graphic)val).rectTransform;
			Vector2 val2 = default(Vector2);
			((Vector2)(ref val2))..ctor(0.5f, 1f);
			rectTransform2.anchorMax = val2;
			rectTransform.anchorMin = val2;
			y += 20f;
		}

		internal void Action(string token, Action action, bool enabled = true)
		{
			//IL_005f: Unknown result type (might be due to invalid IL or missing references)
			((Component)TranceWidgets.Button((Transform)(object)actions, token, delegate
			{
				invoke(action);
			}, enabled, assets.Get("buttons/action.png"))).GetComponent<RectTransform>().anchoredPosition = new Vector2(0f, (float)(54 - actionCount++ * 51));
		}

		internal void DetailAction(string token, Action action, bool enabled = true)
		{
			//IL_0056: Unknown result type (might be due to invalid IL or missing references)
			//IL_005c: 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_005e: 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_0076: Unknown result type (might be due to invalid IL or missing references)
			RectTransform component = ((Component)TranceWidgets.Button((Transform)(object)details, token, delegate
			{
				invoke(action);
			}, enabled, assets.Get("buttons/action.png"))).GetComponent<RectTransform>();
			Vector2 val = default(Vector2);
			((Vector2)(ref val))..ctor(0.5f, 1f);
			component.pivot = val;
			Vector2 anchorMin = (component.anchorMax = val);
			component.anchorMin = anchorMin;
			component.anchoredPosition = new Vector2(0f, 0f - y);
			y += 56f;
		}

		internal void VisibilityToggle(string token, bool value, Action<bool> changed, bool enabled)
		{
			//IL_001f: 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_004d: 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_0057: 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_0072: Unknown result type (might be due to invalid IL or missing references)
			//IL_009e: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ad: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00df: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ee: 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_0103: Unknown result type (might be due to invalid IL or missing references)
			//IL_012e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0135: Unknown result type (might be due to invalid IL or missing references)
			//IL_014d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0168: 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_01a4: Unknown result type (might be due to invalid IL or missing references)
			RectTransform val = TranceWidgets.Rect("MarkVisibility", (Transform)(object)details, Vector2.zero, new Vector2(400f, 44f));
			Vector2 val2 = default(Vector2);
			((Vector2)(ref val2))..ctor(0.5f, 1f);
			val.pivot = val2;
			Vector2 val3 = (val.anchorMin = (val.anchorMax = val2));
			val.anchoredPosition = new Vector2(0f, 0f - y);
			y += 56f;
			Image val6 = TranceWidgets.Image("Checkbox", (Transform)(object)val, new Vector2(-180f, 0f), new Vector2(28f, 28f), null, new Color(0.24f, 0.2f, 0.14f));
			((Graphic)val6).raycastTarget = true;
			Image graphic = TranceWidgets.Image("Checked", ((Component)val6).transform, Vector2.zero, new Vector2(18f, 18f), null, TranceWidgets.Bronze);
			Text val7 = TranceWidgets.Text((Transform)(object)val, token, 19, TranceWidgets.Ink);
			RectTransform rectTransform = ((Graphic)val7).rectTransform;
			RectTransform rectTransform2 = ((Graphic)val7).rectTransform;
			((Vector2)(ref val3))..ctor(0.5f, 0.5f);
			rectTransform2.anchorMax = val3;
			rectTransform.anchorMin = val3;
			((Graphic)val7).rectTransform.anchoredPosition = new Vector2(20f, 0f);
			((Graphic)val7).rectTransform.sizeDelta = new Vector2(350f, 44f);
			val7.alignment = (TextAnchor)3;
			Toggle obj = ((Component)val).gameObject.AddComponent<Toggle>();
			((Selectable)obj).targetGraphic = (Graphic)(object)val6;
			obj.graphic = (Graphic)(object)graphic;
			Navigation navigation = default(Navigation);
			((Navigation)(ref navigation)).mode = (Mode)0;
			((Selectable)obj).navigation = navigation;
			((Selectable)obj).interactable = enabled;
			obj.isOn = value;
			((UnityEvent<bool>)(object)obj.onValueChanged).AddListener((UnityAction<bool>)delegate(bool visible)
			{
				invoke(delegate
				{
					changed(visible);
				});
			});
		}

		internal void End()
		{
			//IL_001b: Unknown result type (might be due to invalid IL or missing references)
			details.sizeDelta = new Vector2(400f, Math.Max(590f, y));
		}
	}
	internal static class TranceLayout
	{
		internal const float Width = 1500f;

		internal const float Height = 900f;

		internal const float SealSize = 256f;

		internal const float SlotSize = 72f;

		internal const float SlotOrbit = 52f;

		internal const float SelectionPadding = 13f;

		internal const float HoverGrowth = 0.035f;

		internal const float SealOuterRadius = 121.25f;

		internal const float SealInnerRadius = 97f;

		internal static double Scale(double width, double height)
		{
			return Math.Min(width / 1500.0, height / 900.0);
		}

		internal static double Radius(int abilities, int modifiers = 0)
		{
			int num = ModifierExtent(modifiers);
			return Math.Max(Math.Max(245, abilities * 75), (abilities > 1) ? ((double)(num + 48) / Math.Sin(Math.PI / (double)abilities)) : 245.0);
		}

		internal static int ModifierExtent(int count)
		{
			return ((count >= 5) ? 140 : 112) + Math.Max(0, (count - 1) / 5) * 88;
		}

		internal static double Angle(int index, int count)
		{
			return Math.PI / 2.0 + (double)index * Math.PI * 2.0 / (double)Math.Max(1, count);
		}

		internal static void Point(double angle, double radius, out float x, out float y)
		{
			x = (float)(Math.Cos(angle) * radius);
			y = (float)(Math.Sin(angle) * radius);
		}

		internal static void Modifier(int index, int count, double branchAngle, out float x, out float y)
		{
			int num = index / 5;
			int num2 = Math.Min(5, count - num * 5);
			Point(branchAngle + ((num2 == 1) ? 0.0 : (((double)(index % 5) / (double)(num2 - 1) - 0.5) * 2.3)), ((count >= 5) ? 140 : 112) + num * 88, out x, out y);
		}

		internal static void Slot(int index, int count, out float x, out float y)
		{
			Point(Angle(index, count), (count <= 1) ? 0f : 52f, out x, out y);
		}
	}
	internal sealed class TranceMotes : MonoBehaviour
	{
		private readonly Image[] images = (Image[])(object)new Image[18];

		private float radius;

		internal void Initialize(Sprite sprite, float radius)
		{
			//IL_001d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0022: Unknown result type (might be due to invalid IL or missing references)
			//IL_002d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0033: Unknown result type (might be due to invalid IL or missing references)
			this.radius = radius;
			for (int i = 0; i < images.Length; i++)
			{
				images[i] = TranceWidgets.Image("Mote", ((Component)this).transform, Vector2.zero, Vector2.one * (float)(i % 3 + 4), sprite, Color.clear);
			}
		}

		private void Update()
		{
			//IL_004d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0053: 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)
			for (int i = 0; i < images.Length; i++)
			{
				float num = Time.unscaledTime * 0.09f + (float)i * 2.39996f;
				float num2 = radius * (0.3f + (float)(i % 7) * 0.1f);
				((Graphic)images[i]).rectTransform.anchoredPosition = new Vector2(Mathf.Cos(num), Mathf.Sin(num)) * num2;
				((Graphic)images[i]).color = new Color(0.65f, 0.52f, 0.85f, 0.2f + Mathf.Sin(num * 3f + (float)i) * 0.13f);
			}
		}
	}
	internal sealed class TranceNodeClicks
	{
		private const float Interval = 0.35f;

		private string ability;

		private string modifier;

		private float clickedAt;

		internal bool Register(string abilityId, string modifierId, int? slotId, float now)
		{
			if (abilityId == null || slotId.HasValue)
			{
				Reset();
				return false;
			}
			if (ability == abilityId && modifier == modifierId && now >= clickedAt && now - clickedAt <= 0.35f)
			{
				Reset();
				return true;
			}
			ability = abilityId;
			modifier = modifierId;
			clickedAt = now;
			return false;
		}

		internal void Reset()
		{
			ability = (modifier = null);
		}
	}
	internal sealed class TranceNodeView : MonoBehaviour, IPointerEnterHandler, IEventSystemHandler, IPointerExitHandler, ICanvasRaycastFilter
	{
		private Image glow;

		private Image rim;

		private Image selection;

		private Color color;

		private bool active;

		private bool selected;

		private bool hovered;

		private float transition;

		private float flash;

		private Action<bool> preview;

		internal void Initialize(Image glow, Image rim, Image selection, Color color, bool active, bool selected, Action<bool> preview)
		{
			//IL_0016: Unknown result type (might be due to invalid IL or missing references)
			//IL_0018: Unknown result type (might be due to invalid IL or missing references)
			this.glow = glow;
			this.rim = rim;
			this.selection = selection;
			this.color = color;
			this.active = active;
			this.selected = selected;
			this.preview = preview;
		}

		internal void Flash()
		{
			flash = 1f;
		}

		public void OnPointerEnter(PointerEventData data)
		{
			hovered = true;
			preview?.Invoke(obj: true);
		}

		public void OnPointerExit(PointerEventData data)
		{
			hovered = false;
			preview?.Invoke(obj: false);
		}

		public bool IsRaycastLocationValid(Vector2 screen, Camera camera)
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_000c: Expected O, but got Unknown
			//IL_000d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0020: 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_002e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0033: Unknown result type (might be due to invalid IL or missing references)
			RectTransform val = (RectTransform)((Component)this).transform;
			Vector2 val2 = default(Vector2);
			if (RectTransformUtility.ScreenPointToLocalPointInRectangle(val, screen, camera, ref val2))
			{
				float sqrMagnitude = ((Vector2)(ref val2)).sqrMagnitude;
				Rect rect = val.rect;
				float width = ((Rect)(ref rect)).width;
				rect = val.rect;
				return sqrMagnitude <= width * ((Rect)(ref rect)).width * 0.25f;
			}
			return false;
		}

		private void Update()
		{
			//IL_00ca: Unknown result type (might be due to invalid IL or missing references)
			//IL_00db: 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_00fe: Unknown result type (might be due to invalid IL or missing references)
			//IL_011f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0136: Unknown result type (might be due to invalid IL or missing references)
			transition = Mathf.MoveTowards(transition, (float)(hovered ? 1 : 0), Time.unscaledDeltaTime * 6f);
			flash = Mathf.MoveTowards(flash, 0f, Time.unscaledDeltaTime * 1.6f);
			float num = (active ? ((1f + Mathf.Sin(Time.unscaledTime * 1.8f)) * 0.06f) : 0f);
			((Graphic)glow).color = new Color(color.r, color.g, color.b, (active ? 0.55f : 0.13f) + num + transition * 0.18f + flash * 0.2f);
			((Graphic)rim).color = Color.Lerp(color, Color.white, transition * 0.3f + flash * 0.35f);
			((Behaviour)selection).enabled = selected;
			((Component)this).transform.localScale = Vector3.one * (1f + transition * 0.035f);
		}
	}
	internal sealed class TranceAnimation : MonoBehaviour
	{
		private CanvasGroup group;

		private float elapsed;

		private bool closing;

		internal void Initialize(CanvasGroup group)
		{
			this.group = group;
			group.alpha = 0f;
		}

		internal void Close()
		{
			closing = true;
			elapsed = 0f;
			CanvasGroup obj = group;
			bool interactable = (group.blocksRaycasts = false);
			obj.interactable = interactable;
		}

		private void Update()
		{
			elapsed += Time.unscaledDeltaTime;
			if (closing)
			{
				group.alpha = 1f - Mathf.SmoothStep(0f, 1f, elapsed / 0.25f);
				if (elapsed >= 0.25f)
				{
					Object.Destroy((Object)(object)((Component)this).gameObject);
				}
			}
			else
			{
				group.alpha = Mathf.SmoothStep(0f, 1f, elapsed / 0.35f);
			}
		}
	}
	internal sealed class TranceRuneCircleView
	{
		private readonly RectTransform content;

		private readonly TranceAssetRegistry assets;

		private readonly ScrollRect scroll;

		internal TranceRuneCircleView(Transform root, TranceAssetRegistry assets)
		{
			//IL_001d: 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_0042: 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_007f: Unknown result type (might be due to invalid IL or missing references)
			this.assets = assets;
			RectTransform val = TranceWidgets.Rect("RuneCircleViewport", root, new Vector2(-260f, 0f), new Vector2(950f, 860f));
			((Graphic)((Component)val).gameObject.AddComponent<Image>()).color = Color.clear;
			((Component)val).gameObject.AddComponent<RectMask2D>();
			scroll = ((Component)val).gameObject.AddComponent<ScrollRect>();
			content = TranceWidgets.Rect("RuneCircle", (Transform)(object)val, Vector2.zero, new Vector2(920f, 840f));
			scroll.viewport = val;
			scroll.content = content;
			scroll.movementType = (MovementType)2;
			scroll.scrollSensitivity = 35f;
			scroll.inertia = false;
		}

		internal void Render(AbilityRegistry registry, PlayerSorceryData data, string selectedAbility, string selectedModifier, int? selectedSlot, bool assigning, Action<string, string, int?> select, Action<string, string, int?, bool> preview, Action<Action> invoke, string flashKey)
		{
			//IL_001c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0021: Unknown result type (might be due to invalid IL or missing references)
			//IL_013a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0150: 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_018e: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c5: 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_01d1: Unknown result type (might be due to invalid IL or missing references)
			//IL_020d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0212: Unknown result type (might be due to invalid IL or missing references)
			//IL_021c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0231: Unknown result type (might be due to invalid IL or missing references)
			//IL_0758: Unknown result type (might be due to invalid IL or missing references)
			//IL_077c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0304: Unknown result type (might be due to invalid IL or missing references)
			//IL_02f5: Unknown result type (might be due to invalid IL or missing references)
			//IL_07d7: Unknown result type (might be due to invalid IL or missing references)
			//IL_07c3: Unknown result type (might be due to invalid IL or missing references)
			//IL_0309: Unknown result type (might be due to invalid IL or missing references)
			//IL_030d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0312: Unknown result type (might be due to invalid IL or missing references)
			//IL_0314: Unknown result type (might be due to invalid IL or missing references)
			//IL_031b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0320: Unknown result type (might be due to invalid IL or missing references)
			//IL_0322: Unknown result type (might be due to invalid IL or missing references)
			//IL_0324: Unknown result type (might be due to invalid IL or missing references)
			//IL_032b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0330: Unknown result type (might be due to invalid IL or missing references)
			//IL_0335: Unknown result type (might be due to invalid IL or missing references)
			//IL_033d: Unknown result type (might be due to invalid IL or missing references)
			//IL_033f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0355: Unknown result type (might be due to invalid IL or missing references)
			//IL_0365: Unknown result type (might be due to invalid IL or missing references)
			//IL_0367: Unknown result type (might be due to invalid IL or missing references)
			//IL_07dc: Unknown result type (might be due to invalid IL or missing references)
			//IL_0379: Unknown result type (might be due to invalid IL or missing references)
			//IL_080d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0819: Unknown result type (might be due to invalid IL or missing references)
			//IL_0396: Unknown result type (might be due to invalid IL or missing references)
			//IL_03ab: Unknown result type (might be due to invalid IL or missing references)
			//IL_03ad: Unknown result type (might be due to invalid IL or missing references)
			//IL_03b7: Unknown result type (might be due to invalid IL or missing references)
			//IL_03cc: Unknown result type (might be due to invalid IL or missing references)
			//IL_03de: Unknown result type (might be due to invalid IL or missing references)
			//IL_03f4: Unknown result type (might be due to invalid IL or missing references)
			//IL_03f6: Unknown result type (might be due to invalid IL or missing references)
			//IL_0400: Unknown result type (might be due to invalid IL or missing references)
			//IL_0415: Unknown result type (might be due to invalid IL or missing references)
			//IL_042b: Unknown result type (might be due to invalid IL or missing references)
			//IL_042d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0437: Unknown result type (might be due to invalid IL or missing references)
			//IL_044c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0485: Unknown result type (might be due to invalid IL or missing references)
			//IL_048b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0490: Unknown result type (might be due to invalid IL or missing references)
			//IL_0495: Unknown result type (might be due to invalid IL or missing references)
			//IL_04fd: Unknown result type (might be due to invalid IL or missing references)
			//IL_0516: Unknown result type (might be due to invalid IL or missing references)
			//IL_04ba: Unknown result type (might be due to invalid IL or missing references)
			//IL_04bc: Unknown result type (might be due to invalid IL or missing references)
			//IL_04c7: Unknown result type (might be due to invalid IL or missing references)
			//IL_05d4: Unknown result type (might be due to invalid IL or missing references)
			//IL_05da: Unknown result type (might be due to invalid IL or missing references)
			//IL_05df: Unknown result type (might be due to invalid IL or missing references)
			//IL_062e: Unknown result type (might be due to invalid IL or missing references)
			//IL_061f: Unknown result type (might be due to invalid IL or missing references)
			//IL_04d9: Unknown result type (might be due to invalid IL or missing references)
			Vector2 anchoredPosition = content.anchoredPosition;
			TranceWidgets.Clear((Transform)(object)content);
			int num = 0;
			foreach (string orderedId in registry.OrderedIds)
			{
				if (registry.TryGet(orderedId, out var ability))
				{
					num = Math.Max(num, ability.Definition.Parameters.Count);
				}
			}
			double num2 = TranceLayout.Radius(registry.OrderedIds.Count, num);
			int num3 = 112;
			foreach (string orderedId2 in registry.OrderedIds)
			{
				if (registry.TryGet(orderedId2, out var ability2))
				{
					num3 = Math.Max(num3, TranceLayout.ModifierExtent(ability2.Definition.Parameters.Count));
				}
			}
			float val = (float)Math.Max(820.0, 2.0 * (num2 + (double)num3 + 52.0));
			content.sizeDelta = new Vector2(Math.Max(920f, val), Math.Max(840f, val));
			scroll.horizontal = content.sizeDelta.x > 950f;
			scroll.vertical = content.sizeDelta.y > 860f;
			content.anchoredPosition = anchoredPosition;
			float num4 = (float)Math.Max(790.0, num2 * 2.0 + 160.0);
			((Component)TranceWidgets.Rect("Motes", (Transform)(object)content, Vector2.zero, Vector2.one * num4)).gameObject.AddComponent<TranceMotes>().Initialize(assets.Get("effects/glow.png"), num4 * 0.46f);
			TranceWidgets.Image("InnerSeal", (Transform)(object)content, Vector2.zero, Vector2.one * 256f, assets.Get("rings/carved.png"), TranceWidgets.Bronze);
			Vector2 val2 = default(Vector2);
			for (int i = 0; i < registry.OrderedIds.Count; i++)
			{
				string id = registry.OrderedIds[i];
				if (!registry.TryGet(id, out var ability3))
				{
					continue;
				}
				AbilityDefinition definition = ability3.Definition;
				double num5 = TranceLayout.Angle(i, registry.OrderedIds.Count);
				TranceLayout.Point(num5, num2, out var x, out var y);
				((Vector2)(ref val2))..ctor(x, y);
				bool flag = SorceryProgression.FindAbility(data, id) != null;
				bool flag2 = flag && data.slots.Exists((AbilitySlotState abilitySlotState) => abilitySlotState.abilityId == id);
				Color color = (Color)(flag ? assets.Color(definition) : new Color(0.29f, 0.29f, 0.31f));
				Vector2 normalized = ((Vector2)(ref val2)).normalized;
				Vector2 val3 = normalized * 121.25f;
				Vector2 to = val2 - normalized * 56f;
				TranceWidgets.Line((Transform)(object)content, val3, to, 6f, new Color(0.09f, 0.08f, 0.075f));
				TranceWidgets.Line((Transform)(object)content, val3, to, flag2 ? 2.5f : 1f, Tint(color, flag2 ? 0.9f : (flag ? 0.3f : 0.12f)));
				TranceWidgets.Image("JunctionGlow", (Transform)(object)content, val3, Vector2.one * 18f, assets.Get("effects/glow.png"), Tint(color, flag2 ? 0.55f : 0.2f));
				TranceWidgets.Image("Junction", (Transform)(object)content, val3, Vector2.one * 8f, assets.Get("frames/socket.png"), Color.white);
				TranceWidgets.Image("JunctionRim", (Transform)(object)content, val3, Vector2.one * 8f, assets.Get("rings/rim.png"), color);
				for (int num6 = 0; num6 < definition.Parameters.Count; num6++)
				{
					AbilityParameterDefinition abilityParameterDefinition = definition.Parameters[num6];
					TranceLayout.Modifier(num6, definition.Parameters.Count, num5, out var x2, out var y2);
					Vector2 to2 = val2 + new Vector2(x2, y2);
					bool flag3 = flag && SorceryProgression.Parameter(data, id, abilityParameterDefinition.Id);
					TranceWidgets.Line((Transform)(object)content, val2, to2, (!flag3) ? 1 : 2, Tint(color, flag3 ? 0.65f : 0.18f));
				}
				Node(val2, 112f, assets.Rune(id), color, flag2, flag, selectedAbility == id && selectedModifier == null && !selectedSlot.HasValue, current: false, delegate
				{
					select(id, null, null);
				}, delegate(bool hover)
				{
					preview(id, null, null, hover);
				}, invoke, flashKey == id);
				for (int num7 = 0; num7 < definition.Parameters.Count; num7++)
				{
					AbilityParameterDefinition parameter = definition.Parameters[num7];
					TranceLayout.Modifier(num7, definition.Parameters.Count, num5, out var x3, out var y3);
					bool flag4 = SorceryProgression.ModifierLearned(data, id, parameter.Id);
					Node(val2 + new Vector2(x3, y3), 62f, assets.Modifier(id, parameter.Id), (Color)(flag4 ? assets.Color(definition) : new Color(0.27f, 0.27f, 0.29f)), flag && SorceryProgression.Parameter(data, id, parameter.Id), flag4, selectedAbility == id && selectedModifier == parameter.Id && !selectedSlot.HasValue, current: false, delegate
					{
						select(id, parameter.Id, null);
					}, delegate(bool hover)
					{
						preview(id, parameter.Id, null, hover);
					}, invoke, flashKe