Decompiled source of VargheimStatues v0.4.1

plugins/VargheimStatues.dll

Decompiled 4 days ago
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Globalization;
using System.IO;
using System.Reflection;
using System.Runtime.CompilerServices;
using BepInEx;
using BepInEx.Configuration;
using HarmonyLib;
using Microsoft.CodeAnalysis;
using UnityEngine;
using UnityEngine.Rendering;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: AssemblyVersion("0.0.0.0")]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[Embedded]
	[AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)]
	internal sealed class RefSafetyRulesAttribute : Attribute
	{
		public readonly int Version;

		public RefSafetyRulesAttribute(int P_0)
		{
			Version = P_0;
		}
	}
}
namespace VargheimStatues
{
	internal class Blessing
	{
		internal string Name;

		internal float Radius = 30f;

		internal bool NoSpawn;

		internal SE_Stats Effect;

		internal readonly Dictionary<string, float> Values = new Dictionary<string, float>();

		private static Sprite s_icon;

		internal int Hash => StringExtensionMethods.GetStableHashCode("VS_" + Name);

		internal string Describe()
		{
			List<string> list = new List<string>();
			foreach (KeyValuePair<string, float> value in Values)
			{
				if (value.Key == "nospawn")
				{
					list.Add("no spawns");
				}
				else if (!(value.Key == "radius"))
				{
					list.Add(value.Key + " " + value.Value.ToString("0.##", CultureInfo.InvariantCulture));
				}
			}
			return string.Join(", ", list.ToArray()) + ", " + Radius.ToString("0", CultureInfo.InvariantCulture) + " m";
		}

		internal static void Register(ObjectDB db)
		{
			if (Plugin.s_blessings.Count == 0)
			{
				string[] array = Plugin.Blessings.Value.Split(';');
				foreach (string text in array)
				{
					int num = text.IndexOf(':');
					if (num < 0)
					{
						continue;
					}
					Blessing blessing = new Blessing
					{
						Name = text.Substring(0, num).Trim().ToLowerInvariant()
					};
					if (blessing.Name.Length == 0)
					{
						continue;
					}
					string[] array2 = text.Substring(num + 1).Split(',');
					for (int j = 0; j < array2.Length; j++)
					{
						string[] array3 = array2[j].Split('=');
						if (array3.Length == 2 && float.TryParse(array3[1].Trim(), NumberStyles.Float, CultureInfo.InvariantCulture, out var result))
						{
							blessing.Values[array3[0].Trim().ToLowerInvariant()] = result;
						}
					}
					if (blessing.Values.TryGetValue("radius", out var value) && value > 0f)
					{
						blessing.Radius = value;
					}
					blessing.NoSpawn = blessing.Values.TryGetValue("nospawn", out var value2) && value2 > 0f;
					blessing.Effect = MakeEffect(blessing);
					Plugin.s_blessings[blessing.Name] = blessing;
				}
				Plugin.Note(Plugin.s_blessings.Count + " blessings defined.");
			}
			foreach (Blessing value3 in Plugin.s_blessings.Values)
			{
				if ((Object)(object)value3.Effect != (Object)null && !db.m_StatusEffects.Contains((StatusEffect)(object)value3.Effect))
				{
					db.m_StatusEffects.Add((StatusEffect)(object)value3.Effect);
				}
			}
		}

		private static SE_Stats MakeEffect(Blessing b)
		{
			//IL_0152: Unknown result type (might be due to invalid IL or missing references)
			//IL_0159: Unknown result type (might be due to invalid IL or missing references)
			//IL_0160: Unknown result type (might be due to invalid IL or missing references)
			//IL_0167: Unknown result type (might be due to invalid IL or missing references)
			SE_Stats obj = ScriptableObject.CreateInstance<SE_Stats>();
			((Object)obj).name = "VS_" + b.Name;
			((StatusEffect)obj).m_name = "Blessing of " + Cap(b.Name);
			((StatusEffect)obj).m_tooltip = "A statue's blessing: " + b.Describe();
			((StatusEffect)obj).m_ttl = 5f;
			((StatusEffect)obj).m_icon = Icon();
			obj.m_healthRegenMultiplier = (b.Values.TryGetValue("hpregen", out var value) ? value : 1f);
			obj.m_staminaRegenMultiplier = (b.Values.TryGetValue("stamregen", out value) ? value : 1f);
			obj.m_eitrRegenMultiplier = (b.Values.TryGetValue("eitrregen", out value) ? value : 1f);
			obj.m_addMaxCarryWeight = (b.Values.TryGetValue("carry", out value) ? value : 0f);
			obj.m_speedModifier = (b.Values.TryGetValue("speed", out value) ? value : 0f);
			obj.m_raiseSkillModifier = (b.Values.TryGetValue("skillgain", out value) ? value : 0f);
			obj.m_damageModifier = (b.Values.TryGetValue("damage", out value) ? value : 0f);
			obj.m_raiseSkill = (SkillType)0;
			obj.m_modifyAttackSkill = (SkillType)0;
			obj.m_skillLevel = (SkillType)0;
			obj.m_skillLevel2 = (SkillType)0;
			return obj;
		}

		private static Sprite Icon()
		{
			if ((Object)(object)s_icon != (Object)null)
			{
				return s_icon;
			}
			ObjectDB instance = ObjectDB.instance;
			if ((Object)(object)instance == (Object)null)
			{
				return null;
			}
			foreach (StatusEffect statusEffect in instance.m_StatusEffects)
			{
				if ((Object)(object)statusEffect != (Object)null && ((Object)statusEffect).name == "Rested" && (Object)(object)statusEffect.m_icon != (Object)null)
				{
					s_icon = statusEffect.m_icon;
					break;
				}
			}
			return s_icon;
		}

		private static string Cap(string s)
		{
			if (s.Length != 0)
			{
				return char.ToUpperInvariant(s[0]) + s.Substring(1);
			}
			return s;
		}
	}
	internal class StatueBuff : MonoBehaviour, Hoverable
	{
		public string m_label = "Statue";

		public string m_key = "";

		public string m_creature = "";

		public string m_pose = "";

		public string m_parts = "";

		public float m_tweak = 1f;

		private ZNetView m_nview;

		private float m_t;

		private string m_current = "";

		private GameObject m_area;

		private bool Valid
		{
			get
			{
				if ((Object)(object)m_nview != (Object)null)
				{
					return m_nview.IsValid();
				}
				return false;
			}
		}

		internal string Current
		{
			get
			{
				if (!Valid)
				{
					return "";
				}
				return m_nview.GetZDO().GetString("vs_bless", "");
			}
		}

		private void Awake()
		{
			m_nview = ((Component)this).GetComponent<ZNetView>();
		}

		internal void SetBlessing(string name)
		{
			if (Valid)
			{
				m_nview.ClaimOwnership();
				m_nview.GetZDO().Set("vs_bless", name ?? "");
			}
		}

		private void Update()
		{
			//IL_00a4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00af: Unknown result type (might be due to invalid IL or missing references)
			m_t += Time.deltaTime;
			if (m_t < 1f)
			{
				return;
			}
			m_t = 0f;
			if (!Valid)
			{
				return;
			}
			string current = Current;
			Plugin.s_blessings.TryGetValue(current, out var value);
			if (current != m_current)
			{
				m_current = current;
				Area((value != null && value.NoSpawn) ? value.Radius : 0f);
			}
			if (value != null && !((Object)(object)value.Effect == (Object)null))
			{
				Player localPlayer = Player.m_localPlayer;
				if (!((Object)(object)localPlayer == (Object)null) && !(Vector3.Distance(((Component)localPlayer).transform.position, ((Component)this).transform.position) > value.Radius))
				{
					((Character)localPlayer).GetSEMan().AddStatusEffect(value.Hash, true, 0, 0f, (short)0);
				}
			}
		}

		private void Area(float radius)
		{
			//IL_002f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0039: Expected O, but got Unknown
			//IL_008a: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)m_area != (Object)null)
			{
				Object.Destroy((Object)(object)m_area);
				m_area = null;
			}
			if (!(radius <= 0f))
			{
				m_area = new GameObject("statue_peace");
				m_area.transform.SetParent(((Component)this).transform, false);
				m_area.layer = LayerMask.NameToLayer("character_trigger");
				SphereCollider obj = m_area.AddComponent<SphereCollider>();
				((Collider)obj).isTrigger = true;
				obj.radius = radius;
				m_area.AddComponent<EffectArea>().m_type = (Type)36;
			}
		}

		public string GetHoverText()
		{
			string text = "<color=orange>" + m_label + "</color>";
			string current = Current;
			if (current.Length > 0 && Plugin.s_blessings.TryGetValue(current, out var value))
			{
				text = text + "\nBlessing of " + char.ToUpperInvariant(current[0]) + current.Substring(1) + ": " + value.Describe();
			}
			else if (Plugin.IsAdmin())
			{
				text += "\n<color=grey>vstatue bless <name></color>";
			}
			return Localization.instance.Localize(text);
		}

		public string GetHoverName()
		{
			return m_label;
		}

		public float GetHoverOffset()
		{
			return 0f;
		}
	}
	internal static class Carve
	{
		private static Material s_figure;

		private static Material s_plinth;

		private static Material s_base;

		private static readonly string[] s_primitives = new string[6] { "capsule", "sphere", "cube", "cylinder", "quad", "plane" };

		private static readonly string[] s_fxShaders = new string[12]
		{
			"particle", "unlit", "additive", "distort", "fx", "trail", "lightning", "glow", "flare", "water",
			"skybox", "billboard"
		};

		private static string s_parts = "";

		private static List<string> s_partNames;

		private static GameObject s_awake;

		private static Mesh s_obj;

		private static GameObject s_holder;

		private static readonly Dictionary<Material, Material> s_stone = new Dictionary<Material, Material>();

