Decompiled source of Drop That v2.3.13
Valheim.DropThat.dll
Decompiled 2 weeks ago
The result has been truncated due to the large size, download it to view full contents!
using System; using System.Collections.Generic; using System.Diagnostics; using System.Globalization; using System.IO; using System.IO.Compression; using System.Linq; using System.Reflection; using System.Reflection.Emit; using System.Runtime.CompilerServices; using System.Runtime.Serialization; using System.Runtime.Serialization.Formatters.Binary; using System.Runtime.Versioning; using System.Security; using System.Security.Permissions; using System.Text; using System.Text.RegularExpressions; using System.Threading; using System.Threading.Tasks; using BepInEx; using BepInEx.Bootstrap; using BepInEx.Configuration; using BepInEx.Logging; using CreatureLevelControl; using EpicLoot; using EpicLoot.Data; using EpicLoot.LegendarySystem; using HarmonyLib; using Microsoft.CodeAnalysis; using UnityEngine; using Valheim.DropThat.Caches; using Valheim.DropThat.Configuration; using Valheim.DropThat.Configuration.ConfigTypes; using Valheim.DropThat.Core; using Valheim.DropThat.Core.Configuration; using Valheim.DropThat.Core.Network; using Valheim.DropThat.Creature.DamageRecords; using Valheim.DropThat.Creature.StatusRecords; using Valheim.DropThat.Debugging; using Valheim.DropThat.Drop.CharacterDropSystem.Caches; using Valheim.DropThat.Drop.CharacterDropSystem.Conditions; using Valheim.DropThat.Drop.CharacterDropSystem.Conditions.ModSpecific; using Valheim.DropThat.Drop.CharacterDropSystem.Conditions.ModSpecific.CLLC; using Valheim.DropThat.Drop.CharacterDropSystem.Conditions.ModSpecific.SpawnThat; using Valheim.DropThat.Drop.CharacterDropSystem.Models; using Valheim.DropThat.Drop.CharacterDropSystem.Modifiers; using Valheim.DropThat.Drop.CharacterDropSystem.Modifiers.ModSpecific; using Valheim.DropThat.Drop.CharacterDropSystem.Modifiers.ModSpecific.ModEpicLoot; using Valheim.DropThat.Drop.CharacterDropSystem.Services; using Valheim.DropThat.Drop.DropTableSystem.Caches; using Valheim.DropThat.Drop.DropTableSystem.Conditions; using Valheim.DropThat.Drop.DropTableSystem.Conditions.ModSpecific; using Valheim.DropThat.Drop.DropTableSystem.Conditions.ModSpecific.ModCLLC; using Valheim.DropThat.Drop.DropTableSystem.Managers; using Valheim.DropThat.Drop.DropTableSystem.Modifiers; using Valheim.DropThat.Drop.DropTableSystem.Modifiers.ModSpecific.ModEpicLoot; using Valheim.DropThat.Drop.DropTableSystem.Wrapper; using Valheim.DropThat.Integrations; using Valheim.DropThat.Integrations.EpicLootIntegration; using Valheim.DropThat.Locations; using Valheim.DropThat.Reset; using Valheim.DropThat.Utilities; using Valheim.DropThat.Utilities.Valheim; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: TargetFramework(".NETFramework,Version=v4.8", FrameworkDisplayName = ".NET Framework 4.8")] [assembly: AssemblyCompany("A Sharp Pen")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyDescription("Valheim mod and tool for configuring loot drops.")] [assembly: AssemblyFileVersion("2.3.13.0")] [assembly: AssemblyInformationalVersion("2.3.13+780bf6647f512c07461ae8296b24713e31979865")] [assembly: AssemblyProduct("Valheim.DropThat")] [assembly: AssemblyTitle("Valheim.DropThat")] [assembly: AssemblyMetadata("RepositoryUrl", "https://github.com/ASharpPen/Valheim.SpawnThat")] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("2.3.13.0")] [module: UnverifiableCode] [module: RefSafetyRules(11)] namespace Microsoft.CodeAnalysis { [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] internal sealed class EmbeddedAttribute : Attribute { } } namespace System.Runtime.CompilerServices { [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] [AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)] internal sealed class RefSafetyRulesAttribute : Attribute { public readonly int Version; public RefSafetyRulesAttribute(int P_0) { Version = P_0; } } } namespace Valheim.DropThat { [BepInDependency(/*Could not decode attribute arguments.*/)] [BepInDependency(/*Could not decode attribute arguments.*/)] [BepInDependency(/*Could not decode attribute arguments.*/)] [BepInDependency(/*Could not decode attribute arguments.*/)] [BepInPlugin("asharppen.valheim.drop_that", "Drop That!", "2.3.13")] public class DropThatPlugin : BaseUnityPlugin { public const string ModId = "asharppen.valheim.drop_that"; public const string PluginName = "Drop That!"; public const string Version = "2.3.13"; private void Awake() { //IL_0015: Unknown result type (might be due to invalid IL or missing references) Log.Logger = ((BaseUnityPlugin)this).Logger; ConfigurationManager.LoadGeneralConfigurations(); new Harmony("asharppen.valheim.drop_that").PatchAll(); NetworkSetup.SetupNetworking(); } } } namespace Valheim.DropThat.Utilities { public static class CodeMatcherExtensions { public static CodeMatcher GetPosition(this CodeMatcher codeMatcher, out int position) { position = codeMatcher.Pos; return codeMatcher; } internal static CodeMatcher Print(this CodeMatcher codeMatcher, int before, int after) { return codeMatcher; } } internal static class HashSetExtensions { public static void AddNullSafe<T>(this HashSet<T> set, T candidate) where T : class { if (set != null && candidate != null) { set.Add(candidate); } } } internal static class ListExtensions { public static void AddNullSafe<T>(this List<T> list, T candidate) where T : class { if (list != null && candidate != null) { list.Add(candidate); } } } internal static class ReflectionUtils { private static MethodInfo InstantiateGameObject; public static MethodInfo InstantiateGameObjectMethod => InstantiateGameObject ?? (InstantiateGameObject = (from x in typeof(Object).GetMethods(BindingFlags.Static | BindingFlags.Public) where x.Name.StartsWith("Instantiate") select x into m where m.IsGenericMethod select m).First((MethodInfo m) => m.ContainsGenericParameters && m.GetParameters().Length == 3).GetGenericMethodDefinition().MakeGenericMethod(typeof(GameObject))); } public static class StringExtensions { private static char[] Comma = new char[1] { ',' }; public static List<string> SplitBy(this string value, char splitChar, bool toUpper = false) { string[] array = value.Split(new char[1] { splitChar }, StringSplitOptions.RemoveEmptyEntries); if (array == null || array.Length == 0) { return new List<string>(); } return array.Select((string x) => Clean(x, toUpper)).ToList(); } public static List<string> SplitByComma(this string value, bool toUpper = false) { string[] array = value.Split(Comma, StringSplitOptions.RemoveEmptyEntries); if (array == null || array.Length == 0) { return new List<string>(); } return array.Select((string x) => Clean(x, toUpper)).ToList(); } private static string Clean(string x, bool toUpper) { string text = x.Trim(); if (toUpper) { return text.ToUpperInvariant(); } return text; } public static bool TryConvertToEnum<T>(this IEnumerable<string> strings, out List<T> enums) where T : struct { enums = new List<T>(); foreach (string @string in strings) { if (Enum.TryParse<T>(@string, ignoreCase: true, out var result)) { enums.Add(result); continue; } return false; } return true; } } public static class UnityObjectExtensions { private static Regex NameRegex = new Regex("^[^$(]*(?=$|[(])", RegexOptions.Compiled); public static bool IsNull(this Object obj) { if (obj == (Object)null || !Object.op_Implicit(obj)) { return true; } return false; } public static bool IsNotNull(this Object obj) { if (obj != (Object)null && Object.op_Implicit(obj)) { return true; } return false; } public static string GetCleanedName(this Object obj, bool toUpper = false) { if (obj.IsNull()) { return null; } string text = obj.name.Split(new char[1] { '(' }, StringSplitOptions.RemoveEmptyEntries).FirstOrDefault()?.Trim(); if (!string.IsNullOrWhiteSpace(text)) { return text; } return obj.name; } } } namespace Valheim.DropThat.Utilities.Valheim { public static class BiomeExtensions { public static string GetNames(this Biome biome) { //IL_0023: Unknown result type (might be due to invalid IL or missing references) //IL_0028: Unknown result type (might be due to invalid IL or missing references) //IL_0029: Unknown result type (might be due to invalid IL or missing references) //IL_002c: Unknown result type (might be due to invalid IL or missing references) //IL_002d: Unknown result type (might be due to invalid IL or missing references) //IL_002e: Unknown result type (might be due to invalid IL or missing references) //IL_0030: Invalid comparison between Unknown and I4 List<string> list = new List<string>(); foreach (Biome value in Enum.GetValues(typeof(Biome))) { Biome val = value; if ((int)val != 0 && (biome & val) > 0) { list.Add(((object)(Biome)(ref val)).ToString()); } } return GeneralExtensions.Join<string>((IEnumerable<string>)list, (Func<string, string>)null, ", "); } } public static class HitDataExtensions { public static DamageType GetCombinedDamageType(this HitData hit) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0014: 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) //IL_0017: 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_002c: Unknown result type (might be due to invalid IL or missing references) //IL_002d: Unknown result type (might be due to invalid IL or missing references) //IL_0040: Unknown result type (might be due to invalid IL or missing references) //IL_0042: Unknown result type (might be due to invalid IL or missing references) //IL_0043: Unknown result type (might be due to invalid IL or missing references) //IL_0056: Unknown result type (might be due to invalid IL or missing references) //IL_0058: Unknown result type (might be due to invalid IL or missing references) //IL_0059: Unknown result type (might be due to invalid IL or missing references) //IL_006c: Unknown result type (might be due to invalid IL or missing references) //IL_006f: Unknown result type (might be due to invalid IL or missing references) //IL_0070: Unknown result type (might be due to invalid IL or missing references) //IL_0083: 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_0087: Unknown result type (might be due to invalid IL or missing references) //IL_009a: Unknown result type (might be due to invalid IL or missing references) //IL_009d: Unknown result type (might be due to invalid IL or missing references) //IL_009e: Unknown result type (might be due to invalid IL or missing references) //IL_00b1: Unknown result type (might be due to invalid IL or missing references) //IL_00b7: Unknown result type (might be due to invalid IL or missing references) //IL_00b8: Unknown result type (might be due to invalid IL or missing references) //IL_00cb: Unknown result type (might be due to invalid IL or missing references) //IL_00d1: Unknown result type (might be due to invalid IL or missing references) //IL_00d2: Unknown result type (might be due to invalid IL or missing references) //IL_00ed: Unknown result type (might be due to invalid IL or missing references) //IL_00e5: Unknown result type (might be due to invalid IL or missing references) //IL_00eb: Unknown result type (might be due to invalid IL or missing references) //IL_00ec: Unknown result type (might be due to invalid IL or missing references) DamageType val = (DamageType)0; if (hit.m_damage.m_blunt > 0f) { val = (DamageType)(val | 1); } if (hit.m_damage.m_slash > 0f) { val = (DamageType)(val | 2); } if (hit.m_damage.m_pierce > 0f) { val = (DamageType)(val | 4); } if (hit.m_damage.m_chop > 0f) { val = (DamageType)(val | 8); } if (hit.m_damage.m_pickaxe > 0f) { val = (DamageType)(val | 0x10); } if (hit.m_damage.m_fire > 0f) { val = (DamageType)(val | 0x20); } if (hit.m_damage.m_frost > 0f) { val = (DamageType)(val | 0x40); } if (hit.m_damage.m_lightning > 0f) { val = (DamageType)(val | 0x80); } if (hit.m_damage.m_poison > 0f) { val = (DamageType)(val | 0x100); } if (hit.m_damage.m_spirit > 0f) { val = (DamageType)(val | 0x200); } return val; } } } namespace Valheim.DropThat.Reset { public static class StateResetter { private static HashSet<Action> OnResetActions = new HashSet<Action>(); public static void Subscribe(Action onReset) { OnResetActions.Add(onReset); } public static void Unsubscribe(Action onReset) { OnResetActions.Remove(onReset); } public static void Reset() { Log.LogDebug("Resetting mod state."); foreach (Action onResetAction in OnResetActions) { onResetAction(); } } } [HarmonyPatch(typeof(FejdStartup), "OnWorldStart")] public static class WorldStartPatch { [HarmonyPatch("OnWorldStart")] [HarmonyPrefix] private static void ResetState() { Log.LogDebug("OnWorldStart - Resetting configurations"); StateResetter.Reset(); ConfigurationManager.LoadAll(); } [HarmonyPatch("JoinServer")] [HarmonyPrefix] private static void ResetStateMultiplayer() { Log.LogDebug("JoinServer - Resetting configurations"); StateResetter.Reset(); } [HarmonyPatch("ParseServerArguments")] [HarmonyPrefix] private static void ResetStateServer() { Log.LogDebug("ParseServerArguments - Resetting configurations"); StateResetter.Reset(); ConfigurationManager.LoadAllCharacterDropConfigurations(); ConfigurationManager.LoadAllCharacterDropLists(); ConfigurationManager.LoadAllDropTableConfigurations(); ConfigurationManager.LoadAllDropTableLists(); } } } namespace Valheim.DropThat.Locations { public static class LocationHelper { private static Dictionary<Vector2i, SimpleLocation> _simpleLocationsByZone { get; set; } static LocationHelper() { StateResetter.Subscribe(delegate { _simpleLocationsByZone = null; }); } internal static void SetLocations(IEnumerable<SimpleLocation> locations) { //IL_0027: Unknown result type (might be due to invalid IL or missing references) if (_simpleLocationsByZone == null) { _simpleLocationsByZone = new Dictionary<Vector2i, SimpleLocation>(); } foreach (SimpleLocation location in locations) { _simpleLocationsByZone[location.ZonePosition] = location; } } public static SimpleLocation FindLocation(Vector3 position) { //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_0023: Unknown result type (might be due to invalid IL or missing references) //IL_00a3: Unknown result type (might be due to invalid IL or missing references) //IL_0053: Unknown result type (might be due to invalid IL or missing references) //IL_0063: Unknown result type (might be due to invalid IL or missing references) //IL_0084: 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_008a: Unknown result type (might be due to invalid IL or missing references) //IL_0090: Unknown result type (might be due to invalid IL or missing references) //IL_0091: Unknown result type (might be due to invalid IL or missing references) if (((Object)(object)ZoneSystem.instance).IsNull()) { Log.LogWarning("Attempting to retrieve location before ZoneSystem is initialized."); return null; } Vector2i zone = ZoneSystem.instance.GetZone(position); if (((Object)(object)ZoneSystem.instance).IsNotNull() && (ZoneSystem.instance.m_locationInstances?.Count ?? 0) > 0 && ZoneSystem.instance.m_locationInstances.TryGetValue(zone, out var value)) { return new SimpleLocation { LocationName = (value.m_location?.m_prefabName ?? ""), Position = value.m_position, ZonePosition = zone }; } if (_simpleLocationsByZone != null && _simpleLocationsByZone.TryGetValue(zone, out var value2)) { return value2; } return null; } } [HarmonyPatch(typeof(ZoneSystem))] internal static class Patch_ZoneSystem_Start_PrintLocations { [HarmonyPatch("Start")] [HarmonyPostfix] private static void PrintLocations(ZoneSystem __instance) { if (__instance.m_locations != null && (bool)ConfigurationManager.GeneralConfig.WriteLocationsToFile) { LocationsFileWriter.WriteToList(__instance.m_locations); } } } public class SimpleLocation { public Vector3 Position; public Vector2i ZonePosition; public string LocationName; } [Serializable] internal class SimpleLocationPackage : CompressedPackage { public string[] LocationNames; public SimpleLocationDTO[] Locations; protected override void BeforePack() { //IL_002f: Unknown result type (might be due to invalid IL or missing references) //IL_0043: 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) Dictionary<Vector2i, LocationInstance> locationInstances = ZoneSystem.instance.m_locationInstances; Dictionary<string, ushort> dictionary = new Dictionary<string, ushort>(); List<string> list = new List<string>(); List<SimpleLocationDTO> list2 = new List<SimpleLocationDTO>(); foreach (KeyValuePair<Vector2i, LocationInstance> item in locationInstances) { string prefabName = item.Value.m_location.m_prefabName; ushort num; if (dictionary.TryGetValue(item.Value.m_location.m_prefabName, out var value)) { num = value; } else { list.Add(prefabName); num = (ushort)(list.Count - 1); dictionary.Add(prefabName, num); } list2.Add(new SimpleLocationDTO(item.Key, num)); } LocationNames = list.ToArray(); Locations = list2.ToArray(); Log.LogTrace($"Packed {LocationNames.Length} location names"); Log.LogTrace($"Packed {Locations.Length} locations"); } protected override void AfterUnpack(object responseObject) { //IL_0096: Unknown result type (might be due to invalid IL or missing references) //IL_0098: 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_00a3: Unknown result type (might be due to invalid IL or missing references) //IL_00a5: Unknown result type (might be due to invalid IL or missing references) if (responseObject is SimpleLocationPackage) { Log.LogTrace($"Unpacking {LocationNames.Length} location names"); Log.LogTrace($"Unpacking {Locations.Length} locations"); List<SimpleLocation> list = new List<SimpleLocation>(Locations.Length); SimpleLocationDTO[] locations = Locations; Vector2i val = default(Vector2i); for (int i = 0; i < locations.Length; i++) { SimpleLocationDTO simpleLocationDTO = locations[i]; ((Vector2i)(ref val))..ctor(simpleLocationDTO.PositionX, simpleLocationDTO.PositionY); list.Add(new SimpleLocation { LocationName = LocationNames[simpleLocationDTO.Location], Position = ZoneSystem.instance.GetZonePos(val), ZonePosition = val }); } LocationHelper.SetLocations(list); } } } [Serializable] public struct SimpleLocationDTO { public int PositionX; public int PositionY; public ushort Location; public SimpleLocationDTO(Vector2i pos, ushort location) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_000d: Unknown result type (might be due to invalid IL or missing references) PositionX = pos.x; PositionY = pos.y; Location = location; } } [HarmonyPatch(typeof(ZNet))] public static class ZoneSystemMultiplayerPatch { private static bool HaveReceivedLocations; static ZoneSystemMultiplayerPatch() { StateResetter.Subscribe(delegate { HaveReceivedLocations = false; }); } [HarmonyPatch("OnNewConnection")] [HarmonyPostfix] private static void TransferLocationData(ZNet __instance, ZNetPeer peer) { //IL_0028: Unknown result type (might be due to invalid IL or missing references) //IL_0032: Expected O, but got Unknown if (ZNet.instance.IsServer()) { Log.LogDebug("Registering server RPC for sending location data on request from client."); peer.m_rpc.Register("RPC_RequestLocationsDropThat", new Method(RPC_RequestLocationsDropThat)); return; } Log.LogDebug("Registering client RPC for receiving location data from server."); peer.m_rpc.Register<ZPackage>("RPC_ReceiveLocationsDropThat", (Action<ZRpc, ZPackage>)RPC_ReceiveLocationsDropThat); Log.LogDebug("Requesting location data from server."); peer.m_rpc.Invoke("RPC_RequestLocationsDropThat", Array.Empty<object>()); } private static void RPC_RequestLocationsDropThat(ZRpc rpc) { try { if (!ZNet.instance.IsServer()) { Log.LogWarning("Non-server instance received request for location data. Ignoring request."); return; } Log.LogInfo("Sending location data."); if (ZoneSystem.instance.m_locationInstances == null) { Log.LogWarning("Unable to get locations from zonesystem to send to client."); return; } ZPackage package = new SimpleLocationPackage().Pack(); DataTransferService.Service.AddToQueue(package, "RPC_ReceiveLocationsDropThat", rpc); Log.LogInfo("Finished sending locations package."); } catch (Exception e) { Log.LogError("Unexpected error while attempting to create and send locations package from server to client.", e); } } private static void RPC_ReceiveLocationsDropThat(ZRpc rpc, ZPackage pkg) { Log.LogDebug("Received locations package."); try { if (HaveReceivedLocations) { Log.LogDebug("Already received locations previously. Skipping."); return; } CompressedPackage.Unpack(pkg); HaveReceivedLocations = true; Log.LogInfo("Successfully received and unpacked locations package."); } catch (Exception e) { Log.LogError("Error while attempting to read received locations package.", e); } } } } namespace Valheim.DropThat.Integrations { public static class InstallationManager { private static bool? _epicLootInstalled; private static bool? _rrrInstalled; public static bool EpicLootInstalled { get { bool valueOrDefault = _epicLootInstalled.GetValueOrDefault(); if (!_epicLootInstalled.HasValue) { valueOrDefault = (object)Type.GetType("EpicLoot.EpicLoot, EpicLoot") != null; _epicLootInstalled = valueOrDefault; return valueOrDefault; } return valueOrDefault; } } public static bool RRRInstalled { get { bool valueOrDefault = _rrrInstalled.GetValueOrDefault(); if (!_rrrInstalled.HasValue) { valueOrDefault = (object)Type.GetType("RRRCore.Plugin, RRRCore") != null; _rrrInstalled = valueOrDefault; return valueOrDefault; } return valueOrDefault; } } } } namespace Valheim.DropThat.Integrations.EpicLootIntegration { internal static class ItemRoller { internal static bool TryRollMagic(ItemData itemData, Vector3 dropPos, ItemRollParameters parameters) { //IL_0034: Unknown result type (might be due to invalid IL or missing references) //IL_003a: Unknown result type (might be due to invalid IL or missing references) if (!EpicLoot.CanBeMagicItem(itemData)) { return false; } Rarity rarity = ItemService.RollRarity(parameters); switch (rarity) { case Rarity.None: return false; case Rarity.Unique: return ItemService.TryMakeUnique(itemData, parameters); default: { ItemRarity? val = ItemService.RarityToItemRarity(rarity); if (val.HasValue) { ItemService.MakeMagic(val.Value, itemData, dropPos); return true; } return false; } } } } internal class ItemRollParameters { public float RarityWeightNone { get; set; } public float RarityWeightMagic { get; set; } public float RarityWeightRare { get; set; } public float RarityWeightEpic { get; set; } public float RarityWeightLegendary { get; set; } public float RarityWeightUnique { get; set; } public List<string> UniqueIds { get; set; } } internal static class ItemService { public static bool TryMakeUnique(ItemData itemData, ItemRollParameters parameters) { //IL_0055: Unknown result type (might be due to invalid IL or missing references) //IL_005a: Unknown result type (might be due to invalid IL or missing references) //IL_005c: Unknown result type (might be due to invalid IL or missing references) //IL_0061: Unknown result type (might be due to invalid IL or missing references) //IL_006d: Unknown result type (might be due to invalid IL or missing references) //IL_007a: Expected O, but got Unknown if (parameters.UniqueIds == null || parameters.UniqueIds.Count == 0) { return false; } string text = parameters.UniqueIds[Random.Range(0, parameters.UniqueIds.Count)]; LegendaryInfo val = default(LegendaryInfo); if (!UniqueLegendaryHelper.TryGetLegendaryInfo(text, ref val)) { Log.LogWarning("Attempted to roll Epic Loot unique legendary with id '" + text + "' but was unable to find matching info registered in Epic Loot."); return false; } MagicItem val2 = new MagicItem { Rarity = (ItemRarity)3, LegendaryID = val.ID, DisplayName = val.Name }; if (!val.Requirements.CheckRequirements(itemData, val2, (string)null)) { Log.LogWarning("Attempted to roll Epic Loot unique legendary with id '" + text + "' but requirements were not met. Skipping."); return false; } if (val.IsSetItem) { val2.SetID = UniqueLegendaryHelper.GetSetForLegendaryItem(val); } if ((val.GuaranteedMagicEffects?.Count ?? 0) > 0) { foreach (GuaranteedMagicEffect guaranteedMagicEffect in val.GuaranteedMagicEffects) { if (MagicItemEffectDefinitions.AllDefinitions.TryGetValue(guaranteedMagicEffect.Type, out var value)) { MagicItemEffect item = LootRoller.RollEffect(value, (ItemRarity)3, guaranteedMagicEffect.Values); val2.Effects.Add(item); continue; } Log.LogWarning("Unable to find a guaranteed Epic Loot magic effect '" + guaranteedMagicEffect.Type + "' while rolling unique legendary with id '" + text + "'. Skipping effect."); } } int num = LootRoller.RollEffectCountPerRarity((ItemRarity)3) - val2.Effects.Count; if (num > 0) { List<MagicItemEffectDefinition> availableEffects = MagicItemEffectDefinitions.GetAvailableEffects(itemData, val2, -1); for (int i = 0; i < num; i++) { MagicItemEffect item2 = LootRoller.RollEffect(RollWeightedEffect(availableEffects, removeSelected: false), (ItemRarity)3, (ValueDef)null); val2.Effects.Add(item2); } } ItemExtensions.Data(itemData).GetOrCreate<MagicItemComponent>("").SetMagicItem(val2); LootRoller.InitializeMagicItem(itemData); return true; } public static void MakeMagic(ItemRarity rarity, ItemData itemData, Vector3 position) { //IL_0010: Unknown result type (might be due to invalid IL or missing references) //IL_0017: Unknown result type (might be due to invalid IL or missing references) MagicItemComponent orCreate = ItemExtensions.Data(itemData).GetOrCreate<MagicItemComponent>(""); float luckFactor = LootRoller.GetLuckFactor(position); MagicItem magicItem = LootRoller.RollMagicItem(rarity, itemData, luckFactor); orCreate.SetMagicItem(magicItem); LootRoller.InitializeMagicItem(itemData); } private static MagicItemEffectDefinition RollWeightedEffect(List<MagicItemEffectDefinition> magicEffects, bool removeSelected) { float num = magicEffects.Sum((MagicItemEffectDefinition x) => x.SelectionWeight); float num2 = Random.Range(0f, num); float num3 = 0f; for (int i = 0; i < magicEffects.Count; i++) { MagicItemEffectDefinition val = magicEffects[i]; num3 += val.SelectionWeight; if (num2 <= num3) { if (removeSelected) { magicEffects.RemoveAt(i); } return val; } } return magicEffects.Last(); } public static Rarity RollRarity(ItemRollParameters parameters) { float num = parameters.RarityWeightNone + parameters.RarityWeightMagic + parameters.RarityWeightRare + parameters.RarityWeightEpic + parameters.RarityWeightLegendary + parameters.RarityWeightUnique; float num2 = Random.Range(0f, num); double num3 = 0.0; num3 += (double)parameters.RarityWeightUnique; if (parameters.RarityWeightUnique > 0f && (double)num2 <= num3) { return Rarity.Unique; } num3 += (double)parameters.RarityWeightLegendary; if (parameters.RarityWeightLegendary > 0f && (double)num2 <= num3) { return Rarity.Legendary; } num3 += (double)parameters.RarityWeightEpic; if (parameters.RarityWeightEpic > 0f && (double)num2 <= num3) { return Rarity.Epic; } num3 += (double)parameters.RarityWeightRare; if (parameters.RarityWeightRare > 0f && (double)num2 <= num3) { return Rarity.Rare; } num3 += (double)parameters.RarityWeightMagic; if (parameters.RarityWeightMagic > 0f && (double)num2 <= num3) { return Rarity.Magic; } return Rarity.None; } public static ItemRarity? RarityToItemRarity(Rarity rarity) { return rarity switch { Rarity.None => null, Rarity.Magic => (ItemRarity)0, Rarity.Rare => (ItemRarity)1, Rarity.Epic => (ItemRarity)2, Rarity.Legendary => (ItemRarity)3, Rarity.Unique => (ItemRarity)3, _ => null, }; } } internal enum Rarity { None, Magic, Rare, Epic, Legendary, Unique } } namespace Valheim.DropThat.Drop.DropTableSystem { public class DropModificationContext { public class CachedComponent<T> where T : Component { private T Component; private GameObject Source; private bool HasChecked; public CachedComponent(GameObject gameObject) { Source = gameObject; } public static implicit operator T(CachedComponent<T> cache) { if (!cache.HasChecked) { cache.Component = cache.Source.GetComponent<T>(); cache.HasChecked = true; } return cache.Component; } } public GameObject Drop { get; } public DropTemplate Template { get; } public CachedComponent<ItemDrop> ItemDrop { get; } public DropModificationContext(GameObject drop, DropTemplate template) { Drop = drop; Template = template; ItemDrop = new CachedComponent<ItemDrop>(drop); } } public class DropSourceTemplateLink { public GameObject Source; public DropTableEntityConfiguration EntityConfig; } public class DropTemplate { public DropTableEntityConfiguration EntityConfig { get; set; } public DropTableItemConfiguration Config { get; set; } public List<IDropTableCondition> Conditions { get; set; } = new List<IDropTableCondition>(); public List<IDropTableModifier> Modifiers { get; set; } = new List<IDropTableModifier>(); public DropData Drop { get; set; } } internal static class DropTableManager { private static readonly ItemData[] Item = (ItemData[])(object)new ItemData[1]; public static List<ItemData> GetItemDrops(DropTable dropTable, DropSourceTemplateLink context) { return GetDrops(dropTable, context, ConvertTemplateToItem); } public static List<GameObject> GetDrops(DropTable dropTable, DropSourceTemplateLink context) { return GetDrops(dropTable, context, ConvertTemplateToDrop); } private static List<T> GetDrops<T>(DropTable dropTable, DropSourceTemplateLink context, Func<DropTemplate, IEnumerable<T>> DropConverter) where T : class { //IL_0114: Unknown result type (might be due to invalid IL or missing references) //IL_0146: Unknown result type (might be due to invalid IL or missing references) List<DropTemplate> possibleDrops = DropConfigManager.GetPossibleDrops(context, dropTable); if (possibleDrops.Count == 0) { return new List<T>(0); } DropTableEntityConfiguration entityConfig = context.EntityConfig; if ((entityConfig == null) ? (Random.value > dropTable.m_dropChance) : (Random.value > (float)entityConfig.SetDropChance / 100f)) { return new List<T>(0); } List<DropTemplate> templates = new List<DropTemplate>(possibleDrops); templates = DropConditionManager.Filter(context, templates); float num = templates.Sum((DropTemplate x) => x.Drop.m_weight); int num2 = ((entityConfig == null) ? Random.Range(dropTable.m_dropMin, dropTable.m_dropMax + 1) : Random.Range((int)entityConfig.SetDropMin, (int)entityConfig.SetDropMax + 1)); bool flag = ((entityConfig == null) ? dropTable.m_oneOfEach : ((bool)entityConfig.SetDropOnlyOnce)); List<T> list = new List<T>(num2); for (int i = 0; i < num2; i++) { float num3 = Random.Range(0f, num); float num4 = 0f; try { bool flag2 = false; foreach (DropTemplate item in templates) { num4 += item.Drop.m_weight; if (num3 <= num4) { list.AddRange(DropConverter(item)); if (flag) { templates.Remove(item); num -= item.Drop.m_weight; } flag2 = true; break; } } if (!flag2 && templates.Count > 0) { list.AddRange(DropConverter(templates.First())); } } catch (Exception e) { Log.LogWarning("Error while rolling drop. Skipping roll\n", e); } } return list; } private static IEnumerable<ItemData> ConvertTemplateToItem(DropTemplate template) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_015c: Unknown result type (might be due to invalid IL or missing references) //IL_005b: Unknown result type (might be due to invalid IL or missing references) //IL_008d: Unknown result type (might be due to invalid IL or missing references) try { ItemData val = template.Drop.m_item.GetComponent<ItemDrop>().m_itemData.Clone(); int num = CalculateAmount(template); ConfigurationEntry<int> configurationEntry; ConfigurationEntry<float> configurationEntry2; if (num > val.m_shared.m_maxStackSize) { int num2 = Mathf.CeilToInt((float)num / (float)val.m_shared.m_maxStackSize); List<ItemData> list = new List<ItemData>(num2); int num3 = num; for (int i = 0; i < num2; i++) { ItemData val2 = template.Drop.m_item.GetComponent<ItemDrop>().m_itemData.Clone(); int num4 = Math.Min(num3, val.m_shared.m_maxStackSize); val2.m_dropPrefab = template.Drop.m_item.Wrap(); val2.m_stack = num4; configurationEntry = template.Config?.SetQualityLevel; val2.m_quality = ((configurationEntry == null) ? 1 : ((int)configurationEntry)); configurationEntry2 = template.Config?.SetDurability; val2.m_durability = ((((configurationEntry2 != null) ? ((float)configurationEntry2) : (-1f)) >= 0f) ? ((float)template.Config.SetDurability) : val2.m_durability); DropTemplateCache.RegisterTemplate(val2, template); DropTemplateCache.RegisterTemplate(val2.m_dropPrefab, template); list.Add(val2); num3 -= num4; } return list; } val.m_dropPrefab = template.Drop.m_item.Wrap(); val.m_stack = num; configurationEntry = template.Config?.SetQualityLevel; val.m_quality = ((configurationEntry == null) ? 1 : ((int)configurationEntry)); configurationEntry2 = template.Config?.SetDurability; val.m_durability = ((((configurationEntry2 != null) ? ((float)configurationEntry2) : (-1f)) >= 0f) ? ((float)template.Config.SetDurability) : val.m_durability); DropTemplateCache.RegisterTemplate(val, template); DropTemplateCache.RegisterTemplate(val.m_dropPrefab, template); Item[0] = val; return Item; } catch (Exception e) { Log.LogError("Error while attempting to prepare new item data", e); return Enumerable.Empty<ItemData>(); } } private static IEnumerable<GameObject> ConvertTemplateToDrop(DropTemplate template) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) GameObject val = template.Drop.m_item.Wrap(); DropTemplateCache.RegisterTemplate(val, template); int num = CalculateAmount(template); GameObject[] array = (GameObject[])(object)new GameObject[num]; for (int i = 0; i < num; i++) { array[i] = val; } return array; } private static int CalculateAmount(DropTemplate template) { //IL_0002: 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_0027: Unknown result type (might be due to invalid IL or missing references) int num = Math.Max(1, template.Drop.m_stackMin); int num2 = template.Drop.m_stackMax + 1; int num3 = Random.Range(num, num2); if (template.Drop.m_dontScale) { return num3; } float num4 = (float)num3 * Game.m_resourceRate; float num5 = num4 % 1f; int num6 = (int)num4; if (num5 > 0.001f && num5 <= Random.Range(0f, 1f)) { num6++; } return num6; } } } namespace Valheim.DropThat.Drop.DropTableSystem.Wrapper { internal class WrapperCache { public GameObject Wrapper { get; set; } public GameObject Wrapped { get; set; } public bool Unwrapped { get; set; } internal static ManagedCache<WrapperCache> Cache { get; } = new ManagedCache<WrapperCache>(); internal static WrapperCache Get(GameObject go) { if (Cache.TryGet((Object)(object)go, out var value)) { return value; } return null; } internal static void SetStatus(GameObject wrapper, bool unwrapped = false) { if (Cache.TryGet((Object)(object)wrapper, out var value)) { value.Unwrapped = unwrapped; } } internal static void Set(GameObject wrapper, GameObject wrapped, bool unwrapped = false) { Cache.Set((Object)(object)wrapper, new WrapperCache { Wrapper = wrapper, Wrapped = wrapped, Unwrapped = unwrapped }); } } public class WrapperComponent : MonoBehaviour { public void Start() { //IL_004a: Unknown result type (might be due to invalid IL or missing references) //IL_004f: Unknown result type (might be due to invalid IL or missing references) //IL_0051: Unknown result type (might be due to invalid IL or missing references) //IL_005d: Unknown result type (might be due to invalid IL or missing references) try { WrapperCache wrapperCache = WrapperCache.Get(((Component)this).gameObject); if ((wrapperCache == null || !wrapperCache.Unwrapped) && wrapperCache == null) { string cleanedName = ((Object)(object)((Component)this).gameObject).GetCleanedName(); GameObject prefab = ZNetScene.instance.GetPrefab(cleanedName); if (((Object)(object)prefab).IsNotNull()) { Vector3 position = ((Component)this).gameObject.transform.position; Object.Instantiate<GameObject>(prefab, position, ((Component)this).gameObject.transform.rotation); } } } catch (Exception e) { Log.LogError("Error during Wrapper.Start", e); } finally { Object.Destroy((Object)(object)((Component)this).gameObject); } } } public static class WrapperGameObjectExtensions { public static GameObject Wrap(this GameObject gameObject) { //IL_0010: Unknown result type (might be due to invalid IL or missing references) //IL_0015: Unknown result type (might be due to invalid IL or missing references) //IL_001c: Unknown result type (might be due to invalid IL or missing references) //IL_0024: Expected O, but got Unknown //IL_0025: Expected O, but got Unknown if (WrapperCache.Get(gameObject) != null) { return gameObject; } GameObject val = new GameObject(((Object)gameObject).name); val.AddComponent<WrapperComponent>(); WrapperCache.Set(val, gameObject); return val; } public static GameObject Unwrap(this GameObject gameObject) { if ((Object)(object)gameObject == (Object)null || !Object.op_Implicit((Object)(object)gameObject)) { return gameObject; } WrapperCache wrapperCache = WrapperCache.Get(gameObject); if (wrapperCache != null) { wrapperCache.Unwrapped = true; return wrapperCache.Wrapped; } return gameObject; } } } namespace Valheim.DropThat.Drop.DropTableSystem.Patches { internal static class Patch_DropSourceLink { [HarmonyPatch(typeof(Container))] internal static class Patch_Container_Awake_InitDropContext { [HarmonyPatch("Awake")] [HarmonyPrefix] private static void SetLink(Container __instance) { CreateLink(__instance.m_defaultItems, ((Component)__instance).gameObject); } } [HarmonyPatch(typeof(DropOnDestroyed))] internal static class Patch_DropOnDestroyed_Awake_InitDropContext { [HarmonyPatch("Awake")] [HarmonyPostfix] private static void SetLink(DropOnDestroyed __instance) { CreateLink(__instance.m_dropWhenDestroyed, ((Component)__instance).gameObject); } } [HarmonyPatch(typeof(LootSpawner))] internal static class Patch_LootSpawner_Awake_InitDropContext { [HarmonyPatch("Awake")] [HarmonyPostfix] private static void SetLink(LootSpawner __instance) { CreateLink(__instance.m_items, ((Component)__instance).gameObject); } } [HarmonyPatch(typeof(TreeBase))] internal static class Patch_TreeBase_Awake_InitDropContext { [HarmonyPatch("Awake")] [HarmonyPostfix] private static void SetLink(TreeBase __instance) { CreateLink(__instance.m_dropWhenDestroyed, ((Component)__instance).gameObject); } } [HarmonyPatch(typeof(TreeLog))] internal static class Patch_TreeLog_Awake_InitDropContext { [HarmonyPatch("Awake")] [HarmonyPostfix] private static void SetLink(TreeLog __instance) { CreateLink(__instance.m_dropWhenDestroyed, ((Component)__instance).gameObject); } } [HarmonyPatch(typeof(MineRock))] internal static class Patch_MineRock_Awake_InitDropContext { [HarmonyPatch("Start")] [HarmonyPostfix] private static void SetLink(MineRock __instance) { CreateLink(__instance.m_dropItems, ((Component)__instance).gameObject); } } [HarmonyPatch(typeof(MineRock5))] internal static class Patch_MineRock5_Awake_InitDropContext { [HarmonyPatch("Start")] [HarmonyPostfix] private static void SetLink(MineRock5 __instance) { CreateLink(__instance.m_dropItems, ((Component)__instance).gameObject); } } private static void CreateLink(DropTable dropTable, GameObject source) { try { if (dropTable == null || source == null) { return; } DropSourceTemplateLink dropSourceTemplateLink = new DropSourceTemplateLink { Source = source }; string cleanedName = ((Object)(object)source).GetCleanedName(); if (string.IsNullOrWhiteSpace(cleanedName)) { return; } if (ConfigurationManager.DropTableConfigs == null) { Log.LogDebug($"{source} woke before configs were loaded. Skipping config for '{source}'"); return; } if (ConfigurationManager.DropTableConfigs.TryGet(cleanedName, out var value)) { dropSourceTemplateLink.EntityConfig = value; } DropLinkCache.SetLink(dropTable, dropSourceTemplateLink); } catch (Exception e) { Log.LogError("Error while attempting to create associate drop table for object with config.", e); } } } [HarmonyPatch(typeof(DropTable))] internal static class Patch_DropTable_GetDrops_Overhaul { [HarmonyPatch("GetDropListItems")] [HarmonyTranspiler] private static IEnumerable<CodeInstruction> DropListItemsOverhaul(IEnumerable<CodeInstruction> instructions, ILGenerator generator) { //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_001a: Unknown result type (might be due to invalid IL or missing references) //IL_0020: Expected O, but got Unknown //IL_0048: Unknown result type (might be due to invalid IL or missing references) //IL_004e: Expected O, but got Unknown //IL_0061: Unknown result type (might be due to invalid IL or missing references) //IL_0067: Expected O, but got Unknown //IL_0086: Unknown result type (might be due to invalid IL or missing references) //IL_008c: Expected O, but got Unknown //IL_00b4: Unknown result type (might be due to invalid IL or missing references) //IL_00ba: Expected O, but got Unknown //IL_00d2: Unknown result type (might be due to invalid IL or missing references) //IL_00d8: Expected O, but got Unknown Label label = default(Label); return new CodeMatcher(instructions, generator).Start().InsertAndAdvance((CodeInstruction[])(object)new CodeInstruction[1] { new CodeInstruction(OpCodes.Ldarg_0, (object)null) }).InsertAndAdvance((CodeInstruction[])(object)new CodeInstruction[1] { new CodeInstruction(OpCodes.Call, (object)AccessTools.Method(typeof(Patch_DropTable_GetDrops_Overhaul), "GetDropListItems", (Type[])null, (Type[])null)) }) .InsertAndAdvance((CodeInstruction[])(object)new CodeInstruction[1] { new CodeInstruction(OpCodes.Ret, (object)null) }) .CreateLabel(ref label) .Start() .InsertAndAdvance((CodeInstruction[])(object)new CodeInstruction[1] { new CodeInstruction(OpCodes.Ldarg_0, (object)null) }) .InsertAndAdvance((CodeInstruction[])(object)new CodeInstruction[1] { new CodeInstruction(OpCodes.Call, (object)AccessTools.Method(typeof(Patch_DropTable_GetDrops_Overhaul), "UseOriginal", (Type[])null, (Type[])null)) }) .InsertAndAdvance((CodeInstruction[])(object)new CodeInstruction[1] { new CodeInstruction(OpCodes.Brtrue, (object)label) }) .InstructionEnumeration(); } [HarmonyPatch("GetDropList", new Type[] { typeof(int) })] [HarmonyTranspiler] private static IEnumerable<CodeInstruction> DropListOverhaul(IEnumerable<CodeInstruction> instructions, ILGenerator generator) { //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_001a: Unknown result type (might be due to invalid IL or missing references) //IL_0020: Expected O, but got Unknown //IL_0033: Unknown result type (might be due to invalid IL or missing references) //IL_0039: Expected O, but got Unknown //IL_0061: Unknown result type (might be due to invalid IL or missing references) //IL_0067: Expected O, but got Unknown //IL_007a: Unknown result type (might be due to invalid IL or missing references) //IL_0080: Expected O, but got Unknown //IL_009f: Unknown result type (might be due to invalid IL or missing references) //IL_00a5: Expected O, but got Unknown //IL_00cd: Unknown result type (might be due to invalid IL or missing references) //IL_00d3: Expected O, but got Unknown //IL_00eb: Unknown result type (might be due to invalid IL or missing references) //IL_00f1: Expected O, but got Unknown Label label = default(Label); return new CodeMatcher(instructions, generator).Start().InsertAndAdvance((CodeInstruction[])(object)new CodeInstruction[1] { new CodeInstruction(OpCodes.Ldarg_0, (object)null) }).InsertAndAdvance((CodeInstruction[])(object)new CodeInstruction[1] { new CodeInstruction(OpCodes.Ldarg_1, (object)null) }) .InsertAndAdvance((CodeInstruction[])(object)new CodeInstruction[1] { new CodeInstruction(OpCodes.Call, (object)AccessTools.Method(typeof(Patch_DropTable_GetDrops_Overhaul), "GetDropList", (Type[])null, (Type[])null)) }) .InsertAndAdvance((CodeInstruction[])(object)new CodeInstruction[1] { new CodeInstruction(OpCodes.Ret, (object)null) }) .CreateLabel(ref label) .Start() .InsertAndAdvance((CodeInstruction[])(object)new CodeInstruction[1] { new CodeInstruction(OpCodes.Ldarg_0, (object)null) }) .InsertAndAdvance((CodeInstruction[])(object)new CodeInstruction[1] { new CodeInstruction(OpCodes.Call, (object)AccessTools.Method(typeof(Patch_DropTable_GetDrops_Overhaul), "UseOriginal", (Type[])null, (Type[])null)) }) .InsertAndAdvance((CodeInstruction[])(object)new CodeInstruction[1] { new CodeInstruction(OpCodes.Brtrue, (object)label) }) .InstructionEnumeration(); } private static bool UseOriginal(DropTable dropTable) { return DropLinkCache.GetLink(dropTable)?.EntityConfig == null; } private static List<ItemData> GetDropListItems(DropTable dropTable) { try { DropSourceTemplateLink link = DropLinkCache.GetLink(dropTable); if (DropConfigManager.GetPossibleDrops(link, dropTable).Count == 0) { return new List<ItemData>(0); } return DropTableManager.GetItemDrops(dropTable, link); } catch (Exception e) { Log.LogError("Error during calculation of item drops", e); return new List<ItemData>(0); } } private static List<GameObject> GetDropList(DropTable dropTable, int dropCount) { try { DropSourceTemplateLink link = DropLinkCache.GetLink(dropTable); if (DropConfigManager.GetPossibleDrops(link, dropTable).Count == 0) { return new List<GameObject>(0); } return DropTableManager.GetDrops(dropTable, link); } catch (Exception e) { Log.LogError("Error during calculation of item drops", e); return new List<GameObject>(0); } } } [HarmonyPatch(typeof(MineRock5))] internal static class Patch_MineRock5_Fix_Naming { private static string _originalPrefabName { get; set; } [HarmonyPatch("Start")] private static void Prefix(MineRock5 __instance) { if (((Object)(object)__instance).IsNotNull() && ((Object)(object)((Component)__instance).gameObject).IsNotNull()) { _originalPrefabName = ((Object)((Component)__instance).gameObject).name; } } [HarmonyPatch("Start")] private static void Postfix(MineRock5 __instance) { if (((Object)(object)__instance).IsNotNull() && ((Object)(object)((Component)__instance).gameObject).IsNotNull() && _originalPrefabName != null) { ((Object)((Component)__instance).gameObject).name = _originalPrefabName; } } } internal static class Patch_OnDrop { [HarmonyPatch(typeof(Container))] internal static class Patch_Container_AddDefaultItems { [HarmonyPatch("AddDefaultItems")] [HarmonyTranspiler] private static IEnumerable<CodeInstruction> InsertItemManagement(IEnumerable<CodeInstruction> instructions) { //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_0020: Unknown result type (might be due to invalid IL or missing references) //IL_0026: Expected O, but got Unknown //IL_0039: Unknown result type (might be due to invalid IL or missing references) //IL_003f: Expected O, but got Unknown //IL_0067: Unknown result type (might be due to invalid IL or missing references) //IL_006d: Expected O, but got Unknown return new CodeMatcher(instructions, (ILGenerator)null).MatchForward(false, (CodeMatch[])(object)new CodeMatch[1] { new CodeMatch((OpCode?)OpCodes.Callvirt, (object)AddItemToInventory, (string)null) }).InsertAndAdvance((CodeInstruction[])(object)new CodeInstruction[1] { new CodeInstruction(OpCodes.Ldarg_0, (object)null) }).InsertAndAdvance((CodeInstruction[])(object)new CodeInstruction[1] { new CodeInstruction(OpCodes.Call, (object)AccessTools.Method(typeof(Patch_OnDrop), "ModifyContainerItem", (Type[])null, (Type[])null)) }) .InstructionEnumeration(); } } [HarmonyPatch(typeof(DropOnDestroyed))] internal static class Patch_DropOnDestroyed_OnDestroyed { [HarmonyPatch("OnDestroyed")] [HarmonyTranspiler] private static IEnumerable<CodeInstruction> InsertDropManagement(IEnumerable<CodeInstruction> instructions) { return instructions.InsertDropManagementInstructions(); } } [HarmonyPatch(typeof(LootSpawner))] internal static class Patch_LootSpawner_UpdateSpawner { [HarmonyPatch("UpdateSpawner")] [HarmonyTranspiler] private static IEnumerable<CodeInstruction> InsertDropManagement(IEnumerable<CodeInstruction> instructions) { return instructions.InsertDropManagementInstructions(); } } [HarmonyPatch(typeof(TreeLog))] internal static class Patch_TreeLog_Destroy { [HarmonyPatch("Destroy")] [HarmonyTranspiler] private static IEnumerable<CodeInstruction> InsertDropManagement(IEnumerable<CodeInstruction> instructions) { return instructions.InsertDropManagementInstructions(); } } [HarmonyPatch(typeof(TreeBase))] internal static class Patch_TreeBase_RPC_Damage { [HarmonyPatch("RPC_Damage")] [HarmonyTranspiler] private static IEnumerable<CodeInstruction> InsertDropManagement(IEnumerable<CodeInstruction> instructions) { return instructions.InsertDropManagementInstructions(); } } [HarmonyPatch(typeof(MineRock))] internal static class Patch_MineRock_RPC_Hit { [HarmonyPatch("RPC_Hit")] [HarmonyTranspiler] private static IEnumerable<CodeInstruction> InsertDropManagement(IEnumerable<CodeInstruction> instructions) { return instructions.InsertDropManagementInstructions(); } } [HarmonyPatch(typeof(MineRock5))] internal static class Patch_MineRock5_DamageArea { [HarmonyPatch("DamageArea")] [HarmonyTranspiler] private static IEnumerable<CodeInstruction> InsertDropManagement(IEnumerable<CodeInstruction> instructions) { return instructions.InsertDropManagementInstructions(); } } private static MethodInfo DropInstantiation = ReflectionUtils.InstantiateGameObjectMethod; private static MethodInfo AddItemToInventory = AccessTools.Method(typeof(Inventory), "AddItem", new Type[1] { typeof(ItemData) }, (Type[])null); private static MethodInfo UnwrapDropMethod = AccessTools.Method(typeof(Patch_OnDrop), "UnwrapDrop", (Type[])null, (Type[])null); private static MethodInfo ModifyDropMethod = AccessTools.Method(typeof(Patch_OnDrop), "ModifyDrop", (Type[])null, (Type[])null); private static GameObject _currentWrapped; private static ItemData _currentItem; private static IEnumerable<CodeInstruction> InsertDropManagementInstructions(this IEnumerable<CodeInstruction> instructions) { //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_0020: Unknown result type (might be due to invalid IL or missing references) //IL_0026: Expected O, but got Unknown //IL_0044: Unknown result type (might be due to invalid IL or missing references) //IL_004a: Expected O, but got Unknown //IL_0068: Unknown result type (might be due to invalid IL or missing references) //IL_006e: Expected O, but got Unknown //IL_0087: Unknown result type (might be due to invalid IL or missing references) //IL_008d: Expected O, but got Unknown //IL_00a4: Unknown result type (might be due to invalid IL or missing references) //IL_00aa: Expected O, but got Unknown return new CodeMatcher(instructions, (ILGenerator)null).MatchForward(false, (CodeMatch[])(object)new CodeMatch[1] { new CodeMatch((OpCode?)OpCodes.Call, (object)DropInstantiation, (string)null) }).Advance(-2).InsertAndAdvance((CodeInstruction[])(object)new CodeInstruction[1] { new CodeInstruction(OpCodes.Call, (object)UnwrapDropMethod) }) .MatchForward(true, (CodeMatch[])(object)new CodeMatch[1] { new CodeMatch((OpCode?)OpCodes.Call, (object)DropInstantiation, (string)null) }) .Advance(1) .InsertAndAdvance((CodeInstruction[])(object)new CodeInstruction[1] { new CodeInstruction(OpCodes.Dup, (object)null) }) .InsertAndAdvance((CodeInstruction[])(object)new CodeInstruction[1] { new CodeInstruction(OpCodes.Call, (object)ModifyDropMethod) }) .InstructionEnumeration(); } private static GameObject UnwrapDrop(GameObject wrappedDrop) { try { _currentWrapped = wrappedDrop; return wrappedDrop.Unwrap(); } catch (Exception e) { Log.LogError("Error while attempting to unwrap drop", e); return wrappedDrop; } } private static void ModifyDrop(GameObject drop) { try { DropTemplate template = DropTemplateCache.GetTemplate(_currentWrapped); if (template == null) { return; } DropModificationContext context = new DropModificationContext(drop, template); foreach (IDropTableModifier modifier in template.Modifiers) { try { modifier.Modify(context); } catch (Exception e) { Log.LogError($"Error while attempting to apply modifier '{modifier.GetType().Name}' to drop '{drop}'. Skipping modifier.", e); } } } catch (Exception e2) { Log.LogError($"Error while preparing to modify drop '{drop}'. Skipping modifiers.", e2); } _currentWrapped = null; } private static ItemData ModifyContainerItem(ItemData item, Container container) { //IL_0042: Unknown result type (might be due to invalid IL or missing references) try { item.m_dropPrefab = item.m_dropPrefab.Unwrap(); DropTemplate template = DropTemplateCache.GetTemplate(item); if (template == null) { return item; } foreach (IDropTableModifier modifier in template.Modifiers) { try { modifier.Modify(ref item, template, ((Component)container).transform.position); } catch (Exception e) { Log.LogError("Error while attempting to apply modifier '" + modifier.GetType().Name + "' to drop '" + ((Object)item.m_dropPrefab).name + "'. Skipping modifier.", e); } } } catch (Exception e2) { Log.LogError("Error while preparing to modify drop '" + ((Object)item.m_dropPrefab).name + "'. Skipping modifiers.", e2); } return item; } private static void RememberCurrentItem(ItemData itemData) { _currentItem = itemData; } } } namespace Valheim.DropThat.Drop.DropTableSystem.Modifiers { public interface IDropTableModifier { void Modify(DropModificationContext context); void Modify(ref ItemData drop, DropTemplate template, Vector3 position); } public class ModifierSetDurability : IDropTableModifier { private static ModifierSetDurability _instance; public static ModifierSetDurability Instance => _instance ?? (_instance = new ModifierSetDurability()); public void Modify(DropModificationContext context) { ConfigurationEntry<float> configurationEntry = context.Template?.Config?.SetDurability; float num = ((configurationEntry != null) ? ((float)configurationEntry) : (-1f)); if (!(num < 0f)) { ItemDrop val = context.ItemDrop; if (val != null) { Log.LogTrace($"Setting durability of item '{context.Drop}' to {num}"); val.m_itemData.m_durability = num; } } } public void Modify(ref ItemData drop, DropTemplate template, Vector3 position) { ConfigurationEntry<float> configurationEntry = template.Config?.SetDurability; float num = ((configurationEntry != null) ? ((float)configurationEntry) : (-1f)); if (!(num < 0f)) { drop.m_durability = num; } } } public class ModifierSetQualityLevel : IDropTableModifier { private static ModifierSetQualityLevel _instance; public static ModifierSetQualityLevel Instance => _instance ?? (_instance = new ModifierSetQualityLevel()); public void Modify(DropModificationContext context) { ConfigurationEntry<int> configurationEntry = context.Template?.Config?.SetQualityLevel; int num = ((configurationEntry != null) ? ((int)configurationEntry) : 0); if (num > 0) { ItemDrop val = context.ItemDrop; if (val != null) { Log.LogTrace($"Setting level of item '{context.Drop}' to {num}"); val.m_itemData.m_quality = num; } } } public void Modify(ref ItemData drop, DropTemplate template, Vector3 position) { ConfigurationEntry<int> configurationEntry = template.Config?.SetQualityLevel; int num = ((configurationEntry != null) ? ((int)configurationEntry) : 0); if (num > 0) { drop.m_quality = num; } } } } namespace Valheim.DropThat.Drop.DropTableSystem.Modifiers.ModSpecific.ModEpicLoot { internal class ModifierMagicItem : IDropTableModifier { private static ModifierMagicItem _instance; public static ModifierMagicItem Instance => _instance ?? (_instance = new ModifierMagicItem()); public void Modify(DropModificationContext context) { //IL_003a: Unknown result type (might be due to invalid IL or missing references) if (!InstallationManager.EpicLootInstalled) { return; } EpicLootItemConfiguration config = GetConfig(context.Template); if (config != null) { ItemDrop val = context.ItemDrop; if (!((Object)(object)val).IsNull() && ItemRoller.TryRollMagic(val.m_itemData, ((Component)val).transform.position, new ItemRollParameters { RarityWeightNone = config.RarityWeightNone, RarityWeightMagic = config.RarityWeightMagic, RarityWeightRare = config.RarityWeightRare, RarityWeightEpic = config.RarityWeightEpic, RarityWeightLegendary = config.RarityWeightLegendary, RarityWeightUnique = config.RarityWeightUnique, UniqueIds = config.UniqueIDs.Value.SplitByComma() })) { val.Save(); } } } public void Modify(ref ItemData drop, DropTemplate template, Vector3 position) { //IL_001b: Unknown result type (might be due to invalid IL or missing references) if (InstallationManager.EpicLootInstalled) { EpicLootItemConfiguration config = GetConfig(template); if (config != null && drop != null) { ItemRoller.TryRollMagic(drop, position, new ItemRollParameters { RarityWeightNone = config.RarityWeightNone, RarityWeightMagic = config.RarityWeightMagic, RarityWeightRare = config.RarityWeightRare, RarityWeightEpic = config.RarityWeightEpic, RarityWeightLegendary = config.RarityWeightLegendary, RarityWeightUnique = config.RarityWeightUnique, UniqueIds = config.UniqueIDs.Value.SplitByComma() }); } } } private EpicLootItemConfiguration GetConfig(DropTemplate template) { if (template == null) { return null; } if (template.Config.TryGet("EpicLoot", out var value) && value is EpicLootItemConfiguration result) { return result; } return null; } } } namespace Valheim.DropThat.Drop.DropTableSystem.Managers { internal static class DropConditionManager { public static List<DropTemplate> Filter(DropSourceTemplateLink context, List<DropTemplate> templates) { return templates.Where(delegate(DropTemplate template) { try { if ((template?.Conditions?.Count).GetValueOrDefault() == 0) { return true; } return !template.Conditions.Any(delegate(IDropTableCondition x) { try { return x?.ShouldFilter(context, template) ?? true; } catch (Exception e2) { Log.LogError($"Error while attempting to check condition '{x?.GetType()?.Name}' for '{template.Config.PrefabName}'. Condition will be ignored", e2); return true; } }); } catch (Exception e) { Log.LogError($"Error while attempting to check conditions for '{template?.Config?.PrefabName}'. Conditions will be ignored", e); return true; } }).ToList(); } } internal static class DropConfigManager { private static Dictionary<int, List<DropTemplate>> TemplateCache { get; set; } private static GeneralConfiguration GeneralConfig => ConfigurationManager.GeneralConfig; static DropConfigManager() { TemplateCache = new Dictionary<int, List<DropTemplate>>(); StateResetter.Subscribe(delegate { TemplateCache = new Dictionary<int, List<DropTemplate>>(); }); } public static List<DropTemplate> GetPossibleDrops(DropSourceTemplateLink context, DropTable dropTable) { int stableHashCode = StringExtensionMethods.GetStableHashCode(((Object)context.Source).name); if (TemplateCache.TryGetValue(stableHashCode, out var value)) { return new List<DropTemplate>(value); } List<DropTemplate> list = PrepareDrops(context, dropTable); TemplateCache[stableHashCode] = new List<DropTemplate>(list); return list; } private static List<DropTemplate> PrepareDrops(DropSourceTemplateLink context, DropTable dropTable) { //IL_014b: Unknown result type (might be due to invalid IL or missing references) //IL_0150: Unknown result type (might be due to invalid IL or missing references) //IL_0152: Unknown result type (might be due to invalid IL or missing references) //IL_0167: Unknown result type (might be due to invalid IL or missing references) List<DropTemplate> list = new List<DropTemplate>(); string text = context.EntityConfig?.UseDropList?.Value; DropTableListConfiguration dropTableListConfiguration = null; if (!string.IsNullOrWhiteSpace(text) && ConfigurationManager.DropTableLists != null && ConfigurationManager.DropTableLists.TryGet(text, out var value)) { dropTableListConfiguration = value; } bool flag = false; if ((bool)GeneralConfig.ClearAllExistingDropTables) { goto IL_0133; } if ((bool)GeneralConfig.ClearAllExistingDropTablesWhenModified) { DropTableEntityConfiguration entityConfig = context.EntityConfig; if ((entityConfig != null && entityConfig.Subsections?.Any((KeyValuePair<string, DropTableItemConfiguration> x) => x.Value.EnableConfig) == true) || (dropTableListConfiguration != null && dropTableListConfiguration.Subsections?.Any((KeyValuePair<string, DropTableItemConfiguration> x) => x.Value.EnableConfig) == true)) { goto IL_0133; } } goto IL_0136; IL_0133: flag = true; goto IL_0136; IL_0136: if (!flag) { foreach (DropData drop in dropTable.m_drops) { if (!(drop.m_weight <= 0f)) { list.Add(new DropTemplate { Drop = drop }); } } } if (context.EntityConfig == null) { return list; } foreach (DropTableItemConfiguration item in MergeAndOrder(dropTableListConfiguration, context.EntityConfig)) { InsertDrop(list, item, context.EntityConfig); } return list; } private static void InsertDrop(List<DropTemplate> drops, DropTableItemConfiguration itemConfig, DropTableEntityConfiguration entityConfig) { //IL_00a5: Unknown result type (might be due to invalid IL or missing references) //IL_00fb: Unknown result type (might be due to invalid IL or missing references) if (!itemConfig.EnableConfig || (float)itemConfig.SetTemplateWeight <= 0f) { return; } GameObject val = ObjectDB.instance.GetItemPrefab(itemConfig.PrefabName.Value); if (((Object)(object)val).IsNull()) { val = ZNetScene.instance.GetPrefab(itemConfig.PrefabName.Value); } if (((Object)(object)val).IsNull()) { Log.LogWarning("Unable to find prefab '" + itemConfig.PrefabName.Value + "' for '" + itemConfig.SectionKey + "'."); return; } DropTemplate item = new DropTemplate { Drop = new DropData { m_item = val, m_weight = itemConfig.SetTemplateWeight, m_stackMin = itemConfig.SetAmountMin, m_stackMax = itemConfig.SetAmountMax, m_dontScale = itemConfig.DisableResourceModifierScaling }, Conditions = ExtractConditions(itemConfig), Modifiers = ExtractModifiers(itemConfig), Config = itemConfig, EntityConfig = entityConfig }; if ((bool)GeneralConfig.AlwaysAppendCharacterDrops) { drops.Add(item); return; } int index = itemConfig.Index; if (drops.Count > index && index >= 0) { drops.RemoveAt(index); } if (index >= 0 && index <= drops.Count) { drops.Insert(index, item); } else { drops.Add(item); } } private static List<IDropTableCondition> ExtractConditions(DropTableItemConfiguration config) { List<IDropTableCondition> list = new List<IDropTableCondition>(); list.AddNullSafe(Valheim.DropThat.Drop.DropTableSystem.Conditions.ConditionBiome.Instance); list.AddNullSafe(ConditionAltitude.Instance); list.AddNullSafe(Valheim.DropThat.Drop.DropTableSystem.Conditions.ConditionDaytime.Instance); list.AddNullSafe(Valheim.DropThat.Drop.DropTableSystem.Conditions.ConditionEnvironments.Instance); list.AddNullSafe(ConditionGlobalKeysRequired.Instance); list.AddNullSafe(Valheim.DropThat.Drop.DropTableSystem.Conditions.ConditionLocation.Instance); list.AddNullSafe(Valheim.DropThat.Drop.DropTableSystem.Conditions.ConditionDistanceToCenter.Instance); list.AddNullSafe(Valheim.DropThat.Drop.DropTableSystem.Conditions.ModSpecific.ConditionLoaderCLLC.ConditionWorldLevel); return list; } private static List<IDropTableModifier> ExtractModifiers(DropTableItemConfiguration config) { List<IDropTableModifier> list = new List<IDropTableModifier>(); list.AddNullSafe(Valheim.DropThat.Drop.DropTableSystem.Modifiers.ModifierSetQualityLevel.Instance); if (InstallationManager.EpicLootInstalled && config.TryGet("EpicLoot", out var value) && value is EpicLootItemConfiguration) { list.AddNullSafe(Valheim.DropThat.Drop.DropTableSystem.Modifiers.ModSpecific.ModEpicLoot.ModifierMagicItem.Instance); } list.AddNullSafe(Valheim.DropThat.Drop.DropTableSystem.Modifiers.ModifierSetDurability.Instance); return list; } private static IEnumerable<DropTableItemConfiguration> MergeAndOrder(DropTableListConfiguration list, DropTableEntityConfiguration entity) { Dictionary<int, DropTableItemConfiguration> dictionary = new Dictionary<int, DropTableItemConfiguration>(); if (list != null) { foreach (DropTableItemConfiguration value in list.Subsections.Values) { if ((bool)value.EnableConfig) { dictionary[value.Index] = value; } } } if (entity != null) { foreach (DropTableItemConfiguration value2 in entity.Subsections.Values) { if ((bool)value2.EnableConfig) { dictionary[value2.Index] = value2; } } } return dictionary.Values.OrderBy((DropTableItemConfiguration x) => x.Index); } } } namespace Valheim.DropThat.Drop.DropTableSystem.Debug { [HarmonyPatch(typeof(DungeonDB))] internal static class Patch_DungeonDB_Start { [HarmonyPatch("Start")] [HarmonyPostfix] private static void WriteDropTableData() { if ((bool)ConfigurationManager.GeneralConfig?.WriteDropTablesToFiles) { DropTableDataWriter.PrintDungeonDropTables(); } } } [HarmonyPatch(typeof(ZoneSystem))] internal static class Patch_ZoneSystem_Start { [HarmonyPatch("Start")] [HarmonyPostfix] private static void WriteDropTableData() { if ((bool)ConfigurationManager.GeneralConfig?.WriteDropTablesToFiles) { DropTableDataWriter.PrintPrefabDropTables(); DropTableDataWriter.PrintLocationDropTables(); } } } internal static class DropTableDataWriter { private static string GetData(MonoBehaviour source, DropTable dropTable, string[] additionalHeaders) { //IL_0107: Unknown result type (might be due to invalid IL or missing references) //IL_010c: Unknown result type (might be due to invalid IL or missing references) //IL_0133: Unknown result type (might be due to invalid IL or missing references) //IL_0148: 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_01ae: Unknown result type (might be due to invalid IL or missing references) //IL_01d0: Unknown result type (might be due to invalid IL or missing references) StringBuilder stringBuilder = new StringBuilder(); string cleanedName = ((Object)(object)((Component)source).gameObject).GetCleanedName(); if (string.IsNullOrWhiteSpace(cleanedName)) { return ""; } stringBuilder.AppendLine(); stringBuilder.AppendLine("## DropTable Source: " + ((object)source).GetType().Name + "; " + GeneralExtensions.Join<string>((IEnumerable<string>)additionalHeaders, (Func<string, string>)null, "; ")); stringBuilder.AppendLine("[" + cleanedName + "]"); stringBuilder.AppendLine("SetDropChance = " + (dropTable.m_dropChance * 100f).ToString(CultureInfo.InvariantCulture)); stringBuilder.AppendLine(string.Format("{0} = {1}", "SetDropOnlyOnce", dropTable.m_oneOfEach)); stringBuilder.AppendLine(string.Format("{0} = {1}", "SetDropMin", dropTable.m_dropMin)); stringBuilder.AppendLine(string.Format("{0} = {1}", "SetDropMax", dropTable.m_dropMax)); for (int i = 0; i < dropTable.m_drops.Count; i++) { DropData val = dropTable.m_drops[i]; stringBuilder.AppendLine(); stringBuilder.AppendLine($"[{cleanedName}.{i}]"); stringBuilder.AppendLine("PrefabName = " + (((Object)(object)val.m_item).IsNotNull() ? ((Object)val.m_item).name : "")); stringBuilder.AppendLine("SetTemplateWeight = " + val.m_weight.ToString(CultureInfo.InvariantCulture)); stringBuilder.AppendLine(string.Format("{0} = {1}", "SetAmountMin", val.m_stackMin)); stringBuilder.AppendLine(string.Format("{0} = {1}", "SetAmountMax", val.m_stackMax)); stringBuilder.AppendLine(string.Format("{0} = {1}", "DisableResourceModifierScaling", val.m_dontScale)); } return stringBuilder.ToString(); } internal static void PrintDungeonDropTables() { //IL_0094: Unknown result type (might be due to invalid IL or missing references) //IL_0166: Unknown result type (might be due to invalid IL or missing references) //IL_0192: Unknown result type (might be due to invalid IL or missing references) IOrderedEnumerable<ZoneLocation> orderedEnumerable = from x in ZoneSystem.instance.m_locations where x.m_enable orderby x.m_biome, x.m_prefabName select x; List<string> list = new List<string>(); foreach (ZoneLocation item in orderedEnumerable) { item.m_prefab.Load(); GameObject asset = item.m_prefab.Asset; if (((Object)(object)asset).IsNull()) { continue; } DungeonGenerator[] componentsInChildren = asset.GetComponentsInChildren<DungeonGenerator>(); if (componentsInChildren == null || componentsInChildren.Length == 0) { continue; } DungeonGenerator[] array = componentsInChildren; foreach (DungeonGenerator dungeon in array) { List<Room> list2 = (from x in DungeonDB.GetRooms().Select(delegate(RoomData x) { //IL_0006: Unknown result type (might be due to invalid IL or missing references) x.m_prefab.Load(); return x.RoomInPrefab; }) where ((Object)(object)x).IsNotNull() && (Theme)(x.m_theme & dungeon.m_themes) == x.m_theme select x).ToList(); if (list2 == null || list2.Count == 0) { continue; } foreach (Room item2 in list2) { list.AddRange(Extract(((Component)item2).gameObject, "Biome: " + item.m_biome.GetNames(), "Location: " + item.m_prefabName, $"Room Theme: {item2.m_theme}", "Room: " + ((Object)item2).name)); } } } PrintDebugFile.PrintFile(list, "drop_that.drop_table.dungeons.txt", "drop tables for dungeons"); } internal static void PrintLocationDropTables() { //IL_0091: Unknown result type (might be due to invalid IL or missing references) //IL_00bb: Unknown result type (might be due to invalid IL or missing references) IOrderedEnumerable<ZoneLocation> orderedEnumerable = from x in ZoneSystem.instance.m_locations where x.m_enable orderby x.m_biome, x.m_prefabName select x; List<string> list = new List<string>(); foreach (ZoneLocation item in orderedEnumerable) { item.m_prefab.Load(); GameObject asset = item.m_prefab.Asset; if (!((Object)(object)asset).IsNull()) { list.AddRange(Extract(asset, "Biome: " + item.m_biome.GetNames(), "Location: " + item.m_prefabName)); } } PrintDebugFile.PrintFile(list, "drop_that.drop_table.locations.txt", "drop tables for locations"); } internal static void PrintPrefabDropTables() { List<string> list = new List<string>(); foreach (GameObject prefab in ZNetScene.instance.m_prefabs) { list.AddRange(Extract(prefab)); } PrintDebugFile.PrintFile(list, "drop_that.drop_table.prefabs.txt", "drop tables for prefabs"); } private static List<string> Extract(GameObject prefab, params string[] additionalHeaders) { List<string> list = new List<string>(); Container componentInChildren = prefab.GetComponentInChildren<Container>(); if (((Object)(object)componentInChildren).IsNotNull() && Object.op_Implicit((Object)(object)componentInChildren)) { list.Add(GetData((MonoBehaviour)(object)componentInChildren, componentInChildren.m_defaultItems, additionalHeaders)); } DropOnDestroyed componentInChildren2 = prefab.GetComponentInChildren<DropOnDestroyed>(); if (((Object)(object)componentInChildren2).IsNotNull() && Object.op_Implicit((Object)(object)componentInChildren2)) { list.Add(GetData((MonoBehaviour)(object)componentInChildren2, componentInChildren2.m_dropWhenDestroyed, additionalHeaders)); } LootSpawner componentInChildren3 = prefab.GetComponentInChildren<LootSpawner>(); if (((Object)(object)componentInChildren3).IsNotNull() && Object.op_Implicit((Object)(object)componentInChildren3)) { list.Add(GetData((MonoBehaviour)(object)componentInChildren3, componentInChildren3.m_items, additionalHeaders)); } TreeBase componentInChildren4 = prefab.GetComponentInChildren<TreeBase>(); if (((Object)(object)componentInChildren4).IsNotNull() && Object.op_Implicit((Object)(object)componentInChildren4)) { list.Add(GetData((MonoBehaviour)(object)componentInChildren4, componentInChildren4.m_dropWhenDestroyed, additionalHeaders)); } TreeLog componentInChildren5 = prefab.GetComponentInChildren<TreeLog>(); if (((Object)(object)componentInChildren5).IsNotNull() && Object.op_Implicit((Object)(object)componentInChildren5)) { list.Add(GetData((MonoBehaviour)(object)componentInChildren5, componentInChildren5.m_dropWhenDestroyed, additionalHeaders)); } MineRock componentInChildren6 = prefab.GetComponentInChildren<MineRock>(); if (((Object)(object)componentInChildren6).IsNotNull() && Object.op_Implicit((Object)(object)componentInChildren6)) { list.Add(GetData((MonoBehaviour)(object)componentInChildren6, componentInChildren6.m_dropItems, additionalHeaders)); } MineRock5 componentInChildren7 = prefab.GetComponentInChildren<MineRock5>(); if (((Object)(object)componentInChildren7).IsNotNull() && Object.op_Implicit((Object)(object)componentInChildren7)) { list.Add(GetData((MonoBehaviour)(object)componentInChildren7, componentInChildren7.m_dropItems, additionalHeaders)); } return list; } } } namespace Valheim.DropThat.Drop.DropTableSystem.Conditions { public class ConditionAltitude : IDropTableCondition { private static ConditionAltitude _instance; public static ConditionAltitude Instance => _instance ?? (_instance = new ConditionAltitude()); public bool ShouldFilter(DropSourceTemplateLink context, DropTemplate template) { //IL_000c: Unknown result type (might be due to invalid IL or missing references) //IL_002c: Unknown result type (might be due to invalid IL or missing references) if (IsValid(context.Source.transform.position, template?.Config)) { return false; } Log.LogTrace("Filtered drop '" + ((Object)template.Drop.m_item).name + "' due being outside required altitude."); return true; } public bool IsValid(Vector3 position, DropTableItemConfiguration config) { //IL_0005: Unknown result type (might be due to invalid IL or missing references) if (config == null) { return true; } float num = position.y - ZoneSystem.instance.m_waterLevel; if (num < (float)config.ConditionAltitudeMin) { return false; } if (num > (float)config.ConditionAltitudeMax) { return false; } return true; } } public class ConditionBiome : IDropTableCondition { private static ConditionBiome _instance; public static ConditionBiome Instance => _instance ?? (_instance = new ConditionBiome()); public bool ShouldFilter(DropSourceTemplateLink context, DropTemplate template) { //IL_000c: Unknown result type (might be due to invalid IL or missing references) //IL_002c: Unknown result type (might be due to invalid IL or missing references) if (IsValid(context.Source.transform.position, template?.Config)) { return false; } Log.LogTrace("Filtered drop '" + ((Object)template.Drop.m_item).name + "' due being outside required biome."); return true; } public bool IsValid(Vector3 position, DropTableItemConfiguration config) { //IL_0030: Unknown result type (might be due to invalid IL or missing references) //IL_0031: Unknown result type (might be due to invalid IL or missing references) //IL_0036: Unknown result type (might be due to invalid IL or missing references) if (config == null) { return true; } if (string.IsNullOrWhiteSpace(config.ConditionBiomes.Value)) { return true; } List<string> source = config.ConditionBiomes.Value.SplitByComma(toUpper: true); Biome val = Heightmap.FindBiome(position); string currentBiomeCleaned = ((object)(Biome)(ref val)).ToString().ToUpperInvariant(); return source.Any((string x) => x == currentBiomeCleaned); } } public class ConditionDaytime : IDropTableCondition { private static ConditionDaytime _instance; public static ConditionDaytime Instance => _instance ?? (_instance = new ConditionDaytime()); public bool ShouldFilter(DropSourceTemplateLink context, DropTemplate template) { //IL_001c: Unknown result type (might be due to invalid IL or missing references) if (IsValid(template?.Config)) { return false; } Log.LogTrace("Filtered drop '" + ((Object)template.Drop.m_item).name + "' due being outside allowed time of day."); return true; } public bool IsValid(DropTableItemConfiguration config) { if (config == null) { return true; } EnvMan instance = EnvMan.instance; if ((bool)config.ConditionNotDay && instance.IsDay()) { return false; } if ((bool)config.ConditionNotAfternoon && instance.IsAfternoon()) { return false; } if ((bool)config.ConditionNotNight && instance.IsNight()) { return false; } return true; } } public class ConditionDistanceToCenter : IDropTableCondition { private static ConditionDistanceToCenter _instance; public static ConditionDistanceToCenter Instance => _instance ?? (_instance = new ConditionDistanceToCenter()); public bool ShouldFilter(DropSourceTemplateLink context, DropTemplate template) { //IL_000c: Unknown result type (might be due to invalid IL or missing references) //IL_002c: Unknown result type (might be due to invalid IL or missing references) if (IsValid(context.Source.transform.position, template?.Config)) { return false; } Log.LogTrace("Filtered drop '" + ((Object)template.Drop.m_item).name + "' due not being within required distance to center of map."); return true; } public bool IsValid(Vector3 position, DropTableItemConfiguration config) { if (config == null) { return true; } float magnitude = ((Vector3)(ref position)).magnitude; if (magnitude < config.ConditionDistanceToCenterMin.Value) { return false; } if (config.ConditionDistanceToCenterMax.Value > 0f && magnitude > config.ConditionDistanceToCenterMax.Value) { return false; } return true; } } public class ConditionEnvironments : IDropTableCondition { private static ConditionEnvironments _instance; public static ConditionEnvironments Instance => _instance ?? (_instance = new ConditionEnvironments()); public bool ShouldFilter(DropSourceTemplateLink context, DropTemplate template) { //IL_0016: Unknown result type (might be due to invalid IL or missing references) if (IsValid(template.Config)) { return false; } Log.LogTrace("Filtered drop '" + ((Object)template.Drop.m_item).name + "' due to current environment."); return true; } public bool IsValid(DropTableItemConfiguration config) { if (string.IsNullOrEmpty(config.ConditionEnvironments.Value)) { return true; } EnvMan instance = EnvMan.instance; string currentEnv = instance.GetCurrentEnvironment().m_name.Trim().ToUpperInvariant(); List<string> list = config.ConditionEnvironments.Value.SplitByComma(toUpper: true); if (list.Count == 0) { return true; } if (list.Any((string x) => x == currentEnv)) { return true; } return false; } } public class ConditionGlobalKeysRequired : IDropTableCondition { private static ConditionGlobalKeysRequired _instance; public static ConditionGlobalKeysRequired Instance => _instance ?? (_instance = new ConditionGlobalKeysRequired()); public bool ShouldFilter(DropSourceTemplateLink context, DropTemplate template) { //IL_0016: Unknown result type (might be due to invalid IL or missing references) if (IsValid(template.Config)) { return false; } Log.LogTrace("Filtered drop '" + ((Object)template.Drop.m_item).name + "' due to not finding required global key."); return true; } public bool IsValid(DropTableItemConfiguration config) { if (string.IsNullOrEmpty(config.ConditionGlobalKeys.Value)) { return true; } List<string> list = config.ConditionGlobalKeys.Value.SplitByComma(); if (list.Count == 0) { return true; } if (list.Any((string x) => ZoneSystem.instance.GetGlobalKey(x))) { return true; } return false; } } public class ConditionLocation : IDropTableCondition { private static ConditionLocation _instance; public static ConditionLocation Instance => _instance ?? (_instance = new ConditionLocation()); public bool ShouldFilter(DropSourceTemplateLink context, DropTemplate template) { //IL_000c: 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) if (IsValid(context.Source.transform.position, template.Config)) { return false; } Log.LogTrace("Filtered drop '" + ((Object)template.Drop.m_item).name + "' due to not being in required location."); return true; } public bool IsValid(Vector3 position, DropTableItemConfiguration config) { //IL_0043: Unknown result type (might be due to invalid IL or missing references) if (string.IsNullOrWhiteSpace(config?.ConditionLocations?.Value)) { return true; } List<string> list = config.ConditionLocations.Value.SplitByComma(toUpper: true); if (list.Count == 0) { return true; } SimpleLocation simpleLocation = LocationHelper.FindLocation(position); string currentLocationName = simpleLocation.LocationName.Trim().ToUpperInvariant(); return list.Any((string x) => x == currentLocationName); } } public interface IDropTableCondition { bool ShouldFilter(DropSourceTemplateLink context, DropTemplate template); } } namespace Valheim.DropThat.Drop.DropTableSystem.Conditions.ModSpecific { internal static class ConditionLoaderCLLC { public static bool InstalledCLLC { get; } = (object)Type.GetType("CreatureLevelControl.API, CreatureLevelControl") != null; public static Valheim.DropThat.Drop.DropTableSystem.Conditions.ModSpecific.ModCLLC.ConditionWorldLevel ConditionWorldLevel { get { if (!InstalledCLLC) { return null; } return Valheim.DropThat.Drop.DropTableSystem.Conditions.ModSpecific.ModCLLC.ConditionWorldLevel.Instance; } } } } namespace Valheim.DropThat.Drop.DropTableSystem.Conditions.ModSpecific.ModCLLC { public class ConditionWorldLevel : IDropTableCondition { private static ConditionWorldLevel _instance; public static ConditionWorldLevel Instance => _instance ?? (_instance = new ConditionWorldLevel()); public bool ShouldFilter(DropSourceTemplateLink context, DropTemplate template) { //IL_001c: Unknown result type (might be due to invalid IL or missing references) if (IsValid(template?.Config)) { return false; } Log.LogTrace("Filtered drop '" + ((Object)template.Drop.m_item).name + "' due to not being within required CLLC world level."); return true; } public bool IsValid(DropTableItemConfiguration itemConfig) { if (itemConfig == null) { return true; } if (itemConfig.TryGet("CreatureLevelAndLootControl", out var value) && value is DropTableModConfigCLLC dropTableModConfigCLLC) { int worldLevel = API.GetWorldLevel(); if (worldLevel < (int)dropTableModConfigCLLC.ConditionWorldLevelMin) { return false; } if ((int)dropTableModConfigCLLC.ConditionWorldLevelMax > 0 && worldLevel > (int)dropTableModConfigCLLC.ConditionWorldLevelMax) { return false; } } return true; } } } namespace Valheim.DropThat.Drop.DropTableSystem.Caches { internal static class DropLinkCache { private static ConditionalWeakTable<DropTable, DropSourceTemplateLink> LinkTable = new ConditionalWeakTable<DropTable, DropSourceTemplateLink>(); public static DropSourceTemplateLink GetLink(DropTable key) { if (LinkTable.TryGetValue(key, out var value)) { return value; } return null; } public static void SetLink(DropTable key, DropSourceTemplateLink context) { if (context != null) { LinkTable.Add(key, context); } } } internal class DropTemplateCache { private static ManagedCache<DropTemplate> DropTemplates { get; } = new ManagedCache<DropTemplate>(); private static ConditionalWeakTable<ItemData, DropTemplateCache> ItemTemplates { get; } = new ConditionalWeakTable<ItemData, DropTemplateCache>(); public DropTemplate Template { get; set; } public static void RegisterTemplate(GameObject drop, DropTemplate template) { DropTemplates.Set((Object)(object)drop, template); } public static void RegisterTemplate(ItemData item, DropTemplate template) { ItemTemplates.GetOrCreateValue(item).Template = template; } public static DropTemplate GetTemplate(ItemData item) { if (ItemTemplates.TryGetValue(item, out var value)) { return value.Template; } return null; } public static DropTemplate GetTemplate(GameObject drop) { if (DropTemplates.TryGet((Object)(object)drop, out var value)) { return value; } return null; } } } namespace Valheim.DropThat.Drop.CharacterDropSystem { public class ConditionChecker { private HashSet<ICondition> OnStartConditions; private HashSet<ICondition> OnDeathConditions; private static ConditionChecker _instance; public static ConditionChecker Instance => _instance ?? (_instance = new ConditionChecker()); private ConditionChecker() { StateResetter.Subscribe(delegate { _instance = null; }); OnStartConditions = new HashSet<ICondition>(); OnStartConditions.AddNullSafe(ConditionInventory.Instance); OnStartConditions.AddNullSafe(Valheim.DropThat.Drop.CharacterDropSystem.Conditions.ConditionLocation.Instance); OnStartConditions.AddNullSafe(Valheim.DropThat.Drop.CharacterDropSystem.Conditions.ConditionDistanceToCenter.Instance); OnStartConditions.AddNullSafe(Valheim.DropThat.Drop.CharacterDropSystem.Conditions.ConditionBiome.Instance); OnDeathConditions = new HashSet<ICondition>(); OnDeathConditions.AddNullSafe(ConditionCreatureState.Instance); OnDeathConditions.AddNullSafe(ConditionLoaderSpawnThat.ConditionTemplateId); OnDeathConditions.AddNullSafe(ConditionFaction.Instance); OnDeathConditions.AddNullSafe(ConditionNotFaction.Instance); OnDeathConditions.AddNullSafe(ConditionKilledByDamageType.Instance); OnDeathConditions.AddNullSafe(ConditionKilledBySkillType.Instance); OnDeathConditions.AddNullSafe(ConditionKilledWithStatus.Instance); OnDeathConditions.AddNullSafe(ConditionKilledWithStatuses.Instance); OnDeathConditions.AddNullSafe(ConditionKilledByEntityType.Instance); OnDeathConditions.AddNullSafe(Valheim.DropThat.Drop.CharacterDropSystem.Conditions.ConditionEnvironments.Instance); OnDeathConditions.AddNullSafe(ConditionGlobalKeys.Instance); OnDeathConditions.AddNullSafe(ConditionLevel.Instance); OnDeathConditions.AddNullSafe(Valheim.DropThat.Drop.CharacterDropSystem.Conditions.ConditionDaytime.Instance); OnDeathConditions.AddNullSafe(ConditionHitByEntityTypeRecently.Instance); OnDeathConditions.AddNullSafe(Valheim.DropThat.Drop.CharacterDropSystem.Conditions.ModSpecific.ConditionLoaderCLLC.ConditionBossAffix); OnDeathConditions.AddNullSafe(Valheim.DropThat.Drop.CharacterDropSystem.Conditions.ModSpecific.ConditionLoaderCLLC.ConditionInfusion); OnDeathConditions.AddNullSafe(Valheim.DropThat.Drop.CharacterDropSystem.Conditions.ModSpecific.ConditionLoaderCLLC.ConditionCreatureExtraEffect); OnDeathConditions.AddNullSafe(Valheim.DropThat.Drop.CharacterDropSystem.Conditions.ModSpecific.ConditionLoaderCLLC.ConditionWorldLevel); } public static List<Drop> FilterOnStart(CharacterDrop characterDrop) { try { return Instance.Filter(characterDrop, Instance.OnStartConditions); } catch (Exception e) { Log.LogError("Error while attempting to run OnStart conditions. Skipping filtering.", e); return characterDrop.m_drops; } } public static List<Drop> FilterOnDeath(CharacterDrop characterDrop) { try { return Instance.Filter(characterDrop, Instance.OnDeathConditions); } catch (Exception e) { Log.LogError("Error while attempting to run OnDeath conditions. Skipping filtering.", e); return characterDrop.m_drops; } } public List<Drop> Filter(CharacterDrop characterDrop, IEnumerable<ICondition> conditions) { List<Drop> list = new List<Drop>(); foreach (Drop drop in characterDrop.m_drops) { DropExtended dropExtended = DropExtended.GetExtension(drop); if (dropExtended == null) { list.Add(drop); } else if (!conditions.Any((ICondition x) => x?.ShouldFilter(drop, dropExtended, characterDrop) ?? false)) { list.Add(drop); } } return list; } } public class DropContext { public GameObject Item { get; set; } public DropExtended Extended { get; set; } public Vector3 Pos { get; set; } } public class DropModificationManager { private HashSet<IDropModifier> DropModifiers = new HashSet<IDropModifier>(); private static DropModificationManager _instance; public static DropModificationManager Instance => _instance ?? (_instance = new DropModificationManager()); private DropModificationManager() { StateResetter.Subscribe(delegate { _instance = null; }); DropModifiers.AddNullSafe(Valheim.DropThat.Drop.CharacterDropSystem.Modifiers.ModifierSetQualityLevel.Instance); DropModifiers.AddNullSafe(ModifierLoaderEpicLoot.MagicItem); DropModifiers.AddNullSafe(Valheim.DropThat.Drop.CharacterDropSystem.Modifiers.ModifierSetDurability.Instance); } public void ApplyModifications(GameObject item, DropExtended extended, Vector3 pos) { //IL_001b: Unknown result type (might be due to invalid IL or missing references) if (item == null || extended == null) { return; } DropContext context = new DropContext { Item = item, Extended = extended, Pos = pos }; foreach (IDropModifier dropModifier in DropModifiers) { try { dropModifier?.Modify(context); } catch (Exception e) { Log.LogError("Error while attempting to modify item drop " + ((Object)item).name, e); } } } } } namespace Valheim.DropThat.Drop.CharacterDropSystem.Services { internal static class MobDropInitializationService { public static IEnumerable<CharacterDropItemConfiguration> PrepareInsertion(CharacterDropListConfiguration listConfig, CharacterDropMobConfiguration mobConfig) { Dictionary<int, CharacterDropItemConfiguration> dictionary = new Dictionary<int, CharacterDropItemConfiguration>(); if (listConfig != null) { foreach (CharacterDropItemConfiguration value in listConfig.Subsections.Values) { if ((bool)value.EnableConfig) { dictionary[value.Index] = value; } } } if (mobConfig != null) { foreach (CharacterDropItemConfiguration value2 in mobConfig.Subsections.Values) { if ((bool)value2.EnableConfig) { dictionary[value2.Index] = value2; } } } return dictionary.Values.OrderBy((CharacterDropItemConfiguration x) => x.Index); } } } namespace Valheim.DropThat.Drop.CharacterDropSystem.Patches { [HarmonyPatch(typeof(CharacterDrop))] public static class Patch_CharacterDrop_DropItems { private class LoopCounter { private static ConditionalWeakTable<object, LoopCounter> LoopCounterTable = new ConditionalWeakTable<object, LoopCounter>(); public int Count; public static void Increment(object obj) { LoopCounterTable.GetOrCreateValue(obj).Count++; } public static void Increment(object obj, int count) { LoopCounterTable.GetOrCreateValue(obj).Count += count; } public static int GetCount(object obj) { if (LoopCounterTable.TryGetValue(obj, out var value)) { return value.Count; } return 0; } } private static MethodInfo OnSpawnedItemMethod = AccessTools.Method(typeof(Patch_CharacterDrop_DropItems), "OnSpawnedItem", new Type[3] { typeof(GameObject), typeof(List<KeyValuePair<GameObject, int>>), typeof(Vector3) }, (Type[])null); private static MethodInfo AfterSpawnedItemMethod = AccessTools.Method(typeof(Patch_CharacterDrop_DropItems), "AfterSpawnedItem", (Type[])null, (Type[])null); [HarmonyPatch("DropItems")] [HarmonyTranspiler] private static IEnumerable<CodeInstruction> HookSpawnedItem(IEnumerable<CodeInstruction> instructions) { //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_001c: Unknown result type (might be due to invalid IL or missing references) //IL_0022: Expected O, but got Unknown //IL_0040: Unknown result type (might be due to invalid IL or missing references) //IL_0046: Expected O, but got Unknown //IL_0059: Unknown result type (might be due to invalid IL or missing references) //IL_005f: Expected O, but got Unknown //IL_0072: Unknown result type (might be due to invalid IL or missing references) //IL_0078: Expected O, but got Unknown //IL_008f: Unknown result type (might be due to invalid IL or missing references) //IL_0095: Expected O, but got Unknown //IL_00ad: Unknown result type (might be due to invalid IL or missing references) //IL_00b3: Expected O, but got Unknown //IL_00c6: Unknown result type (might be due to invalid IL or missing references) //IL_00cc: Expected O, but got Unknown //IL_00df: Unknown result type (might be due to invalid IL or missing references) //IL_00e5: Expected O, but got Unknown //IL_00fc: Unknown result type (might be due to invalid IL or missing references) //IL_0102: Expected O, but got Unknown //IL_0115: Unknown result type (might be due to invalid IL or missing references) //IL_011b: Expected O, but got Unknown return new CodeMatcher(instructions, (ILGenerator)null).MatchForward(false, (CodeMatch[])(object)new CodeMatch[1] { new CodeMatch((OpCode?)OpCodes.Ldloc_3, (object)null, (string)null) }).Advance(3).InsertAndAdvance((CodeInstruction[])(object)new CodeInstruction[1] { new CodeInstruction(OpCodes.Ldloc_S, (object)5) }) .InsertAndAdvance((CodeInstruction[])(object)new CodeInstruction[1] { new CodeInstruction(OpCodes.Ldarg_0, (object)null) }) .InsertAndAdvance((CodeInstruction[])(object)new CodeInstruction[1] { new CodeInstruction(OpCodes.Ldarg_1, (object)null) }) .InsertAndAdvance((CodeInstruction[])(object)new CodeInstruction[1] { new CodeInstruction(OpCodes.Call, (object)OnSpawnedItemMethod) }) .InsertAndAdvance((CodeInstruction[])(object)new CodeInstruction[1] { new CodeInstruction(OpCodes.Ldloc_S, (object)5) }) .InsertAndAdvance((CodeInstruction[])(object)new CodeInstruction[1] { new CodeInstruction(OpCodes.Ldarg_0, (object)null) }) .InsertAndAdvance((CodeInstruction[])(object)new CodeInstruction[1] { new CodeInstruction(OpCodes.Ldloc_2, (object)null) }) .InsertAndAdvance((CodeInstruction[])(object)new CodeInstruction[1] { new CodeInstruction(OpCodes.Call, (object)AfterSpawnedItemMethod) }) .InsertAndAdvance((CodeInstruction[])(object)new CodeInstruction[1] { new CodeInstruction(OpCodes.Stloc_2, (object)null) }) .InstructionEnumeration(); } private static int AfterSpawnedItem(GameObject item, List<KeyValuePair<GameObject, int>> drops, int index) { int num = index; try { int itemCount = LoopCounter.GetCount(drops) - 1; int index2 = GetIndex(drops, itemCount); if (index2 >= drops.Count) { return num; } KeyValuePair<GameObject, int> keyValuePair = drops[index2]; bool flag = false; if (keyValuePair.Value > 1) { if ((bool)ConfigurationManager.GeneralConfig.AlwaysAutoStack) { flag = true; } else { DropExtended drop = TempDropListCache.GetDrop(drops, index2); if