using System; using System.Collections.Generic; using System.Diagnostics; using System.Globalization; using System.IO; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using System.Text; using BepInEx; using BepInEx.Bootstrap; using BepInEx.Configuration; using BepInEx.Logging; using Ezomic.Core; using Grove; using HarmonyLib; using Microsoft.CodeAnalysis; using Stow; using TMPro; using UnityEngine; using UnityEngine.Events; using UnityEngine.Rendering; using UnityEngine.SceneManagement; using UnityEngine.UI; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: TargetFramework(".NETFramework,Version=v4.6.2", FrameworkDisplayName = ".NET Framework 4.6.2")] [assembly: AssemblyCompany("Thijssen Software")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyCopyright("Copyright (c) 2026 Robbin Thijssen")] [assembly: AssemblyDescription("Plant an ancient seed, feed it greydwarf blood, and a forest spirit answers.")] [assembly: AssemblyFileVersion("1.0.0.0")] [assembly: AssemblyInformationalVersion("1.0.0+d8f84037b24170229ade3950fc81695a7ecb19df")] [assembly: AssemblyProduct("Vaettir")] [assembly: AssemblyTitle("Vaettir")] [assembly: AssemblyVersion("1.0.0.0")] [module: RefSafetyRules(11)] namespace Microsoft.CodeAnalysis { [CompilerGenerated] [Embedded] internal sealed class EmbeddedAttribute : Attribute { } } namespace System.Runtime.CompilerServices { [CompilerGenerated] [Embedded] [AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)] internal sealed class RefSafetyRulesAttribute : Attribute { public readonly int Version; public RefSafetyRulesAttribute(int P_0) { Version = P_0; } } } namespace Stow { internal static class CarriedItem { private const float CarrySize = 0.17f; private static readonly Dictionary Templates = new Dictionary(); private static GameObject _holder; public static void Invalidate() { foreach (GameObject value in Templates.Values) { if ((Object)(object)value != (Object)null) { Object.Destroy((Object)(object)value); } } Templates.Clear(); } public static GameObject For(ItemData item) { return For(ItemGroups.PrefabNameOf(item)); } public static GameObject For(string prefabName) { GameObject val = Template(prefabName); if ((Object)(object)val == (Object)null) { return null; } GameObject obj = Object.Instantiate(val); obj.SetActive(true); return obj; } private static GameObject Template(string prefabName) { //IL_005f: Unknown result type (might be due to invalid IL or missing references) //IL_0069: Expected O, but got Unknown if (string.IsNullOrEmpty(prefabName)) { return null; } if (Templates.TryGetValue(prefabName, out var value)) { return value; } Templates[prefabName] = null; if ((Object)(object)ObjectDB.instance == (Object)null) { return null; } GameObject itemPrefab = ObjectDB.instance.GetItemPrefab(prefabName); if ((Object)(object)itemPrefab == (Object)null) { return null; } if ((Object)(object)_holder == (Object)null) { _holder = new GameObject("StowCarriedItems"); _holder.SetActive(false); Object.DontDestroyOnLoad((Object)(object)_holder); } bool forceDisableInit = ZNetView.m_forceDisableInit; ZNetView.m_forceDisableInit = true; GameObject val; try { val = Object.Instantiate(itemPrefab, _holder.transform); } finally { ZNetView.m_forceDisableInit = forceDisableInit; } ((Object)val).name = "carried_" + prefabName; Strip(val); GameObject val2 = Fit(val); if ((Object)(object)val2 == (Object)null) { Object.DestroyImmediate((Object)(object)val); return null; } Templates[prefabName] = val2; return val2; } private static void Strip(GameObject clone) { List list = new List(); MonoBehaviour[] componentsInChildren = clone.GetComponentsInChildren(true); foreach (MonoBehaviour val in componentsInChildren) { if ((Object)(object)val != (Object)null) { list.Add((Component)(object)val); } } Collider[] componentsInChildren2 = clone.GetComponentsInChildren(true); foreach (Collider val2 in componentsInChildren2) { if ((Object)(object)val2 != (Object)null) { list.Add((Component)(object)val2); } } Rigidbody[] componentsInChildren3 = clone.GetComponentsInChildren(true); foreach (Rigidbody val3 in componentsInChildren3) { if ((Object)(object)val3 != (Object)null) { list.Add((Component)(object)val3); } } ParticleSystem[] componentsInChildren4 = clone.GetComponentsInChildren(true); foreach (ParticleSystem val4 in componentsInChildren4) { if ((Object)(object)val4 != (Object)null) { list.Add((Component)(object)val4); } } TrailRenderer[] componentsInChildren5 = clone.GetComponentsInChildren(true); foreach (TrailRenderer val5 in componentsInChildren5) { if ((Object)(object)val5 != (Object)null) { list.Add((Component)(object)val5); } } Light[] componentsInChildren6 = clone.GetComponentsInChildren(true); foreach (Light val6 in componentsInChildren6) { if ((Object)(object)val6 != (Object)null) { list.Add((Component)(object)val6); } } AudioSource[] componentsInChildren7 = clone.GetComponentsInChildren(true); foreach (AudioSource val7 in componentsInChildren7) { if ((Object)(object)val7 != (Object)null) { list.Add((Component)(object)val7); } } foreach (Component item in list) { if ((Object)(object)item != (Object)null) { Object.DestroyImmediate((Object)(object)item); } } ParticleSystemRenderer[] componentsInChildren8 = clone.GetComponentsInChildren(true); foreach (ParticleSystemRenderer val8 in componentsInChildren8) { if ((Object)(object)val8 != (Object)null) { Object.DestroyImmediate((Object)(object)val8); } } Renderer[] componentsInChildren9 = clone.GetComponentsInChildren(true); foreach (Renderer val9 in componentsInChildren9) { if (!((Object)(object)val9 == (Object)null)) { val9.shadowCastingMode = (ShadowCastingMode)0; val9.receiveShadows = false; } } } private static GameObject Fit(GameObject clone) { //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_0010: Unknown result type (might be due to invalid IL or missing references) //IL_0015: Unknown result type (might be due to invalid IL or missing references) //IL_0048: Unknown result type (might be due to invalid IL or missing references) //IL_0050: Unknown result type (might be due to invalid IL or missing references) //IL_0055: 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_00e3: Unknown result type (might be due to invalid IL or missing references) //IL_00ef: Unknown result type (might be due to invalid IL or missing references) //IL_00fb: 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_00b3: Unknown result type (might be due to invalid IL or missing references) //IL_00b8: Unknown result type (might be due to invalid IL or missing references) //IL_00c4: Unknown result type (might be due to invalid IL or missing references) //IL_0132: Unknown result type (might be due to invalid IL or missing references) //IL_0137: Unknown result type (might be due to invalid IL or missing references) //IL_0149: Unknown result type (might be due to invalid IL or missing references) //IL_0150: Expected O, but got Unknown //IL_0180: Unknown result type (might be due to invalid IL or missing references) //IL_0193: Unknown result type (might be due to invalid IL or missing references) //IL_01a3: Unknown result type (might be due to invalid IL or missing references) //IL_01a7: Unknown result type (might be due to invalid IL or missing references) //IL_01ae: Unknown result type (might be due to invalid IL or missing references) //IL_01b3: Unknown result type (might be due to invalid IL or missing references) //IL_01b8: Unknown result type (might be due to invalid IL or missing references) Bounds bounds = default(Bounds); bool found = false; Matrix4x4 worldToLocalMatrix = clone.transform.worldToLocalMatrix; MeshFilter[] componentsInChildren = clone.GetComponentsInChildren(true); foreach (MeshFilter val in componentsInChildren) { if (!((Object)(object)val == (Object)null) && !((Object)(object)val.sharedMesh == (Object)null)) { Grow(ref bounds, ref found, worldToLocalMatrix * ((Component)val).transform.localToWorldMatrix, val.sharedMesh.bounds); } } SkinnedMeshRenderer[] componentsInChildren2 = clone.GetComponentsInChildren(true); foreach (SkinnedMeshRenderer val2 in componentsInChildren2) { if (!((Object)(object)val2 == (Object)null) && !((Object)(object)val2.sharedMesh == (Object)null)) { Grow(ref bounds, ref found, worldToLocalMatrix * ((Component)val2).transform.localToWorldMatrix, val2.sharedMesh.bounds); } } if (!found) { return null; } float num = Mathf.Max(((Bounds)(ref bounds)).size.x, Mathf.Max(((Bounds)(ref bounds)).size.y, ((Bounds)(ref bounds)).size.z)); if (num <= 0.0001f) { return null; } float num2 = 0.17f / num; Quaternion val3 = Quaternion.Euler(-24f, 17f, 9f); GameObject val4 = new GameObject(((Object)clone).name + "_display"); val4.transform.SetParent(_holder.transform, false); clone.transform.SetParent(val4.transform, false); clone.transform.localRotation = val3; clone.transform.localScale = new Vector3(num2, num2, num2); clone.transform.localPosition = -(val3 * (((Bounds)(ref bounds)).center * num2)); return val4; } private static void Grow(ref Bounds bounds, ref bool found, Matrix4x4 local, Bounds mesh) { //IL_0004: Unknown result type (might be due to invalid IL or missing references) //IL_0009: Unknown result type (might be due to invalid IL or missing references) //IL_000e: Unknown result type (might be due to invalid IL or missing references) //IL_0013: Unknown result type (might be due to invalid IL or missing references) //IL_0018: Unknown result type (might be due to invalid IL or missing references) //IL_001d: Unknown result type (might be due to invalid IL or missing references) //IL_0037: Unknown result type (might be due to invalid IL or missing references) //IL_003e: 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_0024: Unknown result type (might be due to invalid IL or missing references) //IL_0029: Unknown result type (might be due to invalid IL or missing references) //IL_002e: Unknown result type (might be due to invalid IL or missing references) Vector3 val = ((Matrix4x4)(ref local)).MultiplyPoint3x4(((Bounds)(ref mesh)).min); Vector3 val2 = ((Matrix4x4)(ref local)).MultiplyPoint3x4(((Bounds)(ref mesh)).max); if (!found) { bounds = new Bounds(val, Vector3.zero); found = true; } ((Bounds)(ref bounds)).Encapsulate(val); ((Bounds)(ref bounds)).Encapsulate(val2); } } internal class Carrier : MonoBehaviour { private enum Phase { Flying, Fading } public const float Orbit = 0.34f; public static float Spin = 24f; public static float BobHeight = 0.045f; public static float BobPeriod = 3.1f; public static float DriftMin = 4f; public static float DriftMax = 13f; private const float Awake = 1.6f; private static readonly int EmissionColour = Shader.PropertyToID("_EmissionColor"); private Renderer[] _renderers; private MaterialPropertyBlock _block; public static float FadeTime = 0.45f; public Transform Body; public Transform Hoop; public Transform Sling; public Transform Hook; private readonly List _rings = new List(); private readonly List _motes = new List(); private readonly List _moteAngle = new List(); private readonly List _moteRate = new List(); private Light _light; private Phase _phase; private SpiritTrips.Flight _flight; private bool _hasFlight; private float _fade; private Vector3 _spin; private Vector3 _rest; private float _bobPhase; private float _pulsePhase; private float _scale = 1f; private GameObject _cargo; public static Color LightColour => ForestSpirit.LightColour; public static float LightRange => ForestSpirit.LightRange; public static float PulseDepth => ForestSpirit.PulseDepth; public static float PulsePeriod => ForestSpirit.PulsePeriod; private void Start() { //IL_001f: Unknown result type (might be due to invalid IL or missing references) //IL_0024: Unknown result type (might be due to invalid IL or missing references) //IL_0062: Unknown result type (might be due to invalid IL or missing references) //IL_008d: Unknown result type (might be due to invalid IL or missing references) //IL_0080: 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) Random random = new Random(((Object)this).GetInstanceID()); _spin = new Vector3(Signed(random), Signed(random), Signed(random)); _bobPhase = (float)random.NextDouble() * (float)Math.PI * 2f; _pulsePhase = (float)random.NextDouble() * (float)Math.PI * 2f; _scale = ((Component)this).transform.localScale.x; _rest = (((Object)(object)Body != (Object)null) ? Body.localPosition : Vector3.zero); CollectMotes(random); MakeLight(); } private static float Signed(Random random) { float num = 1f + (float)random.NextDouble(); if (random.Next(2) != 0) { return num; } return 0f - num; } private void CollectMotes(Random random) { //IL_0026: Unknown result type (might be due to invalid IL or missing references) //IL_002c: Expected O, but got Unknown //IL_005f: Unknown result type (might be due to invalid IL or missing references) //IL_0065: Expected O, but got Unknown //IL_008a: 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) if ((Object)(object)Hoop == (Object)null) { return; } foreach (Transform item in Hoop) { Transform val = item; if (!((Object)val).name.StartsWith("ring")) { continue; } _rings.Add(val); foreach (Transform item2 in val) { Transform val2 = item2; if (((Object)val2).name.StartsWith("mote")) { _motes.Add(val2); _moteAngle.Add(Mathf.Atan2(val2.localPosition.y, val2.localPosition.x) * 57.29578f); float num = DriftMin + (float)random.NextDouble() * (DriftMax - DriftMin); _moteRate.Add((random.Next(2) == 0) ? (0f - num) : num); } } } } private void MakeLight() { //IL_0005: Unknown result type (might be due to invalid IL or missing references) //IL_000b: Expected O, but got Unknown //IL_0061: 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_0093: Expected O, but got Unknown GameObject val = new GameObject("carrier_light"); val.transform.SetParent(((Object)(object)Body != (Object)null) ? Body : ((Component)this).transform, false); _light = val.AddComponent(); _light.type = (LightType)2; _light.range = LightRange; _light.color = LightColour; _light.intensity = 1.6f; _renderers = ((Component)this).GetComponentsInChildren(true); _block = new MaterialPropertyBlock(); _light.shadows = (LightShadows)0; } public void Follow(SpiritTrips.Flight flight) { if (_phase != Phase.Fading) { _flight = flight; _hasFlight = true; } } public void Carry(GameObject model) { //IL_004f: 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) Release(); if (!((Object)(object)model == (Object)null)) { _cargo = model; _cargo.transform.SetParent(((Object)(object)Hook != (Object)null) ? Hook : ((Component)this).transform, false); _cargo.transform.localPosition = Vector3.zero; _cargo.transform.localRotation = Quaternion.identity; } } public void Release() { if (!((Object)(object)_cargo == (Object)null)) { Object.Destroy((Object)(object)_cargo); _cargo = null; } } public void Dismiss() { if (_phase != Phase.Fading) { Release(); _fade = FadeTime; _phase = Phase.Fading; } } private void Update() { //IL_0035: Unknown result type (might be due to invalid IL or missing references) //IL_008d: Unknown result type (might be due to invalid IL or missing references) //IL_0098: 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) float deltaTime = Time.deltaTime; switch (_phase) { case Phase.Flying: if (_hasFlight) { ((Component)this).transform.position = _flight.At(SpiritTrips.Now); } break; case Phase.Fading: { _fade -= deltaTime; if (_fade <= 0f) { Object.Destroy((Object)(object)((Component)this).gameObject); return; } float num = Mathf.Clamp01(_fade / Mathf.Max(0.01f, FadeTime)); ((Component)this).transform.localScale = Vector3.one * _scale * num; if ((Object)(object)_light != (Object)null) { _light.intensity = 1.6f * num; } break; } } Animate(Time.time, deltaTime); } private void Animate(float time, float delta) { //IL_0015: Unknown result type (might be due to invalid IL or missing references) //IL_001f: 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_00ae: Unknown result type (might be due to invalid IL or missing references) //IL_00c4: 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) if ((Object)(object)Hoop != (Object)null) { Hoop.Rotate(_spin * Spin * delta, (Space)1); } float num = Spin * delta; for (int i = 0; i < _rings.Count; i++) { if (!((Object)(object)_rings[i] == (Object)null)) { _rings[i].Rotate(0f, 0f, num, (Space)1); } } if ((Object)(object)Body != (Object)null) { float num2 = Mathf.Sin(time * ((float)Math.PI * 2f / BobPeriod) + _bobPhase); Body.localPosition = _rest + new Vector3(0f, num2 * BobHeight, 0f); } Drift(delta); Sway(time); Pulse(time); } private void Drift(float delta) { //IL_007d: Unknown result type (might be due to invalid IL or missing references) for (int i = 0; i < _motes.Count; i++) { if (!((Object)(object)_motes[i] == (Object)null)) { _moteAngle[i] += _moteRate[i] * delta; float num = _moteAngle[i] * ((float)Math.PI / 180f); _motes[i].localPosition = new Vector3(Mathf.Cos(num) * 0.34f, Mathf.Sin(num) * 0.34f, 0f); } } } private void Sway(float time) { //IL_003e: Unknown result type (might be due to invalid IL or missing references) if (!((Object)(object)Sling == (Object)null)) { Sling.localRotation = Quaternion.Euler(Mathf.Sin(time * 1.7f) * 4.5f, 0f, Mathf.Cos(time * 1.3f) * 5.5f); } } private void Pulse(float time) { //IL_0063: Unknown result type (might be due to invalid IL or missing references) //IL_0069: Unknown result type (might be due to invalid IL or missing references) //IL_006e: Unknown result type (might be due to invalid IL or missing references) //IL_00c4: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)_light == (Object)null || _phase == Phase.Fading) { return; } float num = Mathf.Sin(time * ((float)Math.PI * 2f / PulsePeriod) + _pulsePhase); float num2 = 1f + num * PulseDepth; _light.intensity = 1.6f * num2; if (_renderers == null || _block == null) { return; } Color val = LightColour * num2; Renderer[] renderers = _renderers; foreach (Renderer val2 in renderers) { if (!((Object)(object)val2 == (Object)null)) { Material sharedMaterial = val2.sharedMaterial; if (!((Object)(object)sharedMaterial == (Object)null) && sharedMaterial.HasProperty(EmissionColour)) { val2.GetPropertyBlock(_block); _block.SetColor(EmissionColour, val); val2.SetPropertyBlock(_block); } } } } } internal static class CarrierModel { private const string HeartMesh = "grove_spirit_heart.obj"; private const string HoopMesh = "grove_spirit_hoop.obj"; private const string MoteMesh = "grove_spirit_mote.obj"; private const int Rings = 2; private const int Motes = 6; private static readonly bool ShowHoop; private const float SlingDrop = 0.155f; private const float TetherHigh = 0.035f; private const float TetherLow = 0.09f; private static ModelData _heart; private static ModelData _hoop; private static ModelData _mote; private static bool _missing; public static void Invalidate() { _heart = null; _hoop = null; _mote = null; _missing = false; } public static Carrier Build(Vector3 at) { //IL_0023: Unknown result type (might be due to invalid IL or missing references) //IL_0029: Expected O, but got Unknown //IL_002f: Unknown result type (might be due to invalid IL or missing references) //IL_003e: Unknown result type (might be due to invalid IL or missing references) //IL_004d: Unknown result type (might be due to invalid IL or missing references) //IL_0053: Expected O, but got Unknown //IL_0080: Unknown result type (might be due to invalid IL or missing references) //IL_0086: Expected O, but got Unknown //IL_00a8: Unknown result type (might be due to invalid IL or missing references) //IL_00af: Expected O, but got Unknown //IL_00d8: Unknown result type (might be due to invalid IL or missing references) //IL_011f: Unknown result type (might be due to invalid IL or missing references) //IL_0126: Expected O, but got Unknown //IL_0150: Unknown result type (might be due to invalid IL or missing references) if (!LoadMeshes()) { return null; } float num = Mathf.Max(0.05f, StowConfig.CarrierScale.Value); GameObject val = new GameObject("stow_carrier"); val.transform.position = at; val.transform.localScale = new Vector3(num, num, num); GameObject val2 = new GameObject("body"); val2.transform.SetParent(val.transform, false); Part(val2.transform, "heart", _heart); GameObject val3 = new GameObject("rings"); val3.transform.SetParent(val2.transform, false); BuildRings(val3.transform); GameObject val4 = new GameObject("sling"); val4.transform.SetParent(val2.transform, false); val4.transform.localPosition = new Vector3(0f, -0.34f, 0f); Bead(val4.transform, "tether_high", 0.035f, 1.2f); Bead(val4.transform, "tether_low", 0.09f, 0.92f); GameObject val5 = new GameObject("hook"); val5.transform.SetParent(val4.transform, false); val5.transform.localPosition = new Vector3(0f, -0.155f, 0f); Flare.Attach(val2.transform, 0.884f); Carrier carrier = val.AddComponent(); carrier.Body = val2.transform; carrier.Hoop = val3.transform; carrier.Sling = val4.transform; carrier.Hook = val5.transform; return carrier; } private static void BuildRings(Transform parent) { //IL_0018: Unknown result type (might be due to invalid IL or missing references) //IL_001e: Expected O, but got Unknown //IL_0049: Unknown result type (might be due to invalid IL or missing references) //IL_00db: Unknown result type (might be due to invalid IL or missing references) for (int i = 0; i < 2; i++) { GameObject val = new GameObject("ring" + i); val.transform.SetParent(parent, false); val.transform.localRotation = Quaternion.Euler(90f + 90f * (float)i, 0f, 0f); if (ShowHoop) { Part(val.transform, "hoop", _hoop); } for (int j = 0; j < 6; j++) { float num = (60f * (float)j + 12f * (float)i) * ((float)Math.PI / 180f); Part(val.transform, "mote" + i + "_" + j, _mote).transform.localPosition = new Vector3(Mathf.Cos(num) * 0.34f, Mathf.Sin(num) * 0.34f, 0f); } } } private static GameObject Bead(Transform parent, string name, float drop, float size) { //IL_001e: Unknown result type (might be due to invalid IL or missing references) //IL_0031: Unknown result type (might be due to invalid IL or missing references) GameObject obj = Part(parent, name, _mote); obj.transform.localPosition = new Vector3(0f, 0f - drop, 0f); obj.transform.localScale = new Vector3(size, size, size); return obj; } private static GameObject Part(Transform parent, string name, ModelData model) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_0013: Unknown result type (might be due to invalid IL or missing references) //IL_0024: Unknown result type (might be due to invalid IL or missing references) //IL_0049: Expected O, but got Unknown GameObject val = new GameObject(name); val.transform.SetParent(parent, false); val.AddComponent().sharedMesh = model.Mesh; MeshRenderer obj = val.AddComponent(); ((Renderer)obj).sharedMaterials = Skins.Skin(model.Groups); ((Renderer)obj).shadowCastingMode = (ShadowCastingMode)0; ((Renderer)obj).receiveShadows = false; return val; } private static bool LoadMeshes() { if (_heart != null && _hoop != null && _mote != null) { return true; } if (_missing) { return false; } string? directoryName = Path.GetDirectoryName(typeof(CarrierModel).Assembly.Location); _heart = ObjMesh.Load(Path.Combine(directoryName, "grove_spirit_heart.obj")); _hoop = ObjMesh.Load(Path.Combine(directoryName, "grove_spirit_hoop.obj")); _mote = ObjMesh.Load(Path.Combine(directoryName, "grove_spirit_mote.obj")); if (_heart != null && _hoop != null && _mote != null) { Dress(_heart); Dress(_hoop); Dress(_mote); return true; } _missing = true; StowRuntime.Log.LogError((object)"Carrier meshes are missing from beside the dll - the post will move things instantly instead. Expected grove_spirit_heart.obj, grove_spirit_hoop.obj and grove_spirit_mote.obj."); return false; } private static void Dress(ModelData model) { Skins.Skin(model.Groups); Skins.Remap(model.Mesh, model.Groups); } } internal class CarryRun { private enum Errand { Stow, Fetch, Tidy, Resting } private sealed class Courier { public Errand Errand; public ItemData Item; public Container Target; public Container Source; public bool Outbound; public SpiritTrips.Flight Flight; public double ReadyAt; public bool Idle(double now) { return now >= ReadyAt; } } private const float ScanInterval = 3f; private const float PostHover = 0.45f; private const float ChestHover = 0.35f; private readonly StowPost _post; private readonly List _couriers = new List(); private readonly List _reserved = new List(); private readonly List _touched = new List(); private Transform _heartwood; private float _nextScan; private int _moved; public bool Working => _couriers.Count > 0; public CarryRun(StowPost post) { _post = post; } public void Wake() { _nextScan = 0f; } public void Abandon() { if (_couriers.Count != 0 || _reserved.Count != 0 || _moved != 0) { _couriers.Clear(); _reserved.Clear(); _touched.Clear(); _moved = 0; Publish(); } } public void Tick() { Container val = (((Object)(object)_post != (Object)null) ? _post.Container : null); Inventory val2 = (((Object)(object)val != (Object)null) ? val.GetInventory() : null); if (val2 == null) { Abandon(); return; } ZNetView component = ((Component)_post).GetComponent(); if ((Object)(object)component == (Object)null || !component.IsValid() || !component.IsOwner()) { Abandon(); return; } double now = SpiritTrips.Now; for (int num = _couriers.Count - 1; num >= 0; num--) { Courier courier = _couriers[num]; if (courier.Idle(now)) { if (courier.Outbound) { Land(courier, val2, component); } else { Arrive(courier, component); if (!Dispatch(courier, val2, now)) { Retire(courier, num); } } } } Recruit(val2, now); Publish(); foreach (Courier courier2 in _couriers) { if (courier2.Errand != Errand.Resting) { return; } } _reserved.Clear(); if (_moved > 0) { Announce(); } } private void Land(Courier courier, Inventory inventory, ZNetView nview) { //IL_0022: Unknown result type (might be due to invalid IL or missing references) //IL_0027: Unknown result type (might be due to invalid IL or missing references) //IL_00c3: Unknown result type (might be due to invalid IL or missing references) //IL_00c6: Unknown result type (might be due to invalid IL or missing references) ItemData item = courier.Item; Errand errand = courier.Errand; Container source = courier.Source; Container target = courier.Target; Vector3 to = courier.Flight.To; courier.Outbound = false; bool flag = false; bool flag2 = false; string cargo = null; nview.ClaimOwnership(); switch (errand) { case Errand.Stow: flag = !Move(inventory, target, item, ref cargo, celebrate: true); break; case Errand.Fetch: flag2 = Ready(source, item); if (flag2) { cargo = ItemGroups.PrefabNameOf(item); } break; case Errand.Tidy: flag = !Move(Held(source), target, item, ref cargo, celebrate: true); break; } if (!flag2) { courier.Item = null; courier.Source = null; if (!flag && item != null) { _reserved.Remove(item); } } courier.Target = null; Launch(courier, to, Home(), cargo, SpiritTrips.Now); } private bool Ready(Container source, ItemData item) { //IL_0056: Unknown result type (might be due to invalid IL or missing references) Inventory val = Held(source); Inventory val2 = (((Object)(object)_post.Container != (Object)null) ? _post.Container.GetInventory() : null); if (val != null && val2 != null && item != null && val.ContainsItem(item) && val2.CanAddItem(item, -1)) { return Depositor.Usable(source, ((Component)_post).transform.position, StowConfig.Range.Value); } return false; } private void Arrive(Courier courier, ZNetView nview) { if (courier.Errand == Errand.Fetch && courier.Item != null) { ItemData item = courier.Item; Container source = courier.Source; courier.Item = null; courier.Source = null; nview.ClaimOwnership(); string cargo = null; Move(Held(source), _post.Container, item, ref cargo, celebrate: true); _reserved.Remove(item); } } private static Inventory Held(Container container) { if (!((Object)(object)container == (Object)null)) { return container.GetInventory(); } return null; } private bool Move(Inventory from, Container into, ItemData item, ref string cargo, bool celebrate) { //IL_0028: 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) if (from == null || (Object)(object)into == (Object)null || item == null) { return true; } if (!from.ContainsItem(item)) { return true; } if (!Depositor.Usable(into, ((Component)_post).transform.position, StowConfig.Range.Value)) { return true; } cargo = ItemGroups.PrefabNameOf(item); bool emptied; int num = Depositor.Deposit(from, into, item, out emptied); if (num <= 0) { StowRuntime.Log.LogWarning((object)("A container offered room for " + item.m_shared.m_name + " and then accepted none - not trying it again this run.")); return false; } _moved += num; if (!_touched.Contains(into)) { _touched.Add(into); } if (celebrate && (Object)(object)InventoryGui.instance != (Object)null && InventoryGui.instance.m_moveItemEffects != null) { InventoryGui.instance.m_moveItemEffects.Create(((Component)into).transform.position, Quaternion.identity, (Transform)null, 1f, -1); } return true; } private bool Dispatch(Courier courier, Inventory inventory, double now) { //IL_0017: Unknown result type (might be due to invalid IL or missing references) //IL_001c: Unknown result type (might be due to invalid IL or missing references) //IL_0027: Unknown result type (might be due to invalid IL or missing references) //IL_0062: Unknown result type (might be due to invalid IL or missing references) //IL_0040: 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_007d: 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_0107: Unknown result type (might be due to invalid IL or missing references) //IL_010d: Unknown result type (might be due to invalid IL or missing references) Container container = _post.Container; Vector3 position = ((Component)_post).transform.position; if (Available(inventory) && Depositor.NextTrip(inventory, position, _reserved, out var item, out var target)) { Begin(courier, Errand.Stow, item, null, target, AimAt(target), ItemGroups.PrefabNameOf(item), now, "carrying"); return true; } if (Available(inventory) && Depositor.NextFetch(container, position, _reserved, out item, out var source)) { Begin(courier, Errand.Fetch, item, source, null, AimAt(source), null, now, "fetching"); return true; } if (PostRules.Tidy(container) && Depositor.NextTidy(position, _reserved, out item, out source, out target)) { Begin(courier, Errand.Tidy, item, source, target, AimAt(source), null, now, "tidying"); return true; } if (PostRules.Where(container) != PostRules.Presence.LivesHere) { return false; } if (courier.Errand != Errand.Resting) { courier.Errand = Errand.Resting; courier.Item = null; courier.Source = null; courier.Target = null; courier.Outbound = false; Launch(courier, courier.Flight.To, Home(), null, now); } courier.ReadyAt = now + 3.0; return true; } private void Begin(Courier courier, Errand errand, ItemData item, Container source, Container target, Vector3 aim, string cargo, double now, string verb) { //IL_0051: Unknown result type (might be due to invalid IL or missing references) //IL_0044: Unknown result type (might be due to invalid IL or missing references) //IL_0056: Unknown result type (might be due to invalid IL or missing references) //IL_0059: Unknown result type (might be due to invalid IL or missing references) //IL_005a: Unknown result type (might be due to invalid IL or missing references) courier.Errand = errand; courier.Item = item; courier.Source = source; courier.Target = target; courier.Outbound = true; _reserved.Add(item); Vector3 val = ((courier.Flight.Duration > 0f) ? courier.Flight.To : Home()); Launch(courier, val, aim, cargo, now); if (StowConfig.Verbose.Value) { StowRuntime.Log.LogInfo((object)(verb + " " + item.m_stack + "x " + item.m_shared.m_name)); } } private void Recruit(Inventory inventory, double now) { int num = Mathf.Clamp(StowConfig.Couriers.Value, 1, 8); if (_couriers.Count >= num) { return; } Container container = _post.Container; if ((inventory.NrOfItems() != 0 || PostRules.Fetch(container).Count != 0 || PostRules.Tidy(container) || PostRules.Where(container) == PostRules.Presence.LivesHere) && !(Time.time < _nextScan)) { _nextScan = Time.time + 3f; Courier courier = new Courier { ReadyAt = now }; _couriers.Add(courier); if (!Dispatch(courier, inventory, now)) { _couriers.Remove(courier); } } } private void Retire(Courier courier, int index) { if (courier.Item != null) { _reserved.Remove(courier.Item); } _couriers.RemoveAt(index); } private bool Available(Inventory inventory) { if (inventory.NrOfItems() == 0) { return false; } Container container = _post.Container; if (!((Object)(object)container == (Object)null)) { return !container.IsInUse(); } return true; } public void Instant(Inventory inventory) { //IL_000c: Unknown result type (might be due to invalid IL or missing references) int chestCount; int moved = Depositor.Distribute(inventory, ((Component)_post).transform.position, out chestCount); _moved = moved; _touched.Clear(); Announce(chestCount); } private void Announce() { Announce(_touched.Count); } private void Announce(int chests) { int moved = _moved; _moved = 0; _touched.Clear(); if (StowConfig.Messages.Value && !((Object)(object)Player.m_localPlayer == (Object)null)) { Container container = _post.Container; Inventory val = (((Object)(object)container != (Object)null) ? container.GetInventory() : null); int num = ((val != null) ? val.NrOfItems() : 0); string text = ((moved != 0) ? ("Stowed " + moved + " item" + ((moved == 1) ? "" : "s") + " into " + chests + " chest" + ((chests == 1) ? "" : "s") + ".") : ((num > 0) ? "Nothing here has a home yet." : "")); if (num > 0 && moved > 0) { text = text + " " + num + " left waiting."; } if (text.Length != 0) { ((Character)Player.m_localPlayer).Message((MessageType)2, Localization.instance.Localize(text), 0, (Sprite)null); } } } private void Launch(Courier courier, Vector3 from, Vector3 to, string cargo, double now) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_0029: Unknown result type (might be due to invalid IL or missing references) //IL_002f: Unknown result type (might be due to invalid IL or missing references) //IL_003d: Unknown result type (might be due to invalid IL or missing references) //IL_0043: Unknown result type (might be due to invalid IL or missing references) //IL_006a: Unknown result type (might be due to invalid IL or missing references) //IL_006b: Unknown result type (might be due to invalid IL or missing references) //IL_0071: Unknown result type (might be due to invalid IL or missing references) //IL_0072: Unknown result type (might be due to invalid IL or missing references) //IL_0094: Unknown result type (might be due to invalid IL or missing references) //IL_0095: Unknown result type (might be due to invalid IL or missing references) //IL_009c: 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_00a4: 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) float num = Mathf.Max(from.y, to.y) + Mathf.Max(0f, StowConfig.CarrierCruise.Value); Vector3 val = default(Vector3); ((Vector3)(ref val))..ctor((from.x + to.x) * 0.5f, num, (from.z + to.z) * 0.5f); float num2 = Mathf.Max(0.4f, StowConfig.CarrierSpeed.Value); float num3 = Vector3.Distance(from, val) + Vector3.Distance(val, to); float num4 = Mathf.Max(0.35f, num3 / num2); courier.Flight = new SpiritTrips.Flight { From = from, Control = val, To = to, Cargo = cargo, Start = now, Duration = num4 }; courier.ReadyAt = now + (double)num4 + (double)Mathf.Max(0f, StowConfig.CarrierPause.Value); } private void Publish() { ZNetView val = (((Object)(object)_post != (Object)null) ? ((Component)_post).GetComponent() : null); if ((Object)(object)val == (Object)null || !val.IsValid() || !val.IsOwner()) { return; } List list = new List(); foreach (Courier courier in _couriers) { list.Add(courier.Flight); } SpiritTrips.Publish(val, SpiritTrips.Encode(list)); } private Vector3 Home() { //IL_0058: 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) if ((Object)(object)_heartwood == (Object)null) { _heartwood = ((Component)_post).transform.Find("post_visual/heartwood"); } if (!((Object)(object)_heartwood != (Object)null)) { return Above(((Component)_post).transform, 0.45f, 1f); } return _heartwood.position; } private static Vector3 AimAt(Container container) { //IL_0010: Unknown result type (might be due to invalid IL or missing references) return Above(((Component)container).transform, 0.35f, 0.5f); } private static Vector3 Above(Transform thing, float clearance, float fallback) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_0022: Unknown result type (might be due to invalid IL or missing references) //IL_0027: Unknown result type (might be due to invalid IL or missing references) //IL_002a: Unknown result type (might be due to invalid IL or missing references) //IL_0017: Unknown result type (might be due to invalid IL or missing references) //IL_0035: Unknown result type (might be due to invalid IL or missing references) //IL_003e: Unknown result type (might be due to invalid IL or missing references) //IL_0044: Unknown result type (might be due to invalid IL or missing references) Vector3 position = thing.position; Collider componentInChildren = ((Component)thing).GetComponentInChildren(); float num; if (!((Object)(object)componentInChildren != (Object)null)) { num = position.y + fallback; } else { Bounds bounds = componentInChildren.bounds; num = ((Bounds)(ref bounds)).max.y; } float num2 = num; return new Vector3(position.x, num2 + clearance, position.z); } } internal static class ChestFilter { public sealed class Rule { public Container Container; public float Distance; public bool Configured; public bool CatchesAll; public readonly HashSet Items = new HashSet(); public readonly List Groups = new List(); public readonly HashSet NotItems = new HashSet(); public readonly List NotGroups = new List(); public int Match(ItemData item) { if (item == null || item.m_shared == null) { return -1; } string name = item.m_shared.m_name; if (Excludes(name)) { return -1; } if (Configured) { if (Items.Contains(name)) { return 3; } foreach (ItemGroup group in Groups) { if (group.Members.Contains(name)) { return 2; } } if (!CatchesAll) { return -1; } return 1; } if (!StowConfig.MatchContents.Value) { return -1; } Inventory inventory = Container.GetInventory(); if (inventory == null || !inventory.ContainsItemByName(name)) { return -1; } return 0; } public bool Refuses(ItemData item) { if (item != null && item.m_shared != null) { return Excludes(item.m_shared.m_name); } return false; } private bool Excludes(string shared) { if (NotItems.Contains(shared)) { return true; } foreach (ItemGroup notGroup in NotGroups) { if (notGroup.Members.Contains(shared)) { return true; } } return false; } } private const string ZFilter = "stowFilter"; public const string CatchAll = "*"; public const int TierNone = -1; public const int TierContents = 0; public const int TierCatchAll = 1; public const int TierGroup = 2; public const int TierItem = 3; public static string Read(Container container) { ZDO val = Zdo(container); if (val != null) { return val.GetString("stowFilter", ""); } return ""; } public static void Write(Container container, IEnumerable entries) { ZNetView val = (((Object)(object)container == (Object)null) ? null : ((Component)container).GetComponent()); if (!((Object)(object)val == (Object)null) && val.IsValid()) { val.ClaimOwnership(); val.GetZDO().Set("stowFilter", string.Join(",", Clean(entries).ToArray())); } } public static List Entries(Container container) { return Clean(Read(container).Split(new char[1] { ',' })); } private static List Clean(IEnumerable entries) { List list = new List(); if (entries == null) { return list; } foreach (string entry in entries) { if (entry != null) { string text = entry.Trim(); if (text.Length != 0 && !list.Contains(text)) { list.Add(text); } } } return list; } public static bool IsGroup(string entry) { if (entry != null && entry.Length > 1) { return entry[0] == '@'; } return false; } public static string GroupId(string entry) { if (!IsGroup(entry)) { return null; } return entry.Substring(1); } public static bool IsExclusion(string entry) { if (entry != null && entry.Length > 1) { return entry[0] == '-'; } return false; } public static string Bare(string entry) { if (!IsExclusion(entry)) { return entry; } return entry.Substring(1); } public static Rule RuleFor(Container container, float distance) { Rule rule = new Rule { Container = container, Distance = distance }; foreach (string item in Entries(container)) { bool flag = IsExclusion(item); string text = Bare(item); if (text == "*") { if (!flag) { rule.CatchesAll = true; rule.Configured = true; } continue; } if (IsGroup(text)) { ItemGroup itemGroup = ItemGroups.Find(GroupId(text)); if (itemGroup != null) { if (flag) { rule.NotGroups.Add(itemGroup); continue; } rule.Groups.Add(itemGroup); rule.Configured = true; } continue; } string text2 = ItemGroups.SharedNameOf(text); if (text2 != null) { if (flag) { rule.NotItems.Add(text2); continue; } rule.Items.Add(text2); rule.Configured = true; } } return rule; } public static bool Matches(List entries, ItemData item) { if (entries == null || item == null || item.m_shared == null) { return false; } string name = item.m_shared.m_name; bool result = false; foreach (string entry in entries) { bool flag = IsExclusion(entry); string text = Bare(entry); if (text == "*" || ((!IsGroup(text)) ? (ItemGroups.SharedNameOf(text) == name) : (ItemGroups.Find(GroupId(text))?.Members.Contains(name) ?? false))) { if (flag) { return false; } result = true; } } return result; } public static string Summary(Container container) { List list = Entries(container); if (list.Count == 0) { return null; } List list2 = new List(); List list3 = new List(); foreach (string item2 in list) { bool flag = IsExclusion(item2); string text = Bare(item2); string item; if (text == "*") { item = "anything else"; } else if (IsGroup(text)) { ItemGroup itemGroup = ItemGroups.Find(GroupId(text)); item = ((itemGroup != null) ? itemGroup.Display.ToLowerInvariant() : GroupId(text)); } else { item = ItemGroups.DisplayNameOf(text); } (flag ? list3 : list2).Add(item); } string text2 = string.Join(", ", list2.ToArray()); if (list3.Count == 0) { return text2; } string text3 = "not " + string.Join(" or ", list3.ToArray()); if (text2.Length != 0) { return text2 + " - " + text3; } return text3; } private static ZDO Zdo(Container container) { if ((Object)(object)container == (Object)null) { return null; } ZNetView component = ((Component)container).GetComponent(); if (!((Object)(object)component != (Object)null) || !component.IsValid()) { return null; } return component.GetZDO(); } } internal static class Depositor { private sealed class Plan { public ItemData Item; public int Tier; } private static readonly Collider[] Hits = (Collider[])(object)new Collider[256]; private static HashSet _neverStow; private static string _neverStowRaw; public static int Distribute(Inventory source, Vector3 origin, out int chestCount, Predicate allow = null) { //IL_0015: Unknown result type (might be due to invalid IL or missing references) //IL_014b: Unknown result type (might be due to invalid IL or missing references) //IL_0150: Unknown result type (might be due to invalid IL or missing references) chestCount = 0; if (source == null || !ItemGroups.Ready) { return 0; } List list = new List(); CollectChests(origin, list); if (list.Count == 0) { return 0; } List list2 = new List(); foreach (ItemData item in new List(source.GetAllItems())) { if (allow == null || allow(item)) { int num = BestTier(list, item); if (num != -1) { list2.Add(new Plan { Item = item, Tier = num }); } } } if (list2.Count == 0) { return 0; } list2.Sort((Plan a, Plan b) => b.Tier.CompareTo(a.Tier)); int num2 = 0; List list3 = new List(); foreach (Plan item2 in list2) { num2 += Place(source, list, item2.Item, list3); } foreach (Container item3 in list3) { if ((Object)(object)InventoryGui.instance != (Object)null && InventoryGui.instance.m_moveItemEffects != null) { InventoryGui.instance.m_moveItemEffects.Create(((Component)item3).transform.position, Quaternion.identity, (Transform)null, 1f, -1); } } chestCount = list3.Count; return num2; } public static void Run(Player player) { //IL_0044: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)player == (Object)null) { return; } if (!ItemGroups.Ready) { Announce("Item catalogue not loaded yet."); return; } int chestCount; int num = Distribute(((Humanoid)player).GetInventory(), ((Component)player).transform.position, out chestCount, (ItemData item) => Stowable(player, item)); if (num == 0) { Announce("Nothing here belongs in those chests."); return; } Announce("Stowed " + num + " item" + ((num == 1) ? "" : "s") + " into " + chestCount + " chest" + ((chestCount == 1) ? "" : "s") + "."); } private static int Place(Inventory source, List rules, ItemData item, List touched) { int num = 0; while (item.m_stack > 0) { Container val = BestChestWithRoom(rules, item); if ((Object)(object)val == (Object)null) { break; } bool emptied; int num2 = Deposit(source, val, item, out emptied); if (num2 < 0) { break; } num += num2; if (num2 > 0 && !touched.Contains(val)) { touched.Add(val); } if (emptied || num2 == 0) { break; } } return num; } public static int Deposit(Inventory source, Container target, ItemData item, out bool emptied) { emptied = false; if (source == null || (Object)(object)target == (Object)null || item == null) { return -1; } ZNetView component = ((Component)target).GetComponent(); if ((Object)(object)component == (Object)null || !component.IsValid()) { return -1; } Inventory inventory = target.GetInventory(); if (inventory == null) { return -1; } component.ClaimOwnership(); int value = StowConfig.ItemsPerTrip.Value; int num = ((value > 0) ? Mathf.Min(value, item.m_stack) : item.m_stack); ItemData val = item.Clone(); val.m_stack = num; int num2 = (inventory.AddItem(val) ? num : (num - val.m_stack)); item.m_stack -= num2; if (item.m_stack <= 0) { source.RemoveItem(item); emptied = true; } if (num2 > 0 && StowConfig.Verbose.Value) { StowRuntime.Log.LogInfo((object)("stowed " + num2 + "x " + item.m_shared.m_name + " into " + target.m_name)); } return num2; } public static bool NextFetch(Container post, Vector3 origin, List reserved, out ItemData item, out Container source) { //IL_003c: Unknown result type (might be due to invalid IL or missing references) item = null; source = null; if ((Object)(object)post == (Object)null || !ItemGroups.Ready) { return false; } List list = PostRules.Fetch(post); if (list.Count == 0) { return false; } Inventory inventory = post.GetInventory(); if (inventory == null) { return false; } List list2 = new List(); CollectChests(origin, list2); foreach (ChestFilter.Rule item2 in list2) { Inventory inventory2 = item2.Container.GetInventory(); if (inventory2 == null) { continue; } foreach (ItemData allItem in inventory2.GetAllItems()) { if ((reserved == null || !reserved.Contains(allItem)) && ChestFilter.Matches(list, allItem) && inventory.CanAddItem(allItem, -1)) { item = allItem; source = item2.Container; return true; } } } return false; } public static bool NextTidy(Vector3 origin, List reserved, out ItemData item, out Container source, out Container target) { //IL_0019: Unknown result type (might be due to invalid IL or missing references) item = null; source = null; target = null; if (!ItemGroups.Ready) { return false; } List list = new List(); CollectChests(origin, list); if (list.Count < 2) { return false; } foreach (ChestFilter.Rule item2 in list) { Inventory inventory = item2.Container.GetInventory(); if (inventory == null) { continue; } foreach (ItemData allItem in inventory.GetAllItems()) { if ((reserved == null || !reserved.Contains(allItem)) && item2.Match(allItem) == -1 && item2.Refuses(allItem)) { Container val = BestChestWithRoom(list, allItem); if (!((Object)(object)val == (Object)null) && !((Object)(object)val == (Object)(object)item2.Container)) { item = allItem; source = item2.Container; target = val; return true; } } } } return false; } public static bool NextTrip(Inventory source, Vector3 origin, List reserved, out ItemData item, out Container target) { //IL_0019: Unknown result type (might be due to invalid IL or missing references) item = null; target = null; if (source == null || !ItemGroups.Ready) { return false; } List list = new List(); CollectChests(origin, list); if (list.Count == 0) { return false; } List list2 = new List(); foreach (ItemData allItem in source.GetAllItems()) { if (reserved == null || !reserved.Contains(allItem)) { int num = BestTier(list, allItem); if (num != -1) { list2.Add(new Plan { Item = allItem, Tier = num }); } } } if (list2.Count == 0) { return false; } list2.Sort((Plan a, Plan b) => b.Tier.CompareTo(a.Tier)); foreach (Plan item2 in list2) { Container val = BestChestWithRoom(list, item2.Item); if (!((Object)(object)val == (Object)null)) { item = item2.Item; target = val; return true; } } return false; } private static int BestTier(List rules, ItemData item) { int num = -1; foreach (ChestFilter.Rule rule in rules) { int num2 = rule.Match(item); if (num2 > num) { num = num2; } } return num; } public static Container BestChestWithRoom(List rules, ItemData item) { ChestFilter.Rule rule = null; int num = -1; foreach (ChestFilter.Rule rule2 in rules) { int num2 = rule2.Match(item); if (num2 != -1 && num2 >= num && (num2 != num || rule == null || !(rule2.Distance >= rule.Distance))) { Inventory inventory = rule2.Container.GetInventory(); if (inventory != null && inventory.CanAddItem(item, 1)) { rule = rule2; num = num2; } } } return rule?.Container; } public static void CollectChests(Vector3 point, List into) { //IL_0011: Unknown result type (might be due to invalid IL or missing references) //IL_0054: Unknown result type (might be due to invalid IL or missing references) //IL_0067: Unknown result type (might be due to invalid IL or missing references) //IL_006c: Unknown result type (might be due to invalid IL or missing references) into.Clear(); float value = StowConfig.Range.Value; int num = Physics.OverlapSphereNonAlloc(point, value, Hits); List list = new List(); for (int i = 0; i < num; i++) { Container componentInParent = ((Component)Hits[i]).GetComponentInParent(); if (!((Object)(object)componentInParent == (Object)null) && !list.Contains(componentInParent)) { list.Add(componentInParent); if (Usable(componentInParent, point, value)) { into.Add(ChestFilter.RuleFor(componentInParent, Vector3.Distance(((Component)componentInParent).transform.position, point))); } } } } public static bool Usable(Container container, Vector3 point, float range) { //IL_002a: Unknown result type (might be due to invalid IL or missing references) //IL_002f: Unknown result type (might be due to invalid IL or missing references) //IL_005b: Unknown result type (might be due to invalid IL or missing references) //IL_0061: Invalid comparison between Unknown and I4 //IL_007d: Unknown result type (might be due to invalid IL or missing references) ZNetView component = ((Component)container).GetComponent(); if ((Object)(object)component == (Object)null || !component.IsValid()) { return false; } if (StowPost.Is(container)) { return false; } if (Vector3.Distance(((Component)container).transform.position, point) > range) { return false; } if ((Object)(object)((Component)container).GetComponentInParent() != (Object)null) { return false; } if ((Object)(object)((Component)container).GetComponentInParent() != (Object)null) { return false; } if ((int)container.m_privacy != 2) { return false; } if (container.IsInUse()) { return false; } if (container.m_checkGuardStone && !PrivateArea.CheckAccess(((Component)container).transform.position, 0f, true, false)) { return false; } return true; } private static bool Stowable(Player player, ItemData item) { if (item == null || item.m_shared == null) { return false; } if (item.m_equipped || ((Humanoid)player).IsItemEquiped(item)) { return false; } if (StowConfig.KeepHotbar.Value && item.m_gridPos.y == 0) { return false; } string text = ItemGroups.PrefabNameOf(item); if (text != null && NeverStow().Contains(text)) { return false; } return true; } private static HashSet NeverStow() { string text = StowConfig.NeverStow.Value ?? ""; if (_neverStow != null && text == _neverStowRaw) { return _neverStow; } _neverStowRaw = text; _neverStow = new HashSet(StringComparer.OrdinalIgnoreCase); string[] array = text.Split(new char[1] { ',' }); for (int i = 0; i < array.Length; i++) { string text2 = array[i].Trim(); if (text2.Length > 0) { _neverStow.Add(text2); } } return _neverStow; } private static void Announce(string message) { if (StowConfig.Messages.Value && !((Object)(object)Player.m_localPlayer == (Object)null)) { ((Character)Player.m_localPlayer).Message((MessageType)2, Localization.instance.Localize(message), 0, (Sprite)null); } } } internal static class FilterPanel { public static class Styles { public static GUIStyle Window; public static GUIStyle Title; public static GUIStyle Dim; public static GUIStyle Caption; public static GUIStyle CellOn; public static GUIStyle CellOff; public static GUIStyle CellNot; public static GUIStyle Chip; public static GUIStyle Row; public static GUIStyle Field; public static GUIStyle List; public static Texture2D RuleLine; private static bool _built; public static void Build() { //IL_000e: Unknown result type (might be due to invalid IL or missing references) //IL_0027: Unknown result type (might be due to invalid IL or missing references) //IL_002c: Unknown result type (might be due to invalid IL or missing references) //IL_0035: Unknown result type (might be due to invalid IL or missing references) //IL_003f: Expected O, but got Unknown //IL_003f: Unknown result type (might be due to invalid IL or missing references) //IL_0044: Unknown result type (might be due to invalid IL or missing references) //IL_004e: Expected O, but got Unknown //IL_0053: Expected O, but got Unknown //IL_0058: Unknown result type (might be due to invalid IL or missing references) //IL_005d: Unknown result type (might be due to invalid IL or missing references) //IL_006e: Unknown result type (might be due to invalid IL or missing references) //IL_007f: Unknown result type (might be due to invalid IL or missing references) //IL_0090: Unknown result type (might be due to invalid IL or missing references) //IL_00a8: Unknown result type (might be due to invalid IL or missing references) //IL_00b2: Expected O, but got Unknown //IL_00b4: Unknown result type (might be due to invalid IL or missing references) //IL_00b9: Unknown result type (might be due to invalid IL or missing references) //IL_00ca: Unknown result type (might be due to invalid IL or missing references) //IL_00cf: Unknown result type (might be due to invalid IL or missing references) //IL_00e0: Unknown result type (might be due to invalid IL or missing references) //IL_00e5: Unknown result type (might be due to invalid IL or missing references) //IL_00f6: 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_0113: Unknown result type (might be due to invalid IL or missing references) //IL_011d: Expected O, but got Unknown //IL_011f: Unknown result type (might be due to invalid IL or missing references) //IL_0124: Unknown result type (might be due to invalid IL or missing references) //IL_0148: Unknown result type (might be due to invalid IL or missing references) //IL_014d: Unknown result type (might be due to invalid IL or missing references) //IL_0155: Unknown result type (might be due to invalid IL or missing references) //IL_015a: Unknown result type (might be due to invalid IL or missing references) //IL_0164: Expected O, but got Unknown //IL_0169: Expected O, but got Unknown //IL_018f: Unknown result type (might be due to invalid IL or missing references) //IL_01a3: Unknown result type (might be due to invalid IL or missing references) //IL_01b7: Unknown result type (might be due to invalid IL or missing references) //IL_01bc: Unknown result type (might be due to invalid IL or missing references) //IL_01c1: Unknown result type (might be due to invalid IL or missing references) //IL_01cb: Expected O, but got Unknown //IL_01d0: Expected O, but got Unknown //IL_01d5: Unknown result type (might be due to invalid IL or missing references) //IL_01da: Unknown result type (might be due to invalid IL or missing references) //IL_01f2: Unknown result type (might be due to invalid IL or missing references) //IL_01fc: Expected O, but got Unknown if (!_built) { _built = true; RuleLine = Theme.Solid(Theme.Rule); Window = new GUIStyle(GUI.skin.window) { padding = new RectOffset(14, 14, 12, 12), border = new RectOffset(1, 1, 1, 1) }; Paint(Window, Theme.Bordered(Theme.Bg, Theme.Rule)); Title = Label(14, Theme.Gold); Dim = Label(12, Theme.Dim); Caption = Label(12, Theme.Dim); Caption.margin = new RectOffset(0, 0, 2, 4); CellOff = Button(13, Theme.Ink, Theme.Row); CellOn = Button(13, Theme.Bg, Theme.Gold); CellNot = Button(13, Theme.Gold, Theme.Bg); Chip = Button(12, Theme.Gold, Theme.Panel); Chip.padding = new RectOffset(8, 8, 2, 2); Row = Button(13, Theme.Ink, Color.clear); Row.alignment = (TextAnchor)3; Field = new GUIStyle(GUI.skin.textField) { fontSize = 13, padding = new RectOffset(6, 6, 3, 3) }; if ((Object)(object)Theme.Mono != (Object)null) { Field.font = Theme.Mono; } Field.normal.textColor = Theme.Ink; Field.focused.textColor = Theme.Ink; List = new GUIStyle(GUI.skin.box) { padding = new RectOffset(2, 2, 2, 2) }; Paint(List, Theme.Bordered(Theme.Panel, Theme.Rule)); List.border = new RectOffset(1, 1, 1, 1); } } private static GUIStyle Label(int size, Color colour) { //IL_000a: Unknown result type (might be due to invalid IL or missing references) //IL_000f: Unknown result type (might be due to invalid IL or missing references) //IL_0016: Unknown result type (might be due to invalid IL or missing references) //IL_001b: Unknown result type (might be due to invalid IL or missing references) //IL_0025: Expected O, but got Unknown //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_0034: Expected O, but got Unknown //IL_0034: Unknown result type (might be due to invalid IL or missing references) //IL_003b: Unknown result type (might be due to invalid IL or missing references) //IL_0043: Expected O, but got Unknown //IL_0061: Unknown result type (might be due to invalid IL or missing references) GUIStyle val = new GUIStyle(GUI.skin.label) { fontSize = size, padding = new RectOffset(0, 0, 1, 1), margin = new RectOffset(0, 0, 0, 0), wordWrap = false, clipping = (TextClipping)1 }; if ((Object)(object)Theme.Mono != (Object)null) { val.font = Theme.Mono; } val.normal.textColor = colour; return val; } private static GUIStyle Button(int size, Color ink, Color fill) { //IL_000a: Unknown result type (might be due to invalid IL or missing references) //IL_000f: Unknown result type (might be due to invalid IL or missing references) //IL_0016: Unknown result type (might be due to invalid IL or missing references) //IL_001d: Unknown result type (might be due to invalid IL or missing references) //IL_0022: Unknown result type (might be due to invalid IL or missing references) //IL_002c: Expected O, but got Unknown //IL_002c: Unknown result type (might be due to invalid IL or missing references) //IL_0031: Unknown result type (might be due to invalid IL or missing references) //IL_003b: Expected O, but got Unknown //IL_003b: Unknown result type (might be due to invalid IL or missing references) //IL_0042: Unknown result type (might be due to invalid IL or missing references) //IL_004a: Expected O, but got Unknown //IL_0063: 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) //IL_0070: Unknown result type (might be due to invalid IL or missing references) //IL_0088: Unknown result type (might be due to invalid IL or missing references) //IL_0094: Unknown result type (might be due to invalid IL or missing references) //IL_00a0: Unknown result type (might be due to invalid IL or missing references) //IL_00ac: Unknown result type (might be due to invalid IL or missing references) GUIStyle val = new GUIStyle(GUI.skin.button) { fontSize = size, alignment = (TextAnchor)4, padding = new RectOffset(4, 4, 2, 2), margin = new RectOffset(0, 0, 0, 0), wordWrap = false, clipping = (TextClipping)1 }; if ((Object)(object)Theme.Mono != (Object)null) { val.font = Theme.Mono; } Paint(val, (fill == Color.clear) ? Theme.Clear() : Theme.Solid(fill)); val.normal.textColor = ink; val.hover.textColor = ink; val.active.textColor = ink; val.focused.textColor = ink; return val; } private static void Paint(GUIStyle style, Texture2D texture) { style.normal.background = texture; style.hover.background = texture; style.active.background = texture; style.focused.background = texture; style.onNormal.background = texture; style.onHover.background = texture; style.onActive.background = texture; style.onFocused.background = texture; } } [CompilerGenerated] private static class <>O { public static WindowFunction <0>__DrawWindow; public static Action <1>__CommitChest; } private const float WindowWidth = 520f; private const float CellWidth = 118f; private const float CellGap = 4f; private const int Columns = 4; private static Rect _window = new Rect(90f, 90f, 520f, 0f); private static Container _container; private static List _entries = new List(); private static List _edit; private static Action _save; private static string _search = ""; private static Vector2 _searchScroll; public static bool IsOpen { get; private set; } private static void Editing(List entries, Action commit) { _edit = entries; _save = commit; } public static void Open(Container container) { //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) if (!((Object)(object)container == (Object)null)) { _container = container; _entries = ChestFilter.Entries(container); _search = ""; _searchScroll = Vector2.zero; IsOpen = true; } } public static void Close() { IsOpen = false; _container = null; _search = ""; } public static void Draw() { //IL_0032: Unknown result type (might be due to invalid IL or missing references) //IL_006f: Unknown result type (might be due to invalid IL or missing references) //IL_0074: 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_0052: Expected O, but got Unknown if (!IsOpen) { return; } if ((Object)(object)_container == (Object)null || (Object)(object)Player.m_localPlayer == (Object)null) { Close(); return; } Styles.Build(); Rect window = _window; object obj = <>O.<0>__DrawWindow; if (obj == null) { WindowFunction val = DrawWindow; <>O.<0>__DrawWindow = val; obj = (object)val; } _window = GUILayout.Window(356372, window, (WindowFunction)obj, GUIContent.none, Styles.Window, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(520f) }); } private static void DrawWindow(int id) { //IL_00d4: Unknown result type (might be due to invalid IL or missing references) DrawHeader(); Caption("GROUPS"); DrawGroupGrid(_entries, CommitChest, 118f, 4f, 4); GUILayout.Space(6f); Caption("SINGLE ITEMS"); DrawItemPicker(_entries, CommitChest, ref _search, ref _searchScroll); DrawItemChips(_entries, CommitChest, 520f); GUILayout.Space(6f); Rule(); DrawFooter(); GUI.DragWindow(new Rect(0f, 0f, 10000f, 22f)); } private static void DrawHeader() { Inventory inventory = _container.GetInventory(); int num = 0; int num2 = 0; int num3 = 0; if (inventory != null) { HashSet hashSet = new HashSet(); foreach (ItemData allItem in inventory.GetAllItems()) { if (allItem != null && allItem.m_shared != null) { hashSet.Add(allItem.m_shared.m_name); } } num = hashSet.Count; num2 = inventory.NrOfItems(); num3 = inventory.GetWidth() * inventory.GetHeight(); } GUILayout.BeginHorizontal(Array.Empty()); GUILayout.Label(Localization.instance.Localize(_container.m_name), Styles.Title, Array.Empty()); GUILayout.FlexibleSpace(); GUILayout.Label("holds " + num + " kind" + ((num == 1) ? "" : "s") + " · " + num2 + "/" + num3 + " slots", Styles.Dim, Array.Empty()); GUILayout.EndHorizontal(); Rule(); } public static void DrawGroupGrid(List entries, Action commit, float cellWidth, float cellGap, int columns) { Editing(entries, commit); DrawGroups(cellWidth, cellGap, columns); } private static void DrawGroups(float CellWidth, float CellGap, int Columns) { IList groups = ItemGroups.Groups; int num = groups.Count + 1; int num2 = (num + Columns - 1) / Columns; for (int i = 0; i < num2; i++) { GUILayout.BeginHorizontal(Array.Empty()); for (int j = 0; j < Columns; j++) { int num3 = i * Columns + j; if (num3 >= num) { GUILayout.Space(CellWidth + CellGap); continue; } if (num3 < groups.Count) { ItemGroup itemGroup = groups[num3]; Cell(itemGroup.Display, "@" + itemGroup.Id, CellWidth); } else { Cell("Anything else", "*", CellWidth); } if (j < Columns - 1) { GUILayout.Space(CellGap); } } GUILayout.EndHorizontal(); GUILayout.Space(CellGap); } } private static void Cell(string label, string entry, float CellWidth) { bool num = _edit.Contains("-" + entry); bool flag = _edit.Contains(entry); GUIStyle val = (num ? Styles.CellNot : (flag ? Styles.CellOn : Styles.CellOff)); if (GUILayout.Button(num ? ("not " + label) : label, val, (GUILayoutOption[])(object)new GUILayoutOption[2] { GUILayout.Width(CellWidth), GUILayout.Height(24f) })) { Cycle(entry); } } public static void DrawItemPicker(List entries, Action commit, ref string search, ref Vector2 scroll) { //IL_000f: Unknown result type (might be due to invalid IL or missing references) //IL_0014: Unknown result type (might be due to invalid IL or missing references) //IL_0026: Unknown result type (might be due to invalid IL or missing references) //IL_002b: Unknown result type (might be due to invalid IL or missing references) Editing(entries, commit); _search = search; _searchScroll = scroll; DrawItemPicker(); search = _search; scroll = _searchScroll; } private static void DrawItemPicker() { //IL_00ab: Unknown result type (might be due to invalid IL or missing references) //IL_00d9: Unknown result type (might be due to invalid IL or missing references) //IL_00de: Unknown result type (might be due to invalid IL or missing references) //IL_014e: Unknown result type (might be due to invalid IL or missing references) //IL_0153: Unknown result type (might be due to invalid IL or missing references) GUILayout.BeginHorizontal(Array.Empty()); _search = GUILayout.TextField(_search, Styles.Field, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Height(22f) }); if (GUILayout.Button("add", Styles.CellOff, (GUILayoutOption[])(object)new GUILayoutOption[2] { GUILayout.Width(52f), GUILayout.Height(22f) })) { AddFirstMatch(); } GUILayout.EndHorizontal(); if (_search.Trim().Length == 0) { return; } List list = Matches(_search.Trim()); if (list.Count == 0) { GUILayout.Label(" nothing matches", Styles.Dim, Array.Empty()); return; } _searchScroll = GUILayout.BeginScrollView(_searchScroll, false, true, GUIStyle.none, GUI.skin.verticalScrollbar, Styles.List, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Height(120f) }); foreach (string item in list) { if (GUILayout.Button(" " + ItemGroups.DisplayNameOf(item), Styles.Row, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Height(20f) })) { if (Event.current != null && Event.current.shift) { Refuse(item); } else { Toggle(item); } _search = ""; _searchScroll = Vector2.zero; break; } } GUILayout.EndScrollView(); Caption("shift-click to refuse an item instead of holding it"); } public static void DrawItemChips(List entries, Action commit, float windowWidth) { Editing(entries, commit); DrawItemChips(windowWidth); } private static void DrawItemChips(float WindowWidth) { //IL_00d8: Unknown result type (might be due to invalid IL or missing references) //IL_00e2: Expected O, but got Unknown //IL_00dd: Unknown result type (might be due to invalid IL or missing references) List list = new List(); foreach (string item in _edit) { string text = ChestFilter.Bare(item); if (!ChestFilter.IsGroup(text) && !(text == "*")) { list.Add(item); } } if (list.Count == 0) { return; } GUILayout.Space(4f); float num = WindowWidth - 40f; float num2 = 0f; bool flag = false; string text2 = null; foreach (string item2 in list) { bool flag2 = ChestFilter.IsExclusion(item2); string text3 = ItemGroups.DisplayNameOf(ChestFilter.Bare(item2)); string text4 = (flag2 ? ("not " + text3) : text3) + " ×"; float num3 = Styles.Chip.CalcSize(new GUIContent(text4)).x + 4f; if (!flag || num2 + num3 > num) { if (flag) { GUILayout.FlexibleSpace(); GUILayout.EndHorizontal(); } GUILayout.BeginHorizontal(Array.Empty()); flag = true; num2 = 0f; } if (GUILayout.Button(text4, Styles.Chip, (GUILayoutOption[])(object)new GUILayoutOption[2] { GUILayout.Width(num3), GUILayout.Height(20f) })) { text2 = item2; } num2 += num3 + 4f; } if (flag) { GUILayout.FlexibleSpace(); GUILayout.EndHorizontal(); } if (text2 != null) { Toggle(text2); } } private static List Matches(string text) { List list = new List(); if ((Object)(object)ObjectDB.instance == (Object)null || ObjectDB.instance.m_items == null) { return list; } foreach (GameObject item in ObjectDB.instance.m_items) { if (!((Object)(object)item == (Object)null) && list.Count < 60 && (ItemGroups.DisplayNameOf(((Object)item).name).IndexOf(text, StringComparison.OrdinalIgnoreCase) >= 0 || ((Object)item).name.IndexOf(text, StringComparison.OrdinalIgnoreCase) >= 0) && !list.Contains(((Object)item).name)) { list.Add(((Object)item).name); } } list.Sort(StringComparer.OrdinalIgnoreCase); return list; } private static void AddFirstMatch() { //IL_003a: Unknown result type (might be due to invalid IL or missing references) //IL_003f: Unknown result type (might be due to invalid IL or missing references) string text = _search.Trim(); if (text.Length != 0) { List list = Matches(text); if (list.Count != 0) { Toggle(list[0]); _search = ""; _searchScroll = Vector2.zero; } } } private static void DrawFooter() { GUILayout.BeginHorizontal(Array.Empty()); if (GUILayout.Button("Learn from contents", Styles.CellOff, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Height(24f) })) { LearnFromContents(); } GUILayout.Space(4f); if (GUILayout.Button("Clear", Styles.CellOff, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Height(24f) })) { _entries.Clear(); CommitChest(); } GUILayout.Space(4f); if (GUILayout.Button("Close", Styles.CellOff, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Height(24f) })) { Close(); } GUILayout.EndHorizontal(); } private static void LearnFromContents() { Editing(_entries, CommitChest); Inventory inventory = _container.GetInventory(); if (inventory == null) { return; } foreach (ItemData allItem in inventory.GetAllItems()) { string text = ItemGroups.PrefabNameOf(allItem); if (text != null && !_edit.Contains(text)) { _edit.Add(text); } } Commit(); } private static void Toggle(string entry) { if (_edit.Contains(entry)) { _edit.Remove(entry); } else { _edit.Add(entry); } Commit(); } private static void Refuse(string entry) { string item = "-" + entry; _edit.Remove(entry); if (!_edit.Contains(item)) { _edit.Add(item); } Commit(); } private static void Cycle(string entry) { string item = "-" + entry; if (_edit.Contains(entry)) { _edit.Remove(entry); _edit.Add(item); } else if (_edit.Contains(item)) { _edit.Remove(item); } else { _edit.Add(entry); } Commit(); } private static void Commit() { if (_save != null) { _save(); } } private static void CommitChest() { ChestFilter.Write(_container, _entries); RulesButton.Refresh(); } public static void Caption(string text) { GUILayout.Label(text, Styles.Caption, Array.Empty()); } public static void Rule() { //IL_0019: Unknown result type (might be due to invalid IL or missing references) //IL_001e: Unknown result type (might be due to invalid IL or missing references) //IL_0039: Unknown result type (might be due to invalid IL or missing references) Rect rect = GUILayoutUtility.GetRect(1f, 1f, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.ExpandWidth(true) }); GUI.DrawTexture(new Rect(((Rect)(ref rect)).x, ((Rect)(ref rect)).y, ((Rect)(ref rect)).width, 1f), (Texture)(object)Styles.RuleLine); GUILayout.Space(5f); } } internal static class Flare { private const string FlareMaterial = "light_glow"; private static GameObject _template; private static bool _searched; public static void Invalidate() { _template = null; _searched = false; } public static GameObject Attach(Transform parent, float scale) { //IL_0033: Unknown result type (might be due to invalid IL or missing references) //IL_0043: Unknown result type (might be due to invalid IL or missing references) //IL_0056: Unknown result type (might be due to invalid IL or missing references) GameObject val = Template(); if ((Object)(object)val == (Object)null || (Object)(object)parent == (Object)null) { return null; } GameObject obj = Object.Instantiate(val, parent, false); ((Object)obj).name = "flare"; obj.transform.localPosition = Vector3.zero; obj.transform.localRotation = Quaternion.identity; obj.transform.localScale = new Vector3(scale, scale, scale); obj.SetActive(true); return obj; } private static GameObject Template() { if ((Object)(object)_template != (Object)null || _searched) { return _template; } _searched = true; string[] array = (StowConfig.FlareDonors.Value ?? "").Split(new char[1] { ',' }); for (int i = 0; i < array.Length; i++) { string text = array[i].Trim(); if (text.Length == 0) { continue; } GameObject val = PropIndex.Find(text); if ((Object)(object)val == (Object)null) { continue; } GameObject val2 = FindFlare(val); if (!((Object)(object)val2 == (Object)null)) { _template = Clone(val2); if (!((Object)(object)_template == (Object)null)) { StowRuntime.Log.LogInfo((object)("Flare borrowed from " + text + "/" + ((Object)val2).name + ".")); return _template; } } } StowRuntime.Log.LogWarning((object)"No flare donor resolved - spirits will be lit but will not halo. Set FlareDonors to a prefab that has one."); return null; } private static GameObject FindFlare(GameObject donor) { Renderer[] componentsInChildren = donor.GetComponentsInChildren(true); foreach (Renderer val in componentsInChildren) { if (!((Object)(object)val == (Object)null)) { Material sharedMaterial = val.sharedMaterial; if (!((Object)(object)sharedMaterial == (Object)null) && ((Object)sharedMaterial).name.StartsWith("light_glow")) { return ((Component)val).gameObject; } } } return null; } private static GameObject Clone(GameObject source) { //IL_0005: Unknown result type (might be due to invalid IL or missing references) //IL_000b: Expected O, but got Unknown GameObject val = new GameObject("StowFlareTemplate"); val.SetActive(false); Object.DontDestroyOnLoad((Object)(object)val); bool forceDisableInit = ZNetView.m_forceDisableInit; ZNetView.m_forceDisableInit = true; GameObject val2; try { val2 = Object.Instantiate(source, val.transform); } finally { ZNetView.m_forceDisableInit = forceDisableInit; } MonoBehaviour[] componentsInChildren = val2.GetComponentsInChildren(true); foreach (MonoBehaviour val3 in componentsInChildren) { if ((Object)(object)val3 != (Object)null) { Object.DestroyImmediate((Object)(object)val3); } } return val2; } } internal sealed class ItemGroup { public string Id; public string Display; public readonly HashSet Members = new HashSet(); } internal static class ItemGroups { private static readonly List All = new List(); private static readonly Dictionary ById = new Dictionary(StringComparer.OrdinalIgnoreCase); private static readonly Dictionary SharedByPrefab = new Dictionary(StringComparer.OrdinalIgnoreCase); private static readonly Dictionary PrefabBySharedName = new Dictionary(); private static bool _built; public static IList Groups { get { Build(); return All; } } public static bool Ready { get { Build(); return _built; } } public static void Invalidate() { _built = false; All.Clear(); ById.Clear(); SharedByPrefab.Clear(); PrefabBySharedName.Clear(); } public static ItemGroup Find(string id) { Build(); if (!ById.TryGetValue(id, out var value)) { return null; } return value; } public static string SharedNameOf(string prefabName) { Build(); if (!SharedByPrefab.TryGetValue(prefabName, out var value)) { return null; } return value; } public static string PrefabNameOf(ItemData item) { if (item == null || item.m_shared == null) { return null; } if ((Object)(object)item.m_dropPrefab != (Object)null) { return ((Object)item.m_dropPrefab).name; } Build(); if (!PrefabBySharedName.TryGetValue(item.m_shared.m_name, out var value)) { return null; } return value; } public static string DisplayNameOf(string prefabName) { Build(); if (!SharedByPrefab.TryGetValue(prefabName, out var value)) { return prefabName; } if (Localization.instance == null) { return value; } return Localization.instance.Localize(value); } private static void Build() { //IL_01f7: Unknown result type (might be due to invalid IL or missing references) //IL_01fc: Unknown result type (might be due to invalid IL or missing references) //IL_01fe: Unknown result type (might be due to invalid IL or missing references) //IL_0201: Unknown result type (might be due to invalid IL or missing references) //IL_0267: Expected I4, but got Unknown //IL_02fb: Unknown result type (might be due to invalid IL or missing references) //IL_0301: Invalid comparison between Unknown and I4 if (_built || (Object)(object)ObjectDB.instance == (Object)null || ObjectDB.instance.m_items == null) { return; } All.Clear(); ById.Clear(); SharedByPrefab.Clear(); PrefabBySharedName.Clear(); ItemGroup ore = Group("ore", "Ore"); ItemGroup bars = Group("bars", "Bars & ingots"); ItemGroup fuel = Group("fuel", "Fuel"); ItemGroup wood = Group("wood", "Wood"); ItemGroup raw = Group("raw", "Raw food"); ItemGroup itemGroup = Group("cooked", "Cooked food"); ItemGroup itemGroup2 = Group("mead", "Mead & potions"); ItemGroup itemGroup3 = Group("seeds", "Seeds & crops"); ItemGroup itemGroup4 = Group("building", "Building materials"); ItemGroup itemGroup5 = Group("material", "Crafting materials"); ItemGroup itemGroup6 = Group("gear", "Weapons & armour"); ItemGroup itemGroup7 = Group("ammo", "Ammo"); ItemGroup itemGroup8 = Group("trophies", "Trophies"); ItemGroup itemGroup9 = Group("fish", "Fish"); ItemGroup itemGroup10 = Group("valuable", "Valuables"); foreach (GameObject item in ObjectDB.instance.m_items) { if ((Object)(object)item == (Object)null) { continue; } ItemDrop component = item.GetComponent(); if (!((Object)(object)component == (Object)null) && component.m_itemData != null && component.m_itemData.m_shared != null) { SharedData shared = component.m_itemData.m_shared; SharedByPrefab[((Object)item).name] = shared.m_name; if (!PrefabBySharedName.ContainsKey(shared.m_name)) { PrefabBySharedName[shared.m_name] = ((Object)item).name; } ItemType itemType = shared.m_itemType; switch (itemType - 1) { case 12: itemGroup8.Members.Add(shared.m_name); break; case 8: case 22: itemGroup7.Members.Add(shared.m_name); break; case 20: itemGroup9.Members.Add(shared.m_name); break; case 0: itemGroup5.Members.Add(shared.m_name); break; case 2: case 3: case 4: case 5: case 6: case 10: case 11: case 13: case 14: case 16: case 17: case 18: case 21: case 23: itemGroup6.Members.Add(shared.m_name); break; } if (shared.m_food > 0f) { itemGroup.Members.Add(shared.m_name); } else if ((int)shared.m_itemType == 2) { itemGroup2.Members.Add(shared.m_name); } if (shared.m_value > 0) { itemGroup10.Members.Add(shared.m_name); } } } ReadStations(ore, bars, fuel, raw, itemGroup, itemGroup2); ReadPieceTable("Hammer", itemGroup4); ReadPieceTable("Cultivator", itemGroup3); SplitFirewood(ore, bars, fuel, wood); All.RemoveAll((ItemGroup g) => g.Members.Count == 0); ById.Clear(); foreach (ItemGroup item2 in All) { ById[item2.Id] = item2; } _built = All.Count > 0; if (!_built || StowConfig.Verbose == null || !StowConfig.Verbose.Value) { return; } foreach (ItemGroup item3 in All) { StowRuntime.Log.LogInfo((object)("group " + item3.Id + ": " + item3.Members.Count + " items")); } } private static ItemGroup Group(string id, string display) { ItemGroup itemGroup = new ItemGroup { Id = id, Display = display }; All.Add(itemGroup); ById[id] = itemGroup; return itemGroup; } private static void ReadStations(ItemGroup ore, ItemGroup bars, ItemGroup fuel, ItemGroup raw, ItemGroup cooked, ItemGroup mead) { ZNetScene instance = ZNetScene.instance; if ((Object)(object)instance == (Object)null || instance.m_prefabs == null) { return; } foreach (GameObject prefab in instance.m_prefabs) { if ((Object)(object)prefab == (Object)null) { continue; } Smelter component = prefab.GetComponent(); if ((Object)(object)component != (Object)null) { Add(fuel, component.m_fuelItem); if (component.m_conversion != null) { foreach (ItemConversion item in component.m_conversion) { if (item != null) { Add(ore, item.m_from); Add(bars, item.m_to); } } } } CookingStation component2 = prefab.GetComponent(); if ((Object)(object)component2 != (Object)null) { Add(fuel, component2.m_fuelItem); if (component2.m_conversion != null) { foreach (ItemConversion item2 in component2.m_conversion) { if (item2 != null) { Add(raw, item2.m_from); Add(cooked, item2.m_to); } } } } Fireplace component3 = prefab.GetComponent(); if ((Object)(object)component3 != (Object)null) { Add(fuel, component3.m_fuelItem); } Fermenter component4 = prefab.GetComponent(); if (!((Object)(object)component4 != (Object)null) || component4.m_conversion == null) { continue; } foreach (ItemConversion item3 in component4.m_conversion) { if (item3 != null) { Add(mead, item3.m_from); Add(mead, item3.m_to); } } } } private static void ReadPieceTable(string toolPrefabName, ItemGroup into) { if ((Object)(object)ObjectDB.instance == (Object)null) { return; } GameObject itemPrefab = ObjectDB.instance.GetItemPrefab(toolPrefabName); if ((Object)(object)itemPrefab == (Object)null) { return; } ItemDrop component = itemPrefab.GetComponent(); if ((Object)(object)component == (Object)null || component.m_itemData == null || component.m_itemData.m_shared == null) { return; } PieceTable buildPieces = component.m_itemData.m_shared.m_buildPieces; if ((Object)(object)buildPieces == (Object)null || buildPieces.m_pieces == null) { return; } foreach (GameObject piece in buildPieces.m_pieces) { if ((Object)(object)piece == (Object)null) { continue; } Piece component2 = piece.GetComponent(); if ((Object)(object)component2 == (Object)null || component2.m_resources == null) { continue; } Requirement[] resources = component2.m_resources; foreach (Requirement val in resources) { if (val != null) { Add(into, val.m_resItem); } } } } private static void SplitFirewood(ItemGroup ore, ItemGroup bars, ItemGroup fuel, ItemGroup wood) { ZNetScene instance = ZNetScene.instance; if ((Object)(object)instance == (Object)null || instance.m_prefabs == null) { return; } foreach (GameObject prefab in instance.m_prefabs) { if ((Object)(object)prefab == (Object)null) { continue; } Smelter component = prefab.GetComponent(); if ((Object)(object)component == (Object)null || component.m_conversion == null) { continue; } foreach (ItemConversion item in component.m_conversion) { if (item == null || (Object)(object)item.m_from == (Object)null || (Object)(object)item.m_to == (Object)null) { continue; } string text = SharedNameOfDrop(item.m_to); if (text != null && fuel.Members.Contains(text)) { string text2 = SharedNameOfDrop(item.m_from); if (text2 != null) { ore.Members.Remove(text2); bars.Members.Remove(text); wood.Members.Add(text2); } } } } } private static void Add(ItemGroup group, ItemDrop drop) { string text = SharedNameOfDrop(drop); if (text != null) { group.Members.Add(text); } } private static string SharedNameOfDrop(ItemDrop drop) { if ((Object)(object)drop == (Object)null || drop.m_itemData == null || drop.m_itemData.m_shared == null) { return null; } return drop.m_itemData.m_shared.m_name; } } internal static class PostModel { public const string GlowGroup = "core"; private static readonly Dictionary Donors = new Dictionary(StringComparer.OrdinalIgnoreCase) { { "wood", new string[3] { "wood_wall", "wood_beam", "piece_chest_wood" } }, { "iron", new string[5] { "piece_cauldron", "piece_chest_blackmetal", "forge", "blackforge", "piece_stonecutter" } }, { "stone", new string[3] { "stone_wall_2x1", "piece_stonecutter", "smelter" } } }; private static readonly Dictionary Cache = new Dictionary(StringComparer.OrdinalIgnoreCase); private static readonly Dictionary Atlas = new Dictionary(StringComparer.OrdinalIgnoreCase); public const string HeartwoodAnchor = "heartwood"; private static string ModelFile => StowConfig.PostModelFile.Value; private static string ColliderFile => Path.ChangeExtension(ModelFile, ".col"); public static bool Apply(GameObject prefab) { return Apply(prefab, ModelFile, "post_visual", heartwood: true); } public static bool Apply(GameObject prefab, string modelFile, string visualName, bool heartwood) { //IL_008b: Unknown result type (might be due to invalid IL or missing references) //IL_0091: Expected O, but got Unknown //IL_00a9: Unknown result type (might be due to invalid IL or missing references) //IL_00b9: Unknown result type (might be due to invalid IL or missing references) //IL_00c9: Unknown result type (might be due to invalid IL or missing references) string directoryName = Path.GetDirectoryName(typeof(PostModel).Assembly.Location); ModelData modelData = ObjMesh.Load(Path.Combine(directoryName, modelFile)); if (modelData == null || (Object)(object)modelData.Mesh == (Object)null) { StowRuntime.Log.LogWarning((object)("No " + modelFile + " beside the dll - falling back to the donor's own look.")); return false; } MeshRenderer[] componentsInChildren = prefab.GetComponentsInChildren(true); foreach (MeshRenderer val in componentsInChildren) { if (!((Object)(object)val == (Object)null)) { Object.DestroyImmediate((Object)(object)((Component)val).gameObject); } } GameObject val2 = new GameObject(visualName); val2.transform.SetParent(prefab.transform, false); val2.transform.localPosition = Vector3.zero; val2.transform.localRotation = Quaternion.identity; val2.transform.localScale = Vector3.one; val2.AddComponent().sharedMesh = modelData.Mesh; ((Renderer)val2.AddComponent()).sharedMaterials = SkinsFor(modelData.Groups); Remap(modelData.Mesh, modelData.Groups); if (heartwood) { Heartwood(prefab, val2.transform, modelData); } ReplaceColliders(prefab, Path.Combine(directoryName, Path.ChangeExtension(modelFile, ".col"))); StowRuntime.Log.LogInfo((object)string.Format("{0} loaded: {1} verts, {2} tris, groups [{3}].", modelFile, modelData.Mesh.vertexCount, modelData.Mesh.triangles.Length / 3, string.Join(", ", modelData.Groups))); return true; } private static void Heartwood(GameObject prefab, Transform visual, ModelData model) { //IL_0055: Unknown result type (might be due to invalid IL or missing references) //IL_005a: Unknown result type (might be due to invalid IL or missing references) //IL_005b: Unknown result type (might be due to invalid IL or missing references) //IL_005c: Unknown result type (might be due to invalid IL or missing references) //IL_006d: Unknown result type (might be due to invalid IL or missing references) //IL_0071: Unknown result type (might be due to invalid IL or missing references) //IL_0076: Unknown result type (might be due to invalid IL or missing references) //IL_007b: Unknown result type (might be due to invalid IL or missing references) //IL_007c: Unknown result type (might be due to invalid IL or missing references) //IL_0081: Unknown result type (might be due to invalid IL or missing references) //IL_0086: Unknown result type (might be due to invalid IL or missing references) //IL_008b: Unknown result type (might be due to invalid IL or missing references) //IL_00a0: Unknown result type (might be due to invalid IL or missing references) //IL_00a7: Expected O, but got Unknown //IL_00bc: 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_00c9: Unknown result type (might be due to invalid IL or missing references) //IL_00f2: Unknown result type (might be due to invalid IL or missing references) //IL_013a: Unknown result type (might be due to invalid IL or missing references) //IL_013f: Unknown result type (might be due to invalid IL or missing references) int num = Array.FindIndex(model.Groups, (string group) => string.Equals(group, "core", StringComparison.OrdinalIgnoreCase)); if (num < 0) { return; } int[] triangles = model.Mesh.GetTriangles(num); if (triangles != null && triangles.Length != 0) { Vector3[] vertices = model.Mesh.vertices; Vector3 val = vertices[triangles[0]]; Vector3 val2 = val; int[] array = triangles; foreach (int num3 in array) { val = Vector3.Min(val, vertices[num3]); val2 = Vector3.Max(val2, vertices[num3]); } GameObject val3 = new GameObject("heartwood"); val3.transform.SetParent(visual, false); val3.transform.localPosition = (val + val2) * 0.5f; Light obj = val3.AddComponent(); obj.type = (LightType)2; obj.range = StowConfig.PostLightRange.Value; obj.color = Carrier.LightColour; obj.intensity = StowConfig.PostLightIntensity.Value; obj.shadows = (LightShadows)0; Flare.Attach(val3.transform, StowConfig.PostFlareScale.Value); StowRuntime.Log.LogInfo((object)("Heartwood found at " + ((object)val3.transform.localPosition/*cast due to .constrained prefix*/).ToString() + " - the post is lit and the spirit starts there.")); } } public static Material[] SkinsFor(string[] groups) { Material[] array = (Material[])(object)new Material[groups.Length]; for (int i = 0; i < groups.Length; i++) { array[i] = Borrow(groups[i]); if ((Object)(object)array[i] == (Object)null) { StowRuntime.Log.LogWarning((object)("No material found for group '" + groups[i] + "'.")); } } return array; } public static void Invalidate() { Cache.Clear(); Atlas.Clear(); } private static Material Borrow(string group) { //IL_00c3: Unknown result type (might be due to invalid IL or missing references) //IL_0106: Unknown result type (might be due to invalid IL or missing references) if (Cache.TryGetValue(group, out var value)) { return value; } string[] array = DonorsFor(group); for (int i = 0; i < array.Length; i++) { string text = array[i].Trim(); if (text.Length == 0) { continue; } GameObject val = PropIndex.Find(text); if ((Object)(object)val == (Object)null) { continue; } MeshRenderer[] componentsInChildren = val.GetComponentsInChildren(true); foreach (MeshRenderer val2 in componentsInChildren) { Material sharedMaterial = ((Renderer)val2).sharedMaterial; if (!((Object)(object)sharedMaterial == (Object)null) && !((Object)(object)sharedMaterial.shader == (Object)null) && sharedMaterial.HasProperty("_MainTex") && !((Object)(object)sharedMaterial.GetTexture("_MainTex") == (Object)null)) { Cache[group] = sharedMaterial; Atlas[group] = UvRegion((Renderer)(object)val2); StowRuntime.Log.LogInfo((object)$"Group '{group}' skinned with {((Object)sharedMaterial).name} from {text} (shader {((Object)sharedMaterial.shader).name}), atlas {Atlas[group]}."); return sharedMaterial; } } } Cache[group] = null; return null; } private static string[] DonorsFor(string group) { if (string.Equals(group, "core", StringComparison.OrdinalIgnoreCase)) { return (StowConfig.PostGlowDonors.Value ?? "").Split(new char[1] { ',' }); } if (!Donors.TryGetValue(group, out var value)) { return Donors["wood"]; } return value; } private static Rect UvRegion(Renderer renderer) { //IL_006f: Unknown result type (might be due to invalid IL or missing references) //IL_0070: Unknown result type (might be due to invalid IL or missing references) //IL_020f: Unknown result type (might be due to invalid IL or missing references) //IL_004a: Unknown result type (might be due to invalid IL or missing references) //IL_0055: Unknown result type (might be due to invalid IL or missing references) //IL_0056: Unknown result type (might be due to invalid IL or missing references) //IL_0089: 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_0093: Unknown result type (might be due to invalid IL or missing references) //IL_020c: Unknown result type (might be due to invalid IL or missing references) //IL_020a: Unknown result type (might be due to invalid IL or missing references) Rect val = default(Rect); ((Rect)(ref val))..ctor(0f, 0f, 1f, 1f); MeshFilter val2 = (((Object)(object)renderer != (Object)null) ? ((Component)renderer).GetComponent() : null); Mesh val3 = (((Object)(object)val2 != (Object)null) ? val2.sharedMesh : null); if ((Object)(object)val3 == (Object)null) { return val; } Vector2[] uv; int[] triangles; try { if (!val3.isReadable) { return val; } uv = val3.uv; triangles = val3.triangles; } catch { return val; } if (uv == null || uv.Length == 0 || triangles == null || triangles.Length < 3) { return val; } float num = 0f; Rect result = val; for (int i = 0; i + 2 < triangles.Length; i += 3) { int num2 = triangles[i]; int num3 = triangles[i + 1]; int num4 = triangles[i + 2]; if (num2 >= uv.Length || num3 >= uv.Length || num4 >= uv.Length) { continue; } float num5 = Mathf.Min(uv[num2].x, Mathf.Min(uv[num3].x, uv[num4].x)); float num6 = Mathf.Max(uv[num2].x, Mathf.Max(uv[num3].x, uv[num4].x)); float num7 = Mathf.Min(uv[num2].y, Mathf.Min(uv[num3].y, uv[num4].y)); float num8 = Mathf.Max(uv[num2].y, Mathf.Max(uv[num3].y, uv[num4].y)); float num9 = num6 - num5; float num10 = num8 - num7; if (!(num9 <= 0.005f) && !(num10 <= 0.005f) && !(num9 > 1f) && !(num10 > 1f)) { float num11 = num9 * num10; if (!(num11 <= num)) { num = num11; ((Rect)(ref result))..ctor(num5, num7, num9, num10); } } } if (!(num > 0f)) { return val; } return result; } public static void Remap(Mesh mesh, string[] groups) { //IL_00e6: Unknown result type (might be due to invalid IL or missing references) //IL_00eb: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)mesh == (Object)null || groups == null) { return; } Vector2[] uv = mesh.uv; if (uv == null || uv.Length == 0) { return; } int num = Mathf.Min(groups.Length, mesh.subMeshCount); int num2 = 0; bool[] array = new bool[uv.Length]; for (int i = 0; i < num; i++) { if (!Atlas.TryGetValue(groups[i], out var value) || (((Rect)(ref value)).width >= 0.999f && ((Rect)(ref value)).height >= 0.999f)) { continue; } int[] triangles = mesh.GetTriangles(i); foreach (int num3 in triangles) { if (num3 >= 0 && num3 < uv.Length && !array[num3]) { array[num3] = true; uv[num3] = new Vector2(((Rect)(ref value)).x + Mathf.Clamp01(uv[num3].x) * ((Rect)(ref value)).width, ((Rect)(ref value)).y + Mathf.Clamp01(uv[num3].y) * ((Rect)(ref value)).height); } } num2++; } if (num2 != 0) { mesh.uv = uv; StowRuntime.Log.LogInfo((object)("Remapped UVs into the atlas for " + num2 + " group(s).")); } } private static void ReplaceColliders(GameObject prefab, string path) { //IL_00c7: Unknown result type (might be due to invalid IL or missing references) //IL_00cd: Expected O, but got Unknown //IL_0117: Unknown result type (might be due to invalid IL or missing references) //IL_013f: Unknown result type (might be due to invalid IL or missing references) if (!File.Exists(path)) { StowRuntime.Log.LogWarning((object)"No collider file beside the dll - keeping the donor's collision."); return; } List list = new List(); string[] array = File.ReadAllLines(path); for (int i = 0; i < array.Length; i++) { string text = array[i].Trim(); if (text.Length != 0 && !text.StartsWith("#")) { string[] array2 = text.Split(new char[1] { ' ' }, StringSplitOptions.RemoveEmptyEntries); if (array2.Length >= 7 && array2[0] == "box") { list.Add(array2); } } } if (list.Count == 0) { return; } Collider[] componentsInChildren = prefab.GetComponentsInChildren(true); for (int i = 0; i < componentsInChildren.Length; i++) { Object.DestroyImmediate((Object)(object)componentsInChildren[i]); } CultureInfo invariantCulture = CultureInfo.InvariantCulture; GameObject val = new GameObject("post_collision"); val.transform.SetParent(prefab.transform, false); foreach (string[] item in list) { BoxCollider obj = val.AddComponent(); obj.center = new Vector3(float.Parse(item[1], invariantCulture), float.Parse(item[2], invariantCulture), float.Parse(item[3], invariantCulture)); obj.size = new Vector3(float.Parse(item[4], invariantCulture), float.Parse(item[5], invariantCulture), float.Parse(item[6], invariantCulture)); } StowRuntime.Log.LogInfo((object)("Post collision: " + list.Count + " boxes.")); } } internal static class PostRules { public enum Presence { OnlyWorking, LivesHere } private const string ZFetch = "stowFetch"; private const string ZTidy = "stowTidy"; private const string ZPresence = "stowPresence"; public static List Fetch(Container container) { return Clean(Read(container, "stowFetch")); } public static void SetFetch(Container container, IEnumerable entries) { Write(container, "stowFetch", string.Join(",", Clean(entries).ToArray())); } public static bool Wants(Container post, ItemData item) { List list = Fetch(post); if (list.Count == 0) { return false; } return ChestFilter.Matches(list, item); } public static bool Tidy(Container container) { return Read(container, "stowTidy") == "1"; } public static void SetTidy(Container container, bool on) { Write(container, "stowTidy", on ? "1" : ""); } public static Presence Where(Container container) { if (!(Read(container, "stowPresence") == "1")) { return Presence.OnlyWorking; } return Presence.LivesHere; } public static void SetPresence(Container container, Presence presence) { Write(container, "stowPresence", (presence == Presence.LivesHere) ? "1" : ""); } private static string Read(Container container, string key) { ZNetView val = (((Object)(object)container == (Object)null) ? null : ((Component)container).GetComponent()); if (!((Object)(object)val == (Object)null) && val.IsValid()) { return val.GetZDO().GetString(key, ""); } return ""; } private static void Write(Container container, string key, string value) { ZNetView val = (((Object)(object)container == (Object)null) ? null : ((Component)container).GetComponent()); if (!((Object)(object)val == (Object)null) && val.IsValid()) { val.ClaimOwnership(); val.GetZDO().Set(key, value ?? ""); } } private static List Clean(IEnumerable entries) { List list = new List(); if (entries == null) { return list; } foreach (string entry in entries) { if (entry != null) { string text = entry.Trim(); if (text.Length != 0 && !list.Contains(text)) { list.Add(text); } } } return list; } private static List Clean(string packed) { return Clean((packed ?? "").Split(new char[1] { ',' })); } } internal static class RulesButton { [CompilerGenerated] private static class <>O { public static UnityAction <0>__OnPressed; } private static Button _button; private static TMP_Text _label; public static void Sync(InventoryGui gui, Container container) { if (!((Object)(object)gui == (Object)null) && (!((Object)(object)_button == (Object)null) || Build(gui))) { bool flag = (Object)(object)container != (Object)null && !StowPost.Is(container); if (((Component)_button).gameObject.activeSelf != flag) { ((Component)_button).gameObject.SetActive(flag); } if (flag) { int count = ChestFilter.Entries(container).Count; _label.text = ((count == 0) ? "Holds…" : ("Holds " + count)); } } } public static void Hide() { if ((Object)(object)_button != (Object)null) { ((Component)_button).gameObject.SetActive(false); } } public static void Refresh() { InventoryGui instance = InventoryGui.instance; if (!((Object)(object)instance == (Object)null)) { Sync(instance, StowPatches.CurrentContainer(instance)); } } private static bool Build(InventoryGui gui) { //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_0088: Expected O, but got Unknown //IL_00f3: Unknown result type (might be due to invalid IL or missing references) //IL_00fe: Unknown result type (might be due to invalid IL or missing references) //IL_0103: Unknown result type (might be due to invalid IL or missing references) //IL_0112: 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) Button stackAllButton = gui.m_stackAllButton; if ((Object)(object)stackAllButton == (Object)null) { return false; } GameObject val = Object.Instantiate(((Component)stackAllButton).gameObject, ((Component)stackAllButton).transform.parent); ((Object)val).name = "StowRulesButton"; _button = val.GetComponent