Decompiled source of ValhallEternal v0.7.0

plugins/ValhallEternal.dll

Decompiled a day ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Runtime.Serialization;
using System.Runtime.Versioning;
using System.Security.Permissions;
using System.Text;
using System.Text.RegularExpressions;
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 SimpleJson;
using TMPro;
using UnityEngine;
using UnityEngine.Events;
using UnityEngine.SceneManagement;
using UnityEngine.UI;
using ValhallEternal.boons;
using ValhallEternal.common;
using ValhallEternal.modules;
using YamlDotNet.Serialization;
using YamlDotNet.Serialization.NamingConventions;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)]
[assembly: AssemblyTitle("ValhallEternal")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("ValhallEternal")]
[assembly: AssemblyCopyright("Copyright ©  2021")]
[assembly: AssemblyTrademark("")]
[assembly: ComVisible(false)]
[assembly: Guid("e3243d22-4307-4008-ba36-9f326008cde5")]
[assembly: AssemblyFileVersion("0.7.0")]
[assembly: TargetFramework(".NETFramework,Version=v4.8", FrameworkDisplayName = ".NET Framework 4.8")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("0.7.0.0")]
namespace ValhallEternal
{
	internal class Logger
	{
		public static LogLevel Level = (LogLevel)16;

		public static void enableDebugLogging(object sender, EventArgs e)
		{
			//IL_001d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0012: Unknown result type (might be due to invalid IL or missing references)
			if (ValConfig.EnableDebugMode.Value)
			{
				Level = (LogLevel)32;
			}
			else
			{
				Level = (LogLevel)16;
			}
		}

		public static void CheckEnableDebugLogging()
		{
			//IL_001d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0012: Unknown result type (might be due to invalid IL or missing references)
			if (ValConfig.EnableDebugMode.Value)
			{
				Level = (LogLevel)32;
			}
			else
			{
				Level = (LogLevel)16;
			}
		}

		public static void LogDebug(string message)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0008: Invalid comparison between Unknown and I4
			if ((int)Level >= 32)
			{
				ValhallEternal.Log.LogInfo((object)message);
			}
		}

		public static void LogInfo(string message)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0008: Invalid comparison between Unknown and I4
			if ((int)Level >= 16)
			{
				ValhallEternal.Log.LogInfo((object)message);
			}
		}

		public static void LogWarning(string message)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0007: Invalid comparison between Unknown and I4
			if ((int)Level >= 4)
			{
				ValhallEternal.Log.LogWarning((object)message);
			}
		}

		public static void LogError(string message)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0007: Invalid comparison between Unknown and I4
			if ((int)Level >= 2)
			{
				ValhallEternal.Log.LogError((object)message);
			}
		}
	}
	[BepInPlugin("MidnightsFX.ValhallaEternal", "ValhallEternal", "0.7.0")]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[NetworkCompatibility(/*Could not decode attribute arguments.*/)]
	internal class ValhallEternal : BaseUnityPlugin
	{
		public const string PluginGUID = "MidnightsFX.ValhallaEternal";

		public const string PluginName = "ValhallEternal";

		public const string PluginVersion = "0.7.0";

		public static CustomLocalization Localization = LocalizationManager.Instance.GetLocalization();

		public static AssetBundle EmbeddedResourceBundle;

		internal static Harmony Harmony = new Harmony("MidnightsFX.ValhallaEternal");

		public static ManualLogSource Log;

		public ValConfig cfg;

		public static Harmony HarmonyInstance { get; private set; }

		public void Awake()
		{
			Log = ((BaseUnityPlugin)this).Logger;
			cfg = new ValConfig(((BaseUnityPlugin)this).Config);
			EmbeddedResourceBundle = AssetUtils.LoadAssetBundleFromResources("ValhallEternal.embedded.valeternal", typeof(ValhallEternal).Assembly);
			((BaseUnityPlugin)this).Logger.LogInfo((object)("Asset Names: " + string.Join(",\n", EmbeddedResourceBundle.GetAllAssetNames())));
			Deities.LoadDietyConfigurations();
			HarmonyInstance = Harmony.CreateAndPatchAll(Assembly.GetExecutingAssembly(), "MidnightsFX.ValhallaEternal");
			AddLocalizations();
			SacrificeData.SetupSacrificeData();
			DataObjects.LoadAssets();
			Commands.AddCommands();
			Harmony.PatchAll(Assembly.GetExecutingAssembly());
			Locations.SetupLocations();
			Logger.LogInfo((object)"Live eternal in Valhalla.");
		}

		private void AddLocalizations()
		{
			Localization = LocalizationManager.Instance.GetLocalization();
			string text = Path.Combine(Paths.ConfigPath, "ValhallaEternal", "localizations");
			Directory.CreateDirectory(text);
			string[] manifestResourceNames = typeof(ValhallEternal).Assembly.GetManifestResourceNames();
			foreach (string text2 in manifestResourceNames)
			{
				if (!text2.Contains("localizations"))
				{
					continue;
				}
				string input = ReadEmbeddedResourceFile(text2);
				string text3 = Regex.Replace(input, "\\/\\/.*", "");
				Dictionary<string, string> internal_localization = SimpleJson.DeserializeObject<Dictionary<string, string>>(text3);
				string[] array = text2.Split(new char[1] { '.' });
				if (File.Exists(text + "/" + array[2] + ".json"))
				{
					string text4 = File.ReadAllText(text + "/" + array[2] + ".json");
					try
					{
						Dictionary<string, string> dictionary = SimpleJson.DeserializeObject<Dictionary<string, string>>(text4);
						UpdateLocalizationWithMissingKeys(internal_localization, dictionary);
						((BaseUnityPlugin)this).Logger.LogDebug((object)("Reading " + text + "/" + array[2] + ".json"));
						File.WriteAllText(text + "/" + array[2] + ".json", SimpleJson.SerializeObject((object)dictionary));
						string text5 = File.ReadAllText(text + "/" + array[2] + ".json");
						Localization.AddJsonFile(array[2], text5);
					}
					catch
					{
						File.WriteAllText(text + "/" + array[2] + ".json", text3);
						((BaseUnityPlugin)this).Logger.LogDebug((object)("Reading " + text2));
						Localization.AddJsonFile(array[2], text3);
					}
				}
				else
				{
					File.WriteAllText(text + "/" + array[2] + ".json", text3);
					((BaseUnityPlugin)this).Logger.LogDebug((object)("Reading " + text2));
					Localization.AddJsonFile(array[2], text3);
				}
				((BaseUnityPlugin)this).Logger.LogDebug((object)("Added localization: '" + array[2] + "'"));
			}
		}

		private Dictionary<string, string> UpdateLocalizationWithMissingKeys(Dictionary<string, string> internal_localization, Dictionary<string, string> cached_localization)
		{
			if (internal_localization.Keys != cached_localization.Keys)
			{
				List<string> list = cached_localization.Keys.ToList();
				foreach (KeyValuePair<string, string> item in internal_localization)
				{
					list.Remove(item.Key);
					if (!cached_localization.ContainsKey(item.Key))
					{
						((BaseUnityPlugin)this).Logger.LogDebug((object)("Adding missing localization key " + item.Key));
						cached_localization.Add(item.Key, item.Value);
					}
				}
				if (list.Count > 0)
				{
					((BaseUnityPlugin)this).Logger.LogDebug((object)("Removing extra keys " + string.Join(",", list) + "."));
					foreach (string item2 in list)
					{
						cached_localization.Remove(item2);
					}
				}
			}
			return cached_localization;
		}

		private string ReadEmbeddedResourceFile(string filename)
		{
			using Stream stream = typeof(ValhallEternal).Assembly.GetManifestResourceStream(filename);
			using StreamReader streamReader = new StreamReader(stream);
			return streamReader.ReadToEnd();
		}
	}
}
namespace ValhallEternal.oaths
{
	internal static class DamageTaken
	{
		public static class PlayerOathOfDamageTaken
		{
			[HarmonyPatch(typeof(Character), "RPC_Damage")]
			public static class EnemyDamageScalingIncrease
			{
				public static void Prefix(Character __instance, ref HitData hit)
				{
					if (__instance.IsPlayer() && PlayerData.localPlayerConfig.TotalOaths.ContainsKey(DataObjects.Oaths.DamageTakenIncrease) && (Object)(object)((__instance is Player) ? __instance : null) == (Object)(object)Player.m_localPlayer)
					{
						float num = PlayerData.localPlayerConfig.TotalOaths[DataObjects.Oaths.DamageTakenIncrease] / 100f + 1f;
						Logger.LogDebug($"Oath of Damage Taken mult: {num} Hit total dmg: {hit.GetTotalDamage()}");
						((DamageTypes)(ref hit.m_damage)).Modify(num);
						Logger.LogDebug($"New Oath increased Damage: {hit.GetTotalDamage()}");
					}
				}
			}
		}
	}
	internal static class DealLessDamage
	{
		public static class PlayerOathOfReducedDamageDealt
		{
			[HarmonyPatch(typeof(Character), "RPC_Damage")]
			public static class EnemyDamageScalingIncrease
			{
				public static void Prefix(ref HitData hit)
				{
					Character attacker = hit.GetAttacker();
					if (!((Object)(object)attacker != (Object)null) || !attacker.IsPlayer() || !((Object)(object)((attacker is Player) ? attacker : null) == (Object)(object)Player.m_localPlayer) || !PlayerData.localPlayerConfig.DealReductedDamageActive)
					{
						return;
					}
					if (PlayerData.localPlayerConfig.HasOath(DataObjects.Oaths.DealLessAllDamage, out var OathValue))
					{
						float num = 1f - OathValue;
						if ((double)num < 0.2)
						{
							num = 0.2f;
						}
						((DamageTypes)(ref hit.m_damage)).Modify(num);
						Logger.LogDebug($"Reducing all damage done by {1f - num}");
					}
					if (PlayerData.localPlayerConfig.HasOath(DataObjects.Oaths.DealLessBluntDamage, out var OathValue2))
					{
						float num2 = 1f - OathValue2;
						if ((double)num2 < 0.2)
						{
							num2 = 0.2f;
						}
						hit.m_damage.m_blunt *= num2;
						Logger.LogDebug($"Reduced Blunt damage done by {1f - num2}");
					}
					if (PlayerData.localPlayerConfig.HasOath(DataObjects.Oaths.DealLessSlashDamage, out var OathValue3))
					{
						float num3 = 1f - OathValue3;
						hit.m_damage.m_slash *= num3;
						Logger.LogDebug($"Reduced Slash damage done by {1f - num3}.");
					}
					if (PlayerData.localPlayerConfig.HasOath(DataObjects.Oaths.DealLessPierceDamage, out var OathValue4))
					{
						float num4 = 1f - OathValue4;
						hit.m_damage.m_pierce *= num4;
						Logger.LogDebug($"Reduced Pierce damage done {1f - num4}.");
					}
				}
			}
		}
	}
	internal static class LowerSkillGains
	{
		public static class PlayerOathOfReducedDamageDealt
		{
			[HarmonyPatch(typeof(Player), "RaiseSkill")]
			public static class EnemyDamageScalingIncrease
			{
				public static void Prefix(Player __instance, SkillType skill, ref float value)
				{
					//IL_0023: 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_0025: 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_0027: Unknown result type (might be due to invalid IL or missing references)
					//IL_0029: Unknown result type (might be due to invalid IL or missing references)
					//IL_0067: Expected I4, but got Unknown
					//IL_0069: Unknown result type (might be due to invalid IL or missing references)
					//IL_006c: Invalid comparison between Unknown and I4
					//IL_0073: Unknown result type (might be due to invalid IL or missing references)
					//IL_0076: Invalid comparison between Unknown and I4
					if (!((Object)(object)__instance == (Object)(object)Player.m_localPlayer) || !PlayerData.localPlayerConfig.ReduceSkillGainsActive)
					{
						return;
					}
					switch (skill - 1)
					{
					case 2:
						value *= ModifySkillGain(DataObjects.Oaths.LowerSkillGainClub, value);
						return;
					case 0:
						value *= ModifySkillGain(DataObjects.Oaths.LowerSkillGainSword, value);
						return;
					case 1:
						value *= ModifySkillGain(DataObjects.Oaths.LowerSkillGainKnives, value);
						return;
					case 3:
						value *= ModifySkillGain(DataObjects.Oaths.LowerSkillGainPolearms, value);
						return;
					case 4:
						value *= ModifySkillGain(DataObjects.Oaths.LowerSkillGainSpears, value);
						return;
					case 7:
						value *= ModifySkillGain(DataObjects.Oaths.LowerSkillGainBow, value);
						return;
					case 13:
						value *= ModifySkillGain(DataObjects.Oaths.LowerSkillGainCrossbow, value);
						return;
					case 9:
						value *= ModifySkillGain(DataObjects.Oaths.LowerSkillGainBloodMagic, value);
						return;
					case 8:
						value *= ModifySkillGain(DataObjects.Oaths.LowerSkillGainElementalMagic, value);
						return;
					case 6:
						value *= ModifySkillGain(DataObjects.Oaths.LowerSkillGainAxes, value);
						return;
					case 5:
					case 10:
					case 11:
					case 12:
						return;
					}
					if ((int)skill != 101)
					{
						if ((int)skill == 102)
						{
							value *= ModifySkillGain(DataObjects.Oaths.LowerSkillGainRun, value);
						}
					}
					else
					{
						value *= ModifySkillGain(DataObjects.Oaths.LowerSkillGainSneak, value);
					}
				}

