Decompiled source of Runeforge v0.8.12
BepInEx/plugins/EpicLoot.dll
Decompiled 3 weeks 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.Globalization; 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; using System.Security.Permissions; using System.Text; using System.Text.RegularExpressions; using System.Threading; using BepInEx; using BepInEx.Bootstrap; using BepInEx.Configuration; using BepInEx.Logging; using Common; using EpicLoot.Abilities; using EpicLoot.Adventure; using EpicLoot.Adventure.Feature; using EpicLoot.Config; using EpicLoot.Crafting; using EpicLoot.CraftingV2; using EpicLoot.Data; using EpicLoot.GatedItemType; using EpicLoot.General; using EpicLoot.LegendarySystem; using EpicLoot.LootBeams; using EpicLoot.MagicItemEffects; using EpicLoot.Patching; using EpicLoot.src.GamePatches; using EpicLoot.src.Loot; using EpicLoot.src.Magic; using EpicLoot.src.integrations; using EpicLoot_UnityLib; using HarmonyLib; using JetBrains.Annotations; using Jotunn; using Jotunn.Configs; using Jotunn.Entities; using Jotunn.Managers; using Jotunn.Utils; using Microsoft.CodeAnalysis; using Newtonsoft.Json; using Newtonsoft.Json.Linq; using Splatform; using TMPro; using UnityEngine; using UnityEngine.EventSystems; using UnityEngine.Events; using UnityEngine.UI; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: AssemblyTitle("EpicLoot")] [assembly: AssemblyDescription("")] [assembly: AssemblyConfiguration("")] [assembly: AssemblyCompany("Randy Knapp Mods")] [assembly: AssemblyProduct("EpicLoot")] [assembly: AssemblyCopyright("Copyright © Randy Knapp 2023")] [assembly: AssemblyTrademark("")] [assembly: ComVisible(false)] [assembly: Guid("963cf4f8-ba02-49fc-8884-97e781e6bc18")] [assembly: AssemblyFileVersion("0.11.0")] [assembly: TargetFramework(".NETFramework,Version=v4.8.1", FrameworkDisplayName = ".NET Framework 4.8.1")] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("0.11.0.0")] [module: UnverifiableCode] [module: RefSafetyRules(11)] namespace Microsoft.CodeAnalysis { [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] internal sealed class EmbeddedAttribute : Attribute { } } namespace System.Runtime.CompilerServices { [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] [AttributeUsage(AttributeTargets.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; } } [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] [AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)] internal sealed class RefSafetyRulesAttribute : Attribute { public readonly int Version; public RefSafetyRulesAttribute(int P_0) { Version = P_0; } } } public static class PlayerExtensions { public static ZDO GetZDO(this Player player) { return ((Character)player).m_nview.GetZDO(); } } namespace Common { public class ConfigPositionedElement : MonoBehaviour { public ConfigEntry<TextAnchor> AnchorConfig; public ConfigEntry<Vector2> PositionConfig; protected RectTransform _rt; protected TextAnchor _currentAnchor; public virtual void Awake() { //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_0011: Expected O, but got Unknown _rt = (RectTransform)((Component)this).transform; EnsureCorrectPosition(); } public virtual void Update() { EnsureCorrectPosition(); } public virtual void EnsureCorrectPosition() { //IL_0011: Unknown result type (might be due to invalid IL or missing references) //IL_001c: Unknown result type (might be due to invalid IL or missing references) //IL_0048: Unknown result type (might be due to invalid IL or missing references) //IL_004d: Unknown result type (might be due to invalid IL or missing references) //IL_0053: Unknown result type (might be due to invalid IL or missing references) //IL_0058: Unknown result type (might be due to invalid IL or missing references) //IL_0059: Unknown result type (might be due to invalid IL or missing references) //IL_0083: Expected I4, but got Unknown //IL_0029: Unknown result type (might be due to invalid IL or missing references) //IL_0034: Unknown result type (might be due to invalid IL or missing references) //IL_00ab: Unknown result type (might be due to invalid IL or missing references) //IL_00b1: Unknown result type (might be due to invalid IL or missing references) //IL_00b2: Unknown result type (might be due to invalid IL or missing references) //IL_00b3: Unknown result type (might be due to invalid IL or missing references) //IL_00b9: Unknown result type (might be due to invalid IL or missing references) //IL_00e7: Unknown result type (might be due to invalid IL or missing references) //IL_00ed: 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) //IL_00ef: 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_0123: Unknown result type (might be due to invalid IL or missing references) //IL_0129: Unknown result type (might be due to invalid IL or missing references) //IL_012a: Unknown result type (might be due to invalid IL or missing references) //IL_012b: Unknown result type (might be due to invalid IL or missing references) //IL_0131: Unknown result type (might be due to invalid IL or missing references) //IL_015f: Unknown result type (might be due to invalid IL or missing references) //IL_0165: Unknown result type (might be due to invalid IL or missing references) //IL_0166: Unknown result type (might be due to invalid IL or missing references) //IL_0167: Unknown result type (might be due to invalid IL or missing references) //IL_016d: Unknown result type (might be due to invalid IL or missing references) //IL_019b: Unknown result type (might be due to invalid IL or missing references) //IL_01a1: Unknown result type (might be due to invalid IL or missing references) //IL_01a2: Unknown result type (might be due to invalid IL or missing references) //IL_01a3: Unknown result type (might be due to invalid IL or missing references) //IL_01a9: 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_01dd: Unknown result type (might be due to invalid IL or missing references) //IL_01de: Unknown result type (might be due to invalid IL or missing references) //IL_01df: Unknown result type (might be due to invalid IL or missing references) //IL_01e5: Unknown result type (might be due to invalid IL or missing references) //IL_0213: Unknown result type (might be due to invalid IL or missing references) //IL_0219: Unknown result type (might be due to invalid IL or missing references) //IL_021a: Unknown result type (might be due to invalid IL or missing references) //IL_021b: Unknown result type (might be due to invalid IL or missing references) //IL_0221: Unknown result type (might be due to invalid IL or missing references) //IL_024c: Unknown result type (might be due to invalid IL or missing references) //IL_0252: Unknown result type (might be due to invalid IL or missing references) //IL_0253: Unknown result type (might be due to invalid IL or missing references) //IL_0254: Unknown result type (might be due to invalid IL or missing references) //IL_025a: Unknown result type (might be due to invalid IL or missing references) //IL_0285: Unknown result type (might be due to invalid IL or missing references) //IL_028b: Unknown result type (might be due to invalid IL or missing references) //IL_028c: Unknown result type (might be due to invalid IL or missing references) //IL_028d: Unknown result type (might be due to invalid IL or missing references) //IL_0293: Unknown result type (might be due to invalid IL or missing references) //IL_02a5: Unknown result type (might be due to invalid IL or missing references) if (AnchorConfig != null && PositionConfig != null && (_currentAnchor != AnchorConfig.Value || !(_rt.anchoredPosition == PositionConfig.Value))) { _currentAnchor = AnchorConfig.Value; TextAnchor currentAnchor = _currentAnchor; Vector2 val = default(Vector2); switch ((int)currentAnchor) { case 0: { RectTransform rt25 = _rt; RectTransform rt26 = _rt; RectTransform rt27 = _rt; ((Vector2)(ref val))..ctor(0f, 1f); rt27.anchorMax = val; Vector2 pivot = (rt26.anchorMin = val); rt25.pivot = pivot; break; } case 1: { RectTransform rt22 = _rt; RectTransform rt23 = _rt; RectTransform rt24 = _rt; ((Vector2)(ref val))..ctor(0.5f, 1f); rt24.anchorMax = val; Vector2 pivot = (rt23.anchorMin = val); rt22.pivot = pivot; break; } case 2: { RectTransform rt19 = _rt; RectTransform rt20 = _rt; RectTransform rt21 = _rt; ((Vector2)(ref val))..ctor(1f, 1f); rt21.anchorMax = val; Vector2 pivot = (rt20.anchorMin = val); rt19.pivot = pivot; break; } case 3: { RectTransform rt16 = _rt; RectTransform rt17 = _rt; RectTransform rt18 = _rt; ((Vector2)(ref val))..ctor(0f, 0.5f); rt18.anchorMax = val; Vector2 pivot = (rt17.anchorMin = val); rt16.pivot = pivot; break; } case 4: { RectTransform rt13 = _rt; RectTransform rt14 = _rt; RectTransform rt15 = _rt; ((Vector2)(ref val))..ctor(0.5f, 0.5f); rt15.anchorMax = val; Vector2 pivot = (rt14.anchorMin = val); rt13.pivot = pivot; break; } case 5: { RectTransform rt10 = _rt; RectTransform rt11 = _rt; RectTransform rt12 = _rt; ((Vector2)(ref val))..ctor(1f, 0.5f); rt12.anchorMax = val; Vector2 pivot = (rt11.anchorMin = val); rt10.pivot = pivot; break; } case 6: { RectTransform rt7 = _rt; RectTransform rt8 = _rt; RectTransform rt9 = _rt; ((Vector2)(ref val))..ctor(0f, 0f); rt9.anchorMax = val; Vector2 pivot = (rt8.anchorMin = val); rt7.pivot = pivot; break; } case 7: { RectTransform rt4 = _rt; RectTransform rt5 = _rt; RectTransform rt6 = _rt; ((Vector2)(ref val))..ctor(0.5f, 0f); rt6.anchorMax = val; Vector2 pivot = (rt5.anchorMin = val); rt4.pivot = pivot; break; } case 8: { RectTransform rt = _rt; RectTransform rt2 = _rt; RectTransform rt3 = _rt; ((Vector2)(ref val))..ctor(1f, 0f); rt3.anchorMax = val; Vector2 pivot = (rt2.anchorMin = val); rt.pivot = pivot; break; } } _rt.anchoredPosition = PositionConfig.Value; } } } [Serializable] public class RecipeRequirementConfig { public string item = ""; public int amount = 1; } [Serializable] public class RecipeConfig { public string name = ""; public string item = ""; public int amount = 1; public string craftingStation = ""; public int minStationLevel = 1; public bool enabled = true; public string repairStation = ""; public List<RecipeRequirementConfig> resources = new List<RecipeRequirementConfig>(); } [Serializable] public class RecipesConfig { public List<RecipeConfig> recipes = new List<RecipeConfig>(); } public static class GameObjectExtensions { public static RectTransform RectTransform(this GameObject go) { Transform transform = go.transform; return (RectTransform)(object)((transform is RectTransform) ? transform : null); } public static T RequireComponent<T>(this GameObject go) where T : Component { T component = go.GetComponent<T>(); if (!((Object)(object)component == (Object)null)) { return component; } return go.AddComponent<T>(); } } public class GotDestroyed : MonoBehaviour { public void OnDisable() { Debug.LogError((object)("I got destroyed! (" + ((Object)((Component)this).gameObject).name + ")")); Debug.Log((object)Environment.StackTrace); } } public class MultiValueDictionary<TKey, TValue> : Dictionary<TKey, List<TValue>> { public void Add(TKey key, TValue value) { if (!TryGetValue(key, out var value2)) { value2 = new List<TValue>(); Add(key, value2); } value2.Add(value); } public bool ContainsValue(TKey key, TValue value) { if (TryGetValue(key, out var value2)) { return value2.Contains(value); } return false; } public void Remove(TKey key, TValue value) { if (TryGetValue(key, out var value2)) { value2.Remove(value); if (value2.Count <= 0) { Remove(key); } } } public void Merge(MultiValueDictionary<TKey, TValue> toMergeWith) { if (toMergeWith == null) { return; } foreach (KeyValuePair<TKey, List<TValue>> item in toMergeWith) { foreach (TValue item2 in item.Value) { Add(item.Key, item2); } } } public List<TValue> GetValues(TKey key, bool returnEmptySet = false) { if (!TryGetValue(key, out var value) && returnEmptySet) { return new List<TValue>(); } return value; } } public static class PrefabCreator { public static ManualLogSource Logger; public static Dictionary<string, CraftingStation> CraftingStations; public static T RequireComponent<T>(GameObject go) where T : Component { T val = go.GetComponent<T>(); if ((Object)(object)val == (Object)null) { val = go.AddComponent<T>(); } return val; } public static void Reset() { CraftingStations = null; } private static void InitCraftingStations() { if (CraftingStations != null) { return; } CraftingStations = new Dictionary<string, CraftingStation>(); foreach (Recipe recipe in ObjectDB.instance.m_recipes) { if ((Object)(object)recipe.m_craftingStation != (Object)null && !CraftingStations.ContainsKey(((Object)recipe.m_craftingStation).name)) { CraftingStations.Add(((Object)recipe.m_craftingStation).name, recipe.m_craftingStation); } } } public static Recipe CreateRecipe(string name, string itemId, RecipeConfig recipeConfig) { //IL_0200: Unknown result type (might be due to invalid IL or missing references) //IL_0205: Unknown result type (might be due to invalid IL or missing references) //IL_0212: Unknown result type (might be due to invalid IL or missing references) //IL_0224: Expected O, but got Unknown InitCraftingStations(); GameObject itemPrefab = ObjectDB.instance.GetItemPrefab(itemId); if ((Object)(object)itemPrefab == (Object)null) { ManualLogSource logger = Logger; if (logger != null) { logger.LogWarning((object)("[PrefabCreator] Could not find item prefab (" + itemId + ")")); } return null; } Recipe val = ScriptableObject.CreateInstance<Recipe>(); ((Object)val).name = name; val.m_amount = recipeConfig.amount; val.m_minStationLevel = recipeConfig.minStationLevel; val.m_item = itemPrefab.GetComponent<ItemDrop>(); val.m_enabled = recipeConfig.enabled; if (!string.IsNullOrEmpty(recipeConfig.craftingStation)) { if (!CraftingStations.ContainsKey(recipeConfig.craftingStation)) { ManualLogSource logger2 = Logger; if (logger2 != null) { logger2.LogWarning((object)("[PrefabCreator] Could not find crafting station (" + itemId + "): " + recipeConfig.craftingStation)); } string text = string.Join(", ", CraftingStations.Keys); ManualLogSource logger3 = Logger; if (logger3 != null) { logger3.LogInfo((object)("[PrefabCreator] Available Stations: " + text)); } } else { val.m_craftingStation = CraftingStations[recipeConfig.craftingStation]; } } if (!string.IsNullOrEmpty(recipeConfig.repairStation)) { if (!CraftingStations.ContainsKey(recipeConfig.repairStation)) { ManualLogSource logger4 = Logger; if (logger4 != null) { logger4.LogWarning((object)("[PrefabCreator] Could not find repair station (" + itemId + "): " + recipeConfig.repairStation)); } string text2 = string.Join(", ", CraftingStations.Keys); ManualLogSource logger5 = Logger; if (logger5 != null) { logger5.LogInfo((object)("[PrefabCreator] Available Stations: " + text2)); } } else { val.m_repairStation = CraftingStations[recipeConfig.repairStation]; } } List<Requirement> list = new List<Requirement>(); foreach (RecipeRequirementConfig resource in recipeConfig.resources) { GameObject itemPrefab2 = ObjectDB.instance.GetItemPrefab(resource.item); if ((Object)(object)itemPrefab2 == (Object)null) { ManualLogSource logger6 = Logger; if (logger6 != null) { logger6.LogError((object)("[PrefabCreator] Could not find requirement item (" + itemId + "): " + resource.item)); } } else { list.Add(new Requirement { m_amount = resource.amount, m_resItem = itemPrefab2.GetComponent<ItemDrop>() }); } } val.m_resources = list.ToArray(); return val; } public static Recipe AddNewRecipe(string name, string itemId, RecipeConfig recipeConfig) { Recipe val = CreateRecipe(name, itemId, recipeConfig); if ((Object)(object)val == (Object)null) { ManualLogSource logger = Logger; if (logger != null) { logger.LogError((object)("[PrefabCreator] Failed to create recipe (" + name + ")")); } return null; } return AddNewRecipe(val); } public static Recipe AddNewRecipe(Recipe recipe) { int num = ObjectDB.instance.m_recipes.RemoveAll((Recipe x) => ((Object)x).name == ((Object)recipe).name); if (num > 0) { ManualLogSource logger = Logger; if (logger != null) { logger.LogInfo((object)$"[PrefabCreator] Removed recipe ({((Object)recipe).name}): {num}"); } } ObjectDB.instance.m_recipes.Add(recipe); ManualLogSource logger2 = Logger; if (logger2 != null) { logger2.LogInfo((object)("[PrefabCreator] Added recipe: " + ((Object)recipe).name)); } return recipe; } } [Serializable] public struct SerializableVector3 { public float x; public float y; public float z; public SerializableVector3(float x, float y, float z) { this.x = x; this.y = y; this.z = z; } public void ToPackage(ZPackage pkg) { pkg.Write(x); pkg.Write(y); pkg.Write(z); } public static SerializableVector3 FromPackage(ZPackage pkg) { SerializableVector3 result = default(SerializableVector3); result.x = pkg.ReadSingle(); result.y = pkg.ReadSingle(); result.z = pkg.ReadSingle(); return result; } public override string ToString() { return $"[{x}, {y}, {z}]"; } public static implicit operator Vector3(SerializableVector3 s) { //IL_0012: Unknown result type (might be due to invalid IL or missing references) return new Vector3(s.x, s.y, s.z); } public static implicit operator SerializableVector3(Vector3 v) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_000c: Unknown result type (might be due to invalid IL or missing references) return new SerializableVector3(v.x, v.y, v.z); } public static SerializableVector3 operator +(SerializableVector3 a, SerializableVector3 b) { return new SerializableVector3(a.x + b.x, a.y + b.y, a.z + b.z); } public static SerializableVector3 operator -(SerializableVector3 a, SerializableVector3 b) { return new SerializableVector3(a.x - b.x, a.y - b.y, a.z - b.z); } public static SerializableVector3 operator -(SerializableVector3 a) { return new SerializableVector3(0f - a.x, 0f - a.y, 0f - a.z); } public static SerializableVector3 operator *(SerializableVector3 a, float m) { return new SerializableVector3(a.x * m, a.y * m, a.z * m); } public static SerializableVector3 operator *(float m, SerializableVector3 a) { return new SerializableVector3(a.x * m, a.y * m, a.z * m); } public static SerializableVector3 operator /(SerializableVector3 a, float d) { return new SerializableVector3(a.x / d, a.y / d, a.z / d); } } public static class Utils { public static void PrintObject(object o) { if (o == null) { Debug.Log((object)"null"); } else { Debug.Log((object)(o?.ToString() + ":\n" + GetObjectString(o, " "))); } } public static string GetObjectString(object obj, string indent) { string text = ""; foreach (FieldInfo item in from f in obj.GetType().GetFields() where f.IsPublic select f) { object value = item.GetValue(obj); string text2 = ((value == null) ? "null" : value.ToString()); text = text + "\n" + indent + item.Name + ": " + text2; } return text; } public static string RemoveBetween(string s, string from, string to) { int num = 0; while (num >= 0) { num = s.IndexOf(from, StringComparison.InvariantCulture); if (num < 0) { break; } int num2 = s.IndexOf(to, num, StringComparison.InvariantCulture); if (num2 < 0) { break; } s = s.Remove(num, num2 - num + to.Length); } return s; } public static void CopyFields(object originalObject, object cloneObject, Type typeToReflect, BindingFlags bindingFlags = BindingFlags.Instance | BindingFlags.Public) { FieldInfo[] fields = typeToReflect.GetFields(bindingFlags); foreach (FieldInfo obj in fields) { object value = obj.GetValue(originalObject); obj.SetValue(cloneObject, value); } } public static bool IsServer() { //IL_0018: Unknown result type (might be due to invalid IL or missing references) //IL_001e: Invalid comparison between Unknown and I4 if (!ZNet.instance.IsServer() && !ZNet.instance.IsDedicated()) { return (int)SystemInfo.graphicsDeviceType == 4; } return true; } } public static class ArrayUtils { public static bool IsNullOrEmpty<T>(T[] a) { if (a != null) { return a.Length == 0; } return true; } public static T[] Copy<T>(T[] other) { return other?.ToArray(); } } public static class ListExtensions { public static bool TryFind<T>(this List<T> list, Predicate<T> predicate, out T result) { int num = list.FindIndex(predicate); if (num != -1) { result = list[num]; return true; } result = default(T); return false; } } } namespace EpicLoot { public static class API { private enum SecretStashType { Materials, RandomItems, OtherItems, Gamble, Sale } private static class RuntimeRegistry { private static readonly Dictionary<string, object> registry = new Dictionary<string, object>(); private static int counter; public static string Register(object obj) { string name = obj.GetType().Name; string text = $"{name}_obj_{++counter}"; registry[text] = obj; return text; } public static bool TryGetValue<T>(string key, out T value) where T : class { if (registry.TryGetValue(key, out object value2) && value2 is T val) { value = val; return true; } value = null; return false; } [PublicAPI] public static int GetCount() { return counter; } [PublicAPI] public static List<string> GetRegisteredKeys() { return registry.Keys.ToList(); } } private class AbilityProxyDefinition { public readonly AbilityDefinition Ability; public readonly Dictionary<string, Delegate> Delegates; public AbilityProxyDefinition(AbilityDefinition ability, Dictionary<string, Delegate> delegates) { Ability = ability; Delegates = delegates; } } public class AbilityProxy : Ability { public Dictionary<string, Delegate> _callbacks = new Dictionary<string, Delegate>(); private T? GetCallback<T>(string name) where T : Delegate { if (_callbacks.TryGetValue(name, out Delegate value) && value is T result) { return result; } return null; } public override void Initialize(AbilityDefinition abilityDef, Player player) { base.Initialize(abilityDef, player); GetCallback<Action<Player, string, float>>("Initialize")?.Invoke(player, abilityDef.ID, abilityDef.Cooldown); } public override void OnUpdate() { Action callback = GetCallback<Action>("OnUpdate"); if (callback == null) { base.OnUpdate(); } else { callback(); } } protected override bool ShouldTrigger() { return GetCallback<Func<bool>>("ShouldTrigger")?.Invoke() ?? base.ShouldTrigger(); } public override bool IsOnCooldown() { return GetCallback<Func<bool>>("IsOnCooldown")?.Invoke() ?? base.IsOnCooldown(); } public override float TimeUntilCooldownEnds() { return GetCallback<Func<float>>("TimeUntilCooldownEnds")?.Invoke() ?? base.TimeUntilCooldownEnds(); } public override float PercentCooldownComplete() { return GetCallback<Func<float>>("PercentCooldownComplete")?.Invoke() ?? base.PercentCooldownComplete(); } public override bool CanActivate() { return GetCallback<Func<bool>>("CanActivate")?.Invoke() ?? base.CanActivate(); } public override void TryActivate() { Action callback = GetCallback<Action>("TryActivate"); if (callback == null) { base.TryActivate(); } else { callback(); } } protected override void Activate() { Action callback = GetCallback<Action>("Activate"); if (callback == null) { base.Activate(); } else { callback(); } } protected override void ActivateCustomAction() { Action callback = GetCallback<Action>("ActivateCustomAction"); if (callback == null) { base.ActivateCustomAction(); } else { callback(); } } protected override void ActivateStatusEffectAction() { Action callback = GetCallback<Action>("ActivateStatusEffectAction"); if (callback == null) { base.ActivateStatusEffectAction(); } else { callback(); } } protected override bool HasCooldown() { return GetCallback<Func<bool>>("HasCooldown")?.Invoke() ?? base.HasCooldown(); } protected override void SetCooldownEndTime(float cooldownEndTime) { Action<float> callback = GetCallback<Action<float>>("SetCooldownEndTime"); if (callback == null) { base.SetCooldownEndTime(cooldownEndTime); } else { callback(cooldownEndTime); } } public override float GetCooldownEndTime() { return GetCallback<Func<float>>("GetCooldownEndTime")?.Invoke() ?? base.GetCooldownEndTime(); } } private static bool ShowLogs; private static readonly Dictionary<string, MagicItemEffectDefinition> ExternalMagicItemEffectDefinitions; private static readonly Dictionary<string, AbilityDefinition> ExternalAbilities; private static readonly Dictionary<ItemRarity, List<LegendaryInfo>> ExternalLegendaryItems; private static readonly Dictionary<ItemRarity, List<LegendarySetInfo>> ExternalLegendarySets; private static readonly Dictionary<string, Object> ExternalAssets; private static readonly List<MaterialConversion> ExternalMaterialConversions; private static readonly List<RecipeConfig> ExternalRecipes; private static readonly List<DisenchantProductsConfig> ExternalSacrifices; private static readonly List<BountyTargetConfig> ExternalBountyTargets; private static readonly Dictionary<SecretStashType, List<SecretStashItemConfig>> ExternalSecretStashItems; private static readonly List<TreasureMapBiomeInfoConfig> ExternalTreasureMaps; private static readonly Dictionary<string, Dictionary<string, Delegate>> AbilityProxies; private static event Action<string>? OnReload; private static event Action<string>? OnError; private static event Action<string>? OnDebug; static API() { ShowLogs = false; ExternalMagicItemEffectDefinitions = new Dictionary<string, MagicItemEffectDefinition>(); ExternalAbilities = new Dictionary<string, AbilityDefinition>(); ExternalLegendaryItems = new Dictionary<ItemRarity, List<LegendaryInfo>>(); ExternalLegendarySets = new Dictionary<ItemRarity, List<LegendarySetInfo>>(); ExternalAssets = new Dictionary<string, Object>(); ExternalMaterialConversions = new List<MaterialConversion>(); ExternalRecipes = new List<RecipeConfig>(); ExternalSacrifices = new List<DisenchantProductsConfig>(); ExternalBountyTargets = new List<BountyTargetConfig>(); ExternalSecretStashItems = new Dictionary<SecretStashType, List<SecretStashItemConfig>>(); ExternalTreasureMaps = new List<TreasureMapBiomeInfoConfig>(); AbilityProxies = new Dictionary<string, Dictionary<string, Delegate>>(); MagicItemEffectDefinitions.OnSetupMagicItemEffectDefinitions += ReloadExternalMagicEffects; UniqueLegendaryHelper.OnSetupLegendaryItemConfig += ReloadExternalLegendary; AbilityDefinitions.OnSetupAbilityDefinitions += ReloadExternalAbilities; MaterialConversions.OnSetupMaterialConversions += ReloadExternalMaterialConversions; RecipesHelper.OnSetupRecipeConfig += ReloadExternalRecipes; EnchantCostsHelper.OnSetupEnchantingCosts += ReloadExternalSacrifices; AdventureDataManager.OnSetupAdventureData += ReloadExternalAdventureData; OnReload += delegate(string message) { if (ShowLogs) { EpicLoot.Log(message); } }; OnError += delegate(string message) { if (ShowLogs) { EpicLoot.LogWarning(message); } }; OnDebug += delegate(string message) { if (ShowLogs) { EpicLoot.LogWarningForce(message); } }; } private static void ReloadExternalAdventureData() { ReloadExternalBounties(); ReloadExternalSecretStashItems(); ReloadExternalTreasures(); } private static void ReloadExternalSecretStashItems() { foreach (KeyValuePair<SecretStashType, List<SecretStashItemConfig>> externalSecretStashItem in ExternalSecretStashItems) { switch (externalSecretStashItem.Key) { case SecretStashType.Materials: AdventureDataManager.Config.SecretStash.Materials.AddRange(externalSecretStashItem.Value); break; case SecretStashType.OtherItems: AdventureDataManager.Config.SecretStash.OtherItems.AddRange(externalSecretStashItem.Value); break; case SecretStashType.RandomItems: AdventureDataManager.Config.SecretStash.RandomItems.AddRange(externalSecretStashItem.Value); break; case SecretStashType.Gamble: AdventureDataManager.Config.Gamble.GambleCosts.AddRange(externalSecretStashItem.Value); break; case SecretStashType.Sale: AdventureDataManager.Config.TreasureMap.SaleItems.AddRange(externalSecretStashItem.Value); break; } } } private static void ReloadExternalTreasures() { foreach (TreasureMapBiomeInfoConfig externalTreasureMap in ExternalTreasureMaps) { AdventureDataManager.Config.TreasureMap.BiomeInfo.Add(externalTreasureMap); } API.OnReload?.Invoke("Reloaded external treasures"); } private static void ReloadExternalBounties() { AdventureDataManager.Config.Bounties.Targets.AddRange(ExternalBountyTargets); API.OnReload?.Invoke("Reloaded external bounties"); } private static void ReloadExternalSacrifices() { EnchantCostsHelper.Config.DisenchantProducts.AddRange(ExternalSacrifices); API.OnReload?.Invoke("Reloaded external sacrifices"); } private static void ReloadExternalRecipes() { RecipesHelper.Config.recipes.RemoveAll(ExternalRecipes); RecipesHelper.Config.recipes.AddRange(ExternalRecipes); API.OnReload?.Invoke("Reloaded external recipes"); } private static void ReloadExternalMaterialConversions() { foreach (MaterialConversion externalMaterialConversion in ExternalMaterialConversions) { MaterialConversions.Config.MaterialConversions.Add(externalMaterialConversion); } API.OnReload?.Invoke("Reloaded external material conversions"); } private static void ReloadExternalMagicEffects() { foreach (MagicItemEffectDefinition value in ExternalMagicItemEffectDefinitions.Values) { MagicItemEffectDefinitions.Add(value); } API.OnReload?.Invoke("Reloaded external magic effects"); } private static void ReloadExternalAbilities() { foreach (KeyValuePair<string, AbilityDefinition> externalAbility in ExternalAbilities) { AbilityDefinitions.Config.Abilities.Add(externalAbility.Value); } API.OnReload?.Invoke("Reloaded external abilities"); } private static void ReloadExternalLegendary() { foreach (KeyValuePair<ItemRarity, List<LegendaryInfo>> externalLegendaryItem in ExternalLegendaryItems) { switch (externalLegendaryItem.Key) { case ItemRarity.Legendary: UniqueLegendaryHelper.Config.LegendaryItems.AddRange(externalLegendaryItem.Value); break; case ItemRarity.Mythic: UniqueLegendaryHelper.Config.MythicItems.AddRange(externalLegendaryItem.Value); break; } } foreach (KeyValuePair<ItemRarity, List<LegendarySetInfo>> externalLegendarySet in ExternalLegendarySets) { switch (externalLegendarySet.Key) { case ItemRarity.Legendary: UniqueLegendaryHelper.Config.LegendarySets.AddRange(externalLegendarySet.Value); break; case ItemRarity.Mythic: UniqueLegendaryHelper.Config.MythicSets.AddRange(externalLegendarySet.Value); break; } } API.OnReload?.Invoke("Reloaded external legendary abilities"); } public static void ReloadExternalAssets() { foreach (KeyValuePair<string, Object> externalAsset in ExternalAssets) { EpicLoot._assetCache[externalAsset.Key] = externalAsset.Value; } API.OnReload?.Invoke("Reloaded external assets"); } [PublicAPI] public static string? AddTreasureMap(string json) { try { TreasureMapBiomeInfoConfig treasureMapBiomeInfoConfig = JsonConvert.DeserializeObject<TreasureMapBiomeInfoConfig>(json); if (treasureMapBiomeInfoConfig == null) { return null; } ExternalTreasureMaps.Add(treasureMapBiomeInfoConfig); AdventureDataManager.Config.TreasureMap.BiomeInfo.Add(treasureMapBiomeInfoConfig); return RuntimeRegistry.Register(treasureMapBiomeInfoConfig); } catch { API.OnError?.Invoke("Failed to parse treasure map from external plugin"); return null; } } [PublicAPI] public static bool UpdateTreasureMap(string key, string json) { if (!RuntimeRegistry.TryGetValue<TreasureMapBiomeInfoConfig>(key, out var value)) { return false; } try { TreasureMapBiomeInfoConfig source = JsonConvert.DeserializeObject<TreasureMapBiomeInfoConfig>(json); value.CopyFieldsFrom(source); return true; } catch { API.OnError?.Invoke("Failed to parse treasure map from external plugin"); return false; } } [PublicAPI] public static string? AddSecretStashItem(string type, string json) { try { if (!Enum.TryParse<SecretStashType>(type, ignoreCase: true, out var result)) { return null; } SecretStashItemConfig secretStashItemConfig = JsonConvert.DeserializeObject<SecretStashItemConfig>(json); if (secretStashItemConfig == null) { return null; } ExternalSecretStashItems.AddOrSet(result, secretStashItemConfig); switch (result) { case SecretStashType.Materials: AdventureDataManager.Config.SecretStash.Materials.Add(secretStashItemConfig); break; case SecretStashType.OtherItems: AdventureDataManager.Config.SecretStash.OtherItems.Add(secretStashItemConfig); break; case SecretStashType.RandomItems: AdventureDataManager.Config.SecretStash.RandomItems.Add(secretStashItemConfig); break; case SecretStashType.Gamble: AdventureDataManager.Config.Gamble.GambleCosts.Add(secretStashItemConfig); break; case SecretStashType.Sale: AdventureDataManager.Config.TreasureMap.SaleItems.Add(secretStashItemConfig); break; } return RuntimeRegistry.Register(secretStashItemConfig); } catch { API.OnError?.Invoke("Failed to parse secret stash from external plugin"); return null; } } [PublicAPI] public static bool UpdateSecretStashItem(string key, string json) { if (!RuntimeRegistry.TryGetValue<SecretStashItemConfig>(key, out var value)) { return false; } SecretStashItemConfig secretStashItemConfig = JsonConvert.DeserializeObject<SecretStashItemConfig>(json); if (secretStashItemConfig == null) { return false; } value.CopyFieldsFrom(secretStashItemConfig); return true; } [PublicAPI] public static string? AddMagicEffect(string json) { try { MagicItemEffectDefinition magicItemEffectDefinition = JsonConvert.DeserializeObject<MagicItemEffectDefinition>(json); if (magicItemEffectDefinition == null) { return null; } MagicItemEffectDefinitions.Add(magicItemEffectDefinition); ExternalMagicItemEffectDefinitions[magicItemEffectDefinition.Type] = magicItemEffectDefinition; return RuntimeRegistry.Register(magicItemEffectDefinition); } catch { API.OnError?.Invoke("Failed to parse magic effect from external plugin"); return null; } } [PublicAPI] public static bool UpdateMagicEffect(string key, string json) { if (!RuntimeRegistry.TryGetValue<MagicItemEffectDefinition>(key, out var value)) { return false; } MagicItemEffectDefinition magicItemEffectDefinition = JsonConvert.DeserializeObject<MagicItemEffectDefinition>(json); if (magicItemEffectDefinition == null) { return false; } value.CopyFieldsFrom(magicItemEffectDefinition); return true; } [PublicAPI] public static bool HasLegendaryItem(Player player, string legendaryItemID) { foreach (ItemData item in player.GetEquipment()) { if (item.IsMagic(out var magicItem) && magicItem.LegendaryID == legendaryItemID) { return true; } } return false; } [PublicAPI] public static bool HasLegendarySet(Player player, string legendarySetID, ref int count) { if (!UniqueLegendaryHelper.TryGetLegendarySetInfo(legendarySetID, out var legendarySetInfo, out var _)) { return false; } count = player.GetEquippedSetPieces(legendarySetID).Count; return count >= legendarySetInfo.LegendaryIDs.Count; } [PublicAPI] public static string GetMagicItemEffectDefinition(string type) { if (!MagicItemEffectDefinitions.AllDefinitions.TryGetValue(type, out var value)) { return ""; } return JsonConvert.SerializeObject((object)value); } [PublicAPI] public static float GetTotalActiveMagicEffectValue(Player? player, ItemData? item, string effectType, float scale) { return MagicEffectsHelper.GetTotalActiveMagicEffectValue(player, item, effectType, scale); } [PublicAPI] public static float GetTotalActiveMagicEffectValueForWeapon(Player? player, ItemData? item, string effectType, float scale) { return MagicEffectsHelper.GetTotalActiveMagicEffectValueForWeapon(player, item, effectType, scale); } [PublicAPI] public static bool HasActiveMagicEffect(Player? player, string effectType, ItemData? item, ref float effectValue) { return MagicEffectsHelper.HasActiveMagicEffect(player, item, effectType, out effectValue); } [PublicAPI] public static bool HasActiveMagicEffectOnWeapon(Player player, ItemData item, string effectType, ref float effectValue) { return MagicEffectsHelper.HasActiveMagicEffectOnWeapon(player, item, effectType, out effectValue); } [PublicAPI] public static float GetTotalActiveSetEffectValue(Player player, string effectType, float scale) { return MagicEffectsHelper.GetTotalActiveSetEffectValue(player, effectType, scale); } [PublicAPI] public static List<string> GetAllActiveMagicEffects(Player player, string? effectType = null) { List<MagicItemEffect> allActiveMagicEffects = player.GetAllActiveMagicEffects(effectType); List<string> list = new List<string>(); foreach (MagicItemEffect item in allActiveMagicEffects) { list.Add(JsonConvert.SerializeObject((object)item)); } return list; } [PublicAPI] public static List<string> GetAllActiveSetMagicEffects(Player player, string? effectType = null) { List<MagicItemEffect> allActiveSetMagicEffects = player.GetAllActiveSetMagicEffects(effectType); List<string> list = new List<string>(); foreach (MagicItemEffect item in allActiveSetMagicEffects) { list.Add(JsonConvert.SerializeObject((object)item)); } return list; } [PublicAPI] public static float GetTotalPlayerActiveMagicEffectValue(Player? player, string effectType, float scale, ItemData? ignoreThisItem = null) { return player.GetTotalActiveMagicEffectValue(effectType, scale, ignoreThisItem); } [PublicAPI] public static bool PlayerHasActiveMagicEffect(Player? player, string effectType, ref float effectValue, float scale = 1f, ItemData? ignoreThisItem = null) { return player.HasActiveMagicEffect(effectType, out effectValue, scale, ignoreThisItem); } [PublicAPI] public static string? AddLegendaryItem(string type, string json) { try { if (!Enum.TryParse<ItemRarity>(type, ignoreCase: true, out var result)) { return null; } LegendaryInfo legendaryInfo = JsonConvert.DeserializeObject<LegendaryInfo>(json); if (legendaryInfo == null) { return null; } switch (result) { case ItemRarity.Legendary: UniqueLegendaryHelper.Config.LegendaryItems.Add(legendaryInfo); UniqueLegendaryHelper.LegendaryInfo[legendaryInfo.ID] = legendaryInfo; break; case ItemRarity.Mythic: UniqueLegendaryHelper.Config.MythicItems.Add(legendaryInfo); UniqueLegendaryHelper.MythicInfo[legendaryInfo.ID] = legendaryInfo; break; } ExternalLegendaryItems.AddOrSet(result, legendaryInfo); return RuntimeRegistry.Register(legendaryInfo); } catch { API.OnError?.Invoke("Failed to parse legendary item from external plugin."); return null; } } [PublicAPI] public static bool UpdateLegendaryItem(string key, string json) { if (!RuntimeRegistry.TryGetValue<LegendaryInfo>(key, out var value)) { return false; } LegendaryInfo legendaryInfo = JsonConvert.DeserializeObject<LegendaryInfo>(json); if (legendaryInfo == null) { return false; } value.CopyFieldsFrom(legendaryInfo); return true; } [PublicAPI] public static string? AddLegendarySet(string type, string json) { try { if (!Enum.TryParse<ItemRarity>(type, ignoreCase: true, out var result)) { return null; } LegendarySetInfo legendarySetInfo = JsonConvert.DeserializeObject<LegendarySetInfo>(json); if (legendarySetInfo == null) { return null; } switch (result) { case ItemRarity.Legendary: UniqueLegendaryHelper.LegendarySets[legendarySetInfo.ID] = legendarySetInfo; UniqueLegendaryHelper.Config.LegendarySets.Add(legendarySetInfo); foreach (string legendaryID in legendarySetInfo.LegendaryIDs) { UniqueLegendaryHelper._legendaryItemsToSetMap[legendaryID] = legendarySetInfo; } break; case ItemRarity.Mythic: UniqueLegendaryHelper.MythicSets[legendarySetInfo.ID] = legendarySetInfo; UniqueLegendaryHelper.Config.MythicSets.Add(legendarySetInfo); foreach (string legendaryID2 in legendarySetInfo.LegendaryIDs) { UniqueLegendaryHelper._mythicItemsToSetMap[legendaryID2] = legendarySetInfo; } break; } ExternalLegendarySets.AddOrSet(result, legendarySetInfo); return RuntimeRegistry.Register(legendarySetInfo); } catch { API.OnError?.Invoke("Failed to parse legendary set from external plugin."); return null; } } [PublicAPI] public static bool UpdateLegendarySet(string key, string json) { if (!RuntimeRegistry.TryGetValue<LegendarySetInfo>(key, out var value)) { return false; } LegendarySetInfo legendarySetInfo = JsonConvert.DeserializeObject<LegendarySetInfo>(json); if (legendarySetInfo == null) { return false; } value.CopyFieldsFrom(legendarySetInfo); return true; } [PublicAPI] public static string? AddAbility(string json) { try { AbilityDefinition abilityDefinition = JsonConvert.DeserializeObject<AbilityDefinition>(json); if (abilityDefinition == null) { return null; } if (AbilityDefinitions.Abilities.ContainsKey(abilityDefinition.ID)) { API.OnError?.Invoke("Duplicate entry found for Abilities: " + abilityDefinition.ID + " when adding from external plugin."); return null; } ExternalAbilities[abilityDefinition.ID] = abilityDefinition; AbilityDefinitions.Config.Abilities.Add(abilityDefinition); AbilityDefinitions.Abilities[abilityDefinition.ID] = abilityDefinition; return RuntimeRegistry.Register(abilityDefinition); } catch { API.OnError?.Invoke("Failed to parse ability definition passed in through external plugin."); return null; } } [PublicAPI] public static bool UpdateAbility(string key, string json) { if (!RuntimeRegistry.TryGetValue<AbilityDefinition>(key, out var value)) { return false; } AbilityDefinition abilityDefinition = JsonConvert.DeserializeObject<AbilityDefinition>(json); if (abilityDefinition == null) { return false; } value.CopyFieldsFrom(abilityDefinition); return true; } [PublicAPI] public static bool RegisterAsset(string name, Object asset) { if (EpicLoot._assetCache.ContainsKey(name)) { API.OnError?.Invoke("Duplicate asset: " + name); return false; } EpicLoot._assetCache[name] = asset; ExternalAssets[name] = asset; return true; } [PublicAPI] public static string? AddMaterialConversion(string json) { try { MaterialConversion materialConversion = JsonConvert.DeserializeObject<MaterialConversion>(json); if (materialConversion == null) { return null; } ExternalMaterialConversions.Add(materialConversion); MaterialConversions.Config.MaterialConversions.Add(materialConversion); MaterialConversions.Conversions.Add(materialConversion.Type, materialConversion); return RuntimeRegistry.Register(materialConversion); } catch { API.OnError?.Invoke("Failed to parse material conversion passed in through external plugin."); return null; } } [PublicAPI] public static bool UpdateMaterialConversion(string key, string json) { if (!RuntimeRegistry.TryGetValue<MaterialConversion>(key, out var value)) { return false; } MaterialConversion materialConversion = JsonConvert.DeserializeObject<MaterialConversion>(json); if (materialConversion == null) { return false; } value.CopyFieldsFrom(materialConversion); return true; } [PublicAPI] public static string? AddRecipe(string json) { try { RecipeConfig recipeConfig = JsonConvert.DeserializeObject<RecipeConfig>(json); if (recipeConfig == null) { return null; } ExternalRecipes.Add(recipeConfig); RecipesHelper.Config.recipes.Add(recipeConfig); return RuntimeRegistry.Register(recipeConfig); } catch { API.OnError?.Invoke("Failed to parse recipe passed in through external plugin."); return null; } } [PublicAPI] public static string? AddRecipes(string json) { try { List<RecipeConfig> list = JsonConvert.DeserializeObject<List<RecipeConfig>>(json); if (list == null) { return null; } ExternalRecipes.AddRange(list); RecipesHelper.Config.recipes.AddRange(list); return RuntimeRegistry.Register(list); } catch { API.OnError?.Invoke("Failed to parse recipe from external plugin"); return null; } } [PublicAPI] public static bool UpdateRecipes(string key, string json) { if (!RuntimeRegistry.TryGetValue<List<RecipeConfig>>(key, out var value)) { return false; } List<RecipeConfig> list = JsonConvert.DeserializeObject<List<RecipeConfig>>(json); if (list == null) { return false; } ExternalRecipes.ReplaceThenAdd(value, list); RecipesHelper.Config.recipes.ReplaceThenAdd(value, list); return true; } [PublicAPI] public static string? AddSacrifice(string json) { try { DisenchantProductsConfig disenchantProductsConfig = JsonConvert.DeserializeObject<DisenchantProductsConfig>(json); if (disenchantProductsConfig == null) { return null; } ExternalSacrifices.Add(disenchantProductsConfig); EnchantCostsHelper.Config.DisenchantProducts.Add(disenchantProductsConfig); return RuntimeRegistry.Register(disenchantProductsConfig); } catch { API.OnError?.Invoke("Failed to parse sacrifice from external plugin"); return null; } } [PublicAPI] public static bool UpdateSacrifice(string key, string json) { if (!RuntimeRegistry.TryGetValue<DisenchantProductsConfig>(key, out var value)) { return false; } DisenchantProductsConfig source = JsonConvert.DeserializeObject<DisenchantProductsConfig>(json); value.CopyFieldsFrom(source); return true; } [PublicAPI] public static string? AddBountyTarget(string json) { try { BountyTargetConfig bountyTargetConfig = JsonConvert.DeserializeObject<BountyTargetConfig>(json); if (bountyTargetConfig == null) { return null; } ExternalBountyTargets.Add(bountyTargetConfig); AdventureDataManager.Config.Bounties.Targets.Add(bountyTargetConfig); return RuntimeRegistry.Register(bountyTargetConfig); } catch { API.OnError?.Invoke("Failed to parse bounty target passed in through external plugin."); return null; } } [PublicAPI] public static bool UpdateBountyTarget(string key, string json) { if (!RuntimeRegistry.TryGetValue<BountyTargetConfig>(key, out var value)) { return false; } BountyTargetConfig source = JsonConvert.DeserializeObject<BountyTargetConfig>(json); value.CopyFieldsFrom(source); return true; } private static void AddOrSet<T, V>(this Dictionary<T, List<V>> dict, T key, V value) { if (!dict.ContainsKey(key)) { dict[key] = new List<V>(); } dict[key].Add(value); } private static void CopyFieldsFrom<T>(this T target, T source) { FieldInfo[] fields = typeof(T).GetFields(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); foreach (FieldInfo obj in fields) { obj.SetValue(value: obj.GetValue(source), obj: target); } } private static void ReplaceThenAdd<T>(this List<T> list, List<T> original, List<T> replacements) { list.RemoveAll(original); list.AddRange(replacements); } private static void RemoveAll<T>(this List<T> list, List<T> itemsToRemove) { foreach (T item in itemsToRemove) { list.Remove(item); } } private static bool TryGetProxyAbility(string abilityID, out Dictionary<string, Delegate> proxy) { return AbilityProxies.TryGetValue(abilityID, out proxy); } [PublicAPI] public static string? RegisterProxyAbility(string json, Dictionary<string, Delegate> delegates) { try { AbilityDefinition abilityDefinition = JsonConvert.DeserializeObject<AbilityDefinition>(json); if (abilityDefinition == null) { return null; } AbilityFactory.Register(abilityDefinition.ID, typeof(AbilityProxy)); AbilityProxies[abilityDefinition.ID] = delegates; AbilityProxyDefinition obj = new AbilityProxyDefinition(abilityDefinition, delegates); AbilityDefinitions.Config.Abilities.Add(abilityDefinition); AbilityDefinitions.Abilities[abilityDefinition.ID] = abilityDefinition; return RuntimeRegistry.Register(obj); } catch { API.OnError?.Invoke("Failed to parse ability definition from external plugin"); return null; } } [PublicAPI] public static bool UpdateProxyAbility(string key, string json, Dictionary<string, Delegate> proxy) { if (!RuntimeRegistry.TryGetValue<AbilityProxyDefinition>(key, out var value)) { return false; } AbilityDefinition source = JsonConvert.DeserializeObject<AbilityDefinition>(json); value.Ability.CopyFieldsFrom(source); value.Delegates.CopyFieldsFrom<Dictionary<string, Delegate>>(proxy); return true; } public static bool InjectCallbacks(this AbilityProxy proxy, string abilityID) { if (!TryGetProxyAbility(abilityID, out Dictionary<string, Delegate> proxy2)) { return false; } proxy._callbacks = proxy2; return true; } } public enum LogLevel { Info, Warning, Error } public enum BossDropMode { Default, OnePerPlayerOnServer, OnePerPlayerNearBoss } public enum GatedBountyMode { Unlimited, BossKillUnlocksCurrentBiomeBounties, BossKillUnlocksNextBiomeBounties } public class EpicAssets { public AssetBundle AssetBundle; public Sprite EquippedSprite; public Sprite AugaEquippedSprite; public Sprite GenericSetItemSprite; public Sprite AugaSetItemSprite; public Sprite GenericItemBgSprite; public Sprite AugaItemBgSprite; public Sprite EnchantmentSparkle; public GameObject[] MagicItemLootBeamPrefabs = (GameObject[])(object)new GameObject[5]; public readonly Dictionary<string, GameObject[]> CraftingMaterialPrefabs = new Dictionary<string, GameObject[]>(); public Sprite SmallButtonEnchantOverlay; public Sprite DodgeBuffSprite; public AudioClip[] MagicItemDropSFX = (AudioClip[])(object)new AudioClip[5]; public AudioClip ItemLoopSFX; public AudioClip AugmentItemSFX; public GameObject MerchantPanel; public Sprite MapIconTreasureMap; public Sprite MapIconBounty; public AudioClip AbandonBountySFX; public AudioClip DoubleJumpSFX; public AudioClip DodgeBuffSFX; public AudioClip OffSetSFX; public GameObject DebugTextPrefab; public GameObject AbilityBar; public GameObject WelcomMessagePrefab; } public class PieceDef { public string Table; public string CraftingStation; public string ExtendStation; public List<RecipeRequirementConfig> Resources = new List<RecipeRequirementConfig>(); } [BepInPlugin("randyknapp.mods.epicloot", "Epic Loot", "0.12.2")] [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.*/)] public class EpicLoot : BaseUnityPlugin { public const string PluginId = "randyknapp.mods.epicloot"; public const string DisplayName = "Epic Loot"; public const string Version = "0.12.2"; private static string ConfigFileName = "randyknapp.mods.epicloot.cfg"; private static string ConfigFileFullPath; public static readonly List<ItemType> AllowedMagicItemTypes; public static readonly Dictionary<string, string> MagicItemColors; public static string[] MagicMaterials; public static string[] ItemNames; public static EpicAssets Assets; public static Dictionary<string, Object> _assetCache; public static bool AlwaysDropCheat; public const PinType BountyPinType = 800; public const PinType TreasureMapPinType = 801; public static bool HasAuga; public static bool AugaTooltipNoTextBoxes; private static EpicLoot _instance; private Harmony _harmony; private float _worldLuckFactor; internal ELConfig cfg; private DateTime _lastReloadTime; private const long RELOAD_DELAY = 10000000L; public static event Action AbilitiesInitialized; public static event Action LootTableLoaded; [UsedImplicitly] public void Awake() { _instance = this; Assembly executingAssembly = Assembly.GetExecutingAssembly(); Logger.LogInfo((object)"Checking for EIDF"); EIDFLegacy.CheckForExtendedItemFrameworkLoaded(_instance); Logger.LogInfo((object)"Loading unitylib"); LoadEmbeddedAssembly(executingAssembly, "EpicLoot-UnityLib.dll"); Logger.LogInfo((object)"Setting up config"); cfg = new ELConfig(((BaseUnityPlugin)this).Config); PrefabCreator.Logger = ((BaseUnityPlugin)this).Logger; Logger.LogInfo((object)"Applying config patches"); FilePatching.LoadAndApplyAllPatches(); Logger.LogInfo((object)"Loading abilities"); InitializeAbilities(); Logger.LogInfo((object)"Adding localization"); AddLocalizations(); Logger.LogInfo((object)"Loading assets"); LoadAssets(); Logger.LogInfo((object)"Starting enchanting controller"); EnchantingUIController.Initialize(); Logger.LogInfo((object)"Harmony Patching"); _harmony = Harmony.CreateAndPatchAll(Assembly.GetExecutingAssembly(), "randyknapp.mods.epicloot"); EpicLoot.LootTableLoaded?.Invoke(); RegisterMagicEffectEvents(); TerminalCommands.AddTerminalCommands(); SetupWatcher(); } private static void RegisterMagicEffectEvents() { MagicItemEffectDefinitions.OnSetupMagicItemEffectDefinitions += Riches_CharacterDrop_GenerateDropList_Patch.UpdateRichesOnEffectSetup; } private static void LoadEmbeddedAssembly(Assembly assembly, string assemblyName) { Stream manifestResourceStream = assembly.GetManifestResourceStream(assembly.GetName().Name + "." + assemblyName); if (manifestResourceStream == null) { LogErrorForce("Could not load embedded assembly (" + assemblyName + ")!"); return; } using (manifestResourceStream) { byte[] array = new byte[manifestResourceStream.Length]; manifestResourceStream.Read(array, 0, array.Length); Assembly.Load(array); } } private void AddLocalizations() { CustomLocalization localization = LocalizationManager.Instance.GetLocalization(); Log("Loading Localizations."); string[] manifestResourceNames = typeof(EpicLoot).Assembly.GetManifestResourceNames(); foreach (string text in manifestResourceNames) { if (text.Contains("localizations")) { string text2 = Regex.Replace(ReadEmbeddedResourceFile(text), "\\/\\/.*\\n", ""); string[] array = text.Split(new char[1] { '.' }); Log("Adding localization: " + array[2]); localization.AddJsonFile(array[2], text2); } } ELConfig.StartupProcessModifiedLocalizations(); } private static void InitializeAbilities() { MagicEffectType.Initialize(); EpicLoot.AbilitiesInitialized?.Invoke(); } public static void Log(string message) { if (ELConfig._loggingEnabled.Value && ELConfig._logLevel.Value <= LogLevel.Info) { ((BaseUnityPlugin)_instance).Logger.LogInfo((object)message); } } public static void LogWarning(string message) { if (ELConfig._loggingEnabled.Value && ELConfig._logLevel.Value <= LogLevel.Warning) { ((BaseUnityPlugin)_instance).Logger.LogWarning((object)message); } } public static void LogError(string message) { if (ELConfig._loggingEnabled.Value && ELConfig._logLevel.Value <= LogLevel.Error) { ((BaseUnityPlugin)_instance).Logger.LogError((object)message); } } public static void LogWarningForce(string message) { ((BaseUnityPlugin)_instance).Logger.LogWarning((object)message); } public static void LogErrorForce(string message) { ((BaseUnityPlugin)_instance).Logger.LogError((object)message); } private void LoadAssets() { AssetBundle val = LoadAssetBundle("epicloot"); if ((Object)(object)val == (Object)null || Assets == null) { LogErrorForce("Unable to load asset bundle! This mod will not behave as expected!"); return; } Assets.AssetBundle = val; Assets.EquippedSprite = val.LoadAsset<Sprite>("Equipped"); Assets.AugaEquippedSprite = val.LoadAsset<Sprite>("AugaEquipped"); Assets.GenericSetItemSprite = val.LoadAsset<Sprite>("GenericSetItemMarker"); Assets.AugaSetItemSprite = val.LoadAsset<Sprite>("AugaSetItem"); Assets.GenericItemBgSprite = val.LoadAsset<Sprite>("GenericItemBg"); Assets.AugaItemBgSprite = val.LoadAsset<Sprite>("AugaItemBG"); Assets.EnchantmentSparkle = val.LoadAsset<Sprite>("sparkle"); Assets.SmallButtonEnchantOverlay = val.LoadAsset<Sprite>("SmallButtonEnchantOverlay"); Assets.DodgeBuffSprite = val.LoadAsset<Sprite>("DodgeBuff"); Assets.MagicItemLootBeamPrefabs[0] = val.LoadAsset<GameObject>("MagicLootBeam"); Assets.MagicItemLootBeamPrefabs[1] = val.LoadAsset<GameObject>("RareLootBeam"); Assets.MagicItemLootBeamPrefabs[2] = val.LoadAsset<GameObject>("EpicLootBeam"); Assets.MagicItemLootBeamPrefabs[3] = val.LoadAsset<GameObject>("LegendaryLootBeam"); Assets.MagicItemLootBeamPrefabs[4] = val.LoadAsset<GameObject>("MythicLootBeam"); Assets.MagicItemDropSFX[0] = val.LoadAsset<AudioClip>("MagicItemDrop"); Assets.MagicItemDropSFX[1] = val.LoadAsset<AudioClip>("RareItemDrop"); Assets.MagicItemDropSFX[2] = val.LoadAsset<AudioClip>("EpicItemDrop"); Assets.MagicItemDropSFX[3] = val.LoadAsset<AudioClip>("LegendaryItemDrop"); Assets.MagicItemDropSFX[4] = val.LoadAsset<AudioClip>("MythicItemDrop"); Assets.ItemLoopSFX = val.LoadAsset<AudioClip>("ItemLoop"); Assets.AugmentItemSFX = val.LoadAsset<AudioClip>("AugmentItem"); Assets.MerchantPanel = val.LoadAsset<GameObject>("MerchantPanel"); Assets.MapIconTreasureMap = val.LoadAsset<Sprite>("TreasureMapIcon"); Assets.MapIconBounty = val.LoadAsset<Sprite>("MapIconBounty"); Assets.AbandonBountySFX = val.LoadAsset<AudioClip>("AbandonBounty"); Assets.DoubleJumpSFX = val.LoadAsset<AudioClip>("DoubleJump"); Assets.DodgeBuffSFX = val.LoadAsset<AudioClip>("evasionbuff"); Assets.OffSetSFX = val.LoadAsset<AudioClip>("offset"); Assets.DebugTextPrefab = val.LoadAsset<GameObject>("DebugText"); Assets.AbilityBar = val.LoadAsset<GameObject>("AbilityBar"); Assets.WelcomMessagePrefab = val.LoadAsset<GameObject>("WelcomeMessage"); LoadCraftingMaterialAssets(); LoadPieces(); LoadItems(); LoadBountySpawner(); PrefabManager.OnPrefabsRegistered += SetupAndvaranaut; ItemManager.OnItemsRegistered += SetupStatusEffects; LoadUnidentifiedItems(); MinimapManager.OnVanillaMapAvailable += delegate { AutoAddEnchantableItems.CheckAndAddAllEnchantableItems(); }; DodgeBuff.CreateMyStatusEffect(); } public static T LoadAsset<T>(string assetName) where T : Object { try { if (_assetCache.ContainsKey(assetName)) { return (T)(object)_assetCache[assetName]; } T val = Assets.AssetBundle.LoadAsset<T>(assetName); _assetCache.Add(assetName, (Object)(object)val); return val; } catch (Exception ex) { LogErrorForce("Error loading asset (" + assetName + "): " + ex.Message); return default(T); } } private static void LoadPieces() { //IL_0015: Unknown result type (might be due to invalid IL or missing references) //IL_001b: Expected O, but got Unknown //IL_0041: Unknown result type (might be due to invalid IL or missing references) //IL_0046: 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_0059: Unknown result type (might be due to invalid IL or missing references) //IL_0061: Expected O, but got Unknown //IL_0063: Unknown result type (might be due to invalid IL or missing references) //IL_0068: Unknown result type (might be due to invalid IL or missing references) //IL_0073: Unknown result type (might be due to invalid IL or missing references) //IL_007a: Unknown result type (might be due to invalid IL or missing references) //IL_0082: Expected O, but got Unknown //IL_0084: Unknown result type (might be due to invalid IL or missing references) //IL_0089: 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_009b: Unknown result type (might be due to invalid IL or missing references) //IL_00a3: Expected O, but got Unknown //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_00bc: Unknown result type (might be due to invalid IL or missing references) //IL_00c4: Expected O, but got Unknown //IL_00d1: Unknown result type (might be due to invalid IL or missing references) //IL_00db: Expected O, but got Unknown //IL_00f1: Unknown result type (might be due to invalid IL or missing references) //IL_00f7: Expected O, but got Unknown //IL_011d: Unknown result type (might be due to invalid IL or missing references) //IL_0122: 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_0135: Unknown result type (might be due to invalid IL or missing references) //IL_013d: Expected O, but got Unknown //IL_013f: Unknown result type (might be due to invalid IL or missing references) //IL_0144: 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_0156: Unknown result type (might be due to invalid IL or missing references) //IL_015e: Expected O, but got Unknown //IL_0160: Unknown result type (might be due to invalid IL or missing references) //IL_0165: Unknown result type (might be due to invalid IL or missing references) //IL_0170: Unknown result type (might be due to invalid IL or missing references) //IL_0177: Unknown result type (might be due to invalid IL or missing references) //IL_017f: Expected O, but got Unknown //IL_0181: Unknown result type (might be due to invalid IL or missing references) //IL_0186: Unknown result type (might be due to invalid IL or missing references) //IL_0191: Unknown result type (might be due to invalid IL or missing references) //IL_0198: Unknown result type (might be due to invalid IL or missing references) //IL_01a0: Expected O, but got Unknown //IL_01ad: Unknown result type (might be due to invalid IL or missing references) //IL_01b7: Expected O, but got Unknown //IL_01ce: Unknown result type (might be due to invalid IL or missing references) //IL_01d5: Expected O, but got Unknown //IL_01f7: Unknown result type (might be due to invalid IL or missing references) //IL_01fc: Unknown result type (might be due to invalid IL or missing references) //IL_0207: Unknown result type (might be due to invalid IL or missing references) //IL_020f: Unknown result type (might be due to invalid IL or missing references) //IL_0217: Expected O, but got Unknown //IL_0219: Unknown result type (might be due to invalid IL or missing references) //IL_021e: Unknown result type (might be due to invalid IL or missing references) //IL_0229: Unknown result type (might be due to invalid IL or missing references) //IL_0230: Unknown result type (might be due to invalid IL or missing references) //IL_0238: Expected O, but got Unknown //IL_0247: Unknown result type (might be due to invalid IL or missing references) //IL_0251: Expected O, but got Unknown GameObject val = Assets.AssetBundle.LoadAsset<GameObject>("piece_enchanter"); PieceConfig val2 = new PieceConfig(); val2.PieceTable = "Hammer"; val2.Category = PieceCategories.Misc; val2.AllowedInDungeons = false; val2.Requirements = (RequirementConfig[])(object)new RequirementConfig[4] { new RequirementConfig { Item = "Stone", Amount = 10, Recover = true }, new RequirementConfig { Item = "SurtlingCore", Amount = 3, Recover = true }, new RequirementConfig { Item = "Copper", Amount = 3, Recover = true }, new RequirementConfig { Item = "SwordCheat", Amount = 1, Recover = false } }; PieceManager.Instance.AddPiece(new CustomPiece(val, true, val2)); GameObject val3 = Assets.AssetBundle.LoadAsset<GameObject>("piece_augmenter"); PieceConfig val4 = new PieceConfig(); val4.PieceTable = "Hammer"; val4.Category = PieceCategories.Misc; val4.AllowedInDungeons = false; val4.Requirements = (RequirementConfig[])(object)new RequirementConfig[4] { new RequirementConfig { Item = "Obsidian", Amount = 10, Recover = true }, new RequirementConfig { Item = "Crystal", Amount = 3, Recover = true }, new RequirementConfig { Item = "Bronze", Amount = 3, Recover = true }, new RequirementConfig { Item = "SwordCheat", Amount = 1, Recover = false } }; PieceManager.Instance.AddPiece(new CustomPiece(val3, true, val4)); GameObject val5 = Assets.AssetBundle.LoadAsset<GameObject>("piece_enchantingtable"); PieceConfig val6 = new PieceConfig(); val6.PieceTable = "Hammer"; val6.Category = PieceCategories.Crafting; val6.Requirements = (RequirementConfig[])(object)new RequirementConfig[2] { new RequirementConfig { Item = "FineWood", Amount = 10, Recover = true }, new RequirementConfig { Item = "SurtlingCore", Amount = 1, Recover = true } }; PieceManager.Instance.AddPiece(new CustomPiece(val5, true, val6)); } private static void LoadItems() { //IL_001f: Unknown result type (might be due to invalid IL or missing references) //IL_0025: Expected O, but got Unknown string[] itemNames = ItemNames; foreach (string text in itemNames) { CustomItem val = new CustomItem(Assets.AssetBundle.LoadAsset<GameObject>(text), false); ItemManager.Instance.AddItem(val); } } private static void LoadBountySpawner() { //IL_0032: Unknown result type (might be due to invalid IL or missing references) //IL_0038: Expected O, but got Unknown GameObject val = Assets.AssetBundle.LoadAsset<GameObject>("EL_SpawnController"); if ((Object)(object)val == (Object)null) { LogErrorForce("Unable to find bounty spawner asset! This mod will not behave as expected!"); return; } val.AddComponent<AdventureSpawnController>(); CustomPrefab val2 = new CustomPrefab(val, false); PrefabManager.Instance.AddPrefab(val2); } private static void LoadCraftingMaterialAssets() { //IL_00b8: Unknown result type (might be due to invalid IL or missing references) //IL_00bf: Expected O, but got Unknown string[] magicMaterials = MagicMaterials; foreach (string arg in magicMaterials) { foreach (ItemRarity value in Enum.GetValues(typeof(ItemRarity))) { string text = $"{arg}{value}"; GameObject val = Assets.AssetBundle.LoadAsset<GameObject>(text); if ((Object)(object)val == (Object)null) { LogErrorForce("Tried to load asset " + text + " but it does not exist in the asset bundle!"); continue; } ItemDrop component = val.GetComponent<ItemDrop>(); if ((Object)(object)component != (Object)null && component.m_itemData.IsMagicCraftingMaterial()) { component.m_itemData.m_variant = GetRarityIconIndex(value); } CustomItem val2 = new CustomItem(val, false); ItemManager.Instance.AddItem(val2); } } } private static void LoadUnidentifiedItems() { //IL_0049: Unknown result type (might be due to invalid IL or missing references) //IL_004e: Unknown result type (might be due to invalid IL or missing references) //IL_007a: Unknown result type (might be due to invalid IL or missing references) //IL_00d6: Unknown result type (might be due to invalid IL or missing references) //IL_00db: Unknown result type (might be due to invalid IL or missing references) //IL_00e7: Unknown result type (might be due to invalid IL or missing references) //IL_00f7: Unknown result type (might be due to invalid IL or missing references) //IL_0104: Expected O, but got Unknown //IL_0107: Unknown result type (might be due to invalid IL or missing references) //IL_010e: Expected O, but got Unknown foreach (Biome item in new List<Biome> { (Biome)1, (Biome)8, (Biome)2, (Biome)4, (Biome)16, (Biome)512, (Biome)32 }) { foreach (ItemRarity value in Enum.GetValues(typeof(ItemRarity))) { string text = $"{item}_{value}_Unidentified"; GameObject obj = Assets.AssetBundle.LoadAsset<GameObject>(text); MagicItemComponent orCreate = obj.GetComponent<ItemDrop>().m_itemData.Data().GetOrCreate<MagicItemComponent>(); orCreate.SetMagicItem(new MagicItem { Rarity = value, IsUnidentified = true }); orCreate.Save(); ItemConfig val = new ItemConfig { Name = $"$mod_epicloot_{value} $mod_epicloot_unidentified_{item}", Description = "$mod_epicloot_unidentified_introduce" }; CustomItem val2 = new CustomItem(obj, false, val); ItemManager.Instance.AddItem(val2); Log("Added " + text); } } } [UsedImplicitly] public void OnDestroy() { ((BaseUnityPlugin)this).Config.Save(); _instance = null; } public static bool IsObjectDBReady() { if ((Object)(object)ObjectDB.instance != (Object)null && ObjectDB.instance.m_items.Count != 0) { return (Object)(object)ObjectDB.instance.GetItemPrefab("Amber") != (Object)null; } return false; } private static void SetupAndvaranaut() { //IL_019a: Unknown result type (might be due to invalid IL or missing references) //IL_01a1: Expected O, but got Unknown GameObject obj = Assets.AssetBundle.LoadAsset<GameObject>("Andvaranaut"); ItemDrop component = obj.GetComponent<ItemDrop>(); ItemData itemData = component.m_itemData; ItemData itemData2 = ObjectDB.instance.GetItemPrefab("Wishbone").GetComponent<ItemDrop>().m_itemData; StatusEffect equipStatusEffect = itemData2.m_shared.m_equipStatusEffect; SE_CustomFinder sE_CustomFinder = ScriptableObject.CreateInstance<SE_CustomFinder>(); Utils.CopyFields(equipStatusEffect, sE_CustomFinder, typeof(SE_Finder)); ((Object)sE_CustomFinder).name = "CustomWishboneFinder"; SE_CustomFinder sE_CustomFinder2 = ScriptableObject.CreateInstance<SE_CustomFinder>(); Utils.CopyFields(sE_CustomFinder, sE_CustomFinder2, typeof(SE_CustomFinder)); ((Object)sE_CustomFinder2).name = "Andvaranaut"; ((StatusEffect)sE_CustomFinder2).m_name = "$mod_epicloot_item_andvaranaut"; ((StatusEffect)sE_CustomFinder2).m_icon = itemData.GetIcon(); ((StatusEffect)sE_CustomFinder2).m_tooltip = "$mod_epicloot_item_andvaranaut_tooltip"; ((StatusEffect)sE_CustomFinder2).m_startMessage = "$mod_epicloot_item_andvaranaut_startmsg"; sE_CustomFinder2.RequiredComponentTypes = new List<Type> { typeof(TreasureMapChest), typeof(BountyTarget) }; sE_CustomFinder.DisallowedComponentTypes = new List<Type> { typeof(TreasureMapChest), typeof(BountyTarget) }; ObjectDB.instance.m_StatusEffects.Remove(equipStatusEffect); ObjectDB.instance.m_StatusEffects.Add((StatusEffect)(object)sE_CustomFinder2); ObjectDB.instance.m_StatusEffects.Add((StatusEffect)(object)sE_CustomFinder); itemData.m_shared.m_equipStatusEffect = (StatusEffect)(object)sE_CustomFinder2; itemData2.m_shared.m_equipStatusEffect = (StatusEffect)(object)sE_CustomFinder; MagicItem magicItem = new MagicItem { Rarity = ItemRarity.Epic, TypeNameOverride = "$mod_epicloot_item_andvaranaut_type" }; magicItem.Effects.Add(new MagicItemEffect(MagicEffectType.Andvaranaut)); component.m_itemData.SaveMagicItem(magicItem); CustomItem val = new CustomItem(obj, false); ItemManager.Instance.AddItem(val); PrefabManager.OnPrefabsRegistered -= SetupAndvaranaut; } private static void SetupStatusEffects() { StatusEffect statusEffect = ObjectDB.instance.GetStatusEffect("Lightning".GetHashCode()); SE_Paralyzed sE_Paralyzed = ScriptableObject.CreateInstance<SE_Paralyzed>(); Utils.CopyFields(statusEffect, sE_Paralyzed, typeof(StatusEffect)); ((Object)sE_Paralyzed).name = "Paralyze"; ((StatusEffect)sE_Paralyzed).m_name = "$mod_epicloot_se_paralyze"; ObjectDB.instance.m_StatusEffects.Add((StatusEffect)(object)sE_Paralyzed); ItemManager.OnItemsRegistered -= SetupStatusEffects; } public static AssetBundle LoadAssetBundle(string filename) { Assembly callingAssembly = Assembly.GetCallingAssembly(); return AssetBundle.LoadFromStream(callingAssembly.GetManifestResourceStream(callingAssembly.GetName().Name + "." + filename)); } internal static string ReadEmbeddedResourceFile(string filename) { Log("Attempting to load resource path: " + filename); string[] manifestResourceNames = typeof(EpicLoot).Assembly.GetManifestResourceNames(); for (int i = 0; i < manifestResourceNames.Length; i++) { _ = manifestResourceNames[i]; } using Stream stream = typeof(EpicLoot).Assembly.GetManifestResourceStream(filename); using StreamReader streamReader = new StreamReader(stream); return streamReader.ReadToEnd(); } public static bool CanBeMagicItem(ItemData item) { //IL_0026: Unknown result type (might be due to invalid IL or missing references) if (item != null && IsPlayerItem(item) && Nonstackable(item) && IsNotRestrictedItem(item)) { return AllowedMagicItemTypes.Contains(item.m_shared.m_itemType); } return false; } public static Sprite GetMagicItemBgSprite() { if (!HasAuga) { return Assets.GenericItemBgSprite; } return Assets.AugaItemBgSprite; } public static Sprite GetEquippedSprite() { if (!HasAuga) { return Assets.EquippedSprite; } return Assets.AugaEquippedSprite; } public static Sprite GetSetItemSprite() { if (!HasAuga) { return Assets.GenericSetItemSprite; } return Assets.AugaSetItemSprite; } public static string GetMagicEffectPip(bool hasBeenAugmented) { if (!HasAuga) { if (!hasBeenAugmented) { return "◆"; } return "▼"; } if (!hasBeenAugmented) { return "♦"; } return "▾"; } private static bool IsNotRestrictedItem(ItemData item) { if ((Object)(object)item.m_dropPrefab != (Object)null && LootRoller.Config.RestrictedItems.Contains(((Object)item.m_dropPrefab).name)) { return false; } return !LootRoller.Config.RestrictedItems.Contains(item.m_shared.m_name); } private static bool Nonstackable(ItemData item) { return item.m_shared.m_maxStackSize == 1; } private static bool IsPlayerItem(ItemData item) { return item.m_shared.m_icons.Length != 0; } public static string GetCharacterCleanName(Character character) { return ((Object)character).name.Replace("(Clone)", "").Trim(); } public static string GetSetItemColor() { return ELConfig._setItemColor.Value; } public static string GetRarityDisplayName(ItemRarity rarity) { return rarity switch { ItemRarity.Magic => "$mod_epicloot_Magic", ItemRarity.Rare => "$mod_epicloot_Rare", ItemRarity.Epic => "$mod_epicloot_Epic", ItemRarity.Legendary => "$mod_epicloot_Legendary", ItemRarity.Mythic => "$mod_epicloot_Mythic", _ => "<non magic>", }; } public static string GetRarityColor(ItemRarity rarity) { return rarity switch { ItemRarity.Magic => GetColor(ELConfig._magicRarityColor.Value), ItemRarity.Rare => GetColor(ELConfig._rareRarityColor.Value), ItemRarity.Epic => GetColor(ELConfig._epicRarityColor.Value), ItemRarity.Legendary => GetColor(ELConfig._legendaryRarityColor.Value), ItemRarity.Mythic => GetColor(ELConfig._mythicRarityColor.Value), _ => "#FFFFFF", }; } public static Color GetRarityColorARGB(ItemRarity rarity) { //IL_0015: Unknown result type (might be due to invalid IL or missing references) //IL_000f: Unknown result type (might be due to invalid IL or missing references) Color result = default(Color); if (!ColorUtility.TryParseHtmlString(GetRarityColor(rarity), ref result)) { return Color.white; } return result; } private static string GetColor(string configValue) { if (configValue.StartsWith("#")) { return configValue; } if (MagicItemColors.TryGetValue(configValue, out var value)) { return value; } return "#000000"; } public static int GetRarityIconIndex(ItemRarity rarity) { return rarity switch { ItemRarity.Magic => Mathf.Clamp(ELConfig._magicMaterialIconColor.Value, 0, 9), ItemRarity.Rare => Mathf.Clamp(ELConfig._rareMaterialIconColor.Value, 0, 9), ItemRarity.Epic => Mathf.Clamp(ELConfig._epicMaterialIconColor.Value, 0, 9), ItemRarity.Legendary => Mathf.Clamp(ELConfig._legendaryMaterialIconColor.Value, 0, 9), ItemRarity.Mythic => Mathf.Clamp(ELConfig._mythicMaterialIconColor.Value, 0, 9), _ => throw new ArgumentOutOfRangeException("rarity", rarity, null), }; } public static AudioClip GetMagicItemDropSFX(ItemRarity rarity) { return Assets.MagicItemDropSFX[(int)rarity]; } public static GatedItemTypeMode GetGatedItemTypeMode() { return ELConfig._gatedItemTypeModeConfig.Value; } public static BossDropMode GetBossTrophyDropMode() { return ELConfig._bossTrophyDropMode.Value; } public static float GetBossTrophyDropPlayerRange() { return ELConfig._bossTrophyDropPlayerRange.Value; } public static float GetBossCryptKeyPlayerRange() { return ELConfig._bossCryptKeyDropPlayerRange.Value; } public static BossDropMode GetBossCryptKeyDropMode() { return ELConfig._bossCryptKeyDropMode.Value; } public static BossDropMode GetBossWishboneDropMode() { return ELConfig._bossWishboneDropMode.Value; } public static float GetBossWishboneDropPlayerRange() { return ELConfig._bossWishboneDropPlayerRange.Value; } public static int GetAndvaranautRange() { return ELConfig._andvaranautRange.Value; } public static bool IsAdventureModeEnabled() { return ELConfig._adventureModeEnabled.Value; } public static float GetWorldLuckFactor() { return _instance._worldLuckFactor; } public static void SetWorldLuckFactor(float luckFactor) { _instance._worldLuckFactor = luckFactor; } private void SetupWatcher() { FileSystemWatcher fileSystemWatcher = new FileSystemWatcher(Paths.ConfigPath, ConfigFileName); fileSystemWatcher.Changed += ReadConfigValues; fileSystemWatcher.Created += ReadConfigValues; fileSystemWatcher.Renamed += ReadConfigValues; fileSystemWatcher.IncludeSubdirectories = true; fileSystemWatcher.SynchronizingObject = ThreadingHelper.SynchronizingObject; fileSystemWatcher.EnableRaisingEvents = true; } private void ReadConfigValues(object sender, FileSystemEventArgs e) { DateTime now = DateTime.Now; long num = now.Ticks - _lastReloadTime.Ticks; if (File.Exists(ConfigFileFullPath) && num >= 10000000) { try { Log("Attempting to reload configuration..."); ((BaseUnityPlugin)this).Config.Reload(); } catch { Log("There was an issue loading " + ConfigFileName); return; } _lastReloadTime = now; } } static EpicLoot() { string configPath = Paths.ConfigPath; char directorySeparatorChar = Path.DirectorySeparatorChar; ConfigFileFullPath = configPath + directorySeparatorChar + ConfigFileName; AllowedMagicItemTypes = new List<ItemType> { (ItemType)6, (ItemType)7, (ItemType)11, (ItemType)17, (ItemType)18, (ItemType)4, (ItemType)3, (ItemType)14, (ItemType)22, (ItemType)5, (ItemType)19, (ItemType)15 }; MagicItemColors = new Dictionary<string, string> { { "Red", "#ff4545" }, { "Orange", "#ffac59" }, { "Yellow", "#ffff75" }, { "Green", "#80fa70" }, { "Teal", "#18e7a9" }, { "Blue", "#00abff" }, { "Indigo", "#709bba" }, { "Purple", "#d078ff" }, { "Pink", "#ff63d6" }, { "Gray", "#dbcadb" } }; MagicMaterials = new string[6] { "Runestone", "EtchedRunestone", "Shard", "Dust", "Reagent", "Essence" }; ItemNames = new string[6] { "LeatherBelt", "SilverRing", "GoldRubyRing", "ForestToken", "IronBountyToken", "GoldBountyToken" }; Assets = new EpicAssets(); _assetCache = new Dictionary<string, Object>(); AlwaysDropCheat = false; } } public static class EpicLootAuga { public static Button ReplaceButton(Button button, bool icon = false, bool keepListeners = false) { return ReplaceButtonInternal(button, button, icon, keepListeners); } public static Button ReplaceButtonFancy(Button button, bool icon = false, bool keepListeners = false) { return ReplaceButtonInternal(button, button, icon, keepListeners); } private static Button ReplaceButtonInternal(Button newButton, Button button, bool icon, bool keepListeners) { //IL_0058: Unknown result type (might be due to invalid IL or missing references) //IL_005e: Expected O, but got Unknown //IL_0064: Unknown result type (might be due to invalid IL or missing references) //IL_0069: Unknown result type (might be due to invalid IL or missing references) //IL_006b: Unknown result type (might be due to invalid IL or missing references) //IL_0075: Unknown result type (might be due to invalid IL or missing references) //IL_0077: Unknown result type (might be due to invalid IL or missing references) //IL_0081: Unknown result type (might be due to invalid IL or missing references) //IL_0083: Unknown result type (might be due to invalid IL or missing references) //IL_008d: Unknown result type (might be due to invalid IL or missing references) //IL_008f: 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_00a0: Unknown result type (might be due to invalid IL or missing references) //IL_00bd: Unknown result type (might be due to invalid IL or missing references) //IL_00c7: Expected O, but got Unknown //IL_0108: Unknown result type (might be due to invalid IL or missing references) //IL_010d: Unknown result type (might be due to invalid IL or missing references) if (icon) { Object.Destroy((Object)(object)((Component)((Component)newButton).GetComponentInChildren<TMP_Text>()).gameObject); ((Object)Object.Instantiate<Transform>(((Component)button).transform.Find("Icon"), ((Component)newButton).transform)).name = "Icon"; } else { string text = ((Component)button).GetComponentInChildren<Text>().text; ((Component)newButton).GetComponentInChildren<TMP_Text>().text = text; } RectTransform val = (RectTransform)((Component)button).transform; RectTransform val2 = (RectTransform)((Component)newButton).transform; val2.anchorMin = val.anchorMin; val2.anchorMax = val.anchorMax; val2.pivot = val.pivot; val2.anchoredPosition = val.anchoredPosition; Rect rect = val.rect; val2.SetSizeWithCurrentAnchors((Axis)0, ((Rect)(ref rect)).width); if (keepListeners) { newButton.onClick = button.onClick; button.onClick = new ButtonClickedEvent(); } UIGamePad component = ((Component)button).GetComponent<UIGamePad>(); if ((Object)(object)component != (Object)null && (Object)(object)component.m_hint != (Object)null) { component.m_hint.transform.SetParent(((Component)newButton).transform); UIGamePad obj = ((Component)newButton).gameObject.AddComponent<UIGamePad>(); obj.m_keyCode = component.m_keyCode; obj.m_zinputKey = component.m_zinputKey; obj.m_hint = component.m_hint; obj.m_blockingElements = component.m_blockingElements.ToList(); } Object.DestroyImmediate((Object)(object)((Component)button).gameObject); return newButton; } public static void MakeSimpleTooltip(GameObject obj) { } public static void ReplaceBackground(GameObject obj, bool withCornerDecoration) { } public static void FixItemBG(GameObject obj) { } public static void FixListElementColors(GameObject obj) { //IL_0071: Unknown result type (might be due to invalid IL or missing references) //IL_0056: Unknown result type (might be due to invalid IL or missing references) _ = (Object)(object)obj.transform.Find("Selected") != (Object)null; Transform val = obj.transform.Find("Background"); if ((Object)(object)val != (Object)null) { Image component = ((Component)val).GetComponent<Image>(); if ((Object)(object)component != (Object)null) { ((Graphic)component).color = new Color(0f, 0f, 0f, 0.5f); } } Button component2 = obj.GetComponent<Button>(); if ((Object)(object)component2 != (Object)null) { ((Selectable)component2).colors = ColorBlock.defaultColorBlock; } } public static void FixFonts(GameObject obj) { TMP_Text[] componentsInChildren = obj.GetComponentsInChildren<TMP_Text>(true); for (int i = 0; i < componentsInChildren.Length; i++) { _ = componentsInChildren[i]; } } public static Button ReplaceVerticalLargeTab(Button button) { //IL_003e: Unknown result type (might be due to invalid IL or missing references) //IL_0044: Expected O, but got Unknown //IL_004a: Unknown result type (might be due to invalid IL or missing references) //IL_004f: 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_005b: Unknown result type (might be due to invalid IL or missing references) //IL_005d: Unknown result type (might be due to invalid IL or missing references) //IL_0067: Unknown result type (might be due to invalid IL or missing references) //IL_0069: Unknown result type (might be due to invalid IL or missing references) //IL_0073: Unknown result type (might be due to invalid IL or missing references) //IL_0075: Unknown result type (might be due to invalid IL or missing references) //IL_0081: Unknown result type (might be due to invalid IL or missing references) //IL_0086: Unknown result type (might be due to invalid IL or missing references) //IL_0136: Unknown result type (might be due to invalid IL or missing references) //IL_013b: Unknown result type (might be due to invalid IL or missing references) GameObject obj = Object.Instantiate<GameObject>(EpicLoot.LoadAsset<GameObject>("EnchantingTabAuga"), ((Component)button).transform.parent); ((Object)obj).name = ((Object)button).name; FixFonts(obj); int siblingIndex = ((Component)button).transform.GetSiblingIndex(); RectTransform val = (RectTransform)((Component)button).transform; RectTransform val2 = (RectTransform)obj.transform; val2.anchorMin = val.anchorMin; val2.anchorMax = val.anchorMax; val2.pivot = val.pivot; val2.anchoredPosition = val.anchoredPosition; Rect rect = val.rect; val2.SetSizeWithCurrentAnchors((Axis)0, ((Rect)(ref rect)).width); ((Component)obj.transform.Find("Text")).GetComponent<TMP_Text>().text = ((Component)((Component)button).transform.Find("Text")).GetComponent<TMP_Text>().text; ((Component)obj.transform.Find("Image")).GetComponent<Image>().sprite = ((Component)((Component)button).transform.Find("Image")).GetComponent<Image>().sprite; FeatureStatus component = obj.GetComponent<FeatureStatus>(); FeatureStatus component2 = ((Component)button).GetComponent<FeatureStatus>(); if ((Object)(object)component2 == (Object)null && (Object)(object)component != (Object)null) { Object.DestroyImmediate((Object)(object)component); } if ((Object)(object)component != (Object)null && (Object)(object)component2 != (Object)null) { component.Feature = component2.Feature; component.Refresh(); } Object.DestroyImmediate((Object)(object)((Component)button).gameObject); obj.transform.SetSiblingIndex(siblingIndex); return obj.GetComponent<Button>(); } public static void FixupScrollbar(Scrollbar scrollbar) { //IL_000c: Unknown result type (might be due to invalid IL or missing references) //IL_0031: Unknown result type (might be due to invalid IL or missing references) //IL_0037: Unknown result type (might be due to invalid IL or missing references) //IL_003d: Unknown result type (might be due to invalid IL or missing references) //IL_0048: Unknown result type (might be due to invalid IL or missing references) Object.Destroy((Object)(object)((Component)scrollbar).GetComponent<Image>()); ((Selectable)scrollbar).colors = ColorBlock.defaultColorBlock; Image component = ((Component)scrollbar.handleRect).GetComponent<Image>(); Color val = default(Color); if (ColorUtility.TryParseHtmlString("#8B7C6A", ref val)) { ((Graphic)component).color = new Color(val.r, val.g, val.b, 1f); } } } [HarmonyPatch] public static class Attack_Patch { public static Attack ActiveAttack; [HarmonyPatch(typeof(Attack), "DoMeleeAttack")] [HarmonyPrefix] [HarmonyPriority(0)] public static void Attack_DoMeleeAttack_Prefix(Attack __instance) { ActiveAttack = __instance; } [HarmonyPatch(typeof(Attack), "DoMeleeAttack")] [HarmonyPostfix] public static void Attack_DoMeleeAttack_Postfix() { ActiveAttack = null; } } [HarmonyPatch(typeof(Container), "AddDefaultItems")] public static class Container_AddDefaultItems_Patch { public static void Postfix(Container __instance) { //IL_0064: Unknown result type (might be due to invalid IL or missing references) //IL_0086: Unknown result type (might be due to invalid IL or missing references) //IL_008b: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)__instance == (Object)null || (Object)(object)__instance.m_piece == (Object)null) { return; } string text = ((Object)__instance.m_piece).name.Replace("(Clone)", "").Trim(); List<LootTable> lootTable = LootRoller.GetLootTable(text); if (lootTable == null || lootTable.Count <= 0) { return; } List<ItemData> list = LootRoller.RollLootTable(lootTable, 1, ((Object)__instance.m_piece).name, ((Component)__instance).transform.position); object arg = list.Count; Vector3 position = ((Component)__instance).transform.position; EpicLoot.Log(string.Format("Rolling on loot table: {0}, spawned {1} items at drop point({2}).", text, arg, ((Vector3)(ref position)).ToString("0"))); foreach (ItemData item in list) { __instance.m_inventory.AddItem(item); EpicLoot.Log(" - " + item.m_shared.m_name + (item.IsMagic() ? (": " + string.Join(", ", item.GetMagicItem().Effects.Select((MagicItemEffect x) => x.EffectType.ToString()))) : "")); } } } public static class EpicLootDropsHelper { public static bool InstantDropsEnabled { get; set; } public static void OnCharacterDeath(CharacterDrop characterDrop) { //IL_002b: Unknown result type (might be due to invalid IL or missing references) //IL_0037: Unknown result type (might be due to invalid IL or missing references) //IL_003c: Unknown result type (might be due to invalid IL or missing references) //IL_0041: Unknown result type (might be due to invalid IL or missing references) //IL_0046: Unknown result type (might be due to invalid IL or missing references) //IL_0048: Unknown result type (might be due to invalid IL or missing references) if (CanCharacterDropLoot(characterDrop.m_character)) { string characterCleanName = EpicLoot.GetCharacterCleanName(characterDrop.m_character); int level = characterDrop.m_character.GetLevel(); Vector3 dropPoint = characterDrop.m_character.GetCenterPoint() + ((Component)characterDrop).transform.TransformVector(characterDrop.m_spawnOffset); OnCharacterDeath(characterCleanName, level, dropPoint); } } public static bool CanCharacterDropLoot(Character character) { if ((Object)(object)character != (Object)null) { return !character.IsTamed(); } return false; } public static void OnCharacterDeath(string characterName, int level, Vector3 dropPoint) { //IL_001c: Unknown result type (might be due to invalid IL or missing references) //IL_0044: Unknown result type (might be due to invalid IL or missing references) //IL_005a: 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) List<LootTable> lootTable = LootRoller.GetLootTable(characterName); if (lootTable != null && lootTable.Count > 0) { List<GameObject> list = LootRoller.RollLootTableAndSpawnObjects(lootTable, level, characterName, dropPoint); EpicLoot.Log($"Rolling on loot table: {characterName} (lvl {level}), " + $"spawned {list.Count} items at drop point({dropPoint})."); DropItems(list, dropPoint); { foreach (GameObject item in list) { ItemData itemData = item.GetComponent<ItemDrop>().m_itemData; MagicItem magicItem = itemData.GetMagicItem(); if (magicItem != null) { EpicLoot.Log($" - {itemData.m_shared.m_name} <{item.transform.position}>: " + string.Join(", ", magicItem.Effects.Select((MagicItemEffect x) => x.EffectType.ToString()))); } } return; } } EpicLoot.Log($"Could not find loot table for: {characterName} (lvl {level})"); } public static void DropItems(List<GameObject> loot, Vector3 centerPos, float dropHemisphereRadius = 0.5f) { //IL_0013: Unknown result type (might be due to invalid IL or missing references) //IL_0019: Unknown result type (might be due to invalid IL or missing references) //IL_001e: Unknown result type (might be due to invalid IL or missing references) //IL_0021: Unknown result type (might be due to invalid IL or missing references) //IL_0037: Unknown result type (might be due to invalid IL or missing references) //IL_0038: 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_005f: Unknown result type (might be due to invalid IL or missing references) //IL_0078: Unknown result type (might be due to invalid IL or missing references) //IL_007d: Unknown result type (might be due to invalid IL or missing references) //IL_007e: Unknown result type (might be due to invalid IL or missing references) //IL_009f: Unknown result type (might be due to invalid IL or missing references) //IL_00a5: Unknown result type (might be due to invalid IL or missing references) //IL_0092: Unknown result type (might be due to invalid IL or missing references) foreach (GameObject item in loot) { Vector3 val = Random.insideUnitSphere * dropHemisphereRadius; val.y = Mathf.Abs(val.y); item.transform.position = centerPos + val; item.transform.rotation = Quaternion.Euler(0f, (float)Random.Range(0, 360), 0f); Rigidbody component = item.GetComponent<Rigidbody>(); if ((Object)(object)component != (Object)null) { Vector3 insideUnitSphere = Random.insideUnitSphere; if ((double)insideUnitSphere.y < 0.0) { insideUnitSphere.y = 0f - insideUnitSphere.y; } component.AddForce(insideUnitSphere * 5f, (ForceMode)2); } } } } [HarmonyPatch(typeof(CharacterDrop), "OnDeath")] public static class CharacterDrop_OnDeath_Patch { public static void Postfix(CharacterDrop __instance) { if (EpicLootDropsHelper.InstantDropsEnabled) { EpicLootDropsHelper.OnCharacterDeath(__instance); } } } [HarmonyPatch(typeof(Ragdoll), "Setup")] public static class Ragdoll_Setup_Patch { public static void Postfix(Ragdoll __instance, CharacterDrop characterDrop) { if (!((Object)(object)characterDrop == (Object)null) && !((Object)(object)characterDrop.m_character == (Object)null) && !characterDrop.m_character.IsPlayer() && EpicLootDropsHelper.CanCharacterDropLoot(characterDrop.m_character)) { EpicLootDropsHelper.InstantDropsEnabled = false; string characterCleanName = EpicLoot.GetCharacterCleanName(characterDrop.m_character); int level = characterDrop.m_character.GetLevel(); __instance.m_nview.m_zdo.Set("characterName", characterCleanName); __instance.m_nview.m_zdo.Set("level", level); } } } [HarmonyPatch(typeof(Ragdoll), "SpawnLoot")] public static class Ragdoll_SpawnLoot_Patch { public static void Postfix(Ragdoll __instance, Vector3 center) { //IL_003c: Unknown result type (might be due to invalid IL or missing references) //IL_003d: Unknown res