		internal static GameObject MakePiece(ObjectDB db, ZNetScene zs, GameObject basePiece, string key, string creature, string label, float tweak, string pose, string parts, Requirement[] reqs)
		{
			//IL_011b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0126: Unknown result type (might be due to invalid IL or missing references)
			//IL_0149: Unknown result type (might be due to invalid IL or missing references)
			//IL_02a5: Unknown result type (might be due to invalid IL or missing references)
			//IL_0309: Unknown result type (might be due to invalid IL or missing references)
			//IL_0312: Unknown result type (might be due to invalid IL or missing references)
			//IL_0314: Unknown result type (might be due to invalid IL or missing references)
			//IL_0320: Unknown result type (might be due to invalid IL or missing references)
			//IL_0322: Unknown result type (might be due to invalid IL or missing references)
			//IL_032e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0330: Unknown result type (might be due to invalid IL or missing references)
			//IL_033c: Unknown result type (might be due to invalid IL or missing references)
			//IL_033e: Unknown result type (might be due to invalid IL or missing references)
			//IL_034a: Unknown result type (might be due to invalid IL or missing references)
			//IL_034c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0358: Unknown result type (might be due to invalid IL or missing references)
			//IL_035a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0366: Unknown result type (might be due to invalid IL or missing references)
			//IL_0368: Unknown result type (might be due to invalid IL or missing references)
			//IL_0374: Unknown result type (might be due to invalid IL or missing references)
			//IL_0376: Unknown result type (might be due to invalid IL or missing references)
			//IL_0382: Unknown result type (might be due to invalid IL or missing references)
			//IL_0384: Unknown result type (might be due to invalid IL or missing references)
			//IL_0390: Unknown result type (might be due to invalid IL or missing references)
			//IL_0392: Unknown result type (might be due to invalid IL or missing references)
			//IL_041b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0420: Unknown result type (might be due to invalid IL or missing references)
			GameObject val = null;
			s_obj = null;
			if (ObjModel.IsObj(creature))
			{
				s_obj = ObjModel.Load(creature);
				if ((Object)(object)s_obj == (Object)null)
				{
					return null;
				}
			}
			else
			{
				string[] array = creature.Split('|');
				foreach (string text in array)
				{
					val = Plugin.FindPrefab(db, zs, text.Trim());
					if ((Object)(object)val != (Object)null)
					{
						break;
					}
				}
				if ((Object)(object)val == (Object)null)
				{
					Plugin.Warn("creature prefab '" + creature + "' not found for statue " + key + ".");
					return null;
				}
			}
			GameObject val2 = Object.Instantiate<GameObject>(basePiece, Holder(), false);
			((Object)val2).name = "VargheimStatue_" + key;
			Piece component = val2.GetComponent<Piece>();
			component.m_name = "Statue: " + label;
			component.m_description = label + ", carved in stone, " + Plugin.Height.Value.ToString("0", CultureInfo.InvariantCulture) + " m tall. An admin can bless it (vstatue).";
			component.m_resources = reqs;
			component.m_category = (PieceCategory)0;
			component.m_usage = (UsageTagFlags)513;
			component.m_groundOnly = true;
			component.m_noInWater = false;
			component.m_allowedInDungeons = false;
			component.m_comfort = 1;
			component.m_comfortGroup = (ComfortGroup)0;
			Renderer[] componentsInChildren = val2.GetComponentsInChildren<Renderer>(true);
			for (int i = 0; i < componentsInChildren.Length; i++)
			{
				componentsInChildren[i].enabled = false;
			}
			Collider[] componentsInChildren2 = val2.GetComponentsInChildren<Collider>(true);
			for (int i = 0; i < componentsInChildren2.Length; i++)
			{
				componentsInChildren2[i].enabled = false;
			}
			List<GameObject> list = new List<GameObject>();
			Transform[] componentsInChildren3 = val2.GetComponentsInChildren<Transform>(true);
			foreach (Transform val3 in componentsInChildren3)
			{
				if ((Object)(object)val3 != (Object)(object)val2.transform && ((Object)val3).name.StartsWith("_snappoint", StringComparison.OrdinalIgnoreCase))
				{
					list.Add(((Component)val3).gameObject);
				}
			}
			foreach (GameObject item in list)
			{
				Object.DestroyImmediate((Object)(object)item);
			}
			s_parts = parts ?? "";
			if (!Shape(val2.transform, val, tweak, pose, db, zs, out var radius, out var poseUsed, out var b, out var scale))
			{
				Object.Destroy((Object)(object)val2);
				Plugin.Warn("no meshes baked for " + creature + ".");
				return null;
			}
			if (Plugin.ClearGrass.Value)
			{
				TerrainModifier obj = val2.AddComponent<TerrainModifier>();
				obj.m_level = false;
				obj.m_smooth = false;
				obj.m_square = false;
				obj.m_paintCleared = true;
				obj.m_paintHeightCheck = false;
				obj.m_paintType = (PaintType)4;
				obj.m_paintRadius = radius * 1.12f + 0.5f;
				obj.m_playerModifiction = false;
			}
			WearNTear component2 = val2.GetComponent<WearNTear>();
			if ((Object)(object)component2 != (Object)null)
			{
				component2.m_health = 20000f;
				component2.m_noRoofWear = true;
				component2.m_noSupportWear = SupportWear.Off();
				if (Plugin.Indestructible.Value)
				{
					DamageModifier val4 = (DamageModifier)3;
					component2.m_damages.m_blunt = val4;
					component2.m_damages.m_slash = val4;
					component2.m_damages.m_pierce = val4;
					component2.m_damages.m_chop = val4;
					component2.m_damages.m_pickaxe = val4;
					component2.m_damages.m_fire = val4;
					component2.m_damages.m_frost = val4;
					component2.m_damages.m_lightning = val4;
					component2.m_damages.m_poison = val4;
					component2.m_damages.m_spirit = val4;
				}
			}
			Sprite val5 = Icon.Render(val2, key);
			if ((Object)(object)val5 != (Object)null)
			{
				component.m_icon = val5;
			}
			StatueBuff statueBuff = val2.AddComponent<StatueBuff>();
			statueBuff.m_label = label;
			statueBuff.m_key = key;
			statueBuff.m_creature = creature;
			statueBuff.m_tweak = tweak;
			statueBuff.m_pose = pose;
			statueBuff.m_parts = parts ?? "";
			Plugin.Note("statue " + key + " from " + creature + ": " + ((Bounds)(ref b)).size.y.ToString("0.0", CultureInfo.InvariantCulture) + " m source, scale " + scale.ToString("0.00", CultureInfo.InvariantCulture) + ", pose " + poseUsed + ", finish " + (Carved() ? "carved" : "flat"));
			return val2;
		}

		private static void Drum(Transform parent, string name, float radius, float y, float height, Material mat, int layer)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_000e: Unknown result type (might be due to invalid IL or missing references)
			//IL_001b: Unknown result type (might be due to invalid IL or missing references)
			//IL_002c: 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_004d: Unknown result type (might be due to invalid IL or missing references)
			GameObject val = new GameObject(name)
			{
				layer = layer
			};
			val.transform.SetParent(parent, false);
			val.transform.localPosition = new Vector3(0f, y, 0f);
			Mesh sharedMesh = Cylinder(radius, height, 32);
			val.AddComponent<MeshFilter>().sharedMesh = sharedMesh;
			MeshRenderer obj = val.AddComponent<MeshRenderer>();
			((Renderer)obj).sharedMaterial = mat;
			((Renderer)obj).shadowCastingMode = (ShadowCastingMode)1;
			MeshCollider obj2 = val.AddComponent<MeshCollider>();
			obj2.sharedMesh = sharedMesh;
			obj2.convex = true;
		}

		private static Vector2 FootCentre(Transform figure, Bounds b, float ground)
		{
			//IL_0003: 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_016b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0177: Unknown result type (might be due to invalid IL or missing references)
			//IL_0181: 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_00a4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00af: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bd: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c7: 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_00ce: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f2: Unknown result type (might be due to invalid IL or missing references)
			//IL_0106: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fd: Unknown result type (might be due to invalid IL or missing references)
			//IL_011a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0111: Unknown result type (might be due to invalid IL or missing references)
			//IL_012e: 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_0139: Unknown result type (might be due to invalid IL or missing references)
			float num = ground + ((Bounds)(ref b)).size.y * 0.08f;
			double num2 = 0.0;
			double num3 = 0.0;
			int num4 = 0;
			float num5 = float.MaxValue;
			float num6 = float.MinValue;
			float num7 = float.MaxValue;
			float num8 = float.MinValue;
			MeshFilter[] componentsInChildren = ((Component)figure).GetComponentsInChildren<MeshFilter>(true);
			foreach (MeshFilter val in componentsInChildren)
			{
				Mesh sharedMesh = val.sharedMesh;
				if ((Object)(object)sharedMesh == (Object)null || !sharedMesh.isReadable)
				{
					continue;
				}
				Transform transform = ((Component)val).transform;
				Vector3[] vertices = sharedMesh.vertices;
				foreach (Vector3 val2 in vertices)
				{
					Vector3 val3 = transform.localPosition + transform.localRotation * Vector3.Scale(val2, transform.localScale);
					if (!(val3.y > num))
					{
						num2 += (double)val3.x;
						num3 += (double)val3.z;
						num4++;
						if (val3.x < num5)
						{
							num5 = val3.x;
						}
						if (val3.x > num6)
						{
							num6 = val3.x;
						}
						if (val3.z < num7)
						{
							num7 = val3.z;
						}
						if (val3.z > num8)
						{
							num8 = val3.z;
						}
					}
				}
			}
			if (num4 < 20)
			{
				return new Vector2(((Bounds)(ref b)).center.x, ((Bounds)(ref b)).center.z);
			}
			return new Vector2(((float)(num2 / (double)num4) + (num5 + num6) * 0.5f) * 0.5f, ((float)(num3 / (double)num4) + (num7 + num8) * 0.5f) * 0.5f);
		}

		private static float LowRadius(Transform figure, Bounds b, Vector2 centre)
		{
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			//IL_000e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0079: 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_0089: Unknown result type (might be due to invalid IL or missing references)
			//IL_0090: Unknown result type (might be due to invalid IL or missing references)
			//IL_0095: Unknown result type (might be due to invalid IL or missing references)
			//IL_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_00a4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c7: Unknown result type (might be due to invalid IL or missing references)
			float num = ((Bounds)(ref b)).min.y + ((Bounds)(ref b)).size.y * 0.2f;
			float num2 = 0f;
			bool flag = false;
			MeshFilter[] componentsInChildren = ((Component)figure).GetComponentsInChildren<MeshFilter>(true);
			foreach (MeshFilter val in componentsInChildren)
			{
				Mesh sharedMesh = val.sharedMesh;
				if ((Object)(object)sharedMesh == (Object)null || !sharedMesh.isReadable)
				{
					continue;
				}
				Transform transform = ((Component)val).transform;
				Vector3[] vertices = sharedMesh.vertices;
				for (int j = 0; j < vertices.Length; j++)
				{
					Vector3 val2 = transform.localPosition + transform.localRotation * Vector3.Scale(vertices[j], transform.localScale);
					if (!(val2.y > num))
					{
						float num3 = val2.x - centre.x;
						float num4 = val2.z - centre.y;
						float num5 = Mathf.Sqrt(num3 * num3 + num4 * num4);
						if (num5 > num2)
						{
							num2 = num5;
						}
						flag = true;
					}
				}
			}
			if (!flag)
			{
				return 0f;
			}
			return num2;
		}

		private static float GroundY(Transform figure, Bounds b)
		{
			//IL_00c0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ad: Unknown result type (might be due to invalid IL or missing references)
			//IL_004e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0053: Unknown result type (might be due to invalid IL or missing references)
			//IL_0058: Unknown result type (might be due to invalid IL or missing references)
			//IL_005f: 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_0068: Unknown result type (might be due to invalid IL or missing references)
			//IL_006d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0072: Unknown result type (might be due to invalid IL or missing references)
			//IL_0077: Unknown result type (might be due to invalid IL or missing references)
			List<float> list = new List<float>();
			MeshFilter[] componentsInChildren = ((Component)figure).GetComponentsInChildren<MeshFilter>(true);
			foreach (MeshFilter val in componentsInChildren)
			{
				Mesh sharedMesh = val.sharedMesh;
				if (!((Object)(object)sharedMesh == (Object)null) && sharedMesh.isReadable)
				{
					Transform transform = ((Component)val).transform;
					Vector3[] vertices = sharedMesh.vertices;
					foreach (Vector3 val2 in vertices)
					{
						list.Add((transform.localPosition + transform.localRotation * Vector3.Scale(val2, transform.localScale)).y);
					}
				}
			}
			if (list.Count < 50)
			{
				return ((Bounds)(ref b)).min.y;
			}
			list.Sort();
			return Mathf.Max(((Bounds)(ref b)).min.y, list[Mathf.Clamp((int)((float)list.Count * 0.015f), 0, list.Count - 1)]);
		}

		private static int Rule(Renderer r, Transform root)
		{
			if (string.IsNullOrEmpty(s_parts))
			{
				return 0;
			}
			string[] array = s_parts.Split('|');
			for (int i = 0; i < array.Length; i++)
			{
				string text = array[i].Trim().ToLowerInvariant();
				if (text.Length < 2)
				{
					continue;
				}
				char c = text[0];
				string value = text.Substring(1);
				Transform val = ((Component)r).transform;
				while ((Object)(object)val != (Object)null && (Object)(object)val != (Object)(object)root)
				{
					if (((Object)val).name.ToLowerInvariant().Contains(value))
					{
						if (c != '-')
						{
							return 1;
						}
						return -1;
					}
					val = val.parent;
				}
			}
			return 0;
		}

