Decompiled source of PotatoWright v1.0.0

plugins/PotatoWright.dll

Decompiled 6 hours ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.Globalization;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Security;
using System.Security.Permissions;
using System.Text;
using BepInEx;
using BepInEx.Logging;
using HarmonyLib;
using Jotunn.Configs;
using Jotunn.Entities;
using Jotunn.Managers;
using Jotunn.Utils;
using TMPro;
using UnityEngine;
using UnityEngine.Events;
using UnityEngine.Rendering;
using UnityEngine.U2D;
using UnityEngine.UI;
using Valheim.UI;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("0.0.0.0")]
[module: UnverifiableCode]
namespace PotatoWright;

[HarmonyPatch]
public static class MannequinColor
{
	public static readonly int ColorKey = StringExtensionMethods.GetStableHashCode("PotatoWright_woodColor");

	public static readonly int NoBaseKey = StringExtensionMethods.GetStableHashCode("PotatoWright_noBase");

	public const string RpcName = "PotatoWright_Tint";

	private const string SaveKey = "PotatoWright.MannequinWood";

	public static float H;

	public static float S;

	public static float V;

	public static bool ShowBase = true;

	public static int Version;

	private static Player s_loadedFor;

	private static MannequinTint s_target;

	private static readonly List<Renderer> s_hidden = new List<Renderer>();

	private static readonly List<Renderer> s_renderers = new List<Renderer>();

	public static Color Current
	{
		get
		{
			//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_0021: Unknown result type (might be due to invalid IL or missing references)
			Color result = Color.HSVToRGB(H, S, V);
			result.a = 1f;
			return result;
		}
	}

	public static Vector3 ToVector(Color c)
	{
		//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_000c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0012: Unknown result type (might be due to invalid IL or missing references)
		return new Vector3(c.r, c.g, c.b);
	}

	public static Color ToColor(Vector3 v)
	{
		//IL_0000: 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_0026: Unknown result type (might be due to invalid IL or missing references)
		return new Color(Mathf.Clamp01(v.x), Mathf.Clamp01(v.y), Mathf.Clamp01(v.z), 1f);
	}

	public static void Natural()
	{
		//IL_0000: Unknown result type (might be due to invalid IL or missing references)
		Color.RGBToHSV(WoodTint.NaturalColor, ref H, ref S, ref V);
		Version++;
	}

	public static void EnsureLoaded(Player player)
	{
		if ((Object)(object)player == (Object)null || (Object)(object)player == (Object)(object)s_loadedFor)
		{
			return;
		}
		s_loadedFor = player;
		Natural();
		ShowBase = true;
		if (!player.m_customData.TryGetValue("PotatoWright.MannequinWood", out var value) || string.IsNullOrEmpty(value))
		{
			return;
		}
		string[] array = value.Split(';');
		foreach (string text in array)
		{
			int num = text.IndexOf('=');
			if (num > 0 && float.TryParse(text.Substring(num + 1), NumberStyles.Float, CultureInfo.InvariantCulture, out var result))
			{
				switch (text.Substring(0, num))
				{
				case "h":
					H = Mathf.Clamp01(result);
					break;
				case "s":
					S = Mathf.Clamp01(result);
					break;
				case "v":
					V = Mathf.Clamp01(result);
					break;
				case "base":
					ShowBase = result != 0f;
					break;
				}
			}
		}
		Version++;
	}

	public static void Save(Player player)
	{
		Version++;
		if (!((Object)(object)player == (Object)null))
		{
			player.m_customData["PotatoWright.MannequinWood"] = "h=" + H.ToString("0.####", CultureInfo.InvariantCulture) + ";s=" + S.ToString("0.####", CultureInfo.InvariantCulture) + ";v=" + V.ToString("0.####", CultureInfo.InvariantCulture) + ";base=" + (ShowBase ? "1" : "0");
		}
	}

	private static bool IsMannequinGhost(Player player)
	{
		GameObject val = (((Object)(object)player != (Object)null) ? player.m_placementGhost : null);
		if ((Object)(object)val != (Object)null)
		{
			return (Object)(object)val.GetComponent<MannequinTint>() != (Object)null;
		}
		return false;
	}

	[HarmonyPatch(typeof(Player), "UpdatePlacementGhost")]
	[HarmonyPostfix]
	private static void UpdatePlacementGhost_Postfix(Player __instance)
	{
		//IL_00a7: Unknown result type (might be due to invalid IL or missing references)
		if ((Object)(object)__instance != (Object)(object)Player.m_localPlayer)
		{
			return;
		}
		try
		{
			MannequinTint mannequinTint = null;
			Vector3 val = default(Vector3);
			Vector3 val2 = default(Vector3);
			Piece val3 = default(Piece);
			Heightmap val4 = default(Heightmap);
			Collider val5 = default(Collider);
			if (IsMannequinGhost(__instance) && ((Character)__instance).InPlaceMode() && __instance.PieceRayTest(ref val, ref val2, ref val3, ref val4, ref val5, false) && (Object)(object)val3 != (Object)null)
			{
				MannequinTint componentInParent = ((Component)val3).GetComponentInParent<MannequinTint>();
				if ((Object)(object)componentInParent != (Object)null && componentInParent.IsPlaced)
				{
					mannequinTint = componentInParent;
				}
			}
			if ((Object)(object)mannequinTint != (Object)(object)s_target)
			{
				ClearTarget();
				if ((Object)(object)mannequinTint != (Object)null)
				{
					s_target = mannequinTint;
					((Character)__instance).Message((MessageType)2, Text("potatowright_recolor", "Recolor"), 0, (Sprite)null, false);
				}
			}
			if ((Object)(object)s_target != (Object)null)
			{
				s_target.SetPreview(Current);
				HideGhost(__instance.m_placementGhost);
			}
		}
		catch (Exception ex)
		{
			ClearTarget();
			Debug.LogWarning((object)("[PotatoWright] Mannequin recolor check failed: " + ex.Message));
		}
	}

	private static void HideGhost(GameObject ghost)
	{
		s_renderers.Clear();
		ghost.GetComponentsInChildren<Renderer>(s_renderers);
		foreach (Renderer s_renderer in s_renderers)
		{
			if (!s_renderer.forceRenderingOff)
			{
				s_renderer.forceRenderingOff = true;
				s_hidden.Add(s_renderer);
			}
		}
		s_renderers.Clear();
	}

	private static void ClearTarget()
	{
		if ((Object)(object)s_target != (Object)null)
		{
			s_target.SetPreview(null);
		}
		s_target = null;
		foreach (Renderer item in s_hidden)
		{
			if ((Object)(object)item != (Object)null)
			{
				item.forceRenderingOff = false;
			}
		}
		s_hidden.Clear();
	}

	[HarmonyPatch(typeof(Player), "HaveRequirements", new Type[]
	{
		typeof(Piece),
		typeof(RequirementMode)
	})]
	[HarmonyPrefix]
	private static bool HaveRequirements_Prefix(Player __instance, Piece piece, RequirementMode mode, ref bool __result)
	{
		//IL_000d: Unknown result type (might be due to invalid IL or missing references)
		if ((Object)(object)s_target == (Object)null || (int)mode != 0 || (Object)(object)__instance != (Object)(object)Player.m_localPlayer || (Object)(object)piece == (Object)null || (Object)(object)piece != (Object)(object)__instance.GetSelectedPiece() || (Object)(object)((Component)piece).GetComponent<MannequinTint>() == (Object)null)
		{
			return true;
		}
		__result = true;
		return false;
	}

	[HarmonyPatch(typeof(Player), "TryPlacePiece")]
	[HarmonyPrefix]
	private static bool TryPlacePiece_Prefix(Player __instance, ref bool __result)
	{
		//IL_0033: 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)
		try
		{
			if ((Object)(object)s_target == (Object)null || (Object)(object)__instance != (Object)(object)Player.m_localPlayer || !IsMannequinGhost(__instance))
			{
				return true;
			}
			__result = false;
			if (!PrivateArea.CheckAccess(((Component)s_target).transform.position, 0f, true, false))
			{
				((Character)__instance).Message((MessageType)2, "$msg_privatezone", 0, (Sprite)null, false);
				return false;
			}
			s_target.Send(Current);
			return false;
		}
		catch (Exception ex)
		{
			Debug.LogWarning((object)("[PotatoWright] Mannequin recolor failed: " + ex.Message));
			__result = false;
			return false;
		}
	}

	public static string Text(string key, string fallback)
	{
		string text = Localization.instance.Localize("$" + key);
		if (!string.IsNullOrEmpty(text) && !text.Contains(key))
		{
			return text;
		}
		return fallback;
	}
}
[HarmonyPatch]
public sealed class MannequinTint : MonoBehaviour
{
	private static readonly int MainTex = Shader.PropertyToID("_MainTex");

	private static readonly int ChestTex = Shader.PropertyToID("_ChestTex");

	private static readonly int LegsTex = Shader.PropertyToID("_LegsTex");

	private static readonly string[] BaseParts = new string[2] { "Blocks & Switches/block base", "Blocks & Switches/block pose" };

	private bool m_init;

	private Renderer m_body;

	private Renderer m_layer;

	private Renderer[] m_base;

	private bool? m_baseShown;

	private ZNetView m_nview;

	private Texture m_wood;

	private Texture m_cutOut;

	private bool m_placed;

	private bool m_applied;

	private Color m_color = Color.white;

	private bool m_live;

	private string m_key;

	private string m_maskKey;

	private Color? m_preview;

	private Color m_held;

	private float m_holdUntil;

	private uint m_revision = uint.MaxValue;

	private int m_version = -1;

	public bool IsPlaced
	{
		get
		{
			if (m_placed && (Object)(object)m_nview != (Object)null)
			{
				return m_nview.IsValid();
			}
			return false;
		}
	}

	private void ShowBase(bool show)
	{
		if (m_base == null || m_baseShown == show)
		{
			return;
		}
		m_baseShown = show;
		Renderer[] array = m_base;
		foreach (Renderer val in array)
		{
			if ((Object)(object)val != (Object)null)
			{
				val.enabled = show;
			}
		}
	}

	private bool Init()
	{
		if (m_init)
		{
			return (Object)(object)m_layer != (Object)null;
		}
		m_init = true;
		ArmorStand component = ((Component)this).GetComponent<ArmorStand>();
		VisEquipment val = (((Object)(object)component != (Object)null) ? component.m_visEquipment : null);
		m_body = (Renderer)(object)(((Object)(object)val != (Object)null) ? val.m_bodyModel : null);
		Transform val2 = (((Object)(object)m_body != (Object)null) ? ((Component)m_body).transform.parent.Find("PotatoWrightWoodLayer") : null);
		m_layer = (((Object)(object)val2 != (Object)null) ? ((Component)val2).GetComponent<Renderer>() : null);
		Material val3 = (((Object)(object)m_layer != (Object)null) ? m_layer.sharedMaterial : null);
		m_wood = (((Object)(object)val3 != (Object)null && val3.HasProperty(MainTex)) ? val3.GetTexture(MainTex) : null);
		Material val4 = (((Object)(object)m_body != (Object)null) ? m_body.sharedMaterial : null);
		m_cutOut = (((Object)(object)val4 != (Object)null && val4.HasProperty(MainTex)) ? val4.GetTexture(MainTex) : null);
		if ((Object)(object)m_layer == (Object)null || (Object)(object)m_wood == (Object)null)
		{
			m_layer = null;
			return false;
		}
		m_nview = (((Object)(object)component.m_netViewOverride != (Object)null) ? component.m_netViewOverride : ((Component)this).GetComponent<ZNetView>());
		List<Renderer> list = new List<Renderer>();
		string[] baseParts = BaseParts;
		foreach (string text in baseParts)
		{
			Transform val5 = ((Component)this).transform.Find(text);
			Renderer val6 = (((Object)(object)val5 != (Object)null) ? ((Component)val5).GetComponent<Renderer>() : null);
			if ((Object)(object)val6 != (Object)null)
			{
				list.Add(val6);
			}
		}
		m_base = list.ToArray();
		return true;
	}

	private void Start()
	{
		if (Init())
		{
			m_placed = (Object)(object)m_nview != (Object)null && m_nview.IsValid();
			if (m_placed)
			{
				m_nview.Register<Vector3>("PotatoWright_Tint", (Action<long, Vector3>)RPC_Tint);
			}
			MarkPaintDirty();
			Refresh(force: true);
			((MonoBehaviour)this).InvokeRepeating("Tick", Random.Range(0.2f, 1f), m_placed ? 1f : 0.1f);
		}
	}

	private void WeaponCrateStandPaintChanged()
	{
		MarkPaintDirty();
	}

	public void MarkPaintDirty()
	{
		if (!Init() || (Object)(object)m_body == (Object)null)
		{
			return;
		}
		Material material = m_body.material;
		if (!((Object)(object)material == (Object)null) && material.HasProperty(MainTex))
		{
			Texture chest = (material.HasProperty(ChestTex) ? material.GetTexture(ChestTex) : null);
			Texture legs = (material.HasProperty(LegsTex) ? material.GetTexture(LegsTex) : null);
			string key;
			Texture val = (Texture)(object)PaintMask.Acquire(chest, legs, out key);
			if (m_maskKey != null)
			{
				PaintMask.Release(m_maskKey);
			}
			m_maskKey = key;
			material.SetTexture(MainTex, ((Object)(object)val != (Object)null) ? val : m_cutOut);
		}
	}

