using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using BepInEx;
using BepInEx.Configuration;
using HarmonyLib;
using UnityEngine;
[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: AssemblyTitle("RequipMe")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("RequipMe")]
[assembly: AssemblyCopyright("Copyright © 2021")]
[assembly: AssemblyTrademark("")]
[assembly: ComVisible(false)]
[assembly: Guid("9f8a1b6e-6d0e-4dab-bbd8-9ed433836544")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: TargetFramework(".NETFramework,Version=v4.7.2", FrameworkDisplayName = ".NET Framework 4.7.2")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.0.0.0")]
[module: UnverifiableCode]
internal sealed class ConfigurationManagerAttributes
{
public delegate void CustomHotkeyDrawerFunc(ConfigEntryBase setting, ref bool isCurrentlyAcceptingInput);
public bool? ShowRangeAsPercent;
public Action<ConfigEntryBase> CustomDrawer;
public CustomHotkeyDrawerFunc CustomHotkeyDrawer;
public bool? Browsable;
public string Category;
public object DefaultValue;
public bool? HideDefaultButton;
public bool? HideSettingName;
public string Description;
public string DispName;
public int? Order;
public bool? ReadOnly;
public bool? IsAdvanced;
public Func<object, string> ObjToStr;
public Func<string, object> StrToObj;
}
namespace neobotics.ValheimMods;
public class Logging
{
public enum LogLevels
{
Critical,
Error,
Warning,
Info,
Debug,
Trace
}
private static Logging _logger;
public LogLevels LogLevel { get; set; }
public string ModName { get; set; }
private Logging(LogLevels level, string name)
{
LogLevel = level;
ModName = name;
}
public static Logging GetLogger(LogLevels level, string name)
{
if (_logger == null)
{
_logger = new Logging(level, name);
}
return _logger;
}
public static Logging GetLogger()
{
if (_logger == null)
{
throw new NullReferenceException("Logger not initialized");
}
return _logger;
}
public void Trace(string msg)
{
if (LogLevel >= LogLevels.Trace)
{
Debug.Log((object)Message(msg));
}
}
public void Debug(string msg)
{
if (LogLevel >= LogLevels.Debug)
{
Debug.Log((object)Message(msg));
}
}
public void Info(string msg)
{
if (LogLevel >= LogLevels.Info)
{
Debug.Log((object)Message(msg));
}
}
public void Warning(string msg)
{
if (LogLevel >= LogLevels.Warning)
{
Debug.LogWarning((object)Message(msg));
}
}
public void Error(string msg)
{
if (LogLevel >= LogLevels.Error)
{
Debug.LogWarning((object)Message(msg));
}
}
public void Error(Exception e)
{
Error(e, stackTrace: false);
}
public void Error(Exception e, bool stackTrace)
{
if (LogLevel >= LogLevels.Error)
{
Warning(Message(e.Message));
if (stackTrace)
{
Warning(e.StackTrace);
}
}
}
public void Critical(Exception e)
{
if (LogLevel >= LogLevels.Critical)
{
Debug(Message(e.Message));
Error(e.StackTrace);
}
}
private string Message(string msg)
{
return ModName + ": " + msg;
}
}
[BepInPlugin("neobotics.valheim_mod.requipme", "RequipMe", "0.2.2")]
[BepInProcess("valheim.exe")]
public class RequipMe : BaseUnityPlugin
{
[HarmonyPatch(typeof(TombStone), "OnTakeAllSuccess")]
private static class On_Take_All_Success_Patch
{
private static void Postfix(TombStone __instance)
{
Log.Debug("OnTakeAllSuccess Postfix");
waitFrames = 1;
}
}
[HarmonyPatch(typeof(TombStone), "EasyFitInInventory")]
private static class EasyFitInInventory_Patch
{
private static void Postfix(TombStone __instance, Player player, ref bool __result)
{
if (!((Object)(object)player == (Object)(object)Player.m_localPlayer) || __result)
{
return;
}
Log.Debug("EasyFitInInventory Postfix");
int emptySlots = ((Humanoid)player).GetInventory().GetEmptySlots();
Container container = __instance.m_container;
if (container.GetInventory().NrOfItems() > emptySlots)
{
Log.Debug($"Container Inventory {container.GetInventory().NrOfItems()} exceeds available slots {emptySlots}");
return;
}
float num = player.GetMaxCarryWeight();
ItemData? obj = container.GetInventory().GetAllItems().Find((ItemData x) => x.m_shared.m_name.Equals("$item_beltstrength"));
ItemData val = ((Humanoid)player).GetInventory().GetAllItems().Find((ItemData x) => x.m_shared.m_name.Equals("$item_beltstrength"));
if (obj != null || (val != null && !((Humanoid)player).GetInventory().GetEquippedItems().Contains(val)))
{
Log.Debug("Recalculating max player carry weight including Megingjord");
num += 150f;
}
if (((Humanoid)player).GetInventory().GetTotalWeight() + container.GetInventory().GetTotalWeight() <= num)
{
__result = true;
}
}
}
[HarmonyPatch(typeof(Player), "Update")]
public static class Player_Update_Patch
{
private static void Prefix(Player __instance)
{
//IL_003a: Unknown result type (might be due to invalid IL or missing references)
//IL_003f: Unknown result type (might be due to invalid IL or missing references)
if ((Object)(object)__instance == (Object)(object)Player.m_localPlayer)
{
if (waitFrames == 0)
{
Equip();
waitFrames = -1;
}
else if (waitFrames > 0)
{
waitFrames--;
}
KeyboardShortcut value = equipKey.Value;
if (((KeyboardShortcut)(ref value)).IsDown())
{
Log.Debug("Player triggered Equip");
Equip();
}
}
}
}
public static string Mod = "RequipMe";
public static Logging Log;
private static Harmony harmony;
private static RequipMe _modInstance;
public static ConfigEntry<string> prioritizeWeapon = null;
public static ConfigEntry<KeyboardShortcut> equipKey = null;
public static ConfigEntry<Logging.LogLevels> debugLevel = null;
private static KeyCode[] modifiers = (KeyCode[])(object)new KeyCode[1] { (KeyCode)308 };
private static KeyboardShortcut equipKeyDefault = new KeyboardShortcut((KeyCode)122, modifiers);
private static List<string> priority = null;
private static Dictionary<string, ItemType> weaponTypes = new Dictionary<string, ItemType>
{
{
"bow",
(ItemType)4
},
{
"twohanded",
(ItemType)14
},
{
"onehanded",
(ItemType)3
}
};
private static List<string> equipExclude = new List<string> { "$item_knife_butcher", "$item_spear_chitin", "$item_fishingrod", "$item_stone" };
private static List<ItemType> armorTypes = new List<ItemType>
{
(ItemType)6,
(ItemType)7,
(ItemType)11,
(ItemType)17
};
private static int waitFrames = -1;
public static RequipMe GetInstance()
{
return _modInstance;
}
private void Awake()
{
//IL_0030: Unknown result type (might be due to invalid IL or missing references)
//IL_003a: Expected O, but got Unknown
ConfigureMod();
Log.LogLevel = debugLevel.Value;
_modInstance = this;
harmony = new Harmony(((BaseUnityPlugin)this).Info.Metadata.GUID);
harmony.PatchAll(Assembly.GetExecutingAssembly());
Log.Info("Awake");
}
private void ConfigureMod()
{
//IL_0044: Unknown result type (might be due to invalid IL or missing references)
Log = Logging.GetLogger(Logging.LogLevels.Info, Mod);
prioritizeWeapon = ((BaseUnityPlugin)this).Config.Bind<string>("General", "WeaponPriority", "OneHanded,TwoHanded,Bow", "Priority of weapon types to equip, separated by commas. Will equip the 'best' weapon found in the order specified, e.g., If Bow is first in the list, will equip the best Bow (if one or more bows are found), otherwise will equip the best of the second type, then the third.");
equipKey = ((BaseUnityPlugin)this).Config.Bind<KeyboardShortcut>("General", "EquipShortcut", equipKeyDefault, "Keyboard shortcut to trigger an equip manually. ");
priority = GetPriorities(prioritizeWeapon.Value);
debugLevel = ((BaseUnityPlugin)this).Config.Bind<Logging.LogLevels>("Utility", "LogLevel", Logging.LogLevels.Info, "Controls the level of information contained in the log");
}
private void OnDestroy()
{
harmony.UnpatchAll(harmony.Id);
}
private static List<string> GetPriorities(string delimitedPriority)
{
return delimitedPriority.ToLower().Split(new string[1] { "," }, StringSplitOptions.RemoveEmptyEntries).ToList();
}
private static float ArmorValue(ItemData item)
{
return item.m_shared.m_armor + (float)Mathf.Max(0, item.m_quality - 1) * item.m_shared.m_armorPerLevel;
}
private static float AmmoValue(ItemData item)
{
return ((DamageTypes)(ref item.m_shared.m_damages)).GetTotalBlockableDamage();
}
private static float ShieldValue(ItemData item)
{
return item.m_shared.m_blockPower + (float)Mathf.Max(0, item.m_quality - 1) * item.m_shared.m_blockPowerPerLevel;
}
private static float WeaponValue(ItemData item)
{
//IL_0014: Unknown result type (might be due to invalid IL or missing references)
float num = default(float);
float num2 = default(float);
((Character)Player.m_localPlayer).GetSkills().GetRandomSkillRange(ref num, ref num2, item.m_shared.m_skillType);
return (((DamageTypes)(ref item.m_shared.m_damages)).GetTotalBlockableDamage() + (float)Mathf.Max(0, item.m_quality - 1) * ((DamageTypes)(ref item.m_shared.m_damagesPerLevel)).GetTotalBlockableDamage()) * num2;
}
private static void Equip()
{
//IL_0104: Unknown result type (might be due to invalid IL or missing references)
//IL_0109: Unknown result type (might be due to invalid IL or missing references)
Player aPlayer = Player.m_localPlayer;
List<ItemData> list = ((Humanoid)aPlayer).GetInventory().GetAllItems().FindAll((ItemData i) => i.IsEquipable());
List<ItemData> list2 = new List<ItemData>();
List<ItemData> list3 = null;
ItemData val = list.Find((ItemData x) => x.m_shared.m_name.Equals("$item_beltstrength"));
if (val != null)
{
list2.Add(val);
}
list3 = list.FindAll((ItemData x) => (int)x.m_shared.m_itemType == 9);
if (list3.Count > 0)
{
if (list3.Count > 1)
{
list3.Sort((ItemData x1, ItemData x2) => AmmoValue(x2).CompareTo(AmmoValue(x1)));
}
list2.Add(list3[0]);
}
foreach (ItemType iType2 in armorTypes)
{
list3 = list.FindAll((ItemData x) => x.m_shared.m_itemType == iType2);
if (list3.Count <= 0)
{
continue;
}
if (list3.Count > 1)
{
list3.Sort((ItemData x1, ItemData x2) => ArmorValue(x2).CompareTo(ArmorValue(x1)));
}
list2.Add(list3[0]);
}
foreach (string item in priority)
{
if (!weaponTypes.TryGetValue(item, out var iType))
{
continue;
}
list3 = list.FindAll((ItemData x) => x.m_shared.m_itemType == iType);
list3.RemoveAll((ItemData x) => equipExclude.Contains(x.m_shared.m_name) || (int)x.m_shared.m_skillType == 12);
if (list3.Count <= 0)
{
continue;
}
if (list3.Count > 1)
{
list3.Sort((ItemData x1, ItemData x2) => WeaponValue(x2).CompareTo(WeaponValue(x1)));
}
list2.Add(list3[0]);
if (!item.Equals("onehanded"))
{
break;
}
list3 = list.FindAll((ItemData x) => (int)x.m_shared.m_itemType == 5);
if (list3.Count <= 0)
{
break;
}
if (list3.Count > 1)
{
list3.Sort((ItemData x1, ItemData x2) => ShieldValue(x2).CompareTo(ShieldValue(x1)));
}
list2.Add(list3[0]);
break;
}
list2.ForEach(delegate(ItemData x)
{
((Humanoid)aPlayer).EquipItem(x, false);
});
if (Log.LogLevel >= Logging.LogLevels.Debug)
{
list2.ForEach(delegate(ItemData x)
{
Log.Debug("Equipping " + x.m_shared.m_name);
});
}
}
}