using System; using System.Collections; using System.Collections.Concurrent; using System.Collections.Generic; using System.Collections.ObjectModel; using System.ComponentModel; using System.Diagnostics; using System.Diagnostics.CodeAnalysis; using System.Globalization; using System.IO; using System.IO.Compression; using System.Linq; using System.Linq.Expressions; using System.Reflection; using System.Reflection.Emit; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; using System.Runtime.Serialization; using System.Runtime.Versioning; using System.Security; using System.Security.Permissions; using System.Text; using System.Text.RegularExpressions; using BepInEx; using BepInEx.Bootstrap; using BepInEx.Configuration; using CreatureManager; using HarmonyLib; using ItemManager; using JetBrains.Annotations; using LocalizationManager; using Microsoft.CodeAnalysis; using ServerSync; using TMPro; using UnityEngine; using YamlDotNet.Core; using YamlDotNet.Core.Events; using YamlDotNet.Core.Tokens; using YamlDotNet.Helpers; using YamlDotNet.Serialization; using YamlDotNet.Serialization.Converters; using YamlDotNet.Serialization.EventEmitters; using YamlDotNet.Serialization.NamingConventions; using YamlDotNet.Serialization.NodeDeserializers; using YamlDotNet.Serialization.NodeTypeResolvers; using YamlDotNet.Serialization.ObjectFactories; using YamlDotNet.Serialization.ObjectGraphTraversalStrategies; using YamlDotNet.Serialization.ObjectGraphVisitors; using YamlDotNet.Serialization.Schemas; using YamlDotNet.Serialization.TypeInspectors; using YamlDotNet.Serialization.TypeResolvers; using YamlDotNet.Serialization.Utilities; using YamlDotNet.Serialization.ValueDeserializers; [assembly: Guid("D181CDA7-EF07-4BBC-B975-2B80FC6BBFAE")] [assembly: ComVisible(false)] [assembly: AssemblyTrademark("")] [assembly: AssemblyCopyright("Copyright © 2021")] [assembly: AssemblyProduct("OPBeaver")] [assembly: AssemblyCompany("")] [assembly: TargetFramework(".NETFramework,Version=v4.8", FrameworkDisplayName = ".NET Framework 4.8")] [assembly: AssemblyDescription("")] [assembly: AssemblyTitle("OPBeaver")] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: CompilationRelaxations(8)] [assembly: AssemblyFileVersion("1.0.0.0")] [assembly: AssemblyConfiguration("")] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("1.0.0.0")] [module: UnverifiableCode] namespace Microsoft.CodeAnalysis { [CompilerGenerated] [<42135fe8-c29e-439b-a9e3-134ccd9d3a4c>Embedded] internal sealed class <42135fe8-c29e-439b-a9e3-134ccd9d3a4c>EmbeddedAttribute : Attribute { } } namespace System.Runtime.CompilerServices { [<42135fe8-c29e-439b-a9e3-134ccd9d3a4c>Embedded] [CompilerGenerated] [AttributeUsage(AttributeTargets.Class | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Parameter | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter, AllowMultiple = false, Inherited = false)] internal sealed class <45ff51f2-9e39-418a-bfbe-416ab42ce92d>NullableAttribute : Attribute { public readonly byte[] NullableFlags; public <45ff51f2-9e39-418a-bfbe-416ab42ce92d>NullableAttribute(byte P_0) { NullableFlags = new byte[1] { P_0 }; } public <45ff51f2-9e39-418a-bfbe-416ab42ce92d>NullableAttribute(byte[] P_0) { NullableFlags = P_0; } } [CompilerGenerated] [<42135fe8-c29e-439b-a9e3-134ccd9d3a4c>Embedded] [AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Method | AttributeTargets.Interface | AttributeTargets.Delegate, AllowMultiple = false, Inherited = false)] internal sealed class <65d0f139-86da-4516-8ef5-5a98f9b5b5c6>NullableContextAttribute : Attribute { public readonly byte Flag; public <65d0f139-86da-4516-8ef5-5a98f9b5b5c6>NullableContextAttribute(byte P_0) { Flag = P_0; } } } namespace OdinBeaver { [<45ff51f2-9e39-418a-bfbe-416ab42ce92d>Nullable(0)] [BepInPlugin("org.bepinex.plugins.odinbeaver", "OdinBeaver", "0.0.7")] [<65d0f139-86da-4516-8ef5-5a98f9b5b5c6>NullableContext(1)] public class OdinBeaver : BaseUnityPlugin { private const string ModName = "OdinBeaver"; private const string ModVersion = "0.0.7"; private const string ModGUID = "org.bepinex.plugins.odinbeaver"; private static readonly ConfigSync configSync = new ConfigSync("OdinBeaver") { DisplayName = "OdinBeaver", CurrentVersion = "0.0.7", MinimumRequiredVersion = "0.0.7" }; internal static ConfigEntry BeaverChompDamage = null; internal static ConfigEntry BeaverBiteDamage = null; public static ConfigEntry WaitBetweenTargets = null; public static ConfigEntry CanConsumeWood = null; public static ConfigEntry CanChopStumps = null; public static ConfigEntry FrustrationTime = null; public static ConfigEntry SearchRadius = null; public static OdinBeaver Instance { get; private set; } = null; public void Awake() { //IL_02e2: Unknown result type (might be due to invalid IL or missing references) //IL_02ea: Unknown result type (might be due to invalid IL or missing references) //IL_03dc: Unknown result type (might be due to invalid IL or missing references) //IL_03e3: Expected O, but got Unknown Instance = this; Localizer.Load(); BeaverChompDamage = ((BaseUnityPlugin)this).Config.Bind("Beaver Tree Damage", "Chomp Damage", 5f, "Damage for the beaver's chomp attack."); BeaverBiteDamage = ((BaseUnityPlugin)this).Config.Bind("Beaver Tree Damage", "Bite Damage", 5f, "Damage for the beaver's bite attack."); WaitBetweenTargets = ((BaseUnityPlugin)this).Config.Bind("Beaver", "WaitBetweenTargets", 1f, "Seconds to wait after felling a tree/log before targeting the next one."); CanConsumeWood = ((BaseUnityPlugin)this).Config.Bind("Beaver", "CanConsumeWood", false, "If true, beaver will consume dropped wood nearby."); CanChopStumps = ((BaseUnityPlugin)this).Config.Bind("Beaver", "CanChompStumps", true, "If true, beaver will also chomp tree stumps."); FrustrationTime = ((BaseUnityPlugin)this).Config.Bind("Beaver", "FrustrationTime", 120f, "Seconds the beaver will try to reach a target before giving up."); SearchRadius = ((BaseUnityPlugin)this).Config.Bind("Beaver", "SearchRadius", 20f, "Radius (meters) a beaver searches for trees/logs/stumps/wood."); Item item = new Item("opbeaver", "beaver_attack"); item.Configurable = Configurability.Disabled; ItemDrop component = item.Prefab.GetComponent(); if ((Object)(object)component != (Object)null) { component.m_itemData.m_shared.m_damages.m_chop = BeaverChompDamage.Value; } Item item2 = new Item("opbeaver", "beaver_biteattack"); item2.Configurable = Configurability.Disabled; ItemDrop component2 = item2.Prefab.GetComponent(); if ((Object)(object)component2 != (Object)null) { component2.m_itemData.m_shared.m_damages.m_chop = BeaverBiteDamage.Value; } ItemManager.PrefabManager.RegisterPrefab("opbeaver", "sfx_beaver_alerted"); ItemManager.PrefabManager.RegisterPrefab("opbeaver", "sfx_beaver_idle"); ItemManager.PrefabManager.RegisterPrefab("opbeaver", "sfx_beaver_attack"); ItemManager.PrefabManager.RegisterPrefab("opbeaver", "sfx_beaver_death"); ItemManager.PrefabManager.RegisterPrefab("opbeaver", "fx_beaver_death"); ItemManager.PrefabManager.RegisterPrefab("opbeaver", "sfx_beaver_hit"); ItemManager.PrefabManager.RegisterPrefab("opbeaver", "vfx_beaver_hit"); ItemManager.PrefabManager.RegisterPrefab("opbeaver", "fx_beaver_pet"); ItemManager.PrefabManager.RegisterPrefab("opbeaver", "fx_beaver_tamed"); ItemManager.PrefabManager.RegisterPrefab("opbeaver", "vfx_beaver_birth"); ItemManager.PrefabManager.RegisterPrefab("opbeaver", "vfx_beaver_soothed"); ItemManager.PrefabManager.RegisterPrefab("opbeaver", "vfx_beaver_love"); ItemManager.PrefabManager.RegisterPrefab("opbeaver", "OP_Beaver_Kit"); Creature creature = new Creature("opbeaver", "OP_Beaver") { ConfigurationEnabled = true, CreatureFaction = (Faction)1, Biome = (Biome)9, CanSpawn = true, CanBeTamed = false, CanHaveStars = true, SpawnChance = 15f, GroupSize = new CreatureManager.Range(1f, 1f), CheckSpawnInterval = 2000, RequiredWeather = Weather.ClearSkies, AttackImmediately = false, ForestSpawn = Forest.Both, SpecificSpawnArea = SpawnArea.Edge, RequiredAltitude = new CreatureManager.Range(-1f, 1f), Maximum = 1 }; creature.Drops["LeatherScraps"].Amount = new CreatureManager.Range(1f, 2f); creature.Drops["LeatherScraps"].DropChance = 100f; if ((Object)(object)ZNet.instance == (Object)null || ZNet.instance.IsServer()) { ((MonoBehaviour)this).StartCoroutine(BeaverTargetCache.CacheRoutine()); } Harmony val = new Harmony("org.bepinex.plugins.odinbeaver"); val.PatchAll(Assembly.GetExecutingAssembly()); } } public class BeaverMemory { [<45ff51f2-9e39-418a-bfbe-416ab42ce92d>Nullable(1)] public Component Target; public float NextTargetTime; public float LastSearchTime; public float TargetStartTime; public bool HasDamagedTarget; public bool Wandering; public float WanderEndTime; public Vector3 WanderTarget; public Vector3 LastFailedTargetPos; public bool IsFleeing; public Vector3 FleeDestination; public bool ReachedFleeDestination; public float FleeWaitEndTime; public bool HasPlayedAlertSound; public float IdleAnimTimer; } [<45ff51f2-9e39-418a-bfbe-416ab42ce92d>Nullable(0)] [<65d0f139-86da-4516-8ef5-5a98f9b5b5c6>NullableContext(1)] public static class BeaverTargetCache { private static readonly string[] AllowedTrees = new string[3] { "beech", "fir", "pine" }; private static readonly string[] AllowedStumps = new string[5] { "beech_stub", "firtree_stub", "pinetree_stub", "fir_tree_stub", "pine_tree_stub" }; private static readonly List CachedLogs = new List(); private static readonly List CachedTrees = new List(); private static readonly List CachedStumps = new List(); private static readonly List CachedWood = new List(); private static readonly object cacheLock = new object(); public static IEnumerator CacheRoutine() { yield return (object)new WaitForSeconds(Random.Range(0.5f, 1.5f)); while (true) { RebuildCache(); yield return (object)new WaitForSeconds(3f); } } public static void RebuildCache() { lock (cacheLock) { try { CachedLogs.Clear(); CachedTrees.Clear(); CachedStumps.Clear(); CachedWood.Clear(); TreeLog[] array = Object.FindObjectsOfType(); foreach (TreeLog t in array) { if ((Object)(object)t != (Object)null && AllowedTrees.Any([<65d0f139-86da-4516-8ef5-5a98f9b5b5c6>NullableContext(0)] (string n) => (((Object)t).name ?? "").ToLower().Contains(n))) { CachedLogs.Add(t); } } TreeBase[] array2 = Object.FindObjectsOfType(); foreach (TreeBase t2 in array2) { if ((Object)(object)t2 != (Object)null && AllowedTrees.Any([<65d0f139-86da-4516-8ef5-5a98f9b5b5c6>NullableContext(0)] (string n) => (((Object)t2).name ?? "").ToLower().Contains(n))) { CachedTrees.Add(t2); } } Destructible[] array3 = Object.FindObjectsOfType(); foreach (Destructible d in array3) { if ((Object)(object)d != (Object)null && AllowedStumps.Any([<65d0f139-86da-4516-8ef5-5a98f9b5b5c6>NullableContext(0)] (string n) => (((Object)d).name ?? "").ToLower().Contains(n))) { CachedStumps.Add(d); } } ItemDrop[] array4 = Object.FindObjectsOfType(); foreach (ItemDrop val in array4) { if ((Object)(object)val != (Object)null && val.m_itemData != null) { string text = (val.m_itemData.m_shared.m_name ?? "").ToLower(); string text2 = (((Object)val).name ?? "").ToLower(); if (text.Contains("wood") || text2.Contains("wood")) { CachedWood.Add(val); } } } } catch (Exception arg) { Debug.LogError((object)$"[OdinBeaver] RebuildCache exception: {arg}"); } } } public static Component GetNearestTarget(MonsterAI ai) { //IL_0020: Unknown result type (might be due to invalid IL or missing references) //IL_0025: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)ai == (Object)null) { return null; } Vector3 pos = ((Component)ai).transform.position; float radiusSqr = OdinBeaver.SearchRadius.Value * OdinBeaver.SearchRadius.Value; lock (cacheLock) { if (OdinBeaver.CanChopStumps.Value) { Destructible val = CachedStumps.Where([<65d0f139-86da-4516-8ef5-5a98f9b5b5c6>NullableContext(0)] (Destructible s) => { //IL_0016: Unknown result type (might be due to invalid IL or missing references) //IL_0021: Unknown result type (might be due to invalid IL or missing references) //IL_0026: Unknown result type (might be due to invalid IL or missing references) //IL_002b: Unknown result type (might be due to invalid IL or missing references) int result; if (Object.op_Implicit((Object)(object)s) && ((Component)s).gameObject.activeInHierarchy) { Vector3 val5 = pos - ((Component)s).transform.position; result = ((((Vector3)(ref val5)).sqrMagnitude <= radiusSqr) ? 1 : 0); } else { result = 0; } return (byte)result != 0; }).OrderBy([<65d0f139-86da-4516-8ef5-5a98f9b5b5c6>NullableContext(0)] (Destructible s) => { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_000c: Unknown result type (might be due to invalid IL or missing references) //IL_0011: Unknown result type (might be due to invalid IL or missing references) //IL_0016: Unknown result type (might be due to invalid IL or missing references) Vector3 val5 = pos - ((Component)s).transform.position; return ((Vector3)(ref val5)).sqrMagnitude; }).FirstOrDefault(); if (Object.op_Implicit((Object)(object)val)) { return (Component)(object)val; } } TreeLog val2 = CachedLogs.Where([<65d0f139-86da-4516-8ef5-5a98f9b5b5c6>NullableContext(0)] (TreeLog l) => { //IL_0016: Unknown result type (might be due to invalid IL or missing references) //IL_0021: Unknown result type (might be due to invalid IL or missing references) //IL_0026: Unknown result type (might be due to invalid IL or missing references) //IL_002b: Unknown result type (might be due to invalid IL or missing references) int result; if (Object.op_Implicit((Object)(object)l) && ((Component)l).gameObject.activeInHierarchy) { Vector3 val5 = pos - ((Component)l).transform.position; result = ((((Vector3)(ref val5)).sqrMagnitude <= radiusSqr) ? 1 : 0); } else { result = 0; } return (byte)result != 0; }).OrderBy([<65d0f139-86da-4516-8ef5-5a98f9b5b5c6>NullableContext(0)] (TreeLog l) => { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_000c: Unknown result type (might be due to invalid IL or missing references) //IL_0011: Unknown result type (might be due to invalid IL or missing references) //IL_0016: Unknown result type (might be due to invalid IL or missing references) Vector3 val5 = pos - ((Component)l).transform.position; return ((Vector3)(ref val5)).sqrMagnitude; }).FirstOrDefault(); if (Object.op_Implicit((Object)(object)val2)) { return (Component)(object)val2; } if (OdinBeaver.CanConsumeWood.Value) { ItemDrop val3 = CachedWood.Where([<65d0f139-86da-4516-8ef5-5a98f9b5b5c6>NullableContext(0)] (ItemDrop w) => { //IL_0016: Unknown result type (might be due to invalid IL or missing references) //IL_0021: Unknown result type (might be due to invalid IL or missing references) //IL_0026: Unknown result type (might be due to invalid IL or missing references) //IL_002b: Unknown result type (might be due to invalid IL or missing references) int result; if (Object.op_Implicit((Object)(object)w) && ((Component)w).gameObject.activeInHierarchy) { Vector3 val5 = pos - ((Component)w).transform.position; result = ((((Vector3)(ref val5)).sqrMagnitude <= radiusSqr) ? 1 : 0); } else { result = 0; } return (byte)result != 0; }).OrderBy([<65d0f139-86da-4516-8ef5-5a98f9b5b5c6>NullableContext(0)] (ItemDrop w) => { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_000c: Unknown result type (might be due to invalid IL or missing references) //IL_0011: Unknown result type (might be due to invalid IL or missing references) //IL_0016: Unknown result type (might be due to invalid IL or missing references) Vector3 val5 = pos - ((Component)w).transform.position; return ((Vector3)(ref val5)).sqrMagnitude; }).FirstOrDefault(); if (Object.op_Implicit((Object)(object)val3)) { return (Component)(object)val3; } } TreeBase val4 = CachedTrees.Where([<65d0f139-86da-4516-8ef5-5a98f9b5b5c6>NullableContext(0)] (TreeBase t) => { //IL_0016: Unknown result type (might be due to invalid IL or missing references) //IL_0021: Unknown result type (might be due to invalid IL or missing references) //IL_0026: Unknown result type (might be due to invalid IL or missing references) //IL_002b: Unknown result type (might be due to invalid IL or missing references) int result; if (Object.op_Implicit((Object)(object)t) && ((Component)t).gameObject.activeInHierarchy) { Vector3 val5 = pos - ((Component)t).transform.position; result = ((((Vector3)(ref val5)).sqrMagnitude <= radiusSqr) ? 1 : 0); } else { result = 0; } return (byte)result != 0; }).OrderBy([<65d0f139-86da-4516-8ef5-5a98f9b5b5c6>NullableContext(0)] (TreeBase t) => { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_000c: Unknown result type (might be due to invalid IL or missing references) //IL_0011: Unknown result type (might be due to invalid IL or missing references) //IL_0016: Unknown result type (might be due to invalid IL or missing references) Vector3 val5 = pos - ((Component)t).transform.position; return ((Vector3)(ref val5)).sqrMagnitude; }).FirstOrDefault(); if (Object.op_Implicit((Object)(object)val4)) { return (Component)(object)val4; } } return null; } } [<65d0f139-86da-4516-8ef5-5a98f9b5b5c6>NullableContext(1)] [<45ff51f2-9e39-418a-bfbe-416ab42ce92d>Nullable(0)] [HarmonyPatch(typeof(MonsterAI), "UpdateAI")] public static class BeaverAI_UpdateAI_Patch { private static readonly Dictionary memory = new Dictionary(); private const float CleanupInterval = 10f; private static float _nextCleanupTime; private const float ReacquireCooldown = 1.5f; private static bool Prefix(MonsterAI __instance, float dt, ref bool __result) { //IL_05c1: Unknown result type (might be due to invalid IL or missing references) //IL_05c3: Unknown result type (might be due to invalid IL or missing references) //IL_05d8: Unknown result type (might be due to invalid IL or missing references) //IL_05de: Unknown result type (might be due to invalid IL or missing references) //IL_05e3: Unknown result type (might be due to invalid IL or missing references) //IL_05e8: Unknown result type (might be due to invalid IL or missing references) //IL_05ea: Unknown result type (might be due to invalid IL or missing references) //IL_05ec: Unknown result type (might be due to invalid IL or missing references) //IL_0616: Unknown result type (might be due to invalid IL or missing references) //IL_061d: Unknown result type (might be due to invalid IL or missing references) //IL_0631: Unknown result type (might be due to invalid IL or missing references) //IL_0636: Unknown result type (might be due to invalid IL or missing references) //IL_063b: Unknown result type (might be due to invalid IL or missing references) //IL_05fc: Unknown result type (might be due to invalid IL or missing references) //IL_0601: 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_0226: Unknown result type (might be due to invalid IL or missing references) //IL_022b: Unknown result type (might be due to invalid IL or missing references) //IL_036a: Unknown result type (might be due to invalid IL or missing references) //IL_02c0: Unknown result type (might be due to invalid IL or missing references) //IL_0276: Unknown result type (might be due to invalid IL or missing references) //IL_00d8: Unknown result type (might be due to invalid IL or missing references) //IL_0479: Unknown result type (might be due to invalid IL or missing references) //IL_047e: Unknown result type (might be due to invalid IL or missing references) //IL_0141: Unknown result type (might be due to invalid IL or missing references) //IL_014c: Unknown result type (might be due to invalid IL or missing references) //IL_0151: 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_015a: 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_017e: Unknown result type (might be due to invalid IL or missing references) //IL_0183: Unknown result type (might be due to invalid IL or missing references) //IL_0185: Unknown result type (might be due to invalid IL or missing references) //IL_018a: Unknown result type (might be due to invalid IL or missing references) //IL_01a4: 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_01ad: Unknown result type (might be due to invalid IL or missing references) //IL_01b2: Unknown result type (might be due to invalid IL or missing references) //IL_01b7: Unknown result type (might be due to invalid IL or missing references) //IL_04cf: Unknown result type (might be due to invalid IL or missing references) //IL_04d1: Unknown result type (might be due to invalid IL or missing references) //IL_04c6: Unknown result type (might be due to invalid IL or missing references) //IL_04d6: Unknown result type (might be due to invalid IL or missing references) //IL_04d8: Unknown result type (might be due to invalid IL or missing references) //IL_04da: Unknown result type (might be due to invalid IL or missing references) //IL_04dc: Unknown result type (might be due to invalid IL or missing references) //IL_04e1: Unknown result type (might be due to invalid IL or missing references) //IL_01cf: Unknown result type (might be due to invalid IL or missing references) //IL_01da: Unknown result type (might be due to invalid IL or missing references) //IL_069c: Unknown result type (might be due to invalid IL or missing references) //IL_0686: Unknown result type (might be due to invalid IL or missing references) //IL_05b1: Unknown result type (might be due to invalid IL or missing references) //IL_05b6: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)__instance == (Object)null || !((Object)__instance).name.Contains("OP_Beaver")) { return true; } if ((Object)(object)ZNet.instance == (Object)null || !ZNet.instance.IsServer()) { return true; } if (Time.time >= _nextCleanupTime) { _nextCleanupTime = Time.time + 10f; CleanupDeadEntries(); } if (!memory.TryGetValue(__instance, out var value)) { value = new BeaverMemory(); memory[__instance] = value; } Character character = ((BaseAI)__instance).m_character; Humanoid val = (Humanoid)(object)((character is Humanoid) ? character : null); if ((Object)(object)val == (Object)null) { return true; } Player closestPlayer = Player.GetClosestPlayer(((Component)__instance).transform.position, 12f); Vector3 val2; if ((Object)(object)closestPlayer != (Object)null && !((Character)closestPlayer).InGhostMode() && !((Character)closestPlayer).IsDebugFlying() && !value.IsFleeing) { value.IsFleeing = true; value.ReachedFleeDestination = false; value.Target = null; value.HasPlayedAlertSound = true; val2 = ((Component)__instance).transform.position - ((Component)closestPlayer).transform.position; Vector3 normalized = ((Vector3)(ref val2)).normalized; float num = Random.Range(-30f, 30f); normalized = Quaternion.Euler(0f, num, 0f) * normalized; float num2 = Random.Range(30f, 40f); value.FleeDestination = ((Component)__instance).transform.position + normalized * num2; try { EffectList alertedEffects = ((BaseAI)__instance).m_alertedEffects; if (alertedEffects != null) { alertedEffects.Create(((Component)__instance).transform.position, ((Component)__instance).transform.rotation, (Transform)null, 1f, -1); } } catch { } } if (value.IsFleeing) { if (!value.ReachedFleeDestination) { val2 = ((Component)__instance).transform.position - value.FleeDestination; float sqrMagnitude = ((Vector3)(ref val2)).sqrMagnitude; if (sqrMagnitude < 9f) { value.ReachedFleeDestination = true; value.FleeWaitEndTime = Time.time + Random.Range(3f, 6f); ((BaseAI)__instance).StopMoving(); } else { ((BaseAI)__instance).MoveTo(dt, value.FleeDestination, 0f, true); } __result = true; return false; } if (Time.time < value.FleeWaitEndTime) { ((BaseAI)__instance).StopMoving(); __result = true; return false; } Player closestPlayer2 = Player.GetClosestPlayer(((Component)__instance).transform.position, 20f); if ((Object)(object)closestPlayer2 != (Object)null && !((Character)closestPlayer2).InGhostMode() && !((Character)closestPlayer2).IsDebugFlying()) { value.FleeWaitEndTime = Time.time + Random.Range(2f, 4f); __result = true; return false; } value.IsFleeing = false; value.HasPlayedAlertSound = false; value.ReachedFleeDestination = false; value.NextTargetTime = Time.time + 2f; } if (value.Wandering) { if (Time.time < value.WanderEndTime) { ((BaseAI)__instance).MoveTo(dt, value.WanderTarget, 1f, false); __result = true; return false; } value.Wandering = false; value.NextTargetTime = Time.time + OdinBeaver.WaitBetweenTargets.Value; __result = true; return false; } if (Time.time < value.NextTargetTime) { ((BaseAI)__instance).StopMoving(); __result = true; return false; } if (!((Object)(object)value.Target == (Object)null)) { Component target = value.Target; if (target == null || (!((Object)(object)target == (Object)null) && target.gameObject.activeInHierarchy)) { goto IL_045d; } } if (Time.time - value.LastSearchTime > 1.5f) { value.Target = BeaverTargetCache.GetNearestTarget(__instance); value.LastSearchTime = Time.time; value.TargetStartTime = Time.time; value.HasDamagedTarget = false; } goto IL_045d; IL_045d: if ((Object)(object)value.Target != (Object)null) { Vector3 position = ((Component)__instance).transform.position; Collider component = value.Target.GetComponent(); bool flag = (Object)(object)value.Target.GetComponent() != (Object)null; float num3 = (flag ? 1.5f : 2f); Vector3 val3 = (Object.op_Implicit((Object)(object)component) ? component.ClosestPoint(position) : value.Target.transform.position); val2 = position - val3; float sqrMagnitude2 = ((Vector3)(ref val2)).sqrMagnitude; ItemData currentWeapon = val.GetCurrentWeapon(); float num4 = currentWeapon?.m_shared?.m_aiAttackInterval ?? 2f; bool flag2 = currentWeapon != null && Time.time - currentWeapon.m_lastAttackTime > num4; if (!value.HasDamagedTarget && Time.time - value.TargetStartTime > OdinBeaver.FrustrationTime.Value) { try { Component target2 = value.Target; if (target2 != null && (Object)(object)target2 != (Object)null && (Object)(object)target2.gameObject != (Object)null) { value.LastFailedTargetPos = target2.transform.position; } } catch { value.LastFailedTargetPos = position; } value.Target = null; Vector3 val4 = ((Component)__instance).transform.position - value.LastFailedTargetPos; if (val4 == Vector3.zero) { val4 = Random.insideUnitSphere; } val4.y = 0f; value.WanderTarget = ((Component)__instance).transform.position + ((Vector3)(ref val4)).normalized * Random.Range(5f, 10f); value.WanderEndTime = Time.time + Random.Range(5f, 10f); value.Wandering = true; ((BaseAI)__instance).StopMoving(); __result = true; return false; } if (sqrMagnitude2 > num3 * num3) { ((BaseAI)__instance).MoveTo(dt, val3, 1.5f, false); } else { ((BaseAI)__instance).LookAt(val3); if (flag2) { ((Character)val).StartAttack((Character)null, false); value.TargetStartTime = Time.time; value.HasDamagedTarget = true; } if (flag) { Object.Destroy((Object)(object)value.Target.gameObject); value.Target = null; value.NextTargetTime = Time.time + 0.5f; } else { if (!((Object)(object)value.Target == (Object)null)) { Component target3 = value.Target; if (target3 == null || (!((Object)(object)target3 == (Object)null) && target3.gameObject.activeInHierarchy)) { goto IL_0767; } } value.NextTargetTime = Time.time + OdinBeaver.WaitBetweenTargets.Value; value.Target = null; ((BaseAI)__instance).StopMoving(); } } goto IL_0767; } ((BaseAI)__instance).StopMoving(); if (value.IdleAnimTimer == 0f) { value.IdleAnimTimer = Time.time; } if (Time.time - value.IdleAnimTimer > 10f) { value.IdleAnimTimer = Time.time; try { Animator animator = ((Character)val).m_animator; if (animator != null) { animator.SetTrigger("idle"); } } catch { } } __result = true; return false; IL_0767: __result = true; return false; } private static void CleanupDeadEntries() { if (memory.Count == 0) { return; } List list = null; foreach (KeyValuePair item in memory) { MonsterAI key = item.Key; if ((Object)(object)key == (Object)null || (Object)(object)((BaseAI)key).m_character == (Object)null || ((BaseAI)key).m_character.IsDead()) { (list ?? (list = new List())).Add(key); } } if (list == null) { return; } foreach (MonsterAI item2 in list) { memory.Remove(item2); } } } } namespace CreatureManager { public enum Toggle { On, Off } [PublicAPI] public enum GlobalKey { [InternalName("")] None, [InternalName("defeated_bonemass")] KilledBonemass, [InternalName("defeated_gdking")] KilledElder, [InternalName("defeated_goblinking")] KilledYagluth, [InternalName("defeated_dragon")] KilledModer, [InternalName("defeated_eikthyr")] KilledEikthyr, [InternalName("KilledTroll")] KilledTroll, [InternalName("killed_surtling")] KilledSurtling } [PublicAPI] [Flags] public enum Weather { [InternalName("")] None = 0, [InternalName("Clear")] ClearSkies = 1, [InternalName("Heath clear")] MeadowsClearSkies = 4, [InternalName("LightRain")] LightRain = 8, [InternalName("Rain")] Rain = 0x10, [InternalName("ThunderStorm")] ThunderStorm = 0x20, [InternalName("nofogts")] ClearThunderStorm = 0x40, [InternalName("SwampRain")] SwampRain = 0x80, [InternalName("Darklands_dark")] MistlandsDark = 0x100, [InternalName("Ashrain")] AshlandsAshrain = 0x200, [InternalName("Snow")] MountainSnow = 0x400, [InternalName("SnowStorm")] MountainBlizzard = 0x800, [InternalName("DeepForest Mist")] BlackForestFog = 0x1000, [InternalName("Misty")] Fog = 0x2000, [InternalName("Twilight_Snow")] DeepNorthSnow = 0x4000, [InternalName("Twilight_SnowStorm")] DeepNorthSnowStorm = 0x8000, [InternalName("Twilight_Clear")] DeepNorthClear = 0x10000, [InternalName("Eikthyr")] EikthyrsThunderstorm = 0x20000, [InternalName("GDKing")] EldersHaze = 0x40000, [InternalName("Bonemass")] BonemassDownpour = 0x80000, [InternalName("Moder")] ModersVortex = 0x100000, [InternalName("GoblinKing")] YagluthsMagicBlizzard = 0x200000, [InternalName("Crypt")] Crypt = 0x400000, [InternalName("SunkenCrypt")] SunkenCrypt = 0x800000 } [<45ff51f2-9e39-418a-bfbe-416ab42ce92d>Nullable(0)] [<65d0f139-86da-4516-8ef5-5a98f9b5b5c6>NullableContext(1)] public class InternalName : Attribute { public readonly string internalName; public InternalName(string internalName) { this.internalName = internalName; } } public enum DropOption { Disabled, Default, Custom } public enum SpawnOption { Disabled, Default, Custom } public enum SpawnTime { Day, Night, Always } public enum SpawnArea { Center, Edge, Everywhere } public enum Forest { Yes, No, Both } [PublicAPI] public struct Range { public float min; public float max; public Range(float min, float max) { this.min = min; this.max = max; } } [PublicAPI] [<45ff51f2-9e39-418a-bfbe-416ab42ce92d>Nullable(0)] [<65d0f139-86da-4516-8ef5-5a98f9b5b5c6>NullableContext(1)] public class Creature { [PublicAPI] [<45ff51f2-9e39-418a-bfbe-416ab42ce92d>Nullable(0)] public class DropList { [<45ff51f2-9e39-418a-bfbe-416ab42ce92d>Nullable(0)] internal class SerializedDrops { [<45ff51f2-9e39-418a-bfbe-416ab42ce92d>Nullable(new byte[] { 1, 0, 1, 1 })] public readonly List> Drops; public SerializedDrops(DropList drops, Creature creature) { Drops = (drops.drops ?? creature.Prefab.GetComponent()?.m_drops.ToDictionary([<65d0f139-86da-4516-8ef5-5a98f9b5b5c6>NullableContext(0)] (Drop drop) => ((Object)drop.m_prefab).name, [<65d0f139-86da-4516-8ef5-5a98f9b5b5c6>NullableContext(0)] (Drop drop) => new Drop { Amount = new Range(drop.m_amountMin, drop.m_amountMax), DropChance = drop.m_chance, DropOnePerPlayer = drop.m_onePerPlayer, MultiplyDropByLevel = drop.m_levelMultiplier }) ?? new Dictionary()).ToList(); } public SerializedDrops([<45ff51f2-9e39-418a-bfbe-416ab42ce92d>Nullable(new byte[] { 1, 0, 1, 1 })] List> drops) { Drops = drops; } public SerializedDrops(string reqs) { Drops = (from r in reqs.Split(new char[1] { ',' }) select r.Split(new char[1] { ':' })).ToDictionary([<65d0f139-86da-4516-8ef5-5a98f9b5b5c6>NullableContext(0)] (string[] l) => l[0], [<65d0f139-86da-4516-8ef5-5a98f9b5b5c6>NullableContext(0)] (string[] parts) => { Range amount = new Range(1f, 1f); if (parts.Length > 1) { string[] array = parts[1].Split(new char[1] { '-' }); if (!int.TryParse(array[0], out var result)) { result = 1; } if (array.Length == 1 || !int.TryParse(array[0], out var result2)) { result2 = result; } amount = new Range(result, result2); } float result3; return new Drop { Amount = amount, DropChance = ((parts.Length > 2 && float.TryParse(parts[2], out result3)) ? result3 : 100f), DropOnePerPlayer = (parts.Length > 3 && parts[3] == "onePerPlayer"), MultiplyDropByLevel = (parts.Length > 4 && parts[4] == "multiplyByLevel") }; }).ToList(); } public override string ToString() { return string.Join(",", Drops.Select([<65d0f139-86da-4516-8ef5-5a98f9b5b5c6>NullableContext(0)] (KeyValuePair kv) => string.Format("{0}:{1}-{2}:{3}:{4}:{5}", kv.Key, kv.Value.Amount.min, kv.Value.Amount.max, kv.Value.DropChance, kv.Value.DropOnePerPlayer ? "onePerPlayer" : "unrestricted", kv.Value.MultiplyDropByLevel ? "multiplyByLevel" : "unaffectedByLevel"))); } } [<45ff51f2-9e39-418a-bfbe-416ab42ce92d>Nullable(new byte[] { 2, 1, 1 })] private Dictionary drops = null; public Drop this[string prefabName] { get { Drop result; if (!(drops ?? (drops = new Dictionary())).TryGetValue(prefabName, out var value)) { Drop drop = (drops[prefabName] = new Drop()); result = drop; } else { result = value; } return result; } } public void None() { drops = new Dictionary(); } [HarmonyPriority(700)] internal static void AddDropsToCreature() { foreach (Creature registeredCreature in registeredCreatures) { UpdateDrops(registeredCreature); } } internal static void UpdateDrops(Creature creature) { DropOption dropOption = creatureConfigs[creature].Drops.get(); if (dropOption == DropOption.Default && creature.Drops.drops == null) { return; } CharacterDrop val = creature.Prefab.GetComponent() ?? creature.Prefab.AddComponent(); DropOption dropOption2 = creatureConfigs[creature].Drops.get(); if (1 == 0) { } List> source = dropOption2 switch { DropOption.Custom => new SerializedDrops(creatureConfigs[creature].CustomDrops.get()).Drops, DropOption.Disabled => new List>(), _ => creature.Drops.drops.ToList(), }; if (1 == 0) { } val.m_drops = (from d in ((IEnumerable>)source).Select((Func, Drop>)([<65d0f139-86da-4516-8ef5-5a98f9b5b5c6>NullableContext(0)] (KeyValuePair kv) => { //IL_0079: 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_0085: Unknown result type (might be due to invalid IL or missing references) //IL_009d: 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_00cd: Unknown result type (might be due to invalid IL or missing references) //IL_00df: Unknown result type (might be due to invalid IL or missing references) //IL_00f2: Expected O, but got Unknown if (kv.Key == "" || ZNetScene.instance == null) { return (Drop)null; } GameObject prefab = ZNetScene.instance.GetPrefab(kv.Key); if (prefab == null) { Debug.LogWarning((object)("Found invalid prefab name " + kv.Key + " for creature " + ((Object)creature.Prefab).name)); return (Drop)null; } return new Drop { m_prefab = prefab, m_amountMin = (int)kv.Value.Amount.min, m_amountMax = (int)kv.Value.Amount.max, m_chance = kv.Value.DropChance / 100f, m_onePerPlayer = kv.Value.DropOnePerPlayer, m_levelMultiplier = kv.Value.MultiplyDropByLevel }; })) where d != null select d).ToList(); } } [PublicAPI] [<65d0f139-86da-4516-8ef5-5a98f9b5b5c6>NullableContext(0)] public class Drop { public Range Amount = new Range(1f, 1f); public float DropChance = 100f; public bool DropOnePerPlayer = false; public bool MultiplyDropByLevel = true; } [<65d0f139-86da-4516-8ef5-5a98f9b5b5c6>NullableContext(0)] private class CustomConfig<[<45ff51f2-9e39-418a-bfbe-416ab42ce92d>Nullable(2)] T> { [<45ff51f2-9e39-418a-bfbe-416ab42ce92d>Nullable(1)] public Func get = null; [<45ff51f2-9e39-418a-bfbe-416ab42ce92d>Nullable(new byte[] { 2, 1 })] public ConfigEntry config = null; } [<45ff51f2-9e39-418a-bfbe-416ab42ce92d>Nullable(0)] private class CreatureConfig { public readonly CustomConfig Spawn = new CustomConfig(); public readonly CustomConfig CanBeTamed = new CustomConfig(); public readonly CustomConfig ConsumesItemName = new CustomConfig(); public readonly CustomConfig FedDuration = new CustomConfig(); public readonly CustomConfig TamingTime = new CustomConfig(); public readonly CustomConfig SpawnsTamed = new CustomConfig(); public readonly CustomConfig CreatureFaction = new CustomConfig(); public readonly CustomConfig SpecificSpawnTime = new CustomConfig(); public readonly CustomConfig RequiredAltitude = new CustomConfig(); public readonly CustomConfig RequiredOceanDepth = new CustomConfig(); public readonly CustomConfig RequiredGlobalKey = new CustomConfig(); public readonly CustomConfig GroupSize = new CustomConfig(); public readonly CustomConfig Biome = new CustomConfig(); public readonly CustomConfig SpecificSpawnArea = new CustomConfig(); public readonly CustomConfig RequiredWeather = new CustomConfig(); public readonly CustomConfig SpawnAltitude = new CustomConfig(); public readonly CustomConfig CanHaveStars = new CustomConfig(); public readonly CustomConfig AttackImmediately = new CustomConfig(); public readonly CustomConfig CheckSpawnInterval = new CustomConfig(); public readonly CustomConfig SpawnChance = new CustomConfig(); public readonly CustomConfig ForestSpawn = new CustomConfig(); public readonly CustomConfig Maximum = new CustomConfig(); public readonly CustomConfig Drops = new CustomConfig(); public readonly CustomConfig CustomDrops = new CustomConfig(); } [<65d0f139-86da-4516-8ef5-5a98f9b5b5c6>NullableContext(0)] private class ConfigurationManagerAttributes { [UsedImplicitly] public int? Order; [UsedImplicitly] public bool? Browsable; [UsedImplicitly] [<45ff51f2-9e39-418a-bfbe-416ab42ce92d>Nullable(2)] public string Category; [<45ff51f2-9e39-418a-bfbe-416ab42ce92d>Nullable(new byte[] { 2, 1 })] [UsedImplicitly] public Action CustomDrawer; } [<45ff51f2-9e39-418a-bfbe-416ab42ce92d>Nullable(0)] private class AcceptableEnumValues<[<45ff51f2-9e39-418a-bfbe-416ab42ce92d>Nullable(0)] T> : AcceptableValueBase where T : struct, IConvertible { [PublicAPI] [<45ff51f2-9e39-418a-bfbe-416ab42ce92d>Nullable(new byte[] { 1, 0 })] public virtual T[] AcceptableValues { [return: <45ff51f2-9e39-418a-bfbe-416ab42ce92d>Nullable(new byte[] { 1, 0 })] get; } public AcceptableEnumValues([<45ff51f2-9e39-418a-bfbe-416ab42ce92d>Nullable(new byte[] { 1, 0 })] params T[] acceptableValues) : base(typeof(T)) { AcceptableValues = acceptableValues; } public override object Clamp(object value) { return ((AcceptableValueBase)this).IsValid(value) ? value : ((object)AcceptableValues[0]); } public override bool IsValid(object value) { return AcceptableValues.Contains((T)value); } public override string ToDescriptionString() { return string.Join(", ", AcceptableValues); } } public bool ConfigurationEnabled = true; public readonly GameObject Prefab; public DropList Drops = new DropList(); public bool CanSpawn = true; public bool CanBeTamed = false; [Description("List of items the creature consumes to get tame.\nFor multiple item names, separate them with a comma.")] public string FoodItems; [Description("How long the creature remains fed after eating.")] public float FedDuration; [Description("Time it takes to tame the creature.")] public float TamingTime; [Description("If the creature spawns tamed.")] public bool SpawnsTamed; [Description("The creature faction the creature belongs to.")] public Faction CreatureFaction; [Description("Sets the time of day the creature can spawn.")] public SpawnTime SpecificSpawnTime = SpawnTime.Always; [Description("Sets the minimum and maximum altitude for the creature to spawn.")] public Range RequiredAltitude = new Range(5f, 1000f); [Description("Sets the minimum and maximum depth of the ocean for the creature to spawn.")] public Range RequiredOceanDepth = new Range(0f, 0f); [Description("Sets a global key required for the creature to spawn.")] public GlobalKey RequiredGlobalKey = GlobalKey.None; [Description("Sets a range for the group size the creature spawns in.")] public Range GroupSize = new Range(1f, 1f); [Description("Sets the biome the creature spawns in.")] public Biome Biome = (Biome)1; [Description("Sets spawning area for the creature inside the biome.\nUse SpawnArea.Edge, to make the creature spawn more towards the edge of the biome.\nUse SpawnArea.Center, to make the creature spawn more towards the center of the biome.")] public SpawnArea SpecificSpawnArea = SpawnArea.Everywhere; [Description("Sets the weather condition for the creature to spawn.\nUse the Weather enum for easy configuration.")] public Weather RequiredWeather = Weather.None; [Description("Sets altitude relative to the current ground level for the creature to spawn.\nShould be a higher number for flying creatures, so they spawn in the sky.")] public float SpawnAltitude = 0.5f; public bool CanHaveStars = true; [Description("Controls the first AI command right after spawn.\nSet to true for the creature to immediately start to hunt down the player.")] public bool AttackImmediately = false; [Description("The time between attempts to spawn the creature in.")] public int CheckSpawnInterval = 600; [Description("The chance in percent for the creature to spawn, every time Valheim checks if it should spawn.")] public float SpawnChance = 100f; [Description("Can be used to make the creature spawn in forests or prevent it from spawning in forests.\nUse the Forest enum for easy configuration.")] public Forest ForestSpawn = Forest.Both; [Description("Sets the maximum number of the creature that can be near the player, before Valheim disables its spawn.")] public int Maximum = 1; private static readonly List registeredCreatures = new List(); private static Dictionary creatureConfigs = new Dictionary(); [<45ff51f2-9e39-418a-bfbe-416ab42ce92d>Nullable(2)] private static object configManager; private static List lastRegisteredSpawns = new List(); [<45ff51f2-9e39-418a-bfbe-416ab42ce92d>Nullable(2)] private static Localization _english; [<45ff51f2-9e39-418a-bfbe-416ab42ce92d>Nullable(2)] private static BaseUnityPlugin _plugin; private static bool hasConfigSync = true; [<45ff51f2-9e39-418a-bfbe-416ab42ce92d>Nullable(2)] private static object _configSync; private static Localization english => _english ?? (_english = LocalizationCache.ForLanguage("English")); private static BaseUnityPlugin plugin { get { //IL_00a8: Unknown result type (might be due to invalid IL or missing references) //IL_00b2: Expected O, but got Unknown if (_plugin == null) { IEnumerable source; try { source = Assembly.GetExecutingAssembly().DefinedTypes.ToList(); } catch (ReflectionTypeLoadException ex) { source = from t in ex.Types where t != null select t.GetTypeInfo(); } _plugin = (BaseUnityPlugin)Chainloader.ManagerObject.GetComponent((Type)source.First([<65d0f139-86da-4516-8ef5-5a98f9b5b5c6>NullableContext(0)] (TypeInfo t) => t.IsClass && typeof(BaseUnityPlugin).IsAssignableFrom(t))); } return _plugin; } } [<45ff51f2-9e39-418a-bfbe-416ab42ce92d>Nullable(2)] private static object configSync { [<65d0f139-86da-4516-8ef5-5a98f9b5b5c6>NullableContext(2)] get { if (_configSync == null && hasConfigSync) { Type type = Assembly.GetExecutingAssembly().GetType("ServerSync.ConfigSync"); if ((object)type != null) { _configSync = Activator.CreateInstance(type, plugin.Info.Metadata.GUID + " CreatureManager"); type.GetField("CurrentVersion").SetValue(_configSync, plugin.Info.Metadata.Version.ToString()); type.GetProperty("IsLocked").SetValue(_configSync, true); } else { hasConfigSync = false; } } return _configSync; } } public Creature(string assetBundleFileName, string prefabName, string folderName = "assets") : this(PrefabManager.RegisterAssetBundle(assetBundleFileName, folderName), prefabName) { } public Creature(AssetBundle bundle, string prefabName) : this(PrefabManager.RegisterPrefab(bundle, prefabName)) { } public Creature(GameObject creature) { //IL_006f: Unknown result type (might be due to invalid IL or missing references) //IL_014a: 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) Prefab = creature; registeredCreatures.Add(this); Tameable val = default(Tameable); if (creature.TryGetComponent(ref val)) { CanBeTamed = true; FedDuration = val.m_fedDuration; TamingTime = val.m_tamingTime; SpawnsTamed = val.m_startsTamed; } else { CanBeTamed = false; FedDuration = 0f; TamingTime = 0f; SpawnsTamed = false; } Character val2 = default(Character); if (creature.TryGetComponent(ref val2)) { CreatureFaction = val2.m_faction; } FoodItems = string.Join(",", (from i in creature.GetComponent()?.m_consumeItems where Object.op_Implicit((Object)(object)i.m_itemData.m_dropPrefab) select ((Object)i.m_itemData.m_dropPrefab).name) ?? Enumerable.Empty()); } public LocalizeKey Localize() { return new LocalizeKey(Prefab.GetComponent().m_name); } internal static void Patch_FejdStartup() { //IL_0080: Unknown result type (might be due to invalid IL or missing references) //IL_0085: 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_00d6: Expected O, but got Unknown //IL_0287: Unknown result type (might be due to invalid IL or missing references) //IL_0291: Expected O, but got Unknown //IL_02df: Unknown result type (might be due to invalid IL or missing references) //IL_02e9: Expected O, but got Unknown //IL_0337: Unknown result type (might be due to invalid IL or missing references) //IL_0341: Expected O, but got Unknown //IL_038f: Unknown result type (might be due to invalid IL or missing references) //IL_0399: Expected O, but got Unknown //IL_07ba: Unknown result type (might be due to invalid IL or missing references) //IL_07c4: Expected O, but got Unknown Type type = AppDomain.CurrentDomain.GetAssemblies().FirstOrDefault([<65d0f139-86da-4516-8ef5-5a98f9b5b5c6>NullableContext(0)] (Assembly a) => a.GetName().Name == "ConfigurationManager")?.GetType("ConfigurationManager.ConfigurationManager"); configManager = ((type == null) ? null : Chainloader.ManagerObject.GetComponent(type)); if (!TomlTypeConverter.CanConvert(typeof(Range))) { TomlTypeConverter.AddConverter(typeof(Range), new TypeConverter { ConvertToObject = [<65d0f139-86da-4516-8ef5-5a98f9b5b5c6>NullableContext(0)] (string s, Type _) => { Match match = Regex.Match(s, "^(-?\\d+(?:\\.\\d*)?)\\s*-\\s*(-?\\d+(?:\\.\\d*)?)$"); return match.Success ? new Range(float.Parse(match.Groups[1].Value), float.Parse(match.Groups[2].Value)) : default(Range); }, ConvertToString = [<65d0f139-86da-4516-8ef5-5a98f9b5b5c6>NullableContext(0)] (object obj, Type _) => { Range range = (Range)obj; return $"{range.min} - {range.max}"; } }); } bool saveOnConfigSet = plugin.Config.SaveOnConfigSet; plugin.Config.SaveOnConfigSet = false; foreach (Creature registeredCreature in registeredCreatures) { Creature creature = registeredCreature; CreatureConfig creatureConfig = (creatureConfigs[creature] = new CreatureConfig()); CreatureConfig cfg = creatureConfig; string name = creature.Prefab.GetComponent().m_name; string englishName = new Regex("['[\"\\]]").Replace(english.Localize(name), "").Trim(); string localizedName = Localization.instance.Localize(name).Trim(); int order = 0; ConfigurationManagerAttributes tameConfigVisibility = new ConfigurationManagerAttributes(); config(cfg.CanBeTamed, () => (!creature.CanBeTamed) ? Toggle.Off : Toggle.On, delegate { tameConfigVisibility.Browsable = cfg.CanBeTamed.get() == Toggle.On; reloadConfigDisplay(); updateAI(); }, "Can be tamed", "Decides, if the creature can be tamed."); tameConfigVisibility.Browsable = cfg.CanBeTamed.get() == Toggle.On; configWithDesc(cfg.ConsumesItemName, [<65d0f139-86da-4516-8ef5-5a98f9b5b5c6>NullableContext(0)] () => creature.FoodItems, updateAI, "Food items", new ConfigDescription("The items the creature consumes to get tame.", (AcceptableValueBase)null, new object[1] { tameConfigVisibility })); configWithDesc(cfg.FedDuration, () => creature.FedDuration, updateAI, "Fed Duration", new ConfigDescription("How long the creature stays fed after eating, in seconds.", (AcceptableValueBase)null, new object[1] { tameConfigVisibility })); configWithDesc(cfg.TamingTime, () => creature.TamingTime, updateAI, "Time to Tame", new ConfigDescription("The time it takes to tame the creature.", (AcceptableValueBase)null, new object[1] { tameConfigVisibility })); configWithDesc(cfg.SpawnsTamed, () => (!creature.SpawnsTamed) ? Toggle.Off : Toggle.On, updateAI, "Spawns Tamed", new ConfigDescription("If on, the creature spawns tamed.", (AcceptableValueBase)null, new object[1] { tameConfigVisibility })); ConfigurationManagerAttributes spawnConfigVisibility = new ConfigurationManagerAttributes(); ConfigurationManagerAttributes dropConfigVisibility = new ConfigurationManagerAttributes(); config(cfg.Spawn, () => creature.CanSpawn ? SpawnOption.Default : SpawnOption.Disabled, delegate { spawnConfigVisibility.Browsable = cfg.Spawn.get() == SpawnOption.Custom; reloadConfigDisplay(); updateAllSpawnConfigs(); }, "Spawn", "Configures the spawn for the creature."); spawnConfigVisibility.Browsable = cfg.Spawn.get() == SpawnOption.Custom; spawnConfig(cfg.SpecificSpawnTime, () => creature.SpecificSpawnTime, "Spawn time", "Configures the time of day for the creature to spawn."); spawnConfig(cfg.RequiredAltitude, () => creature.RequiredAltitude, "Required altitude", "Configures the altitude required for the creature to spawn."); spawnConfig(cfg.RequiredOceanDepth, () => creature.RequiredOceanDepth, "Required ocean depth", "Configures the ocean depth required for the creature to spawn."); spawnConfig(cfg.RequiredGlobalKey, () => creature.RequiredGlobalKey, "Required global key", "Configures the global key required for the creature to spawn."); spawnConfig(cfg.GroupSize, () => creature.GroupSize, "Group size", "Configures the size of the groups in which the creature spawns."); spawnConfig(cfg.Biome, () => creature.Biome, "Biome", "Configures the biome required for the creature to spawn."); spawnConfig(cfg.SpecificSpawnArea, () => creature.SpecificSpawnArea, "Spawn area", "Configures if the creature spawns more towards the center or the edge of the biome."); spawnConfig(cfg.RequiredWeather, () => creature.RequiredWeather, "Required weather", "Configures the weather required for the creature to spawn."); spawnConfig(cfg.SpawnAltitude, () => creature.SpawnAltitude, "Spawn altitude", "Configures the height from the ground in which the creature will spawn."); spawnConfig(cfg.CanHaveStars, () => (!creature.CanHaveStars) ? Toggle.Off : Toggle.On, "Can have stars", "If the creature can have stars."); spawnConfig(cfg.AttackImmediately, () => (!creature.AttackImmediately) ? Toggle.Off : Toggle.On, "Hunt player", "Makes the creature immediately hunt down the player after it spawns."); spawnConfig(cfg.CheckSpawnInterval, () => creature.CheckSpawnInterval, "Maximum spawn interval", "Configures the timespan that Valheim has to make the creature spawn."); spawnConfig(cfg.SpawnChance, () => creature.SpawnChance, "Spawn chance", "Sets the chance for the creature to be spawned, every time Valheim checks the spawn."); spawnConfig(cfg.ForestSpawn, () => creature.ForestSpawn, "Forest condition", "If the creature can spawn in forests or cannot spawn in forests. Or both."); spawnConfig(cfg.Maximum, () => creature.Maximum, "Maximum creature count", "The maximum number of this creature near the player, before Valheim stops spawning it in. Setting this lower than the upper limit of the group size does not make sense."); config(cfg.Drops, () => DropOption.Default, delegate { dropConfigVisibility.Browsable = cfg.Drops.get() == DropOption.Custom; reloadConfigDisplay(); DropList.UpdateDrops(creature); }, "Drops", "Configures the drops for the creature."); dropConfigVisibility.Browsable = cfg.Drops.get() == DropOption.Custom; configWithDesc(cfg.CustomDrops, [<65d0f139-86da-4516-8ef5-5a98f9b5b5c6>NullableContext(0)] () => new DropList.SerializedDrops(creature.Drops, creature).ToString(), delegate { DropList.UpdateDrops(creature); }, "Drop config", new ConfigDescription("", (AcceptableValueBase)null, new object[1] { dropConfigVisibility })); config(cfg.CreatureFaction, () => creature.CreatureFaction, updateCharacterAttributes, "Creature Faction", "The creature faction the creature belongs to."); void config([<45ff51f2-9e39-418a-bfbe-416ab42ce92d>Nullable(new byte[] { 1, 0 })] CustomConfig customConfig, [<45ff51f2-9e39-418a-bfbe-416ab42ce92d>Nullable(new byte[] { 1, 0 })] Func getter, Action configChanged, string name2, string desc) { //IL_000e: Unknown result type (might be due to invalid IL or missing references) //IL_0018: Expected O, but got Unknown configWithDesc(customConfig, getter, configChanged, name2, new ConfigDescription(desc, (AcceptableValueBase)null, Array.Empty())); } void configWithDesc([<45ff51f2-9e39-418a-bfbe-416ab42ce92d>Nullable(new byte[] { 1, 0 })] CustomConfig customConfig, [<45ff51f2-9e39-418a-bfbe-416ab42ce92d>Nullable(new byte[] { 1, 0 })] Func getter, Action configChanged, string name2, ConfigDescription desc) { //IL_00e9: Unknown result type (might be due to invalid IL or missing references) //IL_00f3: Expected O, but got Unknown if (creature.ConfigurationEnabled) { customConfig.config = pluginConfig(englishName, name2, getter(), new ConfigDescription(desc.Description, desc.AcceptableValues, desc.Tags.Concat(new ConfigurationManagerAttributes[1] { new ConfigurationManagerAttributes { Order = (order -= 1), CustomDrawer = (((object)customConfig == cfg.CustomDrops) ? new Action(drawConfigTable) : ((typeof(T) == typeof(Range)) ? new Action(drawRange) : null)), Category = localizedName } }).ToArray())); customConfig.config.SettingChanged += [<65d0f139-86da-4516-8ef5-5a98f9b5b5c6>NullableContext(0)] (object _, EventArgs _) => { configChanged(); }; customConfig.get = [<65d0f139-86da-4516-8ef5-5a98f9b5b5c6>NullableContext(0)] () => customConfig.config.Value; } else { customConfig.get = getter; } } void spawnConfig([<45ff51f2-9e39-418a-bfbe-416ab42ce92d>Nullable(new byte[] { 1, 0 })] CustomConfig customConfig, [<45ff51f2-9e39-418a-bfbe-416ab42ce92d>Nullable(new byte[] { 1, 0 })] Func getter, string name2, string desc, [<45ff51f2-9e39-418a-bfbe-416ab42ce92d>Nullable(2)] AcceptableValueBase acceptableValues = null) { //IL_0028: Unknown result type (might be due to invalid IL or missing references) //IL_0032: Expected O, but got Unknown configWithDesc(customConfig, getter, updateAllSpawnConfigs, name2, new ConfigDescription(desc, acceptableValues, new object[1] { spawnConfigVisibility })); } void updateAI() { if (Object.op_Implicit((Object)(object)ObjectDB.instance)) { BaseAI[] array = Object.FindObjectsOfType(); foreach (BaseAI ai in array) { creature.updateAi(ai); } creature.updateAi(creature.Prefab.GetComponent()); } } void updateAllSpawnConfigs() { SpawnSystem[] array = Object.FindObjectsOfType(); foreach (SpawnSystem val in array) { foreach (SpawnSystemList spawnList in val.m_spawnLists) { foreach (SpawnData spawner in spawnList.m_spawners) { if ((Object)(object)creature.Prefab == (Object)(object)spawner.m_prefab) { creature.updateSpawnData(spawner); } } } } } void updateCharacterAttributes() { if (Object.op_Implicit((Object)(object)ObjectDB.instance)) { creature.updateCharacterAttributes(creature.Prefab.GetComponent()); } } } if (saveOnConfigSet) { plugin.Config.SaveOnConfigSet = true; plugin.Config.Save(); } static void reloadConfigDisplay() { if (configManager?.GetType().GetProperty("DisplayingWindow").GetValue(configManager) is int num && num != 0) { configManager.GetType().GetMethod("BuildSettingList").Invoke(configManager, Array.Empty()); } } } private static void drawRange(ConfigEntryBase cfg) { //IL_00aa: Unknown result type (might be due to invalid IL or missing references) //IL_00af: Unknown result type (might be due to invalid IL or missing references) //IL_00c5: Expected O, but got Unknown bool valueOrDefault = cfg.Description.Tags.Select([<65d0f139-86da-4516-8ef5-5a98f9b5b5c6>NullableContext(0)] (object a) => (a.GetType().Name == "ConfigurationManagerAttributes") ? ((bool?)a.GetType().GetField("ReadOnly")?.GetValue(a)) : ((bool?)null)).FirstOrDefault((bool? v) => v.HasValue) == true; ConfigEntry val = (ConfigEntry)(object)cfg; GUILayout.BeginHorizontal(Array.Empty()); float.TryParse(GUILayout.TextField(val.Value.min.ToString(CultureInfo.InvariantCulture), Array.Empty()), out var result); GUILayout.Label(" - ", new GUIStyle(GUI.skin.label) { fixedWidth = 14f }, Array.Empty()); float.TryParse(GUILayout.TextField(val.Value.max.ToString(CultureInfo.InvariantCulture), Array.Empty()), out var result2); GUILayout.EndHorizontal(); if (!valueOrDefault && (Math.Abs(val.Value.min - result) > 1E-05f || Math.Abs(val.Value.max - result2) > 1E-05f)) { val.Value = new Range(result, result2); } } private static void drawConfigTable(ConfigEntryBase cfg) { //IL_0117: Unknown result type (might be due to invalid IL or missing references) //IL_011c: Unknown result type (might be due to invalid IL or missing references) //IL_0132: Expected O, but got Unknown //IL_0165: Unknown result type (might be due to invalid IL or missing references) //IL_016a: Unknown result type (might be due to invalid IL or missing references) //IL_0180: Expected O, but got Unknown //IL_01aa: Unknown result type (might be due to invalid IL or missing references) //IL_01af: Unknown result type (might be due to invalid IL or missing references) //IL_01c5: Expected O, but got Unknown //IL_01f8: Unknown result type (might be due to invalid IL or missing references) //IL_01fd: Unknown result type (might be due to invalid IL or missing references) //IL_0213: Expected O, but got Unknown //IL_0225: Unknown result type (might be due to invalid IL or missing references) //IL_022a: Unknown result type (might be due to invalid IL or missing references) //IL_024f: Expected O, but got Unknown //IL_0285: Unknown result type (might be due to invalid IL or missing references) //IL_028a: Unknown result type (might be due to invalid IL or missing references) //IL_02a0: Expected O, but got Unknown //IL_02e0: Unknown result type (might be due to invalid IL or missing references) //IL_02e5: Unknown result type (might be due to invalid IL or missing references) //IL_02fb: Expected O, but got Unknown //IL_0366: Unknown result type (might be due to invalid IL or missing references) //IL_0375: Expected O, but got Unknown //IL_03b7: Unknown result type (might be due to invalid IL or missing references) //IL_03c6: Expected O, but got Unknown //IL_03f6: Unknown result type (might be due to invalid IL or missing references) //IL_03fb: Unknown result type (might be due to invalid IL or missing references) //IL_03fd: Unknown result type (might be due to invalid IL or missing references) //IL_0404: Unknown result type (might be due to invalid IL or missing references) //IL_0415: Unknown result type (might be due to invalid IL or missing references) //IL_0485: Unknown result type (might be due to invalid IL or missing references) //IL_048a: Unknown result type (might be due to invalid IL or missing references) //IL_04a0: Expected O, but got Unknown bool valueOrDefault = cfg.Description.Tags.Select([<65d0f139-86da-4516-8ef5-5a98f9b5b5c6>NullableContext(0)] (object a) => (a.GetType().Name == "ConfigurationManagerAttributes") ? ((bool?)a.GetType().GetField("ReadOnly")?.GetValue(a)) : ((bool?)null)).FirstOrDefault((bool? v) => v.HasValue) == true; List> list = new List>(); bool flag = false; int num = (int)(configManager?.GetType().GetProperty("RightColumnWidth", BindingFlags.Instance | BindingFlags.NonPublic).GetGetMethod(nonPublic: true) .Invoke(configManager, Array.Empty()) ?? ((object)130)); GUILayout.BeginVertical(Array.Empty()); foreach (KeyValuePair drop in new DropList.SerializedDrops((string)cfg.BoxedValue).Drops) { GUILayout.BeginHorizontal(Array.Empty()); int num2 = Mathf.RoundToInt(drop.Value.Amount.min); if (int.TryParse(GUILayout.TextField(num2.ToString(), new GUIStyle(GUI.skin.textField) { fixedWidth = 35f }, Array.Empty()), out var result) && result != num2 && !valueOrDefault) { num2 = result; flag = true; } GUILayout.Label(" - ", new GUIStyle(GUI.skin.label) { fixedWidth = 14f }, Array.Empty()); int num3 = Mathf.RoundToInt(drop.Value.Amount.max); if (int.TryParse(GUILayout.TextField(num3.ToString(), new GUIStyle(GUI.skin.textField) { fixedWidth = 35f }, Array.Empty()), out var result2) && result2 != num3 && !valueOrDefault) { num3 = result2; flag = true; } GUILayout.Label(" ", new GUIStyle(GUI.skin.label) { fixedWidth = 10f }, Array.Empty()); string text = GUILayout.TextField(drop.Key, new GUIStyle(GUI.skin.textField) { fixedWidth = num - 35 - 14 - 35 - 10 - 21 - 18 }, Array.Empty()); string text2 = (valueOrDefault ? drop.Key : text); flag = flag || text2 != drop.Key; bool flag2 = GUILayout.Button("x", new GUIStyle(GUI.skin.button) { fixedWidth = 21f }, Array.Empty()) && !valueOrDefault; GUILayout.EndHorizontal(); GUILayout.BeginHorizontal(Array.Empty()); float num4 = drop.Value.DropChance; if (float.TryParse(GUILayout.TextField(num4.ToString(CultureInfo.InvariantCulture), new GUIStyle(GUI.skin.textField) { fixedWidth = 45f }, Array.Empty()), out var result3) && Math.Abs(result3 - num4) > 1E-05f && !valueOrDefault) { num4 = result3; flag = true; } GUILayout.Label("% ", Array.Empty()); string tooltip = GUI.tooltip; bool flag3 = drop.Value.MultiplyDropByLevel; bool flag4 = GUILayout.Toggle(flag3, new GUIContent(flag3 ? "per level" : "fixed", "Loot is multiplied by the creature's level."), Array.Empty()); if (flag4 != flag3 && !valueOrDefault) { flag3 = flag4; flag = true; } bool flag5 = drop.Value.DropOnePerPlayer; bool flag6 = GUILayout.Toggle(flag5, new GUIContent(flag5 ? "per player" : "independent", "Drops one per player."), Array.Empty()); if (flag6 != flag5 && !valueOrDefault) { flag5 = flag6; flag = true; } if (GUI.tooltip != tooltip) { Vector3 mousePosition = Input.mousePosition; GUI.Label(new Rect(mousePosition.x, mousePosition.y, 100f, 35f), GUI.tooltip); } if (flag2) { flag = true; } else { Drop value = new Drop { Amount = new Range(num2, num3), DropChance = num4, MultiplyDropByLevel = flag3, DropOnePerPlayer = flag5 }; list.Add(new KeyValuePair(text2, value)); } if (GUILayout.Button("+", new GUIStyle(GUI.skin.button) { fixedWidth = 21f }, Array.Empty()) && !valueOrDefault) { flag = true; list.Add(new KeyValuePair("", new Drop())); } GUILayout.EndHorizontal(); } GUILayout.EndVertical(); if (flag) { cfg.BoxedValue = new DropList.SerializedDrops(list).ToString(); } } private void updateAi(BaseAI ai) { CreatureConfig creatureConfig = creatureConfigs[this]; if (Object.op_Implicit((Object)(object)((Component)ai).GetComponent()) != (creatureConfig.CanBeTamed.get() == Toggle.On)) { if (creatureConfig.CanBeTamed.get() == Toggle.On) { ai.m_tamable = ((Component)ai).gameObject.AddComponent(); } else { Object.Destroy((Object)(object)ai.m_tamable); ai.m_tamable = null; } } Tameable tamable = ai.m_tamable; if (tamable != null) { tamable.m_fedDuration = creatureConfig.FedDuration.get(); tamable.m_tamingTime = creatureConfig.TamingTime.get(); tamable.m_startsTamed = creatureConfig.SpawnsTamed.get() == Toggle.On; } MonsterAI val = (MonsterAI)(object)((ai is MonsterAI) ? ai : null); if (val == null) { return; } val.m_consumeItems.Clear(); string[] array = creatureConfig.ConsumesItemName.get().Split(new char[1] { ',' }); string[] array2 = array; foreach (string text in array2) { GameObject itemPrefab = ObjectDB.instance.GetItemPrefab(text.Trim()); ItemDrop val2 = ((itemPrefab != null) ? itemPrefab.GetComponent() : null); if (val2 != null) { val.m_consumeItems.Add(val2); } } } private void updateCharacterAttributes(Character character) { //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) CreatureConfig creatureConfig = creatureConfigs[this]; character.m_faction = creatureConfig.CreatureFaction.get(); } internal static void UpdateCreatureAis(ObjectDB __instance) { foreach (Creature registeredCreature in registeredCreatures) { registeredCreature.updateAi(registeredCreature.Prefab.GetComponent()); registeredCreature.updateCharacterAttributes(registeredCreature.Prefab.GetComponent()); } } private void updateSpawnData(SpawnData spawnData) { //IL_0047: Unknown result type (might be due to invalid IL or missing references) //IL_004c: Unknown result type (might be due to invalid IL or missing references) //IL_0079: 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_008a: 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_0081: Unknown result type (might be due to invalid IL or missing references) CreatureConfig cfg = creatureConfigs[this]; spawnData.m_enabled = cfg.Spawn.get() != SpawnOption.Disabled; spawnData.m_biome = cfg.Biome.get(); SpawnArea spawnArea = cfg.SpecificSpawnArea.get(); if (1 == 0) { } BiomeArea biomeArea = (BiomeArea)(spawnArea switch { SpawnArea.Center => 2, SpawnArea.Edge => 1, _ => 3, }); if (1 == 0) { } spawnData.m_biomeArea = biomeArea; spawnData.m_maxSpawned = cfg.Maximum.get(); spawnData.m_spawnInterval = cfg.CheckSpawnInterval.get(); spawnData.m_spawnChance = cfg.SpawnChance.get(); spawnData.m_requiredGlobalKey = ((InternalName)typeof(GlobalKey).GetMember(cfg.RequiredGlobalKey.get().ToString())[0].GetCustomAttributes(typeof(InternalName)).First()).internalName; spawnData.m_requiredEnvironments = (from Weather w in Enum.GetValues(typeof(Weather)) where (w & cfg.RequiredWeather.get()) != 0 select ((InternalName)typeof(Weather).GetMember(w.ToString())[0].GetCustomAttributes(typeof(InternalName)).First()).internalName).ToList(); spawnData.m_groupSizeMin = (int)cfg.GroupSize.get().min; spawnData.m_groupSizeMax = (int)cfg.GroupSize.get().max; SpawnTime spawnTime = cfg.SpecificSpawnTime.get(); bool spawnAtNight = (uint)(spawnTime - 1) <= 1u; spawnData.m_spawnAtNight = spawnAtNight; spawnTime = cfg.SpecificSpawnTime.get(); spawnAtNight = ((spawnTime == SpawnTime.Day || spawnTime == SpawnTime.Always) ? true : false); spawnData.m_spawnAtDay = spawnAtNight; spawnData.m_minAltitude = cfg.RequiredAltitude.get().min; spawnData.m_maxAltitude = cfg.RequiredAltitude.get().max; Forest forest = cfg.ForestSpawn.get(); spawnAtNight = ((forest == Forest.Yes || forest == Forest.Both) ? true : false); spawnData.m_inForest = spawnAtNight; forest = cfg.ForestSpawn.get(); spawnAtNight = (uint)(forest - 1) <= 1u; spawnData.m_outsideForest = spawnAtNight; spawnData.m_minOceanDepth = cfg.RequiredOceanDepth.get().min; spawnData.m_maxOceanDepth = cfg.RequiredOceanDepth.get().max; spawnData.m_huntPlayer = cfg.AttackImmediately.get() == Toggle.On; spawnData.m_groundOffset = cfg.SpawnAltitude.get(); spawnData.m_maxLevel = ((cfg.CanHaveStars.get() != Toggle.On) ? 1 : 3); } [HarmonyPriority(700)] internal static void AddToSpawnSystem(SpawnSystem __instance) { //IL_006f: Unknown result type (might be due to invalid IL or missing references) //IL_0074: 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_0095: Expected O, but got Unknown SpawnSystemList val = __instance.m_spawnLists.First(); foreach (SpawnData lastRegisteredSpawn in lastRegisteredSpawns) { val.m_spawners.Remove(lastRegisteredSpawn); } lastRegisteredSpawns.Clear(); foreach (Creature registeredCreature in registeredCreatures) { SpawnData val2 = new SpawnData { m_name = ((Object)registeredCreature.Prefab).name, m_prefab = registeredCreature.Prefab }; registeredCreature.updateSpawnData(val2); lastRegisteredSpawns.Add(val2); val.m_spawners.Add(val2); } } private static ConfigEntry pluginConfig<[<45ff51f2-9e39-418a-bfbe-416ab42ce92d>Nullable(2)] T>(string group, string name, T value, ConfigDescription description) { ConfigEntry val = plugin.Config.Bind(group, name, value, description); configSync?.GetType().GetMethod("AddConfigEntry").MakeGenericMethod(typeof(T)) .Invoke(configSync, new object[1] { val }); return val; } private static ConfigEntry pluginConfig<[<45ff51f2-9e39-418a-bfbe-416ab42ce92d>Nullable(2)] T>(string group, string name, T value, string description) { //IL_000a: Unknown result type (might be due to invalid IL or missing references) //IL_0014: Expected O, but got Unknown return pluginConfig(group, name, value, new ConfigDescription(description, (AcceptableValueBase)null, Array.Empty())); } } [PublicAPI] [<45ff51f2-9e39-418a-bfbe-416ab42ce92d>Nullable(0)] [<65d0f139-86da-4516-8ef5-5a98f9b5b5c6>NullableContext(1)] public class LocalizeKey { private static readonly List keys = new List(); public readonly string Key; public readonly Dictionary Localizations = new Dictionary(); public LocalizeKey(string key) { Key = key.Replace("$", ""); keys.Add(this); } public void Alias(string alias) { Localizations.Clear(); if (!alias.Contains("$")) { alias = "$" + alias; } Localizations["alias"] = alias; if (Localization.m_instance != null) { Localization.instance.AddWord(Key, Localization.instance.Localize(alias)); } } public LocalizeKey English(string key) { return addForLang("English", key); } public LocalizeKey Swedish(string key) { return addForLang("Swedish", key); } public LocalizeKey French(string key) { return addForLang("French", key); } public LocalizeKey Italian(string key) { return addForLang("Italian", key); } public LocalizeKey German(string key) { return addForLang("German", key); } public LocalizeKey Spanish(string key) { return addForLang("Spanish", key); } public LocalizeKey Russian(string key) { return addForLang("Russian", key); } public LocalizeKey Romanian(string key) { return addForLang("Romanian", key); } public LocalizeKey Bulgarian(string key) { return addForLang("Bulgarian", key); } public LocalizeKey Macedonian(string key) { return addForLang("Macedonian", key); } public LocalizeKey Finnish(string key) { return addForLang("Finnish", key); } public LocalizeKey Danish(string key) { return addForLang("Danish", key); } public LocalizeKey Norwegian(string key) { return addForLang("Norwegian", key); } public LocalizeKey Icelandic(string key) { return addForLang("Icelandic", key); } public LocalizeKey Turkish(string key) { return addForLang("Turkish", key); } public LocalizeKey Lithuanian(string key) { return addForLang("Lithuanian", key); } public LocalizeKey Czech(string key) { return addForLang("Czech", key); } public LocalizeKey Hungarian(string key) { return addForLang("Hungarian", key); } public LocalizeKey Slovak(string key) { return addForLang("Slovak", key); } public LocalizeKey Polish(string key) { return addForLang("Polish", key); } public LocalizeKey Dutch(string key) { return addForLang("Dutch", key); } public LocalizeKey Portuguese_European(string key) { return addForLang("Portuguese_European", key); } public LocalizeKey Portuguese_Brazilian(string key) { return addForLang("Portuguese_Brazilian", key); } public LocalizeKey Chinese(string key) { return addForLang("Chinese", key); } public LocalizeKey Japanese(string key) { return addForLang("Japanese", key); } public LocalizeKey Korean(string key) { return addForLang("Korean", key); } public LocalizeKey Hindi(string key) { return addForLang("Hindi", key); } public LocalizeKey Thai(string key) { return addForLang("Thai", key); } public LocalizeKey Abenaki(string key) { return addForLang("Abenaki", key); } public LocalizeKey Croatian(string key) { return addForLang("Croatian", key); } public LocalizeKey Georgian(string key) { return addForLang("Georgian", key); } public LocalizeKey Greek(string key) { return addForLang("Greek", key); } public LocalizeKey Serbian(string key) { return addForLang("Serbian", key); } public LocalizeKey Ukrainian(string key) { return addForLang("Ukrainian", key); } private LocalizeKey addForLang(string lang, string value) { Localizations[lang] = value; if (Localization.m_instance != null) { if (Localization.instance.GetSelectedLanguage() == lang) { Localization.instance.AddWord(Key, value); } else if (lang == "English" && !Localization.instance.m_translations.ContainsKey(Key)) { Localization.instance.AddWord(Key, value); } } return this; } [HarmonyPriority(300)] internal static void AddLocalizedKeys(Localization __instance, string language) { foreach (LocalizeKey key in keys) { string value2; if (key.Localizations.TryGetValue(language, out var value) || key.Localizations.TryGetValue("English", out value)) { __instance.AddWord(key.Key, value); } else if (key.Localizations.TryGetValue("alias", out value2)) { __instance.AddWord(key.Key, Localization.instance.Localize(value2)); } } } } [<45ff51f2-9e39-418a-bfbe-416ab42ce92d>Nullable(0)] [<65d0f139-86da-4516-8ef5-5a98f9b5b5c6>NullableContext(1)] public static class LocalizationCache { private static readonly Dictionary localizations = new Dictionary(); internal static void LocalizationPostfix(Localization __instance, string language) { string key = localizations.FirstOrDefault([<65d0f139-86da-4516-8ef5-5a98f9b5b5c6>NullableContext(0)] (KeyValuePair l) => l.Value == __instance).Key; if (key != null) { localizations.Remove(key); } if (!localizations.ContainsKey(language)) { localizations.Add(language, __instance); } } public static Localization ForLanguage([<45ff51f2-9e39-418a-bfbe-416ab42ce92d>Nullable(2)] string language = null) { //IL_002a: Unknown result type (might be due to invalid IL or missing references) //IL_0030: Expected O, but got Unknown if (localizations.TryGetValue(language ?? PlayerPrefs.GetString("language", "English"), out var value)) { return value; } value = new Localization(); if (language != null) { value.SetupLanguage(language); } return value; } } [<45ff51f2-9e39-418a-bfbe-416ab42ce92d>Nullable(0)] [<65d0f139-86da-4516-8ef5-5a98f9b5b5c6>NullableContext(1)] public static class PrefabManager { [<45ff51f2-9e39-418a-bfbe-416ab42ce92d>Nullable(0)] private struct BundleId { [UsedImplicitly] public string assetBundleFileName; [UsedImplicitly] public string folderName; } private static readonly Dictionary bundleCache; private static readonly List prefabs; static PrefabManager() { //IL_001a: Unknown result type (might be due to invalid IL or missing references) //IL_0020: Expected O, but got Unknown //IL_004d: Unknown result type (might be due to invalid IL or missing references) //IL_005b: Expected O, but got Unknown //IL_008a: Unknown result type (might be due to invalid IL or missing references) //IL_0097: Expected O, but got Unknown //IL_00c6: Unknown result type (might be due to invalid IL or missing references) //IL_00d3: Expected O, but got Unknown //IL_0102: Unknown result type (might be due to invalid IL or missing references) //IL_010f: Expected O, but got Unknown //IL_013e: Unknown result type (might be due to invalid IL or missing references) //IL_014b: Expected O, but got Unknown //IL_017a: Unknown result type (might be due to invalid IL or missing references) //IL_0187: Expected O, but got Unknown //IL_01b6: Unknown result type (might be due to invalid IL or missing references) //IL_01c3: Expected O, but got Unknown //IL_023d: Unknown result type (might be due to invalid IL or missing references) //IL_024a: Expected O, but got Unknown bundleCache = new Dictionary(); prefabs = new List(); Harmony val = new Harmony("org.bepinex.helpers.CreatureManager"); val.Patch((MethodBase)AccessTools.DeclaredMethod(typeof(ZNetScene), "Awake", (Type[])null, (Type[])null), new HarmonyMethod(AccessTools.DeclaredMethod(typeof(PrefabManager), "Patch_ZNetSceneAwake", (Type[])null, (Type[])null)), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null); val.Patch((MethodBase)AccessTools.DeclaredMethod(typeof(ZNetScene), "Awake", (Type[])null, (Type[])null), (HarmonyMethod)null, new HarmonyMethod(AccessTools.DeclaredMethod(typeof(Creature.DropList), "AddDropsToCreature", (Type[])null, (Type[])null)), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null); val.Patch((MethodBase)AccessTools.DeclaredMethod(typeof(SpawnSystem), "Awake", (Type[])null, (Type[])null), (HarmonyMethod)null, new HarmonyMethod(AccessTools.DeclaredMethod(typeof(Creature), "AddToSpawnSystem", (Type[])null, (Type[])null)), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null); val.Patch((MethodBase)AccessTools.DeclaredMethod(typeof(ObjectDB), "Awake", (Type[])null, (Type[])null), (HarmonyMethod)null, new HarmonyMethod(AccessTools.DeclaredMethod(typeof(Creature), "UpdateCreatureAis", (Type[])null, (Type[])null)), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null); val.Patch((MethodBase)AccessTools.DeclaredMethod(typeof(FejdStartup), "Awake", (Type[])null, (Type[])null), (HarmonyMethod)null, new HarmonyMethod(AccessTools.DeclaredMethod(typeof(Creature), "Patch_FejdStartup", (Type[])null, (Type[])null)), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null); val.Patch((MethodBase)AccessTools.DeclaredMethod(typeof(Localization), "LoadCSV", (Type[])null, (Type[])null), (HarmonyMethod)null, new HarmonyMethod(AccessTools.DeclaredMethod(typeof(LocalizeKey), "AddLocalizedKeys", (Type[])null, (Type[])null)), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null); val.Patch((MethodBase)AccessTools.DeclaredMethod(typeof(Localization), "SetupLanguage", (Type[])null, (Type[])null), (HarmonyMethod)null, new HarmonyMethod(AccessTools.DeclaredMethod(typeof(LocalizationCache), "LocalizationPostfix", (Type[])null, (Type[])null)), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null); if (!typeof(Biome).GetCustomAttributes(typeof(FlagsAttribute), inherit: false).Any()) { val.Patch((MethodBase)AccessTools.Method(typeof(Biome).GetType(), "GetCustomAttributes", new Type[2] { typeof(Type), typeof(bool) }, (Type[])null), (HarmonyMethod)null, new HarmonyMethod(AccessTools.DeclaredMethod(typeof(PrefabManager), "BiomeIsFlags", (Type[])null, (Type[])null)), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null); } } private static void BiomeIsFlags(Type __instance, Type attributeType, ref object[] __result) { if (__instance == typeof(Biome) && attributeType == typeof(FlagsAttribute)) { __result = new object[1] { new FlagsAttribute() }; } } public static AssetBundle RegisterAssetBundle(string assetBundleFileName, string folderName = "assets") { BundleId key = new BundleId { assetBundleFileName = assetBundleFileName, folderName = folderName }; if (!bundleCache.TryGetValue(key, out var value)) { Dictionary dictionary = bundleCache; AssetBundle? obj = ((IEnumerable)Resources.FindObjectsOfTypeAll()).FirstOrDefault((Func)([<65d0f139-86da-4516-8ef5-5a98f9b5b5c6>NullableContext(0)] (AssetBundle a) => ((Object)a).name == assetBundleFileName)) ?? AssetBundle.LoadFromStream(Assembly.GetExecutingAssembly().GetManifestResourceStream(Assembly.GetExecutingAssembly().GetName().Name + "." + folderName + "." + assetBundleFileName)); AssetBundle result = obj; dictionary[key] = obj; return result; } return value; } public static GameObject RegisterPrefab(AssetBundle assets, string prefabName) { GameObject val = assets.LoadAsset(prefabName); prefabs.Add(val); return val; } [HarmonyPriority(700)] private static void Patch_ZNetSceneAwake(ZNetScene __instance) { foreach (GameObject prefab in prefabs) { __instance.m_prefabs.Add(prefab); } } } public static class CreatureManagerVersion { [<45ff51f2-9e39-418a-bfbe-416ab42ce92d>Nullable(1)] public const string Version = "1.12.0"; } } namespace Microsoft.CodeAnalysis { [CompilerGenerated] [<01eb7e26-4928-40cb-b28b-10fac3ca7f63>Embedded] internal sealed class <01eb7e26-4928-40cb-b28b-10fac3ca7f63>EmbeddedAttribute : Attribute { } } namespace System.Runtime.CompilerServices { [CompilerGenerated] [<01eb7e26-4928-40cb-b28b-10fac3ca7f63>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; } } [<01eb7e26-4928-40cb-b28b-10fac3ca7f63>Embedded] [AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Method | AttributeTargets.Interface | AttributeTargets.Delegate, AllowMultiple = false, Inherited = false)] [CompilerGenerated] internal sealed class <658e6c10-0eb1-4251-85c8-d4e55dbcb4e3>NullableContextAttribute : Attribute { public readonly byte Flag; public <658e6c10-0eb1-4251-85c8-d4e55dbcb4e3>NullableContextAttribute(byte P_0) { Flag = P_0; } } [<01eb7e26-4928-40cb-b28b-10fac3ca7f63>Embedded] [AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)] [CompilerGenerated] internal sealed class <806dd5b2-9e56-4f22-9e18-0e21cdfdcfe4>RefSafetyRulesAttribute : Attribute { public readonly int Version; public <806dd5b2-9e56-4f22-9e18-0e21cdfdcfe4>RefSafetyRulesAttribute(int P_0) { Version = P_0; } } } namespace ItemManager { [PublicAPI] internal enum CraftingTable { Disabled, Inventory, [InternalName("piece_workbench")] Workbench, [InternalName("piece_cauldron")] Cauldron, [InternalName("piece_MeadCauldron")] MeadCauldron, [InternalName("forge")] Forge, [InternalName("piece_artisanstation")] ArtisanTable, [InternalName("piece_stonecutter")] StoneCutter, [InternalName("piece_magetable")] MageTable, [InternalName("piece_preptable")] PrepTable, [InternalName("blackforge")] BlackForge, Custom } [PublicAPI] internal enum ConversionPiece { Disabled, [InternalName("smelter")] Smelter, [InternalName("charcoal_kiln")] CharcoalKiln, [InternalName("blastfurnace")] BlastFurnace, [InternalName("windmill")] Windmill, [InternalName("piece_spinningwheel")] SpinningWheel, [InternalName("eitrrefinery")] EitrRefinery, Custom } [Nullable(0)] [<658e6c10-0eb1-4251-85c8-d4e55dbcb4e3>NullableContext(1)] internal class InternalName : Attribute { public readonly string internalName; public InternalName(string internalName) { this.internalName = internalName; } } [PublicAPI] [Nullable(0)] [<658e6c10-0eb1-4251-85c8-d4e55dbcb4e3>NullableContext(1)] internal class RequiredResourceList { public readonly List Requirements = new List(); public bool Free; public void Add(string itemName, int amount, int quality = 0) { Requirements.Add(new Requirement { itemName = itemName, amount = amount, quality = quality }); } public void Add(string itemName, ConfigEntry amountConfig, int quality = 0) { Requirements.Add(new Requirement { itemName = itemName, amountConfig = amountConfig, quality = quality }); } } [PublicAPI] [Nullable(0)] [<658e6c10-0eb1-4251-85c8-d4e55dbcb4e3>NullableContext(1)] internal class CraftingStationList { public readonly List Stations = new List(); public void Add(CraftingTable table, int level) { Stations.Add(new CraftingStationConfig { Table = table, level = level }); } public void Add(string customTable, int level) { Stations.Add(new CraftingStationConfig { Table = CraftingTable.Custom, level = level, custom = customTable }); } } [Nullable(0)] [<658e6c10-0eb1-4251-85c8-d4e55dbcb4e3>NullableContext(1)] [PublicAPI] internal class ItemRecipe { public readonly RequiredResourceList RequiredItems = new RequiredResourceList(); public readonly RequiredResourceList RequiredUpgradeItems = new RequiredResourceList(); public readonly CraftingStationList Crafting = new CraftingStationList(); public int CraftAmount = 1; public bool RequireOnlyOneIngredient; public float QualityResultAmountMultiplier = 1f; [Nullable(2)] public ConfigEntryBase RecipeIsActive; } [PublicAPI] internal class Trade { public Trader Trader; public uint Price; public uint Stack = 1u; [Nullable(2)] public string RequiredGlobalKey; } [PublicAPI] [Flags] internal enum Trader { None = 0, Haldor = 1, Hildir = 2 } internal struct Requirement { [Nullable(1)] public string itemName; public int amount; [Nullable(2)] public ConfigEntry amountConfig; [Description("Set to a non-zero value to apply the requirement only for a specific quality")] public int quality; } internal struct CraftingStationConfig { public CraftingTable Table; public int level; [Nullable(2)] public string custom; } [Flags] internal enum Configurability { Disabled = 0, Recipe = 1, Stats = 2, Drop = 4, Trader = 8, Full = 0xF } [<658e6c10-0eb1-4251-85c8-d4e55dbcb4e3>NullableContext(1)] [PublicAPI] [Nullable(0)] internal class DropTargets { public readonly List Drops = new List(); public void Add(string creatureName, float chance, int min = 1, int? max = null, bool levelMultiplier = true) { Drops.Add(new DropTarget { creature = creatureName, chance = chance, min = min, max = (max ?? min), levelMultiplier = levelMultiplier }); } } internal struct DropTarget { [Nullable(1)] public string creature; public int min; public int max; public float chance; public bool levelMultiplier; } internal enum Toggle { On = 1, Off = 0 } [Nullable(0)] [<658e6c10-0eb1-4251-85c8-d4e55dbcb4e3>NullableContext(1)] [PublicAPI] internal class Item { [Nullable(0)] private class ItemConfig { [Nullable(new byte[] { 2, 1 })] public ConfigEntry craft; [Nullable(new byte[] { 2, 1 })] public ConfigEntry upgrade; public ConfigEntry table; public ConfigEntry tableLevel; public ConfigEntry customTable; [Nullable(2)] public ConfigEntry maximumTableLevel; public ConfigEntry requireOneIngredient; public ConfigEntry qualityResultAmountMultiplier; } [Nullable(0)] private class TraderConfig { public ConfigEntry trader; public ConfigEntry price; public ConfigEntry stack; public ConfigEntry requiredGlobalKey; } [<658e6c10-0eb1-4251-85c8-d4e55dbcb4e3>NullableContext(0)] private class RequirementQuality { public int quality; } [<658e6c10-0eb1-4251-85c8-d4e55dbcb4e3>NullableContext(2)] [Nullable(0)] private class ConfigurationManagerAttributes { [UsedImplicitly] public int? Order; [UsedImplicitly] public bool? Browsable; [UsedImplicitly] public string Category; [UsedImplicitly] [Nullable(new byte[] { 2, 1 })] public Action CustomDrawer; public Func browsability; } [<658e6c10-0eb1-4251-85c8-d4e55dbcb4e3>NullableContext(0)] [PublicAPI] public enum DamageModifier { Normal, Resistant, Weak, Immune, Ignore, VeryResistant, VeryWeak, None } [<658e6c10-0eb1-4251-85c8-d4e55dbcb4e3>NullableContext(0)] private delegate void setDmgFunc(ref DamageTypes dmg, float value); [Nullable(0)] private class SerializedRequirements { public readonly List Reqs; public SerializedRequirements(List reqs) { Reqs = reqs; } public SerializedRequirements(string reqs) : this(reqs.Split(new char[1] { ',' }).Select([<658e6c10-0eb1-4251-85c8-d4e55dbcb4e3>NullableContext(0)] (string r) => { string[] array = r.Split(new char[1] { ':' }); int result; int result2; return new Requirement { itemName = array[0], amount = ((array.Length <= 1 || !int.TryParse(array[1], out result)) ? 1 : result), quality = ((array.Length > 2 && int.TryParse(array[2], out result2)) ? result2 : 0) }; }).ToList()) { } public override string ToString() { return string.Join(",", Reqs.Select([<658e6c10-0eb1-4251-85c8-d4e55dbcb4e3>NullableContext(0)] (Requirement r) => $"{r.itemName}:{r.amount}" + ((r.quality > 0) ? $":{r.quality}" : ""))); } [return: Nullable(2)] public static ItemDrop fetchByName(ObjectDB objectDB, string name) { GameObject itemPrefab = objectDB.GetItemPrefab(name); ItemDrop obj = ((itemPrefab != null) ? itemPrefab.GetComponent() : null); if ((Object)(object)obj == (Object)null) { Debug.LogWarning((object)("The required item '" + name + "' does not exist.")); } return obj; } public static Requirement[] toPieceReqs(ObjectDB objectDB, SerializedRequirements craft, SerializedRequirements upgrade) { //IL_00f0: 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_00fd: Unknown result type (might be due to invalid IL or missing references) //IL_0178: Unknown result type (might be due to invalid IL or missing references) //IL_017d: Unknown result type (might be due to invalid IL or missing references) //IL_0185: Unknown result type (might be due to invalid IL or missing references) //IL_018c: Unknown result type (might be due to invalid IL or missing references) //IL_018f: Expected O, but got Unknown //IL_0194: Expected O, but got Unknown //IL_011c: Unknown result type (might be due to invalid IL or missing references) //IL_0125: Expected O, but got Unknown Dictionary dictionary = craft.Reqs.Where((Requirement r) => r.itemName != "").ToDictionary((Func)([<658e6c10-0eb1-4251-85c8-d4e55dbcb4e3>NullableContext(0)] (Requirement r) => r.itemName), (Func)([<658e6c10-0eb1-4251-85c8-d4e55dbcb4e3>NullableContext(0)] (Requirement r) => { //IL_000d: Unknown result type (might be due to invalid IL or missing references) //IL_0012: Unknown result type (might be due to invalid IL or missing references) //IL_002f: Unknown result type (might be due to invalid IL or missing references) //IL_0036: Unknown result type (might be due to invalid IL or missing references) //IL_003e: Expected O, but got Unknown ItemDrop val6 = ResItem(r); return (val6 != null) ? new Requirement { m_amount = (r.amountConfig?.Value ?? r.amount), m_resItem = val6, m_amountPerLevel = 0 } : ((Requirement)null); })); List list = dictionary.Values.Where([<658e6c10-0eb1-4251-85c8-d4e55dbcb4e3>NullableContext(0)] (Requirement v) => v != null).ToList(); foreach (Requirement item in upgrade.Reqs.Where((Requirement r) => r.itemName != "")) { if (item.quality > 0) { ItemDrop val = ResItem(item); if (val != null) { Requirement val2 = new Requirement { m_resItem = val, m_amountPerLevel = (item.amountConfig?.Value ?? item.amount), m_amount = 0 }; list.Add(val2); requirementQuality.Add(val2, new RequirementQuality { quality = item.quality }); } continue; } if (!dictionary.TryGetValue(item.itemName, out var value) || value == null) { ItemDrop val3 = ResItem(item); if (val3 != null) { string itemName = item.itemName; Requirement val4 = new Requirement { m_resItem = val3, m_amount = 0 }; Requirement val5 = val4; dictionary[itemName] = val4; value = val5; list.Add(value); } } if (value != null) { value.m_amountPerLevel = item.amountConfig?.Value ?? item.amount; } } return list.ToArray(); [<658e6c10-0eb1-4251-85c8-d4e55dbcb4e3>NullableContext(2)] ItemDrop ResItem(Requirement r) { return fetchByName(objectDB, r.itemName); } } } [Nullable(0)] private class SerializedDrop { public readonly List Drops; public SerializedDrop(List drops) { Drops = drops; } public SerializedDrop(string drops) { Drops = ((drops == "") ? ((IEnumerable)Array.Empty()) : ((IEnumerable)drops.Split(new char[1] { ',' }))).Select([<658e6c10-0eb1-4251-85c8-d4e55dbcb4e3>NullableContext(0)] (string r) => { string[] array = r.Split(new char[1] { ':' }); if (array.Length <= 2 || !int.TryParse(array[2], out var result)) { result = 1; } if (array.Length <= 3 || !int.TryParse(array[3], out var result2)) { result2 = result; } bool levelMultiplier = array.Length <= 4 || array[4] != "0"; float result3; return new DropTarget { creature = array[0], chance = ((array.Length > 1 && float.TryParse(array[1], out result3)) ? result3 : 1f), min = result, max = result2, levelMultiplier = levelMultiplier }; }).ToList(); } public override string ToString() { return string.Join(",", Drops.Select([<658e6c10-0eb1-4251-85c8-d4e55dbcb4e3>NullableContext(0)] (DropTarget r) => $"{r.creature}:{r.chance.ToString(CultureInfo.InvariantCulture)}:{r.min}:" + ((r.min == r.max) ? "" : $"{r.max}") + (r.levelMultiplier ? "" : ":0"))); } [return: Nullable(2)] private static Character fetchByName(ZNetScene netScene, string name) { GameObject prefab = netScene.GetPrefab(name); Character obj = ((prefab != null) ? prefab.GetComponent() : null); if ((Object)(object)obj == (Object)null) { Debug.LogWarning((object)("The drop target character '" + name + "' does not exist.")); } return obj; } public Dictionary toCharacterDrops(ZNetScene netScene, GameObject item) { //IL_002e: Unknown result type (might be due to invalid IL or missing references) //IL_0033: Unknown result type (might be due to invalid IL or missing references) //IL_003a: Unknown result type (might be due to invalid IL or missing references) //IL_0046: Unknown result type (might be due to invalid IL or missing references) //IL_0052: Unknown result type (might be due to invalid IL or missing references) //IL_005e: Unknown result type (might be due to invalid IL or missing references) //IL_006f: Expected O, but got Unknown Dictionary dictionary = new Dictionary(); foreach (DropTarget drop in Drops) { Character val = fetchByName(netScene, drop.creature); if (val != null) { dictionary[val] = new Drop { m_prefab = item, m_amountMin = drop.min, m_amountMax = drop.max, m_chance = drop.chance, m_levelMultiplier = drop.levelMultiplier }; } } return dictionary; } } private static readonly List registeredItems = new List(); private static readonly Dictionary itemDropMap = new Dictionary(); private static Dictionary>> activeRecipes = new Dictionary>>(); [Nullable(new byte[] { 1, 1, 2 })] private static Dictionary hiddenCraftRecipes = new Dictionary(); [Nullable(new byte[] { 1, 1, 2 })] private static Dictionary hiddenUpgradeRecipes = new Dictionary(); private static Dictionary> itemCraftConfigs = new Dictionary>(); private static Dictionary> itemDropConfigs = new Dictionary>(); private Dictionary characterDrops = new Dictionary(); private readonly Dictionary statsConfigs = new Dictionary(); private static readonly ConditionalWeakTable requirementQuality = new ConditionalWeakTable(); public static Configurability DefaultConfigurability = Configurability.Full; public Configurability? Configurable; private Configurability configurationVisible = Configurability.Full; [Nullable(2)] private TraderConfig traderConfig; public readonly GameObject Prefab; [Description("Specifies the maximum required crafting station level to upgrade and repair the item.\nDefault is calculated from crafting station level and maximum quality.")] public int MaximumRequiredStationLevel = int.MaxValue; [Description("Assigns the item as a drop item to a creature.\nUses a creature name, a drop chance and a minimum and maximum amount.")] public readonly DropTargets DropsFrom = new DropTargets(); [Description("Configures whether the item can be bought at the trader.\nDon't forget to set cost to something above 0 or the item will be sold for free.")] public readonly Trade Trade = new Trade(); internal List Conversions = new List(); internal List conversions = new List(); public Dictionary Recipes = new Dictionary(); [Nullable(2)] private LocalizeKey _name; [Nullable(2)] private LocalizeKey _description; [Nullable(2)] private static object configManager; [Nullable(2)] private static Localization _english; [Nullable(2)] private static BaseUnityPlugin _plugin; private static bool hasConfigSync = true; [Nullable(2)] private static object _configSync; private Configurability configurability => Configurable ?? DefaultConfigurability; [Description("Specifies the resources needed to craft the item.\nUse .Add to add resources with their internal ID and an amount.\nUse one .Add for each resource type the item should need.")] public RequiredResourceList RequiredItems => this[""].RequiredItems; [Description("Specifies the resources needed to upgrade the item.\nUse .Add to add resources with their internal ID and an amount. This amount will be multipled by the item quality level.\nUse one .Add for each resource type the upgrade should need.")] public RequiredResourceList RequiredUpgradeItems => this[""].RequiredUpgradeItems; [Description("Specifies the crafting station needed to craft the item.\nUse .Add to add a crafting station, using the CraftingTable enum and a minimum level for the crafting station.\nUse one .Add for each crafting station.")] public CraftingStationList Crafting => this[""].Crafting; [Description("Specifies a config entry which toggles whether a recipe is active.")] [Nullable(2)] public ConfigEntryBase RecipeIsActive { [<658e6c10-0eb1-4251-85c8-d4e55dbcb4e3>NullableContext(2)] get { return this[""].RecipeIsActive; } [<658e6c10-0eb1-4251-85c8-d4e55dbcb4e3>NullableContext(2)] set { this[""].RecipeIsActive = value; } } [Description("Specifies the number of items that should be given to the player with a single craft of the item.\nDefaults to 1.")] public int CraftAmount { get { return this[""].CraftAmount; } set { this[""].CraftAmount = value; } } public bool RequireOnlyOneIngredient { get { return this[""].RequireOnlyOneIngredient; } set { this[""].RequireOnlyOneIngredient = value; } } public float QualityResultAmountMultiplier { get { return this[""].QualityResultAmountMultiplier; } set { this[""].QualityResultAmountMultiplier = value; } } public ItemRecipe this[string name] { get { if (Recipes.TryGetValue(name, out var value)) { return value; } return Recipes[name] = new ItemRecipe(); } } public LocalizeKey Name { get { LocalizeKey name = _name; if (name != null) { return name; } SharedData shared = Prefab.GetComponent().m_itemData.m_shared; if (shared.m_name.StartsWith("$")) { _name = new LocalizeKey(shared.m_name); } else { string text = "$item_" + ((Object)Prefab).name.Replace(" ", "_"); _name = new LocalizeKey(text).English(shared.m_name); shared.m_name = text; } return _name; } } public LocalizeKey Description { get { LocalizeKey description = _description; if (description != null) { return description; } SharedData shared = Prefab.GetComponent().m_itemData.m_shared; if (shared.m_description.StartsWith("$")) { _description = new LocalizeKey(shared.m_description); } else { string text = "$itemdesc_" + ((Object)Prefab).name.Replace(" ", "_"); _description = new LocalizeKey(text).English(shared.m_description); shared.m_description = text; } return _description; } } private static Localization english => _english ?? (_english = LocalizationCache.ForLanguage("English")); private static BaseUnityPlugin plugin { get { //IL_009b: Unknown result type (might be due to invalid IL or missing references) //IL_00a5: Expected O, but got Unknown if (_plugin == null) { IEnumerable source; try { source = Assembly.GetExecutingAssembly().DefinedTypes.ToList(); } catch (ReflectionTypeLoadException ex) { source = from t in ex.Types where t != null select t.GetTypeInfo(); } _plugin = (BaseUnityPlugin)Chainloader.ManagerObject.GetComponent((Type)source.First([<658e6c10-0eb1-4251-85c8-d4e55dbcb4e3>NullableContext(0)] (TypeInfo t) => t.IsClass && typeof(BaseUnityPlugin).IsAssignableFrom(t))); } return _plugin; } } [Nullable(2)] private static object configSync { [<658e6c10-0eb1-4251-85c8-d4e55dbcb4e3>NullableContext(2)] get { if (_configSync == null && hasConfigSync) { Type type = Assembly.GetExecutingAssembly().GetType("ServerSync.ConfigSync"); if ((object)type != null) { _configSync = Activator.CreateInstance(type, plugin.Info.Metadata.GUID + " ItemManager"); type.GetField("CurrentVersion").SetValue(_configSync, plugin.Info.Metadata.Version.ToString()); type.GetProperty("IsLocked").SetValue(_configSync, true); } else { hasConfigSync = false; } } return _configSync; } } public Item(string assetBundleFileName, string prefabName, string folderName = "assets") : this(PrefabManager.RegisterAssetBundle(assetBundleFileName, folderName), prefabName) { } public Item(AssetBundle bundle, string prefabName) : this(PrefabManager.RegisterPrefab(bundle, prefabName, addToObjectDb: true), skipRegistering: true) { } public Item(GameObject prefab, bool skipRegistering = false) { if (!skipRegistering) { PrefabManager.RegisterPrefab(prefab, addToObjectDb: true); } Prefab = prefab; registeredItems.Add(this); itemDropMap[Prefab.GetComponent()] = this; Prefab.GetComponent().m_itemData.m_dropPrefab = Prefab; } public void ToggleConfigurationVisibility(Configurability visible) { configurationVisible = visible; if (itemDropConfigs.TryGetValue(this, out var value)) { Toggle((ConfigEntryBase)(object)value, Configurability.Drop); } if (itemCraftConfigs.TryGetValue(this, out var value2)) { foreach (ItemConfig value4 in value2.Values) { ToggleObj(value4, Configurability.Recipe); } } foreach (Conversion conversion in Conversions) { if (conversion.config != null) { ToggleObj(conversion.config, Configurability.Recipe); } } foreach (KeyValuePair statsConfig in statsConfigs) { Toggle(statsConfig.Key, Configurability.Stats); if ((visible & Configurability.Stats) != Configurability.Disabled) { statsConfig.Value(); } } reloadConfigDisplay(); void Toggle(ConfigEntryBase cfg, Configurability check) { object[] tags = cfg.Description.Tags; for (int i = 0; i < tags.Length; i++) { if (tags[i] is ConfigurationManagerAttributes configurationManagerAttributes) { configurationManagerAttributes.Browsable = (visible & check) != Configurability.Disabled && (configurationManagerAttributes.browsability == null || configurationManagerAttributes.browsability()); } } } void ToggleObj(object obj, Configurability check) { FieldInfo[] fields = obj.GetType().GetFields(); for (int i = 0; i < fields.Length; i++) { object? value3 = fields[i].GetValue(obj); ConfigEntryBase val = (ConfigEntryBase)((value3 is ConfigEntryBase) ? value3 : null); if (val != null) { Toggle(val, check); } } } } internal static void reloadConfigDisplay() { object obj = configManager?.GetType().GetProperty("DisplayingWindow").GetValue(configManager); if (obj is bool && (bool)obj) { configManager.GetType().GetMethod("BuildSettingList").Invoke(configManager, Array.Empty()); } } private void UpdateItemTableConfig(string recipeKey, CraftingTable table, string customTableValue) { if (activeRecipes.ContainsKey(this) && activeRecipes[this].TryGetValue(recipeKey, out var value)) { value.First().m_enabled = table != CraftingTable.Disabled; if ((uint)table <= 1u) { value.First().m_craftingStation = null; } else if (table == CraftingTable.Custom) { Recipe obj = value.First(); GameObject prefab = ZNetScene.instance.GetPrefab(customTableValue); obj.m_craftingStation = ((prefab != null) ? prefab.GetComponent() : null); } else { value.First().m_craftingStation = ZNetScene.instance.GetPrefab(getInternalName(table)).GetComponent(); } } } private void UpdateCraftConfig(string recipeKey, SerializedRequirements craftRequirements, SerializedRequirements upgradeRequirements) { if (!Object.op_Implicit((Object)(object)ObjectDB.instance) || !activeRecipes.ContainsKey(this) || !activeRecipes[this].TryGetValue(recipeKey, out var value)) { return; } foreach (Recipe item in value) { item.m_resources = SerializedRequirements.toPieceReqs(ObjectDB.instance, craftRequirements, upgradeRequirements); } } internal static void Patch_FejdStartup() { //IL_0e99: Unknown result type (might be due to invalid IL or missing references) //IL_0e9e: Unknown result type (might be due to invalid IL or missing references) //IL_2164: Unknown result type (might be due to invalid IL or missing references) //IL_216e: Expected O, but got Unknown //IL_0f62: Unknown result type (might be due to invalid IL or missing references) //IL_0f65: Unknown result type (might be due to invalid IL or missing references) //IL_0fbb: Expected I4, but got Unknown //IL_0b88: Unknown result type (might be due to invalid IL or missing references) //IL_0b92: Expected O, but got Unknown //IL_030b: Unknown result type (might be due to invalid IL or missing references) //IL_0315: Expected O, but got Unknown //IL_10ef: Unknown result type (might be due to invalid IL or missing references) //IL_10f2: Unknown result type (might be due to invalid IL or missing references) //IL_10f4: Invalid comparison between Unknown and I4 //IL_10f6: Unknown result type (might be due to invalid IL or missing references) //IL_10fa: Invalid comparison between Unknown and I4 //IL_0cab: Unknown result type (might be due to invalid IL or missing references) //IL_0cb5: Expected O, but got Unknown //IL_0d56: Unknown result type (might be due to invalid IL or missing references) //IL_0d60: Expected O, but got Unknown //IL_10fc: Unknown result type (might be due to invalid IL or missing references) //IL_1100: Invalid comparison between Unknown and I4 //IL_03fe: Unknown result type (might be due to invalid IL or missing references) //IL_0408: Expected O, but got Unknown //IL_0e0a: Unknown result type (might be due to invalid IL or missing references) //IL_0e14: Expected O, but got Unknown //IL_12fb: Unknown result type (might be due to invalid IL or missing references) //IL_12fe: Unknown result type (might be due to invalid IL or missing references) //IL_1300: Invalid comparison between Unknown and I4 //IL_1302: Unknown result type (might be due to invalid IL or missing references) //IL_1306: Unknown result type (might be due to invalid IL or missing references) //IL_1308: Invalid comparison between Unknown and I4 //IL_0539: Unknown result type (might be due to invalid IL or missing references) //IL_0543: Expected O, but got Unknown //IL_130a: Unknown result type (might be due to invalid IL or missing references) //IL_130e: Invalid comparison between Unknown and I4 //IL_13e3: Unknown result type (might be due to invalid IL or missing references) //IL_13e8: Unknown result type (might be due to invalid IL or missing references) //IL_13ea: Unknown result type (might be due to invalid IL or missing references) //IL_13ed: Invalid comparison between Unknown and I4 //IL_13ef: Unknown result type (might be due to invalid IL or missing references) //IL_13f3: Invalid comparison between Unknown and I4 //IL_06f0: Unknown result type (might be due to invalid IL or missing references) //IL_06fa: Expected O, but got Unknown //IL_0651: Unknown result type (might be due to invalid IL or missing references) //IL_065b: Expected O, but got Unknown //IL_1462: Unknown result type (might be due to invalid IL or missing references) //IL_1465: Unknown result type (might be due to invalid IL or missing references) //IL_1467: Invalid comparison between Unknown and I4 //IL_07fa: Unknown result type (might be due to invalid IL or missing references) //IL_0804: Expected O, but got Unknown //IL_1469: Unknown result type (might be due to invalid IL or missing references) //IL_146d: Unknown result type (might be due to invalid IL or missing references) //IL_146f: Invalid comparison between Unknown and I4 //IL_1471: Unknown result type (might be due to invalid IL or missing references) //IL_1475: Invalid comparison between Unknown and I4 //IL_15b2: Unknown result type (might be due to invalid IL or missing references) //IL_15b5: Invalid comparison between Unknown and I4 //IL_17b2: Unknown result type (might be due to invalid IL or missing references) //IL_17b9: Invalid comparison between Unknown and I4 //IL_1882: Unknown result type (might be due to invalid IL or missing references) //IL_1887: Unknown result type (might be due to invalid IL or missing references) //IL_1889: Unknown result type (might be due to invalid IL or missing references) //IL_188d: Unknown result type (might be due to invalid IL or missing references) //IL_188f: Invalid comparison between Unknown and I4 //IL_18fe: Unknown result type (might be due to invalid IL or missing references) //IL_1901: Unknown result type (might be due to invalid IL or missing references) //IL_1903: Invalid comparison between Unknown and I4 //IL_1528: Unknown result type (might be due to invalid IL or missing references) //IL_152d: Unknown result type (might be due to invalid IL or missing references) //IL_1905: Unknown result type (might be due to invalid IL or missing references) //IL_1909: Invalid comparison between Unknown and I4 //IL_190b: Unknown result type (might be due to invalid IL or missing references) //IL_190f: Invalid comparison between Unknown and I4 //IL_1d7c: Unknown result type (might be due to invalid IL or missing references) //IL_1d7f: Invalid comparison between Unknown and I4 Type type = AppDomain.CurrentDomain.GetAssemblies().FirstOrDefault([<658e6c10-0eb1-4251-85c8-d4e55dbcb4e3>NullableContext(0)] (Assembly a) => a.GetName().Name == "ConfigurationManager")?.GetType("ConfigurationManager.ConfigurationManager"); if (DefaultConfigurability != Configurability.Disabled) { bool saveOnConfigSet = plugin.Config.SaveOnConfigSet; plugin.Config.SaveOnConfigSet = false; foreach (Item item3 in registeredItems.Where([<658e6c10-0eb1-4251-85c8-d4e55dbcb4e3>NullableContext(0)] (Item i) => i.configurability != Configurability.Disabled)) { Item item = item3; string name = item.Prefab.GetComponent().m_itemData.m_shared.m_name; string englishName = new Regex("[=\\n\\t\\\\\"\\'\\[\\]]*").Replace(english.Localize(name), "").Trim(); string localizedName = Localization.instance.Localize(name).Trim(); int order = 0; if ((item.configurability & Configurability.Recipe) != Configurability.Disabled) { itemCraftConfigs[item] = new Dictionary(); foreach (string item4 in item.Recipes.Keys.DefaultIfEmpty("")) { string configKey = item4; string text = ((configKey == "") ? "" : (" (" + configKey + ")")); if (!item.Recipes.ContainsKey(configKey) || item.Recipes[configKey].Crafting.Stations.Count <= 0) { continue; } ItemConfig itemConfig = (itemCraftConfigs[item][configKey] = new ItemConfig()); ItemConfig cfg = itemConfig; List hideWhenNoneAttributes = new List(); cfg.table = config(englishName, "Crafting Station" + text, item.Recipes[configKey].Crafting.Stations.First().Table, new ConfigDescription("Crafting station where " + englishName + " is available.", (AcceptableValueBase)null, new object[1] { new ConfigurationManagerAttributes { Order = (order -= 1), Browsable = ((item.configurationVisible & Configurability.Recipe) != 0), Category = localizedName } })); ConfigurationManagerAttributes customTableAttributes = new ConfigurationManagerAttributes { Order = (order -= 1), browsability = CustomTableBrowsability, Browsable = (CustomTableBrowsability() && (item.configurationVisible & Configurability.Recipe) != 0), Category = localizedName }; cfg.customTable = config(englishName, "Custom Crafting Station" + text, item.Recipes[configKey].Crafting.Stations.First().custom ?? "", new ConfigDescription("", (AcceptableValueBase)null, new object[1] { customTableAttributes })); cfg.table.SettingChanged += TableConfigChanged; cfg.customTable.SettingChanged += TableConfigChanged; ConfigurationManagerAttributes configurationManagerAttributes = new ConfigurationManagerAttributes { Order = (order -= 1), browsability = TableLevelBrowsability, Browsable = (TableLevelBrowsability() && (item.configurationVisible & Configurability.Recipe) != 0), Category = localizedName }; hideWhenNoneAttributes.Add(configurationManagerAttributes); cfg.tableLevel = config(englishName, "Crafting Station Level" + text, item.Recipes[configKey].Crafting.Stations.First().level, new ConfigDescription("Required crafting station level to craft " + englishName + ".", (AcceptableValueBase)null, new object[1] { configurationManagerAttributes })); cfg.tableLevel.SettingChanged += [<658e6c10-0eb1-4251-85c8-d4e55dbcb4e3>NullableContext(0)] (object _, EventArgs _) => { if (activeRecipes.ContainsKey(item) && activeRecipes[item].TryGetValue(configKey, out var value)) { value.First().m_minStationLevel = cfg.tableLevel.Value; } }; if (item.Prefab.GetComponent().m_itemData.m_shared.m_maxQuality > 1) { cfg.maximumTableLevel = config(englishName, "Maximum Crafting Station Level" + text, (item.MaximumRequiredStationLevel == int.MaxValue) ? (item.Recipes[configKey].Crafting.Stations.First().level + item.Prefab.GetComponent().m_itemData.m_shared.m_maxQuality - 1) : item.MaximumRequiredStationLevel, new ConfigDescription("Maximum crafting station level to upgrade and repair " + englishName + ".", (AcceptableValueBase)null, new object[1] { configurationManagerAttributes })); } cfg.requireOneIngredient = config(englishName, "Require only one resource" + text, item.Recipes[configKey].RequireOnlyOneIngredient ? Toggle.On : Toggle.Off, new ConfigDescription("Whether only one of the ingredients is needed to craft " + englishName, (AcceptableValueBase)null, new object[1] { new ConfigurationManagerAttributes { Order = (order -= 1), Category = localizedName } })); ConfigurationManagerAttributes qualityResultAttributes = new ConfigurationManagerAttributes { Order = (order -= 1), browsability = QualityResultBrowsability, Browsable = (QualityResultBrowsability() && (item.configurationVisible & Configurability.Recipe) != 0), Category = localizedName }; cfg.requireOneIngredient.SettingChanged += [<658e6c10-0eb1-4251-85c8-d4e55dbcb4e3>NullableContext(0)] (object _, EventArgs _) => { if (activeRecipes.ContainsKey(item) && activeRecipes[item].TryGetValue(configKey, out var value)) { foreach (Recipe item5 in value) { item5.m_requireOnlyOneIngredient = cfg.requireOneIngredient.Value == Toggle.On; } } qualityResultAttributes.Browsable = QualityResultBrowsability(); reloadConfigDisplay(); }; cfg.qualityResultAmountMultiplier = config(englishName, "Quality Multiplier" + text, item.Recipes[configKey].QualityResultAmountMultiplier, new ConfigDescription("Multiplies the crafted amount based on the quality of the resources when crafting " + englishName + ". Only works, if Require Only One Resource is true.", (AcceptableValueBase)null, new object[1] { qualityResultAttributes })); cfg.qualityResultAmountMultiplier.SettingChanged += [<658e6c10-0eb1-4251-85c8-d4e55dbcb4e3>NullableContext(0)] (object _, EventArgs _) => { if (activeRecipes.ContainsKey(item) && activeRecipes[item].TryGetValue(configKey, out var value)) { foreach (Recipe item6 in value) { item6.m_qualityResultAmountMultiplier = cfg.qualityResultAmountMultiplier.Value; } } }; if ((!item.Recipes[configKey].RequiredItems.Free || item.Recipes[configKey].RequiredItems.Requirements.Count > 0) && item.Recipes[configKey].RequiredItems.Requirements.All((Requirement r) => r.amountConfig == null)) { cfg.craft = itemConfig3("Crafting Costs" + text, new SerializedRequirements(item.Recipes[configKey].RequiredItems.Requirements).ToString(), "Item costs to craft " + englishName, isUpgrade: false); } if (item.Prefab.GetComponent().m_itemData.m_shared.m_maxQuality > 1 && (!item.Recipes[configKey].RequiredUpgradeItems.Free || item.Recipes[configKey].RequiredUpgradeItems.Requirements.Count > 0) && item.Recipes[configKey].RequiredUpgradeItems.Requirements.All((Requirement r) => r.amountConfig == null)) { cfg.upgrade = itemConfig3("Upgrading Costs" + text, new SerializedRequirements(item.Recipes[configKey].RequiredUpgradeItems.Requirements).ToString(), "Item costs per level to upgrade " + englishName, isUpgrade: true); } if (cfg.craft != null) { cfg.craft.SettingChanged += ConfigChanged; } if (cfg.upgrade != null) { cfg.upgrade.SettingChanged += ConfigChanged; } void ConfigChanged(object o, EventArgs e) { item.UpdateCraftConfig(configKey, new SerializedRequirements(cfg.craft?.Value ?? ""), new SerializedRequirements(cfg.upgrade?.Value ?? "")); } bool CustomTableBrowsability() { return cfg.table.Value == CraftingTable.Custom; } bool ItemBrowsability() { return cfg.table.Value != CraftingTable.Disabled; } bool QualityResultBrowsability() { return cfg.requireOneIngredient.Value == Toggle.On; } void TableConfigChanged(object o, EventArgs e) { item.UpdateItemTableConfig(configKey, cfg.table.Value, cfg.customTable.Value); customTableAttributes.Browsable = cfg.table.Value == CraftingTable.Custom; foreach (ConfigurationManagerAttributes item7 in hideWhenNoneAttributes) { item7.Browsable = cfg.table.Value != CraftingTable.Disabled; } reloadConfigDisplay(); } bool TableLevelBrowsability() { return cfg.table.Value != CraftingTable.Disabled; } ConfigEntry itemConfig3(string name2, string value, string desc, bool isUpgrade) { //IL_00a7: Unknown result type (might be due to invalid IL or missing references) //IL_00b1: Expected O, but got Unknown ConfigurationManagerAttributes configurationManagerAttributes2 = new ConfigurationManagerAttributes { CustomDrawer = drawRequirementsConfigTable(item, isUpgrade), Order = (order -= 1), browsability = ItemBrowsability, Browsable = (ItemBrowsability() && (item.configurationVisible & Configurability.Recipe) != 0), Category = localizedName }; hideWhenNoneAttributes.Add(configurationManagerAttributes2); return config(englishName, name2, value, new ConfigDescription(desc, (AcceptableValueBase)null, new object[1] { configurationManagerAttributes2 })); } } if ((item.configurability & Configurability.Drop) != Configurability.Disabled) { ConfigEntry val = (itemDropConfigs[item] = config(englishName, "Drops from", new SerializedDrop(item.DropsFrom.Drops).ToString(), new ConfigDescription(englishName + " drops from this creature.", (AcceptableValueBase)null, new object[1] { new ConfigurationManagerAttributes { CustomDrawer = drawDropsConfigTable, Category = localizedName, Browsable = ((item.configurationVisible & Configurability.Drop) != 0) } }))); val.SettingChanged += [<658e6c10-0eb1-4251-85c8-d4e55dbcb4e3>NullableContext(0)] (object _, EventArgs _) => { item.UpdateCharacterDrop(); }; } for (int num = 0; num < item.Conversions.Count; num++) { string text2 = ((item.Conversions.Count > 1) ? $"{num + 1}. " : ""); Conversion conversion = item.Conversions[num]; conversion.config = new Conversion.ConversionConfig(); int index = num; conversion.config.input = config(englishName, text2 + "Conversion Input Item", conversion.Input, new ConfigDescription("Input item to create " + englishName, (AcceptableValueBase)null, new object[1] { new ConfigurationManagerAttributes { Category = localizedName, Browsable = ((item.configurationVisible & Configurability.Recipe) != 0) } })); conversion.config.input.SettingChanged += [<658e6c10-0eb1-4251-85c8-d4e55dbcb4e3>NullableContext(0)] (object _, EventArgs _) => { if (index < item.conversions.Count) { ObjectDB instance = ObjectDB.instance; if (instance != null) { ItemDrop val3 = SerializedRequirements.fetchByName(instance, conversion.config.input.Value); item.conversions[index].m_from = val3; UpdatePiece(); } } }; conversion.config.piece = config(englishName, text2 + "Conversion Piece", conversion.Piece, new ConfigDescription("Conversion piece used to create " + englishName, (AcceptableValueBase)null, new object[1] { new ConfigurationManagerAttributes { Category = localizedName, Browsable = ((item.configurationVisible & Configurability.Recipe) != 0) } })); conversion.config.piece.SettingChanged += [<658e6c10-0eb1-4251-85c8-d4e55dbcb4e3>NullableContext(0)] (object _, EventArgs _) => { UpdatePiece(); }; conversion.config.customPiece = config(englishName, text2 + "Conversion Custom Piece", conversion.customPiece ?? "", new ConfigDescription("Custom conversion piece to create " + englishName, (AcceptableValueBase)null, new object[1] { new ConfigurationManagerAttributes { Category = localizedName, Browsable = ((item.configurationVisible & Configurability.Recipe) != 0) } })); conversion.config.customPiece.SettingChanged += [<658e6c10-0eb1-4251-85c8-d4e55dbcb4e3>NullableContext(0)] (object _, EventArgs _) => { UpdatePiece(); }; void UpdatePiece() { if (index < item.conversions.Count && Object.op_Implicit((Object)(object)ZNetScene.instance)) { string text3 = ((conversion.config.piece.Value == ConversionPiece.Disabled) ? null : ((conversion.config.piece.Value == ConversionPiece.Custom) ? conversion.config.customPiece.Value : getInternalName(conversion.config.piece.Value))); string activePiece = conversion.config.activePiece; if (conversion.config.activePiece != null) { int num4 = ZNetScene.instance.GetPrefab(conversion.config.activePiece).GetComponent().m_conversion.IndexOf(item.conversions[index]); if (num4 >= 0) { Smelter[] array3 = Resources.FindObjectsOfTypeAll(); foreach (Smelter val3 in array3) { if (Utils.GetPrefabName(((Component)val3).gameObject) == activePiece) { val3.m_conversion.RemoveAt(num4); } } } conversion.config.activePiece = null; } if (item.conversions[index].m_from != null && conversion.config.piece.Value != ConversionPiece.Disabled) { GameObject prefab = ZNetScene.instance.GetPrefab(text3); if (((prefab != null) ? prefab.GetComponent() : null) != null) { conversion.config.activePiece = text3; Smelter[] array3 = Resources.FindObjectsOfTypeAll(); foreach (Smelter val4 in array3) { if (Utils.GetPrefabName(((Component)val4).gameObject) == text3) { val4.m_conversion.Add(item.conversions[index]); } } } } } } } } if ((item.configurability & Configurability.Stats) != Configurability.Disabled) { item.statsConfigs.Clear(); SharedData shared = item.Prefab.GetComponent().m_itemData.m_shared; ItemType itemType = shared.m_itemType; statcfg("Weight", "Weight of " + englishName + ".", (SharedData val3) => val3.m_weight, delegate(SharedData val3, float value) { val3.m_weight = value; }); statcfg("Trader Value", "Trader value of " + englishName + ".", (SharedData val3) => val3.m_value, delegate(SharedData val3, int value) { val3.m_value = value; }); bool flag; switch (itemType - 3) { case 0: case 1: case 2: case 3: case 4: case 8: case 9: case 11: case 14: case 16: case 19: flag = true; break; default: flag = false; break; } if (flag) { statcfg("Durability", "Durability of " + englishName + ".", (SharedData val3) => val3.m_maxDurability, delegate(SharedData val3, float value) { val3.m_maxDurability = value; }); statcfg("Durability per Level", "Durability gain per level of " + englishName + ".", (SharedData val3) => val3.m_durabilityPerLevel, delegate(SharedData val3, float value) { val3.m_durabilityPerLevel = value; }); statcfg("Movement Speed Modifier", "Movement speed modifier of " + englishName + ".", (SharedData val3) => val3.m_movementModifier, delegate(SharedData val3, float value) { val3.m_movementModifier = value; }); } if ((itemType - 3 <= 2 || (int)itemType == 14 || (int)itemType == 22) ? true : false) { statcfg("Block Armor", "Block armor of " + englishName + ".", (SharedData val3) => val3.m_blockPower, delegate(SharedData val3, float value) { val3.m_blockPower = value; }); statcfg("Block Armor per Level", "Block armor per level for " + englishName + ".", (SharedData val3) => val3.m_blockPowerPerLevel, delegate(SharedData val3, float value) { val3.m_blockPowerPerLevel = value; }); statcfg("Block Force", "Block force of " + englishName + ".", (SharedData val3) => val3.m_deflectionForce, delegate(SharedData val3, float value) { val3.m_deflectionForce = value; }); statcfg("Block Force per Level", "Block force per level for " + englishName + ".", (SharedData val3) => val3.m_deflectionForcePerLevel, delegate(SharedData val3, float value) { val3.m_deflectionForcePerLevel = value; }); statcfg("Parry Bonus", "Parry bonus of " + englishName + ".", (SharedData val3) => val3.m_timedBlockBonus, delegate(SharedData val3, float value) { val3.m_timedBlockBonus = value; }); } else if ((itemType - 6 <= 1 || itemType - 11 <= 1 || (int)itemType == 17) ? true : false) { statcfg("Armor", "Armor of " + englishName + ".", (SharedData val3) => val3.m_armor, delegate(SharedData val3, float value) { val3.m_armor = value; }); statcfg("Armor per Level", "Armor per level for " + englishName + ".", (SharedData val3) => val3.m_armorPerLevel, delegate(SharedData val3, float value) { val3.m_armorPerLevel = value; }); } SkillType skillType = shared.m_skillType; if (((int)skillType == 7 || (int)skillType == 12) ? true : false) { statcfg("Tool tier", "Tool tier of " + englishName + ".", (SharedData val3) => val3.m_toolTier, delegate(SharedData val3, int value) { val3.m_toolTier = value; }); } if ((itemType - 5 <= 2 || itemType - 11 <= 1 || (int)itemType == 17) ? true : false) { Dictionary modifiers = shared.m_damageModifiers.ToDictionary((DamageModPair d) => d.m_type, (DamageModPair d) => (DamageModifier)d.m_modifier); DamageType[] first = (DamageType[])Enum.GetValues(typeof(DamageType)); DamageType[] array = new DamageType[5]; RuntimeHelpers.InitializeArray(array, (RuntimeFieldHandle)/*OpCode not supported: LdMemberToken*/); foreach (DamageType damageType in first.Except((IEnumerable)(object)array)) { statcfg(((object)Unsafe.As(ref damageType)/*cast due to .constrained prefix*/).ToString() + " Resistance", ((object)Unsafe.As(ref damageType)/*cast due to .constrained prefix*/).ToString() + " resistance of " + englishName + ".", (SharedData _) => (!modifiers.TryGetValue(damageType, out var value)) ? DamageModifier.None : value, delegate(SharedData val4, DamageModifier value) { //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_000b: Unknown result type (might be due to invalid IL or missing references) //IL_0010: Unknown result type (might be due to invalid IL or missing references) //IL_0018: Unknown result type (might be due to invalid IL or missing references) //IL_001d: 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_002a: Unknown result type (might be due to invalid IL or missing references) //IL_002f: Unknown result type (might be due to invalid IL or missing references) //IL_0035: 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_0054: Unknown result type (might be due to invalid IL or missing references) DamageModPair val3 = new DamageModPair { m_type = damageType, m_modifier = (DamageModifier)value }; for (int i = 0; i < val4.m_damageModifiers.Count; i++) { if (val4.m_damageModifiers[i].m_type == damageType) { if (value == DamageModifier.None) { val4.m_damageModifiers.RemoveAt(i); } else { val4.m_damageModifiers[i] = val3; } return; } } if (value != DamageModifier.None) { val4.m_damageModifiers.Add(val3); } }); } } if ((int)itemType == 2 && shared.m_food > 0f) { statcfg("Health", "Health value of " + englishName + ".", (SharedData val3) => val3.m_food, delegate(SharedData val3, float value) { val3.m_food = value; }); statcfg("Stamina", "Stamina value of " + englishName + ".", (SharedData val3) => val3.m_foodStamina, delegate(SharedData val3, float value) { val3.m_foodStamina = value; }); statcfg("Eitr", "Eitr value of " + englishName + ".", (SharedData val3) => val3.m_foodEitr, delegate(SharedData val3, float value) { val3.m_foodEitr = value; }); statcfg("Duration", "Duration of " + englishName + ".", (SharedData val3) => val3.m_foodBurnTime, delegate(SharedData val3, float value) { val3.m_foodBurnTime = value; }); statcfg("Health Regen", "Health regen value of " + englishName + ".", (SharedData val3) => val3.m_foodRegen, delegate(SharedData val3, float value) { val3.m_foodRegen = value; }); } if ((int)shared.m_skillType == 10) { statcfg("Health Cost", "Health cost of " + englishName + ".", (SharedData val3) => val3.m_attack.m_attackHealth, delegate(SharedData val3, float value) { val3.m_attack.m_attackHealth = value; }); statcfg("Health Cost Percentage", "Health cost percentage of " + englishName + ".", (SharedData val3) => val3.m_attack.m_attackHealthPercentage, delegate(SharedData val3, float value) { val3.m_attack.m_attackHealthPercentage = value; }); } skillType = shared.m_skillType; if (skillType - 9 <= 1) { statcfg("Eitr Cost", "Eitr cost of " + englishName + ".", (SharedData val3) => val3.m_attack.m_attackEitr, delegate(SharedData val3, float value) { val3.m_attack.m_attackEitr = value; }); } if ((itemType - 3 <= 1 || (int)itemType == 14 || (int)itemType == 22) ? true : false) { statcfg("Knockback", "Knockback of " + englishName + ".", (SharedData val3) => val3.m_attackForce, delegate(SharedData val3, float value) { val3.m_attackForce = value; }); statcfg("Backstab Bonus", "Backstab bonus of " + englishName + ".", (SharedData val3) => val3.m_backstabBonus, delegate(SharedData val3, float value) { val3.m_backstabBonus = value; }); statcfg("Attack Stamina", "Attack stamina of " + englishName + ".", (SharedData val3) => val3.m_attack.m_attackStamina, delegate(SharedData val3, float value) { val3.m_attack.m_attackStamina = value; }); SetDmg("True", (DamageTypes dmg) => dmg.m_damage, delegate(ref DamageTypes dmg, float damage) { dmg.m_damage = damage; }); SetDmg("Slash", (DamageTypes dmg) => dmg.m_slash, delegate(ref DamageTypes dmg, float slash) { dmg.m_slash = slash; }); SetDmg("Pierce", (DamageTypes dmg) => dmg.m_pierce, delegate(ref DamageTypes dmg, float pierce) { dmg.m_pierce = pierce; }); SetDmg("Blunt", (DamageTypes dmg) => dmg.m_blunt, delegate(ref DamageTypes dmg, float blunt) { dmg.m_blunt = blunt; }); SetDmg("Chop", (DamageTypes dmg) => dmg.m_chop, delegate(ref DamageTypes dmg, float chop) { dmg.m_chop = chop; }); SetDmg("Pickaxe", (DamageTypes dmg) => dmg.m_pickaxe, delegate(ref DamageTypes dmg, float pickaxe) { dmg.m_pickaxe = pickaxe; }); SetDmg("Fire", (DamageTypes dmg) => dmg.m_fire, delegate(ref DamageTypes dmg, float fire) { dmg.m_fire = fire; }); SetDmg("Poison", (DamageTypes dmg) => dmg.m_poison, delegate(ref DamageTypes dmg, float poison) { dmg.m_poison = poison; }); SetDmg("Frost", (DamageTypes dmg) => dmg.m_frost, delegate(ref DamageTypes dmg, float frost) { dmg.m_frost = frost; }); SetDmg("Lightning", (DamageTypes dmg) => dmg.m_lightning, delegate(ref DamageTypes dmg, float lightning) { dmg.m_lightning = lightning; }); SetDmg("Spirit", (DamageTypes dmg) => dmg.m_spirit, delegate(ref DamageTypes dmg, float spirit) { dmg.m_spirit = spirit; }); if ((int)itemType == 4) { statcfg("Projectiles", "Number of projectiles that " + englishName + " shoots at once.", (SharedData val3) => val3.m_attack.m_projectileBursts, delegate(SharedData val3, int value) { val3.m_attack.m_projectileBursts = value; }); statcfg("Burst Interval", "Time between the projectiles " + englishName + " shoots at once.", (SharedData val3) => val3.m_attack.m_burstInterval, delegate(SharedData val3, float value) { val3.m_attack.m_burstInterval = value; }); statcfg("Minimum Accuracy", "Minimum accuracy for " + englishName + ".", (SharedData val3) => val3.m_attack.m_projectileAccuracyMin, delegate(SharedData val3, float value) { val3.m_attack.m_projectileAccuracyMin = value; }); statcfg("Accuracy", "Accuracy for " + englishName + ".", (SharedData val3) => val3.m_attack.m_projectileAccuracy, delegate(SharedData val3, float value) { val3.m_attack.m_projectileAccuracy = value; }); statcfg("Minimum Velocity", "Minimum velocity for " + englishName + ".", (SharedData val3) => val3.m_attack.m_projectileVelMin, delegate(SharedData val3, float value) { val3.m_attack.m_projectileVelMin = value; }); statcfg("Velocity", "Velocity for " + englishName + ".", (SharedData val3) => val3.m_attack.m_projectileVel, delegate(SharedData val3, float value) { val3.m_attack.m_projectileVel = value; }); statcfg("Maximum Draw Time", "Time until " + englishName + " is fully drawn at skill level 0.", (SharedData val3) => val3.m_attack.m_drawDurationMin, delegate(SharedData val3, float value) { val3.m_attack.m_drawDurationMin = value; }); statcfg("Stamina Drain", "Stamina drain per second while drawing " + englishName + ".", (SharedData val3) => val3.m_attack.m_drawStaminaDrain, delegate(SharedData val3, float value) { val3.m_attack.m_drawStaminaDrain = value; }); } } } List traderAttributes; if ((item.configurability & Configurability.Trader) != Configurability.Disabled) { traderAttributes = new List(); item.traderConfig = new TraderConfig { trader = config(englishName, "Trader Selling", item.Trade.Trader, new ConfigDescription("Which traders sell " + englishName + ".", (AcceptableValueBase)null, new object[1] { new ConfigurationManagerAttributes { Order = (order -= 1), Browsable = ((item.configurationVisible & Configurability.Trader) != 0), Category = localizedName } })) }; item.traderConfig.trader.SettingChanged += [<658e6c10-0eb1-4251-85c8-d4e55dbcb4e3>NullableContext(0)] (object _, EventArgs _) => { item.ReloadTraderConfiguration(); foreach (ConfigurationManagerAttributes item8 in traderAttributes) { item8.Browsable = TraderBrowsability(); } reloadConfigDisplay(); }; item.traderConfig.price = traderConfig("Trader Price", item.Trade.Price, "Price of " + englishName + " at the trader."); item.traderConfig.stack = traderConfig("Trader Stack", item.Trade.Stack, "Stack size of " + englishName + " in the trader. Also known as the number of items sold by a trader in one transaction."); item.traderConfig.requiredGlobalKey = traderConfig("Trader Required Global Key", item.Trade.RequiredGlobalKey ?? "", "Required global key to unlock " + englishName + " at the trader."); if (item.traderConfig.trader.Value != Trader.None) { PrefabManager.AddItemToTrader(item.Prefab, item.traderConfig.trader.Value, item.traderConfig.price.Value, item.traderConfig.stack.Value, item.traderConfig.requiredGlobalKey.Value); } } else if (item.Trade.Trader != Trader.None) { PrefabManager.AddItemToTrader(item.Prefab, item.Trade.Trader, item.Trade.Price, item.Trade.Stack, item.Trade.RequiredGlobalKey); } void SetDmg(string dmgType, Func readDmg, setDmgFunc setDmg) { statcfg(dmgType + " Damage", dmgType + " damage dealt by " + englishName + ".", (SharedData val3) => readDmg(val3.m_damages), delegate(SharedData val3, float value) { setDmg(ref val3.m_damages, value); }); statcfg(dmgType + " Damage Per Level", dmgType + " damage dealt increase per level for " + englishName + ".", (SharedData val3) => readDmg(val3.m_damagesPerLevel), delegate(SharedData val3, float value) { setDmg(ref val3.m_damagesPerLevel, value); }); } bool TraderBrowsability() { return item.traderConfig.trader.Value != Trader.None; } void statcfg(string configName, string description, [Nullable(new byte[] { 1, 1, 0 })] Func readDefault, [Nullable(new byte[] { 1, 1, 0 })] Action setValue) { //IL_0078: Unknown result type (might be due to invalid IL or missing references) //IL_0082: Expected O, but got Unknown SharedData shared2 = item.Prefab.GetComponent().m_itemData.m_shared; ConfigEntry cfg2 = config(englishName, configName, readDefault(shared2), new ConfigDescription(description, (AcceptableValueBase)null, new object[1] { new ConfigurationManagerAttributes { Category = localizedName, Browsable = ((item.configurationVisible & Configurability.Stats) != 0) } })); if ((item.configurationVisible & Configurability.Stats) != Configurability.Disabled) { setValue(shared2, cfg2.Value); } item.statsConfigs.Add((ConfigEntryBase)(object)cfg2, ApplyConfig); cfg2.SettingChanged += [<658e6c10-0eb1-4251-85c8-d4e55dbcb4e3>NullableContext(0)] (object _, EventArgs _) => { if ((item.configurationVisible & Configurability.Stats) != Configurability.Disabled) { ApplyConfig(); } }; void ApplyConfig() { item.ApplyToAllInstances(delegate(ItemData val3) { setValue(val3.m_shared, cfg2.Value); }); } } [return: Nullable(new byte[] { 1, 0 })] ConfigEntry traderConfig(string name2, [Nullable(0)] T value, string desc) { //IL_0099: Unknown result type (might be due to invalid IL or missing references) //IL_00a3: Expected O, but got Unknown ConfigurationManagerAttributes configurationManagerAttributes2 = new ConfigurationManagerAttributes { Order = (order -= 1), browsability = TraderBrowsability, Browsable = (TraderBrowsability() && (item.configurationVisible & Configurability.Trader) != 0), Category = localizedName }; traderAttributes.Add(configurationManagerAttributes2); ConfigEntry obj = config(englishName, name2, value, new ConfigDescription(desc, (AcceptableValueBase)null, new object[1] { configurationManagerAttributes2 })); obj.SettingChanged += [<658e6c10-0eb1-4251-85c8-d4e55dbcb4e3>NullableContext(0)] (object _, EventArgs _) => { item.ReloadTraderConfiguration(); }; return obj; } } if (saveOnConfigSet) { plugin.Config.SaveOnConfigSet = true; plugin.Config.Save(); } } configManager = ((type == null) ? null : Chainloader.ManagerObject.GetComponent(type)); foreach (Item registeredItem in registeredItems) { Item item2 = registeredItem; foreach (KeyValuePair recipe in item2.Recipes) { KeyValuePair kv = recipe; RequiredResourceList[] array2 = new RequiredResourceList[2] { kv.Value.RequiredItems, kv.Value.RequiredUpgradeItems }; foreach (RequiredResourceList requiredResourceList in array2) { for (int num3 = 0; num3 < requiredResourceList.Requirements.Count; num3++) { ConfigEntry amountCfg; int resourceIndex; if ((item2.configurability & Configurability.Recipe) != Configurability.Disabled) { amountCfg = requiredResourceList.Requirements[num3].amountConfig; if (amountCfg != null) { resourceIndex = num3; amountCfg.SettingChanged += ConfigChanged2; } } void ConfigChanged2(object o, EventArgs e) { if (Object.op_Implicit((Object)(object)ObjectDB.instance) && activeRecipes.ContainsKey(item2) && activeRecipes[item2].TryGetValue(kv.Key, out var value)) { foreach (Recipe item9 in value) { item9.m_resources[resourceIndex].m_amount = amountCfg.Value; } } } } } } item2.InitializeNewRegisteredItem(); } } private void InitializeNewRegisteredItem() { foreach (KeyValuePair recipe in Recipes) { KeyValuePair kv = recipe; ConfigEntryBase enabledCfg = kv.Value.RecipeIsActive; if (enabledCfg != null) { ((object)enabledCfg).GetType().GetEvent("SettingChanged").AddEventHandler(enabledCfg, new EventHandler(ConfigChanged)); } void ConfigChanged(object o, EventArgs e) { if (Object.op_Implicit((Object)(object)ObjectDB.instance) && activeRecipes.ContainsKey(this) && activeRecipes[this].TryGetValue(kv.Key, out var value)) { foreach (Recipe item in value) { item.m_enabled = (int)enabledCfg.BoxedValue != 0; } } } } } public void ReloadCraftingConfiguration() { if (Object.op_Implicit((Object)(object)ObjectDB.instance) && ObjectDB.instance.GetItemPrefab(StringExtensionMethods.GetStableHashCode(((Object)Prefab).name)) == null) { registerRecipesInObjectDB(ObjectDB.instance); ObjectDB.instance.m_items.Add(Prefab); ObjectDB.instance.m_itemByHash.Add(StringExtensionMethods.GetStableHashCode(((Object)Prefab).name), Prefab); ZNetScene.instance.m_prefabs.Add(Prefab); ZNetScene.instance.m_namedPrefabs.Add(StringExtensionMethods.GetStableHashCode(((Object)Prefab).name), Prefab); } foreach (string item in Recipes.Keys.DefaultIfEmpty("")) { if (Recipes.TryGetValue(item, out var value) && value.Crafting.Stations.Count > 0) { UpdateItemTableConfig(item, value.Crafting.Stations.First().Table, value.Crafting.Stations.First().custom ?? ""); UpdateCraftConfig(item, new SerializedRequirements(value.RequiredItems.Requirements), new SerializedRequirements(value.RequiredUpgradeItems.Requirements)); } } } private void ReloadTraderConfiguration() { if (traderConfig.trader.Value == Trader.None) { PrefabManager.RemoveItemFromTrader(Prefab); } else { PrefabManager.AddItemToTrader(Prefab, traderConfig.trader.Value, traderConfig.price.Value, traderConfig.stack.Value, traderConfig.requiredGlobalKey.Value); } } public static void ApplyToAllInstances(GameObject prefab, Action callback) { callback(prefab.GetComponent().m_itemData); string name = prefab.GetComponent().m_itemData.m_shared.m_name; Inventory[] source = (from c in Player.s_players.Select([<658e6c10-0eb1-4251-85c8-d4e55dbcb4e3>NullableContext(0)] (Player p) => ((Humanoid)p).GetInventory()).Concat(from c in Object.FindObjectsOfType() select c.GetInventory()) where c != null select c).ToArray(); foreach (ItemData item in (from i in (from p in ObjectDB.instance.m_items select p.GetComponent() into c where Object.op_Implicit((Object)(object)c) && Object.op_Implicit((Object)(object)((Component)c).GetComponent()) select c).Concat(ItemDrop.s_instances) select i.m_itemData).Concat(source.SelectMany([<658e6c10-0eb1-4251-85c8-d4e55dbcb4e3>NullableContext(0)] (Inventory i) => i.GetAllItems()))) { if (item.m_shared.m_name == name) { callback(item); } } } public void ApplyToAllInstances(Action callback) { ApplyToAllInstances(Prefab, callback); } [<658e6c10-0eb1-4251-85c8-d4e55dbcb4e3>NullableContext(0)] [return: Nullable(1)] private static string getInternalName(T value) where T : struct { return ((InternalName)typeof(T).GetMember(value.ToString())[0].GetCustomAttributes(typeof(InternalName)).First()).internalName; } private void registerRecipesInObjectDB(ObjectDB objectDB) { //IL_044e: Unknown result type (might be due to invalid IL or missing references) //IL_0453: Unknown result type (might be due to invalid IL or missing references) //IL_0486: Unknown result type (might be due to invalid IL or missing references) //IL_049c: Expected O, but got Unknown activeRecipes[this] = new Dictionary>(); itemCraftConfigs.TryGetValue(this, out var value); foreach (KeyValuePair recipe in Recipes) { List list = new List(); foreach (CraftingStationConfig station in recipe.Value.Crafting.Stations) { ItemConfig itemConfig = value?[recipe.Key]; Recipe val = ScriptableObject.CreateInstance(); string name = ((Object)Prefab).name; CraftingTable table = station.Table; ((Object)val).name = name + "_Recipe_" + table; val.m_amount = recipe.Value.CraftAmount; bool enabled; if (itemConfig != null) { enabled = itemConfig.table.Value != CraftingTable.Disabled; } else { ConfigEntryBase recipeIsActive = recipe.Value.RecipeIsActive; enabled = (int)(((recipeIsActive != null) ? recipeIsActive.BoxedValue : null) ?? ((object)1)) != 0; } val.m_enabled = enabled; val.m_item = Prefab.GetComponent(); val.m_resources = SerializedRequirements.toPieceReqs(objectDB, (itemConfig?.craft == null) ? new SerializedRequirements(recipe.Value.RequiredItems.Requirements) : new SerializedRequirements(itemConfig.craft.Value), (itemConfig?.upgrade == null) ? new SerializedRequirements(recipe.Value.RequiredUpgradeItems.Requirements) : new SerializedRequirements(itemConfig.upgrade.Value)); table = ((itemConfig == null || list.Count > 0) ? station.Table : itemConfig.table.Value); if ((uint)table <= 1u) { val.m_craftingStation = null; } else if (((itemConfig == null || list.Count > 0) ? station.Table : itemConfig.table.Value) == CraftingTable.Custom) { GameObject prefab = ZNetScene.instance.GetPrefab((itemConfig == null || list.Count > 0) ? station.custom : itemConfig.customTable.Value); if (prefab != null) { val.m_craftingStation = prefab.GetComponent(); } else { Debug.LogWarning((object)("Custom crafting station '" + ((itemConfig == null || list.Count > 0) ? station.custom : itemConfig.customTable.Value) + "' does not exist")); } } else { val.m_craftingStation = ZNetScene.instance.GetPrefab(getInternalName((itemConfig == null || list.Count > 0) ? station.Table : itemConfig.table.Value)).GetComponent(); } val.m_minStationLevel = ((itemConfig == null || list.Count > 0) ? station.level : itemConfig.tableLevel.Value); val.m_requireOnlyOneIngredient = ((itemConfig == null) ? recipe.Value.RequireOnlyOneIngredient : (itemConfig.requireOneIngredient.Value == Toggle.On)); val.m_qualityResultAmountMultiplier = itemConfig?.qualityResultAmountMultiplier.Value ?? recipe.Value.QualityResultAmountMultiplier; list.Add(val); RequiredResourceList requiredItems = recipe.Value.RequiredItems; if (requiredItems != null && !requiredItems.Free) { List requirements = requiredItems.Requirements; if (requirements != null && requirements.Count == 0) { hiddenCraftRecipes.Add(val, recipe.Value.RecipeIsActive); } } requiredItems = recipe.Value.RequiredUpgradeItems; if (requiredItems != null && !requiredItems.Free) { List requirements = requiredItems.Requirements; if (requirements != null && requirements.Count == 0) { hiddenUpgradeRecipes.Add(val, recipe.Value.RecipeIsActive); } } } activeRecipes[this].Add(recipe.Key, list); objectDB.m_recipes.AddRange(list); } conversions = new List(); for (int i = 0; i < Conversions.Count; i++) { Conversion conversion = Conversions[i]; conversions.Add(new ItemConversion { m_from = SerializedRequirements.fetchByName(ObjectDB.instance, conversion.config?.input.Value ?? conversion.Input), m_to = Prefab.GetComponent() }); ConversionPiece conversionPiece = conversion.config?.piece.Value ?? conversion.Piece; string text = null; if (conversionPiece != ConversionPiece.Disabled && conversions[i].m_from != null) { text = ((conversionPiece != ConversionPiece.Custom) ? getInternalName(conversionPiece) : (conversion.config?.customPiece.Value ?? conversion.customPiece)); GameObject prefab2 = ZNetScene.instance.GetPrefab(text); Smelter val2 = ((prefab2 != null) ? prefab2.GetComponent() : null); if (val2 != null) { val2.m_conversion.Add(conversions[i]); } else { text = null; } } if (conversion.config != null) { conversion.config.activePiece = text; } } } [HarmonyPriority(0)] internal static void Patch_ObjectDBInit(ObjectDB __instance) { if ((Object)(object)__instance.GetItemPrefab("YagluthDrop") == (Object)null) { return; } hiddenCraftRecipes.Clear(); hiddenUpgradeRecipes.Clear(); foreach (Item registeredItem in registeredItems) { registeredItem.registerRecipesInObjectDB(__instance); } } internal static void Patch_TraderGetAvailableItems(Trader __instance, ref List __result) { string prefabName = Utils.GetPrefabName(((Component)__instance).gameObject); Trader trader = ((prefabName == "Haldor") ? Trader.Haldor : ((prefabName == "Hildir") ? Trader.Hildir : Trader.None)); Trader trader2 = trader; __result.AddRange(from tuple in PrefabManager.CustomTradeItems.Values where (tuple.Item1 & trader2) != 0 select tuple.Item2 into tradeItem where string.IsNullOrEmpty(tradeItem.m_requiredGlobalKey) || ZoneSystem.instance.GetGlobalKey(tradeItem.m_requiredGlobalKey) select tradeItem); } internal static void Patch_OnAddSmelterInput(ItemData item, bool __result) { if (__result) { ((Humanoid)Player.m_localPlayer).UnequipItem(item, true); } } internal static void Patch_MaximumRequiredStationLevel(Recipe __instance, ref int __result, int quality) { if (!itemDropMap.TryGetValue(__instance.m_item, out var value)) { return; } IEnumerable source; if (!itemCraftConfigs.TryGetValue(value, out var value2)) { source = Enumerable.Empty(); } else { CraftingStation currentCraftingStation = Player.m_localPlayer.GetCurrentCraftingStation(); if (currentCraftingStation != null) { string stationName = Utils.GetPrefabName(((Component)currentCraftingStation).gameObject); source = from c in value2.Where([<658e6c10-0eb1-4251-85c8-d4e55dbcb4e3>NullableContext(0)] (KeyValuePair c) => { switch (c.Value.table.Value) { case CraftingTable.Disabled: case CraftingTable.Inventory: return false; case CraftingTable.Custom: return c.Value.customTable.Value == stationName; default: return getInternalName(c.Value.table.Value) == stationName; } }) select c.Value; } else { source = value2.Values; } } __result = Mathf.Min(Mathf.Max(1, __instance.m_minStationLevel) + (quality - 1), (from cfg in source where cfg.maximumTableLevel != null select cfg.maximumTableLevel.Value).DefaultIfEmpty(value.MaximumRequiredStationLevel).Max()); } internal static void Patch_GetAvailableRecipesPrefix([Nullable(new byte[] { 2, 1, 1, 1, 2 })] ref Dictionary> __state) { if (__state == null) { __state = new Dictionary>(); } Dictionary dictionary; if (InventoryGui.instance.InCraftTab()) { dictionary = hiddenCraftRecipes; } else { if (!InventoryGui.instance.InUpradeTab()) { return; } dictionary = hiddenUpgradeRecipes; } foreach (Recipe key in dictionary.Keys) { key.m_enabled = false; } __state[Assembly.GetExecutingAssembly()] = dictionary; } internal static void Patch_GetAvailableRecipesFinalizer([Nullable(new byte[] { 1, 1, 1, 1, 2 })] Dictionary> __state) { if (!__state.TryGetValue(Assembly.GetExecutingAssembly(), out var value)) { return; } foreach (KeyValuePair item in value) { Recipe key = item.Key; ConfigEntryBase value2 = item.Value; key.m_enabled = (int)(((value2 != null) ? value2.BoxedValue : null) ?? ((object)1)) != 0; } } internal static IEnumerable Transpile_SetupRequirementList(IEnumerable instructionsEnumerable, ILGenerator ilg) { //IL_0150: Unknown result type (might be due to invalid IL or missing references) //IL_0156: Expected O, but got Unknown //IL_0164: Unknown result type (might be due to invalid IL or missing references) //IL_016a: Expected O, but got Unknown //IL_017b: Unknown result type (might be due to invalid IL or missing references) //IL_0181: Expected O, but got Unknown //IL_019c: Unknown result type (might be due to invalid IL or missing references) //IL_01a2: Expected O, but got Unknown //IL_01aa: Unknown result type (might be due to invalid IL or missing references) //IL_01b0: Expected O, but got Unknown //IL_01be: Unknown result type (might be due to invalid IL or missing references) //IL_01c4: Expected O, but got Unknown //IL_01cc: Unknown result type (might be due to invalid IL or missing references) //IL_01d2: Expected O, but got Unknown //IL_01e4: Unknown result type (might be due to invalid IL or missing references) //IL_01ea: Expected O, but got Unknown //IL_01f9: Unknown result type (might be due to invalid IL or missing references) //IL_01ff: Expected O, but got Unknown //IL_0217: Unknown result type (might be due to invalid IL or missing references) //IL_021c: Unknown result type (might be due to invalid IL or missing references) //IL_0230: Expected O, but got Unknown //IL_0239: Unknown result type (might be due to invalid IL or missing references) //IL_023f: Expected O, but got Unknown List list = instructionsEnumerable.ToList(); MethodInfo methodInfo = AccessTools.DeclaredMethod(typeof(InventoryGui), "SetupRequirement", (Type[])null, (Type[])null); CodeInstruction val = null; CodeInstruction val2 = null; LocalBuilder localBuilder = ilg.DeclareLocal(typeof(int)); Dictionary dictionary = new Dictionary(); bool flag = false; int num = 0; int value = 0; Label? label = default(Label?); for (int i = 0; i < list.Count; i++) { if (CodeInstructionExtensions.Calls(list[i], methodInfo)) { val = list[i + 2]; val2 = list[i + 5]; flag = true; } if (flag) { if (CodeInstructionExtensions.Branches(list[i], ref label) && dictionary.TryGetValue(label.Value, out value)) { num = i; break; } continue; } foreach (Label label4 in list[i].labels) { dictionary[label4] = i; } } if (list[value - 3].opcode == OpCodes.Dup) { return list; } Label label2 = ilg.DefineLabel(); Label label3 = ilg.DefineLabel(); list[num + 1].labels.Add(label2); list.InsertRange(num + 1, (IEnumerable)(object)new CodeInstruction[11] { new CodeInstruction(OpCodes.Ldloc, (object)localBuilder), new CodeInstruction(OpCodes.Brfalse, (object)label2), val.Clone(), new CodeInstruction(OpCodes.Ldarg_0, (object)null), new CodeInstruction(OpCodes.Ldfld, (object)AccessTools.DeclaredField(typeof(InventoryGui), "m_recipeRequirementList")), new CodeInstruction(OpCodes.Ldlen, (object)null), new CodeInstruction(OpCodes.Bgt, (object)label2), new CodeInstruction(OpCodes.Ldc_I4_0, (object)null), val2.Clone(), new CodeInstruction(OpCodes.Ldc_I4_0, (object)null), new CodeInstruction(OpCodes.Br, (object)label3) }); list.InsertRange(value - 2, (IEnumerable)(object)new CodeInstruction[2] { new CodeInstruction(OpCodes.Dup, (object)null) { labels = new List