	[HarmonyPatch(typeof(VisEquipment), "SetChestEquipped")]
	[HarmonyPostfix]
	private static void SetChestEquipped_Postfix(VisEquipment __instance, bool __result)
	{
		PaintChanged(__instance, __result);
	}

	[HarmonyPatch(typeof(VisEquipment), "SetLegEquipped")]
	[HarmonyPostfix]
	private static void SetLegEquipped_Postfix(VisEquipment __instance, bool __result)
	{
		PaintChanged(__instance, __result);
	}

	private static void PaintChanged(VisEquipment vis, bool changed)
	{
		if (!changed || (Object)(object)vis == (Object)null || (vis.m_isPlayer && !vis.m_isArmorStand))
		{
			return;
		}
		try
		{
			MannequinTint componentInParent = ((Component)vis).GetComponentInParent<MannequinTint>();
			if ((Object)(object)componentInParent != (Object)null)
			{
				componentInParent.MarkPaintDirty();
			}
		}
		catch (Exception ex)
		{
			Debug.LogWarning((object)("[PotatoWright] Mannequin paint mask not updated: " + ex.Message));
		}
	}

	private void Tick()
	{
		Refresh(force: false);
	}

	private void Refresh(bool force)
	{
		//IL_0014: 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_0086: 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)
		//IL_00dd: Unknown result type (might be due to invalid IL or missing references)
		//IL_00e2: Unknown result type (might be due to invalid IL or missing references)
		//IL_00e7: Unknown result type (might be due to invalid IL or missing references)
		if (m_preview.HasValue)
		{
			Apply(m_preview.Value, live: true);
		}
		else if (!m_placed)
		{
			if (force || m_version != MannequinColor.Version)
			{
				m_version = MannequinColor.Version;
				Apply(MannequinColor.Current, live: true);
				ShowBase(MannequinColor.ShowBase);
			}
		}
		else
		{
			if ((Object)(object)m_nview == (Object)null || !m_nview.IsValid())
			{
				return;
			}
			if (Time.time < m_holdUntil)
			{
				Apply(m_held, live: false);
				return;
			}
			ZDO zDO = m_nview.GetZDO();
			if (force || zDO.DataRevision != m_revision)
			{
				m_revision = zDO.DataRevision;
				ShowBase(!zDO.GetBool(MannequinColor.NoBaseKey, false));
				Apply(MannequinColor.ToColor(zDO.GetVec3(MannequinColor.ColorKey, MannequinColor.ToVector(WoodTint.NaturalColor))), live: false);
			}
		}
	}

	private void Apply(Color c, bool live)
	{
		//IL_0043: 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_0021: Unknown result type (might be due to invalid IL or missing references)
		//IL_006c: Unknown result type (might be due to invalid IL or missing references)
		//IL_005d: 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_00e6: Unknown result type (might be due to invalid IL or missing references)
		//IL_00e7: Unknown result type (might be due to invalid IL or missing references)
		if ((Object)(object)m_layer == (Object)null || (m_applied && live == m_live && c == m_color && (live || m_key != null || WoodTint.IsNatural(c))))
		{
			return;
		}
		string key = null;
		Texture val = (Texture)(WoodTint.IsNatural(c) ? ((object)m_wood) : ((object)((!live) ? WoodTint.Acquire(m_wood, c, out key) : WoodTint.Live(m_wood, c))));
		if ((Object)(object)val == (Object)null)
		{
			val = m_wood;
			key = null;
		}
		if (m_key != null)
		{
			WoodTint.Release(m_key);
		}
		m_key = key;
		Material[] materials = m_layer.materials;
		foreach (Material val2 in materials)
		{
			if ((Object)(object)val2 != (Object)null && val2.HasProperty(MainTex))
			{
				val2.SetTexture(MainTex, val);
			}
		}
		m_color = c;
		m_live = live;
		m_applied = true;
	}

	public void SetPreview(Color? c)
	{
		m_preview = c;
		Refresh(force: true);
	}

	public void Send(Color c)
	{
		//IL_0018: 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_0041: Unknown result type (might be due to invalid IL or missing references)
		if (IsPlaced)
		{
			Plugin.Debug("Mannequin " + ((Object)this).name + " recolored to " + ColorUtility.ToHtmlStringRGB(c));
			m_nview.InvokeRPC(ZNetView.Everybody, "PotatoWright_Tint", new object[1] { MannequinColor.ToVector(c) });
		}
	}

	private void RPC_Tint(long sender, Vector3 v)
	{
		//IL_0040: Unknown result type (might be due to invalid IL or missing references)
		//IL_0041: Unknown result type (might be due to invalid IL or missing references)
		//IL_0046: 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)
		if (!((Object)(object)m_nview == (Object)null) && m_nview.IsValid())
		{
			if (m_nview.IsOwner())
			{
				m_nview.GetZDO().Set(MannequinColor.ColorKey, v);
			}
			m_held = MannequinColor.ToColor(v);
			m_holdUntil = Time.time + 3f;
			m_revision = uint.MaxValue;
			if (!m_preview.HasValue)
			{
				Refresh(force: true);
			}
		}
	}

	private void OnDestroy()
	{
		if (m_key != null)
		{
			WoodTint.Release(m_key);
			m_key = null;
		}
		if (m_maskKey != null)
		{
			PaintMask.Release(m_maskKey);
			m_maskKey = null;
		}
		DestroyInstances(m_layer);
		DestroyInstances(m_body);
	}

	private static void DestroyInstances(Renderer r)
	{
		if ((Object)(object)r == (Object)null)
		{
			return;
		}
		Material[] sharedMaterials = r.sharedMaterials;
		foreach (Material val in sharedMaterials)
		{
			if ((Object)(object)val != (Object)null && ((Object)val).name.EndsWith(" (Instance)", StringComparison.Ordinal))
			{
				Object.Destroy((Object)(object)val);
			}
		}
	}
}
public static class PaintMask
{
	private sealed class Entry
	{
		public Texture2D Texture;

		public int Refs;
	}

	private static readonly Dictionary<string, Entry> s_masks = new Dictionary<string, Entry>();

	public static Texture2D Acquire(Texture chest, Texture legs, out string key)
	{
		key = (((Object)(object)chest != (Object)null) ? ((Object)chest).GetInstanceID() : 0) + ":" + (((Object)(object)legs != (Object)null) ? ((Object)legs).GetInstanceID() : 0);
		if (s_masks.TryGetValue(key, out var value) && (Object)(object)value.Texture != (Object)null)
		{
			value.Refs++;
			return value.Texture;
		}
		Texture2D val = Make(chest, legs);
		if ((Object)(object)val == (Object)null)
		{
			key = null;
			return null;
		}
		s_masks[key] = new Entry
		{
			Texture = val,
			Refs = 1
		};
		return val;
	}

	public static void Release(string key)
	{
		if (key == null || !s_masks.TryGetValue(key, out var value))
		{
			return;
		}
		value.Refs--;
		if (value.Refs <= 0)
		{
			s_masks.Remove(key);
			if ((Object)(object)value.Texture != (Object)null)
			{
				Object.Destroy((Object)(object)value.Texture);
			}
		}
	}

	private static Texture2D Make(Texture chest, Texture legs)
	{
		//IL_00e8: Unknown result type (might be due to invalid IL or missing references)
		//IL_00ed: Unknown result type (might be due to invalid IL or missing references)
		//IL_00f8: Unknown result type (might be due to invalid IL or missing references)
		//IL_00ff: Unknown result type (might be due to invalid IL or missing references)
		//IL_0109: Expected O, but got Unknown
		//IL_00cc: Unknown result type (might be due to invalid IL or missing references)
		//IL_00d1: Unknown result type (might be due to invalid IL or missing references)
		int num = 64;
		if ((Object)(object)chest != (Object)null)
		{
			num = Mathf.Max(num, Mathf.Max(chest.width, chest.height));
		}
		if ((Object)(object)legs != (Object)null)
		{
			num = Mathf.Max(num, Mathf.Max(legs.width, legs.height));
		}
		num = Mathf.Min(num, 512);
		try
		{
			Color32[] array = ReadAlpha(chest, num);
			Color32[] array2 = ReadAlpha(legs, num);
			Color32[] array3 = (Color32[])(object)new Color32[num * num];
			for (int i = 0; i < array3.Length; i++)
			{
				byte b = 0;
				if (array != null && array[i].a > b)
				{
					b = array[i].a;
				}
				if (array2 != null && array2[i].a > b)
				{
					b = array2[i].a;
				}
				array3[i] = new Color32(byte.MaxValue, byte.MaxValue, byte.MaxValue, b);
			}
			Texture2D val = new Texture2D(num, num, (TextureFormat)4, true, false)
			{
				name = "PotatoWright paint mask"
			};
			val.SetPixels32(array3);
			val.Apply(true, true);
			return val;
		}
		catch (Exception ex)
		{
			Debug.LogWarning((object)("[PotatoWright] Mannequin paint mask not made: " + ex.Message));
			return null;
		}
	}

	private static Color32[] ReadAlpha(Texture source, int size)
	{
		//IL_0021: Unknown result type (might be due to invalid IL or missing references)
		//IL_0027: Expected O, but got Unknown
		//IL_0043: Unknown result type (might be due to invalid IL or missing references)
		if ((Object)(object)source == (Object)null)
		{
			return null;
		}
		RenderTexture active = RenderTexture.active;
		RenderTexture temporary = RenderTexture.GetTemporary(size, size, 0, (RenderTextureFormat)0, (RenderTextureReadWrite)1);
		Texture2D val = new Texture2D(size, size, (TextureFormat)4, false, true);
		try
		{
			Graphics.Blit(source, temporary);
			RenderTexture.active = temporary;
			val.ReadPixels(new Rect(0f, 0f, (float)size, (float)size), 0, 0, false);
			val.Apply(false, false);
			return val.GetPixels32();
		}
		finally
		{
			RenderTexture.active = active;
			RenderTexture.ReleaseTemporary(temporary);
			Object.Destroy((Object)(object)val);
		}
	}
}
public static class WoodTint
{
	private sealed class Entry
	{
		public Texture2D Texture;

		public int Refs;
	}

	private static readonly Dictionary<int, Color32[]> s_base = new Dictionary<int, Color32[]>();

	private static readonly Dictionary<string, Entry> s_copies = new Dictionary<string, Entry>();

	private static readonly Dictionary<int, Texture2D> s_live = new Dictionary<int, Texture2D>();

	private static readonly Dictionary<int, Color32> s_liveColor = new Dictionary<int, Color32>();

	private static Color32[] s_work;

	private static Color32? s_natural;

	public static Color NaturalColor
	{
		get
		{
			//IL_004f: 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_0044: Unknown result type (might be due to invalid IL or missing references)
			if (!s_natural.HasValue && (Object)(object)MannequinPieces.WoodTexture != (Object)null)
			{
				Base(MannequinPieces.WoodTexture);
			}
			if (!s_natural.HasValue)
			{
				return new Color(0.36078432f, 23f / 85f, 14f / 85f, 1f);
			}
			return Color32.op_Implicit(s_natural.Value);
		}
	}

	public static bool IsNatural(Color c)
	{
		//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)
		//IL_0006: 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_000c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0011: Unknown result type (might be due to invalid IL or missing references)
		//IL_0012: Unknown result type (might be due to invalid IL or missing references)
		//IL_0018: 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_002d: Unknown result type (might be due to invalid IL or missing references)
		//IL_003c: 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)
		Color32 val = Color32.op_Implicit(c);
		Color32 val2 = Color32.op_Implicit(NaturalColor);
		if (Mathf.Abs(val.r - val2.r) <= 1 && Mathf.Abs(val.g - val2.g) <= 1)
		{
			return Mathf.Abs(val.b - val2.b) <= 1;
		}
		return false;
	}

	public static Texture2D Acquire(Texture source, Color c, out string key)
	{
		//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)
		//IL_0006: Unknown result type (might be due to invalid IL or missing references)
		//IL_00a3: Unknown result type (might be due to invalid IL or missing references)
		//IL_00bf: Unknown result type (might be due to invalid IL or missing references)
		Color32 c2 = Color32.op_Implicit(c);
		key = ((Object)source).GetInstanceID() + ":" + c2.r + "," + c2.g + "," + c2.b;
		if (s_copies.TryGetValue(key, out var value) && (Object)(object)value.Texture != (Object)null)
		{
			value.Refs++;
			return value.Texture;
		}
		Texture2D val = Make(source, "PotatoWright wood " + ColorUtility.ToHtmlStringRGB(c));
		if ((Object)(object)val == (Object)null || !Fill(val, source, c2, readable: false))
		{
			key = null;
			return null;
		}
		s_copies[key] = new Entry
		{
			Texture = val,
			Refs = 1
		};
		return val;
	}