				private static float ModifySkillGain(DataObjects.Oaths oathkey, float value)
				{
					if (PlayerData.localPlayerConfig.TotalOaths.ContainsKey(oathkey))
					{
						float num = 1f - PlayerData.localPlayerConfig.TotalOaths[oathkey];
						Logger.LogDebug($"Applied {oathkey} {value} * {num} -> {value * num}.");
						value *= num;
					}
					return value;
				}
			}
		}
	}
	internal static class ReduceCarryWeight
	{
		[HarmonyPatch(typeof(SEMan), "ModifyMaxCarryWeight")]
		public static class ReduceCarryWeightOath
		{
			public static void Postfix(SEMan __instance, ref float limit)
			{
				if (__instance.m_character.IsPlayer() && PlayerData.localPlayerConfig.HasOath(DataObjects.Oaths.ReducePlayerCarryWeight, out var OathValue))
				{
					limit -= OathValue;
				}
			}
		}
	}
	internal static class ReducePlayerHealthPercent
	{
		[HarmonyPatch(typeof(Player), "GetTotalFoodValue")]
		public static class ReducePlayerHealthStaminaEitrPercent
		{
			public static void Postfix(ref float stamina, ref float hp, ref float eitr)
			{
				if (PlayerData.localPlayerConfig.HasOath(DataObjects.Oaths.ReducePlayerHealthPercent, out var OathValue))
				{
					hp *= 1f - OathValue;
				}
				if (PlayerData.localPlayerConfig.HasOath(DataObjects.Oaths.ReducePlayerStaminaPercent, out var OathValue2))
				{
					stamina *= 1f - OathValue2;
				}
				if (PlayerData.localPlayerConfig.HasOath(DataObjects.Oaths.ReducePlayerEitrPercent, out var OathValue3))
				{
					eitr *= 1f - OathValue3;
				}
			}
		}
	}
}
namespace ValhallEternal.modules
{
	internal static class Commands
	{
		internal class SetPlayerEternalLevel : ConsoleCommand
		{
			public override string Name => "VE-Set-Player-Level";

			public override string Help => "Format: [level]";

			public override void Run(string[] args)
			{
				if (args.Length < 1)
				{
					Logger.LogInfo("Level required.");
				}
				int.TryParse(args[0].Trim(), out var result);
				if (result != 0)
				{
					Logger.LogDebug($"Setting player prestige level {result}");
					((Character)Player.m_localPlayer).m_nview.GetZDO().Set(DataObjects.CustomLevelZKey, result);
					Player.m_localPlayer.PlayerRemoveUniqueKey(DataObjects.CustomLevelZKey);
					Player.m_localPlayer.AddUniqueKeyValue(DataObjects.CustomLevelZKey, $"{result}");
					PrestigeDisplays.UpdateLocalPlayerLevelDisplay();
				}
			}
		}

		internal class ClearPlayerData : ConsoleCommand
		{
			public override string Name => "VE-remove-player-data";

			public override string Help => "This clears ALL boon, oath, prestige, and player levels. REQUIRES A CLIENT RESTART";

			public override bool IsCheat => true;

			public override void Run(string[] args)
			{
				Player.m_localPlayer.m_customData.Remove(DataObjects.CustomDataKey);
			}
		}

		internal static void AddCommands()
		{
			CommandManager.Instance.AddConsoleCommand((ConsoleCommand)(object)new SetPlayerEternalLevel());
			CommandManager.Instance.AddConsoleCommand((ConsoleCommand)(object)new ClearPlayerData());
		}
	}
	internal static class Compendium
	{
		[HarmonyPatch(typeof(TextsDialog), "UpdateTextsList")]
		public static class TextsDialog_UpdateTextsList_Patch
		{
			public static void Postfix(TextsDialog __instance)
			{
				AddDietyPrestigeExplanations(__instance);
			}

			private static void AddDietyPrestigeExplanations(TextsDialog textsDialog)
			{
				//IL_0261: Unknown result type (might be due to invalid IL or missing references)
				//IL_026b: Expected O, but got Unknown
				StringBuilder stringBuilder = new StringBuilder();
				if (PlayerData.localPlayerConfig.TotalBoons.Count > 0)
				{
					stringBuilder.AppendLine("<size=48><color=" + HeaderColor + ">" + Localization.instance.Localize("$ve_boon_section_header") + "</color></size>");
					stringBuilder.AppendLine();
				}
				foreach (KeyValuePair<DataObjects.Boons, float> totalBoon in PlayerData.localPlayerConfig.TotalBoons)
				{
					stringBuilder.AppendLine(Localization.instance.Localize($"<size=24>{DataObjects.LocalizeBoon(totalBoon.Key)}</size> ($ve_level <color={BoonColor}>{totalBoon.Value}</color>) - {DataObjects.LocalizeBoonDesc(totalBoon.Key)}"));
				}
				if (stringBuilder.Length > 0)
				{
					stringBuilder.AppendLine();
				}
				if (PlayerData.localPlayerConfig.TotalOaths.Count > 0)
				{
					stringBuilder.AppendLine("<size=48><color=" + HeaderColor + ">" + Localization.instance.Localize("$ve_oath_section_header") + "</color></size>");
					stringBuilder.AppendLine();
				}
				foreach (KeyValuePair<DataObjects.Oaths, float> totalOath in PlayerData.localPlayerConfig.TotalOaths)
				{
					stringBuilder.AppendLine(Localization.instance.Localize($"<size=24>{DataObjects.LocalizeOath(totalOath.Key)}</size> ($ve_level <color={OathColor}>{totalOath.Value}</color>) - {DataObjects.LocalizeOathDesc(totalOath.Key, totalOath.Value)}"));
				}
				if (textsDialog.m_texts[0].m_topic != Localization.instance.Localize("$ve_compendium_name"))
				{
					textsDialog.m_texts.Insert(0, new TextInfo(Localization.instance.Localize("$ve_compendium_name"), Localization.instance.Localize(stringBuilder.ToString())));
				}
			}
		}

		private static readonly string HeaderColor = "#ffa64d";

		private static readonly string BoonColor = "#40B850";

		private static readonly string OathColor = "#CF2713";
	}
	internal static class Locations
	{
		public static void SetupLocations()
		{
			AddLocationsToWorldGen((Biome)1, "ve_tribute_gefjun", ValConfig.MaxMeadowsLocations.Value);
			AddLocationsToWorldGen((Biome)8, "ve_tribute_vor", ValConfig.MaxBlackForestLocations.Value);
			AddLocationsToWorldGen((Biome)2, "ve_tribute_baldur", ValConfig.MaxSwampLocations.Value);
			AddLocationsToWorldGen((Biome)4, "ve_tribute_skaldi", ValConfig.MaxMountainLocations.Value);
			AddLocationsToWorldGen((Biome)16, "ve_tribute_syn", ValConfig.MaxPlainsLocations.Value);
			AddLocationsToWorldGen((Biome)512, "ve_tribute_freya", ValConfig.MaxMistlandsLocations.Value);
			AddLocationsToWorldGen((Biome)32, "ve_tribute_hel", ValConfig.MaxAshlandsLocations.Value);
		}

		public static void AddLocationsToWorldGen(Biome targetBiome, string prefabname, int maxLocationAmount = 10)
		{
			//IL_002d: 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_004a: Expected O, but got Unknown
			//IL_004b: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ab: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b5: Expected O, but got Unknown
			GameObject val = ValhallEternal.EmbeddedResourceBundle.LoadAsset<GameObject>("assets/locations/" + prefabname + ".prefab");
			GameObject val2 = ZoneManager.Instance.CreateLocationContainer(val);
			Logger.LogInfo($"Tribute generation: {targetBiome} location {((Object)val2).name}");
			LocationConfig val3 = new LocationConfig();
			val3.Biome = targetBiome;
			val3.Quantity = maxLocationAmount;
			val3.Priotized = true;
			val3.ExteriorRadius = 5f;
			val3.SlopeRotation = true;
			val3.MinAltitude = 1f;
			val3.ClearArea = false;
			val3.RandomRotation = true;
			val3.MinDistanceFromSimilar = ValConfig.MinDistanceBetweenTributeLocations.Value;
			ZoneManager.Instance.AddCustomLocation(new CustomLocation(val2, true, val3));
		}
	}
	internal class OathUI : MonoBehaviour
	{
		private static OathUI _instance;

		private static GameObject OathPanel;

		public static OathUI Instance => _instance ?? (_instance = new OathUI());

		public void Awake()
		{
		}

		public void Show()
		{
			if ((Object)(object)OathPanel == (Object)null)
			{
				CreateStaticUIObjects();
			}
			OathPanel.SetActive(true);
		}

		public void Hide()
		{
			if ((Object)(object)OathPanel != (Object)null)
			{
				OathPanel.SetActive(false);
			}
			GUIManager.BlockInput(false);
		}

		private void CreateStaticUIObjects()
		{
			//IL_0046: Unknown result type (might be due to invalid IL or missing references)
			//IL_0055: 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_00b2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ec: Unknown result type (might be due to invalid IL or missing references)
			if (GUIManager.Instance == null || !Object.op_Implicit((Object)(object)GUIManager.CustomGUIFront))
			{
				Logger.LogWarning("GUIManager not setup, skipping static object creation.");
				return;
			}
			OathPanel = GUIManager.Instance.CreateWoodpanel(GUIManager.CustomGUIFront.transform, new Vector2(0.5f, 0.5f), new Vector2(0.5f, 0.5f), new Vector2(0f, 0f), 800f, 800f, true);
			OathPanel.SetActive(false);
			GameObject val = GUIManager.Instance.CreateText(Localization.instance.Localize("$selection_header"), OathPanel.transform, new Vector2(0.5f, 0.5f), new Vector2(0.5f, 0.5f), new Vector2(50f, 360f), GUIManager.Instance.AveriaSerifBold, 30, GUIManager.Instance.ValheimOrange, true, Color.black, 350f, 40f, false);
			((Object)val).name = "DLHeader";
		}
	}
	public static class PlayerData
	{
		[HarmonyPatch(typeof(Player))]
		public static class LoadPlayerBoonOaths
		{
			[HarmonyPostfix]
			[HarmonyPatch("Load")]
			private static void Postfix(Player __instance)
			{
				LoadPlayerConfiguration(__instance);
			}
		}

		public static DataObjects.CompositePlayerConfig localPlayerConfig = new DataObjects.CompositePlayerConfig();

		public static void SetPlayerConfig(DataObjects.PlayerLevelData pld)
		{
			Dictionary<DataObjects.Oaths, float> dictionary = new Dictionary<DataObjects.Oaths, float>();
			Dictionary<DataObjects.Boons, float> dictionary2 = new Dictionary<DataObjects.Boons, float>();
			if (pld.PlayerOaths != null)
			{
				foreach (KeyValuePair<DataObjects.Oaths, float> playerOath in pld.PlayerOaths)
				{
					if (dictionary.ContainsKey(playerOath.Key))
					{
						dictionary[playerOath.Key] += playerOath.Value;
					}
					else
					{
						dictionary.Add(playerOath.Key, playerOath.Value);
					}
				}
			}
			if (pld.PlayerBoons != null)
			{
				foreach (KeyValuePair<DataObjects.Boons, float> playerBoon in pld.PlayerBoons)
				{
					if (dictionary2.ContainsKey(playerBoon.Key))
					{
						dictionary2[playerBoon.Key] += playerBoon.Value;
					}
					else
					{
						dictionary2.Add(playerBoon.Key, playerBoon.Value);
					}
				}
			}
			bool dealReductedDamageActive = false;
			foreach (DataObjects.Oaths damageReductionOath in DataObjects.DamageReductionOaths)
			{
				if (dictionary.ContainsKey(damageReductionOath))
				{
					dealReductedDamageActive = true;
					break;
				}
			}
			bool reduceSkillGainsActive = false;
			foreach (DataObjects.Oaths reducedSkillGainOath in DataObjects.ReducedSkillGainOaths)
			{
				if (dictionary.ContainsKey(reducedSkillGainOath))
				{
					reduceSkillGainsActive = true;
					break;
				}
			}
			localPlayerConfig = new DataObjects.CompositePlayerConfig
			{
				ReduceSkillGainsActive = reduceSkillGainsActive,
				DealReductedDamageActive = dealReductedDamageActive,
				TotalOaths = dictionary,
				TotalBoons = dictionary2,
				ActiveEffectsForPlayer = pld.ActiveEffectsForPlayer,
				AvailableEffectsForPlayer = pld.AvailableEffectsForPlayer
			};
			if (localPlayerConfig.AvailableEffectsForPlayer != null)
			{
				foreach (KeyValuePair<DataObjects.PrestigeEffect, List<string>> item in localPlayerConfig.AvailableEffectsForPlayer)
				{
					if (!item.Value.Contains(DataObjects.None))
					{
						item.Value.Insert(0, DataObjects.None);
					}
				}
			}
			if (pld != null)
			{
				Logger.LogDebug($"Player Presitge Level: {pld.PlayerLevel}");
				localPlayerConfig.PlayerLevel = pld.PlayerLevel;
			}
			Logger.LogDebug($"Set player config: Oaths-{localPlayerConfig.TotalOaths.Count}, Boons-{localPlayerConfig.TotalBoons.Count}");
			foreach (KeyValuePair<DataObjects.Oaths, float> totalOath in localPlayerConfig.TotalOaths)
			{
				Logger.LogDebug($" - Oath: {totalOath.Key} Value: {totalOath.Value}");
			}
			foreach (KeyValuePair<DataObjects.Boons, float> totalBoon in localPlayerConfig.TotalBoons)
			{
				Logger.LogDebug($" - Boon: {totalBoon.Key} Value: {totalBoon.Value}");
			}
		}

		public static bool HasBoon(DataObjects.Boons boon)
		{
			if (localPlayerConfig.TotalBoons == null)
			{
				return false;
			}
			if (localPlayerConfig.TotalBoons.Keys.Contains(boon))
			{
				return true;
			}
			return false;
		}

