Please disclose if your mod was created primarily using AI tools by adding the 'AI Generated' category. Failing to do so may result in the mod being removed from Thunderstore.
Decompiled source of Deathlink v0.8.3
plugins/Deathlink.dll
Decompiled 36 minutes ago
The result has been truncated due to the large size, download it to view full contents!
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.Serialization.Formatters.Binary; using System.Runtime.Versioning; using System.Security.Permissions; using System.Text; using System.Text.RegularExpressions; using AlmanacClasses.API; using AzuEPI; using AzuEPI.Core.Slots; using AzuExtendedPlayerInventory; using BepInEx; using BepInEx.Configuration; using BepInEx.Logging; using Deathlink.Common; using Deathlink.Death; using Deathlink.external; using HarmonyLib; using JetBrains.Annotations; using Jotunn; using Jotunn.Configs; using Jotunn.Entities; using Jotunn.Managers; using Jotunn.Utils; using Microsoft.CodeAnalysis; using SimpleJson; using Splatform; using UnityEngine; using UnityEngine.Events; using UnityEngine.UI; using YamlDotNet.Serialization; using YamlDotNet.Serialization.NamingConventions; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: AssemblyTitle("ValRougelike")] [assembly: AssemblyDescription("")] [assembly: AssemblyConfiguration("")] [assembly: AssemblyCompany("")] [assembly: AssemblyProduct("ValRougelike")] [assembly: AssemblyCopyright("Copyright © 2021")] [assembly: AssemblyTrademark("")] [assembly: ComVisible(false)] [assembly: Guid("e3243d22-4307-4008-ba36-9f326008cde5")] [assembly: AssemblyFileVersion("0.0.1.0")] [assembly: TargetFramework(".NETFramework,Version=v4.8", FrameworkDisplayName = ".NET Framework 4.8")] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("0.0.1.0")] namespace Microsoft.CodeAnalysis { [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] internal sealed class EmbeddedAttribute : Attribute { } } namespace System.Runtime.CompilerServices { [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] [AttributeUsage(AttributeTargets.Class | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Parameter | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter, AllowMultiple = false, Inherited = false)] internal sealed class NullableAttribute : Attribute { public readonly byte[] NullableFlags; public NullableAttribute(byte P_0) { NullableFlags = new byte[1] { P_0 }; } public NullableAttribute(byte[] P_0) { NullableFlags = P_0; } } [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] [AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Method | AttributeTargets.Interface | AttributeTargets.Delegate, AllowMultiple = false, Inherited = false)] internal sealed class NullableContextAttribute : Attribute { public readonly byte Flag; public NullableContextAttribute(byte P_0) { Flag = P_0; } } } namespace Backpacks { [PublicAPI] public static class API { public static EpicMMOSystem_API.API_State state; private static MethodInfo eCountItemsInBackpacks; private static MethodInfo eAddItemToBackpack; private static MethodInfo eDeleteItemsFromBackpacks; private static MethodInfo eGetEquippedBackpackInventory; private static MethodInfo eGetAllBackpackInventories; public static int CountItemsInBackpacks(Inventory inventory, string name, bool onlyRemoveable = true) { return (int)eCountItemsInBackpacks?.Invoke(null, new object[3] { inventory, name, onlyRemoveable }); } public static bool IsItemInBackpacks(Inventory inventory, string name) { return CountItemsInBackpacks(inventory, name) > 0; } public static bool AddItemToBackpack(ItemData backpack, ItemData item) { return (bool)eAddItemToBackpack?.Invoke(null, new object[2] { backpack, item }); } public static bool DeleteItemsFromBackpacks(Inventory inventory, string name, int count = 1) { return (bool)eDeleteItemsFromBackpacks?.Invoke(null, new object[3] { inventory, name, count }); } public static Inventory? GetEquippedBackpackInventory() { //IL_0018: Unknown result type (might be due to invalid IL or missing references) //IL_001e: Expected O, but got Unknown return (Inventory)(eGetEquippedBackpackInventory?.Invoke(null, new object[0])); } public static List<Inventory> GetAllBackpackInventories(Inventory inventory) { return (List<Inventory>)(eGetAllBackpackInventories?.Invoke(null, new object[1] { inventory })); } public static void Init() { EpicMMOSystem_API.API_State aPI_State = state; if ((uint)(aPI_State - 1) > 1u) { if (Type.GetType("Backpacks.API, Backpacks") == null) { state = EpicMMOSystem_API.API_State.NotInstalled; return; } state = EpicMMOSystem_API.API_State.Ready; Type? type = Type.GetType("Backpacks.API, Backpacks"); eCountItemsInBackpacks = type.GetMethod("CountItemsInBackpacks", BindingFlags.Static | BindingFlags.Public); eAddItemToBackpack = type.GetMethod("AddItemToBackpack", BindingFlags.Static | BindingFlags.Public); eDeleteItemsFromBackpacks = type.GetMethod("DeleteItemsFromBackpacks", BindingFlags.Static | BindingFlags.Public); eGetEquippedBackpackInventory = type.GetMethod("GetEquippedBackpackInventory", BindingFlags.Static | BindingFlags.Public); eGetAllBackpackInventories = type.GetMethod("GetAllBackpackInventories", BindingFlags.Static | BindingFlags.Public); } } } } namespace AzuEPI { [PublicAPI] public class API { public delegate void SlotAddedHandler(string slotName); public delegate void SlotRemovedHandler(string slotName); [CompilerGenerated] private sealed class <EnumerateSlots>d__55 : IEnumerable<SlotDescriptor>, IEnumerable, IEnumerator<SlotDescriptor>, IDisposable, IEnumerator { private int <>1__state; private SlotDescriptor <>2__current; private int <>l__initialThreadId; SlotDescriptor IEnumerator<SlotDescriptor>.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public <EnumerateSlots>d__55(int <>1__state) { this.<>1__state = <>1__state; <>l__initialThreadId = Environment.CurrentManagedThreadId; } [DebuggerHidden] void IDisposable.Dispose() { <>1__state = -2; } private bool MoveNext() { if (<>1__state != 0) { return false; } <>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<SlotDescriptor> IEnumerable<SlotDescriptor>.GetEnumerator() { if (<>1__state == -2 && <>l__initialThreadId == Environment.CurrentManagedThreadId) { <>1__state = 0; return this; } return new <EnumerateSlots>d__55(0); } [DebuggerHidden] IEnumerator IEnumerable.GetEnumerator() { return ((IEnumerable<SlotDescriptor>)this).GetEnumerator(); } } [CompilerGenerated] private sealed class <GetAllSlotSnapshots>d__56 : IEnumerable<SlotSnapshot>, IEnumerable, IEnumerator<SlotSnapshot>, IDisposable, IEnumerator { private int <>1__state; private SlotSnapshot <>2__current; private int <>l__initialThreadId; SlotSnapshot IEnumerator<SlotSnapshot>.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public <GetAllSlotSnapshots>d__56(int <>1__state) { this.<>1__state = <>1__state; <>l__initialThreadId = Environment.CurrentManagedThreadId; } [DebuggerHidden] void IDisposable.Dispose() { <>1__state = -2; } private bool MoveNext() { if (<>1__state != 0) { return false; } <>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<SlotSnapshot> IEnumerable<SlotSnapshot>.GetEnumerator() { if (<>1__state == -2 && <>l__initialThreadId == Environment.CurrentManagedThreadId) { <>1__state = 0; return this; } return new <GetAllSlotSnapshots>d__56(0); } [DebuggerHidden] IEnumerator IEnumerable.GetEnumerator() { return ((IEnumerable<SlotSnapshot>)this).GetEnumerator(); } } [CompilerGenerated] private sealed class <GetEquipmentSlotSnapshots>d__58 : IEnumerable<SlotSnapshot>, IEnumerable, IEnumerator<SlotSnapshot>, IDisposable, IEnumerator { private int <>1__state; private SlotSnapshot <>2__current; private int <>l__initialThreadId; SlotSnapshot IEnumerator<SlotSnapshot>.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public <GetEquipmentSlotSnapshots>d__58(int <>1__state) { this.<>1__state = <>1__state; <>l__initialThreadId = Environment.CurrentManagedThreadId; } [DebuggerHidden] void IDisposable.Dispose() { <>1__state = -2; } private bool MoveNext() { if (<>1__state != 0) { return false; } <>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<SlotSnapshot> IEnumerable<SlotSnapshot>.GetEnumerator() { if (<>1__state == -2 && <>l__initialThreadId == Environment.CurrentManagedThreadId) { <>1__state = 0; return this; } return new <GetEquipmentSlotSnapshots>d__58(0); } [DebuggerHidden] IEnumerator IEnumerable.GetEnumerator() { return ((IEnumerable<SlotSnapshot>)this).GetEnumerator(); } } [CompilerGenerated] private sealed class <GetQuickSlotSnapshots>d__57 : IEnumerable<SlotSnapshot>, IEnumerable, IEnumerator<SlotSnapshot>, IDisposable, IEnumerator { private int <>1__state; private SlotSnapshot <>2__current; private int <>l__initialThreadId; SlotSnapshot IEnumerator<SlotSnapshot>.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public <GetQuickSlotSnapshots>d__57(int <>1__state) { this.<>1__state = <>1__state; <>l__initialThreadId = Environment.CurrentManagedThreadId; } [DebuggerHidden] void IDisposable.Dispose() { <>1__state = -2; } private bool MoveNext() { if (<>1__state != 0) { return false; } <>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<SlotSnapshot> IEnumerable<SlotSnapshot>.GetEnumerator() { if (<>1__state == -2 && <>l__initialThreadId == Environment.CurrentManagedThreadId) { <>1__state = 0; return this; } return new <GetQuickSlotSnapshots>d__57(0); } [DebuggerHidden] IEnumerator IEnumerable.GetEnumerator() { return ((IEnumerable<SlotSnapshot>)this).GetEnumerator(); } } internal static HashSet<Model.EquipmentSlot?> CustomSlots { get; } = new HashSet<Model.EquipmentSlot>(); public static event Action<Hud>? OnHudAwake; public static event Action<Hud>? OnHudAwakeComplete; public static event Action<Hud>? OnHudUpdate; public static event Action<Hud>? OnHudUpdateComplete; public static event Action? OnBeforeQuickSlotsAdded; public static event Action? OnQuickSlotsAdded; public static event SlotAddedHandler? SlotAdded; public static event SlotRemovedHandler? SlotRemoved; public static event Action<string>? OnRegisterVisualPrefab; public static bool IsLoaded() { return false; } public static ItemType GetFakeItemType() { return (ItemType)0; } public static bool AddSlot(string slotName, Func<Player, ItemData?> getItem, Func<ItemData, bool> isValid, int index = -1) { return false; } public static bool AddSlot(string slotName, string prefabName, int index = -1) { return false; } public static bool AddSlot(string slotName, IEnumerable<string> prefabNames, int index = -1) { return false; } public static bool AddSlot(string slotName, Func<ItemData, bool> isValid, int index = -1, IEnumerable<string>? prefabNamesForVisuals = null) { return false; } public static bool AddQuickSlot(string slotName, bool showName = false, int index = -1) { return false; } public static bool RemoveSlot(string slotName) { return false; } public static SlotInfo GetSlots() { return BuildSlotInfo((Model.Slot _) => true); } public static SlotInfo GetQuickSlots() { return BuildSlotInfo((Model.Slot s) => s.IsQuickSlot); } public static SlotInfo GetEquipmentSlots() { return BuildSlotInfo((Model.Slot s) => !s.IsQuickSlot && s.EquipmentSlot != null); } private static SlotInfo BuildSlotInfo(Func<Model.Slot, bool> filter) { return new SlotInfo(); } public static List<ItemData> GetQuickSlotsItems() { return new List<ItemData>(); } public static int GetAddedRows(int width) { return 0; } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static int GetFullHeight(int width) { return 0; } public static void RegisterVisualPrefabs(string slotName, params (string prefabName, string visualName)[] pairs) { } public static int GetSlotCount() { return 0; } public static bool TryGetSlotIndexByName(string slotName, out int index, bool allowLocalized = true) { index = -1; return false; } public static bool TryGetSlotDescriptor(int index, out SlotDescriptor desc) { desc = default(SlotDescriptor); return false; } public static int GetSlotGridLinearIndex(Inventory inv, int slotIndex) { return -1; } public static Vector2i GetSlotGridPos(Inventory inv, int slotIndex) { //IL_0002: Unknown result type (might be due to invalid IL or missing references) return new Vector2i(-1, -1); } public static bool TryGetSlotIndexAtGridPos(Inventory inv, Vector2i gridPos, out int slotIndex) { slotIndex = -1; return false; } public static bool IsEquipmentCell(Inventory inv, int x, int y, out int slotIndex) { slotIndex = -1; return false; } public static bool IsQuickCell(Inventory inv, int x, int y, out int slotIndex) { slotIndex = -1; return false; } public static bool TryGetSlotSnapshot(Inventory inv, int slotIndex, out SlotSnapshot snapshot) { snapshot = default(SlotSnapshot); return false; } [IteratorStateMachine(typeof(<EnumerateSlots>d__55))] public static IEnumerable<SlotDescriptor> EnumerateSlots() { //yield-return decompiler failed: Unexpected instruction in Iterator.Dispose() return new <EnumerateSlots>d__55(-2); } [IteratorStateMachine(typeof(<GetAllSlotSnapshots>d__56))] public static IEnumerable<SlotSnapshot> GetAllSlotSnapshots(Inventory inv) { //yield-return decompiler failed: Unexpected instruction in Iterator.Dispose() return new <GetAllSlotSnapshots>d__56(-2); } [IteratorStateMachine(typeof(<GetQuickSlotSnapshots>d__57))] public static IEnumerable<SlotSnapshot> GetQuickSlotSnapshots(Inventory inv) { //yield-return decompiler failed: Unexpected instruction in Iterator.Dispose() return new <GetQuickSlotSnapshots>d__57(-2); } [IteratorStateMachine(typeof(<GetEquipmentSlotSnapshots>d__58))] public static IEnumerable<SlotSnapshot> GetEquipmentSlotSnapshots(Inventory inv) { //yield-return decompiler failed: Unexpected instruction in Iterator.Dispose() return new <GetEquipmentSlotSnapshots>d__58(-2); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static bool TryGetSlotIndexByItem(Player player, ItemData item, out int slotIndex) { slotIndex = -1; return false; } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static bool TryGetSlotIndexByItem(ItemData item, out int slotIndex) { slotIndex = -1; return false; } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static bool TryGetSlotDescriptorByItem(Player player, ItemData item, out SlotDescriptor desc) { desc = default(SlotDescriptor); return false; } public static bool SlotValidates(int slotIndex, ItemData item) { return false; } public static bool TryGetEquippedItem(int slotIndex, out ItemData? item) { item = null; return false; } public static bool TryGetSlotDescriptorByName(string slotName, out SlotDescriptor desc, bool allowLocalized = true) { desc = default(SlotDescriptor); if (TryGetSlotIndexByName(slotName, out var index, allowLocalized)) { return TryGetSlotDescriptor(index, out desc); } return false; } } [PublicAPI] public struct SlotDescriptor { public int Index { get; } public string Name { get; } public string OriginalName { get; } public bool IsQuickSlot { get; } public bool IsEquipmentSlot { get; } public bool IsCustom { get; } public Vector2 UiPosition { get; } public SlotDescriptor(int index, string name, string originalName, bool isQuickSlot, bool isEquipmentSlot, bool isCustom, Vector2 uiPosition) { //IL_0040: Unknown result type (might be due to invalid IL or missing references) //IL_0042: Unknown result type (might be due to invalid IL or missing references) Index = index; Name = name ?? string.Empty; OriginalName = originalName ?? string.Empty; IsQuickSlot = isQuickSlot; IsEquipmentSlot = isEquipmentSlot; IsCustom = isCustom; UiPosition = uiPosition; } } [PublicAPI] public class SlotInfo { public string[] SlotNames { get; set; } = Array.Empty<string>(); public string[] OriginalSlotNames { get; set; } = Array.Empty<string>(); public Vector2[] SlotPositions { get; set; } = Array.Empty<Vector2>(); public Func<Player, ItemData?>?[] GetItemFuncs { get; set; } = Array.Empty<Func<Player, ItemData>>(); public Func<ItemData, bool>?[] IsValidFuncs { get; set; } = Array.Empty<Func<ItemData, bool>>(); } [PublicAPI] public struct SlotSnapshot { public SlotDescriptor Descriptor { get; } public bool Occupied { get; } public Vector2i GridPos { get; } public int LinearGridIndex { get; } public SlotSnapshot(SlotDescriptor descriptor, bool occupied, Vector2i gridPos, int linearGridIndex) { //IL_000f: Unknown result type (might be due to invalid IL or missing references) //IL_0010: Unknown result type (might be due to invalid IL or missing references) Descriptor = descriptor; Occupied = occupied; GridPos = gridPos; LinearGridIndex = linearGridIndex; } [MethodImpl(MethodImplOptions.AggressiveInlining)] public bool Validates(ItemData item) { return API.SlotValidates(Descriptor.Index, item); } } } namespace AzuEPI.Core.Slots { public class Model { internal class Slot { public string Name; public string OriginalName; public Vector2 Position; public bool IsQuickSlot; public bool IsAPIAdded; public bool Occupied; public EquipmentSlot? EquipmentSlot => this as EquipmentSlot; } internal class EquipmentSlot : Slot { public Func<Player, ItemData?>? Get; public Func<ItemData, bool>? Valid; } } } namespace AzuExtendedPlayerInventory { [PublicAPI] public class API { public delegate void SlotAddedHandler(string slotName); public delegate void SlotRemovedHandler(string slotName); private static readonly Dictionary<SlotAddedHandler, AzuEPI.API.SlotAddedHandler> _slotAddedMap = new Dictionary<SlotAddedHandler, AzuEPI.API.SlotAddedHandler>(); private static readonly Dictionary<SlotRemovedHandler, AzuEPI.API.SlotRemovedHandler> _slotRemovedMap = new Dictionary<SlotRemovedHandler, AzuEPI.API.SlotRemovedHandler>(); private static readonly Dictionary<Action<Hud>, Action<Hud>> _hudAwakeMap = new Dictionary<Action<Hud>, Action<Hud>>(); private static readonly Dictionary<Action<Hud>, Action<Hud>> _hudAwakeCompleteMap = new Dictionary<Action<Hud>, Action<Hud>>(); private static readonly Dictionary<Action<Hud>, Action<Hud>> _hudUpdateMap = new Dictionary<Action<Hud>, Action<Hud>>(); private static readonly Dictionary<Action<Hud>, Action<Hud>> _hudUpdateCompleteMap = new Dictionary<Action<Hud>, Action<Hud>>(); public static event SlotAddedHandler? SlotAdded { add { SlotAddedHandler value2 = value; if (value2 == null || _slotAddedMap.ContainsKey(value2)) { return; } AzuEPI.API.SlotAddedHandler value3 = delegate(string s) { try { value2(s); } catch { } }; _slotAddedMap[value2] = value3; AzuEPI.API.SlotAdded += value3; } remove { if (value != null && _slotAddedMap.TryGetValue(value, out AzuEPI.API.SlotAddedHandler value2)) { AzuEPI.API.SlotAdded -= value2; _slotAddedMap.Remove(value); } } } public static event SlotRemovedHandler? SlotRemoved { add { SlotRemovedHandler value2 = value; if (value2 == null || _slotRemovedMap.ContainsKey(value2)) { return; } AzuEPI.API.SlotRemovedHandler value3 = delegate(string s) { try { value2(s); } catch { } }; _slotRemovedMap[value2] = value3; AzuEPI.API.SlotRemoved += value3; } remove { if (value != null && _slotRemovedMap.TryGetValue(value, out AzuEPI.API.SlotRemovedHandler value2)) { AzuEPI.API.SlotRemoved -= value2; _slotRemovedMap.Remove(value); } } } public static event Action<Hud>? OnHudAwake { add { AddHudEvent(value, _hudAwakeMap, delegate(Action<Hud> h) { AzuEPI.API.OnHudAwake += h; }); } remove { RemoveHudEvent(value, _hudAwakeMap, delegate(Action<Hud> h) { AzuEPI.API.OnHudAwake -= h; }); } } public static event Action<Hud>? OnHudAwakeComplete { add { AddHudEvent(value, _hudAwakeCompleteMap, delegate(Action<Hud> h) { AzuEPI.API.OnHudAwakeComplete += h; }); } remove { RemoveHudEvent(value, _hudAwakeCompleteMap, delegate(Action<Hud> h) { AzuEPI.API.OnHudAwakeComplete -= h; }); } } public static event Action<Hud>? OnHudUpdate { add { AddHudEvent(value, _hudUpdateMap, delegate(Action<Hud> h) { AzuEPI.API.OnHudUpdate += h; }); } remove { RemoveHudEvent(value, _hudUpdateMap, delegate(Action<Hud> h) { AzuEPI.API.OnHudUpdate -= h; }); } } public static event Action<Hud>? OnHudUpdateComplete { add { AddHudEvent(value, _hudUpdateCompleteMap, delegate(Action<Hud> h) { AzuEPI.API.OnHudUpdateComplete += h; }); } remove { RemoveHudEvent(value, _hudUpdateCompleteMap, delegate(Action<Hud> h) { AzuEPI.API.OnHudUpdateComplete -= h; }); } } private static void AddHudEvent(Action<Hud>? handler, Dictionary<Action<Hud>, Action<Hud>> map, Action<Action<Hud>> subscribe) { Action<Hud> handler2 = handler; if (handler2 == null || map.ContainsKey(handler2)) { return; } Action<Hud> value = delegate(Hud h) { try { handler2(h); } catch { } }; map[handler2] = value; } private static void RemoveHudEvent(Action<Hud>? handler, Dictionary<Action<Hud>, Action<Hud>> map, Action<Action<Hud>> unsubscribe) { if (handler != null && map.TryGetValue(handler, out Action<Hud> _)) { map.Remove(handler); } } public static bool IsLoaded() { return AzuEPI.API.IsLoaded(); } public static bool AddSlot(string slotName, Func<Player, ItemData?> getItem, Func<ItemData, bool> isValid, int index = -1) { return false; } public static bool RemoveSlot(string slotName) { return AzuEPI.API.RemoveSlot(slotName); } public static SlotInfo GetSlots() { AzuEPI.SlotInfo slots = AzuEPI.API.GetSlots(); return new SlotInfo { SlotNames = (slots.SlotNames ?? Array.Empty<string>()), SlotPositions = (slots.SlotPositions ?? Array.Empty<Vector2>()), GetItemFuncs = (slots.GetItemFuncs ?? Array.Empty<Func<Player, ItemData>>()), IsValidFuncs = (slots.IsValidFuncs ?? Array.Empty<Func<ItemData, bool>>()) }; } public static SlotInfo GetQuickSlots() { AzuEPI.SlotInfo quickSlots = AzuEPI.API.GetQuickSlots(); return new SlotInfo { SlotNames = (quickSlots.SlotNames ?? Array.Empty<string>()), SlotPositions = (quickSlots.SlotPositions ?? Array.Empty<Vector2>()), GetItemFuncs = (quickSlots.GetItemFuncs ?? Array.Empty<Func<Player, ItemData>>()), IsValidFuncs = (quickSlots.IsValidFuncs ?? Array.Empty<Func<ItemData, bool>>()) }; } public static List<ItemData> GetQuickSlotsItems() { return AzuEPI.API.GetQuickSlotsItems(); } public static int GetAddedRows(int width) { return AzuEPI.API.GetAddedRows(width); } public static void HudAwake(Hud h) { } public static void HudAwakeComplete(Hud h) { } public static void HudUpdate(Hud h) { } public static void HudUpdateComplete(Hud h) { } private static void SafeInvoke(Action a) { try { a(); } catch { } } } [PublicAPI] public class SlotInfo { public string[] SlotNames { get; set; } = Array.Empty<string>(); public Vector2[] SlotPositions { get; set; } = Array.Empty<Vector2>(); public Func<Player, ItemData?>?[] GetItemFuncs { get; set; } = Array.Empty<Func<Player, ItemData>>(); public Func<ItemData, bool>?[] IsValidFuncs { get; set; } = Array.Empty<Func<ItemData, bool>>(); } } namespace AlmanacClasses.API { public static class ClassesAPI { private static readonly MethodInfo? API_AddExperience; private static readonly MethodInfo? API_GetLevel; private static readonly MethodInfo? API_GetCharacteristic; public static void AddEXP(int amount) { API_AddExperience?.Invoke(null, new object[1] { amount }); } public static int GetLevel() { return (int)(API_GetLevel?.Invoke(null, null) ?? ((object)0)); } public static int GetCharacteristic(string type) { return (int)(API_GetCharacteristic?.Invoke(null, new object[1] { type }) ?? ((object)0)); } public static int GetConstitution() { return GetCharacteristic("Constitution"); } public static int GetDexterity() { return GetCharacteristic("Dexterity"); } public static int GetStrength() { return GetCharacteristic("Strength"); } public static int GetIntelligence() { return GetCharacteristic("Intelligence"); } public static int GetWisdom() { return GetCharacteristic("Wisdom"); } static ClassesAPI() { Type type = Type.GetType("AlmanacClasses.API.API, AlmanacClasses"); if ((object)type != null) { API_AddExperience = type.GetMethod("AddExperience", BindingFlags.Static | BindingFlags.Public); API_GetLevel = type.GetMethod("GetLevel", BindingFlags.Static | BindingFlags.Public); API_GetCharacteristic = type.GetMethod("GetCharacteristic", BindingFlags.Static | BindingFlags.Public); } } } } namespace Deathlink { internal class Logger { public static LogLevel Level = (LogLevel)16; public static void enableDebugLogging(object sender, EventArgs e) { //IL_0016: 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) if (ValConfig.EnableDebugMode.Value) { Level = (LogLevel)32; } else { Level = (LogLevel)16; } } public static void CheckEnableDebugLogging() { //IL_0016: 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) if (ValConfig.EnableDebugMode.Value) { Level = (LogLevel)32; } else { Level = (LogLevel)16; } } public static void LogDebug(string message) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Invalid comparison between Unknown and I4 if ((int)Level >= 32) { Deathlink.Log.LogInfo((object)message); } } public static void LogInfo(string message) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Invalid comparison between Unknown and I4 if ((int)Level >= 16) { Deathlink.Log.LogInfo((object)message); } } public static void LogWarning(string message) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0006: Invalid comparison between Unknown and I4 if ((int)Level >= 4) { Deathlink.Log.LogWarning((object)message); } } public static void LogError(string message) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0006: Invalid comparison between Unknown and I4 if ((int)Level >= 2) { Deathlink.Log.LogError((object)message); } } } public static class Extensions { private static readonly List<ItemType> EquipmentTypes = new List<ItemType> { (ItemType)7, (ItemType)12, (ItemType)6, (ItemType)11, (ItemType)4, (ItemType)5, (ItemType)19, (ItemType)17, (ItemType)18, (ItemType)3, (ItemType)14, (ItemType)22, (ItemType)20, (ItemType)24 }; public static List<ItemData> GetEquipment(this List<ItemData> list) { return list.Where((ItemData x) => EquipmentTypes.Contains(x.m_shared.m_itemType)).ToList(); } public static List<ItemData> GetNotEquipment(this List<ItemData> list) { return list.Where((ItemData x) => !EquipmentTypes.Contains(x.m_shared.m_itemType)).ToList(); } public static bool IsEquipment(this ItemData item) { //IL_000b: Unknown result type (might be due to invalid IL or missing references) if (EquipmentTypes.Contains(item.m_shared.m_itemType)) { return true; } return false; } } [BepInPlugin("MidnightsFX.Deathlink", "Deathlink", "0.8.3")] [BepInDependency(/*Could not decode attribute arguments.*/)] [NetworkCompatibility(/*Could not decode attribute arguments.*/)] [BepInDependency(/*Could not decode attribute arguments.*/)] [BepInDependency(/*Could not decode attribute arguments.*/)] [BepInDependency(/*Could not decode attribute arguments.*/)] internal class Deathlink : BaseUnityPlugin { public const string PluginGUID = "MidnightsFX.Deathlink"; public const string PluginName = "Deathlink"; public const string PluginVersion = "0.8.3"; public ValConfig cfg; internal static AssetBundle EmbeddedResourceBundle; internal static bool AzuEPILoaded = false; internal static bool RustyAlmanacClassesLoaded = false; internal static bool WackyMMOLoaded = false; public static CustomLocalization Localization = LocalizationManager.Instance.GetLocalization(); public static ManualLogSource Log; public void Awake() { Log = ((BaseUnityPlugin)this).Logger; cfg = new ValConfig(((BaseUnityPlugin)this).Config); AddLocalizations(); EmbeddedResourceBundle = AssetUtils.LoadAssetBundleFromResources("Deathlink.AssetsEmbedded.deathless", typeof(Deathlink).Assembly); DeathProgressionSkill.SetupDeathSkill(); if (AzuExtendedPlayerInventory.API.IsLoaded()) { AzuEPILoaded = true; } if (BepInExUtils.GetPlugins(false).Keys.Contains("WackyMole.EpicMMOSystem")) { EpicMMOSystem_API.Init(); if (EpicMMOSystem_API.state == EpicMMOSystem_API.API_State.Ready) { WackyMMOLoaded = true; ((BaseUnityPlugin)this).Logger.LogInfo((object)"WackMMO API loaded."); } else { ((BaseUnityPlugin)this).Logger.LogInfo((object)"WackMMO API installed but API not ready."); } } if (BepInExUtils.GetPlugins(false).Keys.Contains("RustyMods.AlmanacClasses")) { RustyAlmanacClassesLoaded = true; } Harmony.CreateAndPatchAll(Assembly.GetExecutingAssembly(), (string)null); DeathConfigurationData.Init(); TerminalCommands.AddCommands(); ((BaseUnityPlugin)this).Logger.LogInfo((object)"Death is not the end."); } public static DataObjects.DeathChoiceLevel pcfg() { return DeathConfigurationData.playerDeathConfiguration; } private void AddLocalizations() { Localization = LocalizationManager.Instance.GetLocalization(); string text = Path.Combine(Paths.ConfigPath, "Deathlink", "localizations"); Directory.CreateDirectory(text); string[] manifestResourceNames = typeof(Deathlink).Assembly.GetManifestResourceNames(); foreach (string text2 in manifestResourceNames) { if (!text2.Contains("Localizations")) { continue; } string text3 = Regex.Replace(ReadEmbeddedResourceFile(text2), "\\/\\/.*", ""); Dictionary<string, string> internal_localization = SimpleJson.DeserializeObject<Dictionary<string, string>>(text3); string[] array = text2.Split(new char[1] { '.' }); if (File.Exists(text + "/" + array[2] + ".json")) { string text4 = File.ReadAllText(text + "/" + array[2] + ".json"); try { Dictionary<string, string> dictionary = SimpleJson.DeserializeObject<Dictionary<string, string>>(text4); UpdateLocalizationWithMissingKeys(internal_localization, dictionary); ((BaseUnityPlugin)this).Logger.LogDebug((object)("Reading " + text + "/" + array[2] + ".json")); File.WriteAllText(text + "/" + array[2] + ".json", SimpleJson.SerializeObject((object)dictionary)); string text5 = File.ReadAllText(text + "/" + array[2] + ".json"); Localization.AddJsonFile(array[2], text5); } catch { File.WriteAllText(text + "/" + array[2] + ".json", text3); ((BaseUnityPlugin)this).Logger.LogDebug((object)("Reading " + text2)); Localization.AddJsonFile(array[2], text3); } } else { File.WriteAllText(text + "/" + array[2] + ".json", text3); ((BaseUnityPlugin)this).Logger.LogDebug((object)("Reading " + text2)); Localization.AddJsonFile(array[2], text3); } ((BaseUnityPlugin)this).Logger.LogDebug((object)("Added localization: '" + array[2] + "'")); } } private void UpdateLocalizationWithMissingKeys(Dictionary<string, string> internal_localization, Dictionary<string, string> cached_localization) { if (internal_localization.Keys.Count == cached_localization.Keys.Count) { return; } ((BaseUnityPlugin)this).Logger.LogDebug((object)"Cached localization was missing some entries. They will be added."); foreach (KeyValuePair<string, string> item in internal_localization) { if (!cached_localization.ContainsKey(item.Key)) { cached_localization.Add(item.Key, item.Value); } } } private string ReadEmbeddedResourceFile(string filename) { using Stream stream = typeof(Deathlink).Assembly.GetManifestResourceStream(filename); using StreamReader streamReader = new StreamReader(stream); return streamReader.ReadToEnd(); } public static List<T> shuffleList<T>(List<T> inputList) { int i = 0; int count = inputList.Count; int num = 0; T val = default(T); List<T> list = new List<T>(); list.AddRange(inputList); for (; i < count; i++) { num = Random.Range(i, list.Count); val = list[i]; list[i] = list[num]; list[num] = val; } return list; } } } namespace Deathlink.external { public static class EpicMMOSystem_API { public enum API_State { NotReady, NotInstalled, Ready } public enum Attribut { Strength, Agility, Intellect, Body, Vigour, Special } public static API_State state; private static MethodInfo eGetLevel; private static MethodInfo eAddExp; private static MethodInfo eGetAttribute; private static MethodInfo eGetAttributeRusty; private static MethodInfo eSetSingleRate; public static int GetLevel() { int result = 0; Init(); if (eGetLevel != null) { result = (int)eGetLevel.Invoke(null, null); } return result; } public static int GetAttribute(Attribut attribute) { int result = 0; Init(); if (eGetAttribute != null) { result = (int)eGetAttribute.Invoke(null, new object[1] { attribute }); } return result; } public static int GetAttributeRusty(string attribute) { int result = 0; Init(); if (eGetAttributeRusty != null) { result = (int)eGetAttributeRusty.Invoke(null, new object[1] { attribute }); } return result; } public static void AddExp(int value) { Init(); eAddExp?.Invoke(null, new object[1] { value }); } public static void SetSingleRate(float rate) { Init(); eSetSingleRate?.Invoke(null, new object[1] { rate }); } public static void Init() { API_State aPI_State = state; if ((uint)(aPI_State - 1) > 1u) { if (Type.GetType("EpicMMOSystem.EpicMMOSystem, EpicMMOSystem") == null) { state = API_State.NotInstalled; return; } state = API_State.Ready; Type? type = Type.GetType("API.EMMOS_API, EpicMMOSystem"); eGetLevel = type.GetMethod("GetLevel", BindingFlags.Static | BindingFlags.Public); eAddExp = type.GetMethod("AddExp", BindingFlags.Static | BindingFlags.Public); eGetAttribute = type.GetMethod("GetAttribute", BindingFlags.Static | BindingFlags.Public); eGetAttributeRusty = type.GetMethod("GetAttribute", BindingFlags.Static | BindingFlags.Public); eSetSingleRate = type.GetMethod("SetSingleRate", BindingFlags.Static | BindingFlags.Public); } } } } namespace Deathlink.Death { public static class Compendium { [HarmonyPatch(typeof(TextsDialog), "UpdateTextsList")] public static class TextsDialog_UpdateTextsList_Patch { public static void Postfix(TextsDialog __instance) { AddDeathLinkExplanationPage(__instance); } private static void AddDeathLinkExplanationPage(TextsDialog textsDialog) { //IL_0138: Unknown result type (might be due to invalid IL or missing references) //IL_0142: Expected O, but got Unknown DataObjects.DeathChoiceLevel playerDeathConfiguration = DeathConfigurationData.playerDeathConfiguration; StringBuilder stringBuilder = new StringBuilder(); stringBuilder.AppendLine("<size=48>" + Localization.instance.Localize("$comp_header") + ": <color=" + specialColor + ">" + playerDeathConfiguration.DisplayName + "</color></size>"); stringBuilder.AppendLine(); stringBuilder.AppendLine("<size=30><b>Death Effects</b></size>"); stringBuilder.AppendLine(playerDeathConfiguration.GetDeathStyleDescription()); stringBuilder.AppendLine(); if (playerDeathConfiguration.SkillModifiers.Count > 0) { stringBuilder.AppendLine("<size=30><b>Skill Modifiers</b></size>"); stringBuilder.AppendLine(playerDeathConfiguration.GetSkillModiferDescription()); stringBuilder.AppendLine(); } if (playerDeathConfiguration.ResourceModifiers.Count > 0) { stringBuilder.AppendLine("<size=30><b>Resource Modifiers</b></size>"); stringBuilder.AppendLine(playerDeathConfiguration.GetResourceModiferDescription()); stringBuilder.AppendLine(); } if (playerDeathConfiguration.DeathLootModifiers.Count > 0) { stringBuilder.AppendLine("<size=30><b>Loot Modifiers</b></size>"); stringBuilder.AppendLine(playerDeathConfiguration.GetLootModifiersDescription()); stringBuilder.AppendLine(); } textsDialog.m_texts.Insert(0, new TextInfo(Localization.instance.Localize("$deathlink_settings"), Localization.instance.Localize(stringBuilder.ToString()))); } } private static string specialColor = "#ffa64d"; } public static class DeathChoiceEnable { [HarmonyPatch(typeof(InventoryGui), "Show")] public static class ShowDeathChoiceUI { public static void Postfix(InventoryGui __instance) { if (ValConfig.UsePrivateKeysForDeathChoice.Value) { if ((Object)(object)Player.m_localPlayer != (Object)null && Player.m_localPlayer.PlayerHasUniqueKey(DataObjects.DeathChoiceKey)) { return; } } else if ((Object)(object)Player.m_localPlayer != (Object)null && DeathConfigurationData.playerSettings.ContainsKey(Player.m_localPlayer.GetPlayerID())) { return; } if ((Object)(object)((Component)__instance).gameObject.GetComponent<DeathChoices.DeathChoiceUI>() == (Object)null) { ((Component)__instance).gameObject.AddComponent<DeathChoices.DeathChoiceUI>(); } DeathChoices.DeathChoiceUI.Instance.Show(); } } [HarmonyPatch(typeof(InventoryGui), "Hide")] public static class HideDeathChoiceUI { public static void Postfix(InventoryGui __instance) { DeathChoices.DeathChoiceUI.Instance.Hide(); } } } public class DeathChoices { public class DeathChoiceUI : MonoBehaviour { private static DeathChoiceUI _instance; private static GameObject DeathChoicePanel; private static GameObject ChoicesScrollView; private static GameObject ChoicesContent; private static GameObject ChoicesContainer; private static GameObject manualCloseButton; private static GameObject selectChoiceButton; private static Text DeathPenaltyDescription; private static Text XPModifiersDescription; private static Text LootModifersDescription; private static Text HarvestModifiersDescription; private static List<Toggle> difficultyToggles = new List<Toggle>(); private static ToggleGroup choiceGroup; private static string selectedDeathChoice = "none"; public static DeathChoiceUI Instance => _instance ?? (_instance = new DeathChoiceUI()); public void Awake() { CreateStaticUIObjects(); SetChoiceList(); } public void Show() { if ((Object)(object)DeathChoicePanel == (Object)null) { CreateStaticUIObjects(); } DeathChoicePanel.SetActive(true); } public void Hide() { if ((Object)(object)DeathChoicePanel != (Object)null) { DeathChoicePanel.SetActive(false); } GUIManager.BlockInput(false); } public void MakePlayerDeathSelection() { if ((Object)(object)Player.m_localPlayer == (Object)null) { Logger.LogWarning("Player not set, ensure the local player is set."); return; } if (selectedDeathChoice == "none") { Logger.LogWarning("No death type selected"); return; } Logger.LogDebug("Player selected death type " + selectedDeathChoice); long playerID = Player.m_localPlayer.GetPlayerID(); if (DeathConfigurationData.playerSettings.ContainsKey(playerID)) { DeathConfigurationData.playerSettings.Remove(playerID); } DeathConfigurationData.playerSettings.Add(playerID, new DataObjects.DeathConfiguration { DeathChoiceLevel = selectedDeathChoice }); Player.m_localPlayer.AddUniqueKeyValue(DataObjects.DeathChoiceKey, selectedDeathChoice); DeathConfigurationData.CheckAndSetPlayerDeathConfig(); DeathConfigurationData.WritePlayerChoices(); Hide(); } private void SetChoiceList() { //IL_00d9: Unknown result type (might be due to invalid IL or missing references) //IL_00f4: Unknown result type (might be due to invalid IL or missing references) difficultyToggles.Clear(); int num = -75; foreach (KeyValuePair<string, DataObjects.DeathChoiceLevel> entry in DeathConfigurationData.DeathLevels) { GameObject obj = Object.Instantiate<GameObject>(ChoicesContainer, ChoicesContent.transform); Transform val = obj.transform.Find("selecter"); ((Component)val.Find("Label")).GetComponent<Text>().text = entry.Key; ((Component)obj.transform.Find("ChoiceName")).GetComponent<Text>().text = entry.Value.DisplayName; Toggle component = ((Component)val).GetComponent<Toggle>(); component.group = choiceGroup; ((UnityEvent<bool>)(object)component.onValueChanged).AddListener((UnityAction<bool>)delegate { ((Component)DeathPenaltyDescription).GetComponent<Text>().text = entry.Value.GetDeathStyleDescription(); ((Component)XPModifiersDescription).GetComponent<Text>().text = entry.Value.GetSkillModiferDescription(); ((Component)LootModifersDescription).GetComponent<Text>().text = entry.Value.GetLootModifiersDescription(); ((Component)HarvestModifiersDescription).GetComponent<Text>().text = entry.Value.GetResourceModiferDescription(); selectedDeathChoice = entry.Key; }); obj.SetActive(true); obj.transform.localPosition = new Vector3 { x = 5f, y = num }; difficultyToggles.Add(component); num -= 50; } } private void CreateStaticUIObjects() { //IL_0041: Unknown result type (might be due to invalid IL or missing references) //IL_0050: Unknown result type (might be due to invalid IL or missing references) //IL_005f: Unknown result type (might be due to invalid IL or missing references) //IL_00ac: Unknown result type (might be due to invalid IL or missing references) //IL_00bb: Unknown result type (might be due to invalid IL or missing references) //IL_00ca: Unknown result type (might be due to invalid IL or missing references) //IL_00e0: Unknown result type (might be due to invalid IL or missing references) //IL_00e6: Unknown result type (might be due to invalid IL or missing references) //IL_012d: 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_014b: Unknown result type (might be due to invalid IL or missing references) //IL_015c: Unknown result type (might be due to invalid IL or missing references) //IL_0162: Unknown result type (might be due to invalid IL or missing references) //IL_01b9: Unknown result type (might be due to invalid IL or missing references) //IL_01c8: Unknown result type (might be due to invalid IL or missing references) //IL_01d7: Unknown result type (might be due to invalid IL or missing references) //IL_020d: Unknown result type (might be due to invalid IL or missing references) //IL_0217: Expected O, but got Unknown //IL_024a: Unknown result type (might be due to invalid IL or missing references) //IL_0259: Unknown result type (might be due to invalid IL or missing references) //IL_0268: Unknown result type (might be due to invalid IL or missing references) //IL_027e: Unknown result type (might be due to invalid IL or missing references) //IL_0284: Unknown result type (might be due to invalid IL or missing references) //IL_02cb: Unknown result type (might be due to invalid IL or missing references) //IL_02da: Unknown result type (might be due to invalid IL or missing references) //IL_02e9: Unknown result type (might be due to invalid IL or missing references) //IL_02fa: Unknown result type (might be due to invalid IL or missing references) //IL_0300: Unknown result type (might be due to invalid IL or missing references) //IL_0369: Unknown result type (might be due to invalid IL or missing references) //IL_0378: Unknown result type (might be due to invalid IL or missing references) //IL_0387: Unknown result type (might be due to invalid IL or missing references) //IL_039d: Unknown result type (might be due to invalid IL or missing references) //IL_03a3: Unknown result type (might be due to invalid IL or missing references) //IL_03ea: Unknown result type (might be due to invalid IL or missing references) //IL_03f9: Unknown result type (might be due to invalid IL or missing references) //IL_0408: Unknown result type (might be due to invalid IL or missing references) //IL_0419: Unknown result type (might be due to invalid IL or missing references) //IL_041f: Unknown result type (might be due to invalid IL or missing references) //IL_0488: Unknown result type (might be due to invalid IL or missing references) //IL_0497: Unknown result type (might be due to invalid IL or missing references) //IL_04a6: Unknown result type (might be due to invalid IL or missing references) //IL_04bc: Unknown result type (might be due to invalid IL or missing references) //IL_04c2: Unknown result type (might be due to invalid IL or missing references) //IL_0509: Unknown result type (might be due to invalid IL or missing references) //IL_0518: Unknown result type (might be due to invalid IL or missing references) //IL_0527: Unknown result type (might be due to invalid IL or missing references) //IL_0538: Unknown result type (might be due to invalid IL or missing references) //IL_053e: Unknown result type (might be due to invalid IL or missing references) //IL_05a7: Unknown result type (might be due to invalid IL or missing references) //IL_05b6: Unknown result type (might be due to invalid IL or missing references) //IL_05c5: Unknown result type (might be due to invalid IL or missing references) //IL_05db: Unknown result type (might be due to invalid IL or missing references) //IL_05e1: Unknown result type (might be due to invalid IL or missing references) //IL_0628: Unknown result type (might be due to invalid IL or missing references) //IL_0637: Unknown result type (might be due to invalid IL or missing references) //IL_0646: Unknown result type (might be due to invalid IL or missing references) //IL_0657: Unknown result type (might be due to invalid IL or missing references) //IL_065d: Unknown result type (might be due to invalid IL or missing references) //IL_06c6: Unknown result type (might be due to invalid IL or missing references) //IL_06d5: Unknown result type (might be due to invalid IL or missing references) //IL_06e4: Unknown result type (might be due to invalid IL or missing references) //IL_0713: Unknown result type (might be due to invalid IL or missing references) //IL_071d: Expected O, but got Unknown //IL_0747: Unknown result type (might be due to invalid IL or missing references) //IL_074c: Unknown result type (might be due to invalid IL or missing references) //IL_0771: Unknown result type (might be due to invalid IL or missing references) //IL_078f: Unknown result type (might be due to invalid IL or missing references) //IL_0790: Unknown result type (might be due to invalid IL or missing references) //IL_07e0: Unknown result type (might be due to invalid IL or missing references) //IL_07f4: Expected O, but got Unknown //IL_0825: Unknown result type (might be due to invalid IL or missing references) //IL_087c: Unknown result type (might be due to invalid IL or missing references) //IL_0881: Unknown result type (might be due to invalid IL or missing references) //IL_08da: Unknown result type (might be due to invalid IL or missing references) //IL_08e9: Unknown result type (might be due to invalid IL or missing references) //IL_08f8: Unknown result type (might be due to invalid IL or missing references) //IL_090e: Unknown result type (might be due to invalid IL or missing references) //IL_0914: Unknown result type (might be due to invalid IL or missing references) if (GUIManager.Instance == null || !Object.op_Implicit((Object)(object)GUIManager.CustomGUIFront)) { Logger.LogWarning("GUIManager not setup, skipping static object creation."); return; } Logger.LogDebug("Creating static UI"); DeathChoicePanel = GUIManager.Instance.CreateWoodpanel(GUIManager.CustomGUIFront.transform, new Vector2(0.5f, 0.5f), new Vector2(0.5f, 0.5f), new Vector2(0f, 0f), 800f, 800f, true); DeathChoicePanel.SetActive(false); ((Object)GUIManager.Instance.CreateText(Localization.instance.Localize("$selection_header"), DeathChoicePanel.transform, new Vector2(0.5f, 0.5f), new Vector2(0.5f, 0.5f), new Vector2(50f, 360f), GUIManager.Instance.AveriaSerifBold, 30, GUIManager.Instance.ValheimOrange, true, Color.black, 350f, 40f, false)).name = "DLHeader"; Text component = GUIManager.Instance.CreateText(Localization.instance.Localize("$selection_description"), DeathChoicePanel.transform, new Vector2(0.5f, 0.5f), new Vector2(0.5f, 0.5f), new Vector2(0f, 315f), GUIManager.Instance.AveriaSerif, 20, Color.white, true, Color.black, 560f, 60f, false).GetComponent<Text>(); component.resizeTextForBestFit = true; component.resizeTextMaxSize = 20; component.alignment = (TextAnchor)4; manualCloseButton = GUIManager.Instance.CreateButton(Localization.instance.Localize("$close"), DeathChoicePanel.transform, new Vector2(0.5f, 0.5f), new Vector2(0.5f, 0.5f), new Vector2(360f, 360f), 60f, 60f); Button component2 = manualCloseButton.GetComponent<Button>(); ((Selectable)component2).interactable = true; ((UnityEvent)component2.onClick).AddListener(new UnityAction(Hide)); manualCloseButton.SetActive(true); ((Object)GUIManager.Instance.CreateText(Localization.instance.Localize("$death_penalty_header"), DeathChoicePanel.transform, new Vector2(0.5f, 0.5f), new Vector2(0.5f, 0.5f), new Vector2(100f, 220f), GUIManager.Instance.AveriaSerifBold, 22, GUIManager.Instance.ValheimOrange, true, Color.black, 400f, 40f, false)).name = "DeathPenaltyTitle"; GameObject obj = GUIManager.Instance.CreateText(Localization.instance.Localize("$death_penalty_description"), DeathChoicePanel.transform, new Vector2(0.5f, 0.5f), new Vector2(0.5f, 0.5f), new Vector2(150f, 110f), GUIManager.Instance.AveriaSerifBold, 18, Color.white, true, Color.black, 500f, 200f, false); ((Object)obj).name = "DeathPenaltyDesc"; DeathPenaltyDescription = obj.GetComponent<Text>(); DeathPenaltyDescription.resizeTextForBestFit = true; DeathPenaltyDescription.resizeTextMaxSize = 18; ((Object)GUIManager.Instance.CreateText(Localization.instance.Localize("$xp_header"), DeathChoicePanel.transform, new Vector2(0.5f, 0.5f), new Vector2(0.5f, 0.5f), new Vector2(100f, 30f), GUIManager.Instance.AveriaSerifBold, 22, GUIManager.Instance.ValheimOrange, true, Color.black, 400f, 40f, false)).name = "xpModifiersTitle"; GameObject obj2 = GUIManager.Instance.CreateText(Localization.instance.Localize("$xp_mod_description"), DeathChoicePanel.transform, new Vector2(0.5f, 0.5f), new Vector2(0.5f, 0.5f), new Vector2(150f, -80f), GUIManager.Instance.AveriaSerifBold, 16, Color.white, true, Color.black, 500f, 200f, false); ((Object)obj2).name = "xpModifiersDesc"; XPModifiersDescription = obj2.GetComponent<Text>(); XPModifiersDescription.resizeTextForBestFit = true; XPModifiersDescription.resizeTextMaxSize = 18; ((Object)GUIManager.Instance.CreateText(Localization.instance.Localize("$loot_header"), DeathChoicePanel.transform, new Vector2(0.5f, 0.5f), new Vector2(0.5f, 0.5f), new Vector2(100f, -130f), GUIManager.Instance.AveriaSerifBold, 22, GUIManager.Instance.ValheimOrange, true, Color.black, 400f, 40f, false)).name = "lootModifiersTitle"; GameObject obj3 = GUIManager.Instance.CreateText(Localization.instance.Localize("$loot_modifier_description"), DeathChoicePanel.transform, new Vector2(0.5f, 0.5f), new Vector2(0.5f, 0.5f), new Vector2(150f, -240f), GUIManager.Instance.AveriaSerifBold, 16, Color.white, true, Color.black, 500f, 200f, false); ((Object)obj3).name = "lootModifersDesc"; LootModifersDescription = obj3.GetComponent<Text>(); LootModifersDescription.resizeTextForBestFit = true; LootModifersDescription.resizeTextMaxSize = 18; ((Object)GUIManager.Instance.CreateText(Localization.instance.Localize("$harvest_header"), DeathChoicePanel.transform, new Vector2(0.5f, 0.5f), new Vector2(0.5f, 0.5f), new Vector2(100f, -260f), GUIManager.Instance.AveriaSerifBold, 22, GUIManager.Instance.ValheimOrange, true, Color.black, 400f, 40f, false)).name = "harvestModifiersTitle"; GameObject obj4 = GUIManager.Instance.CreateText(Localization.instance.Localize("$harvest_modifier_description"), DeathChoicePanel.transform, new Vector2(0.5f, 0.5f), new Vector2(0.5f, 0.5f), new Vector2(150f, -370f), GUIManager.Instance.AveriaSerifBold, 16, Color.white, true, Color.black, 500f, 200f, false); ((Object)obj4).name = "harvestModifersDesc"; HarvestModifiersDescription = obj4.GetComponent<Text>(); HarvestModifiersDescription.resizeTextForBestFit = true; HarvestModifiersDescription.resizeTextMaxSize = 18; selectChoiceButton = GUIManager.Instance.CreateButton(Localization.instance.Localize("$deathchoice_select"), DeathChoicePanel.transform, new Vector2(0.5f, 0.5f), new Vector2(0.5f, 0.5f), new Vector2(-240f, -290f), 200f, 80f); ((UnityEvent)selectChoiceButton.GetComponent<Button>().onClick).AddListener(new UnityAction(MakePlayerDeathSelection)); Logger.LogDebug("Setting up scroll entry"); ChoicesScrollView = GUIManager.Instance.CreateScrollView(DeathChoicePanel.transform, false, true, 10f, 10f, GUIManager.Instance.ValheimScrollbarHandleColorBlock, Color.grey, 250f, 400f); ChoicesScrollView.transform.localPosition = Vector2.op_Implicit(new Vector2 { x = -260f, y = -30f }); ChoicesContent = ((Component)ChoicesScrollView.GetComponentInChildren<ContentSizeFitter>()).gameObject; ChoicesScrollView.GetComponentInChildren<ScrollRect>().scrollSensitivity = 200f; choiceGroup = ChoicesContent.AddComponent<ToggleGroup>(); Logger.LogDebug("Setting up death choice template entry"); ChoicesContainer = Object.Instantiate<GameObject>(new GameObject("DeathChoice"), DeathChoicePanel.transform); RectTransform obj5 = ChoicesContainer.AddComponent<RectTransform>(); obj5.SetSizeWithCurrentAnchors((Axis)0, 100f); obj5.SetSizeWithCurrentAnchors((Axis)1, 50f); ((Transform)obj5).position = new Vector3(0f, 0f); ChoicesContainer.AddComponent<LayoutElement>().minHeight = 50f; ChoicesContainer.SetActive(false); GameObject obj6 = GUIManager.Instance.CreateToggle(ChoicesContainer.transform, 40f, 40f); obj6.transform.localPosition = Vector2.op_Implicit(new Vector2(10f, 0f)); ((Object)obj6).name = "selecter"; ((Component)obj6.transform.Find("Label")).gameObject.SetActive(false); obj6.GetComponent<Toggle>().isOn = false; ((Object)GUIManager.Instance.CreateText("Name", ChoicesContainer.transform, new Vector2(0.5f, 0.5f), new Vector2(0.5f, 0.5f), new Vector2(200f, 0f), GUIManager.Instance.AveriaSerifBold, 20, GUIManager.Instance.ValheimYellow, true, Color.black, 350f, 40f, false)).name = "ChoiceName"; } } } public static class DeathProgressionSkill { [HarmonyPatch(typeof(Player), "RaiseSkill")] public class Deathskill_EXP_Patch { public static void Postfix(Player __instance) { //IL_03b2: Unknown result type (might be due to invalid IL or missing references) timeSinceGameStart += Time.deltaTime; if (lastSkillIncreaseTickTime == 0f) { lastSkillIncreaseTickTime = timeSinceGameStart + ValConfig.SkillProgressUpdateCheckInterval.Value; PlayerProfile playerProfile = Game.instance.GetPlayerProfile(); _bossKills = playerProfile.m_playerStats.m_stats[(PlayerStatType)85]; _enemykills = playerProfile.m_playerStats.m_stats[(PlayerStatType)6]; _piecesBuilt = playerProfile.m_playerStats.m_stats[(PlayerStatType)2]; _treesChopped = playerProfile.m_playerStats.m_stats[(PlayerStatType)27]; _mineAmount = playerProfile.m_playerStats.m_stats[(PlayerStatType)38]; _craftAndUpgrades = playerProfile.m_playerStats.m_stats[(PlayerStatType)1]; } if (timeSinceGameStart > lastSkillIncreaseTickTime) { lastSkillIncreaseTickTime = timeSinceGameStart + ValConfig.SkillProgressUpdateCheckInterval.Value; PlayerProfile playerProfile2 = Game.instance.GetPlayerProfile(); float num = playerProfile2.m_playerStats.m_stats[(PlayerStatType)85]; float num2 = playerProfile2.m_playerStats.m_stats[(PlayerStatType)6]; float num3 = playerProfile2.m_playerStats.m_stats[(PlayerStatType)2]; float num4 = playerProfile2.m_playerStats.m_stats[(PlayerStatType)27]; float num5 = playerProfile2.m_playerStats.m_stats[(PlayerStatType)38]; float num6 = playerProfile2.m_playerStats.m_stats[(PlayerStatType)1]; float num7 = 0f; float num8 = 0f; float num9 = 0f; float num10 = 0f; float num11 = 0f; float num12 = 0f; if (num > _bossKills || num2 > _enemykills) { num12 = (num - _bossKills) * ValConfig.SkillGainOnBossKills.Value; num11 = (num2 - _enemykills) * ValConfig.SkillGainOnKills.Value; Logger.LogDebug($"DeathProgression kill skill bosskill: {num12} kill: {num11}"); _bossKills = num; _enemykills = num2; } if (num3 > _piecesBuilt) { num10 = (num3 - _piecesBuilt) * ValConfig.SkillGainOnBuilding.Value; Logger.LogDebug($"DeathProgression building skill: {num10}"); _piecesBuilt = num3; } if (num4 > _treesChopped || num5 > _mineAmount) { num9 = (num4 - _treesChopped) * ValConfig.SkillGainOnResourceGathering.Value; num8 = (num5 - _mineAmount) * ValConfig.SkillGainOnResourceGathering.Value; Logger.LogDebug($"DeathProgression harvesting skill tree_harvest: {num9} mining: {num8}"); _treesChopped = num4; _mineAmount = num5; } if (num6 > _craftAndUpgrades) { num7 = (num6 - _craftAndUpgrades) * ValConfig.SkillGainOnCrafts.Value; Logger.LogDebug($"DeathProgression crafting skill crafting: {num7}"); _craftAndUpgrades = num6; } float num13 = num12 + num11 + num10 + num10 + num9 + num8 + num7; float num14 = (float)Math.Log(__instance.m_timeSinceDeath) / 5f * 0.5f; float num15 = num14 * num13; if (Deathlink.RustyAlmanacClassesLoaded) { int num16 = Mathf.RoundToInt(num15 * ValConfig.AlmanacClassesXPGainScale.Value); Logger.LogDebug($"Almanac XP Gain {num16}"); ClassesAPI.AddEXP(num16); } if (Deathlink.WackyMMOLoaded) { int num17 = Mathf.RoundToInt(num15 * ValConfig.WackyMMOXPGainScale.Value); Logger.LogDebug($"WackyMMO XP Gain {num17}"); EpicMMOSystem_API.AddExp(num17); } Logger.LogDebug($"DeathProgression skill bonus from survival (survive time: {__instance.m_timeSinceDeath}) {num14} x {num13} = {num15}"); ((Character)Player.m_localPlayer).RaiseSkill(DeathSkill, num15); } } } public static SkillType DeathSkill; private static float lastSkillIncreaseTickTime; private static float timeSinceGameStart; private static float _bossKills; private static float _enemykills; private static float _piecesBuilt; private static float _mineAmount; private static float _treesChopped; private static float _craftAndUpgrades; public static void SetupDeathSkill() { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0006: Expected O, but got Unknown //IL_0061: Unknown result type (might be due to invalid IL or missing references) //IL_0066: Unknown result type (might be due to invalid IL or missing references) //IL_0070: 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) SkillConfig val = new SkillConfig(); val.Name = LocalizationManager.Instance.TryTranslate("$death_skill"); val.Description = LocalizationManager.Instance.TryTranslate("$death_skill_description"); val.Icon = Deathlink.EmbeddedResourceBundle.LoadAsset<Sprite>("Assets/Custom/Icons/death_skill.png"); val.Identifier = "midnightsfx.deathskill"; val.IncreaseStep = 0.1f; DeathSkill = SkillManager.Instance.AddSkill(val); if (!SkillsChanges.skills_to_avoid_standard_death_penalty.Contains(DeathSkill)) { SkillsChanges.skills_to_avoid_standard_death_penalty.Add(DeathSkill); } } public static float DeathSkillCalculatePercentWithBonus(float bonus = 0f, float min = 0.01f, float max = 1f) { //IL_0018: Unknown result type (might be due to invalid IL or missing references) float num = 0f; if ((Object)(object)Player.m_localPlayer != (Object)null) { float skillFactor = ((Character)Player.m_localPlayer).GetSkillFactor(DeathSkill); num += skillFactor; } num += bonus; if (num < min) { num = min; } if (num > max) { num = max; } return num; } } public static class HarvestModifiers { [HarmonyPatch(typeof(TreeLog), "Destroy")] public static class IncreaseDropsFromTree { private static void Postfix(TreeLog __instance, HitData hitData) { //IL_002f: Unknown result type (might be due to invalid IL or missing references) //IL_0039: Unknown result type (might be due to invalid IL or missing references) //IL_0051: Unknown result type (might be due to invalid IL or missing references) if (Deathlink.pcfg().ResourceModifiers != null && Deathlink.pcfg().ResourceModifiers.Count > 0 && hitData != null && (Object)(object)Player.m_localPlayer != (Object)null && hitData.m_attacker == ((Character)Player.m_localPlayer).GetZDOID()) { IncreaseDrops(__instance.m_dropWhenDestroyed, ((Component)__instance).transform.position); } } } [HarmonyPatch(typeof(Pickable), "Drop")] public static class IncreaseDropsPickable { private static void Prefix(Pickable __instance, GameObject prefab, int offset) { //IL_008f: Unknown result type (might be due to invalid IL or missing references) //IL_0099: Unknown result type (might be due to invalid IL or missing references) //IL_009e: Unknown result type (might be due to invalid IL or missing references) //IL_00a5: Unknown result type (might be due to invalid IL or missing references) //IL_00aa: Unknown result type (might be due to invalid IL or missing references) //IL_00b5: Unknown result type (might be due to invalid IL or missing references) //IL_00ba: Unknown result type (might be due to invalid IL or missing references) //IL_00bf: Unknown result type (might be due to invalid IL or missing references) //IL_00cd: Unknown result type (might be due to invalid IL or missing references) //IL_00d3: Unknown result type (might be due to invalid IL or missing references) //IL_00d8: 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) //IL_00f5: 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_0102: Unknown result type (might be due to invalid IL or missing references) //IL_0104: Unknown result type (might be due to invalid IL or missing references) if (Deathlink.pcfg().ResourceModifiers == null || Deathlink.pcfg().ResourceModifiers.Count <= 0 || !((Object)(object)Player.m_localPlayer != (Object)null)) { return; } float num = Deathlink.pcfg().GetResouceEarlyCache(prefab.gameObject) - 1f; int num2 = 0; while (num > 0f) { float value = Random.value; Logger.LogDebug($"Checking to increase drops {value} <= {num}"); if (value <= num) { num2++; } num -= 1f; } if (num2 > 0) { Vector2 val = Random.insideUnitCircle * 0.2f; Vector3 val2 = ((Component)__instance).transform.position + Vector3.up * __instance.m_spawnOffset + new Vector3(val.x, 0.5f * (float)offset, val.y); Quaternion val3 = Quaternion.Euler(0f, (float)Random.Range(0, 360), 0f); for (int i = 0; i < num2; i++) { Object.Instantiate<GameObject>(prefab, val2, val3); } } } } [HarmonyPatch(typeof(MineRock5), "RPC_SetAreaHealth")] public static class Minerock5DestroyPatch { private static void Postfix(MineRock5 __instance, long sender, int index, float health) { //IL_0044: Unknown result type (might be due to invalid IL or missing references) if (Deathlink.pcfg().ResourceModifiers != null && Deathlink.pcfg().ResourceModifiers.Count > 0 && (Object)(object)Player.m_localPlayer != (Object)null && health <= 0f) { IncreaseDrops(__instance.m_dropItems, ((Component)__instance).gameObject.transform.position); } } } [HarmonyPatch(typeof(Destructible), "Destroy")] public static class IncreaseDropsFromDestructible { private static void Prefix(Destructible __instance, HitData hit) { //IL_002f: Unknown result type (might be due to invalid IL or missing references) //IL_0039: Unknown result type (might be due to invalid IL or missing references) if (Deathlink.pcfg().ResourceModifiers != null && Deathlink.pcfg().ResourceModifiers.Count > 0 && hit != null && (Object)(object)Player.m_localPlayer != (Object)null && hit.m_attacker == ((Character)Player.m_localPlayer).GetZDOID()) { IncreaseDestructibleDrops(__instance); } } public static void IncreaseDestructibleDrops(Destructible destructible) { //IL_0015: Unknown result type (might be due to invalid IL or missing references) //IL_001a: Unknown result type (might be due to invalid IL or missing references) //IL_003a: Unknown result type (might be due to invalid IL or missing references) if (!((Object)(object)destructible.m_spawnWhenDestroyed != (Object)null)) { Vector3 position = ((Component)destructible).transform.position; DropOnDestroyed component = ((Component)destructible).GetComponent<DropOnDestroyed>(); if (!((Object)(object)component == (Object)null) && component.m_dropWhenDestroyed != null) { IncreaseDrops(component.m_dropWhenDestroyed, position); } } } } public static void IncreaseDrops(DropTable drops, Vector3 position) { //IL_0065: Unknown result type (might be due to invalid IL or missing references) //IL_006a: Unknown result type (might be due to invalid IL or missing references) //IL_0071: Unknown result type (might be due to invalid IL or missing references) //IL_009b: Unknown result type (might be due to invalid IL or missing references) //IL_0109: Unknown result type (might be due to invalid IL or missing references) //IL_010e: Unknown result type (might be due to invalid IL or missing references) //IL_01a7: Unknown result type (might be due to invalid IL or missing references) //IL_01a8: Unknown result type (might be due to invalid IL or missing references) //IL_014f: Unknown result type (might be due to invalid IL or missing references) //IL_0150: Unknown result type (might be due to invalid IL or missing references) List<KeyValuePair<GameObject, int>> list = new List<KeyValuePair<GameObject, int>>(); List<KeyValuePair<GameObject, int>> list2 = Deathlink.pcfg().RollHarvestLoot(); if (list2.Count > 0) { list.AddRange(list2); } int num = Random.Range(drops.m_dropMin, drops.m_dropMax); int num2 = drops.m_drops.Count; if (num == 0) { num = 1; } if (num2 == 0) { num2 = 1; } int num3 = Mathf.RoundToInt((float)(num / num2)); foreach (DropData drop in drops.m_drops) { float resouceEarlyCache = Deathlink.pcfg().GetResouceEarlyCache(drop.m_item); if (resouceEarlyCache != 1f) { int num4 = Mathf.RoundToInt((float)num3 * resouceEarlyCache); if (num4 > 0) { list.Add(new KeyValuePair<GameObject, int>(drop.m_item, num4)); } } } if (list.Count <= 0) { return; } Logger.LogDebug("Deathlink drop increase."); foreach (KeyValuePair<GameObject, int> item in list) { Quaternion val = Quaternion.Euler(0f, (float)Random.Range(0, 360), 0f); int maxStackSize = item.Key.GetComponent<ItemDrop>().m_itemData.m_shared.m_maxStackSize; int num5 = item.Value; if (num5 > maxStackSize) { int num6 = num5 / maxStackSize; for (int i = 0; i < num6; i++) { Object.Instantiate<GameObject>(item.Key, position, val).GetComponent<ItemDrop>().m_itemData.m_stack = maxStackSize; Logger.LogDebug($"Dropping {maxStackSize} of {((Object)item.Key).name} to the world."); } num5 -= maxStackSize * num6; } Object.Instantiate<GameObject>(item.Key, position, val).GetComponent<ItemDrop>().m_itemData.m_stack = num5; Logger.LogDebug($"Dropping {num5} of {((Object)item.Key).name} to the world."); } } } public static class LootModifiers { [HarmonyPatch(typeof(CharacterDrop))] public static class CalculateLootByModifiers { [HarmonyPostfix] [HarmonyPatch("GenerateDropList")] private static void Postfix(List<KeyValuePair<GameObject, int>> __result, CharacterDrop __instance) { //IL_00e9: Unknown result type (might be due to invalid IL or missing references) //IL_00ee: Unknown result type (might be due to invalid IL or missing references) if (!__instance.m_character.m_localPlayerHasHit || Deathlink.pcfg().DeathLootModifiers == null || Deathlink.pcfg().DeathLootModifiers.Count == 0) { return; } List<KeyValuePair<GameObject, int>> list = new List<KeyValuePair<GameObject, int>>(); foreach (KeyValuePair<GameObject, int> item in __result) { float resouceEarlyCache = Deathlink.pcfg().GetResouceEarlyCache(((Object)item.Key).name); if (resouceEarlyCache == 1f) { list.Add(item); continue; } int num = Mathf.RoundToInt((float)item.Value * resouceEarlyCache); if (num >= 1) { list.Add(new KeyValuePair<GameObject, int>(item.Key, num)); } } List<KeyValuePair<GameObject, int>> list2 = Deathlink.pcfg().RollKillLoot(); if (list2.Count > 0) { foreach (KeyValuePair<GameObject, int> item2 in list2) { for (int i = 0; i < item2.Value; i++) { Object.Instantiate<GameObject>(item2.Key, ((Component)__instance).transform.position, Quaternion.identity); } } } __result = list; } } } public static class SkillsChanges { [HarmonyPatch(typeof(Skills), "OnDeath")] private static class OnDeath_Patch { private static bool Prefix(Skills __instance) { if (((Character)__instance.m_player).m_seman.HaveStatusEffect(SEMan.s_statusEffectSoftDeath)) { return false; } if (Deathlink.pcfg().DeathStyle.skillLossOnDeath) { float num = Mathf.Lerp(Deathlink.pcfg().DeathStyle.maxSkillLossPercentage, Deathlink.pcfg().DeathStyle.minSkillLossPercentage, DeathProgressionSkill.DeathSkillCalculatePercentWithBonus()); Logger.LogDebug($"{num}"); LowerConfigurableSkills(__instance, num); } return false; } private static void LowerConfigurableSkills(Skills skills, float factor) { //IL_001d: Unknown result type (might be due to invalid IL or missing references) //IL_0030: Unknown result type (might be due to invalid IL or missing references) foreach (KeyValuePair<SkillType, Skill> skillDatum in skills.m_skillData) { if (skills_to_avoid_standard_death_penalty.Contains(skillDatum.Key)) { Logger.LogDebug($"Skipping lowering skill {skillDatum.Key} current level: {skillDatum.Value.m_level}"); continue; } float num = skillDatum.Value.m_level * factor; Skill value = skillDatum.Value; value.m_level -= num; skillDatum.Value.m_accumulator = 0f; } if (Deathlink.RustyAlmanacClassesLoaded && ValConfig.EnableAlmanacClassesXPLossOnDeath.Value) { int level = ClassesAPI.GetLevel(); int num2 = Mathf.RoundToInt((float)level * factor * 500f * ValConfig.AlmanacClassesXPLossScale.Value) * -1; Logger.LogDebug($"Almanac (lvl {level}) XP Loss: {num2}"); ClassesAPI.AddEXP(num2); } if (Deathlink.WackyMMOLoaded && ValConfig.EnableWackyMMOXPLossOnDeath.Value) { int level2 = EpicMMOSystem_API.GetLevel(); int num3 = Mathf.RoundToInt((float)level2 * factor * 500f * ValConfig.WackyMMOXPLossScale.Value) * -1; Logger.LogDebug($"WackyMMO (lvl {level2}) XP Loss: {num3}"); EpicMMOSystem_API.AddExp(num3); } Player localPlayer = Player.m_localPlayer; if (localPlayer != null) { ((Character)localPlayer).Message((MessageType)1, "$msg_skills_lowered", 0, (Sprite)null); } } } [HarmonyPatch(typeof(Skills), "RaiseSkill")] private static class SkillRaisePatch { private static void Prefix(Skills __instance, SkillType skillType, float factor) { //IL_0005: 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) float skillBonusLazyCache = Deathlink.pcfg().GetSkillBonusLazyCache(skillType); Logger.LogDebug($"{skillType} skillGain Modified {skillBonusLazyCache}"); if (skillBonusLazyCache != 0f) { factor *= skillBonusLazyCache; } } } public static List<SkillType> skills_to_avoid_standard_death_penalty = new List<SkillType>(); } public static class OnDeathChanges { [HarmonyPatch(typeof(Player))] public static class OnDeath_Tombstone_Patch { [HarmonyTranspiler] [HarmonyPatch("OnDeath")] private static IEnumerable<CodeInstruction> ConstructorTranspiler(IEnumerable<CodeInstruction> instructions, ILGenerator generator) { //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_0008: Expected O, but got Unknown //IL_001d: Unknown result type (might be due to invalid IL or missing references) //IL_0023: Expected O, but got Unknown //IL_0046: Unknown result type (might be due to invalid IL or missing references) //IL_004c: Expected O, but got Unknown //IL_0091: Unknown result type (might be due to invalid IL or missing references) //IL_0097: Expected O, but got Unknown CodeMatcher val = new CodeMatcher(instructions, generator); val.MatchStartForward((CodeMatch[])(object)new CodeMatch[2] { new CodeMatch((OpCode?)OpCodes.Ldarg_0, (object)null, (string)null), new CodeMatch((OpCode?)OpCodes.Call, (object)AccessTools.Method(typeof(Player), "CreateTombStone", (Type[])null, (Type[])null), (string)null) }).Advance(1).InsertAndAdvance((CodeInstruction[])(object)new CodeInstruction[1] { Transpilers.EmitDelegate<Action<Player>>((Action<Player>)ModifyDeath) }) .CreateLabelOffset(out var label, 4) .InsertAndAdvance((CodeInstruction[])(object)new CodeInstruction[1] { new CodeInstruction(OpCodes.Br, (object)label) }) .ThrowIfNotMatch("Unable to patch Deathlink player death changes.", Array.Empty<CodeMatch>()); return val.Instructions(); } private static void ModifyDeath(Player __instance) { TombstoneOnDeath(__instance); FoodLossOnDeath(__instance); } public static void FoodLossOnDeath(Player instance) { if (!Deathlink.pcfg().DeathStyle.foodLossOnDeath) { return; } if (Deathlink.pcfg().DeathStyle.foodLossUsesDeathlink && instance.m_foods.Count > 0) { float num = DeathProgressionSkill.DeathSkillCalculatePercentWithBonus(); if (num >= 0.9f) { return; } if (num >= 0.6f && num < 0.9f) { instance.m_foods.Remove(instance.m_foods[0]); } else if (num > 0.3f && num < 0.6f) { instance.m_foods.Remove(instance.m_foods[0]); if (instance.m_foods.Count > 0) { instance.m_foods.Remove(instance.m_foods[0]); } } else { instance.m_foods.Clear(); } } else { instance.m_foods.Clear(); } } public static void TombstoneOnDeath(Player instance) { //IL_0366: Unknown result type (might be due to invalid IL or missing references) //IL_0376: Unknown result type (might be due to invalid IL or missing references) //IL_04b0: Unknown result type (might be due to invalid IL or missing references) //IL_04df: Unknown result type (might be due to invalid IL or missing references) //IL_04e5: Unknown result type (might be due to invalid IL or missing references) List<ItemData> allItems = ((Humanoid)instance).m_inventory.GetAllItems(); List<ItemData> list = new List<ItemData>(); List<ItemData> list2 = new List<ItemData>(); Inventory inventory = ((Humanoid)instance).m_inventory; Dictionary<DataObjects.ItemResults, List<ItemData>> dictionary = new Dictionary<DataObjects.ItemResults, List<ItemData>>(); string[] source = ValConfig.ItemsNotSkillChecked.Value.Split(new char[1] { ',' }); foreach (ItemData item in allItems) { if ((Object)(object)item.m_dropPrefab != (Object)null && source.Contains(((Object)item.m_dropPrefab).name)) { list2.Add(item); } else { list.Add(item); } } switch (Deathlink.pcfg().DeathStyle.itemLossStyle) { case DataObjects.ItemLossStyle.None: Logger.LogDebug("No items destroyed on death."); dictionary.SafeInsertOrAppend(DataObjects.ItemResults.ItemSaved, list); break; case DataObjects.ItemLossStyle.DestroyNonWeaponArmor: Logger.LogDebug("Destroying non Equipment items."); dictionary.SafeInsertOrAppend(DataObjects.ItemResults.ItemLost, list.GetNotEquipment()); dictionary.SafeInsertOrAppend(DataObjects.ItemResults.EquipmentSaved, list.GetEquipment()); foreach (ItemData item2 in list.GetNotEquipment()) { ((Humanoid)instance).m_inventory.RemoveItem(item2); } if (!Deathlink.AzuEPILoaded) { break; } Logger.LogDebug("AzuEPI| Removing non-equipment items from quickslots."); foreach (ItemData quickSlotsItem in AzuExtendedPlayerInventory.API.GetQuickSlotsItems()) { if (!quickSlotsItem.IsEquipment()) { ((Humanoid)instance).m_inventory.RemoveItem(quickSlotsItem); dictionary.SafeInsertOrAppend(DataObjects.ItemResults.ItemLost, quickSlotsItem); } else { dictionary.SafeInsertOrAppend(DataObjects.ItemResults.EquipmentSaved, quickSlotsItem); } } break; case DataObjects.ItemLossStyle.DestroyAll: Logger.LogDebug("Destroying all non skill checked items."); dictionary.SafeInsertOrAppend(DataObjects.ItemResults.ItemLost, list); foreach (ItemData item3 in list) { ((Humanoid)instance).m_inventory.RemoveItem(item3); } if (Deathlink.AzuEPILoaded) { Logger.LogDebug("AzuEPI| Destroying quickslot items."); dictionary.SafeInsertOrAppend(DataObjects.ItemResults.ItemLost, AzuExtendedPlayerInventory.API.GetQuickSlotsItems()); AzuExtendedPlayerInventory.API.GetQuickSlotsItems().ForEach(delegate(ItemData item) { ((Humanoid)instance).m_inventory.RemoveItem(item); }); } break; case DataObjects.ItemLossStyle.DeathlinkBased: Logger.LogDebug("Destroying random items based on deathlink skill"); dictionary = DetermineItemResultsByDeathlink(instance, list); dictionary[DataObjects.ItemResults.EquipmentLost].ForEach(delegate(ItemData item) { ((Humanoid)instance).m_inventory.RemoveItem(item); }); dictionary[DataObjects.ItemResults.ItemLost].ForEach(delegate(ItemData item) { ((Humanoid)instance).m_inventory.RemoveItem(item); }); break; } if (Deathlink.pcfg().DeathStyle.nonSkillCheckedItemAction == DataObjects.NonSkillCheckedItemAction.Destroy) { Logger.LogDebug("Non skill checked being destroyed."); dictionary.SafeInsertOrAppend(DataObjects.ItemResults.ItemLost, list2); } if (Deathlink.pcfg().DeathStyle.nonSkillCheckedItemAction == DataObjects.NonSkillCheckedItemAction.Save) { Logger.LogDebug("Non skill checked items being left on player."); } if ((!dictionary.ContainsKey(DataObjects.ItemResults.EquipmentSaved) || dictionary[DataObjects.ItemResults.EquipmentSaved].Count <= 0) && (!dictionary.ContainsKey(DataObjects.ItemResults.ItemSaved) || dictionary[DataObjects.ItemResults.ItemSaved].Count <= 0) && (Deathlink.pcfg().DeathStyle.nonSkillCheckedItemAction != DataObjects.NonSkillCheckedItemAction.Tombstone || list2.Count() <= 0)) { return; } Logger.LogDebug("Tombstone needed"); GameObject obj = Object.Instantiate<GameObject>(instance.m_tombstone, ((Character)instance).GetCenterPoint(), ((Component)instance).transform.rotation); Inventory inventory2 = obj.GetComponent<Container>().GetInventory(); if (Deathlink.pcfg().DeathStyle.itemSavedStyle == DataObjects.ItemSavedStyle.Tombstone) { Logger.LogDebug("Adding saved items to tombstone."); if (dictionary.ContainsKey(DataObjects.ItemResults.EquipmentSaved) && dictionary[DataObjects.ItemResults.EquipmentSaved].Count > 0) { AddItemsToTombstone(inventory2, dictionary[DataObjects.ItemResults.EquipmentSaved]); dictionary[DataObjects.ItemResults.EquipmentSaved].ForEach(delegate(ItemData item) { ((Humanoid)instance).m_inventory.RemoveItem(item); }); } if (dictionary.ContainsKey(DataObjects.ItemResults.ItemSaved) && dictionary[DataObjects.ItemResults.ItemSaved].Count > 0) { AddItemsToTombstone(inventory2, dictionary[DataObjects.ItemResults.ItemSaved]); dictionary[DataObjects.ItemResults.ItemSaved].ForEach(delegate(ItemData item) { ((Humanoid)instance).m_inventory.RemoveItem(item); }); } } if (Deathlink.pcfg().DeathStyle.nonSkillCheckedItemAction == DataObjects.NonSkillCheckedItemAction.Tombstone) { Logger.LogDebug("Adding saved non-skill checked items to tombstone."); AddItemsToTombstone(inventory2, list2); list2.ForEach(delegate(ItemData item) { ((Humanoid)instance).m_inventory.RemoveItem(item); }); } TombStone component = obj.GetComponent<TombStone>(); PlayerProfile playerProfile = Game.instance.GetPlayerProfile(); string name = playerProfile.GetName(); long playerID = playerProfile.GetPlayerID(); component.Setup(name, playerID); inventory.Changed(); if (ValConfig.ShowDeathMapMarker.Value) { Minimap.instance.AddPin(((Component)instance).transform.position, (PinType)4, $"$hud_mapday {EnvMan.instance.GetDay(ZNet.instance.GetTimeSeconds())}", true, false, 0L, default(PlatformUserID)); } } public static void AddItemsToTombstone(Inventory tombstone, List<ItemData> transferItems) { int num = Mathf.RoundToInt(Mathf.Sqrt((float)transferItems.Count())) + 1; tombstone.m_width += num; tombstone.m_height += num; foreach (ItemData transferItem in transferItems) { tombstone.m_inventory.Add(transferItem); } tombstone.Changed(); } internal static Dictionary<DataObjects.ItemResults, List<ItemData>> DetermineItemResultsByDeathlink(Player player, List<ItemData> playerItemsWithoutNonSkillCheckedItems) { float num = DeathProgressionSkill.DeathSkillCalculatePercentWithBonus(); int num2 = Mathf.RoundToInt((float)(Deathlink.pcfg().DeathStyle.maxItemsKept - Deathlink.pcfg().DeathStyle.minItemsKept) * num + (float)Deathlink.pcfg().DeathStyle.minItemsKept); int num3 = Mathf.RoundToInt((float)(Deathlink.pcfg().DeathStyle.maxEquipmentKept - Deathlink.pcfg().DeathStyle.minEquipmentKept) * num + (float)Deathlink.pcfg().DeathStyle.minEquipmentKept); int remainingsaves = num2 + num3; Dictionary<DataObjects.ItemResults, List<ItemData>> dictionary = new Dictionary<DataObjects.ItemResults, List<ItemData>> { { DataObjects.ItemResults.EquipmentSaved, new List<ItemData>() }, { DataObjects.ItemResults.EquipmentLost, new List<ItemData>() }, { DataObjects.ItemResults.ItemSaved, new List<ItemData>() }, { DataObjects.ItemResults.ItemLost, new List<ItemData>() } }; int equipment_saved_count = 0; foreach (ItemData item in Deathlink.shuffleList(playerItemsWithoutNonSkillCheckedItems.GetEquipment())) { if (remainingsaves > 0) { if (RemoveEquipmentByStyle(equipment_saved_count, num3, item, remainingsaves, out remainingsaves, out equipment_saved_count)) { Logger.LogDebug("Save: " + item.m_shared.m_name); dictionary[DataObjects.ItemResults.EquipmentSaved].Add(item); } else { Logger.LogDebug("Remove by style: " + item.m_shared.m_name); dictionary[DataObjects.ItemResults.EquipmentLost].Add(item); } } else { Logger.LogDebug("Save limit reached, removing: " + item.m_shared.m_name); dictionary[DataObjects.ItemResults.EquipmentLost].Add(item); } } if (Deathlink.AzuEPILoaded) { foreach (ItemData quickSlotsItem in AzuExtendedPlayerInventory.API.GetQuickSlotsItems()) { if (quickSlotsItem.IsEquipment() && remainingsaves > 0) { remainingsaves--; num2--; dictionary[DataObjects.ItemResults.EquipmentSaved].Add(quickSlotsItem); } else if (remainingsaves > 0) { remainingsaves--; num2--; dictionary[DataObjects.ItemResults.ItemSaved].Add(quickSlotsItem); } else { dictionary[DataObjects.ItemResults.ItemLost].Add(quickSlotsItem); } } } List<ItemData> list = Deathlink.shuffleList(playerItemsWithoutNonSkillCheckedItems.GetNotEquipment()); if (remainingsaves > 0) { foreach (ItemData item2 in list) { if (remainingsaves > 0 && num2 > 0) { Logger.LogDebug("NonEq| Saving: " + item2.m_shared.m_name); dictionary[DataObjects.ItemResults.ItemSaved].Add(item2); remainingsaves--; num2--; } else { Logger.LogDebug("NonEq| Removing: " + item2.m_shared.m_name); dictionary[DataObjects.ItemResults.ItemLost].Add(item2); } } } else { Logger.LogDebug($"NonEq| Removing: {list.Count} due to no saves remaining."); foreach (ItemData item3 in list) { dictionary[DataObjects.ItemResults.ItemLost].Add(item3); } } return dictionary; } internal static bool RemoveEquipmentByStyle(int equipment_saved, int max_equipment_savable, ItemData equipment, int numberOfItemsSavable, out int remainingsaves, out int equipment_saved_count) { equipment_saved_count = 0; remainingsaves = 0; if (numberOfItemsSavable <= 0) { return false; } if (equipment_saved >= max_equipment_savable) { Logger.LogDebug($"Max equipment retained ({max_equipment_savable}) reached, removing {((Object)equipment.m_dropPrefab).name}"); return false; } Logger.LogDebug($"Saving equipment remaining savable?({numberOfItemsSavable}) {((Object)equipment.m_dropPrefab).name}"); equipment_saved_count = equipment_saved + 1; remainingsaves = numberOfItemsSavable - 1; return true; } } } } namespace Deathlink.Common { internal static class TerminalCommands { internal class ResetPlayerDeathChoice : ConsoleCommand { public override string Name => "DL-RESET-CHOICE"; public override bool IsNetwork => true; public override string Help => "Format: [steamID|playerName] resets the deathlink choice for the target player. Accepts a platform Steam ID or a case-insensitive player name."; public override void Run(string[] args) { //IL_0045: Unknown result type (might be due to invalid IL or missing references) //IL_004a: Unknown result type (might be due to invalid IL or missing references) //IL_004b: Unknown result type (might be due to invalid IL or missing references) //IL_004c: Unknown result type (might be due to invalid IL or missing references) //IL_0051: Unknown result type (might be due to invalid IL or missing references) //IL_0062: Unknown result type (might be due to invalid IL or missing references) //IL_0063: Unknown result type (might be due to invalid IL or missing references) //IL_00cc: Unknown result type (might be due to invalid IL or missing references) //IL_00d3: Expected O, but got Unknown //IL_0101: Unknown result type (might be due to invalid IL or missing references) //IL_011b: 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) if (!SynchronizationManager.Instance.PlayerIsAdmin) { Logger.LogWarning("You are not an admin, and not allowed to run this command."); return; } if (args.Length < 1) { Logger.LogInfo("Player Steam ID or name required"); return; } string text = args[0]; bool flag = false; foreach (PlayerInfo player in ZNet.instance.GetPlayerList()) { string text2 = player.m_userInfo.m_id.m_userID.ToString(); string displayName = player.m_userInfo.m_displayName; bool flag2 = text2 == text; bool flag3 = string.Equals(displayName, text, StringComparison.OrdinalIgnoreCase); Logger.LogDebug("Checking Player " + displayName + " (platformID: " + text2 + ") against '" + text + "'"); if (flag2 || flag3) { ZPackage val = new ZPackage(); val.Write(text2); Logger.LogDebug("Requesting server reset of player saved Deathlink choice"); ValConfig.resetChoiceRPC.SendPackage(ZRoutedRpc.instance.GetServerPeerID(), val); Logger.LogDebug("Checking for " + player.m_name + " peer"); ZNetPeer peerByPlayerName = ZNet.instance.GetPeerByPlayerName(player.m_name); if (peerByPlayerName == null) { Logger.LogWarning("Player " + displayName + " found in player list but has no active peer."); break; } ValConfig.resetChoiceRPC.SendPackage(peerByPlayerName.m_uid, val); Logger.LogInfo($"Matched player {player.m_name}|{displayName} (platformID: {text2}, peerUID: {peerByPlayerName.m_uid})"); flag = true; break; } } if (!flag) { Logger.LogInfo("Player could not be found, are they online?"); } } } internal static void AddCommands() { CommandManager.Instance.AddConsoleCommand((ConsoleCommand)(object)new ResetPlayerDeathChoice()); } } public class DataObjects { public enum ItemLossStyle { None, DestroyNonWeaponArmor, DeathlinkBased, DestroyAll } public enum ItemResults { EquipmentSaved, EquipmentLost, ItemSaved, ItemLost } public enum ItemSavedStyle { OnCharacter, Tombstone } public enum ResourceGainTypes { Kills, Harvesting } public enum NonSkillCheckedItemAction { Destroy, Tombstone, Save } public class DeathProgressionDetails { public bool foodLossOnDeath = true; public bool foodLossUsesDeathlink = true; public int minItemsKept; public int maxItemsKept; public int minEquipmentKept; public int maxEquipmentKept; public bool skillLossOnDeath = true; public float maxSkillLossPercentage; public float minSkillLossPercentage; public ItemLossStyle itemLossStyle; public ItemSavedStyle itemSavedStyle; public NonSkillCheckedItemAction nonSkillCheckedItemAction = NonSkillCheckedItemAction.Tombstone; } public class DeathResourceModifier { public bool skillInfluence { get; set; } = true; public List<string> prefabs { get; set; } public float bonusModifer { get; set; } public List<ResourceGainTypes> bonusActions { get; set; } } public class DeathSkillModifier { public bool skillInfluence { get; set; } = true; public SkillType skill { get; set; } public float bonusModifer { get; set; } } public class DeathLootModifier { private bool skillInfluence { get; set; } = true; public string prefab { get; set; } public float chance { get; set; } public int amount { get; set; } = 1; public List<ResourceGainTypes> bonusActions { get; set; } } public class DeathChoiceLevel { private Dictionary<SkillType, float> CalculatedSkillMods = new Dictionary<SkillType, float>(); private Dictionary<string, float> CalculatedResourceMods = new Dictionary<string, float>(); private bool CalculatedResourceModsCached; private Dictionary<GameObject, Tuple<float, int>> KillLootModifiers = new Dictionary<GameObject, Tuple<float, int>>(); private bool CalculatedKillLootModifiersCached; private Dictionary<GameObject, Tuple<float, int>> ResourceLootModifiers = new Dictionary<GameObject, Tuple<float, int>>(); private bool CalculatedHarvestLootModifiersCached; public string DisplayName { get; set; } public DeathProgressionDetails DeathStyle { get; set; } public float DeathSkillRate { get; set; } = 1f; public Dictionary<string, DeathResourceModifier> ResourceModifiers { get; set; } public Dictionary<string, DeathSkillModifier> SkillModifiers { get; set; } public Dictionary<string, DeathLootModifier> DeathLootModifiers { get; set; } public List<KeyValuePair<GameObject, int>> RollKillLoot() { if (!CalculatedKillLootModifiersCached) { if (DeathLootModifiers != null && DeathLootModifiers.Count > 0) { foreach (KeyValuePair<string, DeathLootModifier> deathLootModifier in DeathLootModifiers) { if (deathLootModifier.Value.bonusActions.Contains(ResourceGainTypes.Kills)) { GameObject prefab = PrefabManager.Instance.GetPrefab(deathLootModifier.Value.prefab); if ((Object)(object)prefab == (Object)null) { Logger.LogWarning("Could not find prefab " + deathLootModifier.Value.prefab + " while building kill loot table, it will be skipped."); } else { KillLootModifiers.Add(prefab, new Tuple<float, int>(deathLootModifier.Value.chance, deathLootModifier.Value.amount)); } } } } CalculatedKillLootModifiersCached = true; } List<KeyValuePair<GameObject, int>> list = new List<KeyValuePair<GameObject, int>>(); foreach (KeyValuePair<GameObject, Tuple<float, int>> killLootModifier in KillLootModifiers) { float value = Random.value; Logger.LogDebug($"Rolling chance loot for: {((Object)killLootModifier.Key.gameObject).name} {value} < {killLootModifier.Value.Item1}"); if (value < killLootModifier.Value.Item1) { list.Add(new KeyValuePair<GameObject, int>(killLootModifier.Key, killLootModifier.Value.Item2)); } } return list; } public List<KeyValuePair<GameObject, int>> RollHarvestLoot() { if (!CalculatedHarvestLootModifiersCached) { if (DeathLootModifiers != null && DeathLootModifiers.Count > 0) { foreach (KeyValuePair<string, DeathLootModifier> deathLootModifier in DeathLootModifiers) { if (deathLootModifier.Value.bonusActions.Contains(ResourceGainTypes.Harvesting)) { GameObject prefab = PrefabManager.Instance.GetPrefab(deathLootModifier.Value.prefab); if ((Object)(object)prefab == (Object)null) { Logger.LogWarning("Could not find prefab " + deathLootModifier.Value.prefab + " while building harvest loot table, it will be skipped."); } else { ResourceLootModifiers.Add(prefab, new Tuple<float, int>(deathLootModifier.Value.chance, deathLootModifier.Value.amount)); } } } } CalculatedHarvestLootModifiersCached = true; } List<KeyValuePair<GameObject, int>> list = new List<KeyValuePair<GameObject, int>>(); foreach (KeyValuePair<GameObject, Tuple<float, int>> resourceLootModifier in ResourceLootModifiers) { if (Random.value < resourceLootModifier.Value.Item1) { list.Add(new KeyValuePair<GameObject, int>(resourceLootModifier.Key, resourceLootModifier.Value.Item2)); } } return list; } public float GetResouceEarlyCache(string prefab) { if (!CalculatedResourceModsCached) { Logger.LogDebug("Building cache entry for " + prefab); if (ResourceModifiers != null) { foreach (KeyValuePair<string, DeathResourceModifier> resourceModifier in ResourceModifiers) { if (resourceModifier.Value.prefabs == null) { continue; } foreach (string prefab2 in resourceModifier.Value.prefabs) { Logger.LogDebug($"Building cache entry for {prefab2} - {resourceModifier.Value.bonusModifer}"); CalculatedResourceMods.Add(prefab2, resourceModifier.Value.bonusModifer); } } } CalculatedResourceModsCached = true; } if (CalculatedResourceMods.ContainsKey(prefab)) { return CalculatedResourceMods[prefab]; } return 1f; } public float GetResouceEarlyCache(GameObject prefab) { if ((Object)(object)prefab == (Object)null) { return 1f; } return GetResouceEarlyCache(((Object)prefab).name); } public float GetSkillBonusLazyCache(SkillType skilltype) { //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_0094: Unknown result type (might be due to invalid IL or missing references) //IL_004b: Unknown result type (might be due to invalid IL or missing references) //IL_0055: Invalid comparison between Unknown and I4 //IL_005e: Unknown result type (might be due to invalid IL or missing references) //IL_0063: Unknown result type (might be due to invalid IL or missing references) if (CalculatedSkillMod