	public static void Release(string key)
	{
		if (key == null || !s_copies.TryGetValue(key, out var value))
		{
			return;
		}
		value.Refs--;
		if (value.Refs <= 0)
		{
			s_copies.Remove(key);
			if ((Object)(object)value.Texture != (Object)null)
			{
				Object.Destroy((Object)(object)value.Texture);
			}
		}
	}

	public static Texture2D Live(Texture source, Color c)
	{
		//IL_0007: Unknown result type (might be due to invalid IL or missing references)
		//IL_0008: Unknown result type (might be due to invalid IL or missing references)
		//IL_000d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0090: 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_006a: Unknown result type (might be due to invalid IL or missing references)
		//IL_00a1: 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_0078: 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_0086: Unknown result type (might be due to invalid IL or missing references)
		int instanceID = ((Object)source).GetInstanceID();
		Color32 val = Color32.op_Implicit(c);
		if (!s_live.TryGetValue(instanceID, out var value) || (Object)(object)value == (Object)null)
		{
			value = Make(source, "PotatoWright wood (panel)");
			if ((Object)(object)value == (Object)null)
			{
				return null;
			}
			s_live[instanceID] = value;
			s_liveColor.Remove(instanceID);
		}
		if (!s_liveColor.TryGetValue(instanceID, out var value2) || value2.r != val.r || value2.g != val.g || value2.b != val.b)
		{
			if (!Fill(value, source, val, readable: true))
			{
				return null;
			}
			s_liveColor[instanceID] = val;
		}
		return value;
	}

	private static Texture2D Make(Texture source, string name)
	{
		//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_0025: 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_0031: Unknown result type (might be due to invalid IL or missing references)
		//IL_0033: 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_004a: Expected O, but got Unknown
		if (Base(source) == null)
		{
			return null;
		}
		return new Texture2D(source.width, source.height, (TextureFormat)4, true, false)
		{
			name = name,
			wrapMode = source.wrapMode,
			filterMode = source.filterMode,
			anisoLevel = source.anisoLevel
		};
	}

	private static bool Fill(Texture2D texture, Texture source, Color32 c, bool readable)
	{
		//IL_002c: Unknown result type (might be due to invalid IL or missing references)
		//IL_003c: 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_0085: Unknown result type (might be due to invalid IL or missing references)
		//IL_008a: Unknown result type (might be due to invalid IL or missing references)
		//IL_008c: 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_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)
		//IL_00dd: Unknown result type (might be due to invalid IL or missing references)
		//IL_00e1: Unknown result type (might be due to invalid IL or missing references)
		//IL_00f4: 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)
		Color32[] array = Base(source);
		if (array == null)
		{
			return false;
		}
		if (s_work == null || s_work.Length != array.Length)
		{
			s_work = (Color32[])(object)new Color32[array.Length];
		}
		float num = default(float);
		float num2 = default(float);
		float num3 = default(float);
		Color.RGBToHSV(NaturalColor, ref num, ref num2, ref num3);
		float num4 = default(float);
		float num5 = default(float);
		float num6 = default(float);
		Color.RGBToHSV(Color32.op_Implicit(c), ref num4, ref num5, ref num6);
		float num7 = num4 - num;
		float num8 = ((num2 > 0.001f) ? (num5 / num2) : 0f);
		float num9 = ((num3 > 0.001f) ? (num6 / num3) : 0f);
		float num11 = default(float);
		float num12 = default(float);
		float num10 = default(float);
		for (int i = 0; i < array.Length; i++)
		{
			Color32 val = array[i];
			Color.RGBToHSV(Color32.op_Implicit(val), ref num10, ref num11, ref num12);
			num10 += num7;
			num10 -= Mathf.Floor(num10);
			Color32 val2 = Color32.op_Implicit(Color.HSVToRGB(num10, Mathf.Clamp01((num2 > 0.001f) ? (num11 * num8) : num5), Mathf.Clamp01(num12 * num9)));
			val2.a = val.a;
			s_work[i] = val2;
		}
		texture.SetPixels32(s_work);
		texture.Apply(true, !readable);
		return true;
	}

	private static Color32[] Base(Texture source)
	{
		//IL_0052: Unknown result type (might be due to invalid IL or missing references)
		//IL_0059: Expected O, but got Unknown
		//IL_0073: Unknown result type (might be due to invalid IL or missing references)
		//IL_00cc: Unknown result type (might be due to invalid IL or missing references)
		//IL_00d1: Unknown result type (might be due to invalid IL or missing references)
		//IL_00d5: Unknown result type (might be due to invalid IL or missing references)
		//IL_00e2: 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_0125: Unknown result type (might be due to invalid IL or missing references)
		//IL_013e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0143: Unknown result type (might be due to invalid IL or missing references)
		int instanceID = ((Object)source).GetInstanceID();
		if (s_base.TryGetValue(instanceID, out var value))
		{
			return value;
		}
		RenderTexture active = RenderTexture.active;
		RenderTexture temporary = RenderTexture.GetTemporary(source.width, source.height, 0, (RenderTextureFormat)0, (RenderTextureReadWrite)2);
		Texture2D val = null;
		Color32[] array;
		try
		{
			Graphics.Blit(source, temporary);
			RenderTexture.active = temporary;
			val = new Texture2D(source.width, source.height, (TextureFormat)4, false, false);
			val.ReadPixels(new Rect(0f, 0f, (float)source.width, (float)source.height), 0, 0, false);
			val.Apply(false, false);
			value = val.GetPixels32();
			s_base[instanceID] = value;
			if ((Object)(object)source == (Object)(object)MannequinPieces.WoodTexture && value.Length != 0)
			{
				long num = 0L;
				long num2 = 0L;
				long num3 = 0L;
				array = value;
				foreach (Color32 val2 in array)
				{
					num += val2.r;
					num2 += val2.g;
					num3 += val2.b;
				}
				s_natural = new Color32((byte)(num / value.Length), (byte)(num2 / value.Length), (byte)(num3 / value.Length), byte.MaxValue);
				Plugin.Debug("Mannequin wood average #" + ColorUtility.ToHtmlStringRGB(Color32.op_Implicit(s_natural.Value)));
			}
			Plugin.Debug("Mannequin wood " + ((Object)source).name + " read: " + source.width + "x" + source.height);
			array = value;
		}
		catch (Exception ex)
		{
			Debug.LogWarning((object)("[PotatoWright] Mannequin wood texture not read, colors stay off: " + ex.Message));
			s_base[instanceID] = null;
			array = null;
		}
		finally
		{
			RenderTexture.active = active;
			RenderTexture.ReleaseTemporary(temporary);
			if ((Object)(object)val != (Object)null)
			{
				Object.Destroy((Object)(object)val);
			}
		}
		return array;
	}
}
internal static class MannequinIcons
{
	private static readonly Color32 Fill = new Color32((byte)215, (byte)153, (byte)72, byte.MaxValue);

	internal const int Size = 128;

	internal const int RenderSize = 256;

	internal const int Fit = 118;

	private const float ShadeLow = 0.6f;

	private const float ShadeHigh = 1.06f;

	internal static bool Make(GameObject prefab, int pose, string name)
	{
		//IL_0021: 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_01a2: 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_01b7: 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_01cc: Unknown result type (might be due to invalid IL or missing references)
		//IL_01d7: Unknown result type (might be due to invalid IL or missing references)
		//IL_01e3: Expected O, but got Unknown
		//IL_0230: Unknown result type (might be due to invalid IL or missing references)
		//IL_023f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0119: Unknown result type (might be due to invalid IL or missing references)
		//IL_011f: Expected O, but got Unknown
		//IL_014f: Unknown result type (might be due to invalid IL or missing references)
		if (GUIManager.IsHeadless())
		{
			return false;
		}
		GameObject val = null;
		try
		{
			ZNetView.m_forceDisableInit = true;
			val = Object.Instantiate<GameObject>(prefab, new Vector3(0f, -5000f, 0f), Quaternion.identity);
			ZNetView.m_forceDisableInit = false;
			((Object)val).name = name + "_icon";
			ArmorStand component = val.GetComponent<ArmorStand>();
			Animator val2 = (((Object)(object)component != (Object)null) ? component.m_poseAnimator : null);
			if ((Object)(object)val2 == (Object)null)
			{
				return false;
			}
			val2.cullingMode = (AnimatorCullingMode)0;
			val2.SetInteger("Pose", pose);
			for (int i = 0; i < 12; i++)
			{
				val2.Update(0.5f);
			}
			Material val3 = null;
			Renderer[] componentsInChildren = val.GetComponentsInChildren<Renderer>(true);
			foreach (Renderer val4 in componentsInChildren)
			{
				if ((Object)(object)((Component)val4).transform.parent != (Object)null && ((Object)((Component)val4).transform.parent).name.StartsWith("Blocks"))
				{
					val4.enabled = false;
					continue;
				}
				if ((Object)(object)val3 == (Object)null && (Object)(object)val4.sharedMaterial != (Object)null)
				{
					val3 = new Material(val4.sharedMaterial);
					if (val3.HasProperty("_MainTex"))
					{
						val3.SetTexture("_MainTex", (Texture)(object)Texture2D.whiteTexture);
					}
					if (val3.HasProperty("_Color"))
					{
						val3.SetColor("_Color", Color.white);
					}
				}
				Material[] array = (Material[])(object)new Material[val4.sharedMaterials.Length];
				for (int k = 0; k < array.Length; k++)
				{
					array[k] = val3;
				}
				val4.sharedMaterials = array;
			}
			Sprite val5 = RenderManager.Instance.Render(new RenderRequest(val)
			{
				Rotation = Quaternion.Euler(0f, 160f, 0f),
				Width = 256,
				Height = 256,
				UseCache = false
			});
			if ((Object)(object)val5 == (Object)null || (Object)(object)val5.texture == (Object)null)
			{
				return false;
			}
			Texture2D val6 = Stylize(val5.texture);
			Sprite val7 = Sprite.Create(val6, new Rect(0f, 0f, (float)((Texture)val6).width, (float)((Texture)val6).height), new Vector2(0.5f, 0.5f));
			((Object)val7).name = name + "_icon";
			prefab.GetComponent<Piece>().m_icon = val7;
			return true;
		}
		catch (Exception ex)
		{
			Debug.LogWarning((object)("[PotatoWright] Stance icon " + name + " not made: " + ex.Message));
			return false;
		}
		finally
		{
			ZNetView.m_forceDisableInit = false;
			if ((Object)(object)val != (Object)null)
			{
				Object.DestroyImmediate((Object)(object)val);
			}
		}
	}

	internal static Color[] Fitted(Texture2D source)
	{
		//IL_0158: Unknown result type (might be due to invalid IL or missing references)
		//IL_015d: Unknown result type (might be due to invalid IL or missing references)
		int num = ((Texture)source).width;
		int num2 = ((Texture)source).height;
		int num3 = -1;
		int num4 = -1;
		Color[] pixels = source.GetPixels();
		for (int i = 0; i < ((Texture)source).height; i++)
		{
			for (int j = 0; j < ((Texture)source).width; j++)
			{
				if (pixels[i * ((Texture)source).width + j].a > 0.5f)
				{
					num = Mathf.Min(num, j);
					num3 = Mathf.Max(num3, j);
					num2 = Mathf.Min(num2, i);
					num4 = Mathf.Max(num4, i);
				}
			}
		}
		Color[] array = (Color[])(object)new Color[16384];
		if (num3 < 0)
		{
			return array;
		}
		float num5 = num3 - num + 1;
		float num6 = num4 - num2 + 1;
		float num7 = 118f / Mathf.Max(num5, num6);
		float num8 = (128f - num5 * num7) / 2f;
		float num9 = (128f - num6 * num7) / 2f;
		for (int k = 0; k < 128; k++)
		{
			for (int l = 0; l < 128; l++)
			{
				float num10 = (float)num + ((float)l + 0.5f - num8) / num7;
				float num11 = (float)num2 + ((float)k + 0.5f - num9) / num7;
				if (!(num10 < (float)(num - 1)) && !(num11 < (float)(num2 - 1)) && !(num10 > (float)(num3 + 1)) && !(num11 > (float)(num4 + 1)))
				{
					array[k * 128 + l] = source.GetPixelBilinear(num10 / (float)((Texture)source).width, num11 / (float)((Texture)source).height);
				}
			}
		}
		return array;
	}