		public static bool HasBoonWithValue(DataObjects.Boons boon, out float value)
		{
			value = 0f;
			if (localPlayerConfig.TotalBoons == null)
			{
				return false;
			}
			if (localPlayerConfig.TotalBoons.Keys.Contains(boon))
			{
				value = localPlayerConfig.TotalBoons[boon];
				return true;
			}
			return false;
		}

		public static bool HasOathWithValue(DataObjects.Oaths oath, out float value)
		{
			value = 0f;
			if (localPlayerConfig.TotalOaths == null)
			{
				return false;
			}
			if (localPlayerConfig.TotalOaths.Keys.Contains(oath))
			{
				value = localPlayerConfig.TotalOaths[oath];
				return true;
			}
			return false;
		}

		public static void AddOathToPlayerConfig(DataObjects.Oaths oath, float value)
		{
			if (localPlayerConfig.TotalOaths.ContainsKey(oath))
			{
				localPlayerConfig.TotalOaths[oath] += value;
			}
			else
			{
				localPlayerConfig.TotalOaths.Add(oath, value);
			}
		}

		public static void AddBoonToPlayerConfig(DataObjects.Boons boon, float value)
		{
			if (localPlayerConfig.TotalBoons.ContainsKey(boon))
			{
				localPlayerConfig.TotalBoons[boon] += value;
			}
			else
			{
				localPlayerConfig.TotalBoons.Add(boon, value);
			}
		}

		public static void AddVisualPrestigeEffectOptionToPlayerConfig(DataObjects.PrestigeEffect effectType, string effectKey)
		{
			if (localPlayerConfig.AvailableEffectsForPlayer != null)
			{
				if (localPlayerConfig.AvailableEffectsForPlayer.ContainsKey(effectType) && !localPlayerConfig.AvailableEffectsForPlayer[effectType].Contains(effectKey))
				{
					localPlayerConfig.AvailableEffectsForPlayer[effectType].Add(effectKey);
				}
				else if (!localPlayerConfig.AvailableEffectsForPlayer.ContainsKey(effectType))
				{
					localPlayerConfig.AvailableEffectsForPlayer[effectType] = new List<string> { effectKey };
				}
			}
			else
			{
				localPlayerConfig.AvailableEffectsForPlayer = new Dictionary<DataObjects.PrestigeEffect, List<string>> { 
				{
					effectType,
					new List<string>
					{
						DataObjects.None,
						effectKey
					}
				} };
			}
		}

		public static void SetActivePrestigeEffectForPlayer(DataObjects.PrestigeEffect effectType, string effectKey)
		{
			if (localPlayerConfig.ActiveEffectsForPlayer != null)
			{
				if (localPlayerConfig.ActiveEffectsForPlayer.ContainsKey(effectType))
				{
					localPlayerConfig.ActiveEffectsForPlayer[effectType] = effectKey;
				}
				else
				{
					localPlayerConfig.ActiveEffectsForPlayer.Add(effectType, effectKey);
				}
			}
			else
			{
				localPlayerConfig.ActiveEffectsForPlayer = new Dictionary<DataObjects.PrestigeEffect, string> { { effectType, effectKey } };
			}
		}

		public static bool PlayerHasAnyPrestigeEffect()
		{
			if (localPlayerConfig.AvailableEffectsForPlayer != null)
			{
				foreach (KeyValuePair<DataObjects.PrestigeEffect, List<string>> item in localPlayerConfig.AvailableEffectsForPlayer)
				{
					if (item.Value.Count > 1)
					{
						return true;
					}
				}
			}
			return false;
		}

		public static bool PlayerHasPrestigeEffect(DataObjects.PrestigeEffect type, string name)
		{
			if (localPlayerConfig.AvailableEffectsForPlayer != null && localPlayerConfig.AvailableEffectsForPlayer.ContainsKey(type) && !localPlayerConfig.AvailableEffectsForPlayer[type].Contains(name))
			{
				return true;
			}
			return false;
		}

		public static void SavePlayerConfiguration()
		{
			if ((Object)(object)Player.m_localPlayer == (Object)null)
			{
				Logger.LogWarning("Cannot save player configuration, local player is null.");
				return;
			}
			DataObjects.PlayerLevelData playerLevelData = new DataObjects.PlayerLevelData
			{
				PlayerLevel = localPlayerConfig.PlayerLevel,
				PlayerOaths = localPlayerConfig.TotalOaths,
				PlayerBoons = localPlayerConfig.TotalBoons,
				ActiveEffectsForPlayer = localPlayerConfig.ActiveEffectsForPlayer,
				AvailableEffectsForPlayer = localPlayerConfig.AvailableEffectsForPlayer
			};
			string value = PackPlayerDataToString(playerLevelData);
			if (Player.m_localPlayer.m_customData.ContainsKey(DataObjects.CustomDataKey))
			{
				Player.m_localPlayer.m_customData[DataObjects.CustomDataKey] = value;
			}
			else
			{
				Player.m_localPlayer.m_customData.Add(DataObjects.CustomDataKey, value);
			}
			((Character)Player.m_localPlayer).m_nview.GetZDO().Set(DataObjects.CustomLevelZKey, playerLevelData.PlayerLevel);
		}

		public static List<OptionData> ListPlayerAvailablePrestigeEffect(DataObjects.PrestigeEffect effect = DataObjects.PrestigeEffect.Wings)
		{
			//IL_004f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0059: Expected O, but got Unknown
			List<OptionData> list = new List<OptionData>();
			if (localPlayerConfig.AvailableEffectsForPlayer != null && localPlayerConfig.AvailableEffectsForPlayer.ContainsKey(effect))
			{
				foreach (string item in localPlayerConfig.AvailableEffectsForPlayer[effect])
				{
					list.Add(new OptionData(item));
				}
			}
			return list;
		}

		public static void LoadPlayerConfiguration(Player player)
		{
			if (player.m_customData.ContainsKey(DataObjects.CustomDataKey))
			{
				Logger.LogDebug("Saved player data found, loading.");
				DataObjects.PlayerLevelData playerLevelData = UnpackPlayerData(player.m_customData[DataObjects.CustomDataKey]);
				SetPlayerConfig(playerLevelData);
				PrestigeDisplays.UpdateLocalPlayerLevelDisplay(playerLevelData.PlayerLevel);
				if (playerLevelData.PlayerLevel != 0 && ((Character)player).m_nview.GetZDO().GetInt(DataObjects.CustomLevelZKey, 0) == 0)
				{
					((Character)player).m_nview.GetZDO().Set(DataObjects.CustomLevelZKey, playerLevelData.PlayerLevel);
				}
				if (playerLevelData.ActiveEffectsForPlayer != null && playerLevelData.ActiveEffectsForPlayer.ContainsKey(DataObjects.PrestigeEffect.Wings))
				{
					Logger.LogDebug("Setting up player wings display: " + playerLevelData.ActiveEffectsForPlayer[DataObjects.PrestigeEffect.Wings]);
					PrestigeDisplays.SetupPlayerWingsDisplay(playerLevelData.ActiveEffectsForPlayer[DataObjects.PrestigeEffect.Wings]);
				}
			}
			else
			{
				Logger.LogDebug("No saved player saved data found.");
			}
		}

		public static string PackPlayerDataToString(DataObjects.PlayerLevelData playerData)
		{
			return DataObjects.yamlserializerJsonCompat.Serialize((object)playerData);
		}

		public static DataObjects.PlayerLevelData UnpackPlayerData(string packedPlayerData)
		{
			return DataObjects.yamldeserializer.Deserialize<DataObjects.PlayerLevelData>(packedPlayerData);
		}
	}
	public static class PrestigeAndCosmeticUI
	{
		[HarmonyPatch(typeof(InventoryGui), "Awake")]
		public static class AddSacrificeUIButton
		{
			public static void Postfix(InventoryGui __instance)
			{
				//IL_003f: Unknown result type (might be due to invalid IL or missing references)
				//IL_004e: 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_00a5: Unknown result type (might be due to invalid IL or missing references)
				//IL_00af: Expected O, but got Unknown
				if (!((Object)(object)CosmeticsButton != (Object)null))
				{
					CosmeticsButton = GUIManager.Instance.CreateButton(Localization.instance.Localize("$ve_prestige_options"), ((Component)__instance.m_infoPanel).transform, new Vector2(1f, 1f), new Vector2(1f, 1f), new Vector2(-628f, -90f), 90f, 60f);
					Button component = CosmeticsButton.GetComponent<Button>();
					((Selectable)component).interactable = true;
					CosmeticsButton.AddComponent<PrestigeUI>();
					((UnityEvent)component.onClick).AddListener(new UnityAction(PrestigeUI.Instance.Show));
					CosmeticsButton.SetActive(false);
				}
			}
		}

		[HarmonyPatch(typeof(InventoryGui), "Hide")]
		public static class HideSacrificeUI_InventoryClose
		{
			public static void Postfix()
			{
				PrestigeUI.Instance.Hide();
			}
		}

		[HarmonyPatch(typeof(InventoryGui), "Show")]
		public static class HideSacrificeUI_InventoryOpen
		{
			public static void Postfix()
			{
				if ((Object)(object)CosmeticsButton != (Object)null && (Object)(object)Player.m_localPlayer != (Object)null && PlayerData.PlayerHasAnyPrestigeEffect())
				{
					CosmeticsButton.SetActive(true);
				}
			}
		}

		internal class PrestigeUI : MonoBehaviour
		{
			private static PrestigeUI _instance;

			private static GameObject PrestigePanel;

			private static GameObject WingSelectorDropdown;

			private static GameObject AuraSelectorDropdown;

			private static GameObject ManualCloseButton;

			public static PrestigeUI Instance => _instance ?? (_instance = new PrestigeUI());

			public void Awake()
			{
				_instance = this;
			}

			public void Show()
			{
				if ((Object)(object)PrestigePanel == (Object)null)
				{
					CreateStaticUIObjects();
				}
				PrestigePanel.SetActive(true);
				EnableDisablePrestigeSelctions();
			}

			public void Hide()
			{
				if ((Object)(object)PrestigePanel != (Object)null)
				{
					PrestigePanel.SetActive(false);
				}
				GUIManager.BlockInput(false);
			}

			public static void EnableDisablePrestigeSelctions()
			{
				if (PlayerData.localPlayerConfig.AvailableEffectsForPlayer != null)
				{
					Logger.LogDebug($"Enabling usable prestige options in UI: wings-{PlayerData.localPlayerConfig.AvailableEffectsForPlayer.ContainsKey(DataObjects.PrestigeEffect.Wings)} Aura-{PlayerData.localPlayerConfig.AvailableEffectsForPlayer.ContainsKey(DataObjects.PrestigeEffect.Aura)}.");
					bool active = PlayerData.localPlayerConfig.AvailableEffectsForPlayer.ContainsKey(DataObjects.PrestigeEffect.Wings) && PlayerData.localPlayerConfig.AvailableEffectsForPlayer[DataObjects.PrestigeEffect.Wings].Count > 1;
					WingSelectorDropdown.SetActive(active);
					bool active2 = PlayerData.localPlayerConfig.AvailableEffectsForPlayer.ContainsKey(DataObjects.PrestigeEffect.Aura) && PlayerData.localPlayerConfig.AvailableEffectsForPlayer[DataObjects.PrestigeEffect.Aura].Count > 1;
					AuraSelectorDropdown.SetActive(active2);
				}
			}

			private void CreateStaticUIObjects()
			{
				//IL_0046: Unknown result type (might be due to invalid IL or missing references)
				//IL_0055: 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_00a3: 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_00c1: Unknown result type (might be due to invalid IL or missing references)
				//IL_0125: Unknown result type (might be due to invalid IL or missing references)
				//IL_0134: 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_01b6: 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_01d4: 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_0217: Expected O, but got Unknown
				if (GUIManager.Instance == null || !Object.op_Implicit((Object)(object)GUIManager.CustomGUIFront))
				{
					Logger.LogWarning("GUIManager not setup, skipping static object creation.");
					return;
				}
				PrestigePanel = GUIManager.Instance.CreateWoodpanel(GUIManager.CustomGUIFront.transform, new Vector2(0.5f, 0.5f), new Vector2(0.5f, 0.5f), new Vector2(0f, 0f), 300f, 400f, true);
				PrestigePanel.SetActive(false);
				WingSelectorDropdown = GUIManager.Instance.CreateDropDown(PrestigePanel.transform, new Vector2(0.5f, 0.5f), new Vector2(0.5f, 0.5f), new Vector2(0f, 0f), 18, 200f, 40f);
				Dropdown component = WingSelectorDropdown.GetComponent<Dropdown>();
				component.AddOptions(PlayerData.ListPlayerAvailablePrestigeEffect());
				((UnityEvent<int>)(object)component.onValueChanged).AddListener((UnityAction<int>)UpdateSelectedWings);
				AuraSelectorDropdown = GUIManager.Instance.CreateDropDown(PrestigePanel.transform, new Vector2(0.5f, 0.5f), new Vector2(0.5f, 0.5f), new Vector2(0f, -50f), 18, 200f, 40f);
				Dropdown component2 = AuraSelectorDropdown.GetComponent<Dropdown>();
				component2.AddOptions(PlayerData.ListPlayerAvailablePrestigeEffect(DataObjects.PrestigeEffect.Aura));
				((UnityEvent<int>)(object)component2.onValueChanged).AddListener((UnityAction<int>)UpdateSelectedAura);
				ManualCloseButton = GUIManager.Instance.CreateButton(Localization.instance.Localize("$ve_close"), PrestigePanel.transform, new Vector2(0.5f, 0.5f), new Vector2(0.5f, 0.5f), new Vector2(108f, 158f), 60f, 60f);
				Button component3 = ManualCloseButton.GetComponent<Button>();
				((Selectable)component3).interactable = true;
				((UnityEvent)component3.onClick).AddListener(new UnityAction(Hide));
			}

