using System; using System.Collections.Generic; using System.Diagnostics; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using BepInEx; using BepInEx.Configuration; using HarmonyLib; using Microsoft.CodeAnalysis; using UnityEngine; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: TargetFramework(".NETFramework,Version=v4.8.1", FrameworkDisplayName = ".NET Framework 4.8.1")] [assembly: AssemblyCompany("MGDev.Resilience")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyFileVersion("1.0.0.0")] [assembly: AssemblyInformationalVersion("1.0.0")] [assembly: AssemblyProduct("MGDev.Resilience")] [assembly: AssemblyTitle("MGDev.Resilience")] [assembly: AssemblyVersion("1.0.0.0")] [module: RefSafetyRules(11)] namespace Microsoft.CodeAnalysis { [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] internal sealed class EmbeddedAttribute : Attribute { } } namespace System.Runtime.CompilerServices { [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] [AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)] internal sealed class RefSafetyRulesAttribute : Attribute { public readonly int Version; public RefSafetyRulesAttribute(int P_0) { Version = P_0; } } } namespace MGDev.Resilience { [BepInPlugin("mgdev.resilience", "Resilience", "1.0.0")] [BepInDependency(/*Could not decode attribute arguments.*/)] public class ResiliencePlugin : BaseUnityPlugin { public const string PluginGuid = "mgdev.resilience"; public const string PluginName = "Resilience"; public const string PluginVersion = "1.0.0"; internal static readonly SkillType SkillType = (SkillType)Math.Abs(StringExtensionMethods.GetStableHashCode("Resilience")); internal static SkillDef SkillDef; internal static ConfigEntry BasePlayerHealth; internal static ConfigEntry BaseHealthAt100; internal static ConfigEntry GeneralXpMultiplier; internal static ConfigEntry FoodXpMultiplier; internal static ConfigEntry DamageXpMultiplier; internal static ConfigEntry MinimumDamageForXp; internal static ConfigEntry DeathSkillLossPercent; internal static ConfigEntry BukeperriesSkillLossPercent; private Harmony _harmony; private void Awake() { //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_000b: Unknown result type (might be due to invalid IL or missing references) //IL_000c: Unknown result type (might be due to invalid IL or missing references) //IL_0011: Unknown result type (might be due to invalid IL or missing references) //IL_0016: Unknown result type (might be due to invalid IL or missing references) //IL_0021: Unknown result type (might be due to invalid IL or missing references) //IL_002c: Unknown result type (might be due to invalid IL or missing references) //IL_0041: Expected O, but got Unknown //IL_0070: Unknown result type (might be due to invalid IL or missing references) //IL_007a: Expected O, but got Unknown BindConfig(); SkillDef = new SkillDef { m_skill = SkillType, m_description = "$skilldesc_resilience", m_icon = CreateIcon(), m_increseStep = GeneralXpMultiplier.Value }; GeneralXpMultiplier.SettingChanged += delegate { SkillDef.m_increseStep = GeneralXpMultiplier.Value; }; _harmony = new Harmony("mgdev.resilience"); _harmony.PatchAll(); ((BaseUnityPlugin)this).Logger.LogInfo((object)"Resilience 1.0.0 loaded."); } private void OnDestroy() { Harmony harmony = _harmony; if (harmony != null) { harmony.UnpatchSelf(); } } private void BindConfig() { BasePlayerHealth = ((BaseUnityPlugin)this).Config.Bind("01 - Health Scaling", "BasePlayerHealth", 25f, "Base player health before food, Resilience, and Epic Loot bonuses.\nValheim default is 25."); BaseHealthAt100 = ((BaseUnityPlugin)this).Config.Bind("01 - Health Scaling", "BaseHealthBonusAtLevel100", 25f, "Extra base health gained at Resilience level 100.\nExample: 25 means level 100 gives +25 base health before food."); GeneralXpMultiplier = ((BaseUnityPlugin)this).Config.Bind("02 - Experience", "GeneralXpMultiplier", 2f, "Changes all Resilience XP from every source.\nRecommended range: 1 to 10."); FoodXpMultiplier = ((BaseUnityPlugin)this).Config.Bind("02 - Experience", "FoodXpMultiplier", 1f, "Changes how much food contributes to Resilience XP.\nRecommended range: 1 to 10."); DamageXpMultiplier = ((BaseUnityPlugin)this).Config.Bind("02 - Experience", "DamageXpMultiplier", 1f, "Changes how much damage taken contributes to Resilience XP.\nRecommended range: 1 to 10."); MinimumDamageForXp = ((BaseUnityPlugin)this).Config.Bind("02 - Experience", "MinimumDamageForXp", 0.5f, "Damage must be at least this high to award Resilience XP."); DeathSkillLossPercent = ((BaseUnityPlugin)this).Config.Bind("03 - Penalties", "DeathSkillLossPercent", 5f, "Percent of current Resilience level lost on death.\nRange: 0 to 100. Set to 0 to disable."); BukeperriesSkillLossPercent = ((BaseUnityPlugin)this).Config.Bind("03 - Penalties", "BukeperriesSkillLossPercent", 1f, "Percent of current Resilience level lost when eating Bukeperries.\nRange: 0 to 100. Set to 0 to disable."); } internal static float GetSkillFactor(Player player) { //IL_000a: Unknown result type (might be due to invalid IL or missing references) if (!((Object)(object)player == (Object)null)) { return ((Character)player).GetSkillFactor(SkillType); } return 0f; } internal static float GetHealthBonus(Player player) { return BaseHealthAt100.Value * GetSkillFactor(player); } internal static float GetBaseHealthAdjustment() { return BasePlayerHealth.Value - 25f; } internal static void LowerResilience(Player player, float percent) { //IL_002a: Unknown result type (might be due to invalid IL or missing references) if (!((Object)(object)player == (Object)null) && !(percent <= 0f)) { Skills skills = ((Character)player).GetSkills(); if (AccessTools.FieldRefAccess>("m_skillData").Invoke(skills).TryGetValue(SkillType, out var value)) { Skill obj = value; obj.m_level -= value.m_level * Mathf.Clamp01(percent / 100f); value.m_accumulator = 0f; } } } private static Sprite CreateIcon() { //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_000c: Expected O, but got Unknown //IL_0184: Unknown result type (might be due to invalid IL or missing references) //IL_0189: Unknown result type (might be due to invalid IL or missing references) //IL_0129: Unknown result type (might be due to invalid IL or missing references) //IL_0145: Unknown result type (might be due to invalid IL or missing references) //IL_0142: Unknown result type (might be due to invalid IL or missing references) Texture2D val = new Texture2D(64, 64, (TextureFormat)4, false); Color val2 = default(Color); ((Color)(ref val2))..ctor(0f, 0f, 0f, 0f); Color val3 = default(Color); ((Color)(ref val3))..ctor(0.75f, 0.12f, 0.08f, 1f); Color val4 = default(Color); ((Color)(ref val4))..ctor(0.18f, 0.06f, 0.04f, 1f); for (int i = 0; i < 64; i++) { for (int j = 0; j < 64; j++) { float num = ((float)j - 32f) / 28f; float num2 = ((float)i - 31f) / 28f; float num3 = Mathf.Pow(num + 0.35f, 2f) + Mathf.Pow(num2 - 0.2f, 2f); float num4 = Mathf.Pow(num - 0.35f, 2f) + Mathf.Pow(num2 - 0.2f, 2f); bool flag = num3 < 0.28f || num4 < 0.28f || (Mathf.Abs(num) + num2 * 0.9f < 0.85f && num2 < 0.45f && num2 > -0.85f); val.SetPixel(j, i, flag ? ((j < 6 || i < 6 || j > 57 || i > 57) ? val4 : val3) : val2); } } val.Apply(); return Sprite.Create(val, new Rect(0f, 0f, 64f, 64f), Vector2.zero); } } [HarmonyPatch(typeof(Localization), "LoadCSV")] internal static class LocalizationPatch { private static void Postfix(Localization __instance) { //IL_0029: Unknown result type (might be due to invalid IL or missing references) //IL_002e: Unknown result type (might be due to invalid IL or missing references) MethodInfo methodInfo = AccessTools.Method(typeof(Localization), "AddWord", (Type[])null, (Type[])null); if ((object)methodInfo != null) { object[] array = new object[2]; SkillType skillType = ResiliencePlugin.SkillType; array[0] = "skill_" + ((object)(SkillType)(ref skillType)).ToString().ToLower(); array[1] = "Resilience"; methodInfo.Invoke(__instance, array); } methodInfo?.Invoke(__instance, new object[2] { "skilldesc_resilience", "Increases your base health as you build resilience." }); } } [HarmonyPatch(typeof(Skills), "IsSkillValid")] internal static class SkillsIsSkillValidPatch { private static void Postfix(SkillType type, ref bool __result) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0001: Unknown result type (might be due to invalid IL or missing references) if (type == ResiliencePlugin.SkillType) { __result = true; } } } [HarmonyPatch(typeof(Skills), "GetSkillDef")] internal static class SkillsGetSkillDefPatch { private static void Postfix(ref SkillDef __result, List ___m_skills, SkillType type) { //IL_0004: Unknown result type (might be due to invalid IL or missing references) //IL_0005: Unknown result type (might be due to invalid IL or missing references) if (__result == null && type == ResiliencePlugin.SkillType) { ___m_skills.Add(ResiliencePlugin.SkillDef); __result = ResiliencePlugin.SkillDef; } } } [HarmonyPatch(typeof(Player), "EatFood")] internal static class PlayerEatFoodPatch { private static void Postfix(Player __instance, ItemData item, ref bool __result) { //IL_0009: Unknown result type (might be due to invalid IL or missing references) if (__result && item != null) { ((Character)__instance).RaiseSkill(ResiliencePlugin.SkillType, Mathf.Sqrt(item.m_shared.m_food) * ResiliencePlugin.FoodXpMultiplier.Value); } } } [HarmonyPatch(typeof(Character), "ApplyDamage")] internal static class CharacterApplyDamagePatch { private static void Prefix(Character __instance, HitData hit, out float __state) { __state = (((Object)(object)__instance != (Object)null && __instance.IsPlayer()) ? __instance.GetHealth() : (-1f)); } private static void Postfix(Character __instance, float __state) { //IL_0045: Unknown result type (might be due to invalid IL or missing references) if (__state < 0f || (Object)(object)__instance == (Object)null || !__instance.IsPlayer()) { return; } float num = Mathf.Max(0f, __state - __instance.GetHealth()); if (num >= ResiliencePlugin.MinimumDamageForXp.Value) { Player val = (Player)(object)((__instance is Player) ? __instance : null); if (val != null) { ((Character)val).RaiseSkill(ResiliencePlugin.SkillType, Mathf.Sqrt(num) * ResiliencePlugin.DamageXpMultiplier.Value); } } } } [HarmonyPatch(typeof(Skills), "OnDeath")] internal static class SkillsOnDeathPatch { private static void Prefix(Skills __instance, ref Skill __state) { //IL_0013: Unknown result type (might be due to invalid IL or missing references) //IL_0021: Unknown result type (might be due to invalid IL or missing references) Dictionary dictionary = AccessTools.FieldRefAccess>("m_skillData").Invoke(__instance); if (dictionary.TryGetValue(ResiliencePlugin.SkillType, out __state)) { dictionary.Remove(ResiliencePlugin.SkillType); } } private static void Finalizer(Skills __instance, Skill __state) { //IL_0049: Unknown result type (might be due to invalid IL or missing references) if (__state != null) { __state.m_level -= __state.m_level * Mathf.Clamp01(ResiliencePlugin.DeathSkillLossPercent.Value / 100f); __state.m_accumulator = 0f; AccessTools.FieldRefAccess>("m_skillData").Invoke(__instance)[ResiliencePlugin.SkillType] = __state; } } } [HarmonyPatch(typeof(Player), "ConsumeItem")] internal static class PlayerConsumeItemPatch { private static void Postfix(Player __instance, ItemData item) { if (item != null && item.m_shared.m_name == "$item_pukeberries") { ResiliencePlugin.LowerResilience(__instance, ResiliencePlugin.BukeperriesSkillLossPercent.Value); } } } [HarmonyPatch(typeof(Player), "GetBaseFoodHP")] internal static class PlayerGetBaseFoodHPPatch { [HarmonyPriority(0)] private static void Postfix(Player __instance, ref float __result) { __result += ResiliencePlugin.GetBaseHealthAdjustment() + ResiliencePlugin.GetHealthBonus(__instance); } } [HarmonyPatch(typeof(Player), "GetTotalFoodValue")] internal static class PlayerGetTotalFoodValuePatch { [HarmonyPriority(0)] private static void Postfix(Player __instance, ref float hp) { hp += ResiliencePlugin.GetBaseHealthAdjustment() + ResiliencePlugin.GetHealthBonus(__instance); } } }