		private static bool Keep(Renderer r, Transform root)
		{
			//IL_009a: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)r == (Object)null)
			{
				return false;
			}
			int num = Rule(r, root);
			if (num < 0)
			{
				Dropped(r, "left out by the figure's parts rule");
				return false;
			}
			if (num == 0)
			{
				if (!r.enabled)
				{
					return false;
				}
				Transform val = ((Component)r).transform;
				while ((Object)(object)val != (Object)null && (Object)(object)val != (Object)(object)root)
				{
					if (!((Component)val).gameObject.activeSelf)
					{
						Dropped(r, "hidden by default");
						return false;
					}
					val = val.parent;
				}
			}
			Mesh val2 = ((r is SkinnedMeshRenderer) ? ((SkinnedMeshRenderer)r).sharedMesh : (((Object)(object)((Component)r).GetComponent<MeshFilter>() != (Object)null) ? ((Component)r).GetComponent<MeshFilter>().sharedMesh : null));
			if ((Object)(object)val2 == (Object)null)
			{
				return false;
			}
			string text = ((Object)val2).name.ToLowerInvariant().Replace(" instance", "").Trim();
			string text2 = ((Object)((Component)r).gameObject).name.ToLowerInvariant();
			string[] array = s_primitives;
			foreach (string text3 in array)
			{
				if (text == text3 && (text2.StartsWith(text3) || text2.Contains("collider") || text2.Contains("hit") || text2.Contains("debug") || text2.Contains("bounds")))
				{
					Dropped(r, "helper " + text);
					return false;
				}
			}
			Material sharedMaterial = r.sharedMaterial;
			if ((Object)(object)sharedMaterial != (Object)null && (Object)(object)sharedMaterial.shader != (Object)null)
			{
				string text4 = ((Object)sharedMaterial.shader).name.ToLowerInvariant();
				array = s_fxShaders;
				foreach (string value in array)
				{
					if (text4.Contains(value))
					{
						Dropped(r, "effect shader " + ((Object)sharedMaterial.shader).name);
						return false;
					}
				}
			}
			return true;
		}

		private static void Dropped(Renderer r, string why)
		{
			Plugin.Note("  left out " + ((Object)((Component)r).gameObject).name + " (" + why + ")");
		}

		private static bool Strip(GameObject go)
		{
			//IL_0088: Unknown result type (might be due to invalid IL or missing references)
			//IL_008f: Expected O, but got Unknown
			MonoBehaviour[] componentsInChildren;
			for (int i = 0; i < 6; i++)
			{
				List<MonoBehaviour> list = new List<MonoBehaviour>();
				componentsInChildren = go.GetComponentsInChildren<MonoBehaviour>(true);
				foreach (MonoBehaviour val in componentsInChildren)
				{
					if ((Object)(object)val != (Object)null)
					{
						list.Add(val);
					}
				}
				if (list.Count == 0)
				{
					break;
				}
				HashSet<Type> hashSet = new HashSet<Type>();
				foreach (MonoBehaviour item in list)
				{
					object[] customAttributes = ((object)item).GetType().GetCustomAttributes(typeof(RequireComponent), inherit: true);
					for (int j = 0; j < customAttributes.Length; j++)
					{
						RequireComponent val2 = (RequireComponent)customAttributes[j];
						if (val2.m_Type0 != null)
						{
							hashSet.Add(val2.m_Type0);
						}
						if (val2.m_Type1 != null)
						{
							hashSet.Add(val2.m_Type1);
						}
						if (val2.m_Type2 != null)
						{
							hashSet.Add(val2.m_Type2);
						}
					}
				}
				int num = 0;
				int num2 = 0;
				foreach (MonoBehaviour item2 in list)
				{
					if ((Object)(object)item2 == (Object)null)
					{
						continue;
					}
					bool flag = false;
					foreach (Type item3 in hashSet)
					{
						if (item3.IsAssignableFrom(((object)item2).GetType()))
						{
							flag = true;
							break;
						}
					}
					if (!flag)
					{
						try
						{
							Object.DestroyImmediate((Object)(object)item2);
							num++;
						}
						catch (Exception)
						{
							num2++;
						}
					}
				}
				Rigidbody[] componentsInChildren2 = go.GetComponentsInChildren<Rigidbody>(true);
				foreach (Rigidbody val3 in componentsInChildren2)
				{
					try
					{
						val3.isKinematic = true;
					}
					catch (Exception)
					{
					}
				}
				if (num != 0 || num2 != 0)
				{
					continue;
				}
				componentsInChildren = go.GetComponentsInChildren<MonoBehaviour>(true);
				foreach (MonoBehaviour val4 in componentsInChildren)
				{
					if (!((Object)(object)val4 == (Object)null))
					{
						try
						{
							Object.DestroyImmediate((Object)(object)val4);
						}
						catch (Exception)
						{
						}
					}
				}
				break;
			}
			componentsInChildren = go.GetComponentsInChildren<MonoBehaviour>(true);
			for (int j = 0; j < componentsInChildren.Length; j++)
			{
				if ((Object)(object)componentsInChildren[j] != (Object)null)
				{
					return false;
				}
			}
			Animator[] componentsInChildren3 = go.GetComponentsInChildren<Animator>(true);
			for (int j = 0; j < componentsInChildren3.Length; j++)
			{
				((Behaviour)componentsInChildren3[j]).enabled = false;
			}
			return true;
		}

		private static Transform Awake()
		{
			//IL_0012: Unknown result type (might be due to invalid IL or missing references)
			//IL_001c: Expected O, but got Unknown
			//IL_0035: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)s_awake == (Object)null)
			{
				s_awake = new GameObject("VargheimStatues_Bake");
				s_awake.transform.position = new Vector3(0f, -5000f, 0f);
				Object.DontDestroyOnLoad((Object)(object)s_awake);
			}
			return s_awake.transform;
		}

		internal static bool Shape(Transform piece, GameObject src, float tweak, string pose, ObjectDB db, ZNetScene zs, out float radius, out string poseUsed, out Bounds b, out float scale)
		{
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			//IL_000b: Expected O, but got Unknown
			//IL_0063: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ca: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ea: 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_0126: Unknown result type (might be due to invalid IL or missing references)
			//IL_012e: 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_0153: Unknown result type (might be due to invalid IL or missing references)
			//IL_0159: Unknown result type (might be due to invalid IL or missing references)
			//IL_015e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0166: Unknown result type (might be due to invalid IL or missing references)
			//IL_0179: Unknown result type (might be due to invalid IL or missing references)
			//IL_0185: Unknown result type (might be due to invalid IL or missing references)
			//IL_0191: Unknown result type (might be due to invalid IL or missing references)
			//IL_019d: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ba: 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_02f5: Unknown result type (might be due to invalid IL or missing references)
			//IL_034a: Unknown result type (might be due to invalid IL or missing references)
			//IL_035a: Unknown result type (might be due to invalid IL or missing references)
			GameObject val = new GameObject("statue_figure");
			val.transform.SetParent(piece, false);
			s_partNames = new List<string>();
			Bounds? val2;
			if ((Object)(object)s_obj != (Object)null)
			{
				Bounds? total = null;
				int n = 0;
				Add(val.transform, val.transform, val.transform, s_obj, (Material[])(object)new Material[1] { FigureMat() }, ref total, ref n, Vector3.one);
				val2 = total;
				poseUsed = "model";
			}
			else
			{
				val2 = Bake(src, val.transform, pose, out poseUsed);
			}
			Plugin.Note("  parts: " + string.Join(", ", s_partNames.ToArray()));
			s_partNames = null;
			radius = 0f;
			scale = 1f;
			b = default(Bounds);
			if (!val2.HasValue)
			{
				Object.DestroyImmediate((Object)(object)val);
				return false;
			}
			b = val2.Value;
			float value = Plugin.PlinthHeight.Value;
			scale = Plugin.Height.Value * tweak / Mathf.Max(0.01f, ((Bounds)(ref b)).size.y);
			val.transform.localScale = Vector3.one * scale;
			float num = GroundY(val.transform, b);
			Vector2 val3 = FootCentre(val.transform, b, num);
			val.transform.localPosition = new Vector3((0f - val3.x) * scale, value - num * scale, (0f - val3.y) * scale);
			float num2 = Mathf.Max(((Bounds)(ref b)).size.x, ((Bounds)(ref b)).size.z) * scale;
			float num3 = LowRadius(val.transform, b, val3) * scale;
			radius = ((Plugin.PlinthRadius.Value > 0f) ? Plugin.PlinthRadius.Value : ((num3 > 0f) ? (num3 * 1.2f + 0.6f) : (num2 * 0.45f)));
			radius = Mathf.Clamp(radius, 1.5f, Mathf.Max(2f, Plugin.Height.Value * 0.4f));
			int layer = ((Component)piece).gameObject.layer;
			if (value > 0f)
			{
				float num4 = Mathf.Min(0.15f, value * 0.15f);
				float num5 = Mathf.Min(0.35f, value * 0.3f);
				Material mat = PlinthMat(db, zs);
				Drum(piece, "statue_plinth_footing", radius * 1.12f, -1.5f, num5 + 1.5f, mat, layer);
				Drum(piece, "statue_plinth", radius, num5, Mathf.Max(0.05f, value - num5 - num4), mat, layer);
				Drum(piece, "statue_plinth_lip", radius * 1.04f, value - num4, num4, mat, layer);
			}
			BoxCollider obj = ((Component)piece).gameObject.AddComponent<BoxCollider>();
			float num6 = ((Bounds)(ref b)).size.y * scale;
			float num7 = Mathf.Clamp((num3 > 0f) ? (num3 * 1.6f) : (num2 * 0.5f), 1f, radius * 1.8f);
			obj.center = new Vector3(0f, value + num6 / 2f, 0f);
			obj.size = new Vector3(num7, num6, num7);
			return true;
		}

		internal static string Repose(StatueBuff sb, string pose)
		{
			//IL_00bf: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c6: Expected O, but got Unknown
			GameObject val = null;
			s_obj = null;
			if (ObjModel.IsObj(sb.m_creature))
			{
				s_obj = ObjModel.Load(sb.m_creature);
				if ((Object)(object)s_obj == (Object)null)
				{
					return "model not found.";
				}
			}
			else
			{
				string[] array = sb.m_creature.Split('|');
				foreach (string text in array)
				{
					val = Plugin.FindPrefab(ObjectDB.instance, ZNetScene.instance, text.Trim());
					if ((Object)(object)val != (Object)null)
					{
						break;
					}
				}
				if ((Object)(object)val == (Object)null)
				{
					return "creature prefab '" + sb.m_creature + "' not found.";
				}
			}
			Transform transform = ((Component)sb).transform;
			List<GameObject> list = new List<GameObject>();
			foreach (Transform item in transform)
			{
				Transform val2 = item;
				if (((Object)val2).name.StartsWith("statue_", StringComparison.Ordinal))
				{
					list.Add(((Component)val2).gameObject);
				}
			}
			foreach (GameObject item2 in list)
			{
				Object.Destroy((Object)(object)item2);
			}
			BoxCollider[] components = ((Component)transform).GetComponents<BoxCollider>();
			foreach (BoxCollider val3 in components)
			{
				if (((Collider)val3).enabled)
				{
					Object.Destroy((Object)(object)val3);
				}
			}
			s_parts = sb.m_parts ?? "";
			if (!Shape(transform, val, sb.m_tweak, pose, ObjectDB.instance, ZNetScene.instance, out var _, out var poseUsed, out var _, out var _))
			{
				return "nothing could be baked.";
			}
			sb.m_pose = pose;
			return "pose " + poseUsed;
		}