			public void UpdateSelectedWings(int _actionID)
			{
				Dropdown component = WingSelectorDropdown.GetComponent<Dropdown>();
				string text = component.options[component.value].text;
				PrestigeDisplays.SetupPlayerWingsDisplay(text);
			}

			public void UpdateSelectedAura(int _actionID)
			{
				Dropdown component = WingSelectorDropdown.GetComponent<Dropdown>();
				string text = component.options[component.value].text;
				PrestigeDisplays.SetupPlayerAuraDisplay(text);
			}

			public void ApplySelectedEffects()
			{
				Dropdown component = WingSelectorDropdown.GetComponent<Dropdown>();
			}
		}

		private static GameObject CosmeticsButton;
	}
	internal static class PrestigeDisplays
	{
		public class PrestigeLevelHUD
		{
			public GameObject hudroot { get; set; }

			public GameObject root { get; set; }

			public TextMeshProUGUI tmpGUI { get; set; }
		}

		internal static class EnablePlayerPrestigeDisplays
		{
			[HarmonyPatch(typeof(Player), "Awake")]
			public static class EnableLocalPlayerPrestigeDisplays
			{
				public static void Postfix(Player __instance)
				{
					UpdateLocalPlayerLevelDisplay();
					foreach (KeyValuePair<DataObjects.PrestigeEffect, string> item in PlayerData.localPlayerConfig.ActiveEffectsForPlayer)
					{
						switch (item.Key)
						{
						case DataObjects.PrestigeEffect.Wings:
							SetupPlayerWingsDisplay(item.Value);
							break;
						case DataObjects.PrestigeEffect.Aura:
							SetupPlayerAuraDisplay(item.Value);
							break;
						}
					}
				}
			}
		}

		[HarmonyPatch(typeof(EnemyHud))]
		public static class SetupOtherPlayerLevelDisplay
		{
			[HarmonyPatch("ShowHud")]
			public static void Postfix(EnemyHud __instance, Character c)
			{
				//IL_007c: Unknown result type (might be due to invalid IL or missing references)
				//IL_0081: Unknown result type (might be due to invalid IL or missing references)
				if ((Object)(object)c == (Object)null || !c.IsPlayer() || (Object)(object)__instance == (Object)null)
				{
					return;
				}
				HudData val = __instance.m_huds[c];
				if (val == null)
				{
					return;
				}
				Player val2 = (Player)(object)((c is Player) ? c : null);
				if ((Object)(object)val2 == (Object)null)
				{
					return;
				}
				ZDO zDO = ((Character)val2).m_nview.GetZDO();
				if (zDO == null)
				{
					return;
				}
				ZDOID zDOID = ((Character)val2).GetZDOID();
				uint iD = ((ZDOID)(ref zDOID)).ID;
				int @int = zDO.GetInt(DataObjects.CustomLevelZKey, 0);
				Logger.LogDebug($"Player {val2.GetPlayerName()}-{iD} level {@int}");
				if (extendedPlayerHUDS.ContainsKey(iD))
				{
					if (@int == 0)
					{
						extendedPlayerHUDS[iD].root.SetActive(false);
					}
					else
					{
						extendedPlayerHUDS[iD].root.SetActive(true);
					}
					((TMP_Text)extendedPlayerHUDS[iD].tmpGUI).text = $"{@int}";
				}
				else
				{
					CreateEnemyHud(iD, val.m_gui.transform, @int);
				}
			}
		}

		[HarmonyPatch(typeof(EnemyHud))]
		private static class CleanupOtherPlayerHUDS
		{
			[HarmonyPatch("UpdateHuds")]
			private static void Postfix()
			{
				if (extendedPlayerHUDS.Count != 0)
				{
					extendedPlayerHUDS = extendedPlayerHUDS.Where((KeyValuePair<uint, PrestigeLevelHUD> x) => (Object)(object)x.Value.root != (Object)null).ToDictionary((KeyValuePair<uint, PrestigeLevelHUD> kvp) => kvp.Key, (KeyValuePair<uint, PrestigeLevelHUD> kvp) => kvp.Value);
				}
			}
		}

		private static GameObject localPlayerVEHUD = null;

		private static TextMeshProUGUI localPlayerLevelText = null;

		internal static GameObject localPlayerWings = null;

		internal static GameObject localPlayerAura = null;

		public static Dictionary<uint, PrestigeLevelHUD> extendedPlayerHUDS = new Dictionary<uint, PrestigeLevelHUD>();

		public static void CreateLocalHudElements(Transform targetTform)
		{
			//IL_0081: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ba: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ca: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)localPlayerVEHUD == (Object)null)
			{
				Logger.LogDebug("Creating Local Player Level Display HUD Elements.");
				GameObject val = ValhallEternal.EmbeddedResourceBundle.LoadAsset<GameObject>("VELocalHud");
				localPlayerVEHUD = Object.Instantiate<GameObject>(val, targetTform);
				if ((Object)(object)Hud.m_instance != (Object)null)
				{
					Transform val2 = Hud.m_instance.m_rootObject.transform.Find("MiniMap/small");
					if ((Object)(object)val2 != (Object)null)
					{
						localPlayerVEHUD.transform.position = val2.position;
						localPlayerVEHUD.transform.localPosition = new Vector3(localPlayerVEHUD.transform.localPosition.x - 108f, localPlayerVEHUD.transform.localPosition.y - 10f);
					}
				}
			}
			if ((Object)(object)localPlayerVEHUD != (Object)null && (Object)(object)localPlayerLevelText == (Object)null)
			{
				Logger.LogDebug("Finding Level TextMeshPro component.");
				Transform val3 = localPlayerVEHUD.transform.Find("Level");
				if ((Object)(object)val3 != (Object)null)
				{
					localPlayerLevelText = ((Component)val3).GetComponent<TextMeshProUGUI>();
				}
				else
				{
					Logger.LogDebug("Could not find Level GO");
				}
			}
		}

		public static void UpdateLocalPlayerLevelDisplay(int level = 0)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			Scene activeScene = SceneManager.GetActiveScene();
			if (((Scene)(ref activeScene)).name.Equals("main"))
			{
				if (level == 0)
				{
					level = PlayerData.localPlayerConfig.PlayerLevel;
				}
				CreateLocalHudElements(GUIManager.CustomGUIFront.transform);
				SetupLocalPlayerLevelDisplay(localPlayerVEHUD, level);
			}
		}

		public static void SetupPlayerWingsDisplay(string selectedWings = null)
		{
			if (selectedWings == null || (Object)(object)Player.m_localPlayer == (Object)null)
			{
				return;
			}
			if ((Object)(object)localPlayerWings != (Object)null)
			{
				Object.Destroy((Object)(object)localPlayerWings);
			}
			if (!(selectedWings == DataObjects.None))
			{
				if (Deities.PrestigeEffects[DataObjects.PrestigeEffect.Wings].ContainsKey(selectedWings))
				{
					localPlayerWings = Object.Instantiate<GameObject>(Deities.PrestigeEffects[DataObjects.PrestigeEffect.Wings][selectedWings].EffectObject, ((Component)Player.m_localPlayer).gameObject.transform);
				}
				else
				{
					Logger.LogWarning("Selected wings " + selectedWings + " not found in Deities.PrestigeEffects");
				}
			}
		}

		public static void SetupPlayerAuraDisplay(string selectedAura = null)
		{
			if (selectedAura == null || (Object)(object)Player.m_localPlayer == (Object)null)
			{
				return;
			}
			if ((Object)(object)localPlayerAura != (Object)null)
			{
				Object.Destroy((Object)(object)localPlayerAura);
			}
			if (!(selectedAura == DataObjects.None))
			{
				if (Deities.PrestigeEffects[DataObjects.PrestigeEffect.Aura].ContainsKey(selectedAura))
				{
					localPlayerAura = Object.Instantiate<GameObject>(Deities.PrestigeEffects[DataObjects.PrestigeEffect.Aura][selectedAura].EffectObject, ((Component)Player.m_localPlayer).gameObject.transform);
				}
				else
				{
					Logger.LogWarning("Selected Aura " + selectedAura + " not found in Deities.PrestigeEffects");
				}
			}
		}

		public static void CreateEnemyHud(uint otherplayerzid, Transform targetTform, int otherplayerlevel)
		{
			Logger.LogDebug("Creating Enemy Player Hud.");
			GameObject val = ValhallEternal.EmbeddedResourceBundle.LoadAsset<GameObject>("VERemoteHud");
			GameObject val2 = Object.Instantiate<GameObject>(val, targetTform);
			((Object)val2).name = "VERemoteHud";
			Transform val3 = val2.transform.Find("Level");
			TextMeshProUGUI component = ((Component)val3).GetComponent<TextMeshProUGUI>();
			if (otherplayerlevel == 0)
			{
				val2.SetActive(false);
			}
			else
			{
				((TMP_Text)component).text = $"{otherplayerlevel}";
			}
			extendedPlayerHUDS.Add(otherplayerzid, new PrestigeLevelHUD
			{
				root = val2,
				tmpGUI = component,
				hudroot = ((Component)targetTform).gameObject
			});
		}

