using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Reflection.Emit;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using System.Text.RegularExpressions;
using System.Threading.Tasks;
using Auga;
using BepInEx;
using BepInEx.Bootstrap;
using BepInEx.Configuration;
using BepInEx.Logging;
using EpicLoot.Crafting;
using EpicLoot.CraftingV2;
using HarmonyLib;
using JetBrains.Annotations;
using Jotunn;
using Jotunn.Entities;
using Jotunn.GUI;
using Jotunn.Managers;
using Jotunn.Utils;
using SimpleJson;
using TMPro;
using UnityEngine;
using UnityEngine.EventSystems;
using UnityEngine.Events;
using UnityEngine.UI;
using VNEI.Logic;
using VNEI.Logic.Compatibility;
using VNEI.Patches;
using VNEI.UI;
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("VNEI")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("VNEI")]
[assembly: AssemblyCopyright("Copyright © 2021")]
[assembly: AssemblyTrademark("")]
[assembly: ComVisible(false)]
[assembly: Guid("43367351-2A51-4BC5-9028-1303450B71AB")]
[assembly: AssemblyFileVersion("0.17.5")]
[assembly: TargetFramework(".NETFramework,Version=v4.8", FrameworkDisplayName = ".NET Framework 4.8")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("0.17.5.0")]
[module: UnverifiableCode]
namespace VNEI
{
internal static class Log
{
internal static ManualLogSource _logSource;
internal static void Init(ManualLogSource logSource)
{
_logSource = logSource;
}
internal static void LogDebug(object data)
{
_logSource.LogDebug(data);
}
internal static void LogError(object data)
{
_logSource.LogError(data);
}
internal static void LogFatal(object data)
{
_logSource.LogFatal(data);
}
internal static void LogInfo(object data)
{
_logSource.LogInfo(data);
}
internal static void LogMessage(object data)
{
_logSource.LogMessage(data);
}
internal static void LogWarning(object data)
{
_logSource.LogWarning(data);
}
}
[BepInPlugin("com.maxsch.valheim.vnei", "VNEI", "0.17.5")]
[BepInDependency(/*Could not decode attribute arguments.*/)]
[BepInDependency(/*Could not decode attribute arguments.*/)]
[NetworkCompatibility(/*Could not decode attribute arguments.*/)]
public class Plugin : BaseUnityPlugin
{
public enum InputButtonWrapper
{
Left = 0,
Right = 1,
Middle = 2,
None = -1
}
public const string ModName = "VNEI";
public const string ModGuid = "com.maxsch.valheim.vnei";
public const string ModVersion = "0.17.5";
public static ConfigEntry<bool> useBlacklist;
public static ConfigEntry<bool> invertScroll;
public static ConfigEntry<bool> normalizeScroll;
public static ConfigEntry<bool> attachToCrafting;
public static ConfigEntry<bool> hideUIAtStartup;
public static ConfigEntry<int> rowCount;
public static ConfigEntry<int> columnCount;
public static ConfigEntry<int> transparency;
public static ConfigEntry<KeyboardShortcut> openHotkey;
public static ConfigEntry<KeyboardShortcut> viewRecipeHotkey;
public static ConfigEntry<InputButtonWrapper> itemCheatHotkey;
public static ConfigEntry<InputButtonWrapper> removeRecentHotkey;
public static ConfigEntry<KeyboardShortcut> goForwardHotkey;
public static ConfigEntry<KeyboardShortcut> goBackHotkey;
private static ConfigEntry<bool> showOnlyKnown;
private static ConfigEntry<bool> forceShowOnlyKnown;
public static ConfigEntry<bool> showRecentItems;
public static ConfigEntry<string> tabName;
public static ConfigEntry<bool> cheating;
public static ConfigEntry<bool> cheatCreatures;
public static bool isUiOpen = true;
public Sprite noIconSprite;
public Sprite starSprite;
public Sprite noStarSprite;
public Sprite inventoryIcon;
public GameObject vneiUI;
public GameObject displayItemTemplate;
public GameObject craftingStationTemplate;
public Item allStations;
public Item handStation;
public Item noStation;
private static readonly Regex RichTagRegex = new Regex("<[^>]*>");
private Harmony harmony;
public static Plugin Instance { get; private set; }
public static AssetBundle AssetBundle { get; private set; }
private static HashSet<string> ItemBlacklist { get; set; } = new HashSet<string>();
public static bool ShowOnlyKnown => showOnlyKnown.Value || forceShowOnlyKnown.Value;
public static event Action OnOpenHotkey;
private void Awake()
{
//IL_005f: Unknown result type (might be due to invalid IL or missing references)
//IL_0069: Expected O, but got Unknown
//IL_0090: Unknown result type (might be due to invalid IL or missing references)
//IL_009a: Expected O, but got Unknown
//IL_00c4: Unknown result type (might be due to invalid IL or missing references)
//IL_00c9: Unknown result type (might be due to invalid IL or missing references)
//IL_00d2: Expected O, but got Unknown
//IL_00d2: Unknown result type (might be due to invalid IL or missing references)
//IL_00dc: Expected O, but got Unknown
//IL_0103: Unknown result type (might be due to invalid IL or missing references)
//IL_010d: Expected O, but got Unknown
//IL_0134: Unknown result type (might be due to invalid IL or missing references)
//IL_013e: Expected O, but got Unknown
//IL_0165: Unknown result type (might be due to invalid IL or missing references)
//IL_016f: Expected O, but got Unknown
//IL_0194: 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_0245: Unknown result type (might be due to invalid IL or missing references)
//IL_0279: Unknown result type (might be due to invalid IL or missing references)
//IL_02b6: Unknown result type (might be due to invalid IL or missing references)
//IL_02c0: Expected O, but got Unknown
//IL_02e7: Unknown result type (might be due to invalid IL or missing references)
//IL_02f1: Expected O, but got Unknown
//IL_0318: Unknown result type (might be due to invalid IL or missing references)
//IL_0322: Expected O, but got Unknown
//IL_0349: Unknown result type (might be due to invalid IL or missing references)
//IL_0353: Expected O, but got Unknown
//IL_037a: Unknown result type (might be due to invalid IL or missing references)
//IL_0384: Expected O, but got Unknown
//IL_03af: Unknown result type (might be due to invalid IL or missing references)
//IL_03b9: Expected O, but got Unknown
//IL_03e0: Unknown result type (might be due to invalid IL or missing references)
//IL_03ea: Expected O, but got Unknown
//IL_0411: Unknown result type (might be due to invalid IL or missing references)
//IL_041b: Expected O, but got Unknown
//IL_0438: Unknown result type (might be due to invalid IL or missing references)
//IL_0442: Expected O, but got Unknown
Instance = this;
Log.Init(((BaseUnityPlugin)this).Logger);
AcceptableValueRange<int> val = new AcceptableValueRange<int>(1, 25);
AcceptableValueRange<int> val2 = new AcceptableValueRange<int>(0, 100);
string text = AssetUtils.LoadTextFromResources("Localization.Config.json", Assembly.GetExecutingAssembly());
Dictionary<string, string> dictionary = SimpleJson.DeserializeObject<Dictionary<string, string>>(text);
useBlacklist = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "Use Item Blacklist", true, new ConfigDescription(dictionary["UseItemBlacklist"], (AcceptableValueBase)null, Array.Empty<object>()));
showOnlyKnown = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "Show Only Known", false, new ConfigDescription(dictionary["ShowOnlyKnown"], (AcceptableValueBase)null, Array.Empty<object>()));
forceShowOnlyKnown = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "Force Show Only Known", false, new ConfigDescription(dictionary["ForceShowOnlyKnown"], (AcceptableValueBase)null, new object[1] { (object)new ConfigurationManagerAttributes
{
IsAdminOnly = true
} }));
showRecentItems = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "Show Recent Items", true, new ConfigDescription(dictionary["ShowRecentItems"], (AcceptableValueBase)null, Array.Empty<object>()));
invertScroll = ((BaseUnityPlugin)this).Config.Bind<bool>("Hotkeys", "Invert Scroll", false, new ConfigDescription(dictionary["InvertScroll"], (AcceptableValueBase)null, Array.Empty<object>()));
normalizeScroll = ((BaseUnityPlugin)this).Config.Bind<bool>("Hotkeys", "Normalize Scroll", true, new ConfigDescription(dictionary["NormalizeScroll"], (AcceptableValueBase)null, Array.Empty<object>()));
openHotkey = ((BaseUnityPlugin)this).Config.Bind<KeyboardShortcut>("Hotkeys", "Open UI Hotkey", new KeyboardShortcut((KeyCode)104, (KeyCode[])(object)new KeyCode[1] { (KeyCode)308 }), dictionary["OpenUIHotkey"]);
viewRecipeHotkey = ((BaseUnityPlugin)this).Config.Bind<KeyboardShortcut>("Hotkeys", "View Recipe Hotkey", new KeyboardShortcut((KeyCode)114, Array.Empty<KeyCode>()), dictionary["ViewRecipeHotkey"]);
itemCheatHotkey = ((BaseUnityPlugin)this).Config.Bind<InputButtonWrapper>("Hotkeys", "Item Cheat Mouse Button", InputButtonWrapper.Right, dictionary["ItemCheatMouseButton"]);
removeRecentHotkey = ((BaseUnityPlugin)this).Config.Bind<InputButtonWrapper>("Hotkeys", "Remove Recent Item Mouse Button", InputButtonWrapper.Middle, dictionary["RemoveRecentMouseButton"]);
goForwardHotkey = ((BaseUnityPlugin)this).Config.Bind<KeyboardShortcut>("Hotkeys", "Go Forward Hotkey", new KeyboardShortcut((KeyCode)275, Array.Empty<KeyCode>()), dictionary["GoForwardHotkey"]);
goBackHotkey = ((BaseUnityPlugin)this).Config.Bind<KeyboardShortcut>("Hotkeys", "Go Back Hotkey", new KeyboardShortcut((KeyCode)276, Array.Empty<KeyCode>()), dictionary["GoBackHotkey"]);
columnCount = ((BaseUnityPlugin)this).Config.Bind<int>("UI", "Items Horizontal", 12, new ConfigDescription(dictionary["ItemsHorizontal"], (AcceptableValueBase)(object)val, Array.Empty<object>()));
rowCount = ((BaseUnityPlugin)this).Config.Bind<int>("UI", "Items Vertical", 6, new ConfigDescription(dictionary["ItemsVertical"], (AcceptableValueBase)(object)val, Array.Empty<object>()));
attachToCrafting = ((BaseUnityPlugin)this).Config.Bind<bool>("UI", "Attach To Crafting", true, new ConfigDescription(dictionary["AttachToCrafting"], (AcceptableValueBase)null, Array.Empty<object>()));
hideUIAtStartup = ((BaseUnityPlugin)this).Config.Bind<bool>("UI", "Hide GUI At Start", false, new ConfigDescription(dictionary["HideGUIAtStart"], (AcceptableValueBase)null, Array.Empty<object>()));
transparency = ((BaseUnityPlugin)this).Config.Bind<int>("Visual", "Background Transparency", 0, new ConfigDescription(dictionary["Transparency"], (AcceptableValueBase)(object)val2, Array.Empty<object>()));
tabName = ((BaseUnityPlugin)this).Config.Bind<string>("Visual", "Tab Name", "VNEI", new ConfigDescription(dictionary["TabName"], (AcceptableValueBase)null, Array.Empty<object>()));
cheating = ((BaseUnityPlugin)this).Config.Bind<bool>("Cheating", "Enable Cheating", false, new ConfigDescription(dictionary["EnableCheating"], (AcceptableValueBase)null, Array.Empty<object>()));
cheatCreatures = ((BaseUnityPlugin)this).Config.Bind<bool>("Cheating", "Enable Spawning Creatures", false, new ConfigDescription(dictionary["AllowCreatureSpawn"], (AcceptableValueBase)null, Array.Empty<object>()));
isUiOpen = !hideUIAtStartup.Value;
harmony = new Harmony("com.maxsch.valheim.vnei");
harmony.PatchAll();
AssetBundle = AssetUtils.LoadAssetBundleFromResources("VNEI_AssetBundle");
CustomLocalization localization = LocalizationManager.Instance.GetLocalization();
localization.AddJsonFile("English", AssetUtils.LoadTextFromResources("Localization.English.json"));
localization.AddJsonFile("German", AssetUtils.LoadTextFromResources("Localization.German.json"));
LoadBlacklist();
noIconSprite = AssetBundle.LoadAsset<Sprite>("NoSprite.png");
starSprite = AssetBundle.LoadAsset<Sprite>("Star.png");
noStarSprite = AssetBundle.LoadAsset<Sprite>("NoStar.png");
inventoryIcon = AssetBundle.LoadAsset<Sprite>("Hand.png");
vneiUI = AssetBundle.LoadAsset<GameObject>("VNEI");
displayItemTemplate = AssetBundle.LoadAsset<GameObject>("_Template");
craftingStationTemplate = AssetBundle.LoadAsset<GameObject>("CraftingStationTemplate");
GUIManager.OnCustomGUIAvailable += delegate
{
GetMainUI().CreateBaseUI();
};
CommandManager.Instance.AddConsoleCommand((ConsoleCommand)(object)new SelectUITest.ToggleUIConsoleCommand());
CommandManager.Instance.AddConsoleCommand((ConsoleCommand)(object)new FileWriterControllerCSV());
CommandManager.Instance.AddConsoleCommand((ConsoleCommand)(object)new FileWriterControllerYAML());
CommandManager.Instance.AddConsoleCommand((ConsoleCommand)(object)new FileWriterControllerText());
CommandManager.Instance.AddConsoleCommand((ConsoleCommand)(object)new IconExport());
PrefabManager.OnPrefabsRegistered += ApplyMocks;
ModQuery.Enable();
}
private static void LoadBlacklist()
{
string text = AssetUtils.LoadTextFromResources("ItemBlacklist.json", Assembly.GetExecutingAssembly());
ItemBlacklist = SimpleJson.DeserializeObject<List<string>>(text).ToHashSet();
string path = Path.Combine(Paths.ConfigPath, "com.maxsch.valheim.vnei.blacklist.txt");
if (!File.Exists(path))
{
File.WriteAllText(path, "");
return;
}
string[] array = File.ReadAllLines(path);
foreach (string text2 in array)
{
string text3 = text2.Trim();
if (!string.IsNullOrEmpty(text3) && !ItemBlacklist.Contains(text3))
{
ItemBlacklist.Add(text2);
}
}
}
private void Start()
{
ModCompat.Init(harmony);
PlanBuild.Init();
EpicLootCompat.Init();
WackysDatabaseCompat.Init();
}
private void Update()
{
//IL_0006: Unknown result type (might be due to invalid IL or missing references)
//IL_00ad: Unknown result type (might be due to invalid IL or missing references)
if (openHotkey.Value.IsKeyDown())
{
OpenUI();
}
if (!Indexing.HasIndexed() && Object.op_Implicit((Object)(object)Player.m_localPlayer))
{
Indexing.IndexAll();
Indexing.UpdateKnown();
showOnlyKnown.SettingChanged += delegate
{
Indexing.UpdateKnown();
};
forceShowOnlyKnown.SettingChanged += delegate
{
Indexing.UpdateKnown();
};
KnownRecipesPatches.OnUpdateKnownRecipes += Indexing.UpdateKnown;
}
if (!viewRecipeHotkey.Value.IsKeyDown() || !Object.op_Implicit((Object)(object)UITooltip.m_current))
{
return;
}
string text = UITooltip.m_current.m_topic.Trim();
string text2 = UITooltip.m_current.m_text.Trim();
Item item = null;
if (text.Length > 0)
{
item = Indexing.GetItem(text);
}
if (item == null && text2.Length > 0)
{
item = Indexing.GetItem(text2);
}
if (item == null && RichTagRegex.IsMatch(text))
{
string name = RichTagRegex.Replace(text, string.Empty).Trim();
item = Indexing.GetItem(name);
}
if (item != null)
{
if (attachToCrafting.Value)
{
GetMainUI().SetTabActive();
}
BaseUI baseUI = GetMainUI().GetBaseUI();
baseUI.ShowRecipe(item, trackHistory: true);
}
}
public static void OpenUI()
{
isUiOpen = !isUiOpen;
Plugin.OnOpenHotkey?.Invoke();
}
public static bool AttachToCrafting()
{
return attachToCrafting.Value;
}
private void ApplyMocks()
{
PrefabExtension.FixReferences(vneiUI, true);
PrefabExtension.FixReferences(displayItemTemplate, true);
PrefabExtension.FixReferences(craftingStationTemplate, true);
PrefabManager.OnPrefabsRegistered -= ApplyMocks;
}
public static bool IsItemBlacklisted(Item item)
{
return ItemBlacklist.Contains(item.internalName) || ItemBlacklist.Contains(Indexing.CleanupName(item.internalName));
}
public static VneiHandler GetMainUI()
{
if (IsAugaLoaded())
{
return MainVneiHandlerAuga.Instance;
}
return MainVneiHandler.Instance;
}
public static bool IsAugaLoaded()
{
return Chainloader.PluginInfos.ContainsKey("randyknapp.mods.auga");
}
}
}
namespace VNEI.Patches
{
[HarmonyPatch]
public class InventoryGuiPatch
{
[CompilerGenerated]
private sealed class <UpdateOtherTabs>d__1 : IEnumerator<object>, IDisposable, IEnumerator
{
private int <>1__state;
private object <>2__current;
private WaitForSeconds <wait>5__1;
object IEnumerator<object>.Current
{
[DebuggerHidden]
get
{
return <>2__current;
}
}
object IEnumerator.Current
{
[DebuggerHidden]
get
{
return <>2__current;
}
}
[DebuggerHidden]
public <UpdateOtherTabs>d__1(int <>1__state)
{
this.<>1__state = <>1__state;
}
[DebuggerHidden]
void IDisposable.Dispose()
{
<wait>5__1 = null;
<>1__state = -2;
}
private bool MoveNext()
{
//IL_0026: Unknown result type (might be due to invalid IL or missing references)
//IL_0030: Expected O, but got Unknown
switch (<>1__state)
{
default:
return false;
case 0:
<>1__state = -1;
<wait>5__1 = new WaitForSeconds(1f);
break;
case 1:
<>1__state = -1;
MainVneiHandler.Instance.UpdateOtherTabs();
break;
}
<>2__current = <wait>5__1;
<>1__state = 1;
return true;
}
bool IEnumerator.MoveNext()
{
//ILSpy generated this explicit interface implementation from .override directive in MoveNext
return this.MoveNext();
}
[DebuggerHidden]
void IEnumerator.Reset()
{
throw new NotSupportedException();
}
}
[HarmonyPatch(typeof(InventoryGui), "Awake")]
[HarmonyPostfix]
[HarmonyPriority(200)]
public static void AwakePatch(InventoryGui __instance)
{
if (!Plugin.IsAugaLoaded())
{
MainVneiHandler.Instance.GetTabButton();
((MonoBehaviour)__instance).StartCoroutine(UpdateOtherTabs());
}
else
{
MainVneiHandlerAuga.Instance.CreateBaseUI();
}
}
[IteratorStateMachine(typeof(<UpdateOtherTabs>d__1))]
private static IEnumerator UpdateOtherTabs()
{
//yield-return decompiler failed: Unexpected instruction in Iterator.Dispose()
return new <UpdateOtherTabs>d__1(0);
}
[HarmonyPatch(typeof(InventoryGui), "UpdateCraftingPanel")]
[HarmonyPostfix]
[HarmonyAfter(new string[] { "org.bepinex.plugins.jewelcrafting" })]
public static void UpdateCraftingPanelPatch()
{
if (!Plugin.IsAugaLoaded())
{
MainVneiHandler.Instance.UpdateTabPosition();
if (MainVneiHandler.Instance.VneiTabActive)
{
MainVneiHandler.Instance.SetTabActive();
}
}
}
[HarmonyPatch(typeof(InventoryGui), "OnTabCraftPressed")]
[HarmonyPatch(typeof(InventoryGui), "OnTabUpgradePressed")]
[HarmonyPrefix]
public static void OnTabCraftPressedPatch()
{
if (!Plugin.IsAugaLoaded())
{
MainVneiHandler.Instance.SetTabInactive();
}
}
[HarmonyPatch(typeof(InventoryGui), "SetupCrafting")]
[HarmonyPostfix]
[HarmonyAfter(new string[] { "org.bepinex.plugins.jewelcrafting" })]
public static void SetupCraftingPatch()
{
if (!Plugin.IsAugaLoaded() && MainVneiHandler.Instance.VneiTabActive)
{
MainVneiHandler.Instance.SetTabActive();
}
}
}
public class ModCompat
{
private class ValheimRecycleFix
{
[CompilerGenerated]
private sealed class <TargetMethods>d__0 : IEnumerable<MethodBase>, IEnumerable, IEnumerator<MethodBase>, IDisposable, IEnumerator
{
private int <>1__state;
private MethodBase <>2__current;
private int <>l__initialThreadId;
private Type <valheimRecycle>5__1;
MethodBase IEnumerator<MethodBase>.Current
{
[DebuggerHidden]
get
{
return <>2__current;
}
}
object IEnumerator.Current
{
[DebuggerHidden]
get
{
return <>2__current;
}
}
[DebuggerHidden]
public <TargetMethods>d__0(int <>1__state)
{
this.<>1__state = <>1__state;
<>l__initialThreadId = Environment.CurrentManagedThreadId;
}
[DebuggerHidden]
void IDisposable.Dispose()
{
<valheimRecycle>5__1 = null;
<>1__state = -2;
}
private bool MoveNext()
{
switch (<>1__state)
{
default:
return false;
case 0:
<>1__state = -1;
<valheimRecycle>5__1 = Type.GetType("ValheimRecycle.ValheimRecycle, ValheimRecycle, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null");
<>2__current = <valheimRecycle>5__1.GetMethod("GetOrCreateRecycleTab", BindingFlags.Instance | BindingFlags.NonPublic);
<>1__state = 1;
return true;
case 1:
<>1__state = -1;
return false;
}
}
bool IEnumerator.MoveNext()
{
//ILSpy generated this explicit interface implementation from .override directive in MoveNext
return this.MoveNext();
}
[DebuggerHidden]
void IEnumerator.Reset()
{
throw new NotSupportedException();
}
[DebuggerHidden]
IEnumerator<MethodBase> IEnumerable<MethodBase>.GetEnumerator()
{
if (<>1__state == -2 && <>l__initialThreadId == Environment.CurrentManagedThreadId)
{
<>1__state = 0;
return this;
}
return new <TargetMethods>d__0(0);
}
[DebuggerHidden]
IEnumerator IEnumerable.GetEnumerator()
{
return ((IEnumerable<MethodBase>)this).GetEnumerator();
}
}
[IteratorStateMachine(typeof(<TargetMethods>d__0))]
[UsedImplicitly]
private static IEnumerable<MethodBase> TargetMethods()
{
//yield-return decompiler failed: Unexpected instruction in Iterator.Dispose()
return new <TargetMethods>d__0(-2);
}
[UsedImplicitly]
private static void Postfix(GameObject __result)
{
__result.transform.SetSiblingIndex(2);
}
}
public static void Init(Harmony harmony)
{
if (Chainloader.PluginInfos.ContainsKey("org.lafchi.plugins.valheim_recycle"))
{
harmony.PatchAll(typeof(ValheimRecycleFix));
}
}
}
[HarmonyPatch]
public class KnownRecipesPatches
{
public static event Action OnUpdateKnownRecipes;
[HarmonyPatch(typeof(Player), "UpdateKnownRecipesList")]
[HarmonyPatch(typeof(Player), "OnSpawned")]
[HarmonyPatch(typeof(Player), "ResetCharacterKnownItems")]
[HarmonyPostfix]
public static void UpdateKnownRecipesListPatch()
{
KnownRecipesPatches.OnUpdateKnownRecipes?.Invoke();
}
}
}
namespace VNEI.Logic
{
public readonly struct Amount
{
public readonly int min;
public readonly int max;
public readonly float chance;
public static Amount Zero { get; } = new Amount(0, 0, 0f);
public static Amount One { get; } = new Amount(1);
public Amount(int min, int max, float chance = 1f)
{
this.min = min;
this.max = max;
this.chance = chance;
}
public Amount(int amount, float chance = 1f)
{
min = amount;
max = amount;
this.chance = chance;
}
public static bool IsSameMinMax(Amount a, Amount b)
{
return a.min == b.min && a.max == b.max;
}
public override string ToString()
{
int num = Mathf.RoundToInt(chance * 100f);
string text = "";
bool flag = false;
if (num != 100)
{
text += $"{num}% ";
flag = true;
}
if (min == max)
{
if (!flag || max != 1)
{
text += $"{max}x";
}
}
else
{
text += $"{min}-{max}x";
}
return text;
}
public bool Equals(Amount other)
{
int result;
if (min == other.min && max == other.max)
{
float num = chance;
result = (num.Equals(other.chance) ? 1 : 0);
}
else
{
result = 0;
}
return (byte)result != 0;
}
public override bool Equals(object obj)
{
return obj is Amount other && Equals(other);
}
public override int GetHashCode()
{
int num = min;
num = (num * 397) ^ max;
int num2 = num * 397;
float num3 = chance;
return num2 ^ num3.GetHashCode();
}
}
public static class BepInExExtensions
{
public static bool IsKeyDown(this KeyboardShortcut shortcut)
{
//IL_0028: Unknown result type (might be due to invalid IL or missing references)
//IL_0031: Unknown result type (might be due to invalid IL or missing references)
BaseUI baseUI = Plugin.GetMainUI().GetBaseUI();
if (!Object.op_Implicit((Object)(object)baseUI) || baseUI.BlockInput)
{
return false;
}
if ((int)((KeyboardShortcut)(ref shortcut)).MainKey == 0 || !Input.GetKeyDown(((KeyboardShortcut)(ref shortcut)).MainKey) || !((KeyboardShortcut)(ref shortcut)).Modifiers.All((Func<KeyCode, bool>)Input.GetKey))
{
return false;
}
if (TextInput.IsVisible())
{
return false;
}
return true;
}
}
public class ComponentEvent
{
private readonly Dictionary<Component, Action> listener = new Dictionary<Component, Action>();
public void AddListener(Component component, Action action)
{
if (!listener.ContainsKey(component))
{
listener.Add(component, action);
}
}
public void RemoveListener(Component component)
{
listener.Remove(component);
}
public void Invoke()
{
bool flag = false;
foreach (KeyValuePair<Component, Action> item in listener)
{
if (!Object.op_Implicit((Object)(object)item.Key))
{
flag = true;
}
else
{
item.Value?.Invoke();
}
}
if (flag)
{
RemoveDestroyedKeys();
}
}
private void RemoveDestroyedKeys()
{
listener.Keys.Where((Component i) => !Object.op_Implicit((Object)(object)i)).ToList().ForEach(delegate(Component i)
{
listener.Remove(i);
});
}
}
public static class ExportPaths
{
private static string GetMainExportFolder()
{
return Path.Combine(Paths.BepInExRootPath, "VNEI-Export");
}
public static string GetExportLocation(string fileName, params string[] path)
{
string text = Path.Combine(GetMainExportFolder(), Path.Combine(path), fileName);
string directoryName = Path.GetDirectoryName(text);
if (directoryName == null || string.IsNullOrEmpty(directoryName))
{
throw new DirectoryNotFoundException("Invalid directory for " + fileName + ": " + directoryName);
}
if (!Directory.Exists(directoryName))
{
Directory.CreateDirectory(directoryName);
}
return text;
}
}
public static class FileWriter
{
private const string FileName = "VNEI.indexed.items";
private const string MissingType = "missing-type";
public static void PrintSimpleTextFile(List<Item> items)
{
string exportLocation = ExportPaths.GetExportLocation("VNEI.indexed.items.txt");
Log.LogInfo("Writing indexed items to file " + exportLocation);
File.WriteAllLines(exportLocation, items.Select((Item item) => item.PrintItem()).ToArray());
}
public static void PrintCSVFile(List<Item> items, string separator)
{
string exportLocation = ExportPaths.GetExportLocation("VNEI.indexed.items.csv");
Log.LogInfo("Writing indexed items to file " + exportLocation);
string text = Item.PrintCSVHeader(separator);
string[] second = items.Select((Item item) => EncapsulateFields(item.PrintItemCSV(separator), separator)).ToArray();
File.WriteAllLines(exportLocation, new string[1] { text }.Concat(second).ToArray());
}
private static string EncapsulateFields(string csvLine, string separator)
{
string[] source = csvLine.Split(new string[1] { separator }, StringSplitOptions.None);
IEnumerable<string> values = source.Select((string field) => "\"" + field.Replace("\"", "\"\"") + "\"");
return string.Join(separator, values);
}
public static void PrintCLLCItemConfigYaml(List<Item> items, List<string> itemNamesFilterExcluded, List<string> modNamesFilterExcluded, List<string> modNamesFilterInclude)
{
//IL_0098: Unknown result type (might be due to invalid IL or missing references)
//IL_00a7: Expected O, but got Unknown
string exportLocation = ExportPaths.GetExportLocation("VNEI.indexed.items.yml");
Log.LogInfo("Writing indexed items to file " + exportLocation);
Log.LogInfo("Excluding items via match terms '" + string.Join(",", itemNamesFilterExcluded) + "' and mods with names matching '" + string.Join(",", modNamesFilterExcluded) + "'");
if (modNamesFilterInclude.Count > 0)
{
Log.LogInfo("Including items from mods with names matching '" + string.Join(",", modNamesFilterInclude) + "'");
}
ISerializer val = ((BuilderSkeleton<SerializerBuilder>)new SerializerBuilder()).WithNamingConvention(CamelCaseNamingConvention.Instance).Build();
ItemDrop val2 = default(ItemDrop);
List<(string, string, string)> source = (from item in FilterInvalidItems(items, itemNamesFilterExcluded, modNamesFilterExcluded, modNamesFilterInclude)
select (item.prefab.TryGetComponent<ItemDrop>(ref val2) ? ((object)(ItemType)(ref val2.m_itemData.m_shared.m_itemType)).ToString() : item.itemType.ToString(), item.internalName, item.GetModName())).ToList();
Dictionary<string, List<string>> groups = (from @group in source.GroupBy<(string, string, string), string>(delegate((string itemType, string internalName, string modName) item)
{
string result;
if (!(item.modName != string.Empty))
{
(result, _, _) = item;
}
else
{
result = item.itemType + "_" + CleanModName(item.modName);
}
return result;
})
where @group.Key != "missing-type"
select @group).ToDictionary((IGrouping<string, (string itemType, string internalName, string modName)> group) => group.Key, (IGrouping<string, (string itemType, string internalName, string modName)> group) => group.Select(((string itemType, string internalName, string modName) groupedItem) => groupedItem.internalName).ToList());
string contents = val.Serialize((object)new AllGroups(groups));
File.WriteAllText(exportLocation, contents);
}
private static List<Item> FilterInvalidItems(List<Item> items, List<string> itemNamesFilterExcluded, List<string> modNamesFilterExcluded, List<string> modNamesFilterInclude)
{
return (from item in items
where (Object)(object)item.prefab != (Object)null
where itemNamesFilterExcluded.All((string filterExclude) => !item.internalName.Contains(filterExclude))
select item).FilterExcludeMod(modNamesFilterExcluded).FilterIncludeMod(modNamesFilterInclude).ToList();
}
private static IEnumerable<Item> FilterExcludeMod(this IEnumerable<Item> items, List<string> modNamesFilterExcluded)
{
return items.Where((Item item) => modNamesFilterExcluded.All((string filterExclude) => !item.GetModName().Contains(filterExclude))).ToList();
}
private static IEnumerable<Item> FilterIncludeMod(this IEnumerable<Item> items, List<string> modNamesFilterInclude)
{
if (modNamesFilterInclude.Count == 0)
{
return items;
}
return items.Where((Item item) => modNamesFilterInclude.Any((string filterInclude) => item.GetModName().Contains(filterInclude))).ToList();
}
private static string CleanModName(string modNameOriginal)
{
return Regex.Replace(modNameOriginal, "[^\\w]+", "_");
}
}
public class AllGroups
{
[UsedImplicitly]
public readonly Dictionary<string, List<string>> Groups;
public AllGroups(Dictionary<string, List<string>> groups)
{
Groups = groups;
}
}
public abstract class FileWriterController : ConsoleCommand
{
public override string Help => "Writes all indexed items to a file";
protected static List<Item> GetItems()
{
return (from tuple in Indexing.GetActiveItems()
select tuple.Value).ToList();
}
}
public class FileWriterControllerCSV : FileWriterController
{
public override string Name => "vnei_export_csv";
public override void Run(string[] args)
{
FileWriter.PrintCSVFile(separator: ((args.Length != 0) ? args[0] : string.Empty) switch
{
"comma" => ",",
"tab" => "\t",
"semicolon" => ";",
_ => ",",
}, items: FileWriterController.GetItems());
}
public override List<string> CommandOptionList()
{
return new List<string> { "comma", "semicolon", "tab" };
}
}
public class FileWriterControllerYAML : FileWriterController
{
public override string Name => "vnei_export_yaml";
public override void Run(string[] args)
{
Log.LogInfo("args '" + string.Join("' '", args) + "'");
List<string> itemNamesFilterExcluded = ((args.Length != 0) ? args[0].Split(new char[1] { ',' }).ToList() : new List<string>());
List<string> modNamesFilterExcluded = ((args.Length > 1) ? args[1].Split(new char[1] { ',' }).ToList() : new List<string>());
List<string> modNamesFilterInclude = ((args.Length > 2) ? args[2].Split(new char[1] { ',' }).ToList() : new List<string>());
FileWriter.PrintCLLCItemConfigYaml(FileWriterController.GetItems(), itemNamesFilterExcluded, modNamesFilterExcluded, modNamesFilterInclude);
}
}
public class FileWriterControllerText : FileWriterController
{
public override string Name => "vnei_export_text";
public override void Run(string[] args)
{
FileWriter.PrintSimpleTextFile(FileWriterController.GetItems());
}
}
public class IconExport : ConsoleCommand
{
public override string Name => "vnei_export_icons";
public override string Help => "Exports icons";
public override void Run(string[] args)
{
List<Item> source = (from tuple in Indexing.GetActiveItems()
select tuple.Value).ToList();
Log.LogInfo("Exporting icons into " + ExportPaths.GetExportLocation("", "icons"));
foreach (IGrouping<string, Item> item in from item in source
group item by item.GetModName())
{
if (args.Length >= 1 && !args[0].Split(new char[1] { ',' }).Contains(item.Key))
{
continue;
}
Log.LogInfo($"Exporting {item.Count()} icons for {item.Key}");
foreach (Item item2 in item)
{
SaveIcon(item2);
}
}
}
private static void SaveIcon(Item item)
{
//IL_0113: Unknown result type (might be due to invalid IL or missing references)
//IL_0118: 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_012a: Unknown result type (might be due to invalid IL or missing references)
//IL_0137: Unknown result type (might be due to invalid IL or missing references)
//IL_013c: Unknown result type (might be due to invalid IL or missing references)
//IL_0146: Unknown result type (might be due to invalid IL or missing references)
//IL_0155: Unknown result type (might be due to invalid IL or missing references)
//IL_015a: 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_0176: Unknown result type (might be due to invalid IL or missing references)
//IL_017d: Expected O, but got Unknown
//IL_018b: Unknown result type (might be due to invalid IL or missing references)
if (!Object.op_Implicit((Object)(object)item.prefab))
{
return;
}
Sprite icon = item.GetIcon();
if (!Object.op_Implicit((Object)(object)icon))
{
Log.LogWarning("No icon for " + item.internalName);
return;
}
string fileName = Path.GetInvalidFileNameChars().Aggregate(item.internalName + ".png", (string current, char c) => current.Replace(c, '_'));
string text = Path.GetInvalidPathChars().Aggregate(item.GetModName(), (string current, char c) => current.Replace(c, '_'));
string exportLocation = ExportPaths.GetExportLocation(fileName, "icons", text);
int width = ((Texture)icon.texture).width;
int height = ((Texture)icon.texture).height;
RenderTexture temporary = RenderTexture.GetTemporary(width, height);
Graphics.Blit((Texture)(object)icon.texture, temporary);
RenderTexture active = RenderTexture.active;
RenderTexture.active = temporary;
Rect val = icon.rect;
int num = (int)((Rect)(ref val)).width;
val = icon.rect;
int num2 = (int)((Rect)(ref val)).height;
val = icon.textureRect;
int num3 = (int)(((Rect)(ref val)).x - icon.textureRectOffset.x);
val = icon.textureRect;
int num4 = (int)(((Rect)(ref val)).y - icon.textureRectOffset.y);
Texture2D val2 = new Texture2D(num, num2);
val2.ReadPixels(new Rect((float)num3, (float)num4, (float)num, (float)num2), 0, 0);
val2.Apply();
RenderTexture.active = active;
RenderTexture.ReleaseTemporary(temporary);
File.WriteAllBytes(exportLocation, ImageConversion.EncodeToPNG(val2));
}
}
public class FavouritesSave
{
public const string favouritesFileName = "com.maxsch.valheim.vnei.favourites.txt";
public static string GetFavouritesFilePath()
{
return Path.Combine(Paths.ConfigPath, "com.maxsch.valheim.vnei.favourites.txt");
}
public static void Load()
{
string favouritesFilePath = GetFavouritesFilePath();
if (!File.Exists(favouritesFilePath))
{
return;
}
using StreamReader streamReader = File.OpenText(favouritesFilePath);
while (!streamReader.EndOfStream)
{
string text = streamReader.ReadLine();
if (!string.IsNullOrEmpty(text))
{
Item item = Indexing.GetItem(text);
if (item != null)
{
item.isFavorite = true;
}
}
}
}
public static void Save()
{
using StreamWriter streamWriter = File.CreateText(GetFavouritesFilePath());
foreach (KeyValuePair<string, Item> activeItem in Indexing.GetActiveItems())
{
if (activeItem.Value.isFavorite)
{
streamWriter.WriteLine(activeItem.Value.internalName);
}
}
}
}
public static class Indexing
{
private static int currentKnownCount;
private static bool currentShowOnlyKnown;
private static Dictionary<string, Item> Items { get; } = new Dictionary<string, Item>();
private static Dictionary<string, Item> ItemsByPreLocalizedName { get; } = new Dictionary<string, Item>();
private static Dictionary<string, Item> ItemsByLocalizedName { get; } = new Dictionary<string, Item>();
public static event Action<GameObject> OnIndexingItems;
public static event Action<GameObject> OnDisableItems;
public static event Action AfterDisableItems;
public static event Action<Recipe> OnIndexingRecipes;
public static event Action<GameObject> OnIndexingItemRecipes;
public static event Action AfterIndexingItems;
public static event Action AfterIndexingRecipes;
public static event Action IndexFinished;
public static event Action AfterUpdateKnownItems;
public static void IndexAll()
{
if (HasIndexed())
{
return;
}
if (!Object.op_Implicit((Object)(object)ZNetScene.instance))
{
Log.LogWarning("Cannot index: ZNetScene.instance is null");
return;
}
Log.LogInfo("Index items and recipes");
ModNames.IndexModNames();
Dictionary<string, PieceTable> pieceTables = new Dictionary<string, PieceTable>();
List<GameObject> prefabs = GetPrefabs();
IndexItems(prefabs, pieceTables);
DisableItems(prefabs);
IndexRecipes();
IndexItemRecipes(prefabs, pieceTables);
foreach (RecipeInfo recipe in RecipeInfo.Recipes)
{
recipe.CalculateIsOnBlacklist();
recipe.CalculateWidth();
}
FavouritesSave.Load();
Log.LogInfo($"Loaded {GetActiveItems().Count()} items and {RecipeInfo.Recipes.Count} recipes");
try
{
Indexing.IndexFinished?.Invoke();
}
catch (Exception data)
{
Log.LogError(data);
}
}
private static List<GameObject> GetPrefabs()
{
HashSet<GameObject> first = new HashSet<GameObject>(ZNetScene.instance.m_prefabs);
HashSet<GameObject> second = new HashSet<GameObject>(ZNetScene.instance.m_namedPrefabs.Values);
List<GameObject> list = first.Union(second).ToList();
list.RemoveAll((GameObject prefab) => !Object.op_Implicit((Object)(object)prefab));
return list;
}
private static void IndexItems(List<GameObject> prefabs, Dictionary<string, PieceTable> pieceTables)
{
//IL_02b3: Unknown result type (might be due to invalid IL or missing references)
//IL_02b8: Unknown result type (might be due to invalid IL or missing references)
AddItem(new Item("vnei_any_item", "$vnei_any_item", string.Empty, null, ItemType.Undefined, null));
AddItem(new Item("vnei_unknown_item", "$vnei_unknown_item", string.Empty, null, ItemType.Undefined, null));
AddItem(new Item("vnei_all_stations", "$vnei_all_stations", "", null, ItemType.Undefined, null));
AddItem(new Item("vnei_hand_station", "$vnei_hand_station", "", Plugin.Instance.inventoryIcon, ItemType.Undefined, null));
AddItem(new Item("vnei_no_station", "$vnei_no_station", "", null, ItemType.Undefined, null));
Plugin.Instance.allStations = GetItem("vnei_all_stations");
Plugin.Instance.handStation = GetItem("vnei_hand_station");
Plugin.Instance.noStation = GetItem("vnei_no_station");
DisableItem("vnei_any_item", "is not an item");
DisableItem("vnei_unknown_item", "is not an item");
DisableItem("vnei_all_stations", "is not an item");
DisableItem("vnei_hand_station", "is not an item");
DisableItem("vnei_no_station", "is not an item");
HoverText val = default(HoverText);
CraftingStation val2 = default(CraftingStation);
ItemDrop val3 = default(ItemDrop);
foreach (GameObject prefab in prefabs)
{
string name = ((Object)prefab).name;
string text = string.Empty;
if (prefab.TryGetComponent<HoverText>(ref val))
{
text = val.m_text;
}
if (string.IsNullOrEmpty(text) && prefab.TryGetComponent<CraftingStation>(ref val2))
{
text = val2.m_name;
}
if (name.StartsWith("TreasureChest"))
{
TryAddItem<Piece>(prefab, (Func<Piece, string>)((Piece i) => i.m_name), text, ItemType.Piece, (Func<Piece, string>)((Piece i) => i.m_description), (Func<Piece, Sprite>)((Piece i) => i.m_icon));
}
if (prefab.TryGetComponent<ItemDrop>(ref val3))
{
ItemData itemData = val3.m_itemData;
Sprite icon = null;
if (Object.op_Implicit((Object)(object)val3) && itemData.m_shared.m_icons.Length != 0)
{
icon = itemData.GetIcon();
}
if (itemData.m_shared.m_damageModifiers == null)
{
itemData.m_shared.m_damageModifiers = new List<DamageModPair>();
}
ItemType itemType = ItemTypeHelper.GetItemType(itemData);
SharedData shared = itemData.m_shared;
Item item = new Item(name, shared.m_name, shared.m_description, icon, itemType, prefab, shared.m_maxQuality);
item.itemDropType = itemData.m_shared.m_itemType;
AddItem(item);
if (Object.op_Implicit((Object)(object)itemData.m_shared.m_buildPieces))
{
pieceTables.Add(CleanupName(name), itemData.m_shared.m_buildPieces);
}
}
TryAddItem<Character>(prefab, (Func<Character, string>)((Character i) => i.m_name), text, ItemType.Creature, (Func<Character, string>)null, (Func<Character, Sprite>)null);
TryAddItem<MineRock>(prefab, (Func<MineRock, string>)((MineRock i) => i.m_name), text, ItemType.Undefined, (Func<MineRock, string>)null, (Func<MineRock, Sprite>)null);
TryAddItem<MineRock5>(prefab, (Func<MineRock5, string>)((MineRock5 i) => i.m_name), text, ItemType.Undefined, (Func<MineRock5, string>)null, (Func<MineRock5, Sprite>)null);
TryAddItem<DropOnDestroyed>(prefab, (Func<DropOnDestroyed, string>)((DropOnDestroyed i) => string.Empty), text, ItemType.Undefined, (Func<DropOnDestroyed, string>)null, (Func<DropOnDestroyed, Sprite>)null);
TryAddItem<Pickable>(prefab, (Func<Pickable, string>)((Pickable i) => string.Empty), text, ItemType.Undefined, (Func<Pickable, string>)null, (Func<Pickable, Sprite>)null);
TryAddItem<SpawnArea>(prefab, (Func<SpawnArea, string>)((SpawnArea i) => string.Empty), text, ItemType.Creature, (Func<SpawnArea, string>)null, (Func<SpawnArea, Sprite>)null);
TryAddItem<Destructible>(prefab, (Func<Destructible, string>)((Destructible i) => string.Empty), text, ItemType.Undefined, (Func<Destructible, string>)null, (Func<Destructible, Sprite>)null);
TryAddItem<TreeBase>(prefab, (Func<TreeBase, string>)((TreeBase i) => string.Empty), text, ItemType.Undefined, (Func<TreeBase, string>)null, (Func<TreeBase, Sprite>)null);
TryAddItem<Trader>(prefab, (Func<Trader, string>)((Trader i) => i.m_name), text, ItemType.Undefined, (Func<Trader, string>)null, (Func<Trader, Sprite>)null);
try
{
Indexing.OnIndexingItems?.Invoke(prefab);
}
catch (Exception data)
{
Log.LogError(data);
}
}
foreach (PieceTable value in pieceTables.Values)
{
foreach (GameObject piece in value.m_pieces)
{
TryAddItem<Piece>(piece, (Func<Piece, string>)((Piece i) => i.m_name), ((Object)piece).name, ItemType.Piece, (Func<Piece, string>)((Piece i) => i.m_description), (Func<Piece, Sprite>)((Piece i) => i.m_icon));
try
{
Indexing.OnIndexingItems?.Invoke(piece);
}
catch (Exception data2)
{
Log.LogError(data2);
}
}
}
try
{
Indexing.AfterIndexingItems?.Invoke();
}
catch (Exception data3)
{
Log.LogError(data3);
}
}
private static void DisableItems(List<GameObject> prefabs)
{
Piece val = default(Piece);
Humanoid val2 = default(Humanoid);
foreach (GameObject prefab in prefabs)
{
if (prefab.TryGetComponent<Piece>(ref val) && GetItem(((Object)prefab).name) == null)
{
Log.LogDebug("not indexed piece " + ((Object)val).name + ": not buildable");
}
if (prefab.TryGetComponent<Humanoid>(ref val2))
{
DisableArray(prefab, val2.m_defaultItems);
DisableArray(prefab, val2.m_randomWeapon);
DisableArray(prefab, val2.m_randomShield);
DisableArray(prefab, val2.m_randomArmor);
if (val2.m_randomSets != null)
{
ItemSet[] randomSets = val2.m_randomSets;
for (int i = 0; i < randomSets.Length; i++)
{
DisableArray(prefab, randomSets[i]?.m_items);
}
}
DisableEffectList(prefab, ((Character)val2).m_hitEffects);
DisableEffectList(prefab, ((Character)val2).m_critHitEffects);
DisableEffectList(prefab, ((Character)val2).m_backstabHitEffects);
DisableEffectList(prefab, ((Character)val2).m_deathEffects);
DisableEffectList(prefab, ((Character)val2).m_waterEffects);
DisableEffectList(prefab, ((Character)val2).m_tarEffects);
DisableEffectList(prefab, ((Character)val2).m_slideEffects);
DisableEffectList(prefab, ((Character)val2).m_jumpEffects);
DisableEffectList(prefab, val2.m_pickupEffects);
DisableEffectList(prefab, val2.m_dropEffects);
DisableEffectList(prefab, val2.m_consumeItemEffects);
DisableEffectList(prefab, val2.m_equipEffects);
DisableEffectList(prefab, val2.m_perfectBlockEffect);
}
try
{
Indexing.OnDisableItems?.Invoke(prefab);
}
catch (Exception data)
{
Log.LogError(data);
}
}
try
{
Indexing.AfterDisableItems?.Invoke();
}
catch (Exception data2)
{
Log.LogError(data2);
}
}
private static void DisableArray(GameObject from, GameObject[] array)
{
if (array == null)
{
return;
}
foreach (GameObject item in array.Where((GameObject i) => Object.op_Implicit((Object)(object)i)))
{
ItemDrop component = item.GetComponent<ItemDrop>();
if (Object.op_Implicit((Object)(object)component))
{
ItemData itemData = component.m_itemData;
if (itemData != null && itemData.m_shared?.m_icons?.Length > 0)
{
Log.LogDebug("Not disabling item " + ((Object)item).name + " because it has icons");
continue;
}
}
DisableItem(((Object)item).name, "is defaultItem from " + ((Object)from).name);
}
}
private static void DisableEffectList(GameObject from, EffectList effectList)
{
if (effectList?.m_effectPrefabs == null)
{
return;
}
foreach (EffectData item in effectList.m_effectPrefabs.Where((EffectData i) => i != null && Object.op_Implicit((Object)(object)i.m_prefab)))
{
DisableItem(((Object)item.m_prefab).name, "is defaultItem from " + ((Object)from).name);
}
}
private static void IndexRecipes()
{
if (!Object.op_Implicit((Object)(object)ObjectDB.instance))
{
Log.LogWarning("Cannot index recipes: ObjectDB.instance is null");
return;
}
foreach (Recipe recipe in ObjectDB.instance.m_recipes)
{
bool flag = WackysDatabaseCompat.HasRecipeEnableOverride(recipe);
if (!(recipe.m_enabled || flag) || !Object.op_Implicit((Object)(object)recipe.m_item))
{
continue;
}
for (int i = 1; i <= recipe.m_item.m_itemData.m_shared.m_maxQuality; i++)
{
if ((!flag || i != 1 || !WackysDatabaseCompat.CanBeUpgraded(recipe)) && (!flag || i <= 1 || !WackysDatabaseCompat.CanBeCrafted(recipe)))
{
AddRecipeToItems(new RecipeInfo(recipe, i));
}
}
try
{
Indexing.OnIndexingRecipes?.Invoke(recipe);
}
catch (Exception data)
{
Log.LogError(data);
}
}
}
private static void IndexItemRecipes(List<GameObject> prefabs, Dictionary<string, PieceTable> pieceTables)
{
Incinerator val = default(Incinerator);
Piece val2 = default(Piece);
Container val3 = default(Container);
Destructible val4 = default(Destructible);
foreach (GameObject prefab in prefabs)
{
TryAddRecipeToItemsForEach<Smelter, ItemConversion>(prefab, (Func<Smelter, List<ItemConversion>>)((Smelter i) => i.m_conversion), (Func<Smelter, ItemConversion, RecipeInfo>)((Smelter s, ItemConversion i) => new RecipeInfo(i, s)));
TryAddRecipeToItemsForEach<Fermenter, ItemConversion>(prefab, (Func<Fermenter, List<ItemConversion>>)((Fermenter i) => i.m_conversion), (Func<Fermenter, ItemConversion, RecipeInfo>)((Fermenter f, ItemConversion i) => new RecipeInfo(i, f)));
TryAddRecipeToItemsForEach<CookingStation, ItemConversion>(prefab, (Func<CookingStation, List<ItemConversion>>)((CookingStation i) => i.m_conversion), (Func<CookingStation, ItemConversion, RecipeInfo>)((CookingStation c, ItemConversion i) => new RecipeInfo(i, c)));
if (prefab.TryGetComponent<Incinerator>(ref val))
{
AddRecipeToItems(new RecipeInfo(val));
foreach (IncineratorConversion conversion in val.m_conversions)
{
if (conversion.m_requireOnlyOneIngredient)
{
foreach (Requirement requirement in conversion.m_requirements)
{
AddRecipeToItems(new RecipeInfo(conversion, requirement, val));
}
}
else
{
AddRecipeToItems(new RecipeInfo(conversion, val));
}
}
}
TryAddRecipeToItems<CharacterDrop>(prefab, (Func<CharacterDrop, RecipeInfo>)((CharacterDrop i) => new RecipeInfo(i)), (Func<CharacterDrop, bool>)((CharacterDrop i) => Object.op_Implicit((Object)(object)((Component)i).GetComponent<Character>())));
TryAddRecipeToItems<Growup>(prefab, (Func<Growup, RecipeInfo>)((Growup i) => new RecipeInfo(i)), (Func<Growup, bool>)null);
TryAddRecipeToItems<MineRock>(prefab, (Func<MineRock, RecipeInfo>)((MineRock i) => new RecipeInfo(prefab, i.m_dropItems)), (Func<MineRock, bool>)null);
TryAddRecipeToItems<MineRock5>(prefab, (Func<MineRock5, RecipeInfo>)((MineRock5 i) => new RecipeInfo(prefab, i.m_dropItems)), (Func<MineRock5, bool>)null);
TryAddRecipeToItems<DropOnDestroyed>(prefab, (Func<DropOnDestroyed, RecipeInfo>)((DropOnDestroyed i) => new RecipeInfo(prefab, i.m_dropWhenDestroyed)), (Func<DropOnDestroyed, bool>)null);
prefab.TryGetComponent<Piece>(ref val2);
if (Object.op_Implicit((Object)(object)val2) && prefab.TryGetComponent<Container>(ref val3) && val3.m_defaultItems.m_drops.Count > 0)
{
AddRecipeToItems(new RecipeInfo(((Component)val3).gameObject, val3.m_defaultItems));
}
TryAddRecipeToItems<Pickable>(prefab, (Func<Pickable, RecipeInfo>)((Pickable i) => new RecipeInfo(prefab, i)), (Func<Pickable, bool>)null);
TryAddRecipeToItems<SpawnArea>(prefab, (Func<SpawnArea, RecipeInfo>)((SpawnArea i) => new RecipeInfo(i)), (Func<SpawnArea, bool>)null);
if (prefab.TryGetComponent<Destructible>(ref val4))
{
if (Object.op_Implicit((Object)(object)val4.m_spawnWhenDestroyed) && GetItem(((Object)val4.m_spawnWhenDestroyed).name) != null)
{
AddRecipeToItems(new RecipeInfo(val4));
}
else if (((Behaviour)val4).enabled && !Object.op_Implicit((Object)(object)prefab.GetComponent<DropOnDestroyed>()) && !Object.op_Implicit((Object)(object)prefab.GetComponent<Plant>()))
{
DisableItem(((Object)prefab).name, "destructible.m_spawnWhenDestroyed is null or not indexed");
}
}
TryAddRecipeToItems<TreeBase>(prefab, (Func<TreeBase, RecipeInfo>)((TreeBase i) => new RecipeInfo(i)), (Func<TreeBase, bool>)null);
TryAddRecipeToItemsForEach<Trader, TradeItem>(prefab, (Func<Trader, List<TradeItem>>)((Trader i) => i.m_items), (Func<Trader, TradeItem, RecipeInfo>)((Trader t, TradeItem i) => new RecipeInfo(t, i)));
try
{
Indexing.OnIndexingItemRecipes?.Invoke(prefab);
}
catch (Exception data)
{
Log.LogError(data);
}
}
Piece val5 = default(Piece);
foreach (KeyValuePair<string, PieceTable> pieceTable in pieceTables)
{
if (!Object.op_Implicit((Object)(object)pieceTable.Value))
{
Log.LogDebug("IndexItemRecipes: pieceTable " + pieceTable.Key + " is null");
continue;
}
foreach (GameObject piece in pieceTable.Value.m_pieces)
{
if (!Object.op_Implicit((Object)(object)piece))
{
Log.LogDebug("IndexItemRecipes: prefab in pieceTables " + pieceTable.Key + " is null");
}
else if (piece.TryGetComponent<Piece>(ref val5) && !val5.m_repairPiece)
{
AddRecipeToItems(new RecipeInfo(piece, val5, GetItem(pieceTable.Key)));
}
}
}
try
{
Indexing.AfterIndexingRecipes?.Invoke();
}
catch (Exception data2)
{
Log.LogError(data2);
}
}
private static void TryAddItem<T>(GameObject target, Func<T, string> getName, string fallbackLocalizedName, ItemType itemType, Func<T, string> getDescription = null, Func<T, Sprite> getIcon = null) where T : Component
{
T arg = default(T);
if (!target.TryGetComponent<T>(ref arg))
{
return;
}
try
{
string description = getDescription?.Invoke(arg) ?? string.Empty;
Sprite icon = getIcon?.Invoke(arg);
string text = getName(arg);
if (string.IsNullOrEmpty(text))
{
text = fallbackLocalizedName;
}
Item item = new Item(((Object)target).name, text, description, icon, itemType, target);
AddItem(item);
}
catch (Exception ex)
{
Log.LogError(((Object)target).name + Environment.NewLine + ex?.ToString() + Environment.NewLine);
}
}
private static void TryAddRecipeToItems<T>(GameObject target, Func<T, RecipeInfo> getRecipe, Func<T, bool> check = null) where T : Component
{
T arg = default(T);
if (target.TryGetComponent<T>(ref arg) && (check == null || check(arg)))
{
RecipeInfo recipeInfo;
try
{
recipeInfo = getRecipe(arg);
}
catch (Exception ex)
{
Log.LogError(((Object)target).name + Environment.NewLine + ex?.ToString() + Environment.NewLine);
return;
}
AddRecipeToItems(recipeInfo);
}
}
private static void TryAddRecipeToItemsForEach<T1, T2>(GameObject target, Func<T1, List<T2>> getArray, Func<T1, T2, RecipeInfo> getRecipe) where T1 : Component
{
T1 val = default(T1);
if (!target.TryGetComponent<T1>(ref val))
{
return;
}
foreach (T2 item in getArray(val))
{
try
{
AddRecipeToItems(getRecipe(val, item));
}
catch (Exception ex)
{
Log.LogError(((Object)target).name + Environment.NewLine + ex?.ToString() + Environment.NewLine);
}
}
}
public static bool HasIndexed()
{
return Items.Count > 0;
}
public static void DisableItem(string name, string context)
{
Item item = GetItem(name);
if (item != null)
{
item.isActive = false;
Log.LogDebug("disabling " + name + ": " + context);
}
}
public static void AddItem(Item item)
{
string key = CleanupName(item.internalName);
if (!Items.ContainsKey(key))
{
Items[key] = item;
}
if (!string.IsNullOrEmpty(item.preLocalizeName) && (!ItemsByPreLocalizedName.TryGetValue(item.preLocalizeName, out var value) || IsSaplingItem(value)))
{
ItemsByPreLocalizedName[item.preLocalizeName] = item;
}
if (!string.IsNullOrEmpty(item.localizedName) && (!ItemsByLocalizedName.TryGetValue(item.localizedName, out var value2) || IsSaplingItem(value2)))
{
ItemsByLocalizedName[item.localizedName] = item;
}
}
private static bool IsSaplingItem(Item item)
{
return item.internalName.StartsWith("sapling_") || Object.op_Implicit((Object)(object)item.prefab.GetComponent<Plant>());
}
public static void ItemObtainedInRecipe(string name, RecipeInfo recipeInfo)
{
Item item = GetItem(name);
if (item != null)
{
item.result.Add(recipeInfo);
}
else
{
Log.LogDebug("cannot add recipe to obtaining, '" + CleanupName(name) + "' is not indexed");
}
}
public static void ItemUsedInRecipe(string name, RecipeInfo recipeInfo)
{
Item item = GetItem(name);
if (item != null)
{
item.ingredient.Add(recipeInfo);
}
else
{
Log.LogDebug("cannot add recipe to using, '" + CleanupName(name) + "' is not indexed");
}
}
public static void AddRecipeToItems(RecipeInfo recipeInfo)
{
foreach (Part item in recipeInfo.Ingredients.SelectMany((KeyValuePair<Amount, List<Part>> i) => i.Value))
{
ItemUsedInRecipe(item.item.internalName, recipeInfo);
}
foreach (Part item2 in recipeInfo.Results.SelectMany((KeyValuePair<Amount, List<Part>> i) => i.Value))
{
ItemObtainedInRecipe(item2.item.internalName, recipeInfo);
}
foreach (Part station in recipeInfo.Stations)
{
ItemUsedInRecipe(station.item.internalName, recipeInfo);
}
}
public static string CleanupName(string name)
{
return name.Replace("JVLmock_", "").ToLower();
}
[Obsolete]
public static void SetModOfPrefab(string prefabName, BepInPlugin mod)
{
ModNames.SetModOfPrefab(prefabName, mod);
}
[Obsolete]
public static BepInPlugin GetModByPrefabName(string name)
{
return ModNames.GetModByPrefabName(name);
}
public static IEnumerable<KeyValuePair<string, Item>> GetActiveItems()
{
return Items.Where((KeyValuePair<string, Item> i) => i.Value.isActive);
}
public static Item GetItem(string name)
{
if (Items.TryGetValue(CleanupName(name), out var value))
{
return value;
}
if (ItemsByPreLocalizedName.TryGetValue(name, out value))
{
return value;
}
if (ItemsByLocalizedName.TryGetValue(name, out value))
{
return value;
}
return null;
}
public static void UpdateKnown()
{
if (!Object.op_Implicit((Object)(object)Player.m_localPlayer))
{
return;
}
int num = Player.m_localPlayer.m_knownMaterial.Count + Player.m_localPlayer.m_knownRecipes.Count + Player.m_localPlayer.m_knownStations.Count + Player.m_localPlayer.m_knownTexts.Count + Player.m_localPlayer.m_knownBiome.Count;
if (currentKnownCount == num && currentShowOnlyKnown == Plugin.ShowOnlyKnown)
{
return;
}
currentKnownCount = num;
currentShowOnlyKnown = Plugin.ShowOnlyKnown;
foreach (Item value in Items.Values)
{
value.UpdateSelfKnown();
}
foreach (RecipeInfo recipe in RecipeInfo.Recipes)
{
recipe.UpdateKnown();
}
foreach (Item value2 in Items.Values)
{
value2.UpdateKnown();
}
Indexing.AfterUpdateKnownItems?.Invoke();
}
}
public class Item
{
public readonly string internalName;
public readonly string preLocalizeName;
public string localizedName;
public readonly string description;
public string localizedDescription;
public readonly GameObject prefab;
public readonly bool isOnBlacklist;
public readonly ItemType itemType;
public ItemType itemDropType;
public readonly BepInPlugin mod;
public bool isActive = true;
public int maxQuality;
public bool isFavorite;
private bool isKnown;
private readonly Dictionary<int, string> tooltipsCache = new Dictionary<int, string>();
public readonly HashSet<RecipeInfo> result = new HashSet<RecipeInfo>();
public readonly HashSet<RecipeInfo> ingredient = new HashSet<RecipeInfo>();
public readonly ComponentEvent onFavoriteChanged = new ComponentEvent();
public readonly ComponentEvent onKnownChanged = new ComponentEvent();
private Sprite icon;
public bool IsKnown => isKnown || !Plugin.ShowOnlyKnown;
public bool IsSelfKnown { get; private set; }
public static event Action OnAnyFavoriteChanged;
public Item(string name, string preLocalizeName, string description, Sprite icon, ItemType itemType, GameObject prefab, int maxQuality = 1)
{
//IL_00f4: Unknown result type (might be due to invalid IL or missing references)
//IL_00f9: Unknown result type (might be due to invalid IL or missing references)
//IL_00fa: Unknown result type (might be due to invalid IL or missing references)
//IL_0105: Unknown result type (might be due to invalid IL or missing references)
//IL_0112: Unknown result type (might be due to invalid IL or missing references)
//IL_011b: Expected O, but got Unknown
internalName = name;
this.preLocalizeName = preLocalizeName ?? "";
this.description = description;
this.prefab = prefab;
this.itemType = itemType;
this.maxQuality = maxQuality;
isOnBlacklist = Plugin.IsItemBlacklisted(this);
Localization.OnLanguageChange = (Action)Delegate.Combine(Localization.OnLanguageChange, new Action(UpdateLocalizedName));
UpdateLocalizedName();
if (Object.op_Implicit((Object)(object)prefab))
{
mod = ModNames.GetModByPrefabName(((Object)prefab).name);
}
if (Object.op_Implicit((Object)(object)icon))
{
SetIcon(icon);
}
else if (Object.op_Implicit((Object)(object)prefab))
{
RenderRequest val = new RenderRequest(prefab)
{
Rotation = RenderManager.IsometricRotation,
TargetPlugin = mod,
UseCache = true
};
SetIcon(RenderManager.Instance.Render(val));
}
}
~Item()
{
Localization.OnLanguageChange = (Action)Delegate.Remove(Localization.OnLanguageChange, new Action(UpdateLocalizedName));
}
public string GetNameContext()
{
return internalName + Environment.NewLine + GetModName();
}
public string GetDescription()
{
return description;
}
public string GetTooltip(int quality)
{
if (tooltipsCache.TryGetValue(quality, out var value))
{
return value;
}
value = GenerateTooltip(quality);
tooltipsCache.Add(quality, value);
return value;
}
private void UpdateLocalizedName()
{
localizedName = Localization.instance.Localize(preLocalizeName);
localizedDescription = Localization.instance.Localize(description);
}
private void ClearTooltipCache(object sender, EventArgs e)
{
tooltipsCache.Clear();
}
private string GenerateTooltip(int quality)
{
ItemDrop val = default(ItemDrop);
if (Object.op_Implicit((Object)(object)prefab) && prefab.TryGetComponent<ItemDrop>(ref val))
{
if (!Object.op_Implicit((Object)(object)val.m_itemData.m_dropPrefab))
{
val.m_itemData.m_dropPrefab = prefab;
}
try
{
return ItemData.GetTooltip(val.m_itemData, quality, true, (float)Game.m_worldLevel, -1);
}
catch (Exception arg)
{
Log.LogWarning($"Failed to generate tooltip for '{internalName}': {arg}");
return string.Empty;
}
}
if (WhichModAddedThis.IsLoaded)
{
return description.TrimEnd(Array.Empty<char>()) + WhichModAddedThis.GetTooltipModName(GetModName());
}
return description;
}
public void SetIcon(Sprite sprite)
{
if (!Object.op_Implicit((Object)(object)icon))
{
icon = sprite;
}
}
public Sprite GetIcon()
{
return Object.op_Implicit((Object)(object)icon) ? icon : Plugin.Instance.noIconSprite;
}
public string GetPrimaryName()
{
return (localizedName.Length > 0) ? localizedName : internalName;
}
public string GetModName()
{
return (mod != null) ? mod.Name : "Valheim";
}
public string PrintItem()
{
if (string.IsNullOrEmpty(internalName))
{
return " -- invalid item -- ";
}
string text = GetDescription().Replace('\n', ' ');
string text2 = itemType.ToString();
string text3 = "Internal Name: " + internalName + ", Localized Name: " + GetPrimaryName() + ", Item Type: " + text2;
if (!string.IsNullOrEmpty(text))
{
text3 = text3 + ", Description: " + text;
}
if (!string.IsNullOrEmpty(GetModName()))
{
text3 = text3 + ", Source Mod: " + GetModName();
}
return text3;
}
public string PrintItemCSV(string separator)
{
if (string.IsNullOrEmpty(internalName))
{
return " -- invalid item -- ";
}
string text = GetDescription().Replace('\n', ' ');
return internalName + separator + GetPrimaryName() + separator + $"{itemType}{separator}" + text + separator + GetModName();
}
public static string PrintCSVHeader(string separator)
{
return "Internal Name" + separator + "Localized Name" + separator + "Item Type" + separator + "Description" + separator + "Source Mod";
}
public void UpdateFavorite(bool favorite)
{
isFavorite = favorite;
onFavoriteChanged.Invoke();
Item.OnAnyFavoriteChanged?.Invoke();
}
public void UpdateSelfKnown()
{
isKnown = false;
if (!Plugin.ShowOnlyKnown)
{
IsSelfKnown = true;
}
else
{
IsSelfKnown = Player.m_localPlayer.m_knownMaterial.Contains(preLocalizeName) || Player.m_localPlayer.m_knownStations.ContainsKey(preLocalizeName);
}
}
public void UpdateKnown()
{
if (IsSelfKnown)
{
isKnown = true;
onKnownChanged.Invoke();
}
else if (result.Any((RecipeInfo recipe) => recipe.IsSelfKnown) || ingredient.Any((RecipeInfo recipe) => recipe.IsSelfKnown))
{
isKnown = true;
onKnownChanged.Invoke();
}
else
{
isKnown = false;
onKnownChanged.Invoke();
}
}
public IEnumerable<Item> GetStations()
{
List<Item> list = new List<Item>();
list.AddRange(ingredient.SelectMany((RecipeInfo r) => r.GetStationItems()));
list.AddRange(result.SelectMany((RecipeInfo r) => r.GetStationItems()));
return list.Distinct().ToList();
}
}
public enum ItemType
{
Undefined,
Creature,
Piece,
Item,
Food,
Armor,
Weapon
}
public class ItemTypeHelper
{
public static ItemType GetItemType(ItemData itemData)
{
//IL_0007: 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_000d: Unknown result type (might be due to invalid IL or missing references)
//IL_000e: Unknown result type (might be due to invalid IL or missing references)
//IL_000f: 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_006b: Expected I4, but got Unknown
ItemType itemType = itemData.m_shared.m_itemType;
ItemType val = itemType;
switch (val - 2)
{
case 0:
return ItemType.Food;
case 4:
case 5:
case 9:
case 10:
case 15:
return ItemType.Armor;
case 1:
case 2:
case 3:
case 12:
case 13:
case 20:
return ItemType.Weapon;
default:
return ItemType.Item;
}
}
}
public class ModNames
{
private static readonly Dictionary<string, BepInPlugin> SourceMod = new Dictionary<string, BepInPlugin>();
public static void IndexModNames()
{
foreach (IModPrefab prefab in ModQuery.GetPrefabs())
{
if (prefab != null && Object.op_Implicit((Object)(object)prefab.Prefab))
{
SetModOfPrefab(((Object)prefab.Prefab).name, prefab.SourceMod);
}
}
}
public static void SetModOfPrefab(string prefabName, BepInPlugin mod)
{
if (!SourceMod.ContainsKey(prefabName))
{
SourceMod[prefabName] = mod;
}
}
public static BepInPlugin GetModByPrefabName(string name)
{
if (SourceMod.TryGetValue(name, out var value))
{
return value;
}
return null;
}
}
public class Part
{
public readonly Item item;
public readonly Amount amount;
public readonly int quality;
public Part(Item item, Amount amount, int quality)
{
this.item = item;
this.amount = amount;
this.quality = quality;
}
protected bool Equals(Part other)
{
return object.Equals(item, other.item) && amount.Equals(other.amount) && quality == other.quality;
}
public override bool Equals(object obj)
{
if (obj == null)
{
return false;
}
if (this == obj)
{
return true;
}
if (obj.GetType() != GetType())
{
return false;
}
return Equals((Part)obj);
}
public override int GetHashCode()
{
int num = ((item != null) ? item.GetHashCode() : 0);
num = (num * 397) ^ amount.GetHashCode();
return (num * 397) ^ quality;
}
}
public class RecipeInfo
{
public Dictionary<Amount, List<Part>> Ingredients { get; private set; } = new Dictionary<Amount, List<Part>>();
public Dictionary<Amount, List<Part>> Results { get; private set; } = new Dictionary<Amount, List<Part>>();
public List<Part> Stations { get; private set; } = new List<Part>();
public bool IsOnBlacklist { get; private set; }
public static List<RecipeInfo> Recipes { get; private set; } = new List<RecipeInfo>();
public bool IsSelfKnown { get; private set; }
public float Width { get; private set; }
public IEnumerable<Item> GetStationItems()
{
if (Stations.Count >= 1)
{
return new Item[1] { Stations[0].item ?? Plugin.Instance.noStation };
}
return new Item[1] { Plugin.Instance.noStation };
}
public void UpdateKnown()
{
IsSelfKnown = CalcSelfKnown();
}
private static bool AnySelfKnown(Dictionary<Amount, List<Part>> list)
{
return list.Where((KeyValuePair<Amount, List<Part>> pair) => pair.Key.max != 0 && pair.Value != null).Any((KeyValuePair<Amount, List<Part>> pair) => pair.Value.Any((Part part) => part.item.IsSelfKnown));
}
private static bool AllSelfKnown(Dictionary<Amount, List<Part>> list)
{
return list.Where((KeyValuePair<Amount, List<Part>> pair) => pair.Key.max != 0 && pair.Value != null).All((KeyValuePair<Amount, List<Part>> pair) => pair.Value.All((Part part) => part.item.IsSelfKnown));
}
private bool CalcSelfKnown()
{
if (!Plugin.ShowOnlyKnown)
{
return true;
}
if (Stations.Any((Part s) => !s.item.IsSelfKnown))
{
return false;
}
if (AllSelfKnown(Ingredients))
{
return true;
}
if (AllSelfKnown(Results))
{
return true;
}
return false;
}
public void AddIngredient(string name, Amount groupAmount, Amount count, int quality)
{
Item item = Indexing.GetItem(name);
if (item != null)
{
if (!Ingredients.ContainsKey(groupAmount))
{
Ingredients.Add(groupAmount, new List<Part>());
}
Ingredients[groupAmount].Add(new Part(item, count, quality));
}
}
public void AddIngredient<T>(T target, Amount groupAmount, Amount count, int quality, string context) where T : Object
{
if (Object.op_Implicit((Object)(object)target))
{
AddIngredient(((Object)target).name, groupAmount, count, quality);
}
else
{
Log.LogDebug($"cannot add ingredient to '{context}', item is null (uses amount {count})");
}
}
public void AddResult(string name, Amount groupAmount, Amount count, int quality)
{
Item item = Indexing.GetItem(name);
if (item != null)
{
if (!Results.ContainsKey(groupAmount))
{
Results.Add(groupAmount, new List<Part>());
}
Results[groupAmount].Add(new Part(item, count, quality));
}
}
public void AddResult<T>(T target, Amount groupAmount, Amount count, int quality, string context) where T : Object
{
if (Object.op_Implicit((Object)(object)target))
{
AddResult(((Object)target).name, groupAmount, count, quality);
}
else
{
Log.LogDebug($"cannot add result to '{context}', item is null (uses amount {count})");
}
}
public void AddStation(Item item, int level)
{
if (item != null)
{
Stations.Add(new Part(item, new Amount(1), level));
}
}
public void AddStation(string name, int level)
{
AddStation(Indexing.GetItem(name), level);
}
public void AddStation<T>(T target, int level) where T : Object
{
if ((Object)(object)target != (Object)null)
{
AddStation(((Object)target).name, level);
}
else
{
Log.LogDebug("cannot set station: is null");
}
}
public void CalculateIsOnBlacklist()
{
if (Ingredients.SelectMany((KeyValuePair<Amount, List<Part>> i) => i.Value).Any((Part i) => i.item.isOnBlacklist))
{
IsOnBlacklist = true;
}
else if (Results.SelectMany((KeyValuePair<Amount, List<Part>> i) => i.Value).Any((Part i) => i.item.isOnBlacklist))
{
IsOnBlacklist = true;
}
}
public RecipeInfo()
{
Recipes.Add(this);
}
public RecipeInfo(Recipe recipe, int quality)
: this()
{
if ((Object)(object)recipe.GetRequiredStation(quality) != (Object)null)
{
this.AddStation<CraftingStation>(recipe.GetRequiredStation(quality), recipe.GetRequiredStationLevel(quality));
}
else
{
AddStation(Plugin.Instance.handStation, 1);
}
this.AddResult<ItemDrop>(recipe.m_item, Amount.One, new Amount(recipe.m_amount), quality, ((Object)recipe).name);
if (quality > 1)
{
this.AddIngredient<ItemDrop>(recipe.m_item, Amount.One, Amount.One, quality - 1, ((Object)recipe).name);
}
Requirement[] resources = recipe.m_resources;
foreach (Requirement val in resources)
{
Amount amount = new Amount(val.GetAmount(quality));
if (!Amount.IsSameMinMax(amount, Amount.Zero))
{
this.AddIngredient<ItemDrop>(val.m_resItem, Amount.One, amount, 1, ((Object)recipe).name);
}
}
}
public RecipeInfo(ItemConversion conversion, Smelter smelter)
: this()
{
this.AddStation<Smelter>(smelter, 1);
this.AddIngredient<ItemDrop>(conversion.m_from, Amount.One, Amount.One, 1, ((Object)smelter).name);
if (Object.op_Implicit((Object)(object)smelter.m_fuelItem))
{
this.AddIngredient<ItemDrop>(smelter.m_fuelItem, Amount.One, new Amount(smelter.m_fuelPerProduct), 1, ((Object)smelter).name);
}
this.AddResult<ItemDrop>(conversion.m_to, Amount.One, Amount.One, 1, ((Object)smelter).name);
}
public RecipeInfo(ItemConversion conversion, Fermenter fermenter)
: this()
{
this.AddStation<Fermenter>(fermenter, 1);
this.AddIngredient<ItemDrop>(conversion.m_from, Amount.One, Amount.One, 1, ((Object)fermenter).name);
this.AddResult<ItemDrop>(conversion.m_to, Amount.One, new Amount(conversion.m_producedItems), 1, ((Object)fermenter).name);
}
public RecipeInfo(ItemConversion conversion, CookingStation cookingStation)
: this()
{
this.AddStation<CookingStation>(cookingStation, 1);
this.AddIngredient<ItemDrop>(conversion.m_from, Amount.One, Amount.One, 1, ((Object)cookingStation).name);
this.AddResult<ItemDrop>(conversion.m_to, Amount.One, Amount.One, 1, ((Object)cookingStation).name);
}
public RecipeInfo(Incinerator incinerator)
: this()
{
this.AddStation<Incinerator>(incinerator, 1);
this.AddResult<ItemDrop>(incinerator.m_defaultResult, Amount.One, Amount.One, 1, ((Object)incinerator).name);
AddIngredient("vnei_any_item", Amount.One, new Amount(incinerator.m_defaultCost), 1);
}
public RecipeInfo(IncineratorConversion conversion, Incinerator incinerator)
: this()
{
this.AddStation<Incinerator>(incinerator, 1);
this.AddResult<ItemDrop>(conversion.m_result, Amount.One, new Amount(conversion.m_resultAmount), 1, ((Object)incinerator).name);
foreach (Requirement requirement in conversion.m_requirements)
{
this.AddIngredient<ItemDrop>(requirement.m_resItem, Amount.One, new Amount(requirement.m_amount), 1, ((Object)incinerator).name);
}
}
public RecipeInfo(IncineratorConversion conversion, Requirement requirement, Incinerator incinerator)
: this()
{
this.AddStation<Incinerator>(incinerator, 1);
this.AddResult<ItemDrop>(conversion.m_result, Amount.One, new Amount(conversion.m_resultAmount), 1, ((Object)incinerator).name);
this.AddIngredient<ItemDrop>(requirement.m_resItem, Amount.One, new Amount(requirement.m_amount), 1, ((Object)incinerator).name);
}
public RecipeInfo(CharacterDrop characterDrop)
: this()
{
Character component = ((Component)characterDrop).GetComponent<Character>();
this.AddIngredient<Character>(component, Amount.One, Amount.One, 1, ((Object)component).name);
foreach (Drop drop in characterDrop.m_drops)
{
this.AddResult<GameObject>(count: new Amount(drop.m_amountMin, drop.m_amountMax, drop.m_chance), target: drop.m_prefab, groupAmount: Amount.One, quality: 1, context: ((Object)component).name);
}
}
public RecipeInfo(GameObject prefab, Piece piece, Item crafter)
: this()
{
Stations.Add(new Part(crafter, new Amount(1), 1));
if (Object.op_Implicit((Object)(object)piece.m_craftingStation))
{
this.AddStation<CraftingStation>(piece.m_craftingStation, 1);
}
Requirement[] resources = piece.m_resources;
foreach (Requirement val in resources)
{
this.AddIngredient<ItemDrop>(val.m_resItem, Amount.One, new Amount(val.m_amount), 1, ((Object)prefab).name);
}
Plant val2 = default(Plant);
if (((Component)piece).TryGetComponent<Plant>(ref val2))
{
GameObject[] grownPrefabs = val2.m_grownPrefabs;
if (grownPrefabs != null && grownPrefabs.Length >= 1)
{
GameObject[] grownPrefabs2 = val2.m_grownPrefabs;
foreach (GameObject target in grownPrefabs2)
{
this.AddResult<GameObject>(target, Amount.One, new Amount(1, 1f / (float)val2.m_grownPrefabs.Length), 1, ((Object)prefab).name);
}
Indexing.DisableItem(((Object)prefab).name, "Plant has grownPrefabs");
return;
}
}
this.AddResult<GameObject>(prefab, Amount.One, Amount.One, 1, ((Object)prefab).name);
}
public RecipeInfo(GameObject prefab, Pickable pickable)
: this()
{
this.AddIngredient<GameObject>(prefab, Amount.One, Amount.One, 1, ((Object)prefab).name);
this.AddResult<GameObject>(pickable.m_itemPrefab, Amount.One, new Amount(pickable.m_amount), 1, ((Object)pickable).name);
if (pickable.m_extraDrops != null && pickable.m_extraDrops.m_drops.Count > 0)
{
AddDropTable(prefab, pickable.m_extraDrops);
}
CombineGroupAmounts(Results);
}
public RecipeInfo(GameObject from, DropTable dropTable)
: this()
{
this.AddIngredient<GameObject>(from, Amount.One, Amount.One, 1, ((Object)from).name);
AddDropTable(from, dropTable);
if (dropTable.m_drops != null && dropTable.m_drops.Count == 0)
{
Indexing.DisableItem(((Object)from).name, "No drops in DropTable");
}
}
public RecipeInfo(SpawnArea spawnArea)
: this()
{
this.AddIngredient<SpawnArea>(spawnArea, Amount.One, Amount.One, 1, ((Object)spawnArea).name);
foreach (SpawnData prefab in spawnArea.m_prefabs)
{
this.AddResult<GameObject>(prefab.m_prefab, Amount.One, new Amount(1, 1f / (float)spawnArea.m_prefabs.Count), 1, ((Object)spawnArea).name);
}
}
public RecipeInfo(Destructible spawnArea)
: this()
{
this.AddIngredient<Destructible>(spawnArea, Amount.One, Amount.One, 1, ((Object)spawnArea).name);
this.AddResult<GameObject>(spawnArea.m_spawnWhenDestroyed, Amount.One, Amount.One, 1, ((Object)spawnArea).name);
}
private void AddTreeLog(GameObject logPrefab, int depth, string name, int treeCount)
{
TreeLog val = default(TreeLog);
if (depth > 50)
{
Log.LogWarning("TreeLog is recursively " + name);
}
else if (Object.op_Implicit((Object)(object)logPrefab) && logPrefab.TryGetComponent<TreeLog>(ref val))
{
if (val.m_subLogPoints != null)
{
AddTreeLog(val.m_subLogPrefab, depth + 1, name, val.m_subLogPoints.Length);
}
AddDropTable(((Component)val).gameObject, val.m_dropWhenDestroyed, treeCount);
Indexing.DisableItem(((Object)((Component)val).gameObject).name, name);
}
}
public RecipeInfo(TreeBase treeBase)
: this()
{
this.AddIngredient<TreeBase>(treeBase, Amount.One, Amount.One, 1, ((Object)treeBase).name);
AddTreeLog(treeBase.m_logPrefab, 0, ((Object)treeBase).name, 1);
AddDropTable(((Component)treeBase).gameObject, treeBase.m_dropWhenDestroyed);
DropOnDestroyed val = default(DropOnDestroyed);
if (Object.op_Implicit((Object)(object)treeBase.m_stubPrefab) && treeBase.m_stubPrefab.TryGetComponent<DropOnDestroyed>(ref val))
{
AddDropTable(((Component)treeBase).gameObject, val.m_dropWhenDestroyed);
Indexing.DisableItem(((Object)treeBase.m_stubPrefab).name, ((Object)((Component)treeBase).gameObject).name);
}
}
public RecipeInfo(Trader trader, TradeItem tradeItem)
: this()
{
this.AddStation<Trader>(trader, 1);
this.AddIngredient<ItemDrop>(StoreGui.instance.m_coinPrefab, Amount.One, new Amount(tradeItem.m_price), 1, ((Object)trader).name);
this.AddResult<ItemDrop>(tradeItem.m_prefab, Amount.One, new Amount(tradeItem.m_stack), 1, ((Object)trader).name);
}
public RecipeInfo(Growup growup)
: this()
{
this.AddIngredient<GameObject>(((Component)growup).gameObject, Amount.One, Amount.One, 1, "growup base ");
this.AddResult<GameObject>(growup.m_grownPrefab, Amount.One, Amount.One, 1, "growup result");
}
public RecipeInfo(Amount ingredientAmount, IEnumerable<(string, int)> ingredients, Amount resultAmount, IEnumerable<(string, int)> results, string station, int ingredientQuality = 1, int resultQuality = 1, int stationLevel = 1)
: this()
{
foreach (var ingredient in ingredients)
{
AddIngredient(ingredient.Item1, ingredientAmount, new Amount(ingredient.Item2), ingredientQuality);
}
foreach (var result in results)
{
AddResult(result.Item1, resultAmount, new Amount(result.Item2), resultQuality);
}
AddStation(station, stationLevel);
}
private void AddDropTable(GameObject from, DropTable dropTable, int groupMultiplier = 1)
{
//IL_0068: Unknown result type (might be due to invalid IL or missing references)
//IL_006d: Unknown result type (might be due to invalid IL or missing references)
//IL_0078: Unknown result type (might be due to invalid IL or missing references)
//IL_008b: Unknown result type (might be due to invalid IL or missing references)
//IL_0093: Unknown result type (might be due to invalid IL or missing references)
//IL_009a: Unknown result type (might be due to invalid IL or missing references)
if (dropTable == null)
{
return;
}
Amount groupAmount = new Amount(dropTable.m_dropMin * groupMultiplier, dropTable.m_dropMax * groupMultiplier, dropTable.m_dropChance);
float num = dropTable.m_drops.Sum((DropData i) => i.m_weight);
foreach (DropData drop in dropTable.m_drops)
{
float chance = ((num == 0f) ? 1f : (drop.m_weight / num));
this.AddResult<GameObject>(drop.m_item, groupAmount, new Amount(drop.m_stackMin, drop.m_stackMax, chance), 1, Object.op_Implicit((Object)(object)from) ? ((Object)from).name : "unknown");
}
}
public bool IngredientsAndResultSame()
{
return Ingredients.SequenceEqual(Results);
}
public void CalculateWidth()
{
float num = 0f;
num += (float)Mathf.Max(1, Stations.Count) * 50f;
foreach (KeyValuePair<Amount, List<Part>> ingredient in Ingredients)
{
if (Ingredients.Count > 1 || ingredient.Key.min != 1 || ingredient.Key.max != 1 || Math.Abs(ingredient.Key.chance - 1f) > 0.01f)
{
num += 50f;
}
num += (float)ingredient.Value.Count * 50f;
}
foreach (KeyValuePair<Amount, List<Part>> result in Results)
{
if (Results.Count > 1 || result.Key.min != 1 || result.Key.max != 1 || Math.Abs(result.Key.chance - 1f) > 0.01f)
{
num += 50f;
}
num += (float)result.Value.Count * 50f;
}
Width = num;
}
private void CombineGroupAmounts(Dictionary<Amount, List<Part>> groups)
{
if (groups.Keys.Count > 1 && !groups.Keys.Any((Amount i) => Math.Abs(i.chance - groups.Keys.First().chance) > 0.001f) && groups.Values.Count > 1 && !groups.Values.Any((List<Part> i) => !i.SequenceEqual(groups.Values.First())))
{
Amount key = new Amount(groups.Keys.Sum((Amount i) => i.min), groups.Keys.Sum((Amount i) => i.max), groups.Keys.First().chance);
List<Part> value = groups.Values.First();
groups.Clear();
groups.Add(key, value);
}
}
public bool IsUpgrade(out Item item)
{
List<Part> list = (from i in Ingredients.Values.SelectMany((List<Part> i) => i)
where i.item.maxQuality > 1
select i).ToList();
List<Part> list2 = (from i in Results.Values.SelectMany((List<Part> i) => i)
where i.item.maxQuality > 1
select i).ToList();
if (list.Count != 1 || list2.Count != 1)
{
item = null;
return false;
}
Part part = list[0];
Part part2 = list2[0];
item = part.item;
return part.item == part2.item && part.quality < part2.quality;
}
public override string ToString()
{
return string.Join(", ", Ingredients.SelectMany((KeyValuePair<Amount, List<Part>> parts) => parts.Value.Select((Part part) => parts.Key.ToString() + " " + part.item.GetPrimaryName()))) + " -> " + string.Join(", ", Results.SelectMany((KeyValuePair<Amount, List<Part>> parts) => parts.Value.Select((Part part) => parts.Key.ToString() + " " + part.item.GetPrimaryName()))) + " @ " + string.Join(", ", Stations.Select((Part s) => s.item.GetPrimaryName()));
}
}
}
namespace VNEI.Logic.Compatibility
{
public static class EpicLootCompat
{
public static void Init()
{
if (Chainloader.PluginInfos.ContainsKey("randyknapp.mods.epicloot"))
{
Indexing.AfterIndexingRecipes += IndexMaterialConversions;
Indexing.AfterIndexingRecipes += IndexSacrifices;
}
}
private static void IndexMaterialConversions()
{
//IL_001a: Unknown result type (might be due to invalid IL or missing references)
//IL_001f: Unknown result type (might be due to invalid IL or missing references)
foreach (KeyValuePair<MaterialConversionType, List<MaterialConversion>> item in (Dictionary<MaterialConversionType, List<MaterialConversion>>)(object)MaterialConversions.Conversions)
{
MaterialConversionType key = item.Key;
List<MaterialConversion> value = item.Value;
foreach (MaterialConversion item2 in value)
{
AddMaterialConversion(item2);
}
}
}
private static void AddMaterialConversion(MaterialConversion conversion)
{
Indexing.AddRecipeToItems(new RecipeInfo(Amount.One, conversion.Resources.Select((MaterialConversionRequirement r) => (r.Item, r.Amount)), Amount.One, new(string, int)[1] { (conversion.Product, conversion.Amount) }, "piece_enchantingtable"));
}
private static void IndexSacrifices()
{
foreach (DisenchantProductsConfig disenchantProduct in EnchantCostsHelper.Config.DisenchantProducts)
{
if (disenchantProduct.ItemNames.Count <= 0)
{
continue;
}
foreach (string itemName in disenchantProduct.ItemNames)
{
AddSacrifice(itemName, disenchantProduct);
}
}
}
private static void AddSacrifice(string itemName, DisenchantProductsConfig disenchantProductsConfig)
{
Indexing.AddRecipeToItems(new RecipeInfo(Amount.One, new(string, int)[1] { (itemName, 1) }, Amount.One, disenchantProductsConfig.Products.Select((ItemAmountConfig p) => (p.Item, p.Amount)), "piece_enchantingtable"));
}
}
public class PlanBuild
{
private static List<string> disableToolPieces = new List<string>
{
"piece_bpcapture", "piece_bpselectadd", "piece_bpselectremove", "piece_bpselectedit", "piece_bpsnappoint", "piece_bpcenterpoint", "piece_bpterrainmod", "piece_bpdelete", "piece_bpterrain", "piece_bpobjects",
"piece_bppaint", "piece_plan_delete"
};
public static void Init()
{
if (!Chainloader.PluginInfos.ContainsKey("marcopogo.PlanBuild"))
{
return;
}
Indexing.OnDisableItems += delegate(GameObject prefab)
{
if (Object.op_Implicit((Object)(object)prefab.GetComponent("PlanBuild.Plans.PlanPiece")))
{
Indexing.DisableItem(((Object)prefab).name, "is PlanBuild PlanPiece");
}
};
Indexing.AfterDisableItems += delegate
{
foreach (string disableToolPiece in disableToolPieces)
{
Indexing.DisableItem(disableToolPiece, "is PlanBuild tool piece");
}
};
}
}
public static class WackysDatabaseCompat
{
public static Dictionary<Recipe, bool> RequiredUpgradeItemsString = new Dictionary<Recipe, bool>();
public static Dictionary<Recipe, bool> RequiredCraftItemsString = new Dictionary<Recipe, bool>();
public static bool WackyMoleDatabaseLoaded { get; private set; }
public static void Init()
{
WackyMoleDatabaseLoaded = Chainloader.PluginInfos.ContainsKey("WackyMole.WackysDatabase");
if (WackyMoleDatabaseLoaded)
{
Type type = AccessTools.TypeByName("wackydatabase.WMRecipeCust, WackysDatabase");
FieldInfo fieldInfo = AccessTools.Field(type, "RequiredUpgradeItemsString");
RequiredUpgradeItemsString = (Dictionary<Recipe, bool>)fieldInfo.GetValue(null);
FieldInfo fieldInfo2 = AccessTools.Field(type, "RequiredCraftItemsString");
RequiredCraftItemsString = (Dictionary<Recipe, bool>)fieldInfo2.GetValue(null);
}
}
public static bool HasRecipeEnableOverride(Recipe recipe)
{
if (!WackyMoleDatabaseLoaded)
{
return false;
}
if (RequiredUpgradeItemsString.TryGetValue(recipe, out var value) && value)
{
return true;
}
if (RequiredCraftItemsString.TryGetValue(recipe, out value) && value)
{
return true;
}
return false;
}
public static bool CanBeCrafted(Recipe recipe)
{
if (!WackyMoleDatabaseLoaded)
{
return true;
}
if (RequiredUpgradeItemsString.TryGetValue(recipe, out var value) && value)
{
return false;
}
return true;
}
public static bool CanBeUpgraded(Recipe recipe)
{
if (!WackyMoleDatabaseLoaded)
{
return true;
}
if (RequiredCraftItemsString.TryGetValue(recipe, out var value) && value)
{
return false;
}
return true;
}
}
public class WhichModAddedThis
{
private static MethodInfo GetTooltipModNameMethod;
public static bool IsLoaded => Chainloader.PluginInfos.ContainsKey("com.maxsch.valheim.WhichModAddedThis");
static WhichModAddedThis()
{
if (IsLoaded)
{
Type type = AccessTools.TypeByName("WhichModAddedThis.Patches, WhichModAddedThis");
GetTooltipModNameMethod = AccessTools.Method(type, "GetTooltipModName", (Type[])null, (Type[])null);
}
}
public static string GetTooltipModName(string modName)
{
if (IsLoaded)
{
return (string)GetTooltipModNameMethod.Invoke(null, new object[1] { modName });
}
return string.Empty;
}
}
}
namespace VNEI.UI
{
public class SelectUITest : MonoBehaviour
{
public class ToggleUIConsoleCommand : ConsoleCommand
{
public override string Name => "vnei_toggle_select_test";
public override string Help => "Shows the selection test";
public override void Run(string[] args)
{
if (!Object.op_Implicit((Object)(object)instance))
{
Create();
return;
}
bool flag = ((UIBehaviour)instance.background).IsActive();
((Component)instance.background).gameObject.SetActive(!flag);
((Component)instance.root).gameObject.SetActive(!flag);
}
}
private static SelectUITest instance;
public RectTransform root;
public Image background;
public Text text;
public Button select;
private SelectUI selection;
public static void Create()
{
GameObject val = Plugin.AssetBundle.LoadAsset<GameObject>("SelectUITest");
GameObject val2 = Object.Instantiate<GameObject>(val, GUIManager.CustomGUIFront.transform);
instance = val2.GetComponent<SelectUITest>();
((Component)instance.background).gameObject.AddComponent<DragWindowCntrl>();
GUIManager.Instance.ApplyWoodpanelStyle(((Component)instance.background).transform);
GUIManager.Instance.ApplyTextStyle(instance.text, 16);
GUIManager.Instance.ApplyButtonStyle(instance.select, 16);
}
private void Start()
{
//IL_0013: Unknown result type (might be due to invalid IL or missing references)
//IL_001d: Expected O, but got Unknown
((UnityEvent)select.onClick).AddListener((UnityAction)delegate
{
//IL_002d: Unknown result type (might be due to invalid IL or missing references)
if (!Object.op_Implicit((Object)(object)selection))
{
Action<string> onSelect = delegate(string prefabName)
{
text.text = prefabName;
};
selection = SelectUI.CreateSelection(GUIManager.CustomGUIFront.transform, onSelect, Vector2.zero, new ItemType[2]
{
ItemType.Piece,
ItemType.Item
});
}
});
}
private void Update()
{
//IL_0012: Unknown result type (might be due to invalid IL or missing references)
((Transform)root).position = ((Component)background).transform.position;
}
}
[DefaultExecutionOrder(5)]
public class BaseUI : MonoBehaviour
{
[Header("Local References")]
public RectTransform root;
public RectTransform dragHandler;
public RectTransform lastViewItemsParent;
public SearchUI searchUi;
public RecipeUI recipeUi;
[Header("Prefabs")]
public GameObject itemPrefab;
public GameObject rowPrefab;
public GameObject recipeDroppedTextPrefab;
public GameObject arrowPrefab;
private List<DisplayItem> lastViewedDisplayItems = new List<DisplayItem>();
private List<Item> lastViewedItems = new List<Item>();
public const string HistoryQueueKey = "VNEI_History";
private bool sizeDirty;
[HideInInspector]
public List<ItemTypeToggle> typeToggles = new List<ItemTypeToggle>();
[HideInInspector]
public FavoriteTypeToggle favoriteToggle;
public Action typeToggleChange;
private bool canBeHidden;
private bool usePluginSize = true;
public bool BlockInput { get; private set; }
public int ItemSizeX { get; private set; }
public int ItemSizeY { get; private set; }
public event Action RebuildedSize;
public static BaseUI CreateBaseUI(bool canBeHidden = false, bool scaleWithPluginSetting = false, bool draggable = true)
{
GameObject val = Object.Instantiate<GameObject>(Plugin.Instance.vneiUI, Object.op_Implicit((Object)(object)GUIManager.CustomGUIFront) ? GUIManager.CustomGUIFront.transform : null);
BaseUI component = val.GetComponent<BaseUI>();
component.canBeHidden = canBeHidden;
component.usePluginSize = scaleWithPluginSetting;
if (component.usePluginSize)
{
Plugin.columnCount.SettingChanged += component.RebuildSizeEvent;
Plugin.rowCount.SettingChanged += component.RebuildSizeEvent;
}
if (draggable)
{
((Component)component.dragHandler).gameObject.AddComponent<DragWindowCntrl>();
}
return component;
}
private void Awake()
{
//IL_00ce: Unknown result type (might be due to invalid IL or missing references)
//IL_00dd: Unknown result type (might be due to invalid IL or missing references)
BlockInput = false;
ShowSearch(trackHistory: false);
ShowSearch(trackHistory: true);
Styling.ApplyAllComponents((Transform)(object)root);
Styling.ApplyAllComponents(Plugin.Instance.craftingStationTemplate.transform);
GUIManager.Instance.ApplyWoodpanelStyle((Transform)(object)dragHandler);
recipeUi.OnSetItem += AddItemToLastViewedQueue;
Plugin.OnOpenHotkey += UpdateVisibility;
Plugin.transparency.SettingChanged += UpdateTransparency;
Plugin.showRecentItems.SettingChanged += UpdateLastViewItemsParent;
if (Object.op_Implicit((Object)(object)InventoryGui.instance))
{
((Component)this).transform.SetParent((Transform)(object)InventoryGui.instance.m_player);
((RectTransform)((Component)this).transform).anchoredPosition = new Vector2(665f, -45f);
UpdateVisibility();
}
else
{
SetVisibility(visible: false);
}
UpdateTransparency(null, EventArgs.Empty);
UpdateLastViewItemsParent(null, EventArgs.Empty);
RebuildSize();
RebuildDisplayItemRows();
}
private void RebuildSizeEvent(object sender, EventArgs e)
{
sizeDirty = true;
}
private void RebuildSize()
{
//IL_005b: Unknown result type (might be due to invalid IL or missing references)
//IL_0072: Unknown result type (might be due to invalid IL or missing references)
//IL_0081: Unknown result type (might be due to invalid IL or missing references)
//IL_0086: Unknown result type (might be due to invalid IL or missing references)
if (usePluginSize)
{
ItemSizeX = Plugin.columnCount.Value;
ItemSizeY = Plugin.rowCount.Value;
}
root.sizeDelta = new Vector2((float)ItemSizeX * 50f + 10f, (float)ItemSizeY * 50f + 100f);
dragHandler.sizeDelta = root.sizeDelta + new Vector2(10f, 10f);
this.RebuildedSize?.Invoke();
}
private void Update()
{
//IL_00bd: Unknown result type (might be due to invalid IL or missing references)
//IL_00dd: Unknown result type (might be due to invalid IL or missing references)
bool isFocused = searchUi.searchField.isFocused;
bool activeInHierarchy = ((Component)searchUi.searchField).gameObject.activeInHierarchy;
bool flag = Object.op_Implicit((Object)(object)Hud.instance) && Hud.instance.IsVisible();
if (!BlockInput && isFocused && activeInHierarchy && flag)
{
GUIManager.BlockInput(true);
BlockInput = true;
}
if (BlockInput && (!isFocused || !activeInHierarchy || !flag))
{
GUIManager.BlockInput(false);
BlockInput = false;
}
if (sizeDirty)
{
sizeDirty = false;
RebuildSize();
RebuildDisplayItemRows();
}
if (Plugin.goForwardHotkey.Value.IsKeyDown())
{
NextView();
}
else if (Plugin.goBackHotkey.Value.IsKeyDown())
{
PreviousView();
}
}
public void PreviousView()
{
UndoManager.Instance.Undo("VNEI_History");
}
public void NextView()
{
if (UndoManager.Instance.GetQueue("VNEI_History").GetIndex() == -1)
{
UndoManager.Instance.Redo("VNEI_History");
}
UndoManager.Instance.Redo("VNEI_History");
}
private void RebuildDisplayItemRows()
{
RebuildDisplayItemRow(lastViewedDisplayItems, lastViewItemsParent);
UpdateDisplayItemRow(lastViewedDisplayItems, lastViewedItems);
}
private void RebuildDisplayItemRow(List<DisplayItem> displayItems, RectTransform parent)
{
//IL_007c: Unknown result type (might be due to invalid IL or missing references)
//IL_0086: Unknown result type (might be due to invalid IL or missing references)
//IL_009f: Unknown result type (might be due to invalid IL or missing references)
//IL_00c2: Unknown result type (might be due to invalid IL or missing references)
foreach (DisplayItem displayItem in displayItems)
{
Object.Destroy((Object)(object)((Component)displayItem).gameObject);
}
displayItems.Clear();
if (!Object.op_Implicit((Object)(object)((Component)this).GetComponent<SelectUI>()))
{
int num = Mathf.Max(ItemSizeX - 5, 0);
parent.anchoredPosition = new Vector2((float)num * 50f / 2f + 5f, parent.anchoredPosition.y);
parent.sizeDelta = new Vector2((float)num * 50f, 50f);
for (int i = 0; i < num; i++)
{
DisplayItem item = SpawnDisplayItem(new Vector2(25f + (float)(i * 50), -25f), (Transform)(object)parent);
displayItems.Add(item);
}
}
}
private DisplayItem SpawnDisplayItem(Vector2 anchoredPosition, Transform parent)
{
//IL_0014: Unknown result type (might be due to invalid IL or missing references)
//IL_0019: Unknown result type (might be due to invalid IL or missing references)
GameObject val = Object.Instantiate<GameObject>(itemPrefab, parent);
((RectTransform)val.transform).anchoredPosition = anchoredPosition;
DisplayItem component = val.GetComponent<DisplayItem>();
component.Init(this);
return component;
}
private void LateUpdate()
{
//IL_000d: Unknown result type (might be due to invalid IL or missing references)
root.anchoredPosition = dragHandler.anchoredPosition;
}
public void ShowSearch(bool trackHistory)
{
SwitchView(delegate
{
((Component)recipeUi).gameObject.SetActive(false);
((Component)searchUi).gameObject.SetActive(true);
}, trackHistory);
}
public void ShowRecipe(Item item, bool trackHistory)
{
SwitchView(delegate
{
recipeUi.SetItem(item);
((Component)recipeUi).gameObject.SetActive(true);
((Component)searchUi).gameObject.SetActive(false);
}, trackHistory && item != recipeUi.GetItem());
}
private void SwitchView(Action changeView, bool trackHistory)
{
if (trackHistory)
{
HistorySnapshot currentView = GetCurrentView();
changeView?.Invoke();
HistorySnapshot currentView2 = GetCurrentView();
UndoManager.Instance.Add("VNEI_History", (IUndoAction)(object)new HistoryElement(currentView, currentView2));
}
else
{
changeView?.Invoke();
}
}
private HistorySnapshot GetCurrentView()
{
if (((Component)recipeUi).gameObject.activeSelf)
{
return new HistorySnapshotRecipe(this, recipeUi.GetItem());
}
return new HistorySnapshotSearch(this);
}
private void AddItemToLastViewedQueue(Item item)
{
lastViewedItems.Insert(0, item);
for (int i = 1; i < lastViewedItems.Count; i++)
{
if (lastViewedItems[i] == item)
{
lastViewedItems.RemoveAt(i);
}
}
if (lastViewedItems.Count > 50)
{
lastViewedItems.RemoveAt(lastViewedItems.Count - 1);
}
UpdateDisplayItemRow(lastViewedDisplayItems, lastViewedItems);
}
public void RemoveItemFromLastViewedQueue(