	private static Texture2D Stylize(Texture2D source)
	{
		//IL_0108: Unknown result type (might be due to invalid IL or missing references)
		//IL_010f: Expected O, but got Unknown
		//IL_005b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0060: Unknown result type (might be due to invalid IL or missing references)
		//IL_006b: Unknown result type (might be due to invalid IL or missing references)
		//IL_007c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0089: 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_00a5: 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_03e3: Unknown result type (might be due to invalid IL or missing references)
		//IL_03ea: Unknown result type (might be due to invalid IL or missing references)
		//IL_03fe: Unknown result type (might be due to invalid IL or missing references)
		//IL_0405: Unknown result type (might be due to invalid IL or missing references)
		//IL_0412: Unknown result type (might be due to invalid IL or missing references)
		//IL_0417: Unknown result type (might be due to invalid IL or missing references)
		//IL_041e: Unknown result type (might be due to invalid IL or missing references)
		//IL_03a0: Unknown result type (might be due to invalid IL or missing references)
		//IL_0423: Unknown result type (might be due to invalid IL or missing references)
		//IL_0432: Unknown result type (might be due to invalid IL or missing references)
		//IL_0434: Unknown result type (might be due to invalid IL or missing references)
		//IL_0439: Unknown result type (might be due to invalid IL or missing references)
		int num = 128;
		int num2 = 128;
		int width = ((Texture)source).width;
		int height = ((Texture)source).height;
		Color[] pixels = source.GetPixels();
		int num3 = width;
		int num4 = height;
		int num5 = -1;
		int num6 = -1;
		float[] array = new float[width * height];
		float[] array2 = new float[width * height];
		for (int i = 0; i < height; i++)
		{
			for (int j = 0; j < width; j++)
			{
				Color val = pixels[i * width + j];
				array[i * width + j] = val.a;
				array2[i * width + j] = (val.r * 0.3f + val.g * 0.59f + val.b * 0.11f) * val.a;
				if (val.a > 0.5f)
				{
					num3 = Mathf.Min(num3, j);
					num5 = Mathf.Max(num5, j);
					num4 = Mathf.Min(num4, i);
					num6 = Mathf.Max(num6, i);
				}
			}
		}
		Texture2D val2 = new Texture2D(num, num2, (TextureFormat)4, false);
		Color32[] array3 = (Color32[])(object)new Color32[num * num2];
		if (num5 < 0)
		{
			val2.SetPixels32(array3);
			val2.Apply();
			return val2;
		}
		float num7 = num5 - num3 + 1;
		float num8 = num6 - num4 + 1;
		float num9 = 118f / Mathf.Max(num7, num8);
		float num10 = ((float)num - num7 * num9) / 2f;
		float num11 = ((float)num2 - num8 * num9) / 2f;
		float[] array4 = new float[num * num2];
		float[] array5 = new float[num * num2];
		List<float> list = new List<float>();
		for (int k = 0; k < num2; k++)
		{
			for (int l = 0; l < num; l++)
			{
				float x = (float)num3 + ((float)l + 0.5f - num10) / num9 - 0.5f;
				float y = (float)num4 + ((float)k + 0.5f - num11) / num9 - 0.5f;
				float num12 = Sample(array, width, height, x, y);
				float num13 = Sample(array2, width, height, x, y);
				int num14 = k * num + l;
				array4[num14] = num12;
				array5[num14] = ((num12 > 0.001f) ? (num13 / num12) : 0f);
				if (num12 > 0.5f)
				{
					list.Add(array5[num14]);
				}
			}
		}
		list.Sort();
		float num15 = ((list.Count > 0) ? Mathf.Max(0.05f, list[Mathf.Min(list.Count - 1, (int)((float)list.Count * 0.95f))]) : 1f);
		float[] array6 = new float[num * num2];
		for (int m = 0; m < num2; m++)
		{
			for (int n = 0; n < num; n++)
			{
				float num16 = 0f;
				for (int num17 = -2; num17 <= 2; num17++)
				{
					for (int num18 = -2; num18 <= 2; num18++)
					{
						int num19 = n + num18;
						int num20 = m + num17;
						if (num19 >= 0 && num20 >= 0 && num19 < num && num20 < num2)
						{
							num16 = Mathf.Max(num16, array4[num20 * num + num19]);
						}
					}
				}
				array6[m * num + n] = Mathf.Clamp01(num16);
			}
		}
		float[] array7 = Blur(array6, num, num2, 1.6f);
		for (int num21 = 0; num21 < array3.Length; num21++)
		{
			float num22 = Mathf.Clamp01(array5[num21] / num15);
			float num23 = 0.6f + 0.45999992f * num22;
			float num24 = Mathf.Clamp01(array4[num21]);
			float num25 = array7[num21] * 0.5882353f;
			float num26 = num24 + num25 * (1f - num24);
			Color val3 = ((num26 > 1E-05f) ? ((new Color((float)(int)Fill.r / 255f * num23, (float)(int)Fill.g / 255f * num23, (float)(int)Fill.b / 255f * num23) * num24 + new Color(5f / 51f, 6f / 85f, 4f / 85f) * num25 * (1f - num24)) / num26) : Color.clear);
			val3.a = num26;
			array3[num21] = Color32.op_Implicit(val3);
		}
		val2.SetPixels32(array3);
		val2.Apply();
		return val2;
	}

	private static float Sample(float[] map, int w, int h, float x, float y)
	{
		int num = Mathf.FloorToInt(x);
		int num2 = Mathf.FloorToInt(y);
		float num3 = x - (float)num;
		float num4 = y - (float)num2;
		return Mathf.Lerp(Mathf.Lerp(At(map, w, h, num, num2), At(map, w, h, num + 1, num2), num3), Mathf.Lerp(At(map, w, h, num, num2 + 1), At(map, w, h, num + 1, num2 + 1), num3), num4);
	}

	private static float At(float[] map, int w, int h, int x, int y)
	{
		if (x >= 0 && y >= 0 && x < w && y < h)
		{
			return map[y * w + x];
		}
		return 0f;
	}

	private static float[] Blur(float[] map, int w, int h, float sigma)
	{
		int num = Mathf.CeilToInt(sigma * 3f);
		float[] array = new float[2 * num + 1];
		float num2 = 0f;
		for (int i = -num; i <= num; i++)
		{
			array[i + num] = Mathf.Exp((float)(-(i * i)) / (2f * sigma * sigma));
			num2 += array[i + num];
		}
		for (int j = 0; j < array.Length; j++)
		{
			array[j] /= num2;
		}
		float[] array2 = new float[w * h];
		float[] array3 = new float[w * h];
		for (int k = 0; k < h; k++)
		{
			for (int l = 0; l < w; l++)
			{
				float num3 = 0f;
				for (int m = -num; m <= num; m++)
				{
					num3 += array[m + num] * At(map, w, h, l + m, k);
				}
				array2[k * w + l] = num3;
			}
		}
		for (int n = 0; n < h; n++)
		{
			for (int num4 = 0; num4 < w; num4++)
			{
				float num5 = 0f;
				for (int num6 = -num; num6 <= num; num6++)
				{
					num5 += array[num6 + num] * At(array2, w, h, num4, n + num6);
				}
				array3[n * w + num4] = num5;
			}
		}
		return array3;
	}
}
[HarmonyPatch]
internal static class MannequinMenu
{
	private const int Header = 1000;

	private static readonly string[] Labels = new string[4] { "$potatowright_menu_ask_poses", "$potatowright_menu_ask_emotes", "$potatowright_menu_embla_poses", "$potatowright_menu_embla_emotes" };

	private static readonly HashSet<ByUsagePieceList> s_lists = new HashSet<ByUsagePieceList>();

	private static bool s_open;

	private static readonly HashSet<ByUsagePieceList> s_nested = new HashSet<ByUsagePieceList>();

	private static readonly List<Piece> s_scratch = new List<Piece>();

	private static bool s_redrawPending;

	private static int ModTabIndex(ByUsagePieceList list, PieceTable pieceTable)
	{
		for (int i = 0; i < list.m_availableTags.Count; i++)
		{
			int num = list.m_availableTags[i];
			if (num < list.m_usageTags.Length || IsOurs(num))
			{
				continue;
			}
			s_scratch.Clear();
			list.GetAvailablePiecesWithTag(num, pieceTable, (IList<Piece>)s_scratch);
			foreach (Piece item in s_scratch)
			{
				if ((Object)(object)item != (Object)null && (Object)(object)((Component)item).GetComponent<Swag>() != (Object)null)
				{
					s_scratch.Clear();
					return i;
				}
			}
		}
		s_scratch.Clear();
		return -1;
	}

	private static bool IsOurs(int id)
	{
		if (id >= 1000)
		{
			return id <= 1000 + Labels.Length;
		}
		return false;
	}

	private static MannequinPose PoseOf(Piece piece)
	{
		if (!((Object)(object)piece != (Object)null))
		{
			return null;
		}
		return ((Component)piece).GetComponent<MannequinPose>();
	}

	private static bool InEntry(MannequinPose pose, int id)
	{
		if ((Object)(object)pose == (Object)null)
		{
			return false;
		}
		if (id == 1000)
		{
			return true;
		}
		int num = id - 1000 - 1;
		if (pose.m_body == num / 2)
		{
			return pose.m_emote >= 0 == (num % 2 == 1);
		}
		return false;
	}

	[HarmonyPatch(typeof(ByUsagePieceList), "UpdateAvailableTags")]
	[HarmonyPostfix]
	[HarmonyPriority(200)]
	private static void UpdateAvailableTags_Postfix(ByUsagePieceList __instance, PieceTable pieceTable)
	{
		if ((Object)(object)pieceTable == (Object)null)
		{
			s_lists.Remove(__instance);
			return;
		}
		bool[] array = new bool[Labels.Length];
		bool flag = false;
		foreach (Piece availablePiece in pieceTable.m_availablePieces)
		{
			MannequinPose mannequinPose = PoseOf(availablePiece);
			if (!((Object)(object)mannequinPose == (Object)null))
			{
				flag = true;
				array[mannequinPose.m_body * 2 + ((mannequinPose.m_emote >= 0) ? 1 : 0)] = true;
			}
		}
		if (!flag)
		{
			s_lists.Remove(__instance);
			return;
		}
		s_lists.Add(__instance);
		MannequinPieces.EnsureEmoteIcons();
		List<int> list = new List<int> { 1000 };
		if (s_open)
		{
			for (int i = 0; i < Labels.Length; i++)
			{
				if (array[i])
				{
					list.Add(1001 + i);
				}
			}
		}
		int num = ModTabIndex(__instance, pieceTable);
		if (num >= 0)
		{
			s_nested.Add(__instance);
			__instance.m_availableTags.InsertRange(num + 1, list);
		}
		else
		{
			s_nested.Remove(__instance);
			__instance.m_availableTags.AddRange(list);
		}
	}

	[HarmonyPatch(typeof(ByUsagePieceList), "GetTagDisplayName")]
	[HarmonyPrefix]
	[HarmonyPriority(600)]
	private static bool GetTagDisplayName_Prefix(ByUsagePieceList __instance, int index, ref string __result)
	{
		if (!s_lists.Contains(__instance) || index < 0 || index >= __instance.m_availableTags.Count)
		{
			return true;
		}
		int num = __instance.m_availableTags[index];
		if (!IsOurs(num))
		{
			return true;
		}
		string text = (s_nested.Contains(__instance) ? "     " : "");
		__result = ((num == 1000) ? (text + "<b>" + (s_open ? "- " : "+ ") + Localization.instance.Localize("$potatowright_menu_mannequins") + "</b>") : (text + "     " + Localization.instance.Localize(Labels[num - 1000 - 1])));
		return false;
	}

	[HarmonyPatch(typeof(ByUsagePieceList), "GetAvailablePiecesWithTag")]
	[HarmonyPrefix]
	[HarmonyPriority(600)]
	private static bool GetAvailablePiecesWithTag_Prefix(ByUsagePieceList __instance, int tagId, PieceTable pieceTable, IList<Piece> resultOut)
	{
		if (!IsOurs(tagId) || (Object)(object)pieceTable == (Object)null)
		{
			return true;
		}
		foreach (Piece availablePiece in pieceTable.m_availablePieces)
		{
			if (availablePiece.m_repairPiece || availablePiece.m_removePiece || InEntry(PoseOf(availablePiece), tagId))
			{
				resultOut.Add(availablePiece);
			}
		}
		return false;
	}

	[HarmonyPatch(typeof(ByUsagePieceList), "GetAvailablePiecesWithTag")]
	[HarmonyPostfix]
	[HarmonyPriority(0)]
	private static void GetAvailablePiecesWithTag_Postfix(int tagId, IList<Piece> resultOut)
	{
		if (tagId == -1 || IsOurs(tagId) || resultOut == null)
		{
			return;
		}
		for (int num = resultOut.Count - 1; num >= 0; num--)
		{
			if ((Object)(object)PoseOf(resultOut[num]) != (Object)null)
			{
				resultOut.RemoveAt(num);
			}
		}
	}

	[HarmonyPatch(typeof(BuildUi), "OnSelectTag")]
	[HarmonyPostfix]
	private static void OnSelectTag_Postfix(BuildUi __instance, int tagId)
	{
		if (tagId != -10)
		{
			bool flag = IsOurs(tagId);
			if (flag != s_open)
			{
				s_open = flag;
				s_redrawPending = true;
			}
		}
	}