		public static void SetupLocalPlayerLevelDisplay(GameObject hugGUI, int levelnum)
		{
			if (levelnum == 0)
			{
				Logger.LogInfo("Player level set to zero or not set, disabling display.");
				hugGUI.SetActive(false);
				return;
			}
			hugGUI.SetActive(true);
			if ((Object)(object)localPlayerLevelText != (Object)null)
			{
				Logger.LogDebug($"Setting player HUD with level {levelnum}");
				((TMP_Text)localPlayerLevelText).text = $"{levelnum}";
			}
		}
	}
	public static class SacrificePatches
	{
		[HarmonyPatch(typeof(InventoryGui), "Awake")]
		public static class AddSacrificeUIButton
		{
			public static void Postfix(InventoryGui __instance)
			{
				//IL_0065: 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_0083: Unknown result type (might be due to invalid IL or missing references)
				//IL_00cf: Unknown result type (might be due to invalid IL or missing references)
				//IL_00d9: Expected O, but got Unknown
				if ((Object)(object)SacrificeEnableButton != (Object)null)
				{
					if ((Object)(object)Player.m_localPlayer != (Object)null)
					{
						SacrificeEnableButton.SetActive(Player.m_localPlayer.NoCostCheat());
					}
					return;
				}
				SacrificeEnableButton = GUIManager.Instance.CreateButton(Localization.instance.Localize("$ve_sacrifice_button"), ((Component)__instance.m_infoPanel).transform, new Vector2(1f, 1f), new Vector2(1f, 1f), new Vector2(-612f, -26f), 60f, 60f);
				Button component = SacrificeEnableButton.GetComponent<Button>();
				((Selectable)component).interactable = true;
				invGUISacrifice = SacrificeEnableButton.AddComponent<SacrificeUI>();
				((UnityEvent)component.onClick).AddListener(new UnityAction(invGUISacrifice.Show));
				SacrificeEnableButton.SetActive(false);
			}
		}

		[HarmonyPatch(typeof(InventoryGui), "Hide")]
		public static class HideSacrificeUI_InventoryClose
		{
			public static void Postfix()
			{
				invGUISacrifice.Hide();
			}
		}

		[HarmonyPatch(typeof(InventoryGui), "Show")]
		public static class HideSacrificeUI_InventoryOpen
		{
			public static void Postfix()
			{
				if ((Object)(object)SacrificeEnableButton != (Object)null && (Object)(object)Player.m_localPlayer != (Object)null)
				{
					SacrificeEnableButton.SetActive(Player.m_localPlayer.NoCostCheat());
				}
			}
		}

		private static SacrificeUI invGUISacrifice;

		private static GameObject SacrificeEnableButton;
	}
	internal class SacrificeUI : MonoBehaviour, Hoverable, Interactable
	{
		private GameObject SacrificePanel;

		private GameObject ScrollAreaView;

		private GameObject ScrollContentArea;

		private ToggleGroup SacrificeChoiceGroup;

		private GameObject SacrificeChoiceContainer;

		private GameObject ChoiceSelectButton;

		private GameObject ManualCloseButton;

		private GameObject DeitySelectorDropdown;

		private Text DeityName;

		private Text DeityDescription;

		private Image DeityImage;

		private Text WarningText;

		private List<Toggle> SacrificeToggleOptions = new List<Toggle>();

		private string SelectedChoice = "none";

		private Deities.Deity SelectedDeity;

		public bool enableExclusiveDeityMode;

		public Deities.Deity ExclusiveDeity;

		public void Awake()
		{
		}

		public void Update()
		{
			if (!((Object)(object)SacrificePanel == (Object)null) && SacrificePanel.activeSelf && Input.GetKeyDown((KeyCode)27))
			{
				Hide();
				GUIManager.BlockInput(false);
			}
		}

		public void Show()
		{
			if ((Object)(object)SacrificePanel == (Object)null)
			{
				CreateStaticUIObjects();
				Deities.Deity choiceList = Deities.Deity.Gefjun;
				if (enableExclusiveDeityMode)
				{
					choiceList = ExclusiveDeity;
					DeitySelectorDropdown.SetActive(false);
				}
				SetChoiceList(choiceList);
			}
			GUIManager.BlockInput(true);
			SacrificePanel.SetActive(true);
		}

		public void Hide()
		{
			if ((Object)(object)SacrificePanel != (Object)null)
			{
				SacrificePanel.SetActive(false);
			}
			GUIManager.BlockInput(false);
		}

		public void Toggle()
		{
			if ((Object)(object)SacrificePanel != (Object)null)
			{
				if (SacrificePanel.activeSelf)
				{
					Hide();
				}
				else
				{
					Show();
				}
			}
			else
			{
				Show();
			}
		}

		public void UpdateSelectedDiety(int _actionID)
		{
			Dropdown component = DeitySelectorDropdown.GetComponent<Dropdown>();
			Deities.Deity choiceList = (Deities.Deity)Enum.Parse(typeof(Deities.Deity), component.options[component.value].text);
			SetChoiceList(choiceList);
		}

		public void CompleteSacrifice()
		{
			//IL_051d: Unknown result type (might be due to invalid IL or missing references)
			//IL_051f: Unknown result type (might be due to invalid IL or missing references)
			//IL_04dd: Unknown result type (might be due to invalid IL or missing references)
			//IL_04e9: Unknown result type (might be due to invalid IL or missing references)
			if (SelectedChoice == "None")
			{
				Logger.LogWarning("No sacrifice choice selected.");
				return;
			}
			bool flag = true;
			Logger.LogInfo($"Completing sacrifice choice: {SelectedChoice} for deity {SelectedDeity}");
			DataObjects.Sacrifice sacrifice = SacrificeData.AllSacrifices[SelectedDeity][SelectedChoice];
			if (sacrifice.ItemRequirements != null)
			{
				Dictionary<string, int> itemTotalsByName = ((Humanoid)Player.m_localPlayer).m_inventory.GetItemTotalsByName();
				foreach (KeyValuePair<string, int> itemRequirement in sacrifice.ItemRequirements)
				{
					if (!itemTotalsByName.ContainsKey(itemRequirement.Key))
					{
						flag = false;
						Logger.LogDebug($"Player did not have {itemRequirement.Value} of item {itemRequirement.Key}");
						break;
					}
				}
			}
			if (sacrifice.PlayerKeyRequirements != null)
			{
				foreach (string playerKeyRequirement in sacrifice.PlayerKeyRequirements)
				{
					Logger.LogDebug("Removing unique key " + playerKeyRequirement + " from player.");
					if (!Player.m_localPlayer.PlayerHasUniqueKey(playerKeyRequirement))
					{
						flag = false;
						Logger.LogDebug("Player did not have the required key: " + playerKeyRequirement);
						break;
					}
				}
			}
			if (!flag && !Player.m_localPlayer.NoCostCheat())
			{
				Logger.LogWarning("Player did not meet the requirements, canceling.");
				WarningText.text = "Requirements not met";
				return;
			}
			Logger.LogDebug("Player has met requirements.");
			if (sacrifice.ItemRequirements != null)
			{
				foreach (KeyValuePair<string, int> itemRequirement2 in sacrifice.ItemRequirements)
				{
					Logger.LogDebug($"Removing {itemRequirement2.Value} of item {itemRequirement2.Key} from player inventory.");
					((Humanoid)Player.m_localPlayer).m_inventory.RemoveItem(itemRequirement2.Key, itemRequirement2.Value, -1, true);
				}
			}
			if (sacrifice.PlayerKeyRequirements != null)
			{
				foreach (string playerKeyRequirement2 in sacrifice.PlayerKeyRequirements)
				{
					Logger.LogDebug("Removing unique key " + playerKeyRequirement2 + " from player.");
					((Humanoid)Player.m_localPlayer).RemoveUniqueKey(playerKeyRequirement2);
				}
			}
			if (sacrifice.PlayerBoonsChanges != null)
			{
				foreach (KeyValuePair<DataObjects.Boons, float> playerBoonsChange in sacrifice.PlayerBoonsChanges)
				{
					Logger.LogDebug($"Changing player boon {playerBoonsChange.Key} by {playerBoonsChange.Value}.");
					PlayerData.AddBoonToPlayerConfig(playerBoonsChange.Key, playerBoonsChange.Value);
				}
			}
			if (sacrifice.PlayerOathChanges != null)
			{
				foreach (KeyValuePair<DataObjects.Oaths, float> playerOathChange in sacrifice.PlayerOathChanges)
				{
					Logger.LogDebug($"Changing player oath {playerOathChange.Key} by {playerOathChange.Value}.");
					PlayerData.AddOathToPlayerConfig(playerOathChange.Key, playerOathChange.Value);
				}
			}
			if (sacrifice.ResetPlayer != null)
			{
				if (sacrifice.ResetPlayer.ResetKnownRecipes)
				{
					Player.m_localPlayer.m_knownMaterial.Clear();
					Player.m_localPlayer.m_knownRecipes.Clear();
				}
				if (sacrifice.ResetPlayer.ResetSkillPercentage > 0f)
				{
					Player.m_localPlayer.m_skills.LowerAllSkills(sacrifice.ResetPlayer.ResetSkillPercentage);
				}
				if (sacrifice.ResetPlayer.PrestigeLevelsGained > 0)
				{
					PlayerData.localPlayerConfig.PlayerLevel += sacrifice.ResetPlayer.PrestigeLevelsGained;
				}
				if (sacrifice.ResetPlayer.TeleportToSpawn)
				{
					GameObject val = (from obj in Resources.FindObjectsOfTypeAll<GameObject>()
						where ((Object)obj).name == "StartTemple"
						select obj).FirstOrDefault();
					if ((Object)(object)val != (Object)null)
					{
						Logger.LogDebug("Teleporting player to start temple.");
						((Character)Player.m_localPlayer).TeleportTo(val.transform.position, val.transform.rotation, false);
					}
					else
					{
						Logger.LogWarning("Start temple not found, teleporting to spawn point instead.");
						Vector3 val2 = default(Vector3);
						bool flag2 = default(bool);
						Game.instance.FindSpawnPoint(ref val2, ref flag2, 0f);
						((Character)Player.m_localPlayer).TeleportTo(val2, Quaternion.identity, true);
					}
				}
			}
			if (sacrifice.PrestigeOptions != null)
			{
				foreach (DataObjects.PrestigeEffectDetails prestigeOption in sacrifice.PrestigeOptions)
				{
					if (prestigeOption.PlayerMeetsPrestigeRequirements())
					{
						PlayerData.AddVisualPrestigeEffectOptionToPlayerConfig(prestigeOption.EffectType, prestigeOption.EffectValue);
						Logger.LogDebug($"Adding prestige effect option {prestigeOption.EffectType} of type {prestigeOption.EffectValue} to player config.");
						PlayerData.SetActivePrestigeEffectForPlayer(prestigeOption.EffectType, prestigeOption.EffectValue);
					}
				}
			}
			WarningText.text = "";
			GUIManager.BlockInput(false);
			PlayerData.SavePlayerConfiguration();
			PlayerData.LoadPlayerConfiguration(Player.m_localPlayer);
			PrestigeDisplays.UpdateLocalPlayerLevelDisplay();
			Hide();
			UpdateSelectedDiety(-1);
			if (enableExclusiveDeityMode)
			{
				SetChoiceList(SelectedDeity);
			}
		}

		private void CreateStaticUIObjects()
		{
			//IL_0049: Unknown result type (might be due to invalid IL or missing references)
			//IL_0058: 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_0093: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a8: Expected O, but got Unknown
			//IL_00b9: 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_0130: 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_014e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0164: Unknown result type (might be due to invalid IL or missing references)
			//IL_016a: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c6: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d5: Unknown result type (might be due to invalid IL or missing references)
			//IL_01e4: Unknown result type (might be due to invalid IL or missing references)
			//IL_01f5: Unknown result type (might be due to invalid IL or missing references)
			//IL_01fb: Unknown result type (might be due to invalid IL or missing references)
			//IL_027f: Unknown result type (might be due to invalid IL or missing references)
			//IL_028e: Unknown result type (might be due to invalid IL or missing references)
			//IL_029d: Unknown result type (might be due to invalid IL or missing references)
			//IL_02b3: Unknown result type (might be due to invalid IL or missing references)
			//IL_02b9: 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_0313: 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_0333: Unknown result type (might be due to invalid IL or missing references)
			//IL_0339: Unknown result type (might be due to invalid IL or missing references)
			//IL_03a1: Unknown result type (might be due to invalid IL or missing references)
			//IL_03b0: Unknown result type (might be due to invalid IL or missing references)
			//IL_03bf: Unknown result type (might be due to invalid IL or missing references)
			//IL_03d5: Unknown result type (might be due to invalid IL or missing references)
			//IL_03db: Unknown result type (might be due to invalid IL or missing references)
			//IL_0436: Unknown result type (might be due to invalid IL or missing references)
			//IL_0445: Unknown result type (might be due to invalid IL or missing references)
			//IL_0454: Unknown result type (might be due to invalid IL or missing references)
			//IL_0491: Unknown result type (might be due to invalid IL or missing references)
			//IL_049b: Expected O, but got Unknown
			//IL_04c6: Unknown result type (might be due to invalid IL or missing references)
			//IL_04d5: Unknown result type (might be due to invalid IL or missing references)
			//IL_04e4: Unknown result type (might be due to invalid IL or missing references)
			//IL_0518: Unknown result type (might be due to invalid IL or missing references)
			//IL_0522: Expected O, but got Unknown
			//IL_0550: Unknown result type (might be due to invalid IL or missing references)
			//IL_0555: Unknown result type (might be due to invalid IL or missing references)
			//IL_057b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0599: Unknown result type (might be due to invalid IL or missing references)
			//IL_059b: Unknown result type (might be due to invalid IL or missing references)
			//IL_05fe: Unknown result type (might be due to invalid IL or missing references)
			//IL_060d: Unknown result type (might be due to invalid IL or missing references)
			//IL_061c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0684: Unknown result type (might be due to invalid IL or missing references)
			//IL_0699: Expected O, but got Unknown
			//IL_0756: Unknown result type (might be due to invalid IL or missing references)
			//IL_076b: Expected O, but got Unknown
			//IL_07ef: Unknown result type (might be due to invalid IL or missing references)
			//IL_08b5: Unknown result type (might be due to invalid IL or missing references)
			//IL_08c4: Unknown result type (might be due to invalid IL or missing references)
			//IL_08d3: Unknown result type (might be due to invalid IL or missing references)
			//IL_08e9: Unknown result type (might be due to invalid IL or missing references)
			//IL_08ef: Unknown result type (might be due to invalid IL or missing references)
			//IL_0924: Unknown result type (might be due to invalid IL or missing references)
			//IL_0971: Unknown result type (might be due to invalid IL or missing references)
			//IL_0980: Unknown result type (might be due to invalid IL or missing references)
			//IL_098f: Unknown result type (might be due to invalid IL or missing references)
			//IL_09a5: Unknown result type (might be due to invalid IL or missing references)
			//IL_09ab: Unknown result type (might be due to invalid IL or missing references)
			//IL_0a28: Unknown result type (might be due to invalid IL or missing references)
			//IL_0a37: Unknown result type (might be due to invalid IL or missing references)
			//IL_0a46: Unknown result type (might be due to invalid IL or missing references)
			//IL_0a57: Unknown result type (might be due to invalid IL or missing references)
			//IL_0a5d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0ac0: Unknown result type (might be due to invalid IL or missing references)
			//IL_0ad5: Expected O, but got Unknown
			//IL_0afa: Unknown result type (might be due to invalid IL or missing references)
			//IL_0b35: Unknown result type (might be due to invalid IL or missing references)
			//IL_0b4a: Expected O, but got Unknown
			//IL_0bba: Unknown result type (might be due to invalid IL or missing references)
			if (GUIManager.Instance == null || !Object.op_Implicit((Object)(object)GUIManager.CustomGUIFront))
			{
				Logger.LogWarning("GUIManager not setup, skipping static object creation.");
				return;
			}
			SacrificePanel = GUIManager.Instance.CreateWoodpanel(GUIManager.CustomGUIFront.transform, new Vector2(0.5f, 0.5f), new Vector2(0.5f, 0.5f), new Vector2(0f, 0f), 800f, 800f, true);
			SacrificePanel.SetActive(false);
			GameObject val = Object.Instantiate<GameObject>(new GameObject("DeityImage"), SacrificePanel.transform);
			val.transform.localPosition = new Vector3(-323f, 323f);
			DeityImage = val.AddComponent<Image>();
			val.GetComponent<RectTransform>().sizeDelta = new Vector2(125f, 125f);
			DeityImage.sprite = Deities.DeityConfiguration[Deities.Deity.Gefjun].Image;
			GameObject val2 = GUIManager.Instance.CreateText(Localization.instance.Localize("$ve_header_gefjun"), SacrificePanel.transform, new Vector2(0.5f, 0.5f), new Vector2(0.5f, 0.5f), new Vector2(11f, 360f), GUIManager.Instance.AveriaSerifBold, 20, GUIManager.Instance.ValheimYellow, true, Color.black, 350f, 40f, false);
			DeityName = val2.GetComponent<Text>();
			((Object)DeityName).name = "DeityName";
			GameObject val3 = GUIManager.Instance.CreateText(Localization.instance.Localize("$ve_description_gefjun"), SacrificePanel.transform, new Vector2(0.5f, 0.5f), new Vector2(0.5f, 0.5f), new Vector2(-110f, 325f), GUIManager.Instance.AveriaSerif, 14, Color.white, true, Color.black, 300f, 80f, false);
			DeityDescription = val3.GetComponent<Text>();
			DeityDescription.resizeTextForBestFit = true;
			DeityDescription.resizeTextMaxSize = 20;
			DeityDescription.alignment = (TextAnchor)4;
			((Object)DeityDescription).name = "DeityDesc";
			GameObject val4 = GUIManager.Instance.CreateText(Localization.instance.Localize("$ve_sacrifice_header"), SacrificePanel.transform, new Vector2(0.5f, 0.5f), new Vector2(0.5f, 0.5f), new Vector2(275f, 305f), GUIManager.Instance.AveriaSerifBold, 30, GUIManager.Instance.ValheimOrange, true, Color.black, 350f, 40f, false);
			((Object)val4).name = "Sacrifice";
			GameObject val5 = GUIManager.Instance.CreateText(Localization.instance.Localize("$ve_sacrifice_header_desc"), SacrificePanel.transform, new Vector2(0.5f, 0.5f), new Vector2(0.5f, 0.5f), new Vector2(6f, 217f), GUIManager.Instance.AveriaSerif, 20, Color.white, true, Color.black, 730f, 80f, false);
			((Object)val5).name = "SacrificeDesc";
			Text component = val5.GetComponent<Text>();
			component.resizeTextForBestFit = true;
			component.resizeTextMaxSize = 20;
			component.alignment = (TextAnchor)0;
			GameObject val6 = GUIManager.Instance.CreateText("", SacrificePanel.transform, new Vector2(0.5f, 0.5f), new Vector2(0.5f, 0.5f), new Vector2(335f, -350f), GUIManager.Instance.AveriaSerifBold, 14, GUIManager.Instance.ValheimYellow, true, Color.black, 250f, 40f, false);
			((Object)val6).name = "Warning";
			WarningText = val6.GetComponent<Text>();
			ManualCloseButton = GUIManager.Instance.CreateButton(Localization.instance.Localize("$ve_close"), SacrificePanel.transform, new Vector2(0.5f, 0.5f), new Vector2(0.5f, 0.5f), new Vector2(360f, 360f), 60f, 60f);
			Button component2 = ManualCloseButton.GetComponent<Button>();
			((Selectable)component2).interactable = true;
			((UnityEvent)component2.onClick).AddListener(new UnityAction(Hide));
			ChoiceSelectButton = GUIManager.Instance.CreateButton(Localization.instance.Localize("$ve_sacrifice_sealed"), SacrificePanel.transform, new Vector2(0.5f, 0.5f), new Vector2(0.5f, 0.5f), new Vector2(0f, -350f), 300f, 60f);
			Button component3 = ChoiceSelectButton.GetComponent<Button>();
			((UnityEvent)component3.onClick).AddListener(new UnityAction(CompleteSacrifice));
			Logger.LogDebug("Setting up scroll entry");
			ScrollAreaView = GUIManager.Instance.CreateScrollView(SacrificePanel.transform, false, true, 10f, 10f, GUIManager.Instance.ValheimScrollbarHandleColorBlock, Color.grey, 750f, 500f);
			ScrollAreaView.transform.localPosition = Vector2.op_Implicit(new Vector2
			{
				x = 0f,
				y = -68f
			});
			ScrollAreaView.GetComponentInChildren<ScrollRect>().scrollSensitivity = 1000f;
			ScrollContentArea = ((Component)ScrollAreaView.GetComponentInChildren<ContentSizeFitter>()).gameObject;
			SacrificeChoiceGroup = ScrollContentArea.AddComponent<ToggleGroup>();
			DeitySelectorDropdown = GUIManager.Instance.CreateDropDown(SacrificePanel.transform, new Vector2(0.5f, 0.5f), new Vector2(0.5f, 0.5f), new Vector2(200f, 357f), 18, 200f, 40f);
			Dropdown component4 = DeitySelectorDropdown.GetComponent<Dropdown>();
			component4.AddOptions(Deities.DeityOptions());
			component4.value = 2;
			((UnityEvent<int>)(object)component4.onValueChanged).AddListener((UnityAction<int>)UpdateSelectedDiety);
			Logger.LogDebug("Setting Template");
			SacrificeChoiceContainer = Object.Instantiate<GameObject>(new GameObject("ChoiceTemplate"), SacrificePanel.transform);
			VerticalLayoutGroup val7 = SacrificeChoiceContainer.AddComponent<VerticalLayoutGroup>();
			((LayoutGroup)val7).childAlignment = (TextAnchor)3;
			((HorizontalOrVerticalLayoutGroup)val7).childControlHeight = true;
			((HorizontalOrVerticalLayoutGroup)val7).spacing = 5f;
			((HorizontalOrVerticalLayoutGroup)val7).childForceExpandHeight = false;
			if ((Object)(object)SacrificeChoiceContainer.GetComponent<RectTransform>() == (Object)null)
			{
				SacrificeChoiceContainer.AddComponent<RectTransform>();
			}
			SacrificeChoiceContainer.layer = 5;
			RectTransform component5 = SacrificeChoiceContainer.GetComponent<RectTransform>();
			component5.SetSizeWithCurrentAnchors((Axis)0, 760f);
			component5.SetSizeWithCurrentAnchors((Axis)1, 300f);
			ContentSizeFitter val8 = SacrificeChoiceContainer.AddComponent<ContentSizeFitter>();
			val8.verticalFit = (FitMode)2;
			SacrificeChoiceContainer.SetActive(false);
			GameObject val9 = Object.Instantiate<GameObject>(new GameObject("ChoiceHeader"), SacrificeChoiceContainer.transform);
			((Object)val9).name = "ChoiceHeader";
			HorizontalLayoutGroup val10 = val9.AddComponent<HorizontalLayoutGroup>();
			((HorizontalOrVerticalLayoutGroup)val10).childForceExpandHeight = false;
			((HorizontalOrVerticalLayoutGroup)val10).childForceExpandWidth = false;
			((HorizontalOrVerticalLayoutGroup)val10).childControlWidth = true;
			LayoutElement val11 = val9.AddComponent<LayoutElement>();
			val11.minHeight = 40f;
			GameObject val12 = GUIManager.Instance.CreateToggle(val9.transform, 40f, 40f);
			((Object)val12).name = "selecter";
			val12.transform.localPosition = new Vector3(-370f, 10f);
			((Component)val12.transform.Find("Label")).gameObject.SetActive(false);
			val12.GetComponent<Toggle>().isOn = false;
			LayoutElement val13 = val12.AddComponent<LayoutElement>();
			val13.minWidth = 45f;
			HorizontalLayoutGroup val14 = val12.AddComponent<HorizontalLayoutGroup>();
			((HorizontalOrVerticalLayoutGroup)val14).childForceExpandHeight = false;
			((HorizontalOrVerticalLayoutGroup)val14).childForceExpandWidth = false;
			((HorizontalOrVerticalLayoutGroup)val14).childControlWidth = true;
			GameObject gameObject = ((Component)val12.transform.Find("Background")).gameObject;
			LayoutElement val15 = gameObject.AddComponent<LayoutElement>();
			val15.minHeight = 40f;
			val15.minWidth = 40f;
			GameObject val16 = GUIManager.Instance.CreateText("Name", val9.transform, new Vector2(0.5f, 0.5f), new Vector2(0.5f, 0.5f), new Vector2(0f, 0f), GUIManager.Instance.AveriaSerifBold, 30, GUIManager.Instance.ValheimOrange, true, Color.black, 660f, 80f, false);
			((Object)val16).name = "ChoiceName";
			val16.transform.localPosition = new Vector3(-240f, -10f);
			LayoutElement val17 = val16.AddComponent<LayoutElement>();
			val17.flexibleHeight = 900f;
			val17.minHeight = 40f;
			GameObject val18 = GUIManager.Instance.CreateText("Desc", SacrificeChoiceContainer.transform, new Vector2(0.5f, 0.5f), new Vector2(0.5f, 0.5f), new Vector2(16f, 40f), GUIManager.Instance.AveriaSerif, 20, GUIManager.Instance.ValheimBeige, true, Color.black, 660f, 80f, false);
			((Object)val18).name = "ChoiceDesc";
			LayoutElement val19 = val18.AddComponent<LayoutElement>();
			val19.flexibleHeight = 900f;
			VerticalLayoutGroup val20 = val18.AddComponent<VerticalLayoutGroup>();
			((HorizontalOrVerticalLayoutGroup)val20).childForceExpandHeight = false;
			((HorizontalOrVerticalLayoutGroup)val20).childForceExpandWidth = false;
			((HorizontalOrVerticalLayoutGroup)val20).childControlWidth = true;
			GameObject val21 = GUIManager.Instance.CreateText("Description", SacrificeChoiceContainer.transform, new Vector2(0.5f, 0.5f), new Vector2(0.5f, 0.5f), new Vector2(16f, -40f), GUIManager.Instance.AveriaSerif, 20, Color.white, true, Color.black, 660f, 80f, false);
			((Object)val21).name = "RequirementDesc";
			LayoutElement val22 = val21.AddComponent<LayoutElement>();
			val22.flexibleHeight = 900f;
			VerticalLayoutGroup val23 = val21.AddComponent<VerticalLayoutGroup>();
			((HorizontalOrVerticalLayoutGroup)val23).childForceExpandHeight = false;
			((HorizontalOrVerticalLayoutGroup)val23).childForceExpandWidth = false;
			((HorizontalOrVerticalLayoutGroup)val23).childControlWidth = true;
			GameObject val24 = Object.Instantiate<GameObject>(new GameObject("ItemRequirements"), SacrificeChoiceContainer.transform);
			((Object)val24).name = "ItemRequirements";
			val24.transform.localPosition = new Vector3(-300f, 30f, 0f);
			val24.AddComponent<RectTransform>();
			val24.AddComponent<LayoutElement>();
			HorizontalLayoutGroup val25 = val24.AddComponent<HorizontalLayoutGroup>();
			((HorizontalOrVerticalLayoutGroup)val25).childForceExpandHeight = false;
			((HorizontalOrVerticalLayoutGroup)val25).childForceExpandWidth = false;
			GameObject val26 = Object.Instantiate<GameObject>(new GameObject("ChoiceFooter"), SacrificeChoiceContainer.transform);
			((Object)val26).name = "ChoiceFooter";
			LayoutElement val27 = val26.AddComponent<LayoutElement>();
			val27.minHeight = 50f;
			VerticalLayoutGroup val28 = val26.AddComponent<VerticalLayoutGroup>();
			((HorizontalOrVerticalLayoutGroup)val28).childForceExpandHeight = false;
			((HorizontalOrVerticalLayoutGroup)val28).childForceExpandWidth = false;
			((HorizontalOrVerticalLayoutGroup)val28).childControlWidth = true;
			Image val29 = val26.AddComponent<Image>();
			val29.sprite = DataObjects.boonbackground;
			((Component)val29).GetComponent<RectTransform>().sizeDelta = new Vector2(512f, 50f);
		}

		private void SetChoiceList(Deities.Deity selectedDiety)
		{
			//IL_0334: Unknown result type (might be due to invalid IL or missing references)
			//IL_034f: Unknown result type (might be due to invalid IL or missing references)
			//IL_04cc: Unknown result type (might be due to invalid IL or missing references)
			//IL_04d8: Expected O, but got Unknown
			//IL_04f4: Unknown result type (might be due to invalid IL or missing references)
			//IL_055d: Unknown result type (might be due to invalid IL or missing references)
			//IL_056c: Unknown result type (might be due to invalid IL or missing references)
			//IL_057b: Unknown result type (might be due to invalid IL or missing references)
			//IL_058c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0592: Unknown result type (might be due to invalid IL or missing references)
			//IL_05e6: Unknown result type (might be due to invalid IL or missing references)
			//IL_0600: Unknown result type (might be due to invalid IL or missing references)
			DeityName.text = Localization.instance.Localize(Deities.DeityConfiguration[selectedDiety].NameLocalKey);
			DeityDescription.text = Localization.instance.Localize(Deities.DeityConfiguration[selectedDiety].DescriptionLocalKey);
			DeityImage.sprite = Deities.DeityConfiguration[selectedDiety].Image;
			SacrificeToggleOptions.Clear();
			while (ScrollContentArea.transform.childCount > 0)
			{
				Transform child = ScrollContentArea.transform.GetChild(0);
				if ((Object)(object)child == (Object)null)
				{
					break;
				}
				Object.DestroyImmediate((Object)(object)((Component)child).gameObject);
			}
			SelectedDeity = selectedDiety;
			int num = -40;
			ItemDrop val3 = default(ItemDrop);
			foreach (KeyValuePair<string, DataObjects.Sacrifice> entry in SacrificeData.AllSacrifices[selectedDiety])
			{
				bool flag = true;
				bool flag2 = true;
				bool flag3 = true;
				if ((Object)(object)Player.m_localPlayer != (Object)null && (Object)(object)ZoneSystem.instance != (Object)null)
				{
					if (entry.Value.PlayerKeyRequirements != null)
					{
						foreach (string playerKeyRequirement in entry.Value.PlayerKeyRequirements)
						{
							if (!ZoneSystem.instance.GetGlobalKey(playerKeyRequirement) && !Player.m_localPlayer.PlayerHasUniqueKey(playerKeyRequirement))
							{
								flag = false;
								break;
							}
						}
					}
					float BoonValue;
					if (entry.Value.PlayerBoonRequirements != null)
					{
						foreach (KeyValuePair<DataObjects.Boons, float> playerBoonRequirement in entry.Value.PlayerBoonRequirements)
						{
							if (!PlayerData.localPlayerConfig.HasBoon(playerBoonRequirement.Key, out BoonValue))
							{
								flag2 = false;
								break;
							}
						}
					}
					if (entry.Value.PlayerOathRequirements != null)
					{
						foreach (KeyValuePair<DataObjects.Oaths, float> playerOathRequirement in entry.Value.PlayerOathRequirements)
						{
							if (!PlayerData.localPlayerConfig.HasOath(playerOathRequirement.Key, out BoonValue))
							{
								flag3 = false;
								break;
							}
						}
					}
				}
				if ((!flag && ValConfig.KeyRequirementsHideChoices.Value) || (!flag2 && ValConfig.BoonRequirementsHideChoices.Value) || (!flag3 && ValConfig.OathRequirementsHideChoices.Value))
				{
					continue;
				}
				GameObject val = Object.Instantiate<GameObject>(SacrificeChoiceContainer, ScrollContentArea.transform);
				val.SetActive(true);
				RectTransform component = val.GetComponent<RectTransform>();
				((Transform)component).localPosition = new Vector3
				{
					x = 250f,
					y = num
				};
				((Component)val.transform.Find("ChoiceHeader/ChoiceName")).GetComponent<Text>().text = entry.Value.Name;
				((Object)val).name = "choice_" + entry.Value.Name;
				((Component)val.transform.Find("ChoiceDesc")).GetComponent<Text>().text = entry.Value.Description;
				((Component)val.transform.Find("RequirementDesc")).GetComponent<Text>().text = entry.Value.GetTotalDescription();
				if (entry.Value.ItemRequirements != null)
				{
					Transform val2 = val.transform.Find("ItemRequirements");
					if ((Object)(object)val2 == (Object)null)
					{
						Logger.LogWarning("Item requirements parent not found.");
					}
					int num2 = 0;
					foreach (KeyValuePair<string, int> itemRequirement in entry.Value.ItemRequirements)
					{
						GameObject prefab = PrefabManager.Instance.GetPrefab(itemRequirement.Key);
						if ((Object)(object)prefab != (Object)null)
						{
							prefab.TryGetComponent<ItemDrop>(ref val3);
							if ((Object)(object)val3 != (Object)null)
							{
								GameObject val4 = Object.Instantiate<GameObject>(new GameObject("ReqItem_" + itemRequirement.Key), val2);
								Image val5 = val4.AddComponent<Image>();
								val4.GetComponent<RectTransform>().sizeDelta = new Vector2(50f, 50f);
								LayoutElement val6 = val4.AddComponent<LayoutElement>();
								val6.minHeight = 50f;
								val6.minWidth = 50f;
								val5.sprite = val3.m_itemData.GetIcon();
								GameObject val7 = GUIManager.Instance.CreateText($"{itemRequirement.Value}", val2, new Vector2(0.5f, 0.5f), new Vector2(0.5f, 0.5f), new Vector2(-10f, 360f), GUIManager.Instance.AveriaSerifBold, 14, Color.grey, true, Color.black, 40f, 40f, false);
								Logger.LogDebug("Added Text.");
								LayoutElement val8 = val7.AddComponent<LayoutElement>();
								val8.minHeight = 10f;
								val8.minWidth = 10f;
								val7.transform.localPosition = new Vector3((float)num2, 0f);
								val4.transform.localPosition = new Vector3((float)num2, 0f);
								num2 += 45;
							}
						}
					}
				}
				Toggle component2 = ((Component)val.transform.Find("ChoiceHeader/selecter")).GetComponent<Toggle>();
				component2.group = SacrificeChoiceGroup;
				((UnityEvent<bool>)(object)component2.onValueChanged).AddListener((UnityAction<bool>)delegate
				{
					SelectedChoice = entry.Key;
				});
				SacrificeToggleOptions.Add(component2);
				num -= 180;
			}
		}

		public bool Interact(Humanoid user, bool hold, bool alt)
		{
			Toggle();
			return true;
		}

		public bool UseItem(Humanoid user, ItemData item)
		{
			return false;
		}

		public string GetHoverText()
		{
			return Localization.instance.Localize("[<color=yellow><b>$KEY_Use</b></color>] $ve_shrine_of_the_gods");
		}

		public string GetHoverName()
		{
			return Localization.instance.Localize("$ve_tribute_shrine");
		}
	}
}
namespace ValhallEternal.common
{
	public static class DataObjects
	{
		public enum DisplayStyle
		{
			Numeric,
			Roman,
			Nordic
		}

