Please disclose if any significant portion of your mod was created using AI tools by adding the 'AI Generated' category. Failing to do so may result in the mod being removed from Thunderstore.
Decompiled source of Vaettir v1.0.0
plugins/Vaettir/Vaettir.dll
Decompiled 13 hours ago
The result has been truncated due to the large size, download it to view full contents!
using System; using System.Collections.Generic; using System.Diagnostics; using System.Globalization; using System.IO; using System.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<string, GameObject> Templates = new Dictionary<string, GameObject>(); 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<GameObject>(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<GameObject>(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<Component> list = new List<Component>(); MonoBehaviour[] componentsInChildren = clone.GetComponentsInChildren<MonoBehaviour>(true); foreach (MonoBehaviour val in componentsInChildren) { if ((Object)(object)val != (Object)null) { list.Add((Component)(object)val); } } Collider[] componentsInChildren2 = clone.GetComponentsInChildren<Collider>(true); foreach (Collider val2 in componentsInChildren2) { if ((Object)(object)val2 != (Object)null) { list.Add((Component)(object)val2); } } Rigidbody[] componentsInChildren3 = clone.GetComponentsInChildren<Rigidbody>(true); foreach (Rigidbody val3 in componentsInChildren3) { if ((Object)(object)val3 != (Object)null) { list.Add((Component)(object)val3); } } ParticleSystem[] componentsInChildren4 = clone.GetComponentsInChildren<ParticleSystem>(true); foreach (ParticleSystem val4 in componentsInChildren4) { if ((Object)(object)val4 != (Object)null) { list.Add((Component)(object)val4); } } TrailRenderer[] componentsInChildren5 = clone.GetComponentsInChildren<TrailRenderer>(true); foreach (TrailRenderer val5 in componentsInChildren5) { if ((Object)(object)val5 != (Object)null) { list.Add((Component)(object)val5); } } Light[] componentsInChildren6 = clone.GetComponentsInChildren<Light>(true); foreach (Light val6 in componentsInChildren6) { if ((Object)(object)val6 != (Object)null) { list.Add((Component)(object)val6); } } AudioSource[] componentsInChildren7 = clone.GetComponentsInChildren<AudioSource>(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<ParticleSystemRenderer>(true); foreach (ParticleSystemRenderer val8 in componentsInChildren8) { if ((Object)(object)val8 != (Object)null) { Object.DestroyImmediate((Object)(object)val8); } } Renderer[] componentsInChildren9 = clone.GetComponentsInChildren<Renderer>(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<MeshFilter>(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<SkinnedMeshRenderer>(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<Transform> _rings = new List<Transform>(); private readonly List<Transform> _motes = new List<Transform>(); private readonly List<float> _moteAngle = new List<float>(); private readonly List<float> _moteRate = new List<float>(); 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>(); _light.type = (LightType)2; _light.range = LightRange; _light.color = LightColour; _light.intensity = 1.6f; _renderers = ((Component)this).GetComponentsInChildren<Renderer>(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>(); 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<MeshFilter>().sharedMesh = model.Mesh; MeshRenderer obj = val.AddComponent<MeshRenderer>(); ((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<Courier> _couriers = new List<Courier>(); private readonly List<ItemData> _reserved = new List<ItemData>(); private readonly List<Container> _touched = new List<Container>(); 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<ZNetView>(); 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<ZNetView>() : null); if ((Object)(object)val == (Object)null || !val.IsValid() || !val.IsOwner()) { return; } List<SpiritTrips.Flight> list = new List<SpiritTrips.Flight>(); 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<Collider>(); 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<string> Items = new HashSet<string>(); public readonly List<ItemGroup> Groups = new List<ItemGroup>(); public readonly HashSet<string> NotItems = new HashSet<string>(); public readonly List<ItemGroup> NotGroups = new List<ItemGroup>(); 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<string> entries) { ZNetView val = (((Object)(object)container == (Object)null) ? null : ((Component)container).GetComponent<ZNetView>()); if (!((Object)(object)val == (Object)null) && val.IsValid()) { val.ClaimOwnership(); val.GetZDO().Set("stowFilter", string.Join(",", Clean(entries).ToArray())); } } public static List<string> Entries(Container container) { return Clean(Read(container).Split(new char[1] { ',' })); } private static List<string> Clean(IEnumerable<string> entries) { List<string> list = new List<string>(); 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<string> 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<string> list = Entries(container); if (list.Count == 0) { return null; } List<string> list2 = new List<string>(); List<string> list3 = new List<string>(); 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<ZNetView>(); 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<string> _neverStow; private static string _neverStowRaw; public static int Distribute(Inventory source, Vector3 origin, out int chestCount, Predicate<ItemData> 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<ChestFilter.Rule> list = new List<ChestFilter.Rule>(); CollectChests(origin, list); if (list.Count == 0) { return 0; } List<Plan> list2 = new List<Plan>(); foreach (ItemData item in new List<ItemData>(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<Container> list3 = new List<Container>(); 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<ChestFilter.Rule> rules, ItemData item, List<Container> 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<ZNetView>(); 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<ItemData> 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<string> list = PostRules.Fetch(post); if (list.Count == 0) { return false; } Inventory inventory = post.GetInventory(); if (inventory == null) { return false; } List<ChestFilter.Rule> list2 = new List<ChestFilter.Rule>(); 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<ItemData> 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<ChestFilter.Rule> list = new List<ChestFilter.Rule>(); 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<ItemData> 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<ChestFilter.Rule> list = new List<ChestFilter.Rule>(); CollectChests(origin, list); if (list.Count == 0) { return false; } List<Plan> list2 = new List<Plan>(); 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<ChestFilter.Rule> 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<ChestFilter.Rule> 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<ChestFilter.Rule> 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<Container> list = new List<Container>(); for (int i = 0; i < num; i++) { Container componentInParent = ((Component)Hits[i]).GetComponentInParent<Container>(); 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<ZNetView>(); 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<Vagon>() != (Object)null) { return false; } if ((Object)(object)((Component)container).GetComponentInParent<Ship>() != (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<string> NeverStow() { string text = StowConfig.NeverStow.Value ?? ""; if (_neverStow != null && text == _neverStowRaw) { return _neverStow; } _neverStowRaw = text; _neverStow = new HashSet<string>(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<string> _entries = new List<string>(); private static List<string> _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<string> 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<string> hashSet = new HashSet<string>(); 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<GUILayoutOption>()); GUILayout.Label(Localization.instance.Localize(_container.m_name), Styles.Title, Array.Empty<GUILayoutOption>()); GUILayout.FlexibleSpace(); GUILayout.Label("holds " + num + " kind" + ((num == 1) ? "" : "s") + " · " + num2 + "/" + num3 + " slots", Styles.Dim, Array.Empty<GUILayoutOption>()); GUILayout.EndHorizontal(); Rule(); } public static void DrawGroupGrid(List<string> 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<ItemGroup> 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<GUILayoutOption>()); 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<string> 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<GUILayoutOption>()); _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<string> list = Matches(_search.Trim()); if (list.Count == 0) { GUILayout.Label(" nothing matches", Styles.Dim, Array.Empty<GUILayoutOption>()); 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<string> 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<string> list = new List<string>(); 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<GUILayoutOption>()); 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<string> Matches(string text) { List<string> list = new List<string>(); 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<string> list = Matches(text); if (list.Count != 0) { Toggle(list[0]); _search = ""; _searchScroll = Vector2.zero; } } } private static void DrawFooter() { GUILayout.BeginHorizontal(Array.Empty<GUILayoutOption>()); 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<GUILayoutOption>()); } 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<GameObject>(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<Renderer>(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<GameObject>(source, val.transform); } finally { ZNetView.m_forceDisableInit = forceDisableInit; } MonoBehaviour[] componentsInChildren = val2.GetComponentsInChildren<MonoBehaviour>(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<string> Members = new HashSet<string>(); } internal static class ItemGroups { private static readonly List<ItemGroup> All = new List<ItemGroup>(); private static readonly Dictionary<string, ItemGroup> ById = new Dictionary<string, ItemGroup>(StringComparer.OrdinalIgnoreCase); private static readonly Dictionary<string, string> SharedByPrefab = new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase); private static readonly Dictionary<string, string> PrefabBySharedName = new Dictionary<string, string>(); private static bool _built; public static IList<ItemGroup> 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<ItemDrop>(); 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<Smelter>(); 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<CookingStation>(); 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<Fireplace>(); if ((Object)(object)component3 != (Object)null) { Add(fuel, component3.m_fuelItem); } Fermenter component4 = prefab.GetComponent<Fermenter>(); 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<ItemDrop>(); 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<Piece>(); 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<Smelter>(); 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<string, string[]> Donors = new Dictionary<string, string[]>(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<string, Material> Cache = new Dictionary<string, Material>(StringComparer.OrdinalIgnoreCase); private static readonly Dictionary<string, Rect> Atlas = new Dictionary<string, Rect>(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<MeshRenderer>(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<MeshFilter>().sharedMesh = modelData.Mesh; ((Renderer)val2.AddComponent<MeshRenderer>()).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