	[HarmonyPatch(typeof(BuildUi), "Update")]
	[HarmonyPostfix]
	private static void BuildUi_Update_Postfix(BuildUi __instance)
	{
		if (!s_redrawPending)
		{
			return;
		}
		s_redrawPending = false;
		try
		{
			if (!((Component)__instance).gameObject.activeInHierarchy)
			{
				return;
			}
			__instance.UpdateTagButtons(true);
			__instance.ConfigureButtonNavigation();
			BuildUiTagButton val = default(BuildUiTagButton);
			if (__instance.TryGetTagButtonById(__instance.m_currentTagId, ref val) && (Object)(object)val != (Object)null)
			{
				Selectable component = ((Component)val).GetComponent<Selectable>();
				if (component != null)
				{
					component.Select();
				}
			}
		}
		catch (Exception ex)
		{
			Debug.LogWarning((object)("[PotatoWright] Build menu Mannequins entry redraw failed: " + ex));
		}
	}
}
[HarmonyPatch]
public static class MannequinPanel
{
	private sealed class Row
	{
		public TMP_Text Label;

		public TMP_Text Value;

		public Slider Slider;

		public Texture2D Strip;
	}

	private const int StripWidth = 64;

	private static GameObject s_panel;

	private static Hud s_owner;

	private static readonly Row[] s_rows = new Row[3];

	private static Image s_swatch;

	private static TMP_Text s_hex;

	private static TMP_Text s_baseText;

	private static bool s_syncing;

	private static bool s_failed;

	private static readonly Color ButtonNormal = new Color(0.824f, 0.824f, 0.824f, 1f);

	[HarmonyPatch(typeof(Hud), "Update")]
	[HarmonyPostfix]
	private static void Hud_Update_Postfix(Hud __instance)
	{
		Player localPlayer = Player.m_localPlayer;
		if ((Object)(object)localPlayer == (Object)null)
		{
			return;
		}
		MannequinColor.EnsureLoaded(localPlayer);
		if (Hud.IsPieceSelectionVisible())
		{
			MannequinPieces.EnsureEmoteIcons();
		}
		if (s_failed || !((Character)localPlayer).InPlaceMode() || !Hud.IsPieceSelectionVisible() || !SelectedIsMannequin(localPlayer))
		{
			if ((Object)(object)s_panel != (Object)null && s_panel.activeSelf)
			{
				s_panel.SetActive(false);
			}
			return;
		}
		try
		{
			if ((Object)(object)s_panel == (Object)null || (Object)(object)s_owner != (Object)(object)__instance)
			{
				Build(__instance);
			}
			if ((Object)(object)s_panel != (Object)null && !s_panel.activeSelf)
			{
				s_panel.SetActive(true);
				Show();
				Fit();
			}
		}
		catch (Exception ex)
		{
			s_failed = true;
			Debug.LogWarning((object)("[PotatoWright] Mannequin color panel is off this session: " + ex));
			if ((Object)(object)s_panel != (Object)null)
			{
				Object.Destroy((Object)(object)s_panel);
			}
			s_panel = null;
		}
	}

	private static bool SelectedIsMannequin(Player player)
	{
		Piece selectedPiece = player.GetSelectedPiece();
		if ((Object)(object)selectedPiece != (Object)null)
		{
			return (Object)(object)((Component)selectedPiece).GetComponent<MannequinTint>() != (Object)null;
		}
		return false;
	}

	private static void Show()
	{
		s_syncing = true;
		s_rows[0].Slider.value = MannequinColor.H;
		s_rows[1].Slider.value = MannequinColor.S;
		s_rows[2].Slider.value = MannequinColor.V;
		s_syncing = false;
		Refresh();
	}

	private static void Changed()
	{
		if (!s_syncing)
		{
			MannequinColor.H = s_rows[0].Slider.value;
			MannequinColor.S = s_rows[1].Slider.value;
			MannequinColor.V = s_rows[2].Slider.value;
			MannequinColor.Save(Player.m_localPlayer);
			Refresh();
		}
	}

	private static void NaturalWood()
	{
		MannequinColor.Natural();
		MannequinColor.Save(Player.m_localPlayer);
		Show();
	}

	private static void Refresh()
	{
		//IL_00d7: Unknown result type (might be due to invalid IL or missing references)
		//IL_00eb: Unknown result type (might be due to invalid IL or missing references)
		float h = MannequinColor.H;
		float s = MannequinColor.S;
		float v = MannequinColor.V;
		s_rows[0].Value.text = Mathf.RoundToInt(h * 360f).ToString(CultureInfo.InvariantCulture) + "°";
		s_rows[1].Value.text = Mathf.RoundToInt(s * 100f).ToString(CultureInfo.InvariantCulture) + "%";
		s_rows[2].Value.text = Mathf.RoundToInt(v * 100f).ToString(CultureInfo.InvariantCulture) + "%";
		((Graphic)s_swatch).color = MannequinColor.Current;
		s_hex.text = "#" + ColorUtility.ToHtmlStringRGB(MannequinColor.Current);
		if ((Object)(object)s_baseText != (Object)null)
		{
			s_baseText.text = (MannequinColor.ShowBase ? MannequinColor.Text("potatowright_base_on", "On") : MannequinColor.Text("potatowright_base_off", "Off"));
		}
		Paint(s_rows[0], (float x) => Color.HSVToRGB(x, 1f, 1f));
		Paint(s_rows[1], (float x) => Color.HSVToRGB(h, x, Mathf.Max(v, 0.35f)));
		Paint(s_rows[2], (float x) => Color.HSVToRGB(h, s, x));
	}

	private static void Paint(Row row, Func<float, Color> at)
	{
		//IL_0015: Unknown result type (might be due to invalid IL or missing references)
		for (int i = 0; i < 64; i++)
		{
			row.Strip.SetPixel(i, 0, at((float)i / 63f));
		}
		row.Strip.Apply(false);
	}

	private static void Build(Hud hud)
	{
		//IL_0182: Unknown result type (might be due to invalid IL or missing references)
		//IL_018c: Expected O, but got Unknown
		//IL_01ab: Unknown result type (might be due to invalid IL or missing references)
		//IL_01b2: Expected O, but got Unknown
		//IL_01d1: 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_01eb: 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_0214: 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)
		//IL_00cb: Unknown result type (might be due to invalid IL or missing references)
		//IL_00d0: Unknown result type (might be due to invalid IL or missing references)
		//IL_028c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0243: Unknown result type (might be due to invalid IL or missing references)
		//IL_0250: Unknown result type (might be due to invalid IL or missing references)
		//IL_0122: Unknown result type (might be due to invalid IL or missing references)
		//IL_0127: Unknown result type (might be due to invalid IL or missing references)
		//IL_012c: Unknown result type (might be due to invalid IL or missing references)
		//IL_013b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0140: Unknown result type (might be due to invalid IL or missing references)
		//IL_0145: Unknown result type (might be due to invalid IL or missing references)
		//IL_02ac: 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_0163: Expected O, but got Unknown
		//IL_03ee: Unknown result type (might be due to invalid IL or missing references)
		//IL_0602: Unknown result type (might be due to invalid IL or missing references)
		//IL_0607: Unknown result type (might be due to invalid IL or missing references)
		//IL_0617: Unknown result type (might be due to invalid IL or missing references)
		//IL_0625: Unknown result type (might be due to invalid IL or missing references)
		//IL_062b: Unknown result type (might be due to invalid IL or missing references)
		//IL_064c: Expected O, but got Unknown
		//IL_069a: Unknown result type (might be due to invalid IL or missing references)
		//IL_06bb: Unknown result type (might be due to invalid IL or missing references)
		//IL_06c5: Expected O, but got Unknown
		//IL_0727: Unknown result type (might be due to invalid IL or missing references)
		//IL_0748: Unknown result type (might be due to invalid IL or missing references)
		//IL_0752: Expected O, but got Unknown
		//IL_052c: Unknown result type (might be due to invalid IL or missing references)
		//IL_054d: Expected O, but got Unknown
		//IL_04a0: Unknown result type (might be due to invalid IL or missing references)
		//IL_04c4: Unknown result type (might be due to invalid IL or missing references)
		//IL_04f4: Unknown result type (might be due to invalid IL or missing references)
		//IL_04fe: Unknown result type (might be due to invalid IL or missing references)
		//IL_0511: Unknown result type (might be due to invalid IL or missing references)
		//IL_051b: Unknown result type (might be due to invalid IL or missing references)
		if ((Object)(object)s_panel != (Object)null)
		{
			Object.Destroy((Object)(object)s_panel);
		}
		s_panel = null;
		s_owner = hud;
		RectTransform val = (RectTransform)(((Object)(object)hud.m_buildUi != (Object)null) ? /*isinst with value type is only supported in some contexts*/: null);
		TMP_Text pieceDescription = hud.m_pieceDescription;
		if ((Object)(object)val == (Object)null || (Object)(object)pieceDescription == (Object)null)
		{
			throw new InvalidOperationException("the build menu or its description text is missing");
		}
		Canvas componentInParent = ((Component)val).GetComponentInParent<Canvas>();
		componentInParent = (((Object)(object)componentInParent != (Object)null) ? componentInParent.rootCanvas : null);
		Image val2 = null;
		float num = 0f;
		Image[] componentsInChildren = ((Component)val).GetComponentsInChildren<Image>(true);
		foreach (Image val3 in componentsInChildren)
		{
			if (!((Object)(object)val3.sprite == (Object)null) && !((Object)(object)((Component)val3).GetComponentInParent<Selectable>() != (Object)null))
			{
				Rect rect = ((RectTransform)((Component)val3).transform).rect;
				if (((Rect)(ref rect)).width * ((Rect)(ref rect)).height > num)
				{
					num = ((Rect)(ref rect)).width * ((Rect)(ref rect)).height;
					val2 = val3;
				}
			}
		}
		RectTransform val4 = val;
		if ((Object)(object)val2 != (Object)null && (Object)(object)componentInParent != (Object)null)
		{
			Rect rect2 = ((RectTransform)((Component)val2).transform).rect;
			float width = ((Rect)(ref rect2)).width;
			rect2 = ((RectTransform)((Component)componentInParent).transform).rect;
			if (width < ((Rect)(ref rect2)).width * 0.8f)
			{
				val4 = (RectTransform)((Component)val2).transform;
			}
		}
		float num2 = 262f;
		s_panel = new GameObject("PotatoWright_MannequinColor", new Type[1] { typeof(RectTransform) });
		s_panel.layer = ((Component)val).gameObject.layer;
		RectTransform val5 = (RectTransform)s_panel.transform;
		((Transform)val5).SetParent((Transform)(object)val4, false);
		Vector2 val6 = default(Vector2);
		((Vector2)(ref val6))..ctor(1f, 1f);
		val5.anchorMax = val6;
		val5.anchorMin = val6;
		val5.pivot = new Vector2(0f, 1f);
		val5.anchoredPosition = new Vector2(12f, 0f);
		val5.sizeDelta = new Vector2(340f, num2);
		Image val7 = s_panel.AddComponent<Image>();
		if ((Object)(object)val2 != (Object)null)
		{
			val7.sprite = val2.sprite;
			val7.type = val2.type;
			((Graphic)val7).color = ((Graphic)val2).color;
			((Graphic)val7).material = ((Graphic)val2).material;
			val7.pixelsPerUnitMultiplier = val2.pixelsPerUnitMultiplier;
		}
		else
		{
			((Graphic)val7).color = new Color(0f, 0f, 0f, 0.75f);
		}
		((Graphic)val7).raycastTarget = true;
		SpriteAtlas val8 = FindAtlas("UIAtlas");
		Resources val9 = new Resources
		{
			knob = (((Object)(object)val8 != (Object)null) ? val8.GetSprite("checkbox_marker") : null),
			standard = (((Object)(object)val8 != (Object)null) ? val8.GetSprite("button") : null)
		};
		float num3 = 16f;
		TMP_Text obj = Text(pieceDescription, "Title", 16f, num3, 308f, 30f);
		obj.alignment = (TextAlignmentOptions)514;
		obj.fontSize = pieceDescription.fontSize * 1.2f;
		obj.text = MannequinColor.Text("potatowright_mannequin_color", "Mannequin color");
		num3 += 34f;
		string[] array = new string[3]
		{
			MannequinColor.Text("potatowright_hue", "Hue"),
			MannequinColor.Text("potatowright_saturation", "Saturation"),
			MannequinColor.Text("potatowright_brightness", "Brightness")
		};
		for (int j = 0; j < 3; j++)
		{
			Row row = new Row();
			row.Label = Text(pieceDescription, "Label" + j, 16f, num3, 104f, 26f);
			row.Label.alignment = (TextAlignmentOptions)513;
			row.Label.text = array[j];
			GameObject val10 = DefaultControls.CreateSlider(val9);
			((Object)val10).name = "PotatoWright_Slider" + j;
			Transform[] componentsInChildren2 = val10.GetComponentsInChildren<Transform>(true);
			for (int i = 0; i < componentsInChildren2.Length; i++)
			{
				((Component)componentsInChildren2[i]).gameObject.layer = s_panel.layer;
			}
			val10.transform.SetParent((Transform)(object)val5, false);
			Slider component = val10.GetComponent<Slider>();
			component.minValue = 0f;
			component.maxValue = 1f;
			component.wholeNumbers = false;
			if ((Object)(object)component.handleRect != (Object)null)
			{
				component.handleRect.sizeDelta = new Vector2(40f, 10f);
				Image component2 = ((Component)component.handleRect).GetComponent<Image>();
				if ((Object)(object)component2 != (Object)null)
				{
					((Graphic)component2).color = Color.white;
				}
				Transform parent = ((Transform)component.handleRect).parent;
				RectTransform val11 = (RectTransform)(object)((parent is RectTransform) ? parent : null);
				if ((Object)(object)val11 != (Object)null)
				{
					val11.offsetMin = new Vector2(5f, val11.offsetMin.y);
					val11.offsetMax = new Vector2(-5f, val11.offsetMax.y);
				}
			}
			Place((RectTransform)val10.transform, 124f, num3 + 4f, 142f, 18f);
			row.Slider = component;
			Strip(row);
			((UnityEvent<float>)(object)component.onValueChanged).AddListener((UnityAction<float>)delegate
			{
				Changed();
			});
			row.Value = Text(pieceDescription, "Value" + j, 270f, num3, 54f, 26f);
			row.Value.alignment = (TextAlignmentOptions)516;
			s_rows[j] = row;
			num3 += 34f;
		}
		GameObject val12 = new GameObject("PotatoWright_Swatch", new Type[1] { typeof(RectTransform) })
		{
			layer = s_panel.layer
		};
		val12.transform.SetParent((Transform)(object)val5, false);
		Place((RectTransform)val12.transform, 16f, num3 + 8f, 40f, 30f);
		s_swatch = val12.AddComponent<Image>();
		((Graphic)s_swatch).raycastTarget = false;
		s_hex = Text(pieceDescription, "Hex", 64f, num3 + 10f, 104f, 26f);
		s_hex.alignment = (TextAlignmentOptions)513;
		MakeButton(val, val5, val9, pieceDescription, "PotatoWright_NaturalWood", 174f, num3 + 6f, 150f, new UnityAction(NaturalWood)).text = MannequinColor.Text("potatowright_natural_wood", "Natural wood");
		num3 += 50f;
		TMP_Text obj2 = Text(pieceDescription, "BaseLabel", 16f, num3 + 8f, 104f, 26f);
		obj2.alignment = (TextAlignmentOptions)513;
		obj2.text = MannequinColor.Text("potatowright_base", "Base");
		s_baseText = MakeButton(val, val5, val9, pieceDescription, "PotatoWright_Base", 174f, num3 + 4f, 150f, new UnityAction(ToggleBase));
		s_panel.SetActive(false);
	}