		public enum PrestigeEffect
		{
			Wings,
			Footprints,
			Aura,
			LevelColor,
			Title
		}

		public enum Oaths
		{
			DamageTakenIncrease,
			DealLessBluntDamage,
			DealLessPierceDamage,
			DealLessSlashDamage,
			DealLessAllDamage,
			LowerSkillGainBow,
			LowerSkillGainSword,
			LowerSkillGainClub,
			LowerSkillGainPolearms,
			LowerSkillGainKnives,
			LowerSkillGainRun,
			LowerSkillGainSneak,
			LowerSkillGainBloodMagic,
			LowerSkillGainElementalMagic,
			LowerSkillGainCrossbow,
			LowerSkillGainSpears,
			LowerSkillGainAxes,
			ReducePlayerHealthPercent,
			ReducePlayerStaminaPercent,
			ReducePlayerEitrPercent,
			ReducePlayerCarryWeight,
			NoBows,
			NoCrossbows
		}

		public enum Boons
		{
			IncreasePickableYields,
			SeedsGrowEverywhere,
			QualityNourishment,
			FishingProsperity,
			GefjunFeasts,
			RandomXPBonus,
			KnowledgeIsPower,
			HuntressArrowReturn,
			SwiftShadow,
			PowerfulShield,
			ExtraLoot,
			IncreaseEitrRegen,
			IncreaseStaminaRegen,
			ReturnStaminaOnDamage,
			ReturnEitrOnDamage,
			ReduceDodgeCost,
			BladeboundKnowledge,
			StormboundRage,
			IncreaseBaseEitr,
			IncreaseBaseStamina,
			IncreaseHeatResistance,
			MovementSpeedOnKill,
			ReduceWet,
			IncreaseMeleeDamage,
			Everwatchful,
			BrutalDefiance,
			DamageAgainstUndead,
			StrongerBlock,
			StrongerTowerBlock,
			DedicationToTheBlade,
			WealthOfAges,
			BuiltDifferent,
			GoddessOfWar,
			SeidrOfPlenty,
			PerfectForm,
			BalanceOfTheJotunn,
			BalanceOfTheAesir,
			HastenTheInevitable,
			ReduceFirePoison,
			HungerForKnowledge,
			BasicProtection,
			ArrowCatcher
		}

