Decompiled source of Thrift v1.0.0

ThriftMod.dll

Decompiled 2 weeks ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using System.Text;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using HarmonyLib;
using Jotunn.Configs;
using Jotunn.Entities;
using Jotunn.Managers;
using Jotunn.Utils;
using Microsoft.CodeAnalysis;
using UnityEngine;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: InternalsVisibleTo("ThriftDevBoot")]
[assembly: IgnoresAccessChecksTo("assembly_valheim")]
[assembly: TargetFramework(".NETFramework,Version=v4.6.2", FrameworkDisplayName = ".NET Framework 4.6.2")]
[assembly: AssemblyCompany("ThriftMod")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0")]
[assembly: AssemblyProduct("ThriftMod")]
[assembly: AssemblyTitle("ThriftMod")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.0.0.0")]
[module: UnverifiableCode]
[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 ThriftMod
{
	internal static class Kitbash
	{
		public class Fit
		{
			public float Height;

			public float Width;

			public float Scale;
		}

		public static GameObject Source(string prefab)
		{
			GameObject prefab2 = PrefabManager.Instance.GetPrefab(prefab);
			if (!Object.op_Implicit((Object)(object)prefab2))
			{
				Plugin.Log.LogWarning((object)("Kitbash: vanilla prefab '" + prefab + "' not found"));
			}
			return prefab2;
		}

		private static bool Find(string prefab, string childPath, out Transform root, out Transform node)
		{
			node = null;
			GameObject obj = Source(prefab);
			root = ((obj != null) ? obj.transform : null);
			if (!Object.op_Implicit((Object)(object)root))
			{
				return false;
			}
			node = (string.IsNullOrEmpty(childPath) ? root : root.Find(childPath));
			if (!Object.op_Implicit((Object)(object)node))
			{
				Plugin.Log.LogWarning((object)("Kitbash: '" + prefab + "/" + childPath + "' not found"));
			}
			return Object.op_Implicit((Object)(object)node);
		}

		private static Mesh MeshOf(Transform t, out Material[] mats)
		{
			mats = null;
			SkinnedMeshRenderer component = ((Component)t).GetComponent<SkinnedMeshRenderer>();
			if (Object.op_Implicit((Object)(object)component))
			{
				mats = ((Renderer)component).sharedMaterials;
				return component.sharedMesh;
			}
			MeshRenderer component2 = ((Component)t).GetComponent<MeshRenderer>();
			MeshFilter component3 = ((Component)t).GetComponent<MeshFilter>();
			if (Object.op_Implicit((Object)(object)component2) && Object.op_Implicit((Object)(object)component3))
			{
				mats = ((Renderer)component2).sharedMaterials;
				return component3.sharedMesh;
			}
			return null;
		}

		private static Bounds Transformed(Bounds b, Matrix4x4 m)
		{
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//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_0014: Unknown result type (might be due to invalid IL or missing references)
			//IL_0015: Unknown result type (might be due to invalid IL or missing references)
			//IL_001c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0023: Unknown result type (might be due to invalid IL or missing references)
			//IL_002a: Unknown result type (might be due to invalid IL or missing references)
			//IL_002f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0034: 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)
			//IL_0047: 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_0055: 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_0069: 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_007d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0075: Unknown result type (might be due to invalid IL or missing references)
			//IL_0084: Unknown result type (might be due to invalid IL or missing references)
			//IL_0089: Unknown result type (might be due to invalid IL or missing references)
			//IL_008e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0094: Unknown result type (might be due to invalid IL or missing references)
			//IL_0096: Unknown result type (might be due to invalid IL or missing references)
			Vector3 center = ((Bounds)(ref b)).center;
			Vector3 extents = ((Bounds)(ref b)).extents;
			Bounds result = default(Bounds);
			((Bounds)(ref result))..ctor(((Matrix4x4)(ref m)).MultiplyPoint3x4(center + new Vector3(0f - extents.x, 0f - extents.y, 0f - extents.z)), Vector3.zero);
			for (int i = 1; i < 8; i++)
			{
				Vector3 val = center + new Vector3(((i & 1) == 0) ? (0f - extents.x) : extents.x, ((i & 2) == 0) ? (0f - extents.y) : extents.y, ((i & 4) == 0) ? (0f - extents.z) : extents.z);
				((Bounds)(ref result)).Encapsulate(((Matrix4x4)(ref m)).MultiplyPoint3x4(val));
			}
			return result;
		}

		public static Transform Part(Transform parent, string prefab, string childPath, Vector3 anchor, Fit fit, Quaternion? extraRotation = null, Material[] materials = null, string name = null)
		{
			//IL_0058: Unknown result type (might be due to invalid IL or missing references)
			//IL_005e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0063: Unknown result type (might be due to invalid IL or missing references)
			//IL_0068: Unknown result type (might be due to invalid IL or missing references)
			//IL_0089: Unknown result type (might be due to invalid IL or missing references)
			//IL_008e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0090: 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_0075: Unknown result type (might be due to invalid IL or missing references)
			//IL_007a: Unknown result type (might be due to invalid IL or missing references)
			//IL_007f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0081: Unknown result type (might be due to invalid IL or missing references)
			//IL_0086: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bc: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c8: Unknown result type (might be due to invalid IL or missing references)
			//IL_0110: Unknown result type (might be due to invalid IL or missing references)
			//IL_0117: Expected O, but got Unknown
			//IL_0159: Unknown result type (might be due to invalid IL or missing references)
			//IL_0165: Unknown result type (might be due to invalid IL or missing references)
			//IL_0171: Unknown result type (might be due to invalid IL or missing references)
			//IL_017b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0182: Unknown result type (might be due to invalid IL or missing references)
			//IL_0187: Unknown result type (might be due to invalid IL or missing references)
			//IL_0192: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a5: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ac: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c0: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c5: Unknown result type (might be due to invalid IL or missing references)
			//IL_01cc: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d1: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d2: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d4: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d9: Unknown result type (might be due to invalid IL or missing references)
			//IL_0218: Unknown result type (might be due to invalid IL or missing references)
			//IL_0236: Unknown result type (might be due to invalid IL or missing references)
			//IL_024a: Unknown result type (might be due to invalid IL or missing references)
			if (!Find(prefab, childPath, out var root, out var node))
			{
				return null;
			}
			Material[] mats;
			Mesh val = MeshOf(node, out mats);
			if (!Object.op_Implicit((Object)(object)val))
			{
				Plugin.Log.LogWarning((object)("Kitbash: no mesh on '" + prefab + "/" + childPath + "'"));
				return null;
			}
			Matrix4x4 val2 = root.worldToLocalMatrix * node.localToWorldMatrix;
			if (extraRotation.HasValue)
			{
				val2 = Matrix4x4.Rotate(extraRotation.Value) * val2;
			}
			Bounds val3 = Transformed(val.bounds, val2);
			float num = ((fit.Scale > 0f) ? fit.Scale : ((fit.Height > 0f) ? (fit.Height / ((Bounds)(ref val3)).size.y) : (fit.Width / Mathf.Max(((Bounds)(ref val3)).size.x, ((Bounds)(ref val3)).size.z))));
			GameObject val4 = new GameObject(name ?? (prefab + "_" + ((Object)node).name));
			val4.layer = ((Component)parent).gameObject.layer;
			val4.transform.SetParent(parent, false);
			val4.AddComponent<MeshFilter>().sharedMesh = val;
			((Renderer)val4.AddComponent<MeshRenderer>()).sharedMaterials = materials ?? mats;
			Vector3 val5 = new Vector3(((Bounds)(ref val3)).center.x, ((Bounds)(ref val3)).min.y, ((Bounds)(ref val3)).center.z) * num;
			val4.transform.localRotation = ((Matrix4x4)(ref val2)).rotation;
			val4.transform.localScale = ((Matrix4x4)(ref val2)).lossyScale * num;
			val4.transform.localPosition = Vector4.op_Implicit(((Matrix4x4)(ref val2)).GetColumn(3)) * num + (anchor - val5);
			Plugin.Log.LogDebug((object)$"Kitbash {((Object)val4).name}: mesh={((Object)val).name} verts={val.vertexCount} srcBounds={((Bounds)(ref val3)).size} k={num} scale={val4.transform.localScale} pos={val4.transform.localPosition}");
			return val4.transform;
		}

		public static Transform Effect(Transform parent, string prefab, string effectPath, string relativeTo, Vector3 anchor)
		{
			//IL_0028: Unknown result type (might be due to invalid IL or missing references)
			//IL_002d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0082: Unknown result type (might be due to invalid IL or missing references)
			//IL_0087: Unknown result type (might be due to invalid IL or missing references)
			//IL_008c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0038: 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)
			//IL_0049: Unknown result type (might be due to invalid IL or missing references)
			//IL_004e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0053: Unknown result type (might be due to invalid IL or missing references)
			//IL_0059: Unknown result type (might be due to invalid IL or missing references)
			//IL_0065: Unknown result type (might be due to invalid IL or missing references)
			//IL_0071: Unknown result type (might be due to invalid IL or missing references)
			//IL_0114: Unknown result type (might be due to invalid IL or missing references)
			//IL_0116: Unknown result type (might be due to invalid IL or missing references)
			//IL_0118: Unknown result type (might be due to invalid IL or missing references)
			//IL_011a: 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_0131: Unknown result type (might be due to invalid IL or missing references)
			//IL_0136: Unknown result type (might be due to invalid IL or missing references)
			//IL_013c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0141: Unknown result type (might be due to invalid IL or missing references)
			if (!Find(prefab, effectPath, out var root, out var node))
			{
				return null;
			}
			if (!Find(prefab, relativeTo, out var _, out var node2))
			{
				return null;
			}
			Material[] mats;
			Mesh val = MeshOf(node2, out mats);
			Vector3 position = node2.position;
			if (Object.op_Implicit((Object)(object)val))
			{
				Bounds val2 = Transformed(val.bounds, root.worldToLocalMatrix * node2.localToWorldMatrix);
				((Vector3)(ref position))..ctor(((Bounds)(ref val2)).center.x, ((Bounds)(ref val2)).min.y, ((Bounds)(ref val2)).center.z);
			}
			Vector3 val3 = root.InverseTransformPoint(node.position);
			GameObject val4 = Object.Instantiate<GameObject>(((Component)node).gameObject, parent, false);
			((Object)val4).name = prefab + "_" + ((Object)node).name;
			foreach (Component item in from c in val4.GetComponentsInChildren<Component>(true)
				where !(c is Transform) && !(c is ParticleSystem) && !(c is ParticleSystemRenderer) && !(c is Light) && !(c is LightFlicker) && !(c is LightLod)
				select c)
			{
				Object.DestroyImmediate((Object)(object)item);
			}
			val4.transform.localPosition = anchor + (val3 - position);
			val4.transform.localRotation = Quaternion.Inverse(root.rotation) * node.rotation;
			return val4.transform;
		}

		public static string EffectPathUnder(string prefab, string underPath)
		{
			//IL_001e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0024: Expected O, but got Unknown
			if (!Find(prefab, underPath, out var _, out var node))
			{
				return null;
			}
			foreach (Transform item in node)
			{
				Transform val = item;
				if (Object.op_Implicit((Object)(object)((Component)val).GetComponentInChildren<ParticleSystem>(true)) || Object.op_Implicit((Object)(object)((Component)val).GetComponentInChildren<Light>(true)))
				{
					return string.IsNullOrEmpty(underPath) ? ((Object)val).name : (underPath + "/" + ((Object)val).name);
				}
			}
			Plugin.Log.LogWarning((object)("Kitbash: no effect under '" + prefab + "/" + underPath + "'"));
			return null;
		}

		public static Material Tinted(Material src, Color tint, string name)
		{
			//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_000e: Expected O, but got Unknown
			//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_0023: Unknown result type (might be due to invalid IL or missing references)
			Material val = new Material(src)
			{
				name = name
			};
			if (val.HasProperty("_Color"))
			{
				val.color *= tint;
			}
			return val;
		}

		public static Material Matte(Material src, Color tint, string name, float smoothness = 0.12f)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			Material val = Tinted(src, tint, name);
			if (val.HasProperty("_Glossiness"))
			{
				val.SetFloat("_Glossiness", smoothness);
			}
			if (val.HasProperty("_GlossMapScale"))
			{
				val.SetFloat("_GlossMapScale", smoothness);
			}
			if (val.HasProperty("_Metallic"))
			{
				val.SetFloat("_Metallic", 0f);
			}
			return val;
		}

		public static void ClearVisuals(Transform t)
		{
			foreach (Transform item in ((IEnumerable)t).Cast<Transform>().ToList())
			{
				Object.DestroyImmediate((Object)(object)((Component)item).gameObject);
			}
			MeshRenderer[] components = ((Component)t).GetComponents<MeshRenderer>();
			for (int i = 0; i < components.Length; i++)
			{
				Object.DestroyImmediate((Object)(object)components[i]);
			}
			SkinnedMeshRenderer[] components2 = ((Component)t).GetComponents<SkinnedMeshRenderer>();
			for (int i = 0; i < components2.Length; i++)
			{
				Object.DestroyImmediate((Object)(object)components2[i]);
			}
			MeshFilter[] components3 = ((Component)t).GetComponents<MeshFilter>();
			for (int i = 0; i < components3.Length; i++)
			{
				Object.DestroyImmediate((Object)(object)components3[i]);
			}
			Collider[] components4 = ((Component)t).GetComponents<Collider>();
			for (int i = 0; i < components4.Length; i++)
			{
				Object.DestroyImmediate((Object)(object)components4[i]);
			}
		}
	}
	internal static class Loc
	{
		public static void Register()
		{
			CustomLocalization localization = LocalizationManager.Instance.GetLocalization();
			string text = "English";
			localization.AddTranslation(ref text, new Dictionary<string, string>
			{
				{ "item_thrift_trashbag", "Trash Bag" },
				{ "item_thrift_trashbag_desc", "Use it to open. Everything left inside is destroyed for good when you close it. Protected items (see config) are returned." },
				{ "piece_thrift_altar", "Altar of Thrift" },
				{ "piece_thrift_altar_desc", "Offer trophies and metals to master Resource Thrift." },
				{ "skill_thrift", "Resource Thrift" },
				{ "skill_thrift_desc", "Cheaper crafting and upgrades at stations. Raised only at the Altar of Thrift." },
				{ "thrift_level", "Resource Thrift: level {0}/{1}, discount {2}%" },
				{ "thrift_next", "Level {0}: discount {1}%" },
				{ "thrift_next_free", "Level {0}: discount {1}% + {2}% chance of a free craft" },
				{ "thrift_max", "Mastered" },
				{ "thrift_offer", "Make an offering" },
				{ "thrift_missing", "The altar demands more" },
				{ "thrift_levelup", "Resource Thrift raised to level {0}" },
				{ "thrift_freecraft", "Thrift: free craft!" },
				{ "thrift_trash_deleted", "Trash bag: {0} items destroyed" },
				{ "thrift_trash_protected", "Protected item, returned: {0}" }
			});
			text = "Russian";
			localization.AddTranslation(ref text, new Dictionary<string, string>
			{
				{ "item_thrift_trashbag", "Сумка для мусора" },
				{ "item_thrift_trashbag_desc", "Используйте, чтобы открыть. Всё, что останется внутри, безвозвратно исчезнет при закрытии. Защищённые предметы (см. конфиг) возвращаются." },
				{ "piece_thrift_altar", "Алтарь бережливости" },
				{ "piece_thrift_altar_desc", "Принесите трофеи и металлы, чтобы освоить «Экономию ресурсов»." },
				{ "skill_thrift", "Экономия ресурсов" },
				{ "skill_thrift_desc", "Дешевле крафт и улучшения на станциях. Повышается только у Алтаря бережливости." },
				{ "thrift_level", "Экономия ресурсов: уровень {0}/{1}, скидка {2}%" },
				{ "thrift_next", "Уровень {0}: скидка {1}%" },
				{ "thrift_next_free", "Уровень {0}: скидка {1}% + {2}% шанс бесплатного крафта" },
				{ "thrift_max", "Навык освоен полностью" },
				{ "thrift_offer", "Принести дар" },
				{ "thrift_missing", "Алтарю нужно больше" },
				{ "thrift_levelup", "Экономия ресурсов: уровень {0}" },
				{ "thrift_freecraft", "Бережливость: бесплатный крафт!" },
				{ "thrift_trash_deleted", "Сумка для мусора: уничтожено предметов: {0}" },
				{ "thrift_trash_protected", "Защищённый предмет возвращён: {0}" }
			});
		}

		public static string T(string token, params object[] args)
		{
			string text = Localization.instance.Localize("$" + token);
			if (args.Length != 0)
			{
				return string.Format(text, args);
			}
			return text;
		}
	}
	internal struct ResourceCost
	{
		public string Prefab;

		public int Amount;
	}
	internal static class ModConfig
	{
		public const int MaxLevel = 5;

		private static ConfigEntry<string> _protectedItems;

		public static ConfigEntry<int> TrashWidth;

		public static ConfigEntry<int> TrashHeight;

		private static readonly ConfigEntry<int>[] _discount = new ConfigEntry<int>[6];

		private static readonly ConfigEntry<string>[] _requirements = new ConfigEntry<string>[6];

		public static ConfigEntry<float> FreeCraftChance;

		private static readonly int[] DefaultDiscount = new int[6] { 0, 20, 40, 60, 80, 80 };

		private static readonly string[] DefaultRequirements = new string[6] { "", "TrophyTheElder:1, Bronze:20", "TrophyBonemass:1, Iron:20, Silver:10", "TrophyDragonQueen:1, Silver:30, BlackMetal:20", "TrophySeekerQueen:1, BlackMetal:30, Eitr:20", "TrophyFader:1, FlametalNew:20" };

		private const string DefaultProtected = "TrophyEikthyr, TrophyTheElder, TrophyBonemass, TrophyDragonQueen, TrophyGoblinKing, TrophySeekerQueen, TrophyFader, HardAntler, CryptKey, Wishbone, DragonTear, YagluthDrop, QueenDrop, FaderDrop, DragonEgg, Thunderstone, Demister, BeltStrength";

		private static HashSet<string> _protectedSet = new HashSet<string>(StringComparer.OrdinalIgnoreCase);

		public static void Bind(ConfigFile cfg)
		{
			//IL_006a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0074: Expected O, but got Unknown
			//IL_0096: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a0: Expected O, but got Unknown
			//IL_00ec: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f6: Expected O, but got Unknown
			//IL_011f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0129: Expected O, but got Unknown
			//IL_0167: Unknown result type (might be due to invalid IL or missing references)
			//IL_0171: Expected O, but got Unknown
			_protectedItems = cfg.Bind<string>("1 - Trash bag", "ProtectedItems", "TrophyEikthyr, TrophyTheElder, TrophyBonemass, TrophyDragonQueen, TrophyGoblinKing, TrophySeekerQueen, TrophyFader, HardAntler, CryptKey, Wishbone, DragonTear, YagluthDrop, QueenDrop, FaderDrop, DragonEgg, Thunderstone, Demister, BeltStrength", "Comma-separated prefab names the trash bag will never delete. Protected items are pushed back to your inventory (or dropped at your feet if it is full). The trash bag itself is always protected.");
			_protectedItems.SettingChanged += delegate
			{
				RebuildProtected();
			};
			RebuildProtected();
			TrashWidth = cfg.Bind<int>("1 - Trash bag", "Width", 6, new ConfigDescription("Columns in the trash bag window.", (AcceptableValueBase)(object)new AcceptableValueRange<int>(1, 8), Array.Empty<object>()));
			TrashHeight = cfg.Bind<int>("1 - Trash bag", "Height", 3, new ConfigDescription("Rows in the trash bag window.", (AcceptableValueBase)(object)new AcceptableValueRange<int>(1, 6), Array.Empty<object>()));
			for (int num = 1; num <= 5; num++)
			{
				string text = $"2 - Thrift level {num}";
				_discount[num] = cfg.Bind<int>(text, "DiscountPercent", DefaultDiscount[num], new ConfigDescription("Crafting/upgrade cost discount at this level (rounded up, minimum 1).", (AcceptableValueBase)(object)new AcceptableValueRange<int>(0, 95), new object[1] { AdminOnly() }));
				_requirements[num] = cfg.Bind<string>(text, "Requirements", DefaultRequirements[num], new ConfigDescription("Offering needed at the Altar of Thrift to reach this level: Prefab:Amount, ...", (AcceptableValueBase)null, new object[1] { AdminOnly() }));
			}
			FreeCraftChance = cfg.Bind<float>("2 - Thrift level 5", "FreeCraftChance", 0.1f, new ConfigDescription("Chance (0-1) that a craft or upgrade costs nothing at max level.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 1f), new object[1] { AdminOnly() }));
		}

		private static ConfigurationManagerAttributes AdminOnly()
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			//IL_000d: Expected O, but got Unknown
			return new ConfigurationManagerAttributes
			{
				IsAdminOnly = true
			};
		}

		private static void RebuildProtected()
		{
			_protectedSet = new HashSet<string>(from s in _protectedItems.Value.Split(new char[1] { ',' })
				select s.Trim() into s
				where s.Length > 0
				select s, StringComparer.OrdinalIgnoreCase);
		}

		public static bool IsProtected(ItemData item)
		{
			if (item == null)
			{
				return false;
			}
			if (item.m_shared.m_name == "$item_thrift_trashbag")
			{
				return true;
			}
			string text = (Object.op_Implicit((Object)(object)item.m_dropPrefab) ? ((Object)item.m_dropPrefab).name : null);
			if (text == null || !_protectedSet.Contains(text))
			{
				return _protectedSet.Contains(item.m_shared.m_name);
			}
			return true;
		}

		public static int DiscountPercent(int level)
		{
			if (level <= 0)
			{
				return 0;
			}
			return _discount[Math.Min(level, 5)].Value;
		}

		public static List<ResourceCost> Requirements(int level)
		{
			List<ResourceCost> list = new List<ResourceCost>();
			if (level < 1 || level > 5)
			{
				return list;
			}
			string[] array = _requirements[level].Value.Split(new char[1] { ',' });
			for (int i = 0; i < array.Length; i++)
			{
				string[] array2 = array[i].Split(new char[1] { ':' });
				string text = array2[0].Trim();
				if (text.Length != 0)
				{
					int result = 1;
					if (array2.Length > 1 && !int.TryParse(array2[1].Trim(), out result))
					{
						result = 1;
					}
					list.Add(new ResourceCost
					{
						Prefab = text,
						Amount = Math.Max(1, result)
					});
				}
			}
			return list;
		}

		public static void ValidatePrefabNames()
		{
			List<string> list = new List<string>();
			for (int i = 1; i <= 5; i++)
			{
				list.AddRange(from r in Requirements(i)
					select r.Prefab);
			}
			list.AddRange(_protectedSet);
			foreach (string item in list.Distinct())
			{
				if ((Object)(object)ObjectDB.instance.GetItemPrefab(item) == (Object)null)
				{
					Plugin.Log.LogWarning((object)("Unknown item prefab in config: '" + item + "'"));
				}
			}
			Plugin.Log.LogInfo((object)"Config prefab names validated");
		}
	}
	[BepInPlugin("com.tokir.thrift", "Thrift", "1.0.0")]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[NetworkCompatibility(/*Could not decode attribute arguments.*/)]
	public class Plugin : BaseUnityPlugin
	{
		public const string ModGuid = "com.tokir.thrift";

		public const string ModName = "Thrift";

		public const string ModVersion = "1.0.0";

		internal static ManualLogSource Log;

		private void Awake()
		{
			//IL_0056: Unknown result type (might be due to invalid IL or missing references)
			Log = ((BaseUnityPlugin)this).Logger;
			ModConfig.Bind(((BaseUnityPlugin)this).Config);
			Loc.Register();
			ThriftSkill.Register();
			PrefabManager.OnVanillaPrefabsAvailable += AddContent;
			ItemManager.OnItemsRegistered += ModConfig.ValidatePrefabNames;
			new Harmony("com.tokir.thrift").PatchAll(typeof(Plugin).Assembly);
			Log.LogInfo((object)"Thrift 1.0.0 loaded");
		}

		private void AddContent()
		{
			PrefabManager.OnVanillaPrefabsAvailable -= AddContent;
			TrashBag.AddItem();
			ThriftAltar.AddPiece();
			ThriftSkill.SetRenderedIcon();
		}
	}
	internal class ThriftAltar : MonoBehaviour, Hoverable, Interactable
	{
		public const string PrefabName = "Thrift_Altar";

		private const string BasePrefab = "piece_artisanstation";

		public static void AddPiece()
		{
			//IL_000a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0010: Expected O, but got Unknown
			//IL_0059: Unknown result type (might be due to invalid IL or missing references)
			//IL_005f: Expected O, but got Unknown
			//IL_006a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0070: Expected O, but got Unknown
			//IL_007a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0080: Expected O, but got Unknown
			//IL_0086: Unknown result type (might be due to invalid IL or missing references)
			//IL_008c: Expected O, but got Unknown
			PieceConfig val = new PieceConfig();
			val.Name = "$piece_thrift_altar";
			val.Description = "$piece_thrift_altar_desc";
			val.PieceTable = PieceTables.Hammer;
			val.Category = PieceCategories.Crafting;
			val.CraftingStation = CraftingStations.Workbench;
			val.Requirements = (RequirementConfig[])(object)new RequirementConfig[3]
			{
				new RequirementConfig("Stone", 20, 0, true),
				new RequirementConfig("FineWood", 10, 0, true),
				new RequirementConfig("Bronze", 5, 0, true)
			};
			CustomPiece val2 = new CustomPiece("Thrift_Altar", "piece_artisanstation", val);
			CraftingStation[] componentsInChildren = val2.PiecePrefab.GetComponentsInChildren<CraftingStation>(true);
			for (int i = 0; i < componentsInChildren.Length; i++)
			{
				Object.DestroyImmediate((Object)(object)componentsInChildren[i]);
			}
			Visuals.BuildAltar(val2.PiecePrefab);
			Sprite val3 = Visuals.RenderIcon(val2.PiecePrefab);
			if (Object.op_Implicit((Object)(object)val3))
			{
				val2.Piece.m_icon = val3;
			}
			val2.PiecePrefab.AddComponent<ThriftAltar>();
			PieceManager.Instance.AddPiece(val2);
		}

		public string GetHoverName()
		{
			return Localization.instance.Localize("$piece_thrift_altar");
		}

		public float GetHoverOffset()
		{
			return 0f;
		}

		public string GetHoverText()
		{
			Player localPlayer = Player.m_localPlayer;
			if (!Object.op_Implicit((Object)(object)localPlayer))
			{
				return GetHoverName();
			}
			int level = ThriftSkill.GetLevel(localPlayer);
			StringBuilder stringBuilder = new StringBuilder();
			stringBuilder.AppendLine(GetHoverName());
			stringBuilder.AppendLine(Loc.T("thrift_level", level, 5, ModConfig.DiscountPercent(level)));
			if (level >= 5)
			{
				stringBuilder.Append("<color=orange>").Append(Loc.T("thrift_max")).Append("</color>");
				return stringBuilder.ToString();
			}
			int num = level + 1;
			stringBuilder.AppendLine((num == 5) ? Loc.T("thrift_next_free", num, ModConfig.DiscountPercent(num), Mathf.RoundToInt(ModConfig.FreeCraftChance.Value * 100f)) : Loc.T("thrift_next", num, ModConfig.DiscountPercent(num)));
			Inventory inventory = ((Humanoid)localPlayer).GetInventory();
			foreach (ResourceCost item in ModConfig.Requirements(num))
			{
				ItemData val = ItemData(item.Prefab);
				string text = ((val != null) ? Localization.instance.Localize(val.m_shared.m_name) : item.Prefab);
				int num2 = ((val != null) ? inventory.CountItems(val.m_shared.m_name, -1, true) : 0);
				string text2 = ((num2 >= item.Amount) ? "white" : "red");
				stringBuilder.AppendLine($"  <color={text2}>{text} {num2}/{item.Amount}</color>");
			}
			stringBuilder.Append(Localization.instance.Localize("[<color=yellow><b>$KEY_Use</b></color>] ")).Append(Loc.T("thrift_offer"));
			return stringBuilder.ToString();
		}

		public bool Interact(Humanoid user, bool hold, bool alt)
		{
			//IL_0143: 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_0161: Unknown result type (might be due to invalid IL or missing references)
			//IL_0167: Unknown result type (might be due to invalid IL or missing references)
			if (hold)
			{
				return false;
			}
			Player val = (Player)(object)((user is Player) ? user : null);
			if (!Object.op_Implicit((Object)(object)val) || (Object)(object)val != (Object)(object)Player.m_localPlayer)
			{
				return false;
			}
			int level = ThriftSkill.GetLevel(val);
			if (level >= 5)
			{
				return false;
			}
			int num = level + 1;
			List<ResourceCost> list = ModConfig.Requirements(num);
			Inventory inventory = ((Humanoid)val).GetInventory();
			foreach (ResourceCost item in list)
			{
				ItemData val2 = ItemData(item.Prefab);
				if (val2 == null || inventory.CountItems(val2.m_shared.m_name, -1, true) < item.Amount)
				{
					((Character)val).Message((MessageType)2, Loc.T("thrift_missing"), 0, (Sprite)null, false);
					return false;
				}
			}
			foreach (ResourceCost item2 in list)
			{
				inventory.RemoveItem(ItemData(item2.Prefab).m_shared.m_name, item2.Amount, -1, true);
			}
			ThriftSkill.SetLevel(val, num);
			((Character)val).Message((MessageType)2, Loc.T("thrift_levelup", num), 0, (Sprite)null, false);
			val.m_skillLevelupEffects.Create(((Character)val).GetHeadPoint(), ((Component)val).transform.rotation, ((Component)val).transform, 1f, -1, default(ZDOID));
			Plugin.Log.LogInfo((object)$"Resource Thrift raised to {num}");
			return true;
		}

		public bool UseItem(Humanoid user, ItemData item)
		{
			return false;
		}

		private static ItemData ItemData(string prefab)
		{
			GameObject val = (Object.op_Implicit((Object)(object)ObjectDB.instance) ? ObjectDB.instance.GetItemPrefab(prefab) : null);
			if (!Object.op_Implicit((Object)(object)val))
			{
				return null;
			}
			return val.GetComponent<ItemDrop>()?.m_itemData;
		}
	}
	internal static class ThriftSkill
	{
		[HarmonyPatch(typeof(Skills), "RaiseSkill")]
		private static class NoRaise
		{
			private static bool Prefix(SkillType skillType)
			{
				//IL_0000: Unknown result type (might be due to invalid IL or missing references)
				//IL_0001: Unknown result type (might be due to invalid IL or missing references)
				return skillType != Type;
			}
		}

		[HarmonyPatch(typeof(Skills), "LowerAllSkills")]
		private static class NoDeathPenalty
		{
			private static void Prefix(Skills __instance, out float __state)
			{
				//IL_0007: Unknown result type (might be due to invalid IL or missing references)
				__state = (__instance.m_skillData.TryGetValue(Type, out var value) ? value.m_level : (-1f));
			}

			private static void Postfix(Skills __instance, float __state)
			{
				//IL_000e: Unknown result type (might be due to invalid IL or missing references)
				if (__state >= 0f && __instance.m_skillData.TryGetValue(Type, out var value))
				{
					value.m_level = __state;
				}
			}
		}

		public static SkillType Type;

		private static SkillConfig _config;

		public static void Register()
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0005: 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_001b: 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_0031: Unknown result type (might be due to invalid IL or missing references)
			//IL_0041: Expected O, but got Unknown
			//IL_004b: 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)
			_config = new SkillConfig
			{
				Identifier = "com.tokir.thrift.resource_thrift",
				Name = "$skill_thrift",
				Description = "$skill_thrift_desc",
				Icon = Icons.Coin(),
				IncreaseStep = 0f
			};
			Type = SkillManager.Instance.AddSkill(_config);
		}

		public static void SetRenderedIcon()
		{
			Sprite val = Visuals.RenderSkillIcon();
			if (Object.op_Implicit((Object)(object)val))
			{
				_config.Icon = val;
			}
		}

		public static int GetLevel(Player player)
		{
			//IL_0015: Unknown result type (might be due to invalid IL or missing references)
			if (!Object.op_Implicit((Object)(object)player))
			{
				return 0;
			}
			if (!((Character)player).GetSkills().m_skillData.TryGetValue(Type, out var value))
			{
				return 0;
			}
			return Mathf.Clamp(Mathf.FloorToInt(value.m_level), 0, 5);
		}

		public static void SetLevel(Player player, int level)
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			Skill skill = ((Character)player).GetSkills().GetSkill(Type);
			skill.m_level = level;
			skill.m_accumulator = 0f;
		}

		public static int Discounted(int amount, int level)
		{
			int num = ModConfig.DiscountPercent(level);
			if (amount <= 0 || num <= 0)
			{
				return amount;
			}
			return Math.Max(1, (amount * (100 - num) + 99) / 100);
		}
	}
	internal static class CraftScope
	{
		[HarmonyPatch]
		private static class Scoped
		{
			private static IEnumerable<MethodBase> TargetMethods()
			{
				yield return AccessTools.Method(typeof(InventoryGui), "UpdateRecipeList", (Type[])null, (Type[])null);
				yield return AccessTools.Method(typeof(InventoryGui), "UpdateRecipe", (Type[])null, (Type[])null);
				yield return AccessTools.Method(typeof(InventoryGui), "SetupRequirementList", (Type[])null, (Type[])null);
				yield return AccessTools.Method(typeof(InventoryGui), "OnCraftPressed", (Type[])null, (Type[])null);
				yield return AccessTools.Method(typeof(Player), "HaveRequirements", new Type[4]
				{
					typeof(Recipe),
					typeof(bool),
					typeof(int),
					typeof(int)
				}, (Type[])null);
				yield return AccessTools.Method(typeof(Player), "GetFirstRequiredItem", (Type[])null, (Type[])null);
			}

			private static void Prefix(out bool __state)
			{
				__state = true;
				_depth++;
			}

			private static void Finalizer(bool __state)
			{
				if (__state)
				{
					_depth--;
				}
			}
		}

		[HarmonyPatch(typeof(InventoryGui), "DoCrafting")]
		private static class DoCraftingScope
		{
			private static void Prefix(out bool __state)
			{
				__state = true;
				_depth++;
				_craftDepth++;
				FreeCraft = ThriftSkill.GetLevel(Player.m_localPlayer) >= 5 && Random.value < ModConfig.FreeCraftChance.Value;
			}

			private static void Finalizer(bool __state)
			{
				if (__state)
				{
					_depth--;
					_craftDepth--;
					FreeCraft = false;
				}
			}
		}

		[HarmonyPatch(typeof(Requirement), "GetAmount")]
		private static class DiscountAmount
		{
			private static void Postfix(ref int __result)
			{
				if (Active && __result > 0)
				{
					__result = ThriftSkill.Discounted(__result, ThriftSkill.GetLevel(Player.m_localPlayer));
				}
			}
		}

		[HarmonyPatch(typeof(Player), "ConsumeResources")]
		private static class FreeCraftSkip
		{
			private static bool Prefix(Player __instance)
			{
				if (!InDoCrafting || !FreeCraft || (Object)(object)__instance != (Object)(object)Player.m_localPlayer)
				{
					return true;
				}
				((Character)__instance).Message((MessageType)2, Loc.T("thrift_freecraft"), 0, (Sprite)null, false);
				Plugin.Log.LogInfo((object)"Free craft triggered, resources not consumed");
				return false;
			}
		}

		private static int _depth;

		private static int _craftDepth;

		public static bool FreeCraft;

		public static bool Active => _depth > 0;

		public static bool InDoCrafting => _craftDepth > 0;
	}
	internal static class Icons
	{
		public static Sprite Coin()
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_000c: Expected O, but got Unknown
			//IL_00d9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e8: 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_005e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0066: Unknown result type (might be due to invalid IL or missing references)
			//IL_006b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0076: Unknown result type (might be due to invalid IL or missing references)
			//IL_0077: Unknown result type (might be due to invalid IL or missing references)
			//IL_0082: Unknown result type (might be due to invalid IL or missing references)
			//IL_0083: Unknown result type (might be due to invalid IL or missing references)
			//IL_009f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0097: 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)
			Texture2D val = new Texture2D(64, 64, (TextureFormat)4, false);
			Color val2 = default(Color);
			((Color)(ref val2))..ctor(0.95f, 0.75f, 0.2f);
			Color val3 = default(Color);
			((Color)(ref val3))..ctor(0.6f, 0.42f, 0.08f);
			Vector2 val4 = default(Vector2);
			((Vector2)(ref val4))..ctor(31.5f, 31.5f);
			for (int i = 0; i < 64; i++)
			{
				for (int j = 0; j < 64; j++)
				{
					float num = Vector2.Distance(new Vector2((float)j, (float)i), val4);
					Color val5 = Color.clear;
					if (num < 28f)
					{
						val5 = val3;
					}
					if (num < 24f)
					{
						val5 = val2;
					}
					if (num < 14f && num > 10f)
					{
						val5 = val3;
					}
					val.SetPixel(j, i, val5);
				}
			}
			val.Apply();
			return Sprite.Create(val, new Rect(0f, 0f, 64f, 64f), new Vector2(0.5f, 0.5f));
		}
	}
	internal static class TrashBag
	{
		[HarmonyPatch(typeof(Humanoid), "UseItem")]
		private static class UseItemPatch
		{
			private static bool Prefix(Humanoid __instance, ItemData item)
			{
				if (item == null || item.m_shared.m_name != "$item_thrift_trashbag")
				{
					return true;
				}
				if ((Object)(object)__instance != (Object)(object)Player.m_localPlayer)
				{
					return true;
				}
				Open(Player.m_localPlayer);
				return false;
			}
		}

		[HarmonyPatch(typeof(InventoryGui), "CloseContainer")]
		private static class ClosePatch
		{
			private static void Prefix(InventoryGui __instance)
			{
				if (IsProxy(__instance.m_currentContainer))
				{
					Purge(__instance.m_currentContainer);
				}
			}
		}

		[HarmonyPatch(typeof(InventoryGui), "Hide")]
		private static class HidePatch
		{
			private static void Prefix(InventoryGui __instance)
			{
				if (IsProxy(__instance.m_currentContainer))
				{
					Purge(__instance.m_currentContainer);
				}
			}
		}

		[HarmonyPatch(typeof(InventoryGui), "Show")]
		private static class ShowPatch
		{
			private static void Prefix(InventoryGui __instance, Container container)
			{
				Container currentContainer = __instance.m_currentContainer;
				if (IsProxy(currentContainer) && (Object)(object)currentContainer != (Object)(object)container)
				{
					Purge(currentContainer);
				}
			}
		}

		[HarmonyPatch(typeof(Container), "Awake")]
		private static class AwakePatch
		{
			[HarmonyPriority(800)]
			private static bool Prefix(Container __instance)
			{
				return !IsProxy(__instance);
			}
		}

		[HarmonyPatch(typeof(Container), "IsOwner")]
		private static class IsOwnerPatch
		{
			private static bool Prefix(Container __instance, ref bool __result)
			{
				if (!IsProxy(__instance))
				{
					return true;
				}
				__result = true;
				return false;
			}
		}

		[HarmonyPatch(typeof(Container), "SetInUse")]
		private static class SetInUsePatch
		{
			private static bool Prefix(Container __instance)
			{
				return !IsProxy(__instance);
			}
		}

		[HarmonyPatch(typeof(Container), "CheckAccess")]
		private static class CheckAccessPatch
		{
			private static bool Prefix(Container __instance, ref bool __result)
			{
				if (!IsProxy(__instance))
				{
					return true;
				}
				__result = true;
				return false;
			}
		}

		[HarmonyPatch(typeof(Container), "StackAll")]
		private static class StackAllPatch
		{
			private static bool Prefix(Container __instance)
			{
				if (!IsProxy(__instance))
				{
					return true;
				}
				if (Object.op_Implicit((Object)(object)Player.m_localPlayer))
				{
					__instance.GetInventory().StackAll(((Humanoid)Player.m_localPlayer).GetInventory(), false);
				}
				return false;
			}
		}

		[HarmonyPatch(typeof(Container), "Save")]
		private static class SavePatch
		{
			private static bool Prefix(Container __instance)
			{
				return !IsProxy(__instance);
			}
		}

		public const string PrefabName = "Thrift_TrashBag";

		public const string ItemToken = "$item_thrift_trashbag";

		private const string ProxyName = "Thrift_TrashProxy";

		public static void AddItem()
		{
			//IL_000a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0010: Expected O, but got Unknown
			//IL_0049: Unknown result type (might be due to invalid IL or missing references)
			//IL_004f: Expected O, but got Unknown
			//IL_0059: Unknown result type (might be due to invalid IL or missing references)
			//IL_005f: Expected O, but got Unknown
			//IL_0069: Unknown result type (might be due to invalid IL or missing references)
			//IL_006f: Expected O, but got Unknown
			//IL_0075: Unknown result type (might be due to invalid IL or missing references)
			//IL_007b: Expected O, but got Unknown
			//IL_008f: Unknown result type (might be due to invalid IL or missing references)
			ItemConfig val = new ItemConfig();
			val.Name = "$item_thrift_trashbag";
			val.Description = "$item_thrift_trashbag_desc";
			val.CraftingStation = CraftingStations.Workbench;
			val.MinStationLevel = 1;
			val.Requirements = (RequirementConfig[])(object)new RequirementConfig[3]
			{
				new RequirementConfig("LeatherScraps", 6, 0, true),
				new RequirementConfig("DeerHide", 2, 0, true),
				new RequirementConfig("Resin", 4, 0, true)
			};
			CustomItem val2 = new CustomItem("Thrift_TrashBag", "LeatherScraps", val);
			SharedData shared = val2.ItemDrop.m_itemData.m_shared;
			shared.m_itemType = (ItemType)16;
			shared.m_maxStackSize = 1;
			shared.m_weight = 1f;
			shared.m_teleportable = true;
			Visuals.BuildBag(val2.ItemPrefab);
			Sprite val3 = Visuals.RenderIcon(val2.ItemPrefab);
			if (Object.op_Implicit((Object)(object)val3))
			{
				shared.m_icons = (Sprite[])(object)new Sprite[1] { val3 };
			}
			ItemManager.Instance.AddItem(val2);
		}

		public static bool IsProxy(Container c)
		{
			if (Object.op_Implicit((Object)(object)c))
			{
				return ((Object)((Component)c).gameObject).name == "Thrift_TrashProxy";
			}
			return false;
		}

		private static Container GetProxy(Player player, bool create)
		{
			//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_0036: 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_008d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0097: Expected O, but got Unknown
			//IL_0097: Unknown result type (might be due to invalid IL or missing references)
			Transform val = ((Component)player).transform.Find("Thrift_TrashProxy");
			if (Object.op_Implicit((Object)(object)val))
			{
				return ((Component)val).GetComponent<Container>();
			}
			if (!create)
			{
				return null;
			}
			GameObject val2 = new GameObject("Thrift_TrashProxy");
			val2.SetActive(false);
			val2.transform.SetParent(((Component)player).transform, false);
			Container val3 = val2.AddComponent<Container>();
			val3.m_name = "$item_thrift_trashbag";
			val3.m_width = ModConfig.TrashWidth.Value;
			val3.m_height = ModConfig.TrashHeight.Value;
			val3.m_inventory = new Inventory("$item_thrift_trashbag", (Sprite)null, val3.m_width, val3.m_height);
			val2.AddComponent<TrashProxy>().Init(val3);
			val2.SetActive(true);
			return val3;
		}

		public static void Open(Player player)
		{
			InventoryGui instance = InventoryGui.instance;
			if (!Object.op_Implicit((Object)(object)instance) || !Object.op_Implicit((Object)(object)player))
			{
				return;
			}
			Container proxy = GetProxy(player, create: true);
			if (!((Object)(object)instance.m_currentContainer == (Object)(object)proxy))
			{
				if (Object.op_Implicit((Object)(object)instance.m_currentContainer))
				{
					instance.CloseContainer();
				}
				instance.Show(proxy, 1);
				Plugin.Log.LogInfo((object)"Trash bag opened");
			}
		}

		public static void Purge(Container proxy)
		{
			Inventory inventory = proxy.GetInventory();
			Player localPlayer = Player.m_localPlayer;
			if (inventory == null || inventory.NrOfItems() == 0)
			{
				return;
			}
			int num = 0;
			List<string> list = new List<string>();
			foreach (ItemData item in inventory.GetAllItems().ToList())
			{
				if (ModConfig.IsProtected(item))
				{
					ReturnToPlayer(localPlayer, item);
					continue;
				}
				num += item.m_stack;
				GameObject dropPrefab = item.m_dropPrefab;
				list.Add($"{((dropPrefab != null) ? ((Object)dropPrefab).name : null) ?? item.m_shared.m_name} x{item.m_stack}");
			}
			inventory.RemoveAll();
			if (num > 0)
			{
				Plugin.Log.LogInfo((object)("Trash bag destroyed: " + string.Join(", ", list)));
				if (localPlayer != null)
				{
					((Character)localPlayer).Message((MessageType)1, Loc.T("thrift_trash_deleted", num), 0, (Sprite)null, false);
				}
			}
		}

		public static void ReturnToPlayer(Player player, ItemData item)
		{
			//IL_0053: Unknown result type (might be due to invalid IL or missing references)
			//IL_005e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0063: Unknown result type (might be due to invalid IL or missing references)
			//IL_0068: Unknown result type (might be due to invalid IL or missing references)
			//IL_006d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0072: Unknown result type (might be due to invalid IL or missing references)
			//IL_007a: Unknown result type (might be due to invalid IL or missing references)
			//IL_007b: Unknown result type (might be due to invalid IL or missing references)
			if (Object.op_Implicit((Object)(object)player))
			{
				string text = Localization.instance.Localize(item.m_shared.m_name);
				Container proxy = GetProxy(player, create: false);
				Inventory obj = ((proxy != null) ? proxy.GetInventory() : null);
				if (obj != null)
				{
					obj.RemoveItem(item);
				}
				if (!((Humanoid)player).GetInventory().AddItem(item))
				{
					Vector3 val = ((Component)player).transform.position + ((Component)player).transform.forward + Vector3.up;
					ItemDrop.DropItem(item, item.m_stack, val, Quaternion.identity);
				}
				((Character)player).Message((MessageType)2, Loc.T("thrift_trash_protected", text), 0, (Sprite)null, false);
				ManualLogSource log = Plugin.Log;
				GameObject dropPrefab = item.m_dropPrefab;
				log.LogInfo((object)("Protected item returned from trash bag: " + (((dropPrefab != null) ? ((Object)dropPrefab).name : null) ?? item.m_shared.m_name)));
			}
		}
	}
	internal class TrashProxy : MonoBehaviour
	{
		private Container _container;

		private bool _dirty;

		public void Init(Container c)
		{
			_container = c;
			Inventory inventory = c.GetInventory();
			inventory.m_onChanged = (Action)Delegate.Combine(inventory.m_onChanged, (Action)delegate
			{
				_dirty = true;
			});
		}

		private void LateUpdate()
		{
			if (!_dirty || !Object.op_Implicit((Object)(object)_container))
			{
				return;
			}
			_dirty = false;
			if (Object.op_Implicit((Object)(object)InventoryGui.instance) && Object.op_Implicit((Object)(object)InventoryGui.instance.m_dragGo))
			{
				_dirty = true;
				return;
			}
			foreach (ItemData item in _container.GetInventory().GetAllItems().ToList())
			{
				if (ModConfig.IsProtected(item))
				{
					TrashBag.ReturnToPlayer(Player.m_localPlayer, item);
				}
			}
		}
	}
	internal static class Visuals
	{
		private static Material _leather;

		private static Material Leather()
		{
			//IL_0066: Unknown result type (might be due to invalid IL or missing references)
			if (Object.op_Implicit((Object)(object)_leather))
			{
				return _leather;
			}
			GameObject obj = Kitbash.Source("Bilebag");
			object obj2;
			if (obj == null)
			{
				obj2 = null;
			}
			else
			{
				Transform obj3 = obj.transform.Find("default");
				if (obj3 == null)
				{
					obj2 = null;
				}
				else
				{
					MeshRenderer component = ((Component)obj3).GetComponent<MeshRenderer>();
					obj2 = ((component != null) ? ((Renderer)component).sharedMaterial : null);
				}
			}
			Material val = (Material)obj2;
			_leather = (Object.op_Implicit((Object)(object)val) ? Kitbash.Matte(val, new Color(0.5f, 0.36f, 0.27f), "thrift_leather") : null);
			return _leather;
		}

		public static void BuildBag(GameObject itemPrefab)
		{
			//IL_0012: Unknown result type (might be due to invalid IL or missing references)
			//IL_003a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0044: 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_0073: Unknown result type (might be due to invalid IL or missing references)
			Transform transform = itemPrefab.transform;
			Kitbash.ClearVisuals(transform);
			Transform transform2 = new GameObject("attach").transform;
			((Component)transform2).gameObject.layer = ((Component)transform).gameObject.layer;
			transform2.SetParent(transform, false);
			AddBagMesh(transform2, Vector3.down * 0.2f, 0.4f);
			BoxCollider obj = itemPrefab.AddComponent<BoxCollider>();
			obj.size = new Vector3(0.5f, 0.4f, 0.5f);
			obj.center = Vector3.zero;
		}

		private static void AddBagMesh(Transform parent, Vector3 anchor, float height)
		{
			//IL_0029: Unknown result type (might be due to invalid IL or missing references)
			Material[] materials = (Material[])(object)((!Object.op_Implicit((Object)(object)Leather())) ? null : new Material[1] { Leather() });
			Kitbash.Part(parent, "Bilebag", "default", anchor, new Kitbash.Fit
			{
				Height = height
			}, null, materials, "sack");
		}

		public static void BuildAltar(GameObject piecePrefab)
		{
			//IL_0012: 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_00dc: Unknown result type (might be due to invalid IL or missing references)
			//IL_0121: Unknown result type (might be due to invalid IL or missing references)
			//IL_015c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0182: Unknown result type (might be due to invalid IL or missing references)
			//IL_0187: Unknown result type (might be due to invalid IL or missing references)
			//IL_019d: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a2: 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)
			//IL_01bd: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d3: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d8: Unknown result type (might be due to invalid IL or missing references)
			//IL_01e8: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ed: Unknown result type (might be due to invalid IL or missing references)
			//IL_01fa: Unknown result type (might be due to invalid IL or missing references)
			//IL_0232: Unknown result type (might be due to invalid IL or missing references)
			//IL_024d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0252: Unknown result type (might be due to invalid IL or missing references)
			//IL_025f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0274: Unknown result type (might be due to invalid IL or missing references)
			//IL_029a: Unknown result type (might be due to invalid IL or missing references)
			//IL_02be: Unknown result type (might be due to invalid IL or missing references)
			//IL_02c3: Unknown result type (might be due to invalid IL or missing references)
			//IL_02d4: Unknown result type (might be due to invalid IL or missing references)
			//IL_02f6: Unknown result type (might be due to invalid IL or missing references)
			//IL_030f: Unknown result type (might be due to invalid IL or missing references)
			//IL_034c: Unknown result type (might be due to invalid IL or missing references)
			Transform transform = piecePrefab.transform;
			Kitbash.ClearVisuals(transform);
			Transform transform2 = new GameObject("visual").transform;
			((Component)transform2).gameObject.layer = ((Component)transform).gameObject.layer;
			transform2.SetParent(transform, false);
			GameObject obj = Kitbash.Source("offeraltar_FrozenKing_bossroom");
			object obj2;
			if (obj == null)
			{
				obj2 = null;
			}
			else
			{
				Transform obj3 = obj.transform.Find("altar");
				if (obj3 == null)
				{
					obj2 = null;
				}
				else
				{
					MeshRenderer component = ((Component)obj3).GetComponent<MeshRenderer>();
					obj2 = ((component != null) ? ((Renderer)component).sharedMaterial : null);
				}
			}
			Material val = (Material)obj2;
			Vector3 zero = Vector3.zero;
			Kitbash.Fit fit = new Kitbash.Fit
			{
				Height = 1f
			};
			Material[] materials = (Material[])(object)((!Object.op_Implicit((Object)(object)val)) ? null : new Material[1] { val });
			Kitbash.Part(transform2, "blackmarble_altar_crystal", "new/altar", zero, fit, null, materials, "plinth");
			Kitbash.Part(transform2, "offeraltar_FrozenKing_bossroom", "bowl", new Vector3(0f, 0.99f, 0f), new Kitbash.Fit
			{
				Width = 0.8f
			}, null, null, "bowl");
			Kitbash.Part(transform2, "treasure_pile", "pile/pile", new Vector3(0f, 1.03f, 0f), new Kitbash.Fit
			{
				Width = 0.62f
			}, null, null, "coins");
			AddBagMesh(transform2, new Vector3(0.48f, 0f, 0.52f), 0.32f);
			Vector3[] array = (Vector3[])(object)new Vector3[4]
			{
				new Vector3(0.72f, 0f, 0.72f),
				new Vector3(-0.72f, 0f, 0.72f),
				new Vector3(0.72f, 0f, -0.72f),
				new Vector3(-0.72f, 0f, -0.72f)
			};
			foreach (Vector3 anchor in array)
			{
				Kitbash.Part(transform2, "Candle_resin", "full/stack", anchor, new Kitbash.Fit
				{
					Scale = 1f
				}, null, null, "candle");
				Kitbash.Effect(transform2, "Candle_resin", "high", "full/stack", anchor);
			}
			GameObject val2 = new GameObject("glow");
			val2.transform.SetParent(transform2, false);
			val2.transform.localPosition = new Vector3(0f, 1.35f, 0f);
			Light obj4 = val2.AddComponent<Light>();
			obj4.type = (LightType)2;
			obj4.color = new Color(1f, 0.78f, 0.38f);
			obj4.range = 3.5f;
			obj4.intensity = 1.1f;
			GameObject val3 = new GameObject("collider")
			{
				layer = ((Component)transform).gameObject.layer
			};
			val3.transform.SetParent(transform, false);
			BoxCollider obj5 = val3.AddComponent<BoxCollider>();
			obj5.size = new Vector3(1.3f, 1.2f, 1.3f);
			obj5.center = new Vector3(0f, 0.6f, 0f);
			WearNTear component2 = piecePrefab.GetComponent<WearNTear>();
			if (Object.op_Implicit((Object)(object)component2))
			{
				component2.m_new = (component2.m_worn = (component2.m_broken = ((Component)transform2).gameObject));
				component2.m_materialType = (MaterialType)1;
			}
		}

		public static Sprite RenderIcon(GameObject go, Quaternion? rotation = null)
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_000b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0016: Unknown result type (might be due to invalid IL or missing references)
			//IL_0021: Unknown result type (might be due to invalid IL or missing references)
			//IL_0036: Unknown result type (might be due to invalid IL or missing references)
			//IL_002d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0040: Unknown result type (might be due to invalid IL or missing references)
			//IL_004c: Expected O, but got Unknown
			try
			{
				return RenderManager.Instance.Render(new RenderRequest(go)
				{
					Width = 128,
					Height = 128,
					Rotation = (Quaternion)(((??)rotation) ?? RenderManager.IsometricRotation),
					UseCache = false
				});
			}
			catch (Exception ex)
			{
				Plugin.Log.LogWarning((object)("Icon render failed for " + ((Object)go).name + ": " + ex.Message));
				return null;
			}
		}

		public static Sprite RenderSkillIcon()
		{
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			//IL_000b: Expected O, but got Unknown
			//IL_0031: Unknown result type (might be due to invalid IL or missing references)
			//IL_007a: Unknown result type (might be due to invalid IL or missing references)
			//IL_009e: 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_0112: Unknown result type (might be due to invalid IL or missing references)
			//IL_0131: Unknown result type (might be due to invalid IL or missing references)
			GameObject val = new GameObject("thrift_skill_icon");
			val.SetActive(false);
			Kitbash.Part(val.transform, "bar_gold_stack", "New/objects/model (3)", new Vector3(-0.05f, 0f, -0.15f), new Kitbash.Fit
			{
				Width = 0.55f
			}, null, null, "bar1");
			Kitbash.Part(val.transform, "bar_gold_stack", "New/objects/model (3)", new Vector3(-0.05f, 0.11f, -0.15f), new Kitbash.Fit
			{
				Width = 0.55f
			}, Quaternion.Euler(0f, 25f, 0f), null, "bar2");
			Kitbash.Part(val.transform, "treasure_pile", "pile/pile", new Vector3(0.2f, 0f, 0.15f), new Kitbash.Fit
			{
				Width = 0.55f
			}, null, null, "coins");
			AddBagMesh(val.transform, new Vector3(-0.3f, 0f, 0.25f), 0.42f);
			Sprite result = RenderIcon(val, Quaternion.Euler(20f, -35f, 0f));
			Object.Destroy((Object)(object)val);
			return result;
		}
	}
}
namespace System.Runtime.CompilerServices
{
	[AttributeUsage(AttributeTargets.Assembly, AllowMultiple = true)]
	internal sealed class IgnoresAccessChecksToAttribute : Attribute
	{
		public IgnoresAccessChecksToAttribute(string assemblyName)
		{
		}
	}
}