Please disclose if any significant portion of your mod was created using AI tools by adding the 'AI Generated' category. Failing to do so may result in the mod being removed from Thunderstore.
Decompiled source of Companions v1.0.5
plugins/Companions.dll
Decompiled 3 hours ago
The result has been truncated due to the large size, download it to view full contents!
using System; using System.Collections; using System.Collections.Concurrent; using System.Collections.Generic; using System.Collections.ObjectModel; using System.ComponentModel; using System.Diagnostics; using System.Diagnostics.CodeAnalysis; using System.Globalization; using System.IO; using System.IO.Compression; using System.Linq; using System.Linq.Expressions; using System.Reflection; using System.Reflection.Emit; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; using System.Runtime.Serialization; using System.Runtime.Versioning; using System.Security; using System.Security.Permissions; using System.Text; using System.Text.RegularExpressions; using System.Threading; using AzuEPI; using AzuEPI.Core.Slots; using AzuExtendedPlayerInventory; using BepInEx; using BepInEx.Bootstrap; using BepInEx.Configuration; using BiomeLockAPI; using HarmonyLib; using ItemManager; using JetBrains.Annotations; using LocalizationManager; using Microsoft.CodeAnalysis; using ServerSync; using Splatform; using TMPro; using UnityEngine; using UnityEngine.Audio; using UnityEngine.UI; using YamlDotNet.Core; using YamlDotNet.Core.Events; using YamlDotNet.Core.ObjectPool; using YamlDotNet.Core.Tokens; using YamlDotNet.Helpers; using YamlDotNet.Serialization; using YamlDotNet.Serialization.BufferedDeserialization; using YamlDotNet.Serialization.BufferedDeserialization.TypeDiscriminators; using YamlDotNet.Serialization.Callbacks; using YamlDotNet.Serialization.Converters; using YamlDotNet.Serialization.EventEmitters; using YamlDotNet.Serialization.NamingConventions; using YamlDotNet.Serialization.NodeDeserializers; using YamlDotNet.Serialization.NodeTypeResolvers; using YamlDotNet.Serialization.ObjectFactories; using YamlDotNet.Serialization.ObjectGraphTraversalStrategies; using YamlDotNet.Serialization.ObjectGraphVisitors; using YamlDotNet.Serialization.Schemas; using YamlDotNet.Serialization.TypeInspectors; using YamlDotNet.Serialization.TypeResolvers; using YamlDotNet.Serialization.Utilities; using YamlDotNet.Serialization.ValueDeserializers; [assembly: Guid("E74EB49A-461D-48EA-85BC-F462D60C98C4")] [assembly: ComVisible(false)] [assembly: AssemblyTrademark("")] [assembly: AssemblyCopyright("Copyright © 2025")] [assembly: AssemblyProduct("Companions")] [assembly: TargetFramework(".NETFramework,Version=v4.8", FrameworkDisplayName = ".NET Framework 4.8")] [assembly: AssemblyConfiguration("")] [assembly: AssemblyDescription("")] [assembly: AssemblyTitle("Companions")] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: CompilationRelaxations(8)] [assembly: AssemblyFileVersion("1.0.5")] [assembly: AssemblyCompany("Radamanto")] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("1.0.5.0")] [module: <6614e539-fad0-4684-8001-d01a4f520e3d>RefSafetyRules(11)] [module: UnverifiableCode] namespace Microsoft.CodeAnalysis { [CompilerGenerated] [<99995f88-b594-49e7-8035-aef7df1fa491>Embedded] internal sealed class <99995f88-b594-49e7-8035-aef7df1fa491>EmbeddedAttribute : Attribute { } } namespace System.Runtime.CompilerServices { [CompilerGenerated] [<99995f88-b594-49e7-8035-aef7df1fa491>Embedded] [AttributeUsage(AttributeTargets.Class | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Parameter | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter, AllowMultiple = false, Inherited = false)] internal sealed class <040cafbb-8436-4a5b-a3c8-5aa8abcf3260>NullableAttribute : Attribute { public readonly byte[] NullableFlags; public <040cafbb-8436-4a5b-a3c8-5aa8abcf3260>NullableAttribute(byte P_0) { NullableFlags = new byte[1] { P_0 }; } public <040cafbb-8436-4a5b-a3c8-5aa8abcf3260>NullableAttribute(byte[] P_0) { NullableFlags = P_0; } } [CompilerGenerated] [<99995f88-b594-49e7-8035-aef7df1fa491>Embedded] [AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Method | AttributeTargets.Interface | AttributeTargets.Delegate, AllowMultiple = false, Inherited = false)] internal sealed class <4aa5bef7-1be0-456e-b57f-5048df7109d2>NullableContextAttribute : Attribute { public readonly byte Flag; public <4aa5bef7-1be0-456e-b57f-5048df7109d2>NullableContextAttribute(byte P_0) { Flag = P_0; } } [AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)] [<99995f88-b594-49e7-8035-aef7df1fa491>Embedded] [CompilerGenerated] internal sealed class <6614e539-fad0-4684-8001-d01a4f520e3d>RefSafetyRulesAttribute : Attribute { public readonly int Version; public <6614e539-fad0-4684-8001-d01a4f520e3d>RefSafetyRulesAttribute(int P_0) { Version = P_0; } } } namespace Companions { [<4aa5bef7-1be0-456e-b57f-5048df7109d2>NullableContext(1)] [<040cafbb-8436-4a5b-a3c8-5aa8abcf3260>Nullable(0)] [PublicAPI] public static class MaterialReplacer { [<4aa5bef7-1be0-456e-b57f-5048df7109d2>NullableContext(0)] public enum ShaderType { PieceShader, VegetationShader, RockShader, RugShader, GrassShader, CustomCreature, UseUnityShader } private static readonly Dictionary<GameObject, bool> ObjectToSwap; private static readonly Dictionary<string, Material> OriginalMaterials; private static readonly Dictionary<GameObject, ShaderType> ObjectsForShaderReplace; private static readonly HashSet<Shader> CachedShaders; private static bool hasRun; static MaterialReplacer() { //IL_005b: Unknown result type (might be due to invalid IL or missing references) //IL_0068: Expected O, but got Unknown CachedShaders = new HashSet<Shader>(); hasRun = false; OriginalMaterials = new Dictionary<string, Material>(); ObjectToSwap = new Dictionary<GameObject, bool>(); ObjectsForShaderReplace = new Dictionary<GameObject, ShaderType>(); CompanionsPlugin.H.Patch((MethodBase)AccessTools.DeclaredMethod(typeof(ZoneSystem), "Start", (Type[])null, (Type[])null), (HarmonyMethod)null, new HarmonyMethod(typeof(MaterialReplacer), "ReplaceAllMaterialsWithOriginal", (Type[])null), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null); } public static void RegisterGameObjectForShaderSwap(GameObject go, ShaderType type) { if (!ObjectsForShaderReplace.ContainsKey(go)) { ObjectsForShaderReplace.Add(go, type); } } public static void RegisterGameObjectForMatSwap(GameObject go, bool isJotunnMock = false) { if (!ObjectToSwap.ContainsKey(go)) { ObjectToSwap.Add(go, isJotunnMock); } } private static void GetAllMaterials() { Material[] array = Resources.FindObjectsOfTypeAll<Material>(); foreach (Material val in array) { OriginalMaterials[((Object)val).name] = val; } } [HarmonyPriority(700)] private static void ReplaceAllMaterialsWithOriginal() { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Invalid comparison between Unknown and I4 if ((int)SystemInfo.graphicsDeviceType == 4 || hasRun) { return; } if (OriginalMaterials.Count == 0) { GetAllMaterials(); } foreach (KeyValuePair<GameObject, bool> item in ObjectToSwap) { GameObject key = item.Key; bool value = item.Value; ProcessGameObjectMaterials(key, value); } AssetBundle[] array = Resources.FindObjectsOfTypeAll<AssetBundle>(); AssetBundle[] array2 = array; foreach (AssetBundle val in array2) { IEnumerable<Shader> enumerable3; try { IEnumerable<Shader> enumerable2; if (!val.isStreamedSceneAssetBundle) { IEnumerable<Shader> enumerable = val.LoadAllAssets<Shader>(); enumerable2 = enumerable; } else { enumerable2 = from shader in ((IEnumerable<string>)val.GetAllAssetNames()).Select((Func<string, Shader>)val.LoadAsset<Shader>) where (Object)(object)shader != (Object)null select shader; } enumerable3 = enumerable2; } catch (Exception) { continue; } if (enumerable3 == null) { continue; } foreach (Shader item2 in enumerable3) { CachedShaders.Add(item2); } } foreach (KeyValuePair<GameObject, ShaderType> item3 in ObjectsForShaderReplace) { GameObject key2 = item3.Key; ShaderType value2 = item3.Value; ProcessGameObjectShaders(key2, value2); } hasRun = true; } private static void ProcessGameObjectMaterials(GameObject go, bool isJotunnMock) { Renderer[] componentsInChildren = go.GetComponentsInChildren<Renderer>(true); Renderer[] array = componentsInChildren; foreach (Renderer val in array) { Material[] sharedMaterials = val.sharedMaterials.Select([<4aa5bef7-1be0-456e-b57f-5048df7109d2>NullableContext(0)] (Material material) => ReplaceMaterial(material, isJotunnMock)).ToArray(); val.sharedMaterials = sharedMaterials; } } private static Material ReplaceMaterial(Material originalMaterial, bool isJotunnMock) { string text = (isJotunnMock ? "JVLmock_" : "_REPLACE_"); if (!((Object)originalMaterial).name.StartsWith(text, StringComparison.Ordinal)) { return originalMaterial; } string key = ((Object)originalMaterial).name.Replace(" (Instance)", "").Replace(text, ""); if (OriginalMaterials.TryGetValue(key, out var value)) { return value; } return originalMaterial; } private static void ProcessGameObjectShaders(GameObject go, ShaderType shaderType) { Renderer[] componentsInChildren = go.GetComponentsInChildren<Renderer>(true); Renderer[] array = componentsInChildren; foreach (Renderer val in array) { Material[] sharedMaterials = val.sharedMaterials; foreach (Material val2 in sharedMaterials) { if ((Object)(object)val2 != (Object)null) { val2.shader = GetShaderForType(val2.shader, shaderType, ((Object)val2.shader).name); } } } } private static Shader GetShaderForType(Shader orig, ShaderType shaderType, string originalShaderName) { return (Shader)(shaderType switch { ShaderType.PieceShader => FindShaderWithName(orig, "Custom/Piece"), ShaderType.VegetationShader => FindShaderWithName(orig, "Custom/Vegetation"), ShaderType.RockShader => FindShaderWithName(orig, "Custom/StaticRock"), ShaderType.RugShader => FindShaderWithName(orig, "Custom/Rug"), ShaderType.GrassShader => FindShaderWithName(orig, "Custom/Grass"), ShaderType.CustomCreature => FindShaderWithName(orig, "Custom/Creature"), ShaderType.UseUnityShader => FindShaderWithName(orig, ((Object)(object)FindShaderWithName(orig, originalShaderName) != (Object)null) ? originalShaderName : "ToonDeferredShading2017"), _ => FindShaderWithName(orig, "Standard"), }); } public static Shader FindShaderWithName(Shader origShader, string name) { foreach (Shader cachedShader in CachedShaders) { if (((Object)cachedShader).name == name) { return cachedShader; } } return origShader; } } internal enum CompanionCollectionMode { MarkedItems, AllItems, None } [<4aa5bef7-1be0-456e-b57f-5048df7109d2>NullableContext(1)] [<040cafbb-8436-4a5b-a3c8-5aa8abcf3260>Nullable(0)] public sealed class CompanionCollector : MonoBehaviour { internal const string SelectionKey = "radamanto.companions.collect"; private const float PickableScanInterval = 2f; private const float TrackInterval = 1f; private const float TargetApproachDistance = 3.2f; private const float TargetTimeout = 20f; private const float FailedRetryDelay = 15f; private const int PickablePurgeInterval = 256; private const int MaxOverlapBuffer = 8192; private static readonly HashSet<CompanionCollector> Active = new HashSet<CompanionCollector>(); private static readonly HashSet<Pickable> Pickables = new HashSet<Pickable>(); private static readonly List<Pickable> DeadPickables = new List<Pickable>(); private static readonly Dictionary<GameObject, ItemData> Templates = new Dictionary<GameObject, ItemData>(); private static Collider[] _overlapBuffer = (Collider[])(object)new Collider[256]; private static int _itemLayerMask = -1; private static int _pickableRegistrations; private static bool _pickablesSeeded; private readonly HashSet<string> _selectedPrefabs = new HashSet<string>(); private SphereCollider _sensor = null; [<040cafbb-8436-4a5b-a3c8-5aa8abcf3260>Nullable(2)] private ZNetView _view; [<040cafbb-8436-4a5b-a3c8-5aa8abcf3260>Nullable(2)] private Inventory _inventory; [<040cafbb-8436-4a5b-a3c8-5aa8abcf3260>Nullable(2)] private CompanionIdentity _identity; private bool _started; private bool _active; private bool _collecting; private bool _scanPending; private float _pollAt = -1f; private float _trackAt = -1f; [<040cafbb-8436-4a5b-a3c8-5aa8abcf3260>Nullable(2)] private ItemDrop _targetDrop; [<040cafbb-8436-4a5b-a3c8-5aa8abcf3260>Nullable(2)] private Pickable _targetPickable; [<040cafbb-8436-4a5b-a3c8-5aa8abcf3260>Nullable(2)] private GameObject _targetAnchor; private float _targetStarted; [<040cafbb-8436-4a5b-a3c8-5aa8abcf3260>Nullable(2)] private ItemDrop _failedDrop; private float _failedUntil; [<040cafbb-8436-4a5b-a3c8-5aa8abcf3260>Nullable(2)] private Pickable _failedPickable; private float _failedPickableUntil; [<040cafbb-8436-4a5b-a3c8-5aa8abcf3260>Nullable(2)] private Player _owner; private int _ownerFrame = -1; private int _selectedFrame = -1; private float _biomeCheckAt; private bool _biomeLocked; internal static bool AnyActive => Active.Count > 0; private static CompanionCollectionMode Mode => CompanionsPlugin.CollectionMode?.Value ?? CompanionCollectionMode.MarkedItems; private static CompanionCollectionMode PickableMode => CompanionsPlugin.PickableMode?.Value ?? CompanionCollectionMode.MarkedItems; private static bool AnyModeEnabled => Mode != CompanionCollectionMode.None || PickableMode != CompanionCollectionMode.None; private static float Radius => Mathf.Clamp(CompanionsPlugin.CollectionRadius?.Value ?? 6f, 1f, 30f); private static float DetectionRadius => Mathf.Clamp(CompanionsPlugin.CollectionDetectionRadius?.Value ?? 50f, 1f, 100f); private static float PickableDetectionRadius => Mathf.Clamp(CompanionsPlugin.PickableDetectionRadius?.Value ?? 20f, 1f, 100f); private static float MaxOwnerDistance => Mathf.Clamp(CompanionsPlugin.CollectionMaxOwnerDistance?.Value ?? 70f, 10f, 150f); private static int ItemLayerMask { get { if (_itemLayerMask == -1) { int mask = LayerMask.GetMask(new string[1] { "item" }); _itemLayerMask = ((mask != 0) ? mask : (-1)); } return _itemLayerMask; } } private bool IsFollowing => (Object)(object)_view != (Object)null && _view.IsValid() && !string.IsNullOrEmpty(_view.GetZDO().GetString(ZDOVars.s_follow, "")); [<040cafbb-8436-4a5b-a3c8-5aa8abcf3260>Nullable(2)] private Player Owner { [<4aa5bef7-1be0-456e-b57f-5048df7109d2>NullableContext(2)] get { if (_ownerFrame != Time.frameCount) { _ownerFrame = Time.frameCount; _owner = (((Object)(object)_view != (Object)null && _view.IsValid()) ? CompanionsState.FindOwner(_view.GetZDO()) : null); } return _owner; } } [<040cafbb-8436-4a5b-a3c8-5aa8abcf3260>Nullable(2)] private Transform TargetTransform { [<4aa5bef7-1be0-456e-b57f-5048df7109d2>NullableContext(2)] get { return ((Object)(object)_targetDrop != (Object)null) ? ((Component)_targetDrop).transform : (((Object)(object)_targetPickable != (Object)null) ? ((Component)_targetPickable).transform : null); } } internal static void RegisterPickable(Pickable pickable) { if (_pickablesSeeded && !((Object)(object)pickable == (Object)null)) { Pickables.Add(pickable); if (++_pickableRegistrations % 256 == 0) { PurgeDeadPickables(); } } } [<4aa5bef7-1be0-456e-b57f-5048df7109d2>NullableContext(2)] internal static void ApplyLayerFilter(Collider trigger) { //IL_001e: Unknown result type (might be due to invalid IL or missing references) if (!((Object)(object)trigger == (Object)null)) { int itemLayerMask = ItemLayerMask; trigger.excludeLayers = LayerMask.op_Implicit((itemLayerMask != -1) ? (~itemLayerMask) : 0); } } [<4aa5bef7-1be0-456e-b57f-5048df7109d2>NullableContext(2)] internal static bool IsSelected(ItemData item) { return item?.m_customData.ContainsKey("radamanto.companions.collect") ?? false; } internal static void RefreshSensors() { foreach (CompanionCollector item in Active) { item.RefreshSensor(); } } internal static void NotifyNearby(ItemDrop drop) { //IL_002b: Unknown result type (might be due to invalid IL or missing references) //IL_0030: Unknown result type (might be due to invalid IL or missing references) //IL_005b: Unknown result type (might be due to invalid IL or missing references) //IL_0060: 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_0066: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)drop == (Object)null) { return; } float num = Mathf.Max(Radius, DetectionRadius); float num2 = num * num; Vector3 position = ((Component)drop).transform.position; foreach (CompanionCollector item in Active) { if ((Object)(object)item != (Object)null) { Vector3 val = ((Component)item).transform.position - position; if (((Vector3)(ref val)).sqrMagnitude <= num2) { item.ScheduleScan(); } } } } internal static void ResetStatics() { Active.Clear(); ReleasePickables(); Templates.Clear(); } internal void ScheduleScan() { _scanPending = true; } internal void UpdateActive() { if (!_started) { return; } bool flag = (Object)(object)_view != (Object)null && _view.IsValid() && _view.IsOwner(); if (flag == _active) { if (flag) { ScheduleScan(); } return; } _active = flag; if (flag) { Active.Add(this); RefreshSensor(); ScheduleScan(); } else { Deactivate(); } } internal void CancelTarget() { _trackAt = -1f; _targetDrop = null; _targetPickable = null; SetCollecting(collecting: false); } internal bool RestoreTarget(Character character) { if (((Object)(object)_targetDrop == (Object)null && (Object)(object)_targetPickable == (Object)null) || (Object)(object)_targetAnchor == (Object)null) { return false; } if (!IsFollowing || IsOwnerTooFar() || !TargetStillValid()) { CancelTarget(); return false; } UpdateTargetPosition(); CompanionsFlight.FollowCollectionTarget(character, _targetAnchor); return true; } private static void PurgeDeadPickables() { foreach (Pickable pickable in Pickables) { if ((Object)(object)pickable == (Object)null) { DeadPickables.Add(pickable); } } for (int i = 0; i < DeadPickables.Count; i++) { Pickables.Remove(DeadPickables[i]); } DeadPickables.Clear(); } private static void SeedPickables() { if (!_pickablesSeeded) { _pickablesSeeded = true; Pickables.Clear(); Pickable[] array = Object.FindObjectsByType<Pickable>((FindObjectsSortMode)0); foreach (Pickable item in array) { Pickables.Add(item); } } } private static void ReleasePickables() { _pickablesSeeded = false; _pickableRegistrations = 0; Pickables.Clear(); DeadPickables.Clear(); } private static bool IsWardProtected(Vector3 point, long ownerId) { //IL_003e: 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) List<PrivateArea> allAreas = PrivateArea.m_allAreas; if (allAreas == null) { return false; } foreach (PrivateArea item in allAreas) { if (!((Object)(object)item == (Object)null) && !(Utils.DistanceXZ(((Component)item).transform.position, point) >= item.m_radius)) { ZNetView nview = item.m_nview; Piece piece = item.m_piece; if ((Object)(object)nview != (Object)null && nview.IsValid() && nview.GetZDO().GetBool(ZDOVars.s_enabled, false) && (ownerId == 0L || (Object)(object)piece == (Object)null || piece.GetCreator() != ownerId)) { return true; } } } return false; } private static int OverlapItems(Vector3 position, float radius) { //IL_0004: Unknown result type (might be due to invalid IL or missing references) int num; while (true) { num = Physics.OverlapSphereNonAlloc(position, radius, _overlapBuffer, ItemLayerMask, (QueryTriggerInteraction)2); if (num < _overlapBuffer.Length || _overlapBuffer.Length >= 8192) { break; } _overlapBuffer = (Collider[])(object)new Collider[_overlapBuffer.Length * 2]; } return num; } [<4aa5bef7-1be0-456e-b57f-5048df7109d2>NullableContext(2)] private static ItemData GetTemplate(GameObject prefab) { if ((Object)(object)prefab == (Object)null) { return null; } if (Templates.TryGetValue(prefab, out var value)) { return value; } ItemData val = CreateItem(prefab, 1); if (val != null) { Templates[prefab] = val; } return val; } [<4aa5bef7-1be0-456e-b57f-5048df7109d2>NullableContext(2)] private static ItemData CreateItem(GameObject prefab, int stack) { ItemDrop val = (((Object)(object)prefab != (Object)null) ? prefab.GetComponent<ItemDrop>() : null); if ((Object)(object)val == (Object)null || val.m_itemData == null) { return null; } ItemData val2 = val.m_itemData.Clone(); val2.m_dropPrefab = prefab; val2.m_stack = stack; val2.m_worldLevel = (byte)Game.m_worldLevel; return val2; } private static int HarvestAmount(Pickable pickable) { return pickable.m_dontScale ? pickable.m_amount : Mathf.Max(pickable.m_minAmountScaled, Game.instance.ScaleDrops(pickable.m_itemPrefab, pickable.m_amount)); } private void Start() { //IL_007d: Unknown result type (might be due to invalid IL or missing references) //IL_0082: Unknown result type (might be due to invalid IL or missing references) //IL_0089: Unknown result type (might be due to invalid IL or missing references) //IL_00a7: Unknown result type (might be due to invalid IL or missing references) //IL_00b3: Unknown result type (might be due to invalid IL or missing references) //IL_00d1: Unknown result type (might be due to invalid IL or missing references) //IL_00dd: Unknown result type (might be due to invalid IL or missing references) //IL_00fb: Unknown result type (might be due to invalid IL or missing references) //IL_0107: Unknown result type (might be due to invalid IL or missing references) _sensor = ((Component)this).GetComponent<SphereCollider>(); ApplyLayerFilter((Collider)(object)_sensor); _view = ((Component)this).GetComponentInParent<ZNetView>(); Container componentInParent = ((Component)this).GetComponentInParent<Container>(); _inventory = (((Object)(object)componentInParent != (Object)null) ? componentInParent.GetInventory() : null); if (!((Object)(object)_view == (Object)null) && _inventory != null && !((Object)(object)_sensor == (Object)null)) { Vector3 lossyScale = ((Component)this).transform.parent.lossyScale; ((Component)this).transform.localScale = new Vector3((Mathf.Abs(lossyScale.x) > 0.001f) ? (1f / Mathf.Abs(lossyScale.x)) : 1f, (Mathf.Abs(lossyScale.y) > 0.001f) ? (1f / Mathf.Abs(lossyScale.y)) : 1f, (Mathf.Abs(lossyScale.z) > 0.001f) ? (1f / Mathf.Abs(lossyScale.z)) : 1f); Inventory inventory = _inventory; inventory.m_onChanged = (Action)Delegate.Combine(inventory.m_onChanged, new Action(OnInventoryChanged)); ((Collider)_sensor).enabled = false; _started = true; UpdateActive(); } } private void Update() { if (!_active) { return; } float time = Time.time; if (time >= _biomeCheckAt) { _biomeCheckAt = time + 1f; bool flag = IsOwnerBiomeLocked(); if (flag != _biomeLocked) { _biomeLocked = flag; if (!flag) { ScheduleScan(); } } } if (_trackAt >= 0f && time >= _trackAt) { _trackAt = time + 1f; TrackTarget(); } if (_pollAt >= 0f && time >= _pollAt) { _pollAt = time + 2f; if ((Object)(object)_targetDrop == (Object)null && (Object)(object)_targetPickable == (Object)null) { ScanNearby(); } } if (_scanPending) { _scanPending = false; ScanNearby(); } } private void OnDestroy() { CancelTarget(); if ((Object)(object)_targetAnchor != (Object)null) { Object.Destroy((Object)(object)_targetAnchor); } _targetAnchor = null; if (_active) { _active = false; RemoveActive(); } if (_inventory != null) { Inventory inventory = _inventory; inventory.m_onChanged = (Action)Delegate.Remove(inventory.m_onChanged, new Action(OnInventoryChanged)); } } private void OnTriggerEnter(Collider other) { if (_active) { ItemDrop componentInParent = ((Component)other).GetComponentInParent<ItemDrop>(); if ((Object)(object)componentInParent != (Object)null) { ScheduleScan(); } } } private void OnInventoryChanged() { _selectedFrame = -1; if (!_collecting) { ScheduleScan(); } } private void Deactivate() { RemoveActive(); CancelTarget(); _scanPending = false; _pollAt = -1f; if ((Object)(object)_sensor != (Object)null) { ((Collider)_sensor).enabled = false; } } private void RemoveActive() { Active.Remove(this); if (Active.Count == 0) { ReleasePickables(); } } private void RefreshSensor() { if ((Object)(object)_sensor == (Object)null) { return; } _sensor.radius = Mathf.Max(Radius, DetectionRadius); ((Collider)_sensor).enabled = _active && Mode != CompanionCollectionMode.None; _pollAt = ((_active && PickableMode != CompanionCollectionMode.None) ? (Time.time + Random.Range(0.5f, 2f)) : (-1f)); if ((!((Object)(object)_targetDrop != (Object)null) || Mode == CompanionCollectionMode.None) && (!((Object)(object)_targetPickable != (Object)null) || PickableMode == CompanionCollectionMode.None) && ((Object)(object)_targetDrop != (Object)null || (Object)(object)_targetPickable != (Object)null)) { CancelTarget(); if ((Object)(object)_view != (Object)null) { CompanionsFlight.RestoreFollow(((Component)_view).gameObject); } } if (AnyModeEnabled) { ScanNearby(); } } private bool IsOwnerTooFar() { //IL_0017: Unknown result type (might be due to invalid IL or missing references) //IL_0022: Unknown result type (might be due to invalid IL or missing references) Player owner = Owner; return (Object)(object)owner == (Object)null || Utils.DistanceXZ(((Component)owner).transform.position, ((Component)this).transform.position) > MaxOwnerDistance; } private bool IsBeyondOwnerRange(Vector3 point) { //IL_0011: Unknown result type (might be due to invalid IL or missing references) //IL_0016: Unknown result type (might be due to invalid IL or missing references) Player owner = Owner; return owner == null || Utils.DistanceXZ(((Component)owner).transform.position, point) > MaxOwnerDistance; } private void ScanNearby() { if (!_collecting && CanCollect()) { if ((Object)(object)_targetDrop != (Object)null || (Object)(object)_targetPickable != (Object)null) { TrackTarget(); } else if (!IsOwnerTooFar() && !ScanDrops()) { ScanPickables(); } } } private bool ScanDrops() { //IL_0035: Unknown result type (might be due to invalid IL or missing references) //IL_00bd: Unknown result type (might be due to invalid IL or missing references) //IL_00c9: Unknown result type (might be due to invalid IL or missing references) //IL_00ce: Unknown result type (might be due to invalid IL or missing references) //IL_00d3: Unknown result type (might be due to invalid IL or missing references) if (Mode == CompanionCollectionMode.None) { return false; } float radius = Mathf.Max(Radius, DetectionRadius); ItemDrop val = null; float num = float.MaxValue; int num2 = OverlapItems(((Component)this).transform.position, radius); for (int i = 0; i < num2; i++) { Collider val2 = _overlapBuffer[i]; _overlapBuffer[i] = null; if ((Object)(object)val2 == (Object)null) { continue; } ItemDrop componentInParent = ((Component)val2).GetComponentInParent<ItemDrop>(); if (!((Object)(object)componentInParent == (Object)null) && (!((Object)(object)componentInParent == (Object)(object)_failedDrop) || !(Time.time < _failedUntil)) && CanTake(componentInParent, out var _)) { Vector3 val3 = ((Component)this).transform.position - ((Component)componentInParent).transform.position; float sqrMagnitude = ((Vector3)(ref val3)).sqrMagnitude; if (sqrMagnitude < num) { val = componentInParent; num = sqrMagnitude; } } } if ((Object)(object)val == (Object)null) { return false; } if (num <= Radius * Radius && TryCollect(val)) { ScheduleScan(); return true; } StartTarget(val, null); return true; } private void ScanPickables() { //IL_004c: Unknown result type (might be due to invalid IL or missing references) //IL_0051: Unknown result type (might be due to invalid IL or missing references) //IL_0095: 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_00a2: Unknown result type (might be due to invalid IL or missing references) //IL_00a7: Unknown result type (might be due to invalid IL or missing references) if (PickableMode == CompanionCollectionMode.None) { return; } SeedPickables(); if (Pickables.Count == 0) { return; } float num = Mathf.Max(Radius, PickableDetectionRadius); float num2 = num * num; Vector3 position = ((Component)this).transform.position; Pickable val = null; float num3 = float.MaxValue; foreach (Pickable pickable in Pickables) { if ((Object)(object)pickable == (Object)null) { DeadPickables.Add(pickable); continue; } Vector3 val2 = position - ((Component)pickable).transform.position; float sqrMagnitude = ((Vector3)(ref val2)).sqrMagnitude; if (!(sqrMagnitude > num2) && !(sqrMagnitude >= num3) && (!((Object)(object)pickable == (Object)(object)_failedPickable) || !(Time.time < _failedPickableUntil)) && CanHarvest(pickable)) { val = pickable; num3 = sqrMagnitude; } } if (DeadPickables.Count > 0) { for (int i = 0; i < DeadPickables.Count; i++) { Pickables.Remove(DeadPickables[i]); } DeadPickables.Clear(); } if (!((Object)(object)val == (Object)null)) { if (num3 <= Radius * Radius && TryHarvest(val)) { ScheduleScan(); } else { StartTarget(null, val); } } } private bool CanCollect() { return _active && AnyModeEnabled && IsFollowing && (Object)(object)_view != (Object)null && _view.IsValid() && _view.IsOwner() && _inventory != null && !_view.GetZDO().GetBool(CompanionsFlight.DungeonWaitKey, false) && !IsOwnerBiomeLocked(); } private bool IsOwnerBiomeLocked() { Player owner = Owner; if ((Object)(object)owner == (Object)null || (Object)(object)owner != (Object)(object)Player.m_localPlayer) { return false; } return BiomeLockAPI.API.IsRestricted(); } private void SetCollecting(bool collecting) { if ((Object)(object)_identity == (Object)null && (Object)(object)_view != (Object)null) { _identity = ((Component)_view).GetComponent<CompanionIdentity>(); } if ((Object)(object)_identity != (Object)null) { _identity.Collecting = collecting; } } private bool TargetStillValid() { int capacity; if ((Object)(object)_targetDrop != (Object)null) { return CanTake(_targetDrop, out capacity); } if ((Object)(object)_targetPickable != (Object)null) { return CanHarvest(_targetPickable); } return false; } [<4aa5bef7-1be0-456e-b57f-5048df7109d2>NullableContext(2)] private void StartTarget(ItemDrop drop, Pickable pickable) { //IL_008b: Unknown result type (might be due to invalid IL or missing references) //IL_0095: Expected O, but got Unknown if (!IsFollowing || IsOwnerTooFar() || (Object)(object)_view == (Object)null || ((Object)(object)drop == (Object)null && (Object)(object)pickable == (Object)null)) { return; } Character component = ((Component)_view).GetComponent<Character>(); if (!((Object)(object)component == (Object)null)) { CancelTarget(); _targetDrop = drop; _targetPickable = pickable; if ((Object)(object)_targetAnchor == (Object)null) { _targetAnchor = new GameObject("CompanionCollectionTarget"); } SetCollecting(collecting: true); _targetStarted = Time.time; UpdateTargetPosition(); CompanionsFlight.FollowCollectionTarget(component, _targetAnchor); _trackAt = Time.time + 1f; } } private void UpdateTargetPosition() { //IL_0038: Unknown result type (might be due to invalid IL or missing references) //IL_003d: Unknown result type (might be due to invalid IL or missing references) //IL_0047: Unknown result type (might be due to invalid IL or missing references) //IL_004c: Unknown result type (might be due to invalid IL or missing references) //IL_0051: 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_0068: Unknown result type (might be due to invalid IL or missing references) //IL_006d: Unknown result type (might be due to invalid IL or missing references) //IL_00c1: Unknown result type (might be due to invalid IL or missing references) //IL_008e: 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) //IL_00ab: Unknown result type (might be due to invalid IL or missing references) //IL_00b0: Unknown result type (might be due to invalid IL or missing references) //IL_00b5: Unknown result type (might be due to invalid IL or missing references) Transform targetTransform = TargetTransform; if (!((Object)(object)targetTransform == (Object)null) && !((Object)(object)_targetAnchor == (Object)null) && !((Object)(object)_view == (Object)null)) { Vector3 val = targetTransform.position + Vector3.up * CompanionsFlight.Height; Vector3 val2 = targetTransform.position - ((Component)_view).transform.position; val2.y = 0f; if (((Vector3)(ref val2)).sqrMagnitude > 0.01f) { val += ((Vector3)(ref val2)).normalized * Mathf.Max(0f, 3.2f - Radius); } _targetAnchor.transform.position = val; } } private void TrackTarget() { //IL_00c8: Unknown result type (might be due to invalid IL or missing references) //IL_00ce: Unknown result type (might be due to invalid IL or missing references) //IL_00d3: Unknown result type (might be due to invalid IL or missing references) //IL_00d8: Unknown result type (might be due to invalid IL or missing references) Transform targetTransform = TargetTransform; if ((Object)(object)targetTransform == (Object)null || (Object)(object)_targetAnchor == (Object)null || !IsFollowing || IsOwnerTooFar() || !TargetStillValid()) { FinishTarget(); } else if (Time.time - _targetStarted > 20f) { if ((Object)(object)_targetDrop != (Object)null) { _failedDrop = _targetDrop; _failedUntil = Time.time + 15f; } else { _failedPickable = _targetPickable; _failedPickableUntil = Time.time + 15f; } FinishTarget(); } else { Vector3 val = ((Component)_view).transform.position - targetTransform.position; if (((Vector3)(ref val)).sqrMagnitude <= Radius * Radius && (((Object)(object)_targetDrop != (Object)null) ? TryCollect(_targetDrop) : TryHarvest(_targetPickable))) { FinishTarget(); } else { UpdateTargetPosition(); } } } private void FinishTarget() { CancelTarget(); ScanNearby(); if ((Object)(object)_targetDrop == (Object)null && (Object)(object)_targetPickable == (Object)null && (Object)(object)_view != (Object)null) { CompanionsFlight.RestoreFollow(((Component)_view).gameObject, smooth: true); ScheduleScan(); } } private bool CanTake(ItemDrop drop, out int capacity) { //IL_005c: 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) capacity = 0; if (Mode == CompanionCollectionMode.None || !CanCollect() || (Object)(object)drop == (Object)null || IsWardProtected(((Component)drop).transform.position, _view.GetZDO().GetLong(CompanionsState.OwnerKey, 0L))) { return false; } if (IsBeyondOwnerRange(((Component)drop).transform.position)) { return false; } ZNetView nview = drop.m_nview; if ((Object)(object)nview == (Object)null || !nview.IsValid()) { return false; } drop.Load(); ItemData itemData = drop.m_itemData; if (itemData == null || (Object)(object)itemData.m_dropPrefab == (Object)null || itemData.m_stack <= 0 || !IsOwnDrop(nview.GetZDO(), itemData) || CompanionsContainer.IsBlocked(_inventory, itemData)) { return false; } CompanionCollectionMode mode = Mode; string prefabName = Utils.GetPrefabName(itemData.m_dropPrefab); if (mode == CompanionCollectionMode.MarkedItems && !IsPrefabSelected(prefabName)) { return false; } int num = 0; foreach (ItemData allItem in _inventory.GetAllItems()) { if (allItem.IsSameType(itemData)) { num += Mathf.Max(0, allItem.m_shared.m_maxStackSize - allItem.m_stack); } } int num2 = _inventory.GetEmptySlots() * itemData.m_shared.m_maxStackSize; capacity = num + num2; return (mode == CompanionCollectionMode.MarkedItems) ? (capacity > 0) : (capacity >= itemData.m_stack); } private bool IsOwnDrop(ZDO dropZdo, ItemData item) { //IL_004d: Unknown result type (might be due to invalid IL or missing references) //IL_0052: Unknown result type (might be due to invalid IL or missing references) if (!item.m_pickedUp) { return true; } long userID = ((ZDOID)(ref dropZdo.m_uid)).UserID; if (userID == ZDOID.NullUser || userID == ZDOID.UnknownFormerUser) { return true; } Player owner = Owner; int result; if ((Object)(object)owner != (Object)null) { ZDOID zDOID = ((Character)owner).GetZDOID(); result = ((userID == ((ZDOID)(ref zDOID)).UserID) ? 1 : 0); } else { result = 0; } return (byte)result != 0; } private bool IsPrefabSelected(string prefabName) { if (_selectedFrame != Time.frameCount) { _selectedFrame = Time.frameCount; _selectedPrefabs.Clear(); foreach (ItemData allItem in _inventory.GetAllItems()) { if (IsSelected(allItem) && (Object)(object)allItem.m_dropPrefab != (Object)null) { _selectedPrefabs.Add(Utils.GetPrefabName(allItem.m_dropPrefab)); } } } return _selectedPrefabs.Contains(prefabName); } private int FreeCapacity(ItemData item) { return _inventory.FindFreeStackSpace(item.m_shared.m_name, (float)Game.m_worldLevel) + _inventory.GetEmptySlots() * item.m_shared.m_maxStackSize; } private bool CanHarvest(Pickable pickable) { //IL_0111: Unknown result type (might be due to invalid IL or missing references) //IL_0116: Unknown result type (might be due to invalid IL or missing references) //IL_0117: Unknown result type (might be due to invalid IL or missing references) //IL_0140: Unknown result type (might be due to invalid IL or missing references) if (PickableMode == CompanionCollectionMode.None || !CanCollect() || (Object)(object)pickable == (Object)null || (Object)(object)pickable.m_itemPrefab == (Object)null) { return false; } ZNetView nview = pickable.m_nview; if ((Object)(object)nview == (Object)null || !nview.IsValid() || pickable.GetPicked() || pickable.GetEnabled != 1 || IsControlledByOtherPeer(nview.GetZDO())) { return false; } if (pickable.m_tarPreventsPicking) { Floating component = ((Component)pickable).GetComponent<Floating>(); if ((Object)(object)component != (Object)null && component.IsInTar()) { return false; } } CompanionCollectionMode pickableMode = PickableMode; if (pickableMode == CompanionCollectionMode.MarkedItems && !IsPrefabSelected(Utils.GetPrefabName(pickable.m_itemPrefab))) { return false; } ItemData template = GetTemplate(pickable.m_itemPrefab); if (template == null || CompanionsContainer.IsBlocked(_inventory, template)) { return false; } Vector3 position = ((Component)pickable).transform.position; if (IsWardProtected(position, _view.GetZDO().GetLong(CompanionsState.OwnerKey, 0L))) { return false; } if (IsBeyondOwnerRange(position)) { return false; } int num = FreeCapacity(template); return (pickableMode == CompanionCollectionMode.MarkedItems) ? (num > 0) : (num >= Mathf.Max(1, pickable.m_amount)); } private static bool IsControlledByOtherPeer(ZDO zdo) { long owner = zdo.GetOwner(); return owner != 0L && owner != ZDOMan.GetSessionID(); } private bool TryHarvest(Pickable pickable) { //IL_0018: 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_0028: 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_00a5: Unknown result type (might be due to invalid IL or missing references) //IL_00ab: Unknown result type (might be due to invalid IL or missing references) //IL_00b0: 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_00b5: Unknown result type (might be due to invalid IL or missing references) //IL_00bd: Unknown result type (might be due to invalid IL or missing references) //IL_00bf: Unknown result type (might be due to invalid IL or missing references) //IL_00cd: Unknown result type (might be due to invalid IL or missing references) //IL_00d3: Unknown result type (might be due to invalid IL or missing references) //IL_0188: Unknown result type (might be due to invalid IL or missing references) if (!_collecting && CanHarvest(pickable)) { Vector3 val = ((Component)this).transform.position - ((Component)pickable).transform.position; if (!(((Vector3)(ref val)).sqrMagnitude > Radius * Radius) && !IsOwnerTooFar()) { ZNetView nview = pickable.m_nview; nview.ClaimOwnership(); if (!nview.IsOwner() || pickable.GetPicked()) { return false; } _collecting = true; try { Vector3 val2 = (pickable.m_pickEffectAtSpawnPoint ? (((Component)pickable).transform.position + pickable.GetSpawnOffset()) : ((Component)pickable).transform.position); pickable.m_pickEffector.Create(val2, Quaternion.identity, (Transform)null, 1f, -1, default(ZDOID)); StoreOrDrop(pickable, pickable.m_itemPrefab, HarvestAmount(pickable)); if (!pickable.m_extraDrops.IsEmpty()) { foreach (ItemData dropListItem in pickable.m_extraDrops.GetDropListItems()) { if (dropListItem != null && (Object)(object)dropListItem.m_dropPrefab != (Object)null) { StoreOrDrop(pickable, dropListItem.m_dropPrefab, dropListItem.m_stack); } } } if (pickable.m_aggravateRange > 0f) { BaseAI.AggravateAllInArea(((Component)pickable).transform.position, pickable.m_aggravateRange, (AggravatedReason)2); } nview.InvokeRPC(ZNetView.Everybody, "RPC_SetPicked", new object[1] { true }); return true; } finally { _collecting = false; } } } return false; } private void StoreOrDrop(Pickable pickable, GameObject prefab, int amount) { ItemData template = GetTemplate(prefab); if (template == null || amount <= 0) { return; } bool flag = CompanionsContainer.IsBlocked(_inventory, template); int num = amount; while (!flag && num > 0) { int num2 = Mathf.Min(new int[3] { num, template.m_shared.m_maxStackSize, FreeCapacity(template) }); if (num2 <= 0) { break; } ItemData val = CreateItem(prefab, num2); if (val == null || !_inventory.AddItem(val)) { break; } num -= num2; } int num3 = 0; while (num > 0) { int num4 = Mathf.Min(num, template.m_shared.m_maxStackSize); pickable.Drop(prefab, num3++, num4); num -= num4; } } private bool TryCollect(ItemDrop drop) { //IL_001a: Unknown result type (might be due to invalid IL or missing references) //IL_0025: Unknown result type (might be due to invalid IL or missing references) //IL_002a: Unknown result type (might be due to invalid IL or missing references) //IL_002f: Unknown result type (might be due to invalid IL or missing references) if (!_collecting && CanTake(drop, out var capacity)) { Vector3 val = ((Component)this).transform.position - ((Component)drop).transform.position; if (!(((Vector3)(ref val)).sqrMagnitude > Radius * Radius) && !IsOwnerTooFar()) { ZNetView nview = drop.m_nview; if (!drop.CanPickup(false)) { drop.RequestOwn(); return false; } _collecting = true; try { ItemData itemData = drop.m_itemData; ItemData val2 = itemData.Clone(); int num = (val2.m_stack = ((Mode == CompanionCollectionMode.MarkedItems) ? Mathf.Min(itemData.m_stack, capacity) : itemData.m_stack)); val2.m_customData.Remove("radamanto.companions.collect"); bool flag = _inventory.AddItem(val2); if (flag && nview.IsOwner()) { if (num == itemData.m_stack) { nview.Destroy(); } else { itemData.m_stack -= num; ItemDrop.SaveToZDO(itemData, nview.GetZDO(), -1); } } return flag; } finally { _collecting = false; } } } return false; } } [HarmonyPatch(typeof(ItemDrop), "DropItem", new Type[] { typeof(ItemData), typeof(int), typeof(Vector3), typeof(Quaternion) })] internal static class ItemDrop_DropItem_CompanionCollection_Patch { [<4aa5bef7-1be0-456e-b57f-5048df7109d2>NullableContext(1)] private static void Postfix(ItemDrop __result) { CompanionCollector.NotifyNearby(__result); } } [HarmonyPatch(typeof(Pickable), "Awake")] internal static class Pickable_Awake_CompanionCollection_Patch { [<4aa5bef7-1be0-456e-b57f-5048df7109d2>NullableContext(1)] private static void Postfix(Pickable __instance) { CompanionCollector.RegisterPickable(__instance); } } [<4aa5bef7-1be0-456e-b57f-5048df7109d2>NullableContext(1)] [<040cafbb-8436-4a5b-a3c8-5aa8abcf3260>Nullable(0)] internal static class CompanionsCollectionSelection { private const string OverlayName = "CompanionCollectionSelection"; private const string TooltipKeyColor = "#ADFF2F"; private const string TooltipTextColor = "#FFD700"; private static readonly Color SelectedColor = new Color(0.15f, 0.85f, 0.25f, 0.38f); private static readonly HashSet<string> SelectedPrefabs = new HashSet<string>(); [<040cafbb-8436-4a5b-a3c8-5aa8abcf3260>Nullable(2)] private static Container _container; [<040cafbb-8436-4a5b-a3c8-5aa8abcf3260>Nullable(2)] private static Inventory _inventory; [<040cafbb-8436-4a5b-a3c8-5aa8abcf3260>Nullable(2)] private static InventoryGrid _grid; private static bool _normalizing; internal static void Open(InventoryGui gui, Container container) { Close(); if ((Object)(object)gui == (Object)null || (Object)(object)container == (Object)null || !CompanionsContainer.IsCompanionContainer(container) || !CompanionsState.IsOwner((Humanoid)(object)Player.m_localPlayer, CompanionsContainer.GetView((Component)(object)container))) { return; } _container = container; _inventory = container.GetInventory(); _grid = gui.ContainerGrid; if (_inventory == null || (Object)(object)_grid == (Object)null) { Close(); return; } if (_grid.m_elements.Count == 0) { _grid.m_width = 0; _grid.m_height = 0; } NormalizeSelection(); Inventory inventory = _inventory; inventory.m_onChanged = (Action)Delegate.Combine(inventory.m_onChanged, new Action(Refresh)); Refresh(); } internal static void Close() { if (_inventory != null) { Inventory inventory = _inventory; inventory.m_onChanged = (Action)Delegate.Remove(inventory.m_onChanged, new Action(Refresh)); } if ((Object)(object)_grid != (Object)null) { InventoryElement[] componentsInChildren = ((Component)_grid.m_gridRoot).GetComponentsInChildren<InventoryElement>(true); foreach (InventoryElement element in componentsInChildren) { SetMark(element, selected: false); } } _container = null; _inventory = null; _grid = null; } internal static bool OnLeftDown(InventoryGrid grid, UIInputHandler handler) { //IL_0059: Unknown result type (might be due to invalid IL or missing references) //IL_0064: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)_grid != (Object)(object)grid || (Object)(object)_container == (Object)null || _inventory == null || !CompanionsControls.IsSelectModifierHeld()) { return true; } InventoryElement componentInParent = ((Component)handler).GetComponentInParent<InventoryElement>(); if ((Object)(object)componentInParent == (Object)null) { return false; } ItemData itemAt = _inventory.GetItemAt(componentInParent.Position.x, componentInParent.Position.y); if (itemAt == null) { return false; } if (!_container.IsOwner()) { return false; } if (CompanionsContainer.IsBlocked(_inventory, itemAt)) { CompanionsContainer.Show("$companions_msg_blocked_item"); return false; } if ((Object)(object)itemAt.m_dropPrefab == (Object)null) { return false; } if (CompanionCollector.IsSelected(itemAt)) { itemAt.m_customData.Remove("radamanto.companions.collect"); } else { string prefabName = Utils.GetPrefabName(itemAt.m_dropPrefab); foreach (ItemData allItem in _inventory.GetAllItems()) { if ((Object)(object)allItem.m_dropPrefab != (Object)null && Utils.GetPrefabName(allItem.m_dropPrefab) == prefabName) { allItem.m_customData.Remove("radamanto.companions.collect"); } } itemAt.m_customData["radamanto.companions.collect"] = "1"; } _inventory.m_onChanged?.Invoke(); return false; } internal static void OnElementInitialized(InventoryElement element) { if ((Object)(object)_grid != (Object)null && (Object)(object)((Component)element).GetComponentInParent<InventoryGrid>() == (Object)(object)_grid) { UpdateMark(element); } } internal static void AppendItemTooltip(InventoryGrid grid, ItemData item, UITooltip tooltip) { //IL_00aa: Unknown result type (might be due to invalid IL or missing references) //IL_00b0: Unknown result type (might be due to invalid IL or missing references) if (!((Object)(object)grid != (Object)(object)_grid) && _inventory != null && item != null && !((Object)(object)tooltip == (Object)null)) { string text = CompanionsLocalization.Localize("$companions_tooltip_click").Replace("{0}", CompanionsControls.SelectModifierLabel); string text2 = CompanionsLocalization.Localize(CompanionCollector.IsSelected(item) ? "$companions_tooltip_deselect_collection" : "$companions_tooltip_select_collection"); string text3 = "<color=#FFD700><b>" + text2.Replace("{0}", "<color=#ADFF2F>" + text + "</color>") + "</b></color>"; tooltip.Set(tooltip.m_topic, tooltip.m_text + "\n\n" + text3, grid.m_tooltipAnchor, default(Vector2)); } } private static bool NormalizeSelection() { if (_inventory == null || _normalizing) { return false; } SelectedPrefabs.Clear(); bool flag = false; foreach (ItemData allItem in _inventory.GetAllItems()) { if (CompanionCollector.IsSelected(allItem) && ((Object)(object)allItem.m_dropPrefab == (Object)null || !SelectedPrefabs.Add(Utils.GetPrefabName(allItem.m_dropPrefab)))) { allItem.m_customData.Remove("radamanto.companions.collect"); flag = true; } } if (!flag) { return false; } _normalizing = true; try { _inventory.m_onChanged?.Invoke(); } finally { _normalizing = false; } return true; } private static void Refresh() { if (!((Object)(object)_grid == (Object)null) && _inventory != null && !NormalizeSelection()) { InventoryElement[] componentsInChildren = ((Component)_grid.m_gridRoot).GetComponentsInChildren<InventoryElement>(true); foreach (InventoryElement element in componentsInChildren) { UpdateMark(element); } } } private static void UpdateMark(InventoryElement element) { //IL_000e: Unknown result type (might be due to invalid IL or missing references) //IL_0019: Unknown result type (might be due to invalid IL or missing references) Inventory inventory = _inventory; ItemData item = ((inventory != null) ? inventory.GetItemAt(element.Position.x, element.Position.y) : null); SetMark(element, CompanionCollector.IsSelected(item)); } private static void SetMark(InventoryElement element, bool selected) { //IL_0048: Unknown result type (might be due to invalid IL or missing references) //IL_004e: 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 //IL_006e: Unknown result type (might be due to invalid IL or missing references) //IL_007a: Unknown result type (might be due to invalid IL or missing references) //IL_0086: Unknown result type (might be due to invalid IL or missing references) //IL_0092: Unknown result type (might be due to invalid IL or missing references) //IL_00a7: Unknown result type (might be due to invalid IL or missing references) Transform val = ((Component)element).transform.Find("CompanionCollectionSelection"); if ((Object)(object)val == (Object)null && selected) { GameObject val2 = new GameObject("CompanionCollectionSelection", new Type[2] { typeof(RectTransform), typeof(Image) }); val2.transform.SetParent(((Component)element).transform, false); RectTransform val3 = (RectTransform)val2.transform; val3.anchorMin = Vector2.zero; val3.anchorMax = Vector2.one; val3.offsetMin = Vector2.zero; val3.offsetMax = Vector2.zero; Image component = val2.GetComponent<Image>(); ((Graphic)component).color = SelectedColor; ((Graphic)component).raycastTarget = false; val2.transform.SetAsFirstSibling(); val = val2.transform; } if ((Object)(object)val != (Object)null) { ((Component)val).gameObject.SetActive(selected); } } } [HarmonyPatch(typeof(InventoryGui), "Show", new Type[] { typeof(Container), typeof(int) })] internal static class InventoryGui_Show_CompanionSelection_Patch { [<4aa5bef7-1be0-456e-b57f-5048df7109d2>NullableContext(1)] private static void Postfix(InventoryGui __instance, Container container) { CompanionsCollectionSelection.Open(__instance, container); } } [HarmonyPatch(typeof(InventoryGui), "Hide")] internal static class InventoryGui_Hide_CompanionSelection_Patch { private static void Prefix() { CompanionsCollectionSelection.Close(); } } [HarmonyPatch(typeof(InventoryGui), "CloseContainer")] internal static class InventoryGui_CloseContainer_CompanionSelection_Patch { private static void Prefix() { CompanionsCollectionSelection.Close(); } } [HarmonyPatch(typeof(InventoryGrid), "OnLeftDown", new Type[] { typeof(UIInputHandler) })] internal static class InventoryGrid_OnLeftDown_CompanionSelection_Patch { [<4aa5bef7-1be0-456e-b57f-5048df7109d2>NullableContext(1)] private static bool Prefix(InventoryGrid __instance, UIInputHandler clickHandler) { return CompanionsCollectionSelection.OnLeftDown(__instance, clickHandler); } } [HarmonyPatch(typeof(InventoryElement), "Initialize", new Type[] { typeof(int), typeof(int) })] internal static class InventoryElement_Initialize_CompanionSelection_Patch { [<4aa5bef7-1be0-456e-b57f-5048df7109d2>NullableContext(1)] private static void Postfix(InventoryElement __instance) { CompanionsCollectionSelection.OnElementInitialized(__instance); } } [HarmonyPatch(typeof(InventoryGrid), "CreateItemTooltip", new Type[] { typeof(ItemData), typeof(UITooltip) })] internal static class InventoryGrid_CreateItemTooltip_CompanionSelection_Patch { [<4aa5bef7-1be0-456e-b57f-5048df7109d2>NullableContext(1)] private static void Postfix(InventoryGrid __instance, ItemData item, UITooltip tooltip) { CompanionsCollectionSelection.AppendItemTooltip(__instance, item, tooltip); } } [<4aa5bef7-1be0-456e-b57f-5048df7109d2>NullableContext(1)] [<040cafbb-8436-4a5b-a3c8-5aa8abcf3260>Nullable(0)] internal static class CompanionsAudio { private static readonly HashSet<AudioSource> Sources = new HashSet<AudioSource>(); [<040cafbb-8436-4a5b-a3c8-5aa8abcf3260>Nullable(2)] private static AudioMixer _appliedMixer; internal static void Initialize(AssetBundle bundle) { if (Application.isBatchMode || (Object)(object)bundle == (Object)null) { return; } Sources.Clear(); GameObject[] array = bundle.LoadAllAssets<GameObject>(); foreach (GameObject val in array) { if ((Object)(object)val == (Object)null) { continue; } AudioSource[] componentsInChildren = val.GetComponentsInChildren<AudioSource>(true); foreach (AudioSource val2 in componentsInChildren) { if ((Object)(object)val2 != (Object)null) { Sources.Add(val2); } } } Apply(AudioMan.instance); } [<4aa5bef7-1be0-456e-b57f-5048df7109d2>NullableContext(2)] internal static void Apply(AudioMan audioManager) { AudioMixer val = (((Object)(object)audioManager != (Object)null) ? audioManager.m_masterMixer : null); if ((Object)(object)val == (Object)null || (Object)(object)val == (Object)(object)_appliedMixer) { return; } AudioMixerGroup val2 = FindSfx(val); if ((Object)(object)val2 == (Object)null) { return; } foreach (AudioSource source in Sources) { if ((Object)(object)source != (Object)null) { source.outputAudioMixerGroup = val2; } } _appliedMixer = val; } [return: <040cafbb-8436-4a5b-a3c8-5aa8abcf3260>Nullable(2)] private static AudioMixerGroup FindSfx(AudioMixer mixer) { AudioMixerGroup[] array = mixer.FindMatchingGroups(string.Empty); foreach (AudioMixerGroup val in array) { if ((Object)(object)val != (Object)null && string.Equals(((Object)val).name, "SFX", StringComparison.OrdinalIgnoreCase)) { return val; } } return null; } } [HarmonyPatch(typeof(AudioMan), "Awake")] internal static class AudioMan_Awake_CompanionAudio_Patch { [<4aa5bef7-1be0-456e-b57f-5048df7109d2>NullableContext(1)] private static void Postfix(AudioMan __instance) { CompanionsAudio.Apply(__instance); } } internal static class CompanionsDefaults { internal const CompanionCollectionMode CollectionMode = CompanionCollectionMode.MarkedItems; internal const float PickupRadius = 6f; internal const float MinPickupRadius = 1f; internal const float MaxPickupRadius = 30f; internal const float DropDetectionRadius = 50f; internal const float PickableDetectionRadius = 20f; internal const float MinDetectionRadius = 1f; internal const float MaxDetectionRadius = 100f; internal const float MaxOwnerDistance = 70f; internal const float MinOwnerDistance = 10f; internal const float MaxMaxOwnerDistance = 150f; internal const bool TeleportCompanion = true; internal const bool WaitAtDungeonEntrance = false; internal const bool CatchUpTeleport = true; internal const float CatchUpDistance = 80f; internal const bool ShowMapIcon = true; internal const CompanionSelectModifier SelectModifier = CompanionSelectModifier.Alt; internal static readonly KeyboardShortcut CallKey = new KeyboardShortcut((KeyCode)104, Array.Empty<KeyCode>()); internal static readonly KeyboardShortcut FollowStayKey = new KeyboardShortcut((KeyCode)101, Array.Empty<KeyCode>()); internal static readonly KeyboardShortcut OpenChestKey = new KeyboardShortcut((KeyCode)101, (KeyCode[])(object)new KeyCode[1] { (KeyCode)304 }); } [<040cafbb-8436-4a5b-a3c8-5aa8abcf3260>Nullable(0)] [<4aa5bef7-1be0-456e-b57f-5048df7109d2>NullableContext(1)] internal static class CompanionTokens { internal const string SlotName = "$companions_slot_name"; internal const string ChestName = "$companions_chest_name"; internal const string CargoName = "$companions_cargo_name"; internal const string HoverFollowStay = "$companions_hover_follow_stay"; internal const string HoverOpenChest = "$companions_hover_open_chest"; internal const string HoverCall = "$companions_hover_call"; internal const string TooltipClick = "$companions_tooltip_click"; internal const string TooltipSelectCollection = "$companions_tooltip_select_collection"; internal const string TooltipDeselectCollection = "$companions_tooltip_deselect_collection"; internal const string PopupTitle = "$companions_popup_title"; internal const string PopupDiscard = "$companions_popup_discard"; internal const string MsgPopupUnavailable = "$companions_msg_popup_unavailable"; internal const string MsgBlockedItem = "$companions_msg_blocked_item"; internal const string MsgOwnerOpen = "$companions_msg_owner_open"; internal const string MsgOwnerTakeAll = "$companions_msg_owner_take_all"; internal const string MsgUnequipFirst = "$companions_msg_unequip_first"; internal const string MsgWaitingAtEntrance = "$companions_msg_waiting_at_entrance"; internal const string MsgCalled = "$companions_msg_called"; internal const string MsgServerUnavailable = "$companions_msg_server_unavailable"; internal const string MsgServerNotResponding = "$companions_msg_server_not_responding"; } internal static class CompanionsLocalization { [<4aa5bef7-1be0-456e-b57f-5048df7109d2>NullableContext(1)] internal static string Localize(string token) { if (Localization.instance == null) { return token; } string text = Localization.instance.Localize(token); return string.IsNullOrEmpty(text) ? token : text; } } [BepInPlugin("radamanto.Companions", "Companions", "1.0.5")] [BepInDependency(/*Could not decode attribute arguments.*/)] [BepInDependency(/*Could not decode attribute arguments.*/)] [<040cafbb-8436-4a5b-a3c8-5aa8abcf3260>Nullable(0)] [<4aa5bef7-1be0-456e-b57f-5048df7109d2>NullableContext(2)] public class CompanionsPlugin : BaseUnityPlugin { [<4aa5bef7-1be0-456e-b57f-5048df7109d2>NullableContext(0)] private sealed class ConfigurationManagerAttributes { public bool? Browsable; } [<040cafbb-8436-4a5b-a3c8-5aa8abcf3260>Nullable(1)] public const string PluginId = "radamanto.Companions"; [<040cafbb-8436-4a5b-a3c8-5aa8abcf3260>Nullable(1)] public const string PluginName = "Companions"; [<040cafbb-8436-4a5b-a3c8-5aa8abcf3260>Nullable(1)] public const string PluginVersion = "1.0.5"; [<040cafbb-8436-4a5b-a3c8-5aa8abcf3260>Nullable(1)] internal static readonly Harmony H = new Harmony("radamanto.Companions"); internal static ConfigEntry<float> FlightHeight; [<040cafbb-8436-4a5b-a3c8-5aa8abcf3260>Nullable(new byte[] { 2, 1 })] internal static ConfigEntry<string> BlockedItems; internal static ConfigEntry<bool> TeleportCompanion; internal static ConfigEntry<bool> WaitAtDungeonEntrance; internal static ConfigEntry<bool> CatchUpTeleport; internal static ConfigEntry<float> CatchUpDistance; internal static ConfigEntry<bool> ShowMapIcon; internal static ConfigEntry<CompanionCollectionMode> CollectionMode; internal static ConfigEntry<float> CollectionRadius; internal static ConfigEntry<float> CollectionDetectionRadius; internal static ConfigEntry<float> CollectionMaxOwnerDistance; internal static ConfigEntry<CompanionCollectionMode> PickableMode; internal static ConfigEntry<float> PickableDetectionRadius; internal static ConfigEntry<KeyboardShortcut> CallKey; internal static ConfigEntry<KeyboardShortcut> FollowStayKey; internal static ConfigEntry<KeyboardShortcut> OpenChestKey; internal static ConfigEntry<CompanionSelectModifier> SelectModifier; private static bool _bootstrapped; private bool _ownsBootstrap; private const float ConfigReloadDelay = 0.5f; internal static ConfigSync ConfigSync; private FileSystemWatcher _configWatcher; private bool _reloadInProgress; private float _reloadAt = -1f; private void Awake() { if (_bootstrapped) { return; } if (!CompanionsAssets.LoadBundle(out var error)) { ((BaseUnityPlugin)this).Logger.LogError((object)error); return; } Localizer.Load(); _ownsBootstrap = true; bool saveOnConfigSet = ((BaseUnityPlugin)this).Config.SaveOnConfigSet; ((BaseUnityPlugin)this).Config.SaveOnConfigSet = false; try { SetupServerSync(); BindConfiguration(); CompanionsAssets.Register(); CompanionsAudio.Initialize(CompanionsAssets.Bundle); H.PatchAll(); CompanionsInvoker.Initialize(); _bootstrapped = true; } finally { ((BaseUnityPlugin)this).Config.SaveOnConfigSet = saveOnConfigSet; } ((BaseUnityPlugin)this).Config.Save(); SetupConfigWatcher(); } private void OnDestroy() { if (_ownsBootstrap) { CompanionsInvoker.Unregister(); CompanionsNetwork.Unregister(); H.UnpatchSelf(); DisposeConfigWatcher(); ClearStaticState(); _bootstrapped = false; } } private static void ClearStaticState() { CompanionsInvoker.Reset(); CompanionsNetwork.Reset(); CompanionsTracker.Reset(); CompanionsCatchUp.Reset(); CompanionsTeleport.Reset(); CompanionsCollectionSelection.Close(); CompanionsMapIcons.Clear(); CompanionsControls.InvalidateLabels(); CompanionCollector.ResetStatics(); } private void BindConfiguration() { //IL_01d1: Unknown result type (might be due to invalid IL or missing references) //IL_01f2: Unknown result type (might be due to invalid IL or missing references) //IL_0213: Unknown result type (might be due to invalid IL or missing references) FlightHeight = Cfg("02 - Flight", "02.01 - Flight Height", 1f, "Companion flight height in meters."); BlockedItems = Cfg("03 - Companion Container", "03.01 - Blocked Items", "BlackMetal, BlackMetalScrap, Bronze, BronzeScrap, CharredCogwheel, Copper, CopperOre, CopperScrap, DragonEgg, DvergrNeedle, Flametal, FlametalNew, FlametalOre, FlametalOreNew, Gold, GoldOre, Iron, IronOre, Ironpit, IronScrap, MechanicalSpring, Silver, SilverOre, Tin, TinOre", "Comma-separated prefab names, item tokens, or localized names that companions cannot carry. Vanilla ores are preconfigured."); BindContainerConfiguration(); TeleportCompanion = Cfg("04 - Teleport", "04.01 - Follow Through Portals", defaultValue: true, "If true, companions follow their owner through portals and other game teleports. Dungeon entrances are controlled only by 04.02."); WaitAtDungeonEntrance = Cfg("04 - Teleport", "04.02 - Wait At Dungeon Entrance", defaultValue: false, "If true, companions wait at the dungeon entrance while you are inside and rejoin you when you leave. While waiting they do nothing else. If false, they follow you inside. Independent of 04.01."); CatchUpTeleport = Cfg("04 - Teleport", "04.03 - Catch Up Teleport", defaultValue: true, "If true, a following companion that falls too far behind reappears next to its owner with its spawn effect. Companions left behind by a portal while 04.01 is off are not pulled; they resume following once you come back near them."); CatchUpDistance = Cfg("04 - Teleport", "04.04 - Catch Up Distance", 80f, "Distance in meters from the owner that triggers the catch-up teleport, from 20 to 300. Keep it above 07.02 Max Owner Distance so collecting companions are not pulled back.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(20f, 300f)); CollectionMode = Cfg("05 - Collection Dropped", "05.01 - Mode", CompanionCollectionMode.MarkedItems, "Collection of dropped items (items lying on the ground). MarkedItems collects every item type selected in the companion chest into matching stacks and empty chest slots. Select with the key in 07.06 + left-click; doing it on another stack of the same type moves the selection. AllItems collects any allowed ground item. None disables it. Items dropped by other players are never collected."); CollectionDetectionRadius = Cfg("05 - Collection Dropped", "05.02 - Detection Radius", 50f, "Radius in meters for finding dropped items while following, from 1 to 100.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(1f, 100f)); PickableMode = Cfg("06 - Collection Pickables", "06.01 - Mode", CompanionCollectionMode.MarkedItems, "Harvesting of pickables such as raspberries, blueberries, mushrooms, thistle, flint and branches. MarkedItems harvests only pickables whose item is selected in the companion chest (same selection used for dropped items). AllItems harvests any pickable whose item is allowed. None disables it. The yield goes straight into the chest; what is blocked or does not fit drops on the ground. Never inside other players' wards."); PickableDetectionRadius = Cfg("06 - Collection Pickables", "06.02 - Detection Radius", 20f, "Radius in meters for finding pickables while following, from 1 to 100. Usually smaller than 05.02, so the companion only harvests what is close to you.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(1f, 100f)); CollectionRadius = Cfg("07 - Companion Control", "07.01 - Pickup Radius", 6f, "Distance in meters at which the companion picks up dropped items and harvests pickables, from 1 to 30. A staying companion only collects within this radius.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(1f, 30f)); CollectionMaxOwnerDistance = Cfg("07 - Companion Control", "07.02 - Max Owner Distance", 70f, "A following companion stops collecting and returns to you beyond this distance in meters, from 10 to 150.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(10f, 150f)); CallKey = Cfg<KeyboardShortcut>("07 - Companion Control", "07.03 - Call Key", CompanionsDefaults.CallKey, "Calls your loaded companions from any distance: whether following, staying or collecting, each one comes next to you and stays there. A companion waiting at a dungeon entrance is left as it is. Set to None to disable.", null, synced: false); FollowStayKey = Cfg<KeyboardShortcut>("07 - Companion Control", "07.04 - Follow Stay Key", CompanionsDefaults.FollowStayKey, "Key pressed while looking at your companion up close to toggle follow / stay. Set to None to disable. Gamepads keep the game's interact button.", null, synced: false); OpenChestKey = Cfg<KeyboardShortcut>("07 - Companion Control", "07.05 - Open Chest Key", CompanionsDefaults.OpenChestKey, "Key pressed while looking at your companion up close to open its chest. Set to None to disable. Gamepads keep the game's alternate interact.", null, synced: false); SelectModifier = Cfg("07 - Companion Control", "07.06 - Select For Collection Key", CompanionSelectModifier.Alt, "Hold this key and left-click an item in the companion chest to select or clear it for collection (dropped items and pickables).", null, synced: false); ShowMapIcon = Cfg("08 - Map", "08.01 - Show Map Icon", defaultValue: true, "If true, your companions are shown on the minimap and the large map, at any distance."); FlightHeight.SettingChanged += [<4aa5bef7-1be0-456e-b57f-5048df7109d2>NullableContext(0)] (object _, EventArgs _) => { CompanionsFlight.RefreshHeight(); }; CallKey.SettingChanged += [<4aa5bef7-1be0-456e-b57f-5048df7109d2>NullableContext(0)] (object _, EventArgs _) => { CompanionsControls.InvalidateLabels(); }; FollowStayKey.SettingChanged += [<4aa5bef7-1be0-456e-b57f-5048df7109d2>NullableContext(0)] (object _, EventArgs _) => { CompanionsControls.InvalidateLabels(); }; OpenChestKey.SettingChanged += [<4aa5bef7-1be0-456e-b57f-5048df7109d2>NullableContext(0)] (object _, EventArgs _) => { CompanionsControls.InvalidateLabels(); }; BlockedItems.SettingChanged += [<4aa5bef7-1be0-456e-b57f-5048df7109d2>NullableContext(0)] (object _, EventArgs _) => { CompanionsContainer.ReloadBlocklist(BlockedItems.Value); }; CollectionMode.SettingChanged += [<4aa5bef7-1be0-456e-b57f-5048df7109d2>NullableContext(0)] (object _, EventArgs _) => { CompanionCollector.RefreshSensors(); }; CollectionRadius.SettingChanged += [<4aa5bef7-1be0-456e-b57f-5048df7109d2>NullableContext(0)] (object _, EventArgs _) => { CompanionCollector.RefreshSensors(); }; CollectionDetectionRadius.SettingChanged += [<4aa5bef7-1be0-456e-b57f-5048df7109d2>NullableContext(0)] (object _, EventArgs _) => { CompanionCollector.RefreshSensors(); }; CollectionMaxOwnerDistance.SettingChanged += [<4aa5bef7-1be0-456e-b57f-5048df7109d2>NullableContext(0)] (object _, EventArgs _) => { CompanionCollector.RefreshSensors(); }; PickableMode.SettingChanged += [<4aa5bef7-1be0-456e-b57f-5048df7109d2>NullableContext(0)] (object _, EventArgs _) => { CompanionCollector.RefreshSensors(); }; PickableDetectionRadius.SettingChanged += [<4aa5bef7-1be0-456e-b57f-5048df7109d2>NullableContext(0)] (object _, EventArgs _) => { CompanionCollector.RefreshSensors(); }; CompanionsContainer.ReloadBlocklist(BlockedItems.Value); } private void BindContainerConfiguration() { Dictionary<string, string> english = LoadEnglishTexts(); CompanionDefinition[] all = CompanionsRegistry.All; foreach (CompanionDefinition definition in all) { string englishName = GetEnglishName(english, definition.CompanionNameToken, "Companion " + definition.Id); string section = "03." + definition.Id + " - " + englishName + " Container"; ConfigEntry<int> width = Cfg(section, "01 - Width", definition.DefaultContainerWidth, "Container width for the " + englishName + ", from 1 to 8.", (AcceptableValueBase)(object)new AcceptableValueRange<int>(1, 8)); ConfigEntry<int> height = Cfg(section, "02 - Height", definition.DefaultContainerHeight, "Container height for the " + englishName + ", from 1 to 8.", (AcceptableValueBase)(object)new AcceptableValueRange<int>(1, 8)); definition.ContainerWidth = width.Value; definition.ContainerHeight = height.Value; width.SettingChanged += [<4aa5bef7-1be0-456e-b57f-5048df7109d2>NullableContext(0)] (object _, EventArgs _) => { definition.ContainerWidth = width.Value; }; height.SettingChanged += [<4aa5bef7-1be0-456e-b57f-5048df7109d2>NullableContext(0)] (object _, EventArgs _) => { definition.ContainerHeight = height.Value; }; } } [<4aa5bef7-1be0-456e-b57f-5048df7109d2>NullableContext(1)] private Dictionary<string, string> LoadEnglishTexts() { try { byte[] array = Localizer.ReadEmbeddedFileBytes("translations.English.yml", typeof(CompanionsPlugin).Assembly); if (array == null) { return new Dictionary<string, string>(); } string input = Encoding.UTF8.GetString(array).TrimStart(new char[1] { '\ufeff' }); return new DeserializerBuilder().Build().Deserialize<Dictionary<string, string>>(input) ?? new Dictionary<string, string>(); } catch (Exception ex) { ((BaseUnityPlugin)this).Logger.LogWarning((object)("English translations could not be read: " + ex.Message)); return new Dictionary<string, string>(); } } [<4aa5bef7-1be0-456e-b57f-5048df7109d2>NullableContext(1)] private static string GetEnglishName(Dictionary<string, string> english, string token, string fallback) { string key = (token.StartsWith("$") ? token.Substring(1) : token); if (!english.TryGetValue(key, out var value) || string.IsNullOrWhiteSpace(value)) { return fallback; } string text = Regex.Replace(value, "[=\\n\\t\\\\\"\\'\\[\\]]*", string.Empty).Trim(); return (text.Length > 0) ? text : fallback; } private void Update() { if (!(_reloadAt < 0f) && !(Time.realtimeSinceStartup < _reloadAt)) { _reloadAt = -1f; ReloadConfig(); } } private void SetupServerSync() { //IL_009f: Unknown result type (might be due to invalid IL or missing references) //IL_00a9: Expected O, but got Unknown ConfigSync = new ConfigSync(((BaseUnityPlugin)this).Info.Metadata.GUID) { DisplayName = ((BaseUnityPlugin)this).Info.Metadata.Name, CurrentVersion = ((BaseUnityPlugin)this).Info.Metadata.Version.ToString(), MinimumRequiredVersion = ((BaseUnityPlugin)this).Info.Metadata.Version.ToString(), ModRequired = true }; ConfigEntry<bool> lockingConfig = ((BaseUnityPlugin)this).Config.Bind<bool>("01 - General", "Lock Configuration", true, new ConfigDescription("If true, the server locks synchronized configuration values.", (AcceptableValueBase)null, new object[1] { new ConfigurationManagerAttributes { Browsable = false } })); ConfigSync.AddLockingConfigEntry<bool>(lockingConfig); } [<4aa5bef7-1be0-456e-b57f-5048df7109d2>NullableContext(1)] private ConfigEntry<T> Cfg<[<040cafbb-8436-4a5b-a3c8-5aa8abcf3260>Nullable(2)] T>(string section, string key, T defaultValue, string description, [<040cafbb-8436-4a5b-a3c8-5aa8abcf3260>Nullable(2)] AcceptableValueBase acceptableValues = null, bool synced = true) { //IL_0036: Unknown result type (might be due to invalid IL or missing references) //IL_003c: Expected O, but got Unknown if (ConfigSync == null) { throw new InvalidOperationException("ServerSync has not been initialized."); } ConfigDescription val = new ConfigDescription(description + (synced ? " [Synced with Server]" : " [Not Synced with Server]"), acceptableValues, Array.Empty<object>()); ConfigEntry<T> val2 = ((BaseUnityPlugin)this).Config.Bind<T>(section, key, defaultValue, val); ConfigSync.AddConfigEntry<T>(val2).SynchronizedConfig = synced; return val2; } private void SetupConfigWatcher() { try { _configWatcher?.Dispose(); _configWatcher = new FileSystemWatcher(Path.GetDirectoryName(((BaseUnityPlugin)this).Config.ConfigFilePath), Path.GetFileName(((BaseUnityPlugin)this).Config.ConfigFilePath)) { IncludeSubdirectories = false, NotifyFilter = (NotifyFilters.FileName | NotifyFilters.Size | NotifyFilters.LastWrite), SynchronizingObject = ThreadingHelper.SynchronizingObject }; FileSystemEventHandler value = [<4aa5bef7-1be0-456e-b57f-5048df7109d2>NullableContext(0)] (object _, FileSystemEventArgs _) => { ScheduleConfigReload(); }; _configWatcher.Changed += value; _configWatcher.Created += value; _configWatcher.Renamed += [<4aa5bef7-1be0-456e-b57f-5048df7109d2>NullableContext(0)] (object _, RenamedEventArgs _) => { ScheduleConfigReload(); }; _configWatcher.EnableRaisingEvents = true; } catch (Exception ex) { ((BaseUnityPlugin)this).Logger.LogWarning((object)("Config file watcher disabled: " + ex.Message)); _configWatcher?.Dispose(); _configWatcher = null; } } private void ScheduleConfigReload() { if (!((Behaviour)this).isActiveAndEnabled) { ReloadConfig(); } else { _reloadAt = Time.realtimeSinceStartup + 0.5f; } } private void ReloadConfig() { if (_reloadInProgress) { return; } bool saveOnConfigSet = ((BaseUnityPlugin)this).Config.SaveOnConfigSet; try { _reloadInProgress = true; if (_configWatcher != null) { _configWatcher.EnableRaisingEvents = false; } ((BaseUnityPlugin)this).Config.SaveOnConfigSet = false; ((BaseUnityPlugin)this).Config.Reload(); } catch (Exception ex) { ((BaseUnityPlugin)this).Logger.LogError((object)("Failed to reload configuration: " + ex)); } finally { ((BaseUnityPlugin)this).Config.SaveOnConfigSet = saveOnConfigSet; _reloadInProgress = false; if (_configWatcher != null) { _configWatcher.EnableRaisingEvents = true; } } } private void DisposeConfigWatcher() { _reloadAt = -1f; if (_configWatcher != null) { _configWatcher.EnableRaisingEvents = false; _configWatcher.Dispose(); _configWatcher = null; } } } [<4aa5bef7-1be0-456e-b57f-5048df7109d2>NullableContext(1)] [<040cafbb-8436-4a5b-a3c8-5aa8abcf3260>Nullable(0)] internal static class CompanionsContainer { [<4aa5bef7-1be0-456e-b57f-5048df7109d2>NullableContext(0)] private sealed class InventoryMarker { } internal const string DefaultBlockedOres = "BlackMetal, BlackMetalScrap, Bronze, BronzeScrap, CharredCogwheel, Copper, CopperOre, CopperScrap, DragonEgg, DvergrNeedle, Flametal, FlametalNew, FlametalOre, FlametalOreNew, Gold, GoldOre, Iron, IronOre, Ironpit, IronScrap, MechanicalSpring, Silver, SilverOre, Tin, TinOre"; internal const string OpenResponseRpc = "RPC_OpenResponse"; internal const string TakeAllResponseRpc = "RPC_TakeAllResponse"; private const float MessageRepeatDelay = 1f; internal static readonly int CargoOwnerKey = StringExtensionMethods.GetStableHashCode("comp.cargoOwner"); internal static readonly int CargoOwnerPlatformKey = StringExtensionMethods.GetStableHashCode("comp.cargoOwnerPlatform"); private static readonly HashSet<string> Blocked = new HashSet<string>(StringComparer.OrdinalIgnoreCase); private static readonly ConditionalWeakTable<Inventory, InventoryMarker> Inventories = new ConditionalWeakTable<Inventory, InventoryMarker>(); [<040cafbb-8436-4a5b-a3c8-5aa8abcf3260>Nullable(2)] private static string _lastMessageToken; private static float _lastMessageTime = float.MinValue; private static int _loadingDepth; internal static void ReloadBlocklist(string value) { Blocked.Clear(); string[] array = (value ?? string.Empty).Split(new char[5] { ',', ';', '\n', '\r', '\t' }, StringSplitOptions.RemoveEmptyEntries); for (int i = 0; i < array.Length; i++) { string text = array[i].Trim(); if (text.Length > 0) { Blocked.Add(text); } } } internal static void BeginLoad() { _loadingDepth++; } internal static void EndLoad() { _loadingDepth--; } [return: <040cafbb-8436-4a5b-a3c8-5aa8abcf3260>Nullable(2)] internal static ZNetView GetView(Component component) { return ((Object)(object)component != (Object)null) ? (component.GetComponentInParent<ZNetView>() ?? component.GetComponent<ZNetView>()) : null; } [return: <040cafbb-8436-4a5b-a3c8-5aa8abcf3260>Nullable(2)] internal static Container FindContainer(Component component) { if ((Object)(object)component == (Object)null) { return null; } Container val = component.GetComponent<Container>(); if ((Object)(object)val == (Object)null) { val = component.GetComponentInParent<Container>(); } if ((Object)(object)val == (Object)null) { val = component.GetComponentInChildren<Container>(); } return val; } internal static bool IsCompanionContainer(Container container) { if ((Object)(object)container == (Object)null) { return false; } Character componentInParent = ((Component)container).GetComponentInParent<Character>(); return (Object)(object)componentInParent != (Object)null && CompanionsState.IsCompanion(((Component)componentInParent).gameObject); } internal static bool CanAccess(Humanoid character, Container container) { return IsCompanionContainer(container) ? CompanionsState.IsOwner(character, GetView((Component)(object)container)) : IsCargoOwner(character, container); } internal static bool AllowsRequest(Container container, long playerId) { ZNetView nview = container.m_nview; if ((Object)(object)nview == (Object)null || !nview.IsValid() || !nview.IsOwner()) { return true; } ZDO zDO = nview.GetZDO(); if (IsCompanionContainer(container)) { long num = zDO.GetLong(CompanionsState.OwnerKey, 0L); return num != 0L && num == playerId; } long num2 = zDO.GetLong(CargoOwnerKey, 0L); return num2 == 0L || num2 == playerId; } internal static void RefreshOwnerPlatform(Humanoid character, Container container) { Player val = (Player)(object)((character is Player) ? character : null); if (val != null) { ZNetView view = GetView((Component)(object)container); if (!((Object)(object)view == (Object)null) && view.IsValid()) { bool flag = IsCompanionContainer(container); CompanionsState.RefreshPlatform(view.GetZDO(), flag ? CompanionsState.OwnerKey : CargoOwnerKey, flag ? CompanionsState.OwnerPlatformKey : CargoOwnerPlatformKey, val.GetPlayerID(), CompanionsState.GetPlatformId(val)); } } } internal static void Register(Container container) { Inventory val = (((Object)(object)container != (Object)null) ? container.GetInventory() : null); if (val != null && !Inventories.TryGetValue(val, out var _)) { Inventories.Add(val, new InventoryMarker()); } } internal static void ApplySize(Container container, [<040cafbb-8436-4a5b-a3c8-5aa8abcf3260>Nullable(2)] CompanionDefinition definition = null) { if ((Object)(object)container == (Object)null) { return; } ZDO val = null; if (definition == null) { GameObject gameObject = ((Component)((Component)container).transform.root).gameObject; CompanionIdentity companionIdentity = default(CompanionIdentity); if (!gameObject.TryGetComponent<CompanionIdentity>(ref companionIdentity)) { return; } definition = CompanionsRegistry.ForCompanion(Utils.GetPrefabName(gameObject)); ZNetView view = GetView((Component)(object)container); val = (((Object)(object)view != (Object)null) ? view.GetZDO() : null); } if (definition != null) { int width = definition.ContainerWidth; int height = definition.ContainerHeight; if (val != null) { FitStoredItems(val, ref width, ref height); } container.m_width = width; container.m_height = height; } } internal static void EnsureCapacity(Container container) { if ((Object)(object)container == (Object)null) { return; } Inventory inventory = container.m_inventory; ZNetView nview = container.m_nview; if (inventory == null || (Object)(object)nview == (Object)null || !nview.IsValid() || !Inventories.TryGetValue(inventory, out var _)) { return; } ZDO zDO = nview.GetZDO(); if (zDO.DataRevision != container.m_lastRevision && !container.m_inUse) { int width = inventory.m_width; int height = inventory.m_height; if (FitStoredItems(zDO, ref width, ref height)) { inventory.m_width = width; inventory.m_height = height; container.m_width = width; container.m_height = height; } } } internal static bool WouldSwap([<040cafbb-8436-4a5b-a3c8-5aa8abcf3260>Nullable(2)] ItemData itemAt, ItemData item, int amount) { return itemAt != null && itemAt != item && item.m_stack == amount && (itemAt.m_shared.m_name != item.m_shared.m_name || (item.m_shared.m_maxQuality > 1 && itemAt.m_quality != item.m_quality) || itemAt.m_shared.m_maxStackSize == 1); } [<4aa5bef7-1be0-456e-b57f-5048df7109d2>NullableContext(2)] internal static bool BlocksDrop(Inventory target, Inventory from, ItemData item, int amount, Vector2i position) { //IL_0026: 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) if (target == null || from == null || item == null) { return false; } if (IsBlocked(target, item)) { return true; } ItemData itemAt = target.GetItemAt(position.x, position.y); return WouldSwap(itemAt, item, amount) && IsBlocked(from, itemAt); } internal static bool IsBlocked(Inventory inventory, ItemData item) { if (inventory == null || item == null || !Inventories.TryGetValue(inventory, out var _)) { return false; } if (CompanionsRegistry.ForInvoker(item) != null) { return true; } if (Blocked.Count == 0) { return false; } string text = (((Object)(object)item.m_dropPrefab != (Object)null) ? Utils.GetPrefabName(item.m_dropPrefab) : string.Empty); if (text.Length > 0 && Blocked.Contains(text)) { return true; } string text2 = ((item.m_shared != null) ? item.m_shared.m_name : string.Empty); if (text2.Length == 0) { return false; } if (Blocked.Contains(text2)) { return true; } if (text2[0] == '$' && Blocked.Contains(text2.Substring(1))) { return true; } if (Localization.instance == null) { return false; } string text3 = Localization.instance.Localize(text2); if (string.IsNullOrEmpty(text3)) { return false; } string item2 = text3.Replace("<b>", string.Empty).Replace("</b>", string.Empty).Replace("<color=yellow>", string.Empty) .Replace("</color>", string.Empty) .Trim(); return Blocked.Contains(text3) || Blocked.Contains(item2); } internal static bool AllowAdd(Inventory inventory, ItemData item, ref bool result) { if (_loadingDepth > 0 || !IsBlocked(inventory, item)) { return true; } result = false; Show("$companions_msg_blocked_item"); return false; } internal static void Show(string token) { if (!(token == _lastMessageToken) || !(Time.time - _lastMessageTime < 1f)) { MessageHud instance = MessageHud.instance; if (!((Object)(object)instance == (Object)null)) { _lastMessageToken = token; _lastMessageTime = Time.time; instance.ShowMessage((MessageType)2, CompanionsLocalization.Localize(token), 0, (Sprite)null, false, true); } } } private static bool IsCargoOwner(Humanoid character, Container container) { ZNetView view = GetView((Component)(object)container); if ((Object)(object)view == (Object)null || !view.IsValid()) { return true; } ZDO zDO = view.GetZDO(); if (zDO.GetLong(CargoOwnerKey, 0L) == 0) { return true; } Player val = (Player)(object)((character is Player) ? character : null); return val != null && CompanionsState.MatchesOwner(zDO, CargoOwnerKey, CargoOwnerPlatformKey, val.GetPlayerID(), CompanionsState.GetPlatformId(val)); } private static bool FitStoredItems(ZDO zdo, ref int width, ref int height) { //IL_0028: Unknown result type (might be due to invalid IL or missing references) //IL_002e: Expected O, but got Unknown //IL_0031: Unknown result type (might be due to invalid IL or missing references) //IL_003b: Expected O, but got Unknown //IL_0060: Unknown result type (might be due to invalid IL or missing references) //IL_0065: Unknown result type (might be due to invalid IL or missing references) //IL_0067: Unknown result type (might be due to invalid IL or missing references) //IL_008a: Unknown result type (might be due to invalid IL or missing references) //IL_007d: Unknown result type (might be due to invalid IL or missing references) //IL_00a0: Unknown result type (might be due to invalid IL or missing references) byte[] byteArray = zdo.GetByteArray(ZDOVars.s_items, (byte[])null); if (byteArray == null || byteArray.Length == 0) { return false; } Inventory val = new Inventory(true); try { val.Load(new ZPackage(byteArray)); } catch { return false; } bool result = false; List<ItemData> allItems = val.GetAllItems(); for (int i = 0; i < allItems.Count; i++) { Vector2i gridPos = allItems[i].m_gridPos; if (gridPos.x >= width) { width = gridPos.x + 1; result = true; } if (gridPos.y >= height) { height = gridPos.y + 1; result = true; } } return result; } } [<040cafbb-8436-4a5b-a3c8-5aa8abcf3260>Nullable(0)] [HarmonyPatch(typeof(Container), "Awake")] [<4aa5bef7-1be0-456e-b57f-5048df7109d2>NullableContext(1)] internal static class Container_Awake_CompanionRegistration_Patch { private static void Prefix(Container __instance) { CompanionsContainer.ApplySize(__instance); } private static void Postfix(Container __instance) { if (CompanionsContainer.IsCompanionContainer(__instance)) { CompanionsContainer.Register(__instance); } } } [HarmonyPatch(typeof(Container), "Load")] internal static class Container_Load_CompanionCapacity_Patch { [<4aa5bef7-1be0-456e-b57f-5048df7109d2>NullableContext(1)] private static void Prefix(Container __instance) { CompanionsContainer.EnsureCapacity(__instance); } } [HarmonyPatch(typeof(InventoryGrid), "DropItem", new Type[] { typeof(Inventory), typeof(ItemData), typeof(int), typeof(Vector2i) })] internal static class InventoryGrid_DropItem_Companion_Patch { [<4aa5bef7-1be0-456e-b57f-5048df7109d2>NullableContext(1)] private static bool Prefix(InventoryGrid __instance, Inventory fromInventory, ItemData item, int amount, Vector2i pos, ref bool __result) { //IL_000c: Unknown result type (might be due to invalid IL or missing references) //IL_0019: Unknown result type (might be due to invalid IL or missing references) Inventory inventory = __instance.GetInventory(); string text = (CompanionsInvoker.BlocksDrop(inventory, fromInventory, item, amount, pos) ? "$companions_msg_unequip_first" : (CompanionsContainer.BlocksDrop(inventory, fromInventory, item, amount, pos) ? "$companions_msg_blocked_item" : null)); if (text == null) { return true; } __result = false; CompanionsContainer.Show(text); return false; } } [HarmonyPatch(typeof(Container), "Interact", new Type[] { typeof(Humanoid), typeof(bool), typeof(bool) })] internal static class Container_Interact_CompanionOwnership_Patch { [<4aa5bef7-1be0-456e-b57f-5048df7109d2>NullableContext(1)] private static bool Prefix(Container __instance, Humanoid character, ref bool __result) { if (CompanionsContainer.CanAccess(character, __instance)) { CompanionsContainer.RefreshOwnerPlatform(character, __instance); return true; } __result = false; CompanionsContainer.Show("$companions_msg_owner_open"); return false; } } [HarmonyPatch(typeof(Container), "TakeAll", new Type[] { typeof(Humanoid) })] internal static class Container_TakeAll_CompanionOwnership_Patch { [<4aa5bef7-1be0-456e-b57f-5048df7109d2>NullableContext(1)] private static bool Prefix(Container __instance, Humanoid character) { if (CompanionsContainer.CanAccess(character, __instance)) { return true; } CompanionsContainer.Show("$companions_msg_owner_take_all"); return false; } } [HarmonyPatch(typeof(Container), "RPC_RequestOpen", new Type[] { typeof(long), typeof(long) })] internal static class Container_RPC_RequestOpen_CompanionOwnership_Patch { [<4aa5bef7-1be0-456e-b57f-5048df7109d2>NullableContext(1)] private static bool Prefix(Container __instance, long uid, long playerID) { if (CompanionsContainer.AllowsRequest(__instance, playerID)) { return true; } __instance.m_nview.InvokeRPC(uid, "RPC_OpenResponse", new object[1] { false }); return false; } } [HarmonyPatch(typeof(Container), "RPC_RequestTakeAll", new Type[] { typeof(long), typeof(long) })] internal static class Container_RPC_RequestTakeAll_CompanionOwnership_Patch { [<4aa5bef7-1be0-456e-b57f-5048df7109d2>NullableContext(1)] private static bool Prefix(Container __instance, long uid, long playerID) { if (CompanionsContainer.AllowsRequest(__instance, playerID)) { return true; } __instance.m_nview.InvokeRPC(uid, "RPC_TakeAllResponse", new object[1] { false }); return false; } } [HarmonyPatch(typeof(Inventory), "Load", new Type[] { typeof(ZPackage) })] internal static class Inventory_Load_CompanionBlocklist_Patch { private static void Prefix(out bool __state) { __state = true; CompanionsContainer.BeginLoad(); } private static void Finalizer(bool __state) { if (__state) { CompanionsContainer.EndLoad(); } } } [HarmonyPatch(typeof(Inventory), "Load", new Type[] { typeof(ZPackage), typeof(bool) })] internal static class Inventory_LoadVersioned_CompanionBlocklist_Patch { private static void Prefix(out bool __state) { __state = true; CompanionsContainer.BeginLoad(); } private static void Finalizer(bool __state) { if (__state) { CompanionsContainer.EndLoad(); } } } [HarmonyPatch(typeof(Inventory), "CanAddItem", new Type[] { typeof(ItemData), typeof(int) })] internal static class Inventory_CanAddItem_CompanionBlocklist_Patch { [<4aa5bef7-1be0-456e-b57f-5048df7109d2>NullableContext(1)] private static bool Prefix(Inventory __instance, ItemData item, ref bool __result) { return CompanionsContainer.AllowAdd(__instance, item, ref __result); } } [HarmonyPatch(typeof(Inventory), "AddItem", new Type[] { typeof(ItemData) })] internal static class Inventory_AddItem_CompanionBlocklist_Patch { [<4aa5bef7-1be0-456e-b57f-5048df7109d2>NullableContext(1)] private static bool Prefix(Inventory __instance, ItemData item, ref bool __result) { return CompanionsContainer.AllowAdd(__instance, item, ref __result); } } [HarmonyPatch(typeof(Inventory), "AddItem", new Type[] { typeof(ItemData), typeof(Vector2i) })] internal static class Inventory_AddItemAtPosition_CompanionBlocklist_Patch { [<4aa5bef7-1be0-456e-b57f-5048df7109d2>NullableContext(1)] private static bool Prefix(Inventory __instance, ItemData item, ref bool __result) { return CompanionsContainer.AllowAdd(__instance, item, ref __result); } } [HarmonyPatch(typeof(Inventory), "AddItem", new Type[] { typeof(ItemData), typeof(int), typeof(int), typeof(int), typeof(bool) })] internal static class Inventory_AddItemInternal_CompanionBlocklist_Patch { [<4aa5bef7-1be0-456e-b57f-5048df7109d2>NullableContext(1)] private static bool Prefix(Inventory __instance, ItemData item, ref bool __result) { return CompanionsContainer.AllowAdd(__instance, item, ref __result); } } [<4aa5bef7-1be0-456e-b57f-5048df7109d2>NullableContext(1)] [<040cafbb-8436-4a5b-a3c8-5aa8abcf3260>Nullable(0)] internal static class CompanionsDeathDrop { private static readonly List<ZNetView> Loaded = new List<ZNetView>(); internal static void DropLoaded(Player owner) { //IL_004e: Unknown result type (might be due to invalid IL or missing references) CompanionsState.CollectLoaded(owner, null, Loaded); for (int i = 0; i < Loaded.Count; i++) { ZNetView val = Loaded[i]; if (!val.IsOwner()) { val.ClaimOwnership(); } Container val2 = CompanionsContainer.FindContainer((Component)(object)val); if ((Object)(object)val2 != (Object)null) { DropInventory(val2, ((Component)val).transform.position); } } Loaded.Clear(); } internal static void DropInventory(Container source, Vector3 position) { //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_00a3: Unknown result type (might be due to invalid IL or missing references) Inventory inventory = source.GetInventory(); if (inventory == null || inventory.NrOfItems() == 0) { return; } GameObject val = FindDropPrefab(); if ((Object)(object)val == (Object)null) { return; } ZNetView view = CompanionsContainer.GetView((Component)(object)source); ZDO val2 = (((Object)(object)view != (Object)null && view.IsValid()) ? view.GetZDO() : null); long num = ((val2 != null) ? val2.GetLong(CompanionsState.OwnerKey, 0L) : 0); string platform = ((val2 != null) ? val2.GetString(CompanionsState.OwnerPlatformKey, string.Empty) : string.Empty); while (inventory.NrOfItems() > 0) { int num2 = inventory.NrOfItems(); GameObject val3 = Object.Instantiate<GameObject>(val, GetDropPosition(position), Random.rotation); Container componentInChildren = val3.GetComponentInChildren<Container>(); if ((Object)(object)componentInChildren == (Object)null) { DestroyDrop(val3); break; } ZNetView component = val3.GetComponent<ZNetView>(); if (num != 0L && (Object)(object)component != (Object)null && component.IsValid()) {