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.Serialization.Formatters.Binary; 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.6")] [assembly: TargetFramework(".NETFramework,Version=v4.8", FrameworkDisplayName = ".NET Framework 4.8")] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("0.7.6.0")] namespace ValhallEternal { internal class Logger { public static LogLevel Level = (LogLevel)16; public static void enableDebugLogging(object sender, EventArgs e) { CheckEnableDebugLogging(); } 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.6")] [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.6"; 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); Deities.LoadDietyConfigurations(); HarmonyInstance = Harmony.CreateAndPatchAll(Assembly.GetExecutingAssembly(), "MidnightsFX.ValhallaEternal"); AddLocalizations(); SacrificeData.SetupSacrificeData(); DataObjects.LoadAssets(); Commands.AddCommands(); 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 internal_localization = SimpleJson.DeserializeObject>(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 dictionary = SimpleJson.DeserializeObject>(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 UpdateLocalizationWithMissingKeys(Dictionary internal_localization, Dictionary cached_localization) { if (internal_localization.Keys != cached_localization.Keys) { List list = cached_localization.Keys.ToList(); foreach (KeyValuePair 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) { diagTexts = __instance; AddDietyPrestigeExplanations(__instance); } private static void AddDietyPrestigeExplanations(TextsDialog textsDialog) { //IL_003c: Unknown result type (might be due to invalid IL or missing references) //IL_0046: Expected O, but got Unknown string text = BuildPrestigeOathBoonCompendiumEntry(); string text2 = Localization.instance.Localize("$ve_compendium_name"); if (textsDialog.m_texts[0].m_topic != text2) { textsDialog.m_texts.Insert(0, new TextInfo(text2, text)); } } } private static readonly string HeaderColor = "#ffa64d"; private static readonly string BoonColor = "#40B850"; private static readonly string OathColor = "#CF2713"; private static TextsDialog diagTexts; internal static void UpdateDietyPrestigeExplanations() { //IL_0070: Unknown result type (might be due to invalid IL or missing references) //IL_007a: Expected O, but got Unknown if (!((Object)(object)diagTexts == (Object)null)) { string compendiumTopic = Localization.instance.Localize("$ve_compendium_name"); int num = diagTexts.m_texts.FindIndex((TextInfo t) => t.m_topic == compendiumTopic); if (num >= 0) { string text = BuildPrestigeOathBoonCompendiumEntry(); diagTexts.m_texts[num] = new TextInfo(compendiumTopic, text); } } } private static string BuildPrestigeOathBoonCompendiumEntry() { StringBuilder stringBuilder = new StringBuilder(); if (PlayerData.localPlayerConfig.TotalBoons.Count > 0) { stringBuilder.AppendLine("" + Localization.instance.Localize("$ve_boon_section_header") + ""); stringBuilder.AppendLine(); } foreach (KeyValuePair totalBoon in PlayerData.localPlayerConfig.TotalBoons) { stringBuilder.AppendLine(Localization.instance.Localize($"{DataObjects.LocalizeBoon(totalBoon.Key)} ($ve_level {totalBoon.Value}) - {DataObjects.LocalizeBoonDesc(totalBoon.Key)}")); } if (stringBuilder.Length > 0) { stringBuilder.AppendLine(); } if (PlayerData.localPlayerConfig.TotalOaths.Count > 0) { stringBuilder.AppendLine("" + Localization.instance.Localize("$ve_oath_section_header") + ""); stringBuilder.AppendLine(); } foreach (KeyValuePair totalOath in PlayerData.localPlayerConfig.TotalOaths) { stringBuilder.AppendLine(Localization.instance.Localize($"{DataObjects.LocalizeOath(totalOath.Key)} ($ve_level {totalOath.Value}) - {DataObjects.LocalizeOathDesc(totalOath.Key, totalOath.Value)}")); } Logger.LogDebug($"Built compendium entry:\n{stringBuilder}"); return Localization.instance.Localize(stringBuilder.ToString()); } } 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("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 dictionary = new Dictionary(); Dictionary dictionary2 = new Dictionary(); if (pld.PlayerOaths != null) { foreach (KeyValuePair 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 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> 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 totalOath in localPlayerConfig.TotalOaths) { Logger.LogDebug($" - Oath: {totalOath.Key} Value: {totalOath.Value}"); } foreach (KeyValuePair 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 { effectKey }; } } else { localPlayerConfig.AvailableEffectsForPlayer = new Dictionary> { { effectType, new List { 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 { { effectType, effectKey } }; } } public static bool PlayerHasAnyPrestigeEffect() { if (localPlayerConfig.AvailableEffectsForPlayer != null) { foreach (KeyValuePair> 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); WritePrestigeEffectsToZDO(); } public static string PackActiveEffectsForZDO(Dictionary active) { if (active == null || active.Count == 0) { return ""; } List list = new List(active.Count); foreach (KeyValuePair item in active) { if (!string.IsNullOrEmpty(item.Value) && !(item.Value == DataObjects.None)) { list.Add($"{item.Key}={item.Value}"); } } return string.Join("|", list); } public static Dictionary UnpackActiveEffectsFromZDO(string packed) { Dictionary dictionary = new Dictionary(); if (string.IsNullOrEmpty(packed)) { return dictionary; } string[] array = packed.Split(new char[1] { '|' }); foreach (string text in array) { int num = text.IndexOf('='); if (num > 0 && Enum.TryParse(text.Substring(0, num), out var result)) { dictionary[result] = text.Substring(num + 1); } } return dictionary; } public static void WritePrestigeEffectsToZDO() { if (!((Object)(object)Player.m_localPlayer == (Object)null) && !((Object)(object)((Character)Player.m_localPlayer).m_nview == (Object)null)) { ZDO zDO = ((Character)Player.m_localPlayer).m_nview.GetZDO(); if (zDO != null) { DataObjects.PrestigeEffectsDictionaryZNetProperty prestigeEffectsDictionaryZNetProperty = new DataObjects.PrestigeEffectsDictionaryZNetProperty(DataObjects.CustomPrestigeFxZKey, ((Character)Player.m_localPlayer).m_nview, null); prestigeEffectsDictionaryZNetProperty.ForceSet(localPlayerConfig.ActiveEffectsForPlayer); } } } public static List 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 list = new List(); if (localPlayerConfig.AvailableEffectsForPlayer != null && localPlayerConfig.AvailableEffectsForPlayer.ContainsKey(effect)) { foreach (string item in localPlayerConfig.AvailableEffectsForPlayer[effect]) { list.Add(new OptionData(item)); } } return list; } public static string GetActivePrestigeEffectForType(DataObjects.PrestigeEffect type = DataObjects.PrestigeEffect.Wings) { if (localPlayerConfig.ActiveEffectsForPlayer != null && localPlayerConfig.ActiveEffectsForPlayer.ContainsKey(type)) { return localPlayerConfig.ActiveEffectsForPlayer[type]; } return null; } 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) { foreach (KeyValuePair item in playerLevelData.ActiveEffectsForPlayer) { Logger.LogDebug($"Setting up player {item.Key} display: {item.Value}"); switch (item.Key) { case DataObjects.PrestigeEffect.Wings: PrestigeDisplays.SetupPlayerWingsDisplay(item.Value); break; case DataObjects.PrestigeEffect.Aura: PrestigeDisplays.SetupPlayerAuraDisplay(item.Value); break; } } } WritePrestigeEffectsToZDO(); Compendium.UpdateDietyPrestigeExplanations(); } 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(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