		internal static string Clips(string creature)
		{
			if (ObjModel.IsObj(creature))
			{
				return "a sculpted model - no animations, use vstatue size to resize it.";
			}
			GameObject val = null;
			string[] array = creature.Split('|');
			foreach (string text in array)
			{
				val = Plugin.FindPrefab(ObjectDB.instance, ZNetScene.instance, text.Trim());
				if ((Object)(object)val != (Object)null)
				{
					break;
				}
			}
			if ((Object)(object)val == (Object)null)
			{
				return "creature prefab '" + creature + "' not found.";
			}
			Animator componentInChildren = val.GetComponentInChildren<Animator>(true);
			if ((Object)(object)componentInChildren == (Object)null || (Object)(object)componentInChildren.runtimeAnimatorController == (Object)null)
			{
				return ((Object)val).name + " has no animations (its rest pose is the only one).";
			}
			List<string> list = new List<string>();
			AnimationClip[] animationClips = componentInChildren.runtimeAnimatorController.animationClips;
			foreach (AnimationClip val2 in animationClips)
			{
				if ((Object)(object)val2 != (Object)null && !list.Contains(((Object)val2).name + " (" + val2.length.ToString("0.0", CultureInfo.InvariantCulture) + "s)"))
				{
					list.Add(((Object)val2).name + " (" + val2.length.ToString("0.0", CultureInfo.InvariantCulture) + "s)");
				}
			}
			return string.Join(", ", list.ToArray());
		}

		private static Transform Holder()
		{
			//IL_0012: Unknown result type (might be due to invalid IL or missing references)
			//IL_001c: Expected O, but got Unknown
			if ((Object)(object)s_holder == (Object)null)
			{
				s_holder = new GameObject("VargheimStatues_Prefabs");
				s_holder.SetActive(false);
				Object.DontDestroyOnLoad((Object)(object)s_holder);
			}
			return s_holder.transform;
		}

		private static Bounds? Bake(GameObject src, Transform into, string poseHint, out string poseUsed)
		{
			//IL_0013: Unknown result type (might be due to invalid IL or missing references)
			//IL_0023: Unknown result type (might be due to invalid IL or missing references)
			//IL_0033: 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_01d1: Expected O, but got Unknown
			//IL_01b6: Unknown result type (might be due to invalid IL or missing references)
			//IL_0251: Unknown result type (might be due to invalid IL or missing references)
			//IL_020a: Unknown result type (might be due to invalid IL or missing references)
			//IL_020f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0213: Unknown result type (might be due to invalid IL or missing references)
			//IL_0218: Unknown result type (might be due to invalid IL or missing references)
			//IL_038f: Unknown result type (might be due to invalid IL or missing references)
			GameObject val = Object.Instantiate<GameObject>(src, Holder(), false);
			val.transform.localPosition = Vector3.zero;
			val.transform.localRotation = Quaternion.identity;
			val.transform.localScale = Vector3.one;
			Bounds? total = null;
			int n = 0;
			poseUsed = "bind pose";
			try
			{
				try
				{
					poseUsed = Pose(val, poseHint);
				}
				catch (Exception ex)
				{
					poseUsed = "bind pose (" + ex.GetType().Name + ")";
				}
				bool flag = false;
				SkinnedMeshRenderer[] componentsInChildren = val.GetComponentsInChildren<SkinnedMeshRenderer>(true);
				foreach (SkinnedMeshRenderer val2 in componentsInChildren)
				{
					if ((Object)(object)val2.sharedMesh != (Object)null && !val2.sharedMesh.isReadable)
					{
						flag = true;
					}
				}
				if (flag && Strip(val))
				{
					val.transform.SetParent(Awake(), false);
					val.SetActive(true);
				}
				componentsInChildren = val.GetComponentsInChildren<SkinnedMeshRenderer>(true);
				foreach (SkinnedMeshRenderer val3 in componentsInChildren)
				{
					if ((Object)(object)val3.sharedMesh == (Object)null)
					{
						continue;
					}
					string text = ((Object)((Component)val3).gameObject).name.ToLowerInvariant();
					if (text.Contains("ragdoll") || text.Contains("fx") || text.Contains("particle") || !Keep((Renderer)(object)val3, val.transform))
					{
						continue;
					}
					Material[] mats = StoneMats(((Renderer)val3).sharedMaterials, val3.sharedMesh.subMeshCount);
					Mesh val4 = null;
					try
					{
						val4 = Skin(val3, val.transform);
					}
					catch (Exception)
					{
						val4 = null;
					}
					if ((Object)(object)val4 != (Object)null)
					{
						Add(into, val.transform, val.transform, val4, mats, ref total, ref n, Vector3.one);
						continue;
					}
					Mesh val5 = new Mesh();
					((Object)val5).name = "statue_" + ((Object)((Component)val3).gameObject).name;
					val3.BakeMesh(val5, true);
					val5.RecalculateBounds();
					if (val5.vertexCount != 0)
					{
						Bounds bounds = val5.bounds;
						Vector3 size = ((Bounds)(ref bounds)).size;
						if (!(((Vector3)(ref size)).magnitude < 0.3f))
						{
							Add(into, val.transform, ((Component)val3).transform, val5, mats, ref total, ref n, null);
							continue;
						}
					}
					Object.DestroyImmediate((Object)(object)val5);
					Add(into, val.transform, ((Component)val3).transform, val3.sharedMesh, mats, ref total, ref n, ((Component)val3).transform.lossyScale);
				}
				MeshFilter[] componentsInChildren2 = val.GetComponentsInChildren<MeshFilter>(true);
				foreach (MeshFilter val6 in componentsInChildren2)
				{
					if ((Object)(object)val6.sharedMesh == (Object)null)
					{
						continue;
					}
					MeshRenderer component = ((Component)val6).GetComponent<MeshRenderer>();
					if (!((Object)(object)component == (Object)null))
					{
						string text2 = ((Object)((Component)val6).gameObject).name.ToLowerInvariant();
						if (!text2.Contains("ragdoll") && !text2.Contains("fx") && !text2.Contains("particle") && !text2.Contains("collider") && !text2.Contains("lod1") && !text2.Contains("lod2") && Keep((Renderer)(object)component, val.transform))
						{
							Add(into, val.transform, ((Component)val6).transform, val6.sharedMesh, StoneMats(((Renderer)component).sharedMaterials, val6.sharedMesh.subMeshCount), ref total, ref n, ((Component)val6).transform.lossyScale);
						}
					}
				}
			}
			finally
			{
				Object.DestroyImmediate((Object)(object)val);
			}
			if (n == 0)
			{
				return null;
			}
			return total;
		}

		private static string Pose(GameObject tmp, string hint)
		{
			hint = (hint ?? "").Trim();
			if (hint.Equals("bind", StringComparison.OrdinalIgnoreCase))
			{
				return "bind pose (asked)";
			}
			Animator componentInChildren = tmp.GetComponentInChildren<Animator>(true);
			if ((Object)(object)componentInChildren == (Object)null || (Object)(object)componentInChildren.runtimeAnimatorController == (Object)null)
			{
				return "bind pose (no animator)";
			}
			AnimationClip[] animationClips = componentInChildren.runtimeAnimatorController.animationClips;
			if (animationClips == null || animationClips.Length == 0)
			{
				return "bind pose (no clips)";
			}
			float result = 0f;
			string text = hint;
			int num = hint.IndexOf('@');
			bool flag = false;
			if (num >= 0)
			{
				string text2 = hint.Substring(num + 1).Trim();
				if (text2.EndsWith("%"))
				{
					flag = true;
					text2 = text2.TrimEnd('%');
				}
				float.TryParse(text2, NumberStyles.Float, CultureInfo.InvariantCulture, out result);
				text = hint.Substring(0, num).Trim();
			}
			AnimationClip val = null;
			if (text.Length > 0)
			{
				AnimationClip[] array = animationClips;
				foreach (AnimationClip val2 in array)
				{
					if ((Object)(object)val2 != (Object)null && ((Object)val2).name.IndexOf(text, StringComparison.OrdinalIgnoreCase) >= 0)
					{
						val = val2;
						break;
					}
				}
			}
			string[] array2 = new string[12]
			{
				"combat", "alert", "sleep", "swim", "fly", "hover", "air", "attack", "hit", "death",
				"taunt", "stagger"
			};
			if ((Object)(object)val == (Object)null)
			{
				AnimationClip[] array = animationClips;
				foreach (AnimationClip val3 in array)
				{
					if ((Object)(object)val3 == (Object)null || ((Object)val3).name.IndexOf("idle", StringComparison.OrdinalIgnoreCase) < 0)
					{
						continue;
					}
					bool flag2 = false;
					string[] array3 = array2;
					foreach (string value in array3)
					{
						if (((Object)val3).name.IndexOf(value, StringComparison.OrdinalIgnoreCase) >= 0)
						{
							flag2 = true;
							break;
						}
					}
					if (!flag2)
					{
						val = val3;
						break;
					}
				}
			}
			if ((Object)(object)val == (Object)null)
			{
				AnimationClip[] array = animationClips;
				foreach (AnimationClip val4 in array)
				{
					if ((Object)(object)val4 != (Object)null && (((Object)val4).name.IndexOf("idle", StringComparison.OrdinalIgnoreCase) >= 0 || ((Object)val4).name.IndexOf("stand", StringComparison.OrdinalIgnoreCase) >= 0))
					{
						val = val4;
						break;
					}
				}
			}
			Plugin.Note(((Object)tmp).name.Replace("(Clone)", "") + " clips: " + ClipNames(animationClips));
			if ((Object)(object)val == (Object)null)
			{
				return "bind pose (no idle clip)";
			}
			if (flag)
			{
				result = val.length * Mathf.Clamp01(result / 100f);
			}
			result = Mathf.Clamp(result, 0f, val.length);
			val.SampleAnimation(((Component)componentInChildren).gameObject, result);
			return ((Object)val).name + "@" + result.ToString("0.##", CultureInfo.InvariantCulture) + "s of " + val.length.ToString("0.##", CultureInfo.InvariantCulture) + "s";
		}

		private static string ClipNames(AnimationClip[] clips)
		{
			List<string> list = new List<string>();
			foreach (AnimationClip val in clips)
			{
				if ((Object)(object)val != (Object)null && !list.Contains(((Object)val).name))
				{
					list.Add(((Object)val).name);
				}
			}
			if (list.Count > 40)
			{
				list = list.GetRange(0, 40);
			}
			return string.Join(", ", list.ToArray());
		}