	private static TMP_Text MakeButton(RectTransform ui, RectTransform parent, Resources resources, TMP_Text textSource, string name, float x, float y, float w, UnityAction onClick)
	{
		//IL_0000: 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_0094: Expected O, but got Unknown
		//IL_009b: 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_00a3: 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_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_010f: 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_01af: Unknown result type (might be due to invalid IL or missing references)
		//IL_01b4: Unknown result type (might be due to invalid IL or missing references)
		//IL_01b5: Unknown result type (might be due to invalid IL or missing references)
		//IL_01bf: 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_01ca: Unknown result type (might be due to invalid IL or missing references)
		//IL_01cb: Unknown result type (might be due to invalid IL or missing references)
		//IL_01d0: Unknown result type (might be due to invalid IL or missing references)
		//IL_01d1: 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)
		GameObject val = DefaultControls.CreateButton(resources);
		((Object)val).name = name;
		Transform[] componentsInChildren = val.GetComponentsInChildren<Transform>(true);
		for (int i = 0; i < componentsInChildren.Length; i++)
		{
			((Component)componentsInChildren[i]).gameObject.layer = s_panel.layer;
		}
		Text[] componentsInChildren2 = val.GetComponentsInChildren<Text>(true);
		for (int i = 0; i < componentsInChildren2.Length; i++)
		{
			Object.Destroy((Object)(object)((Component)componentsInChildren2[i]).gameObject);
		}
		val.transform.SetParent((Transform)(object)parent, false);
		Place((RectTransform)val.transform, x, y, w, 36f);
		Button component = val.GetComponent<Button>();
		ColorBlock colors = ((Selectable)component).colors;
		((ColorBlock)(ref colors)).normalColor = ButtonNormal;
		((ColorBlock)(ref colors)).highlightedColor = new Color(1.3f, 1.3f, 1.3f, 1f);
		((ColorBlock)(ref colors)).pressedColor = new Color(0.537f, 0.556f, 0.556f, 1f);
		((ColorBlock)(ref colors)).selectedColor = ButtonNormal;
		((ColorBlock)(ref colors)).disabledColor = new Color(0.566f, 0.566f, 0.566f, 0.502f);
		((ColorBlock)(ref colors)).colorMultiplier = 1f;
		((ColorBlock)(ref colors)).fadeDuration = 0.1f;
		((Selectable)component).colors = colors;
		ButtonSfx componentInChildren = ((Component)ui).GetComponentInChildren<ButtonSfx>(true);
		if ((Object)(object)componentInChildren != (Object)null && (Object)(object)componentInChildren.m_sfxPrefab != (Object)null)
		{
			val.AddComponent<ButtonSfx>().m_sfxPrefab = componentInChildren.m_sfxPrefab;
		}
		((UnityEvent)component.onClick).AddListener(onClick);
		TMP_Text obj = Text(textSource, name + "Label", 0f, 0f, w, 36f);
		obj.transform.SetParent(val.transform, false);
		RectTransform val2 = (RectTransform)obj.transform;
		val2.anchorMin = Vector2.zero;
		val2.anchorMax = Vector2.one;
		Vector2 offsetMin = (val2.offsetMax = Vector2.zero);
		val2.offsetMin = offsetMin;
		obj.alignment = (TextAlignmentOptions)514;
		return obj;
	}

	private static void ToggleBase()
	{
		MannequinColor.ShowBase = !MannequinColor.ShowBase;
		MannequinColor.Save(Player.m_localPlayer);
		Refresh();
	}

	private static SpriteAtlas FindAtlas(string name)
	{
		SpriteAtlas[] array = Resources.FindObjectsOfTypeAll<SpriteAtlas>();
		foreach (SpriteAtlas val in array)
		{
			if ((Object)(object)val != (Object)null && ((Object)val).name == name)
			{
				return val;
			}
		}
		return null;
	}

	private static void Strip(Row row)
	{
		//IL_004f: 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_005b: 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_0072: Expected O, but got Unknown
		//IL_008a: Unknown result type (might be due to invalid IL or missing references)
		//IL_008f: 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_00a5: Unknown result type (might be due to invalid IL or missing references)
		//IL_00aa: Unknown result type (might be due to invalid IL or missing references)
		//IL_00b7: Unknown result type (might be due to invalid IL or missing references)
		//IL_00bd: 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_00d2: Unknown result type (might be due to invalid IL or missing references)
		//IL_00dd: Unknown result type (might be due to invalid IL or missing references)
		//IL_00e7: 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_00ed: Unknown result type (might be due to invalid IL or missing references)
		//IL_00ee: Unknown result type (might be due to invalid IL or missing references)
		//IL_00f5: Unknown result type (might be due to invalid IL or missing references)
		//IL_011c: Unknown result type (might be due to invalid IL or missing references)
		//IL_012b: Unknown result type (might be due to invalid IL or missing references)
		Slider slider = row.Slider;
		RectTransform handleRect = slider.handleRect;
		Image[] componentsInChildren = ((Component)slider).GetComponentsInChildren<Image>(true);
		foreach (Image val in componentsInChildren)
		{
			if ((Object)(object)handleRect == (Object)null || !((Component)val).transform.IsChildOf((Transform)(object)handleRect))
			{
				((Behaviour)val).enabled = false;
			}
		}
		row.Strip = new Texture2D(64, 1, (TextureFormat)4, false)
		{
			wrapMode = (TextureWrapMode)1,
			filterMode = (FilterMode)1,
			name = "PotatoWright strip"
		};
		GameObject val2 = new GameObject("PotatoWright_Strip", new Type[1] { typeof(RectTransform) })
		{
			layer = s_panel.layer
		};
		RectTransform val3 = (RectTransform)val2.transform;
		((Transform)val3).SetParent(((Component)slider).transform, false);
		((Transform)val3).SetAsFirstSibling();
		val3.anchorMin = new Vector2(0f, 0.2f);
		val3.anchorMax = new Vector2(1f, 0.8f);
		Vector2 offsetMin = (val3.offsetMax = Vector2.zero);
		val3.offsetMin = offsetMin;
		Image obj = val2.AddComponent<Image>();
		obj.sprite = Sprite.Create(row.Strip, new Rect(0f, 0f, 64f, 1f), new Vector2(0.5f, 0.5f));
		((Graphic)obj).raycastTarget = true;
	}

	private static void Fit()
	{
		//IL_000a: Unknown result type (might be due to invalid IL or missing references)
		//IL_0010: Expected O, but got Unknown
		//IL_001b: 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_005a: Expected O, but got Unknown
		//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_0098: Unknown result type (might be due to invalid IL or missing references)
		//IL_009a: Unknown result type (might be due to invalid IL or missing references)
		//IL_009f: Unknown result type (might be due to invalid IL or missing references)
		//IL_00a3: Unknown result type (might be due to invalid IL or missing references)
		//IL_00b3: 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_00d3: Unknown result type (might be due to invalid IL or missing references)
		//IL_00f0: Unknown result type (might be due to invalid IL or missing references)
		//IL_00f5: Unknown result type (might be due to invalid IL or missing references)
		//IL_0189: Unknown result type (might be due to invalid IL or missing references)
		//IL_018e: 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_0198: Unknown result type (might be due to invalid IL or missing references)
		//IL_019c: Unknown result type (might be due to invalid IL or missing references)
		//IL_01a1: Unknown result type (might be due to invalid IL or missing references)
		//IL_01a8: Unknown result type (might be due to invalid IL or missing references)
		//IL_01af: Unknown result type (might be due to invalid IL or missing references)
		//IL_01b4: Unknown result type (might be due to invalid IL or missing references)
		RectTransform val = (RectTransform)s_panel.transform;
		val.anchoredPosition = new Vector2(12f, 0f);
		Canvas componentInParent = ((Component)val).GetComponentInParent<Canvas>();
		componentInParent = (((Object)(object)componentInParent != (Object)null) ? componentInParent.rootCanvas : null);
		if (!((Object)(object)componentInParent == (Object)null))
		{
			Canvas.ForceUpdateCanvases();
			RectTransform val2 = (RectTransform)((Component)componentInParent).transform;
			Vector3[] array = (Vector3[])(object)new Vector3[4];
			val.GetWorldCorners(array);
			float num = float.MaxValue;
			float num2 = float.MinValue;
			float num3 = float.MaxValue;
			float num4 = float.MinValue;
			Vector3[] array2 = array;
			foreach (Vector3 val3 in array2)
			{
				Vector3 val4 = ((Transform)val2).InverseTransformPoint(val3);
				num = Mathf.Min(num, val4.x);
				num2 = Mathf.Max(num2, val4.x);
				num3 = Mathf.Min(num3, val4.y);
				num4 = Mathf.Max(num4, val4.y);
			}
			Rect rect = val2.rect;
			float num5 = 0f;
			float num6 = 0f;
			if (num2 > ((Rect)(ref rect)).xMax)
			{
				num5 = ((Rect)(ref rect)).xMax - num2;
			}
			if (num + num5 < ((Rect)(ref rect)).xMin)
			{
				num5 = ((Rect)(ref rect)).xMin - num;
			}
			if (num3 < ((Rect)(ref rect)).yMin)
			{
				num6 = ((Rect)(ref rect)).yMin - num3;
			}
			if (num4 + num6 > ((Rect)(ref rect)).yMax)
			{
				num6 = ((Rect)(ref rect)).yMax - num4;
			}
			if (num5 != 0f || num6 != 0f)
			{
				Vector3 val5 = ((Transform)val).parent.InverseTransformVector(((Transform)val2).TransformVector(new Vector3(num5, num6, 0f)));
				val.anchoredPosition += new Vector2(val5.x, val5.y);
			}
		}
	}

	private static TMP_Text Text(TMP_Text source, string name, float x, float y, float w, float h)
	{
		//IL_0099: Unknown result type (might be due to invalid IL or missing references)
		//IL_00f4: Unknown result type (might be due to invalid IL or missing references)
		//IL_0104: Expected O, but got Unknown
		GameObject val = Object.Instantiate<GameObject>(((Component)source).gameObject, s_panel.transform, false);
		((Object)val).name = "PotatoWright_" + name;
		Localize[] componentsInChildren = val.GetComponentsInChildren<Localize>(true);
		for (int i = 0; i < componentsInChildren.Length; i++)
		{
			Object.Destroy((Object)(object)componentsInChildren[i]);
		}
		LayoutElement[] components = val.GetComponents<LayoutElement>();
		for (int i = 0; i < components.Length; i++)
		{
			Object.Destroy((Object)(object)components[i]);
		}
		ContentSizeFitter[] components2 = val.GetComponents<ContentSizeFitter>();
		for (int i = 0; i < components2.Length; i++)
		{
			Object.Destroy((Object)(object)components2[i]);
		}
		foreach (Transform item in val.transform)
		{
			Object.Destroy((Object)(object)((Component)item).gameObject);
		}
		TMP_Text component = val.GetComponent<TMP_Text>();
		component.text = "";
		component.textWrappingMode = (TextWrappingModes)0;
		component.overflowMode = (TextOverflowModes)1;
		((Graphic)component).raycastTarget = false;
		Place((RectTransform)val.transform, x, y, w, h);
		return component;
	}