		public interface IProbability
		{
			string Name { get; set; }

			float SelectionWeight { get; set; }
		}

		public class LevelTextGradiant
		{
			public string TopLeft { get; set; }

			public string BottomLeft { get; set; }

			public string TopRight { get; set; }

			public string BottomRight { get; set; }
		}

		public class PlayerLevelConfiguration
		{
			public LevelTextGradiant TextColors { get; set; }

			public DisplayStyle DisplayStyle { get; set; }

			public int Level { get; set; }

			public Dictionary<Oaths, float> DifficultyOaths { get; set; }

			public Dictionary<Boons, float> DifficultyBoons { get; set; }
		}

		public class CompositePlayerConfig
		{
			public int PlayerLevel { get; set; } = 0;


			public bool ReduceSkillGainsActive { get; set; } = false;


			public bool DealReductedDamageActive { get; set; } = false;


			public Dictionary<Oaths, float> TotalOaths { get; set; } = new Dictionary<Oaths, float>();


			public Dictionary<Boons, float> TotalBoons { get; set; } = new Dictionary<Boons, float>();


			public Dictionary<PrestigeEffect, string> ActiveEffectsForPlayer { get; set; } = new Dictionary<PrestigeEffect, string>();


			public Dictionary<PrestigeEffect, List<string>> AvailableEffectsForPlayer { get; set; } = new Dictionary<PrestigeEffect, List<string>>
			{
				{
					PrestigeEffect.Wings,
					new List<string> { None }
				},
				{
					PrestigeEffect.Aura,
					new List<string> { None }
				}
			};


			public bool HasOath(Oaths oath, out float OathValue)
			{
				OathValue = 0f;
				if (TotalOaths.ContainsKey(oath))
				{
					OathValue = TotalOaths[oath];
					return true;
				}
				return false;
			}

			public bool HasOath(Oaths oath)
			{
				if (TotalOaths.ContainsKey(oath))
				{
					return true;
				}
				return false;
			}

			public bool HasBoon(Boons boon, out float BoonValue)
			{
				BoonValue = 0f;
				if (TotalBoons.ContainsKey(boon))
				{
					BoonValue = TotalBoons[boon];
					return true;
				}
				return false;
			}

			public bool HasBoon(Boons boon)
			{
				if (TotalBoons.ContainsKey(boon))
				{
					return true;
				}
				return false;
			}
		}

		[Serializable]
		public class PlayerLevelData
		{
			[DataMember]
			public int PlayerLevel { get; set; }

			[DataMember]
			public Dictionary<Oaths, float> PlayerOaths { get; set; }

			[DataMember]
			public Dictionary<Boons, float> PlayerBoons { get; set; }

			[DataMember]
			public Dictionary<PrestigeEffect, string> ActiveEffectsForPlayer { get; set; }

			[DataMember]
			public Dictionary<PrestigeEffect, List<string>> AvailableEffectsForPlayer { get; set; }
		}

		public class PlayerResetData
		{
			public float ResetSkillPercentage { get; set; } = 0.5f;


			public bool ResetKnownRecipes { get; set; } = true;


			public bool TeleportToSpawn { get; set; } = false;


			public int PrestigeLevelsGained { get; set; } = 1;

		}

		public class PrestigeEffectDetails
		{
			public int LevelRequirement { get; set; }

			public Dictionary<Oaths, float> PlayerOathRequirements { get; set; }

			public Dictionary<Boons, float> PlayerBoonRequirements { get; set; }

			public PrestigeEffect EffectType { get; set; }

			public string EffectValue { get; set; }

			public bool PlayerMeetsPrestigeRequirements()
			{
				bool result = false;
				bool flag = false;
				bool flag2 = false;
				if (PlayerBoonRequirements != null && PlayerBoonRequirements.Count > 0)
				{
					foreach (KeyValuePair<Boons, float> playerBoonRequirement in PlayerBoonRequirements)
					{
						if (PlayerData.HasBoonWithValue(playerBoonRequirement.Key, out var value) && value > playerBoonRequirement.Value)
						{
							flag = true;
						}
					}
				}
				else
				{
					flag = true;
				}
				if (PlayerOathRequirements != null && PlayerOathRequirements.Count > 0)
				{
					foreach (KeyValuePair<Oaths, float> playerOathRequirement in PlayerOathRequirements)
					{
						if (PlayerData.HasOathWithValue(playerOathRequirement.Key, out var value2) && value2 > playerOathRequirement.Value)
						{
							flag2 = true;
						}
					}
				}
				else
				{
					flag2 = true;
				}
				if (LevelRequirement <= PlayerData.localPlayerConfig.PlayerLevel && flag && flag2)
				{
					result = true;
				}
				return result;
			}
		}

		[Serializable]
		public class Sacrifice
		{
			public string Name { get; set; }

			public string Description { get; set; }

			public PlayerResetData ResetPlayer { get; set; }

			public Dictionary<string, int> ItemRequirements { get; set; }

			public List<string> PlayerKeyRequirements { get; set; }

			public Dictionary<Oaths, float> PlayerOathRequirements { get; set; }

			public Dictionary<Boons, float> PlayerBoonRequirements { get; set; }

			[DataMember]
			public Dictionary<Oaths, float> PlayerOathChanges { get; set; }

			[DataMember]
			public Dictionary<Boons, float> PlayerBoonsChanges { get; set; }

			public List<PrestigeEffectDetails> PrestigeOptions { get; set; }

			public string GetPlayerRequirementsDescription(bool includeOathsInDescription = true, bool includeBoonsInDescription = true, bool includeKeysInDescription = false, bool includeItemReference = true)
			{
				StringBuilder stringBuilder = new StringBuilder();
				if ((PlayerOathRequirements != null && PlayerOathRequirements.Count > 0) || (PlayerBoonRequirements != null && PlayerBoonRequirements.Count > 0) || (PlayerKeyRequirements != null && PlayerKeyRequirements.Count > 0))
				{
					stringBuilder.AppendLine(Localization.instance.Localize("$ve_requires"));
				}
				if (includeOathsInDescription && PlayerOathRequirements != null && PlayerOathRequirements.Count > 0)
				{
					foreach (KeyValuePair<Oaths, float> playerOathRequirement in PlayerOathRequirements)
					{
						stringBuilder.AppendLine(Localization.instance.Localize(string.Format("{0} <color={1}>-($ve_oath)-</color> $ve_level_required {2}", LocalizeOath(playerOathRequirement.Key), "#ff4040", playerOathRequirement.Value)));
					}
				}
				if (stringBuilder.Length > 0)
				{
					stringBuilder.AppendLine("");
				}
				if (includeBoonsInDescription && PlayerBoonRequirements != null && PlayerBoonRequirements.Count > 0)
				{
					foreach (KeyValuePair<Boons, float> playerBoonRequirement in PlayerBoonRequirements)
					{
						stringBuilder.AppendLine(Localization.instance.Localize(string.Format("{0} <color={1}>-($ve_boon)-</color> $ve_level_required {2}", LocalizeBoon(playerBoonRequirement.Key), "#b9f2ff", playerBoonRequirement.Value)));
					}
					stringBuilder.AppendLine("");
				}
				if (includeKeysInDescription && PlayerKeyRequirements != null && PlayerKeyRequirements.Count > 0)
				{
					foreach (string playerKeyRequirement in PlayerKeyRequirements)
					{
						stringBuilder.AppendLine(Localization.instance.Localize("$ve_playerkey " + playerKeyRequirement));
					}
					stringBuilder.AppendLine("");
				}
				if (includeItemReference && ItemRequirements != null && ItemRequirements.Count > 0)
				{
					stringBuilder.AppendLine(Localization.instance.Localize("$ve_item_req"));
				}
				return stringBuilder.ToString();
			}