		private static Mesh Skin(SkinnedMeshRenderer smr, Transform root)
		{
			//IL_006f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0074: Unknown result type (might be due to invalid IL or missing references)
			//IL_0076: Unknown result type (might be due to invalid IL or missing references)
			//IL_007e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0083: Unknown result type (might be due to invalid IL or missing references)
			//IL_0088: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bf: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c4: Unknown result type (might be due to invalid IL or missing references)
			//IL_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_00b5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d6: 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_0114: Unknown result type (might be due to invalid IL or missing references)
			//IL_0116: Unknown result type (might be due to invalid IL or missing references)
			//IL_011b: Unknown result type (might be due to invalid IL or missing references)
			//IL_011d: 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_0141: Unknown result type (might be due to invalid IL or missing references)
			//IL_02b5: Unknown result type (might be due to invalid IL or missing references)
			//IL_02bc: Expected O, but got Unknown
			//IL_02d6: Unknown result type (might be due to invalid IL or missing references)
			//IL_0155: Unknown result type (might be due to invalid IL or missing references)
			//IL_014a: Unknown result type (might be due to invalid IL or missing references)
			//IL_017b: Unknown result type (might be due to invalid IL or missing references)
			//IL_018f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0184: 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_01c9: Unknown result type (might be due to invalid IL or missing references)
			//IL_01be: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ef: Unknown result type (might be due to invalid IL or missing references)
			//IL_0203: Unknown result type (might be due to invalid IL or missing references)
			//IL_01f8: Unknown result type (might be due to invalid IL or missing references)
			//IL_0385: Unknown result type (might be due to invalid IL or missing references)
			//IL_038a: Unknown result type (might be due to invalid IL or missing references)
			//IL_038e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0393: Unknown result type (might be due to invalid IL or missing references)
			//IL_0222: Unknown result type (might be due to invalid IL or missing references)
			//IL_0227: Unknown result type (might be due to invalid IL or missing references)
			//IL_022c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0274: Unknown result type (might be due to invalid IL or missing references)
			//IL_0276: Unknown result type (might be due to invalid IL or missing references)
			//IL_025a: Unknown result type (might be due to invalid IL or missing references)
			//IL_025e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0263: Unknown result type (might be due to invalid IL or missing references)
			//IL_0265: Unknown result type (might be due to invalid IL or missing references)
			//IL_0269: Unknown result type (might be due to invalid IL or missing references)
			//IL_026e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0238: Unknown result type (might be due to invalid IL or missing references)
			//IL_023d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0242: Unknown result type (might be due to invalid IL or missing references)
			//IL_029a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0291: Unknown result type (might be due to invalid IL or missing references)
			//IL_029f: Unknown result type (might be due to invalid IL or missing references)
			Mesh sharedMesh = smr.sharedMesh;
			if ((Object)(object)sharedMesh == (Object)null || !sharedMesh.isReadable)
			{
				return null;
			}
			Transform[] bones = smr.bones;
			Matrix4x4[] bindposes = sharedMesh.bindposes;
			BoneWeight[] boneWeights = sharedMesh.boneWeights;
			Vector3[] vertices = sharedMesh.vertices;
			if (bones == null || bones.Length == 0 || bindposes == null || bindposes.Length == 0 || boneWeights == null || boneWeights.Length != vertices.Length)
			{
				return null;
			}
			Vector3[] normals = sharedMesh.normals;
			bool flag = normals != null && normals.Length == vertices.Length;
			Matrix4x4 worldToLocalMatrix = root.worldToLocalMatrix;
			Matrix4x4 val = worldToLocalMatrix * ((Component)smr).transform.localToWorldMatrix;
			int num = Mathf.Min(bones.Length, bindposes.Length);
			Matrix4x4[] array = (Matrix4x4[])(object)new Matrix4x4[num];
			for (int i = 0; i < num; i++)
			{
				array[i] = (((Object)(object)bones[i] != (Object)null) ? (worldToLocalMatrix * bones[i].localToWorldMatrix * bindposes[i]) : val);
			}
			Vector3[] array2 = (Vector3[])(object)new Vector3[vertices.Length];
			Vector3[] array3 = (Vector3[])(object)(flag ? new Vector3[vertices.Length] : null);
			for (int j = 0; j < vertices.Length; j++)
			{
				BoneWeight val2 = boneWeights[j];
				Vector3 p = Vector3.zero;
				Vector3 q = Vector3.zero;
				float sum = 0f;
				Acc(array, num, ((BoneWeight)(ref val2)).boneIndex0, ((BoneWeight)(ref val2)).weight0, vertices[j], flag ? normals[j] : Vector3.zero, ref p, ref q, ref sum);
				Acc(array, num, ((BoneWeight)(ref val2)).boneIndex1, ((BoneWeight)(ref val2)).weight1, vertices[j], flag ? normals[j] : Vector3.zero, ref p, ref q, ref sum);
				Acc(array, num, ((BoneWeight)(ref val2)).boneIndex2, ((BoneWeight)(ref val2)).weight2, vertices[j], flag ? normals[j] : Vector3.zero, ref p, ref q, ref sum);
				Acc(array, num, ((BoneWeight)(ref val2)).boneIndex3, ((BoneWeight)(ref val2)).weight3, vertices[j], flag ? normals[j] : Vector3.zero, ref p, ref q, ref sum);
				if (sum < 0.0001f)
				{
					p = ((Matrix4x4)(ref val)).MultiplyPoint3x4(vertices[j]);
					if (flag)
					{
						q = ((Matrix4x4)(ref val)).MultiplyVector(normals[j]);
					}
				}
				else if (Mathf.Abs(sum - 1f) > 0.001f)
				{
					p /= sum;
					q /= sum;
				}
				array2[j] = p;
				if (flag)
				{
					array3[j] = ((((Vector3)(ref q)).sqrMagnitude > 1E-12f) ? ((Vector3)(ref q)).normalized : Vector3.up);
				}
			}
			Mesh val3 = new Mesh();
			((Object)val3).name = "statue_" + ((Object)sharedMesh).name;
			val3.indexFormat = sharedMesh.indexFormat;
			val3.vertices = array2;
			if (flag)
			{
				val3.normals = array3;
			}
			Vector2[] uv = sharedMesh.uv;
			if (uv != null && uv.Length == vertices.Length)
			{
				val3.uv = uv;
			}
			val3.subMeshCount = sharedMesh.subMeshCount;
			for (int k = 0; k < sharedMesh.subMeshCount; k++)
			{
				val3.SetTriangles(sharedMesh.GetTriangles(k), k);
			}
			if (!flag)
			{
				val3.RecalculateNormals();
			}
			if (val3.uv != null && val3.uv.Length == vertices.Length)
			{
				val3.RecalculateTangents();
			}
			val3.RecalculateBounds();
			if (val3.vertexCount > 0)
			{
				Bounds bounds = val3.bounds;
				Vector3 size = ((Bounds)(ref bounds)).size;
				if (((Vector3)(ref size)).magnitude >= 0.3f)
				{
					return val3;
				}
			}
			return null;
		}

		private static void Acc(Matrix4x4[] m, int nb, int bi, float w, Vector3 v, Vector3 n, ref Vector3 p, ref Vector3 q, ref float sum)
		{
			//IL_0015: 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_0023: Unknown result type (might be due to invalid IL or missing references)
			//IL_0029: Unknown result type (might be due to invalid IL or missing references)
			//IL_002e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0033: 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_0048: 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_0050: Unknown result type (might be due to invalid IL or missing references)
			//IL_0055: Unknown result type (might be due to invalid IL or missing references)
			//IL_005a: Unknown result type (might be due to invalid IL or missing references)
			if (!(w <= 0f) && bi >= 0 && bi < nb)
			{
				p += ((Matrix4x4)(ref m[bi])).MultiplyPoint3x4(v) * w;
				q += ((Matrix4x4)(ref m[bi])).MultiplyVector(n) * w;
				sum += w;
			}
		}

		private static void Add(Transform into, Transform root, Transform part, Mesh mesh, Material[] mats, ref Bounds? total, ref int n, Vector3? scale)
		{
			//IL_0028: Unknown result type (might be due to invalid IL or missing references)
			//IL_002e: Expected O, but got Unknown
			//IL_0043: Unknown result type (might be due to invalid IL or missing references)
			//IL_0048: Unknown result type (might be due to invalid IL or missing references)
			//IL_0059: Unknown result type (might be due to invalid IL or missing references)
			//IL_005e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0064: Unknown result type (might be due to invalid IL or missing references)
			//IL_0069: Unknown result type (might be due to invalid IL or missing references)
			//IL_008e: 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_00b9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00be: 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_00d8: Unknown result type (might be due to invalid IL or missing references)
			//IL_018d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0192: Unknown result type (might be due to invalid IL or missing references)
			//IL_0106: 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_01b9: Unknown result type (might be due to invalid IL or missing references)
			//IL_01be: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c2: 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_019f: 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_01a6: Unknown result type (might be due to invalid IL or missing references)
			//IL_0126: Unknown result type (might be due to invalid IL or missing references)
			//IL_0118: Unknown result type (might be due to invalid IL or missing references)
			//IL_0135: Unknown result type (might be due to invalid IL or missing references)
			//IL_013d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0142: Unknown result type (might be due to invalid IL or missing references)
			//IL_0147: Unknown result type (might be due to invalid IL or missing references)
			//IL_0152: 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)
			//IL_0162: Unknown result type (might be due to invalid IL or missing references)
			//IL_0164: Unknown result type (might be due to invalid IL or missing references)
			//IL_0169: Unknown result type (might be due to invalid IL or missing references)
			//IL_016e: Unknown result type (might be due to invalid IL or missing references)
			if (s_partNames != null)
			{
				s_partNames.Add(((Object)part).name);
			}
			GameObject val = new GameObject("statue_part_" + n);
			val.transform.SetParent(into, false);
			val.transform.localPosition = root.InverseTransformPoint(part.position);
			val.transform.localRotation = Quaternion.Inverse(root.rotation) * part.rotation;
			val.transform.localScale = (Vector3)(((??)scale) ?? Vector3.one);
			val.AddComponent<MeshFilter>().sharedMesh = mesh;
			MeshRenderer obj = val.AddComponent<MeshRenderer>();
			((Renderer)obj).sharedMaterials = mats;
			((Renderer)obj).shadowCastingMode = (ShadowCastingMode)1;
			Bounds bounds = mesh.bounds;
			Vector3[] array = (Vector3[])(object)new Vector3[8];
			Vector3 val2 = default(Vector3);
			for (int i = 0; i < 8; i++)
			{
				((Vector3)(ref val2))..ctor(((i & 1) == 0) ? ((Bounds)(ref bounds)).min.x : ((Bounds)(ref bounds)).max.x, ((i & 2) == 0) ? ((Bounds)(ref bounds)).min.y : ((Bounds)(ref bounds)).max.y, ((i & 4) == 0) ? ((Bounds)(ref bounds)).min.z : ((Bounds)(ref bounds)).max.z);
				val2 = Vector3.Scale(val2, val.transform.localScale);
				array[i] = val.transform.localPosition + val.transform.localRotation * val2;
			}
			Vector3[] array2 = array;
			foreach (Vector3 val3 in array2)
			{
				if (!total.HasValue)
				{
					total = new Bounds(val3, Vector3.zero);
					continue;
				}
				Bounds value = total.Value;
				((Bounds)(ref value)).Encapsulate(val3);
				total = value;
			}
			n++;
		}

		internal static bool Carved()
		{
			return !string.Equals((Plugin.Finish.Value ?? "").Trim(), "Flat", StringComparison.OrdinalIgnoreCase);
		}