	private static void Place(RectTransform rect, float x, float y, float w, float h)
	{
		//IL_0013: Unknown result type (might be due to invalid IL or missing references)
		//IL_0019: Unknown result type (might be due to invalid IL or missing references)
		//IL_002a: 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_0046: Unknown result type (might be due to invalid IL or missing references)
		Vector2 val = default(Vector2);
		((Vector2)(ref val))..ctor(0f, 1f);
		rect.anchorMax = val;
		rect.anchorMin = val;
		rect.pivot = new Vector2(0f, 1f);
		rect.anchoredPosition = new Vector2(x, 0f - y);
		rect.sizeDelta = new Vector2(w, h);
	}
}
[HarmonyPatch]
public static class MannequinPieces
{
	public static readonly int EmoteKey = StringExtensionMethods.GetStableHashCode("PotatoWright_emote");

	private static readonly int InitKey = StringExtensionMethods.GetStableHashCode("PotatoWright_mannequinInit");

	private static readonly string[] BodyPrefabs = new string[2] { "ArmorStand_Male", "ArmorStand_Female" };

	private static readonly string[] BodyLabels = new string[2] { "Male", "Female" };

	private static readonly string[] BodyNames = new string[2] { "Ask", "Embla" };

	private static readonly string[] StandPoses = new string[15]
	{
		"A-Pose", "T-Pose", "Upright", "Wave", "Forge", "Cooking", "Equip (back)", "Equip (middle)", "Equip (loop)", "Hold the mast",
		"Kickstep", "Thumbs up", "Roar", "Warrior idle", "Sitting"
	};

	private static readonly Material[] s_paintable = (Material[])(object)new Material[2];

	private static bool s_iconsSet;

	private static float s_nextIconTry;

	private static readonly List<GameObject> s_pieces = new List<GameObject>();

	public const string WoodLayerName = "PotatoWrightWoodLayer";

	public static Texture WoodTexture;

	private static readonly FieldInfo ClothColliders = AccessTools.Field(typeof(VisEquipment), "m_clothColliders");

	private static bool s_clothLogged;

	internal static IEnumerable<GameObject> Pieces => s_pieces;

	private static void MakePaintable(GameObject piece, int body)
	{
		//IL_031a: Unknown result type (might be due to invalid IL or missing references)
		//IL_014f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0156: Expected O, but got Unknown
		//IL_0465: Unknown result type (might be due to invalid IL or missing references)
		//IL_046a: Unknown result type (might be due to invalid IL or missing references)
		//IL_0488: Unknown result type (might be due to invalid IL or missing references)
		//IL_0490: Expected O, but got Unknown
		ArmorStand component = piece.GetComponent<ArmorStand>();
		VisEquipment val = (((Object)(object)component != (Object)null) ? component.m_visEquipment : null);
		if ((Object)(object)val == (Object)null || (Object)(object)val.m_bodyModel == (Object)null)
		{
			return;
		}
		Material sharedMaterial = ((Renderer)val.m_bodyModel).sharedMaterial;
		if ((Object)(object)s_paintable[body] == (Object)null)
		{
			GameObject prefab = PrefabManager.Instance.GetPrefab("ArmorStand");
			ArmorStand val2 = (((Object)(object)prefab != (Object)null) ? prefab.GetComponent<ArmorStand>() : null);
			Material val3 = (((Object)(object)val2 != (Object)null && (Object)(object)val2.m_visEquipment != (Object)null && (Object)(object)val2.m_visEquipment.m_bodyModel != (Object)null) ? ((Renderer)val2.m_visEquipment.m_bodyModel).sharedMaterial : null);
			if ((Object)(object)val3 == (Object)null || (Object)(object)sharedMaterial == (Object)null || !val3.HasProperty("_ChestTex") || !val3.HasProperty("_MainTex"))
			{
				Debug.LogWarning((object)("[PotatoWright] Mannequin " + BodyLabels[body].ToLowerInvariant() + ": no paintable body material (ArmorStand skin " + (((Object)(object)val3 != (Object)null) ? ((Object)val3.shader).name : "missing") + "); painted armor will not show."));
				s_paintable[body] = sharedMaterial;
			}
			else
			{
				Material val4 = new Material(val3);
				((Object)val4).name = "PotatoWrightMannequinPaint_" + BodyLabels[body];
				val4.renderQueue = 2450;
				s_paintable[body] = val4;
				Plugin.Debug("Mannequin " + BodyLabels[body].ToLowerInvariant() + ": wood " + ((Object)sharedMaterial).name + " (" + ((Object)sharedMaterial.shader).name + ") under paint " + ((Object)val4).name + " (" + ((Object)val4.shader).name + ", main texture " + (((Object)(object)val4.GetTexture("_MainTex") != (Object)null) ? ((Object)val4.GetTexture("_MainTex")).name : "none") + "), models " + val.m_models.Length);
			}
		}
		Material val5 = s_paintable[body];
		if ((Object)(object)WoodTexture == (Object)null && (Object)(object)sharedMaterial != (Object)null && sharedMaterial.HasProperty("_MainTex"))
		{
			WoodTexture = sharedMaterial.GetTexture("_MainTex");
		}
		if ((Object)(object)val5 == (Object)(object)sharedMaterial)
		{
			return;
		}
		GameObject val6 = Object.Instantiate<GameObject>(((Component)val.m_bodyModel).gameObject, ((Component)val.m_bodyModel).transform.parent, false);
		((Object)val6).name = "PotatoWrightWoodLayer";
		Component[] components = val6.GetComponents<Component>();
		foreach (Component val7 in components)
		{
			if (!(val7 is Transform) && !(val7 is Renderer))
			{
				Object.DestroyImmediate((Object)(object)val7);
			}
		}
		foreach (Transform item in val6.transform)
		{
			Object.DestroyImmediate((Object)(object)((Component)item).gameObject);
		}
		Renderer component2 = val6.GetComponent<Renderer>();
		Material[] array = (Material[])(object)new Material[((Renderer)val.m_bodyModel).sharedMaterials.Length];
		for (int j = 0; j < array.Length; j++)
		{
			array[j] = sharedMaterial;
		}
		component2.sharedMaterials = array;
		LODGroup componentInChildren = piece.GetComponentInChildren<LODGroup>(true);
		if ((Object)(object)componentInChildren != (Object)null)
		{
			LOD[] lODs = componentInChildren.GetLODs();
			for (int k = 0; k < lODs.Length; k++)
			{
				Renderer[] array2 = (Renderer[])(((object)lODs[k].renderers) ?? ((object)new Renderer[0]));
				if (Array.IndexOf(array2, (Renderer)(object)val.m_bodyModel) >= 0)
				{
					Renderer[] array3 = (Renderer[])(object)new Renderer[array2.Length + 1];
					array2.CopyTo(array3, 0);
					array3[array2.Length] = component2;
					lODs[k].renderers = array3;
				}
			}
			componentInChildren.SetLODs(lODs);
		}
		Material[] sharedMaterials = ((Renderer)val.m_bodyModel).sharedMaterials;
		for (int l = 0; l < sharedMaterials.Length; l++)
		{
			sharedMaterials[l] = val5;
		}
		((Renderer)val.m_bodyModel).sharedMaterials = sharedMaterials;
		for (int m = 0; m < val.m_models.Length; m++)
		{
			PlayerModel val8 = val.m_models[m];
			val.m_models[m] = new PlayerModel
			{
				m_mesh = ((val8 != null) ? val8.m_mesh : val.m_bodyModel.sharedMesh),
				m_baseMaterial = val5
			};
		}
	}

	public static void EnsureEmoteIcons()
	{
		//IL_00c4: Unknown result type (might be due to invalid IL or missing references)
		if (s_iconsSet || s_pieces.Count == 0 || Time.time < s_nextIconTry)
		{
			return;
		}
		s_nextIconTry = Time.time + 1f;
		try
		{
			EmoteMappings val = (((Object)(object)RadialData.SO != (Object)null) ? RadialData.SO.EmoteMappings : null);
			if ((Object)(object)val == (Object)null)
			{
				EmoteMappings[] array = Resources.FindObjectsOfTypeAll<EmoteMappings>();
				val = ((array.Length != 0) ? array[0] : null);
			}
			if ((Object)(object)val == (Object)null)
			{
				return;
			}
			int num = 0;
			int num2 = 0;
			foreach (GameObject s_piece in s_pieces)
			{
				MannequinPose mannequinPose = (((Object)(object)s_piece != (Object)null) ? s_piece.GetComponent<MannequinPose>() : null);
				if (!((Object)(object)mannequinPose == (Object)null) && mannequinPose.m_emote >= 0)
				{
					num2++;
					Sprite sprite = val.GetMapping((Emotes)mannequinPose.m_emote).Sprite;
					if ((Object)(object)sprite != (Object)null)
					{
						s_piece.GetComponent<Piece>().m_icon = sprite;
						num++;
					}
				}
			}
			s_iconsSet = true;
			Plugin.Debug("Mannequin emote icons: " + num + " of " + num2);
		}
		catch (Exception ex)
		{
			s_iconsSet = true;
			Debug.LogWarning((object)("[PotatoWright] Mannequin emote icons not set: " + ex.Message));
		}
	}

	public static void Create()
	{
		//IL_00d8: Unknown result type (might be due to invalid IL or missing references)
		//IL_00dd: Unknown result type (might be due to invalid IL or missing references)
		//IL_00df: Unknown result type (might be due to invalid IL or missing references)
		//IL_00e3: Invalid comparison between Unknown and I4
		//IL_0110: Unknown result type (might be due to invalid IL or missing references)
		//IL_0117: Expected I4, but got Unknown
		for (int i = 0; i < BodyPrefabs.Length; i++)
		{
			GameObject prefab = PrefabManager.Instance.GetPrefab(BodyPrefabs[i]);
			if ((Object)(object)prefab == (Object)null || (Object)(object)prefab.GetComponent<ArmorStand>() == (Object)null || (Object)(object)prefab.GetComponent<Piece>() == (Object)null)
			{
				Debug.LogWarning((object)("[PotatoWright] " + BodyPrefabs[i] + " not found; no " + BodyLabels[i].ToLowerInvariant() + " mannequins."));
				continue;
			}
			for (int j = 0; j < StandPoses.Length; j++)
			{
				Make(i, "Pose_" + Key(StandPoses[j]), StandPoses[j], j, -1);
			}
			foreach (Emotes value in Enum.GetValues(typeof(Emotes)))
			{
				if ((int)value != 25)
				{
					Make(i, "Emote_" + ((object)value/*cast due to .constrained prefix*/).ToString(), Spaced(((object)value/*cast due to .constrained prefix*/).ToString()), 0, (int)value);
				}
			}
		}
		Plugin.Debug("Mannequin pieces: " + s_pieces.Count);
		PieceManager.OnPiecesRegistered += ClearUsage;
	}

	private static void ClearUsage()
	{
		//IL_0033: Unknown result type (might be due to invalid IL or missing references)
		foreach (GameObject s_piece in s_pieces)
		{
			Piece val = (((Object)(object)s_piece != (Object)null) ? s_piece.GetComponent<Piece>() : null);
			if ((Object)(object)val != (Object)null)
			{
				val.m_usage = (UsageTagFlags)0;
			}
		}
	}