			public string GetChangesGrantedDescription()
			{
				StringBuilder stringBuilder = new StringBuilder();
				if (PrestigeOptions != null && PrestigeOptions.Count > 0)
				{
					foreach (PrestigeEffectDetails prestigeOption in PrestigeOptions)
					{
						if (!PlayerData.PlayerHasPrestigeEffect(prestigeOption.EffectType, prestigeOption.EffectValue) && prestigeOption.PlayerMeetsPrestigeRequirements())
						{
							switch (prestigeOption.EffectType)
							{
							case PrestigeEffect.Wings:
								stringBuilder.AppendLine(Localization.instance.Localize("$ve_prestige_wings_granted $ve_" + prestigeOption.EffectValue + "_local") ?? "");
								break;
							case PrestigeEffect.Footprints:
								stringBuilder.AppendLine(Localization.instance.Localize("$ve_prestige_footprints_granted $ve_" + prestigeOption.EffectValue + "_local") ?? "");
								break;
							case PrestigeEffect.Aura:
								stringBuilder.AppendLine(Localization.instance.Localize("$ve_prestige_aura_granted $ve_" + prestigeOption.EffectValue + "_local") ?? "");
								break;
							case PrestigeEffect.LevelColor:
								stringBuilder.AppendLine(Localization.instance.Localize("$ve_prestige_levelcolor_granted $ve_" + prestigeOption.EffectValue + "_local") ?? "");
								break;
							case PrestigeEffect.Title:
								stringBuilder.AppendLine(Localization.instance.Localize("$ve_prestige_title_granted $ve_" + prestigeOption.EffectValue + "_local") ?? "");
								break;
							}
						}
					}
				}
				if (PlayerOathChanges != null && PlayerOathChanges.Count > 0)
				{
					if (stringBuilder.Length > 0)
					{
						stringBuilder.AppendLine("");
					}
					stringBuilder.AppendLine(Localization.instance.Localize("$ve_oath_changes") ?? "");
					foreach (KeyValuePair<Oaths, float> playerOathChange in PlayerOathChanges)
					{
						if (playerOathChange.Value > 0f)
						{
							stringBuilder.AppendLine(Localization.instance.Localize(string.Format("  « <size=18>{0}</size> <color={1}>+{2}</color> | {3}\n", LocalizeOath(playerOathChange.Key), "#b9f2ff", playerOathChange.Value, LocalizeOathDesc(playerOathChange.Key, playerOathChange.Value))));
						}
						else
						{
							stringBuilder.AppendLine(Localization.instance.Localize(string.Format("  « <size=18>{0}</size> <color={1}>-{2}</color> | {3}\n", LocalizeOath(playerOathChange.Key), "#ff4040", playerOathChange.Value, LocalizeOathDesc(playerOathChange.Key, playerOathChange.Value))));
						}
					}
				}
				if (PlayerBoonsChanges != null && PlayerBoonsChanges.Count > 0)
				{
					if (PlayerOathChanges != null && PlayerOathChanges.Count > 0)
					{
						stringBuilder.AppendLine("");
					}
					stringBuilder.AppendLine(Localization.instance.Localize("$ve_boon_changes") ?? "");
					foreach (KeyValuePair<Boons, float> playerBoonsChange in PlayerBoonsChanges)
					{
						if (playerBoonsChange.Value > 0f)
						{
							stringBuilder.AppendLine(Localization.instance.Localize(string.Format("  » <size=18>{0}</size> <color={1}>+{2}</color> | {3}\n", LocalizeBoon(playerBoonsChange.Key), "#b9f2ff", playerBoonsChange.Value, LocalizeBoonDesc(playerBoonsChange.Key))));
						}
						else
						{
							stringBuilder.AppendLine(Localization.instance.Localize(string.Format("  » <size=18>{0}</size> <color={1}>-{2}</color> | {3}\n", LocalizeBoon(playerBoonsChange.Key), "#ff4040", playerBoonsChange.Value, LocalizeBoonDesc(playerBoonsChange.Key))));
						}
					}
				}
				return stringBuilder.ToString();
			}

			public string GetResetDetails()
			{
				StringBuilder stringBuilder = new StringBuilder();
				if (ResetPlayer != null)
				{
					stringBuilder.AppendLine(Localization.instance.Localize("$ve_this_prestige"));
					if (ResetPlayer.ResetSkillPercentage > 0f)
					{
						stringBuilder.AppendLine(Localization.instance.Localize(string.Format("$ve_skill_decrease <color={0}>{1}%</color>", "#ff4040", ResetPlayer.ResetSkillPercentage * 100f)));
					}
					if (ResetPlayer.ResetKnownRecipes)
					{
						stringBuilder.AppendLine(Localization.instance.Localize("$ve_forget_all_recipes"));
					}
					if (ResetPlayer.TeleportToSpawn)
					{
						stringBuilder.AppendLine(Localization.instance.Localize("$ve_teleport_to_spawn"));
					}
					if (ResetPlayer.PrestigeLevelsGained > 0)
					{
						stringBuilder.AppendLine(Localization.instance.Localize(string.Format("$ve_you_gain <color={0}>{1}</color> $ve_prestige_levels", "#b9f2ff", ResetPlayer.PrestigeLevelsGained)));
					}
					if (ResetPlayer.PrestigeLevelsGained < 0)
					{
						stringBuilder.AppendLine(Localization.instance.Localize(string.Format("$ve_you_loose <color={0}>{1}</color> $ve_prestige_levels", "#ff4040", ResetPlayer.PrestigeLevelsGained)));
					}
				}
				return stringBuilder.ToString();
			}

			public string GetTotalDescription(bool showreqboons = true, bool showreqoaths = true)
			{
				string playerRequirementsDescription = GetPlayerRequirementsDescription(showreqoaths, showreqboons);
				string resetDetails = GetResetDetails();
				string text = "";
				text += GetChangesGrantedDescription();
				if (resetDetails.Length > 0)
				{
					text += "\n";
				}
				text += resetDetails;
				if (playerRequirementsDescription.Length > 0)
				{
					text += "\n";
				}
				return text + playerRequirementsDescription;
			}
		}

		public static readonly string CustomLevelZKey = "VELevel";

		public static readonly string CustomDataKey = "VE_DATA";

		public static IDeserializer yamldeserializer = ((BuilderSkeleton<DeserializerBuilder>)new DeserializerBuilder()).WithNamingConvention(CamelCaseNamingConvention.Instance).Build();

		public static ISerializer yamlserializer = ((BuilderSkeleton<SerializerBuilder>)new SerializerBuilder()).WithNamingConvention(CamelCaseNamingConvention.Instance).ConfigureDefaultValuesHandling((DefaultValuesHandling)2).Build();

		public static ISerializer yamlserializerJsonCompat = ((BuilderSkeleton<SerializerBuilder>)new SerializerBuilder()).WithNamingConvention(CamelCaseNamingConvention.Instance).JsonCompatible().Build();

		public static Sprite boonbackground;

		public static Sprite hastenDeath;

		private const string color_increase = "#b9f2ff";

		private const string color_decrease = "#ff4040";

		public static readonly string HarvestingBonusColor = "#ffc87c";

		public static readonly string FishBountyBonusColor = "#619CFF";

		public static readonly string None = "None";

		public static readonly List<Oaths> DamageReductionOaths = new List<Oaths>
		{
			Oaths.DealLessBluntDamage,
			Oaths.DealLessPierceDamage,
			Oaths.DealLessSlashDamage
		};

		public static readonly List<Oaths> ReducedSkillGainOaths = new List<Oaths>
		{
			Oaths.LowerSkillGainBow,
			Oaths.LowerSkillGainSword,
			Oaths.LowerSkillGainClub,
			Oaths.LowerSkillGainPolearms,
			Oaths.LowerSkillGainKnives,
			Oaths.LowerSkillGainRun,
			Oaths.LowerSkillGainSneak,
			Oaths.LowerSkillGainElementalMagic,
			Oaths.LowerSkillGainBloodMagic,
			Oaths.LowerSkillGainCrossbow,
			Oaths.LowerSkillGainSpears,
			Oaths.LowerSkillGainAxes
		};

		public static void LoadAssets()
		{
			boonbackground = ValhallEternal.EmbeddedResourceBundle.LoadAsset<Sprite>("assets/art/bottom_border_divider.png");
			hastenDeath = ValhallEternal.EmbeddedResourceBundle.LoadAsset<Sprite>("assets/art/hastenDeath.png");
			HastenTheInevitable.AddHastenDeathStatus();
		}

		public static string LocalizeOath(Oaths oath)
		{
			return $"$ve_{oath}";
		}

		public static string LocalizeOathDesc(Oaths oath, float value = 0f)
		{
			if (value > 0f)
			{
				return string.Format($"$ve_{oath}_desc", value);
			}
			return $"$ve_{oath}_desc_noval";
		}

		public static string LocalizeBoon(Boons boon)
		{
			return $"$ve_{boon}";
		}

		public static string LocalizeBoonDesc(Boons boon, float value = 0f)
		{
			if (value > 0f)
			{
				return string.Format($"$ve_{boon}_desc", value);
			}
			return $"$ve_{boon}_desc_noval";
		}
	}
	public static class Deities
	{
		public enum Deity
		{
			Baldur,
			Hel,
			Gefjun,
			Skaldi,
			Freya,
			Vor,
			Syn
		}

		public class PrestigeEffectDetails
		{
			public GameObject EffectObject { get; set; }

			public DataObjects.LevelTextGradiant LevelText { get; set; }

			public string Title { get; set; }
		}

		public class DeityDetails
		{
			public Sprite Image { get; set; }

			public string NameLocalKey { get; set; }

			public string DescriptionLocalKey { get; set; }
		}

		internal static Dictionary<Deity, DeityDetails> DeityConfiguration = new Dictionary<Deity, DeityDetails>();

		internal static Dictionary<string, GameObject> DeityEffects = new Dictionary<string, GameObject>();

		internal static Dictionary<DataObjects.PrestigeEffect, Dictionary<string, PrestigeEffectDetails>> PrestigeEffects = new Dictionary<DataObjects.PrestigeEffect, Dictionary<string, PrestigeEffectDetails>>
		{
			{
				DataObjects.PrestigeEffect.Wings,
				new Dictionary<string, PrestigeEffectDetails>()
			},
			{
				DataObjects.PrestigeEffect.Aura,
				new Dictionary<string, PrestigeEffectDetails>()
			},
			{
				DataObjects.PrestigeEffect.Footprints,
				new Dictionary<string, PrestigeEffectDetails>()
			}
		};

		internal static void LoadDietyConfigurations()
		{
			AddDeityConfiguration(Deity.Baldur, ValhallEternal.EmbeddedResourceBundle.LoadAsset<Sprite>("assets/art/baladur_nobackground.png"));
			AddDeityConfiguration(Deity.Hel, ValhallEternal.EmbeddedResourceBundle.LoadAsset<Sprite>("assets/art/hel_nobackground.png"));
			AddDeityConfiguration(Deity.Gefjun, ValhallEternal.EmbeddedResourceBundle.LoadAsset<Sprite>("assets/art/gefjun_nobackground.png"));
			AddDeityConfiguration(Deity.Skaldi, ValhallEternal.EmbeddedResourceBundle.LoadAsset<Sprite>("assets/art/skaldi_nobackground.png"));
			AddDeityConfiguration(Deity.Freya, ValhallEternal.EmbeddedResourceBundle.LoadAsset<Sprite>("assets/art/freya_nobackground.png"));
			AddDeityConfiguration(Deity.Vor, ValhallEternal.EmbeddedResourceBundle.LoadAsset<Sprite>("assets/art/vor_nobackground.png"));
			AddDeityConfiguration(Deity.Syn, ValhallEternal.EmbeddedResourceBundle.LoadAsset<Sprite>("assets/art/syn_nobackground.png"));
			AddEffect("leafburstverticle", ValhallEternal.EmbeddedResourceBundle.LoadAsset<GameObject>("assets/boons/harvestbonus.prefab"));
			AddEffect("vinepulseinward", ValhallEternal.EmbeddedResourceBundle.LoadAsset<GameObject>("assets/boons/naturegeneric.prefab"));
			AddEffect("snowswirl", ValhallEternal.EmbeddedResourceBundle.LoadAsset<GameObject>("assets/boons/snowswirlsoft.prefab"));
			AddEffect("goldenswirl", ValhallEternal.EmbeddedResourceBundle.LoadAsset<GameObject>("assets/boons/goldenswirl.prefab"));
			AddPrestigeEffect(DataObjects.PrestigeEffect.Wings, "natureWings", ValhallEternal.EmbeddedResourceBundle.LoadAsset<GameObject>("assets/leveldisplay/wings/naturewings.prefab"));
			AddPrestigeEffect(DataObjects.PrestigeEffect.Aura, "natureAura", ValhallEternal.EmbeddedResourceBundle.LoadAsset<GameObject>("assets/leveldisplay/aura/natureaura.prefab"));
			AddPrestigeEffect(DataObjects.PrestigeEffect.Aura, "lightAura", ValhallEternal.EmbeddedResourceBundle.LoadAsset<GameObject>("assets/leveldisplay/aura/lightaura.prefab"));
			AddPrestigeEffect(DataObjects.PrestigeEffect.Aura, "fireAura", ValhallEternal.EmbeddedResourceBundle.LoadAsset<GameObject>("assets/leveldisplay/aura/fireaura.prefab"));
			AddPrestigeEffect(DataObjects.PrestigeEffect.Aura, "frostAura", ValhallEternal.EmbeddedResourceBundle.LoadAsset<GameObject>("assets/leveldisplay/aura/frostaura.prefab"));
			AddPrestigeEffect(DataObjects.PrestigeEffect.Aura, "darkAura", ValhallEternal.EmbeddedResourceBundle.LoadAsset<GameObject>("assets/leveldisplay/aura/darkaura.prefab"));
		}

		internal static void AddPrestigeEffect(DataObjects.PrestigeEffect type, string key, GameObject asset)
		{
			if (type != DataObjects.PrestigeEffect.Aura && type != 0 && type != DataObjects.PrestigeEffect.Footprints)
			{
				Logger.LogWarning("Refused to add (" + key + ") incorrect Prestige effect as a game asset.");
			}
			else if (!PrestigeEffects[type].ContainsKey(key))
			{
				PrestigeEffects[type].Add(key, new PrestigeEffectDetails
				{
					EffectObject = asset
				});
				PrefabManager.Instance.AddPrefab(asset);
			}
		}

		internal static void AddPrestigeLevelText(string key, string topRight, string topLeft, string bottomRight