		private static bool Headless()
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0006: Invalid comparison between Unknown and I4
			return (int)SystemInfo.graphicsDeviceType == 4;
		}

		private static Material[] StoneMats(Material[] src, int subMeshes)
		{
			int num = Mathf.Max(1, subMeshes);
			Material[] array = (Material[])(object)new Material[num];
			for (int i = 0; i < num; i++)
			{
				Material src2 = ((src != null && src.Length != 0) ? src[Mathf.Min(i, src.Length - 1)] : null);
				array[i] = StoneOf(src2);
			}
			return array;
		}

		private static Material StoneOf(Material src)
		{
			//IL_0073: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ab: Expected O, but got Unknown
			//IL_00dc: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f3: Unknown result type (might be due to invalid IL or missing references)
			Material val = FigureMat();
			if ((Object)(object)src == (Object)null || !Carved() || Headless())
			{
				return val;
			}
			if (s_stone.TryGetValue(src, out var value))
			{
				return value;
			}
			value = val;
			try
			{
				Texture val2 = (src.HasProperty("_MainTex") ? src.GetTexture("_MainTex") : null);
				if ((Object)(object)val2 != (Object)null && val2.width >= 8 && val2.height >= 8)
				{
					Texture2D val3 = Stoneify(val2, StoneColour(), Mathf.Clamp(Plugin.Detail.Value, 0f, 3f));
					if ((Object)(object)val3 != (Object)null)
					{
						Material val4 = new Material(val);
						((Object)val4).name = "statue_carved_" + ((Object)src).name;
						val4.SetTexture("_MainTex", (Texture)(object)val3);
						val4.SetTextureScale("_MainTex", src.GetTextureScale("_MainTex"));
						val4.SetTextureOffset("_MainTex", src.GetTextureOffset("_MainTex"));
						Texture val5 = (src.HasProperty("_BumpMap") ? src.GetTexture("_BumpMap") : null);
						if ((Object)(object)val5 != (Object)null && val4.HasProperty("_BumpMap"))
						{
							val4.SetTexture("_BumpMap", val5);
							val4.EnableKeyword("_NORMALMAP");
						}
						value = val4;
					}
				}
			}
			catch (Exception ex)
			{
				Plugin.Warn("carved finish for " + ((Object)src).name + " failed (" + ex.GetType().Name + "); flat stone used.");
				value = val;
			}
			s_stone[src] = value;
			return value;
		}

		private static Color StoneColour()
		{
			//IL_0051: 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)
			string text = (Plugin.Material.Value ?? "").Trim();
			Color result = default(Color);
			if (text.StartsWith("#", StringComparison.Ordinal) && ColorUtility.TryParseHtmlString(text.Split(',')[0].Trim(), ref result))
			{
				return result;
			}
			return new Color(0.42f, 0.41f, 0.4f);
		}

		private static Texture2D Stoneify(Texture src, Color stone, float detail)
		{
			//IL_004a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0051: Expected O, but got Unknown
			//IL_006e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0186: Unknown result type (might be due to invalid IL or missing references)
			//IL_0194: 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_01b5: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ba: Unknown result type (might be due to invalid IL or missing references)
			int num = src.width;
			int num2 = src.height;
			while (num > 1024 || num2 > 1024)
			{
				num = Mathf.Max(8, num / 2);
				num2 = Mathf.Max(8, num2 / 2);
			}
			RenderTexture temporary = RenderTexture.GetTemporary(num, num2, 0, (RenderTextureFormat)0, (RenderTextureReadWrite)2);
			RenderTexture active = RenderTexture.active;
			Texture2D val = new Texture2D(num, num2, (TextureFormat)4, true, false);
			try
			{
				Graphics.Blit(src, temporary);
				RenderTexture.active = temporary;
				val.ReadPixels(new Rect(0f, 0f, (float)num, (float)num2), 0, 0, false);
			}
			finally
			{
				RenderTexture.active = active;
				RenderTexture.ReleaseTemporary(temporary);
			}
			Color32[] pixels = val.GetPixels32();
			float[] array = new float[pixels.Length];
			double num3 = 0.0;
			for (int i = 0; i < pixels.Length; i++)
			{
				array[i] = (0.299f * (float)(int)pixels[i].r + 0.587f * (float)(int)pixels[i].g + 0.114f * (float)(int)pixels[i].b) / 255f;
				num3 += (double)array[i];
			}
			float num4 = (float)(num3 / (double)Mathf.Max(1, pixels.Length));
			Random random = new Random(((Object)src).name.GetHashCode());
			for (int j = 0; j < pixels.Length; j++)
			{
				float num5 = 1f + (array[j] - num4) * 1.6f * detail;
				num5 *= 0.93f + 0.14f * (float)random.NextDouble();
				num5 = Mathf.Clamp(num5, 0.4f, 1.6f);
				pixels[j] = new Color32(B(stone.r * num5), B(stone.g * num5), B(stone.b * num5), byte.MaxValue);
			}
			val.SetPixels32(pixels);
			val.Apply(true, true);
			((Object)val).name = "statue_carved_" + ((Object)src).name;
			return val;
		}

		private static byte B(float v)
		{
			return (byte)Mathf.Clamp(Mathf.RoundToInt(v * 255f), 0, 255);
		}

		private static Material FigureMat()
		{
			return s_figure ?? (s_figure = Make(Plugin.Material.Value, "figure"));
		}

		private static Material PlinthMat(ObjectDB db, ZNetScene zs)
		{
			return s_plinth ?? (s_plinth = Make(Plugin.PlinthMaterial.Value, "plinth"));
		}

		private static Material BaseMat()
		{
			if ((Object)(object)s_base != (Object)null)
			{
				return s_base;
			}
			string[] array = new string[3] { "stone_wall_2x1", "stone_floor_2x2", "wood_pole" };
			foreach (string text in array)
			{
				GameObject val = (((Object)(object)ZNetScene.instance != (Object)null) ? ZNetScene.instance.GetPrefab(text) : null);
				if ((Object)(object)val == (Object)null)
				{
					continue;
				}
				MeshRenderer[] componentsInChildren = val.GetComponentsInChildren<MeshRenderer>(true);
				foreach (MeshRenderer val2 in componentsInChildren)
				{
					if ((Object)(object)((Renderer)val2).sharedMaterial != (Object)null && (Object)(object)((Renderer)val2).sharedMaterial.shader != (Object)null && ((Object)((Renderer)val2).sharedMaterial.shader).name.Contains("Piece"))
					{
						s_base = ((Renderer)val2).sharedMaterial;
						return s_base;
					}
				}
			}
			return null;
		}

		private static Material Make(string spec, string what)
		{
			//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_015c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0163: Expected O, but got Unknown
			//IL_0175: Unknown result type (might be due to invalid IL or missing references)
			//IL_0194: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b9: 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_0153: Unknown result type (might be due to invalid IL or missing references)
			//IL_0075: Unknown result type (might be due to invalid IL or missing references)
			//IL_007a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0092: Expected O, but got Unknown
			//IL_0325: Unknown result type (might be due to invalid IL or missing references)
			//IL_02de: Unknown result type (might be due to invalid IL or missing references)
			//IL_03a2: Unknown result type (might be due to invalid IL or missing references)
			spec = (spec ?? "").Trim();
			if (!spec.StartsWith("#", StringComparison.Ordinal))
			{
				GameObject val = (((Object)(object)ZNetScene.instance != (Object)null) ? ZNetScene.instance.GetPrefab(spec) : null);
				if ((Object)(object)val != (Object)null)
				{
					MeshRenderer[] componentsInChildren = val.GetComponentsInChildren<MeshRenderer>(true);
					foreach (MeshRenderer val2 in componentsInChildren)
					{
						if ((Object)(object)((Renderer)val2).sharedMaterial != (Object)null)
						{
							return new Material(((Renderer)val2).sharedMaterial)
							{
								name = "statue_" + what + "_" + spec
							};
						}
					}
				}
				Plugin.Warn(what + " material '" + spec + "' not found; using grey stone.");
				spec = "#6a6866,0,0.2";
			}
			string[] array = spec.Split(',');
			Color gray = default(Color);
			if (!ColorUtility.TryParseHtmlString(array[0].Trim(), ref gray))
			{
				gray = Color.gray;
			}
			float result = 0f;
			float result2 = 0.2f;
			if (array.Length > 1)
			{
				float.TryParse(array[1].Trim(), NumberStyles.Float, CultureInfo.InvariantCulture, out result);
			}
			if (array.Length > 2)
			{
				float.TryParse(array[2].Trim(), NumberStyles.Float, CultureInfo.InvariantCulture, out result2);
			}
			Material val3 = BaseMat();
			Material val4 = (((Object)(object)val3 != (Object)null) ? new Material(val3) : new Material(Shader.Find("Custom/Piece") ?? Shader.Find("Standard")));
			((Object)val4).name = "statue_" + what;
			Texture2D val5 = Grain(gray, what);
			Texture2D val6 = Flat(new Color(Mathf.Clamp01(result), 0f, 0f, Mathf.Clamp01(result2)), "metal");
			Texture2D val7 = Flat(new Color(0.5f, 0.5f, 1f, 1f), "normal");
			Texture2D val8 = Flat(Color.black, "black");
			string[] array2 = new string[13]
			{
				"_MainTex", "_BumpMap", "_MetallicGlossMap", "_EmissiveTex", "_EmissionMap", "_OcclusionMap", "_DetailAlbedoMap", "_DetailNormalMap", "_MossTex", "_SnowTex",
				"_RustTex", "_Mask", "_MaskTex"
			};
			foreach (string text in array2)
			{
				if (val4.HasProperty(text))
				{
					switch (text)
					{
					case "_MainTex":
						val4.SetTexture(text, (Texture)(object)val5);
						break;
					case "_BumpMap":
					case "_DetailNormalMap":
						val4.SetTexture(text, (Texture)(object)val7);
						break;
					case "_MetallicGlossMap":
						val4.SetTexture(text, (Texture)(object)val6);
						break;
					case "_OcclusionMap":
						val4.SetTexture(text, (Texture)(object)Flat(Color.white, "white"));
						break;
					default:
						val4.SetTexture(text, (Texture)(object)val8);
						break;
					}
				}
			}
			if (val4.HasProperty("_Color"))
			{
				val4.SetColor("_Color", Color.white);
			}
			if (val4.HasProperty("_Metallic"))
			{
				val4.SetFloat("_Metallic", Mathf.Clamp01(result));
			}
			if (val4.HasProperty("_Glossiness"))
			{
				val4.SetFloat("_Glossiness", Mathf.Clamp01(result2));
			}
			array2 = new string[2] { "_EmissionColor", "_EmissiveColor" };
			foreach (string text2 in array2)
			{
				if (val4.HasProperty(text2))
				{
					val4.SetColor(text2, Color.black);
				}
			}
			array2 = new string[6] { "_MossAlpha", "_SnowAlpha", "_RustAlpha", "_UseGlossmap", "_EmissionEnabled", "_TriplanarMap" };
			foreach (string text3 in array2)
			{
				if (val4.HasProperty(text3))
				{
					val4.SetFloat(text3, 0f);
				}
			}
			if (val4.HasProperty("_Cull"))
			{
				val4.SetFloat("_Cull", 0f);
			}
			return val4;
		}

		private static Texture2D Grain(Color c, string name)
		{
			//IL_0174: Unknown result type (might be due to invalid IL or missing references)
			//IL_0179: Unknown result type (might be due to invalid IL or missing references)
			//IL_0180: Unknown result type (might be due to invalid IL or missing references)
			//IL_0187: Unknown result type (might be due to invalid IL or missing references)
			//IL_018f: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a1: Expected O, but got Unknown
			//IL_010a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0118: Unknown result type (might be due to invalid IL or missing references)
			//IL_0126: Unknown result type (might be due to invalid IL or missing references)
			//IL_0139: 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)
			Random random = new Random(name.GetHashCode());
			float[] array = new float[256];
			for (int i = 0; i < array.Length; i++)
			{
				array[i] = (float)random.NextDouble();
			}
			Color32[] array2 = (Color32[])(object)new Color32[16384];
			for (int j = 0; j < 128; j++)
			{
				for (int k = 0; k < 128; k++)
				{
					float num = (float)k / 8f;
					float num2 = (float)j / 8f;
					int num3 = (int)num;
					int num4 = (int)num2;
					float num5 = num - (float)num3;
					float num6 = num2 - (float)num4;
					float num7 = array[num4 % 16 * 16 + num3 % 16];
					float num8 = array[num4 % 16 * 16 + (num3 + 1) % 16];
					float num9 = array[(num4 + 1) % 16 * 16 + num3 % 16];
					float num10 = array[(num4 + 1) % 16 * 16 + (num3 + 1) % 16];
					float num11 = Mathf.Lerp(Mathf.Lerp(num7, num8, num5), Mathf.Lerp(num9, num10, num5), num6);
					float num12 = 0.86f + 0.2f * num11 + 0.08f * (float)random.NextDouble();
					array2[j * 128 + k] = new Color32(B(c.r * num12), B(c.g * num12), B(c.b * num12), byte.MaxValue);
				}
			}
			Texture2D val = new Texture2D(128, 128, (TextureFormat)4, true, false)
			{
				wrapMode = (TextureWrapMode)0
			};
			val.SetPixels32(array2);
			val.Apply(true, true);
			((Object)val).name = "statue_grain_" + name;
			return val;
		}

		private static Texture2D Flat(Color c, string name)
		{
			//IL_001f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0025: Expected O, but got Unknown
			//IL_0033: Unknown result type (might be due to invalid IL or missing references)
			//IL_0034: Unknown result type (might be due to invalid IL or missing references)
			Texture2D val = new Texture2D(4, 4, (TextureFormat)4, false, name == "normal" || name == "metal");
			Color[] array = (Color[])(object)new Color[16];
			for (int i = 0; i < array.Length; i++)
			{
				array[i] = c;
			}
			val.SetPixels(array);
			val.Apply();
			((Object)val).name = "statue_" + name;
			return val;
		}

		private static Mesh Cylinder(float radius, float height, int seg)
		{
			//IL_004f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0052: Unknown result type (might be due to invalid IL or missing references)
			//IL_005d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0076: Unknown result type (might be due to invalid IL or missing references)
			//IL_0081: Unknown result type (might be due to invalid IL or missing references)
			//IL_0084: Unknown result type (might be due to invalid IL or missing references)
			//IL_0089: Unknown result type (might be due to invalid IL or missing references)
			//IL_008f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0094: Unknown result type (might be due to invalid IL or missing references)
			//IL_009f: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b4: 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_012b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0136: Unknown result type (might be due to invalid IL or missing references)
			//IL_014b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0182: Unknown result type (might be due to invalid IL or missing references)
			//IL_018d: Unknown result type (might be due to invalid IL or missing references)
			//IL_01be: Unknown result type (might be due to invalid IL or missing references)
			//IL_020e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0219: Unknown result type (might be due to invalid IL or missing references)
			//IL_022e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0269: Unknown result type (might be due to invalid IL or missing references)
			//IL_0274: Unknown result type (might be due to invalid IL or missing references)
			//IL_02a5: Unknown result type (might be due to invalid IL or missing references)
			//IL_02ec: Unknown result type (might be due to invalid IL or missing references)
			//IL_02f1: Unknown result type (might be due to invalid IL or missing references)
			//IL_02fc: Unknown result type (might be due to invalid IL or missing references)
			//IL_0303: Unknown result type (might be due to invalid IL or missing references)
			//IL_030a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0312: Unknown result type (might be due to invalid IL or missing references)
			//IL_031a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0321: Expected O, but got Unknown
			List<Vector3> list = new List<Vector3>();
			List<Vector3> list2 = new List<Vector3>();
			List<Vector2> list3 = new List<Vector2>();
			List<int> list4 = new List<int>();
			Vector3 val = default(Vector3);
			for (int i = 0; i <= seg; i++)
			{
				float num = (float)i / (float)seg * (float)Math.PI * 2f;
				((Vector3)(ref val))..ctor(Mathf.Cos(num), 0f, Mathf.Sin(num));
				list.Add(val * radius);
				list2.Add(val);
				list3.Add(new Vector2((float)i / (float)seg * 4f, 0f));
				list.Add(val * radius + Vector3.up * height);
				list2.Add(val);
				list3.Add(new Vector2((float)i / (float)seg * 4f, height));
			}
			for (int j = 0; j < seg; j++)
			{
				int num2 = j * 2;
				list4.Add(num2);
				list4.Add(num2 + 1);
				list4.Add(num2 + 2);
				list4.Add(num2 + 1);
				list4.Add(num2 + 3);
				list4.Add(num2 + 2);
			}
			int count = list.Count;
			list.Add(Vector3.up * height);
			list2.Add(Vector3.up);
			list3.Add(new Vector2(0.5f, 0.5f));
			for (int k = 0; k <= seg; k++)
			{
				float num3 = (float)k / (float)seg * (float)Math.PI * 2f;
				list.Add(new Vector3(Mathf.Cos(num3) * radius, height, Mathf.Sin(num3) * radius));
				list2.Add(Vector3.up);
				list3.Add(new Vector2(0.5f + Mathf.Cos(num3) * 0.5f, 0.5f + Mathf.Sin(num3) * 0.5f));
			}
			for (int l = 0; l < seg; l++)
			{
				list4.Add(count);
				list4.Add(count + 2 + l);
				list4.Add(count + 1 + l);
			}
			int count2 = list.Count;
			list.Add(Vector3.zero);
			list2.Add(Vector3.down);
			list3.Add(new Vector2(0.5f, 0.5f));
			for (int m = 0; m <= seg; m++)
			{
				float num4 = (float)m / (float)seg * (float)Math.PI * 2f;
				list.Add(new Vector3(Mathf.Cos(num4) * radius, 0f, Mathf.Sin(num4) * radius));
				list2.Add(Vector3.down);
				list3.Add(new Vector2(0.5f + Mathf.Cos(num4) * 0.5f, 0.5f + Mathf.Sin(num4) * 0.5f));
			}
			for (int n = 0; n < seg; n++)
			{
				list4.Add(count2);
				list4.Add(count2 + 1 + n);
				list4.Add(count2 + 2 + n);
			}
			Mesh val2 = new Mesh
			{
				name = "statue_plinth"
			};
			val2.SetVertices(list);
			val2.SetNormals(list2);
			val2.SetUVs(0, list3);
			val2.SetTriangles(list4, 0);
			val2.RecalculateBounds();
			return val2;
		}
	}
	public static class SupportWear
	{
		private static bool? s_off;

		private static readonly string[] s_reference = new string[4] { "woodwall", "wood_wall_half", "wood_floor", "stone_wall_1x1" };

		private static string s_referenceName = "woodwall";

		private static WearNTear Reference()
		{
			if ((Object)(object)ZNetScene.instance == (Object)null)
			{
				return null;
			}
			string[] array = s_reference;
			foreach (string text in array)
			{
				GameObject prefab = ZNetScene.instance.GetPrefab(text);
				WearNTear val = (((Object)(object)prefab != (Object)null) ? prefab.GetComponent<WearNTear>() : null);
				if ((Object)(object)val != (Object)null)
				{
					s_referenceName = text;
					return val;
				}
			}
			return null;
		}

		public static bool Off()
		{
			if (s_off.HasValue)
			{
				return s_off.Value;
			}
			bool flag = true;
			try
			{
				WearNTear val = Reference();
				if (!((Object)(object)val != (Object)null))
				{
					return !flag;
				}
				flag = val.m_noSupportWear;
			}
			catch
			{
				return !flag;
			}
			s_off = !flag;
			Plugin.Note("support wear: vanilla " + s_referenceName + " m_noSupportWear=" + flag + " -> statues use " + s_off.Value + " (off)");
			return s_off.Value;
		}

		public static void Recheck(IEnumerable<GameObject> prefabs)
		{
			s_off = null;
			bool flag = Off();
			if (!s_off.HasValue)
			{
				Plugin.Warn("support wear: no reference piece (woodwall...) in ZNetScene; keeping fallback " + flag);
				return;
			}
			int num = 0;
			foreach (GameObject prefab in prefabs)
			{
				if (!((Object)(object)prefab == (Object)null))
				{
					WearNTear component = prefab.GetComponent<WearNTear>();
					if ((Object)(object)component != (Object)null && component.m_noSupportWear != flag)
					{
						component.m_noSupportWear = flag;
						num++;
					}
				}
			}
			if (num > 0)
			{
				Plugin.Note("support wear: corrected " + num + " statue prefab(s) to " + flag + ".");
			}
		}
	}
	internal static class TerrainModifierGuard
	{
		private static readonly MethodInfo s_getModifiers = AccessTools.Method(typeof(TerrainModifier), "GetModifiers", (Type[])null, (Type[])null);

		private static readonly FieldInfo s_nview = AccessTools.Field(typeof(TerrainModifier), "m_nview");

		internal static bool RemoveOthers(TerrainModifier __instance, Vector3 point, float range)
		{
			//IL_003a: 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_00b0: Unknown result type (might be due to invalid IL or missing references)
			if (Plugin.IsStatue((Component)(object)__instance))
			{
				return false;
			}
			if (s_getModifiers == null || s_nview == null)
			{
				return true;
			}
			List<TerrainModifier> list = new List<TerrainModifier>();
			try
			{
				s_getModifiers.Invoke(null, new object[4] { point, range, list, __instance });
			}
			catch
			{
				return true;
			}
			foreach (TerrainModifier item in list)
			{
				if (!((Object)(object)item == (Object)null) && !((Object)(object)item == (Object)(object)__instance) && !Plugin.IsStatue((Component)(object)item) && item.m_level == __instance.m_level && item.m_paintCleared == __instance.m_paintCleared && item.m_paintType == __instance.m_paintType)
				{
					object? value = s_nview.GetValue(item);
					ZNetView val = (ZNetView)((value is ZNetView) ? value : null);
					if (!((Object)(object)val == (Object)null) && val.IsValid())
					{
						val.ClaimOwnership();
						val.Destroy();
					}
				}
			}
			return false;
		}
	}
	internal static class Icon
	{
		private const int Layer = 31;

		private const int Size = 128;

		internal static Sprite Render(GameObject piece, string key)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0006: Invalid comparison between Unknown and I4
			//IL_001e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0024: Expected O, but got Unknown
			//IL_0039: Unknown result type (might be due to invalid IL or missing references)
			//IL_0051: Unknown result type (might be due to invalid IL or missing references)
			//IL_0056: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ae: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b3: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ba: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c0: Expected O, but got Unknown
			//IL_01fa: Unknown result type (might be due to invalid IL or missing references)
			//IL_022f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0234: Unknown result type (might be due to invalid IL or missing references)
			//IL_0238: Unknown result type (might be due to invalid IL or missing references)
			//IL_023d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0241: Unknown result type (might be due to invalid IL or missing references)
			//IL_0246: Unknown result type (might be due to invalid IL or missing references)
			//IL_027d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0282: Unknown result type (might be due to invalid IL or missing references)
			//IL_0286: Unknown result type (might be due to invalid IL or missing references)
			//IL_028b: Unknown result type (might be due to invalid IL or missing references)
			//IL_029e: Unknown result type (might be due to invalid IL or missing references)
			//IL_02db: Unknown result type (might be due to invalid IL or missing references)
			//IL_02e1: Expected O, but got Unknown
			//IL_0313: Unknown result type (might be due to invalid IL or missing references)
			//IL_0332: Unknown result type (might be due to invalid IL or missing references)
			//IL_0337: Unknown result type (might be due to invalid IL or missing references)
			//IL_033b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0340: Unknown result type (might be due to invalid IL or missing references)
			//IL_0345: Unknown result type (might be due to invalid IL or missing references)
			//IL_0384: Unknown result type (might be due to invalid IL or missing references)
			//IL_0389: Unknown result type (might be due to invalid IL or missing references)
			//IL_039e: Unknown result type (might be due to invalid IL or missing references)
			//IL_03ab: Unknown result type (might be due to invalid IL or missing references)
			//IL_03b3: Unknown result type (might be due to invalid IL or missing references)
			//IL_03e0: Unknown result type (might be due to invalid IL or missing references)
			//IL_03ef: Unknown result type (might be due to invalid IL or missing references)
			//IL_03fe: Expected O, but got Unknown
			//IL_00b4: 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_00c2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ce: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00db: 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_00f6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fb: Unknown result type (might be due to invalid IL or missing references)
			//IL_0105: Unknown result type (might be due to invalid IL or missing references)
			//IL_010d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0117: Unknown result type (might be due to invalid IL or missing references)
			//IL_011f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0129: Unknown result type (might be due to invalid IL or missing references)
			//IL_0154: Unknown result type (might be due to invalid IL or missing references)
			//IL_0159: Unknown result type (might be due to invalid IL or missing references)
			//IL_0171: Unknown result type (might be due to invalid IL or missing references)
			//IL_0176: Unknown result type (might be due to invalid IL or missing references)
			//IL_017a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0183: Unknown result type (might be due to invalid IL or missing references)
			//IL_0166: Unknown result type (might be due to invalid IL or missing references)
			if ((int)SystemInfo.graphicsDeviceType == 4)
			{
				return null;
			}
			GameObject val = null;
			GameObject val2 = null;
			GameObject val3 = null;
			RenderTexture val4 = null;
			RenderTexture active = RenderTexture.active;
			try
			{
				val = new GameObject("VargheimStatues_IconStage");
				val.transform.position = new Vector3(0f, 8000f, 0f);
				Bounds? val5 = null;
				Matrix4x4 worldToLocalMatrix = piece.transform.worldToLocalMatrix;
				MeshRenderer[] componentsInChildren = piece.GetComponentsInChildren<MeshRenderer>(true);
				foreach (MeshRenderer val6 in componentsInChildren)
				{
					MeshFilter component = ((Component)val6).GetComponent<MeshFilter>();
					if (!((Object)(object)component == (Object)null) && !((Object)(object)component.sharedMesh == (Object)null) && ((Object)((Component)val6).gameObject).name.StartsWith("statue_", StringComparison.Ordinal))
					{
						Matrix4x4 val7 = worldToLocalMatrix * ((Component)val6).transform.localToWorldMatrix;
						GameObject val8 = new GameObject("icon_part")
						{
							layer = 31
						};
						val8.transform.SetParent(val.transform, false);
						val8.transform.localPosition = Vector4.op_Implicit(((Matrix4x4)(ref val7)).GetColumn(3));
						val8.transform.localRotation = ((Matrix4x4)(ref val7)).rotation;
						val8.transform.localScale = ((Matrix4x4)(ref val7)).lossyScale;
						val8.AddComponent<MeshFilter>().sharedMesh = component.sharedMesh;
						MeshRenderer obj = val8.AddComponent<MeshRenderer>();
						((Renderer)obj).sharedMaterials = ((Renderer)val6).sharedMaterials;
						((Renderer)obj).shadowCastingMode = (ShadowCastingMode)0;
						Bounds bounds = ((Renderer)obj).bounds;
						if (!val5.HasValue)
						{
							val5 = bounds;
							continue;
						}
						Bounds value = val5.Value;
						((Bounds)(ref value)).Encapsulate(bounds);
						val5 = value;
					}
				}
				if (!val5.HasValue)
				{
					return null;
				}
				Bounds value2 = val5.Value;
				val2 = new GameObject("VargheimStatues_IconCam");
				Camera val9 = val2.AddComponent<Camera>();
				((Behaviour)val9).enabled = false;
				val9.cullingMask = int.MinValue;
				val9.clearFlags = (CameraClearFlags)2;
				val9.backgroundColor = new Color(0f, 0f, 0f, 0f);
				val9.fieldOfView = 30f;
				val9.allowHDR = false;
				val9.allowMSAA = false;
				Vector3 val10 = new Vector3(0.45f, 0.25f, 1f);
				Vector3 normalized = ((Vector3)(ref val10)).normalized;
				val10 = ((Bounds)(ref value2)).extents;
				float magnitude = ((Vector3)(ref val10)).magnitude;
				float num = magnitude / Mathf.Sin(val9.fieldOfView * 0.5f * ((float)Math.PI / 180f)) * 1.02f;
				((Component)val9).transform.position = ((Bounds)(ref value2)).center + normalized * num;
				((Component)val9).transform.LookAt(((Bounds)(ref value2)).center);
				val9.nearClipPlane = Mathf.Max(0.05f, num - magnitude * 2f);
				val9.farClipPlane = num + magnitude * 2f;
				val3 = new GameObject("VargheimStatues_IconLight");
				Light obj2 = val3.AddComponent<Light>();
				obj2.type = (LightType)1;
				obj2.cullingMask = int.MinValue;
				obj2.intensity = 1.3f;
				obj2.color = new Color(1f, 0.97f, 0.92f);
				Transform transform = val3.transform;
				val10 = new Vector3(-0.4f, 0.8f, 0.6f);
				transform.rotation = Quaternion.LookRotation(-((Vector3)(ref val10)).normalized);
				val4 = (val9.targetTexture = RenderTexture.GetTemporary(128, 128, 24, (RenderTextureFormat)0, (RenderTextureReadWrite)2));
				val9.Render();
				RenderTexture.active = val4;
				Texture2D val11 = new Texture2D(128, 128, (TextureFormat)4, false);
				val11.ReadPixels(new Rect(0f, 0f, 128f, 128f), 0, 0, false);
				val11.Apply(false, true);
				((Object)val11).name = "statue_icon_" + key;
				val9.targetTexture = null;
				Sprite obj3 = Sprite.Create(val11, new Rect(0f, 0f, 128f, 128f), new Vector2(0.5f, 0.5f), 100f);
				((Object)obj3).name = "statue_icon_" + key;
				return obj3;
			}
			catch (Exception ex)
			{
				Plugin.Warn("icon for " + key + " could not be rendered (" + ex.GetType().Name + "); it keeps the stone icon.");
				return null;
			}
			finally
			{
				RenderTexture.active = active;
				if ((Object)(object)val4 != (Object)null)
				{
					RenderTexture.ReleaseTemporary(val4);
				}
				if ((Object)(object)val != (Object)null)
				{
					Object.DestroyImmediate((Object)(object)val);
				}
				if ((Object)(object)val2 != (Object)null)
				{
					Object.DestroyImmediate((Object)(object)val2);
				}
				if ((Object)(object)val3 != (Object)null)
				{
					Object.DestroyImmediate((Object)(object)val3);
				}
			}
		}
	}
	internal static class ObjModel
	{
		private static readonly Dictionary<string, Mesh> s_cache = new Dictionary<string, Mesh>(StringComparer.OrdinalIgnoreCase);

		internal static bool IsObj(string creature)
		{
			return creature?.Trim().EndsWith(".obj", StringComparison.OrdinalIgnoreCase) ?? false;
		}

		internal static IEnumerable<string> Folders()
		{
			string here = Path.GetDirectoryName(((BaseUnityPlugin)Plugin.Instance).Info.Location);
			yield return Path.Combine(here, "models");
			yield return here;
			yield return Path.Combine(Path.Combine(Paths.ConfigPath, "VargheimStatues"), "models");
		}

		internal static Mesh Load(string creature)
		{
			//IL_018b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0190: Unknown result type (might be due to invalid IL or missing references)
			//IL_0194: Unknown result type (might be due to invalid IL or missing references)
			//IL_0199: Unknown result type (might be due to invalid IL or missing references)
			string text = Path.GetFileName(creature.Trim());
			if (text.EndsWith(".obj", StringComparison.OrdinalIgnoreCase))
			{
				text = text.Substring(0, text.Length - 4);
			}
			if (s_cache.TryGetValue(text, out var value) && (Object)(object)value != (Object)null)
			{
				return value;
			}
			string text2 = null;
			foreach (string item in Folders())
			{
				string text3 = Path.Combine(item, text + ".vsm");
				if (File.Exists(text3))
				{
					text2 = text3;
					break;
				}
				string text4 = Path.Combine(item, text + ".obj");
				if (File.Exists(text4))
				{
					text2 = text4;
					break;
				}
			}
			if (text2 == null)
			{
				Plugin.Warn("model " + text + " not found as .vsm or .obj (looked in the mod's models folder and BepInEx/config/VargheimStatues/models).");
				return null;
			}
			try
			{
				value = (text2.EndsWith(".vsm", StringComparison.OrdinalIgnoreCase) ? ReadVsm(File.ReadAllBytes(text2), text) : Parse(File.ReadAllLines(text2), text));
			}
			catch (Exception ex)
			{
				Plugin.Warn("model " + Path.GetFileName(text2) + " could not be read: " + ex.Message);
				return null;
			}
			if ((Object)(object)value != (Object)null)
			{
				string[] obj = new string[9]
				{
					"model ",
					Path.GetFileName(text2),
					": ",
					value.vertexCount.ToString(),
					" vertices, ",
					(value.triangles.Length / 3).ToString(),
					" triangles, ",
					null,
					null
				};
				Bounds bounds = value.bounds;
				obj[7] = ((Bounds)(ref bounds)).size.y.ToString("0.00", CultureInfo.InvariantCulture);
				obj[8] = " m tall.";
				Plugin.Note(string.Concat(obj));
			}
			s_cache[text] = value;
			return value;
		}

		private static Mesh Parse(string[] lines, string name)
		{
			//IL_033d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0344: Expected O, but got Unknown
			//IL_00ab: 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_01b8: Unknown result type (might be due to invalid IL or missing references)
			//IL_01bd: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c7: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d4: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d9: Unknown result type (might be due to invalid IL or missing references)
			//IL_01db: Unknown result type (might be due to invalid IL or missing references)
			//IL_01dd: Unknown result type (might be due to invalid IL or missing references)
			//IL_01e2: Unknown result type (might be due to invalid IL or missing references)
			//IL_01e4: Unknown result type (might be due to invalid IL or missing references)
			//IL_01e6: 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_01f0: Unknown result type (might be due to invalid IL or missing references)
			//IL_020c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0218: Unknown result type (might be due to invalid IL or missing references)
			//IL_0224: Unknown result type (might be due to invalid IL or missing references)
			//IL_024e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0253: Unknown result type (might be due to invalid IL or missing references)
			//IL_0267: Unknown result type (might be due to invalid IL or missing references)
			//IL_025d: Unknown result type (might be due to invalid IL or missing references)
			//IL_026c: Unknown result type (might be due to invalid IL or missing references)
			//IL_027c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0284: Unknown result type (might be due to invalid IL or missing references)
			//IL_028d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0294: Unknown result type (might be due to invalid IL or missing references)
			//IL_02ad: Unknown result type (might be due to invalid IL or missing references)
			//IL_02b4: Unknown result type (might be due to invalid IL or missing references)
			//IL_029d: Unknown result type (might be due to invalid IL or missing references)
			//IL_02a4: Unknown result type (might be due to invalid IL or missing references)
			//IL_02d2: Unknown result type (might be due to invalid IL or missing references)
			//IL_02d9: Unknown result type (might be due to invalid IL or missing references)
			//IL_02e0: Unknown result type (might be due to invalid IL or missing references)
			//IL_02bd: Unknown result type (might be due to invalid IL or missing references)
			//IL_02c4: Unknown result type (might be due to invalid IL or missing references)
			//IL_02cb: Unknown result type (might be due to invalid IL or missing references)
			//IL_02e7: Unknown result type (might be due to invalid IL or missing references)
			//IL_02ee: Unknown result type (might be due to invalid IL or missing references)
			//IL_02f5: Unknown result type (might be due to invalid IL or missing references)
			List<Vector3> list = new List<Vector3>();
			List<Vector3> list2 = new List<Vector3>();
			List<Vector3> list3 = new List<Vector3>();
			List<Vector3> list4 = new List<Vector3>();
			List<Vector2> list5 = new List<Vector2>();
			List<int> list6 = new List<int>();
			char[] separator = new char[2] { ' ', '\t' };
			Vector3 val5 = default(Vector3);
			for (int i = 0; i < lines.Length; i++)
			{
				string text = lines[i].Trim();
				if (text.Length < 2 || text[0] == '#')
				{
					continue;
				}
				string[] array = text.Split(separator, StringSplitOptions.RemoveEmptyEntries);
				if (array[0] == "v" && array.Length >= 4)
				{
					list.Add(new Vector3(0f - F(array[1]), F(array[2]), F(array[3])));
				}
				else if (array[0] == "vn" && array.Length >= 4)
				{
					list2.Add(new Vector3(0f - F(array[1]), F(array[2]), F(array[3])));
				}
				else
				{
					if (!(array[0] == "f") || array.Length < 4)
					{
						continue;
					}
					int num = array.Length - 1;
					int[] array2 = new int[num];
					int[] array3 = new int[num];
					for (int j = 0; j < num; j++)
					{
						string[] array4 = array[j + 1].Split('/');
						array2[j] = Idx(array4[0], list.Count);
						array3[j] = ((array4.Length >= 3 && array4[2].Length > 0) ? Idx(array4[2], list2.Count) : (-1));
					}
					for (int k = 1; k + 1 < num; k++)
					{
						int[] array5 = new int[3]
						{
							0,
							k + 1,
							k
						};
						Vector3 val = list[array2[array5[0]]];
						Vector3 val2 = list[array2[array5[1]]];
						Vector3 val3 = list[array2[array5[2]]];
						Vector3 val4 = Vector3.Cross(val2 - val, val3 - val);
						if (!(((Vector3)(ref val4)).sqrMagnitude < 1E-14f))
						{