	private static void Make(int body, string key, string label, int standPose, int emote)
	{
		//IL_0043: Unknown result type (might be due to invalid IL or missing references)
		//IL_004a: Expected O, but got Unknown
		//IL_00db: Unknown result type (might be due to invalid IL or missing references)
		//IL_00e1: Expected O, but got Unknown
		//IL_00eb: Unknown result type (might be due to invalid IL or missing references)
		//IL_00f1: Expected O, but got Unknown
		//IL_00fb: Unknown result type (might be due to invalid IL or missing references)
		//IL_0101: Expected O, but got Unknown
		//IL_0108: Unknown result type (might be due to invalid IL or missing references)
		//IL_010e: Expected O, but got Unknown
		string text = "PotatoWright_Mannequin" + BodyLabels[body] + "_" + key;
		string text2 = Text("potatowright_mannequin_" + BodyLabels[body].ToLowerInvariant(), BodyNames[body]);
		string obj = BodyPrefabs[body];
		PieceConfig val = new PieceConfig();
		val.Name = ((emote < 0) ? (text2 + ": " + label) : (text2 + ", " + Text("potatowright_emote", "emote") + ": " + label));
		val.Description = "$potatowright_mannequin_description";
		val.PieceTable = "Hammer";
		val.Category = "Misc";
		val.CraftingStation = "piece_workbench";
		val.Requirements = (RequirementConfig[])(object)new RequirementConfig[3]
		{
			new RequirementConfig("FineWood", 8, 0, true),
			new RequirementConfig("BronzeNails", 2, 0, true),
			new RequirementConfig("Tar", 4, 0, true)
		};
		CustomPiece val2 = new CustomPiece(text, obj, val);
		GameObject piecePrefab = val2.PiecePrefab;
		if ((Object)(object)piecePrefab == (Object)null)
		{
			Debug.LogWarning((object)("[PotatoWright] Mannequin " + text + " not made."));
			return;
		}
		MakePaintable(piecePrefab, body);
		ArmorStand component = piecePrefab.GetComponent<ArmorStand>();
		int num = CleanClothColliders(((Object)(object)component != (Object)null) ? component.m_visEquipment : null);
		if (key == "Pose_APose" && num > 0)
		{
			Plugin.Debug("Mannequin " + BodyPrefabs[body] + ": " + num + " cape collider entries without a cloth collider left out of its pieces");
		}
		string text3 = CleanEffects(piecePrefab);
		if (key == "Pose_APose" && text3.Length > 0)
		{
			Plugin.Debug("Mannequin " + BodyPrefabs[body] + " effect entries without a prefab, left out of its pieces:" + text3);
		}
		MannequinPose mannequinPose = piecePrefab.AddComponent<MannequinPose>();
		mannequinPose.m_standPose = standPose;
		mannequinPose.m_body = body;
		mannequinPose.m_emote = emote;
		piecePrefab.AddComponent<MannequinTint>();
		if (emote < 0 && !MannequinIcons.Make(piecePrefab, standPose, text))
		{
			Plugin.Debug("Stance icon for " + text + " not made");
		}
		PieceManager.Instance.AddPiece(val2);
		s_pieces.Add(piecePrefab);
	}

	public static int CleanClothColliders(VisEquipment vis)
	{
		IList list = (((Object)(object)vis != (Object)null && ClothColliders != null) ? (ClothColliders.GetValue(vis) as IList) : null);
		if (list == null || list.Count == 0)
		{
			return 0;
		}
		if (!s_clothLogged)
		{
			s_clothLogged = true;
			StringBuilder stringBuilder = new StringBuilder();
			foreach (object item in list)
			{
				Object val = (Object)((item is Object) ? item : null);
				stringBuilder.Append(" ").Append((item == null) ? "null" : ((val == (Object)null) ? (item.GetType().Name + "(destroyed)") : (item.GetType().Name + " " + val.name)));
			}
			Plugin.Debug("Mannequin " + ((Object)vis).name + " cape collider entries at run time:" + stringBuilder);
		}
		int count = list.Count;
		list.Clear();
		return count;
	}

	private static string CleanEffects(GameObject piece)
	{
		StringBuilder stringBuilder = new StringBuilder();
		MonoBehaviour[] componentsInChildren = piece.GetComponentsInChildren<MonoBehaviour>(true);
		foreach (MonoBehaviour val in componentsInChildren)
		{
			if ((Object)(object)val == (Object)null)
			{
				continue;
			}
			FieldInfo[] fields = ((object)val).GetType().GetFields(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
			foreach (FieldInfo fieldInfo in fields)
			{
				if (fieldInfo.FieldType != typeof(EffectList))
				{
					continue;
				}
				object? value = fieldInfo.GetValue(val);
				EffectList val2 = (EffectList)((value is EffectList) ? value : null);
				if (val2 == null || val2.m_effectPrefabs == null)
				{
					continue;
				}
				List<EffectData> list = new List<EffectData>();
				EffectData[] effectPrefabs = val2.m_effectPrefabs;
				foreach (EffectData val3 in effectPrefabs)
				{
					if (val3 != null && (Object)(object)val3.m_prefab != (Object)null)
					{
						list.Add(val3);
					}
				}
				if (list.Count != val2.m_effectPrefabs.Length)
				{
					stringBuilder.Append(' ').Append(((object)val).GetType().Name).Append('.')
						.Append(fieldInfo.Name)
						.Append(' ')
						.Append(val2.m_effectPrefabs.Length - list.Count)
						.Append(" of ")
						.Append(val2.m_effectPrefabs.Length);
					val2.m_effectPrefabs = list.ToArray();
				}
			}
		}
		return stringBuilder.ToString();
	}

	private static string Key(string label)
	{
		StringBuilder stringBuilder = new StringBuilder();
		foreach (char c in label)
		{
			if (char.IsLetterOrDigit(c))
			{
				stringBuilder.Append(c);
			}
		}
		return stringBuilder.ToString();
	}

	private static string Spaced(string name)
	{
		StringBuilder stringBuilder = new StringBuilder();
		for (int i = 0; i < name.Length; i++)
		{
			if (i > 0 && char.IsUpper(name[i]))
			{
				stringBuilder.Append(' ');
			}
			stringBuilder.Append(name[i]);
		}
		return stringBuilder.ToString();
	}

	private static string Text(string key, string fallback)
	{
		if (Localization.instance == null)
		{
			return fallback;
		}
		string text = Localization.instance.Localize("$" + key);
		if (!string.IsNullOrEmpty(text) && !text.Contains(key))
		{
			return text;
		}
		return fallback;
	}

	[HarmonyPatch(typeof(ArmorStand), "Awake")]
	[HarmonyPrefix]
	private static void ArmorStand_Awake_Prefix(ArmorStand __instance)
	{
		//IL_00ca: 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_00e1: Unknown result type (might be due to invalid IL or missing references)
		try
		{
			MannequinPose component = ((Component)__instance).GetComponent<MannequinPose>();
			if ((Object)(object)component == (Object)null)
			{
				return;
			}
			ZNetView val = (((Object)(object)__instance.m_netViewOverride != (Object)null) ? __instance.m_netViewOverride : ((Component)__instance).GetComponent<ZNetView>());
			ZDO val2 = (((Object)(object)val != (Object)null) ? val.GetZDO() : null);
			if (val2 == null || !val.IsOwner() || val2.GetInt(InitKey, 0) != 0)
			{
				return;
			}
			val2.Set(InitKey, 1, false);
			val2.Set(ZDOVars.s_pose, Mathf.Max(component.m_standPose, 0), false);
			val2.Set(EmoteKey, component.m_emote, false);
			Player localPlayer = Player.m_localPlayer;
			if ((Object)(object)localPlayer != (Object)null && (Object)(object)localPlayer.m_placementGhost != (Object)null && (Object)(object)localPlayer.m_placementGhost.GetComponent<MannequinTint>() != (Object)null)
			{
				if (!WoodTint.IsNatural(MannequinColor.Current))
				{
					val2.Set(MannequinColor.ColorKey, MannequinColor.ToVector(MannequinColor.Current));
				}
				if (!MannequinColor.ShowBase)
				{
					val2.Set(MannequinColor.NoBaseKey, true);
				}
			}
		}
		catch (Exception ex)
		{
			Debug.LogWarning((object)("[PotatoWright] Mannequin pose not set: " + ex));
		}
	}

	[HarmonyPatch(typeof(ArmorStand), "SetPose")]
	[HarmonyPrefix]
	private static void ArmorStand_SetPose_Prefix(ArmorStand __instance, bool effect)
	{
		if (effect)
		{
			MannequinPose component = ((Component)__instance).GetComponent<MannequinPose>();
			if ((Object)(object)component != (Object)null)
			{
				component.EndEmote();
			}
		}
	}
}
public sealed class MannequinPose : MonoBehaviour
{
	public int m_standPose = -1;

	public int m_emote = -1;

	public int m_body;

	private const float EmoteTimeout = 6f;

	private static readonly int EmoteTag = Animator.StringToHash("emote");

	private ArmorStand m_stand;

	private Animator m_animator;

	private RuntimeAnimatorController m_standController;

	private bool m_emoteOn;

	private bool m_frozen;

	private float m_start;

	private void Start()
	{
		m_stand = ((Component)this).GetComponent<ArmorStand>();
		m_animator = (((Object)(object)m_stand != (Object)null) ? m_stand.m_poseAnimator : null);
		if ((Object)(object)m_animator == (Object)null)
		{
			((Behaviour)this).enabled = false;
			return;
		}
		ZNetView nview = m_stand.m_nview;
		int num;
		if ((Object)(object)nview != (Object)null)
		{
			num = (nview.IsValid() ? 1 : 0);
			if (num != 0)
			{
				goto IL_0084;
			}
		}
		else
		{
			num = 0;
		}
		if (m_standPose >= 0)
		{
			m_animator.SetInteger("Pose", m_standPose);
		}
		goto IL_0084;
		IL_0084:
		int num2 = ((num != 0) ? nview.GetZDO().GetInt(MannequinPieces.EmoteKey, -1) : m_emote);
		if (num2 < 0 || !StartEmote(num2))
		{
			((Behaviour)this).enabled = false;
		}
	}

	private static RuntimeAnimatorController PlayerController()
	{
		GameObject val = (((Object)(object)ZNetScene.instance != (Object)null) ? ZNetScene.instance.GetPrefab("Player") : null);
		Animator val2 = (((Object)(object)val != (Object)null) ? val.GetComponentInChildren<Animator>(true) : null);
		if (!((Object)(object)val2 != (Object)null))
		{
			return null;
		}
		return val2.runtimeAnimatorController;
	}

	private bool StartEmote(int emote)
	{
		//IL_0073: Unknown result type (might be due to invalid IL or missing references)
		RuntimeAnimatorController val = PlayerController();
		if ((Object)(object)val == (Object)null || emote >= 25)
		{
			return false;
		}
		m_standController = m_animator.runtimeAnimatorController;
		m_animator.runtimeAnimatorController = val;
		m_animator.fireEvents = false;
		m_animator.cullingMode = (AnimatorCullingMode)0;
		m_animator.SetBool("wakeup", false);
		m_animator.SetBool("onGround", true);
		string text = "emote_" + ((object)(Emotes)emote/*cast due to .constrained prefix*/).ToString().ToLowerInvariant();
		if (emote == 1)
		{
			m_animator.SetBool(text, true);
		}
		else
		{
			m_animator.SetTrigger(text);
		}
		m_emoteOn = true;
		m_frozen = false;
		m_start = Time.time;
		return true;
	}

	private void Update()
	{
		if (!m_emoteOn || m_frozen || (Object)(object)m_animator == (Object)null)
		{
			((Behaviour)this).enabled = false;
		}
		else if (!(Time.time - m_start < 6f) || EmoteHalfway())
		{
			Freeze();
			((Behaviour)this).enabled = false;
		}
	}

	private bool EmoteHalfway()
	{
		//IL_000b: 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)
		for (int i = 0; i < m_animator.layerCount; i++)
		{
			AnimatorStateInfo currentAnimatorStateInfo = m_animator.GetCurrentAnimatorStateInfo(i);
			if (((AnimatorStateInfo)(ref currentAnimatorStateInfo)).tagHash == EmoteTag && ((AnimatorStateInfo)(ref currentAnimatorStateInfo)).normalizedTime >= 0.5f)
			{
				return true;
			}
		}
		return false;
	}

	private void Freeze()
	{
		//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_0045: Unknown result type (might be due to invalid IL or missing references)
		//IL_004a: Unknown result type (might be due to invalid IL or missing references)
		//IL_0056: 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_0085: 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)
		//IL_00a7: Unknown result type (might be due to invalid IL or missing references)
		Transform[] componentsInChildren = ((Component)m_animator).GetComponentsInChildren<Transform>(true);
		Vector3[] array = (Vector3[])(object)new Vector3[componentsInChildren.Length];
		Quaternion[] array2 = (Quaternion[])(object)new Quaternion[componentsInChildren.Length];
		Vector3[] array3 = (Vector3[])(object)new Vector3[componentsInChildren.Length];
		for (int i = 0; i < componentsInChildren.Length; i++)
		{
			array[i] = componentsInChildren[i].localPosition;
			array2[i] = componentsInChildren[i].localRotation;
			array3[i] = componentsInChildren[i].localScale;
		}
		((Behaviour)m_animator).enabled = false;
		for (int j = 0; j < componentsInChildren.Length; j++)
		{
			componentsInChildren[j].localPosition = array[j];
			componentsInChildren[j].localRotation = array2[j];
			componentsInChildren[j].localScale = array3[j];
		}
		m_frozen = true;
	}

	public void EndEmote()
	{
		if (m_emoteOn && !((Object)(object)m_animator == (Object)null))
		{
			m_emoteOn = false;
			m_frozen = false;
			((Behaviour)this).enabled = false;
			((Behaviour)m_animator).enabled = true;
			if ((Object)(object)m_standController != (Object)null)
			{
				m_animator.runtimeAnimatorController = m_standController;
			}
			ZNetView val = (((Object)(object)m_stand != (Object)null) ? m_stand.m_nview : null);
			if ((Object)(object)val != (Object)null && val.IsValid() && val.IsOwner())
			{
				val.GetZDO().Set(