Decompiled source of VargheimRoundhouse v0.5.6

plugins/VargheimRoundhouse.dll

Decompiled an hour ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.Globalization;
using System.IO;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Text;
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 VargheimRoundhouse
{
	internal class MetaSnap
	{
		public string name;

		public float[] position_blender_z_up;

		public float facing_degrees;
	}
	internal class MetaBox
	{
		public string name;

		public float[] center;

		public float[] size;

		public float rotation_z_degrees;

		public float[] rotation_quaternion_blender_wxyz;

		public float[] center_unity_xyz;

		public float[] size_unity_xyz;

		public float[] rotation_unity_xyzw;
	}
	internal class MetaPart
	{
		public string model;

		public string material_role;
	}
	internal class MetaLeaf
	{
		public string name;

		public MetaPart[] render_parts;

		public float[] hinge_blender_z_up;

		public float open_degrees;

		public MetaBox[] boxes;
	}
	internal class Meta
	{
		public string schema;

		public string name;

		public string label;

		public string import_contract_revision;

		public string kind;

		public string exact_collision_model;

		public float radius_m;

		public float height_m;

		public float angle_degrees;

		public float pitch_degrees;

		public float ground_offset;

		public bool inverse;

		public MetaSnap[] snap_points;

		public MetaBox[] box_colliders_blender_z_up;

		public MetaPart[] render_parts;

		public MetaLeaf[] interactive_components;

		public MetaSnap[] effect_anchors;

		public List<KeyValuePair<string, int>> cost = new List<KeyValuePair<string, int>>();

		public string station;

		public string material;

		public float health;

		public bool ground_only;

		public bool has_ground_only;

		internal static MetaBox Box(Dictionary<string, object> o)
		{
			return new MetaBox
			{
				name = Json.S(o, "name"),
				center = Json.Floats(o, "center"),
				size = Json.Floats(o, "size"),
				rotation_z_degrees = Json.F(o, "rotation_z_degrees"),
				rotation_quaternion_blender_wxyz = Json.Floats(o, "rotation_quaternion_blender_wxyz"),
				center_unity_xyz = Json.Floats(o, "center_unity_xyz"),
				size_unity_xyz = Json.Floats(o, "size_unity_xyz"),
				rotation_unity_xyzw = Json.Floats(o, "rotation_unity_xyzw")
			};
		}

		internal static Meta Read(string text)
		{
			if (!(Json.Parse(text) is Dictionary<string, object> dictionary))
			{
				return null;
			}
			Meta meta = new Meta
			{
				schema = Json.S(dictionary, "schema"),
				name = Json.S(dictionary, "name"),
				label = Json.S(dictionary, "label"),
				import_contract_revision = Json.S(dictionary, "import_contract_revision"),
				kind = Json.S(dictionary, "kind"),
				exact_collision_model = Json.S(dictionary, "exact_collision_model"),
				radius_m = Json.F(dictionary, "radius_m"),
				height_m = Json.F(dictionary, "height_m"),
				angle_degrees = Json.F(dictionary, "angle_degrees"),
				pitch_degrees = (dictionary.ContainsKey("pitch_degrees") ? Json.F(dictionary, "pitch_degrees") : Json.F(dictionary, "pitch_family_degrees")),
				inverse = Json.B(dictionary, "inverse"),
				ground_offset = Json.F(dictionary, "placement_ground_offset_m")
			};
			List<MetaPart> list = new List<MetaPart>();
			foreach (Dictionary<string, object> item in Json.Objects(dictionary, "render_parts"))
			{
				list.Add(new MetaPart
				{
					model = Json.S(item, "model"),
					material_role = Json.S(item, "material_role")
				});
			}
			meta.render_parts = list.ToArray();
			List<MetaSnap> list2 = new List<MetaSnap>();
			foreach (Dictionary<string, object> item2 in Json.Objects(dictionary, "snap_points"))
			{
				list2.Add(new MetaSnap
				{
					name = Json.S(item2, "name"),
					position_blender_z_up = Json.Floats(item2, "position_blender_z_up")
				});
			}
			meta.snap_points = list2.ToArray();
			List<MetaBox> list3 = new List<MetaBox>();
			foreach (Dictionary<string, object> item3 in Json.Objects(dictionary, "box_colliders_blender_z_up"))
			{
				list3.Add(Box(item3));
			}
			meta.box_colliders_blender_z_up = list3.ToArray();
			List<MetaLeaf> list4 = new List<MetaLeaf>();
			foreach (Dictionary<string, object> item4 in Json.Objects(dictionary, "interactive_components"))
			{
				List<MetaPart> list5 = new List<MetaPart>();
				foreach (Dictionary<string, object> item5 in Json.Objects(item4, "render_parts"))
				{
					list5.Add(new MetaPart
					{
						model = Json.S(item5, "model"),
						material_role = Json.S(item5, "material_role")
					});
				}
				List<MetaBox> list6 = new List<MetaBox>();
				foreach (Dictionary<string, object> item6 in Json.Objects(item4, "box_colliders_blender_z_up"))
				{
					list6.Add(Box(item6));
				}
				list4.Add(new MetaLeaf
				{
					name = Json.S(item4, "name"),
					render_parts = list5.ToArray(),
					hinge_blender_z_up = Json.Floats(item4, "hinge_blender_z_up"),
					open_degrees = (item4.ContainsKey("open_degrees") ? Json.F(item4, "open_degrees") : 90f),
					boxes = list6.ToArray()
				});
			}
			meta.interactive_components = list4.ToArray();
			List<MetaSnap> list7 = new List<MetaSnap>();
			foreach (Dictionary<string, object> item7 in Json.Objects(dictionary, "effect_anchors"))
			{
				list7.Add(new MetaSnap
				{
					name = Json.S(item7, "name"),
					position_blender_z_up = Json.Floats(item7, "position_blender_z_up"),
					facing_degrees = (item7.ContainsKey("facing_degrees") ? Json.F(item7, "facing_degrees") : 0f)
				});
			}
			meta.effect_anchors = list7.ToArray();
			foreach (Dictionary<string, object> item8 in Json.Objects(dictionary, "cost"))
			{
				string text2 = Json.S(item8, "item");
				int num = (int)Math.Round(Json.F(item8, "amount"));
				if (!string.IsNullOrEmpty(text2) && num > 0)
				{
					meta.cost.Add(new KeyValuePair<string, int>(text2, num));
				}
			}
			meta.station = Json.S(dictionary, "station");
			meta.material = Json.S(dictionary, "material");
			meta.health = Json.F(dictionary, "health");
			meta.has_ground_only = dictionary.ContainsKey("ground_only");
			meta.ground_only = Json.B(dictionary, "ground_only");
			return meta;
		}
	}
	internal static class Builder
	{
		private static GameObject s_holder;

		private static Material s_wood;

		private static Material s_stone;

		private static Material s_thatch;

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

		private static readonly Dictionary<string, GameObject> s_templates = new Dictionary<string, GameObject>();

		private static ObjectDB s_db;

		private static ZNetScene s_zs;

		private static Chair s_chair;

		internal static readonly string[] KnownKinds = new string[33]
		{
			"fort_wall", "fort_tower", "fort_stair", "fort_gate", "fort_door", "fort_bridge", "fort_deck", "wall", "gable", "diagnostic",
			"base", "floor", "floor_adapter", "step", "roof", "roof_transition", "roof_cap", "smoke_collar", "smoke_cowl", "ridge",
			"porch_roof", "post", "beam", "railing", "brace", "roof_batten", "railing_gate", "gate", "door", "torch",
			"firepit", "decor", "decor_stone"
		};

		private static string s_boundLog = "";

		private static readonly Dictionary<string, Material> s_bound = new Dictionary<string, Material>(StringComparer.OrdinalIgnoreCase);

		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("VargheimRoundhouse_Prefabs");
				s_holder.SetActive(false);
				Object.DontDestroyOnLoad((Object)(object)s_holder);
			}
			return s_holder.transform;
		}

		internal static List<GameObject> BuildAll(ObjectDB db, ZNetScene zs)
		{
			List<GameObject> list = new List<GameObject>();
			string text = Plugin.PiecesDir();
			if (!Directory.Exists(text))
			{
				Plugin.Warn("no pieces folder at " + text);
				return list;
			}
			GameObject val = Plugin.FirstPiece(db, zs, "woodwall", "wood_wall_half", "wood_floor");
			GameObject val2 = Plugin.FirstPiece(db, zs, "stone_wall_1x1", "stone_wall_2x1", "stone_floor_2x2");
			if ((Object)(object)val == (Object)null || (Object)(object)val2 == (Object)null)
			{
				Plugin.Warn("vanilla base pieces not found (woodwall / stone_wall_1x1).");
				return list;
			}
			s_templates.Clear();
			s_templates["wall"] = val;
			s_templates["base"] = val2;
			s_templates["floor"] = Plugin.FirstPiece(db, zs, "wood_floor", "wood_floor_1x1") ?? val;
			s_templates["roof26"] = Plugin.FirstPiece(db, zs, "wood_roof", "darkwood_roof") ?? val;
			s_templates["roof45"] = Plugin.FirstPiece(db, zs, "wood_roof_45", "darkwood_roof_45", "wood_roof") ?? val;
			s_templates["pole"] = Plugin.FirstPiece(db, zs, "wood_pole2", "wood_pole") ?? val;
			s_templates["beam"] = Plugin.FirstPiece(db, zs, "wood_beam", "wood_beam_1") ?? val;
			s_templates["stair"] = Plugin.FirstPiece(db, zs, "stone_stair", "wood_stair") ?? val2;
			s_templates["wood_stair"] = Plugin.FirstPiece(db, zs, "wood_stair", "stone_stair") ?? val;
			s_db = db;
			s_zs = zs;
			s_templates["gate"] = Plugin.FirstPiece(db, zs, "wood_gate", "wood_door") ?? val;
			s_templates["door"] = Plugin.FirstPiece(db, zs, "wood_door", "wood_gate") ?? val;
			s_templates["torch"] = Plugin.FirstPiece(db, zs, "piece_walltorch", "piece_groundtorch_wood") ?? s_templates["beam"];
			s_templates["firepit"] = Plugin.FirstPiece(db, zs, "fire_pit", "fire_pit_iron", "hearth") ?? val2;
			GameObject val3 = Plugin.FirstPiece(db, zs, "piece_chair", "piece_chair02", "piece_bench01");
			s_chair = (((Object)(object)val3 != (Object)null) ? val3.GetComponentInChildren<Chair>(true) : null);
			if ((Object)(object)s_chair == (Object)null)
			{
				Plugin.Warn("no vanilla chair found; seat anchors use built-in chair settings.");
			}
			Seats.Calibrate(db, zs);
			s_wood = PieceMaterial(val);
			GameObject val4 = Plugin.FirstPiece(db, zs, "stone_floor_2x2", "stone_floor");
			s_stone = PieceMaterial(((Object)(object)val4 != (Object)null) ? val4 : val2);
			s_thatch = ThatchMaterial(s_templates["roof26"]) ?? ThatchMaterial(s_templates["roof45"]) ?? s_wood;
			Plugin.Note("templates: wall " + ((Object)val).name + ", base " + ((Object)val2).name + ", floor " + ((Object)s_templates["floor"]).name + ", roofs " + ((Object)s_templates["roof26"]).name + "/" + ((Object)s_templates["roof45"]).name + ", pole " + ((Object)s_templates["pole"]).name + ", beam " + ((Object)s_templates["beam"]).name + ", stair " + ((Object)s_templates["stair"]).name + ", gate " + ((Object)s_templates["gate"]).name + "; materials: wood=" + Name(s_wood) + ", stone=" + Name(s_stone) + ", thatch=" + Name(s_thatch));
			string[] directories = Directory.GetDirectories(text);
			Array.Sort(directories, (IComparer<string>?)StringComparer.OrdinalIgnoreCase);
			HashSet<string> hashSet = new HashSet<string>(StringComparer.OrdinalIgnoreCase);
			string path = Path.Combine(text, "retired.txt");
			string[] array;
			if (File.Exists(path))
			{
				array = File.ReadAllLines(path);
				for (int i = 0; i < array.Length; i++)
				{
					string text2 = array[i].Trim();
					if (text2.Length > 0 && !text2.StartsWith("#"))
					{
						hashSet.Add(text2);
					}
				}
			}
			if (hashSet.Count > 0)
			{
				Plugin.Note(hashSet.Count + " retired piece folders skipped: " + string.Join(", ", new List<string>(hashSet).ToArray()));
			}
			array = directories;
			foreach (string text3 in array)
			{
				if (hashSet.Contains(Path.GetFileName(text3)))
				{
					continue;
				}
				string[] array2 = new string[2] { "piece_metadata.json", "base_metadata.json" };
				foreach (string text4 in array2)
				{
					string text5 = Path.Combine(text3, text4);
					if (!File.Exists(text5))
					{
						continue;
					}
					try
					{
						Meta meta = Meta.Read(File.ReadAllText(text5));
						if (meta != null)
						{
							Plugin.Note(Path.GetFileName(text3) + "/" + Path.GetFileName(text5) + ": " + meta.render_parts.Length + " parts, " + meta.snap_points.Length + " snaps, " + meta.box_colliders_blender_z_up.Length + " boxes.");
						}
						if (meta == null || string.IsNullOrEmpty(meta.name))
						{
							Plugin.Warn(text5 + ": no name.");
							continue;
						}
						string text6 = (text4.StartsWith("base", StringComparison.Ordinal) ? "base" : (string.IsNullOrEmpty(meta.kind) ? "wall" : meta.kind.ToLowerInvariant()));
						if (meta.name.IndexOf("diagnostic", StringComparison.OrdinalIgnoreCase) >= 0)
						{
							text6 = "diagnostic";
						}
						if (text6 == "decor")
						{
							MetaPart[] render_parts = meta.render_parts;
							for (int k = 0; k < render_parts.Length; k++)
							{
								if (string.Equals(render_parts[k].material_role, "stone", StringComparison.OrdinalIgnoreCase))
								{
									text6 = "decor_stone";
								}
							}
						}
						if (Array.IndexOf(KnownKinds, text6) < 0)
						{
							Plugin.Warn(meta.name + ": unknown kind \"" + text6 + "\" - built as a plain wall. Add it to the loader or change the sidecar.");
						}
						Requirement[] reqs = ((meta.cost.Count > 0) ? CostFromSidecar(db, meta) : Cost(db, text6));
						GameObject val5 = Make(meta, text3, Template(text6, meta.pitch_degrees, meta.material), reqs, text6);
						if ((Object)(object)val5 != (Object)null)
						{
							list.Add(val5);
						}
					}
					catch (Exception ex)
					{
						Plugin.Warn(text5 + ": " + ex);
					}
				}
			}
			return list;
		}

		private static GameObject Template(string kind, float pitch, string material)
		{
			string key = ((pitch >= 35f) ? "roof45" : "roof26");
			bool flag = IsStone(material);
			switch (kind)
			{
			case "fort_wall":
			case "fort_tower":
				if (!flag)
				{
					return s_templates["wall"];
				}
				return s_templates["base"];
			case "fort_stair":
				if (!flag)
				{
					return s_templates["wood_stair"];
				}
				return s_templates["stair"];
			case "fort_gate":
				return s_templates["gate"];
			case "fort_door":
				return s_templates["door"];
			case "fort_deck":
			case "fort_bridge":
				if (!flag)
				{
					return s_templates["floor"];
				}
				return s_templates["base"];
			case "base":
				return s_templates["base"];
			case "floor":
			case "floor_adapter":
				return s_templates["floor"];
			case "step":
				return s_templates["stair"];
			case "porch_roof":
			case "smoke_cowl":
			case "roof":
			case "ridge":
			case "smoke_collar":
			case "roof_transition":
			case "roof_cap":
				return s_templates[key];
			case "post":
				return s_templates["pole"];
			case "gate":
			case "railing_gate":
				return s_templates["gate"];
			case "door":
				return s_templates["door"];
			case "torch":
				return s_templates["torch"];
			case "firepit":
				return s_templates["firepit"];
			case "decor_stone":
				return s_templates["base"];
			case "decor":
				return s_templates["beam"];
			case "roof_batten":
			case "beam":
			case "brace":
			case "railing":
				return s_templates["beam"];
			default:
				return s_templates["wall"];
			}
		}

		private static Requirement[] Cost(ObjectDB db, string kind)
		{
			switch (kind)
			{
			case "base":
				return Reqs(db, "Stone", 3);
			case "step":
				return Reqs(db, "Stone", 2);
			case "beam":
			case "post":
			case "diagnostic":
			case "railing":
			case "brace":
			case "ridge":
			case "roof_batten":
				return Reqs(db, "Wood", 1);
			case "gate":
			case "door":
			case "railing_gate":
				return Reqs(db, "Wood", 4);
			case "decor_stone":
				return Reqs(db, "Stone", 4);
			case "decor":
				return Reqs(db, "Wood", 2);
			case "torch":
				return Reqs(db, "Wood", 2);
			case "firepit":
				return Reqs(db, "Stone", 5);
			case "roof":
			case "porch_roof":
			case "smoke_cowl":
			case "floor":
			case "gable":
			case "smoke_collar":
			case "floor_adapter":
			case "roof_transition":
			case "roof_cap":
				return Reqs(db, "Wood", 2);
			default:
				return Reqs(db, "Wood", 3);
			}
		}

		private static GameObject Make(Meta meta, string dir, GameObject basePiece, Requirement[] reqs, string kind)
		{
			//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_0348: 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_0360: Unknown result type (might be due to invalid IL or missing references)
			//IL_0367: Unknown result type (might be due to invalid IL or missing references)
			//IL_036d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0379: Unknown result type (might be due to invalid IL or missing references)
			//IL_0496: Unknown result type (might be due to invalid IL or missing references)
			//IL_049b: Unknown result type (might be due to invalid IL or missing references)
			//IL_04a6: Unknown result type (might be due to invalid IL or missing references)
			//IL_04ae: Unknown result type (might be due to invalid IL or missing references)
			//IL_04e0: Unknown result type (might be due to invalid IL or missing references)
			//IL_061d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0622: Unknown result type (might be due to invalid IL or missing references)
			//IL_0548: Unknown result type (might be due to invalid IL or missing references)
			//IL_054d: Unknown result type (might be due to invalid IL or missing references)
			//IL_054e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0553: Unknown result type (might be due to invalid IL or missing references)
			//IL_0555: Unknown result type (might be due to invalid IL or missing references)
			List<KeyValuePair<Mesh, Material>> list = new List<KeyValuePair<Mesh, Material>>();
			int num = 0;
			int num2 = 0;
			s_boundLog = "";
			MetaPart[] array = meta.render_parts ?? new MetaPart[0];
			foreach (MetaPart metaPart in array)
			{
				string path = Path.Combine(dir, metaPart.model);
				if (!File.Exists(path))
				{
					Plugin.Warn(meta.name + ": missing " + metaPart.model);
					continue;
				}
				Obj.Result result = Obj.Load(path, "vrh_" + meta.name + "_" + metaPart.material_role);
				if (result == null)
				{
					Plugin.Warn(meta.name + ": " + metaPart.model + " has no faces.");
					continue;
				}
				num += result.Triangles;
				num2 += result.Reordered;
				list.Add(new KeyValuePair<Mesh, Material>(result.Mesh, RoleMaterial(metaPart.material_role, dir)));
			}
			if (list.Count == 0)
			{
				Plugin.Warn(meta.name + ": nothing to show, skipped.");
				return null;
			}
			GameObject val = Object.Instantiate<GameObject>(basePiece, Holder(), false);
			((Object)val).name = "VRH_" + meta.name;
			int layer = val.layer;
			List<Transform> list2 = FireRoots(val);
			Renderer[] componentsInChildren = val.GetComponentsInChildren<Renderer>(true);
			foreach (Renderer val2 in componentsInChildren)
			{
				bool flag = false;
				foreach (Transform item in list2)
				{
					if (((Component)val2).transform.IsChildOf(item))
					{
						flag = true;
						break;
					}
				}
				if (!flag)
				{
					val2.enabled = false;
				}
			}
			if (list2.Count > 0)
			{
				MoveFire(val, list2, meta);
			}
			Collider[] componentsInChildren2 = val.GetComponentsInChildren<Collider>(true);
			foreach (Collider val3 in componentsInChildren2)
			{
				if (!val3.isTrigger || !((Object)(object)((Component)val3).GetComponent<EffectArea>() != (Object)null))
				{
					Object.DestroyImmediate((Object)(object)val3);
				}
			}
			List<GameObject> list3 = new List<GameObject>();
			Transform[] componentsInChildren3 = val.GetComponentsInChildren<Transform>(true);
			foreach (Transform val4 in componentsInChildren3)
			{
				if ((Object)(object)val4 != (Object)(object)val.transform && (((Component)val4).CompareTag("snappoint") || ((Object)val4).name.StartsWith("_snappoint", StringComparison.OrdinalIgnoreCase)))
				{
					list3.Add(((Component)val4).gameObject);
				}
			}
			foreach (GameObject item2 in list3)
			{
				Object.DestroyImmediate((Object)(object)item2);
			}
			GameObject val5 = Visual(val.transform, "rh_new", list, layer);
			GameObject val6 = Visual(val.transform, "rh_worn", list, layer);
			GameObject val7 = Visual(val.transform, "rh_broken", list, layer);
			val6.SetActive(false);
			val7.SetActive(false);
			int num3 = 0;
			MetaBox[] array2 = meta.box_colliders_blender_z_up ?? new MetaBox[0];
			for (int i = 0; i < array2.Length; i++)
			{
				if (BoxPose(array2[i], out var c, out var size, out var q))
				{
					GameObject val8 = new GameObject("rh_col_" + num3)
					{
						layer = layer
					};
					val8.transform.SetParent(val.transform, false);
					val8.transform.localPosition = c;
					val8.transform.localRotation = q;
					val8.AddComponent<BoxCollider>().size = size;
					num3++;
				}
			}
			if (num3 == 0)
			{
				Plugin.Warn(meta.name + ": no box colliders in the sidecar, piece skipped (it could not be placed or hit).");
				Object.DestroyImmediate((Object)(object)val);
				return null;
			}
			int num4 = 0;
			MetaLeaf[] array3 = meta.interactive_components ?? new MetaLeaf[0];
			foreach (MetaLeaf leaf in array3)
			{
				if (AddLeaf(val, leaf, dir, layer, meta.name))
				{
					num4++;
				}
			}
			if ((meta.interactive_components ?? new MetaLeaf[0]).Length != 0 && (Object)(object)val.GetComponent<Door>() == (Object)null)
			{
				Plugin.Warn(meta.name + ": has a moving leaf but its template " + ((Object)basePiece).name + " has no Door; the leaf will not open.");
			}
			int num5 = 0;
			MetaSnap[] array4 = meta.snap_points ?? new MetaSnap[0];
			foreach (MetaSnap metaSnap in array4)
			{
				if (metaSnap.position_blender_z_up != null && metaSnap.position_blender_z_up.Length >= 3)
				{
					GameObject val9 = new GameObject(string.IsNullOrEmpty(metaSnap.name) ? "_snappoint" : metaSnap.name)
					{
						tag = "snappoint",
						layer = layer
					};
					val9.transform.SetParent(val.transform, false);
					val9.transform.localPosition = Obj.Pos(metaSnap.position_blender_z_up[0], metaSnap.position_blender_z_up[1], metaSnap.position_blender_z_up[2]);
					num5++;
				}
			}
			AddSeats(val, meta, layer);
			if (meta.ground_offset > 0f)
			{
				Vector3 val10 = default(Vector3);
				((Vector3)(ref val10))..ctor(0f, meta.ground_offset, 0f);
				foreach (Transform item3 in val.transform)
				{
					item3.localPosition += val10;
				}
				Plugin.Note(meta.name + ": lifted " + meta.ground_offset.ToString("0.00", CultureInfo.InvariantCulture) + " m (placement_ground_offset_m).");
			}
			WearNTear component = val.GetComponent<WearNTear>();
			if ((Object)(object)component != (Object)null)
			{
				component.m_new = val5;
				component.m_worn = val6;
				component.m_broken = val7;
				if (meta.health > 0f)
				{
					component.m_health = meta.health;
				}
				if (!string.IsNullOrEmpty(meta.material))
				{
					try
					{
						component.m_materialType = (MaterialType)Enum.Parse(typeof(MaterialType), meta.material, ignoreCase: true);
					}
					catch
					{
						Plugin.Warn(meta.name + ": unknown material \"" + meta.material + "\" (Wood, Stone, Iron, HardWood, Marble, Ashstone); template's kept.");
					}
				}
				SetField(component, "m_fragmentRoots", (GameObject[])(object)new GameObject[1] { val5 });
				ClearArray(component, "m_nonSolidRenderers");
				Docks.Apply(meta.name, component);
			}
			Piece component2 = val.GetComponent<Piece>();
			string text = (string.IsNullOrEmpty(meta.label) ? meta.name : meta.label);
			bool flag2 = kind == "base";
			bool flag3 = kind.StartsWith("fort_", StringComparison.Ordinal);
			switch (kind)
			{
			case "fort_wall":
			case "fort_tower":
			case "fort_deck":
			case "fort_bridge":
			case "fort_door":
				Fort.EarthFilled.Add(((Object)val).name);
				break;
			}
			component2.m_name = (flag3 ? "Fort: " : (flag2 ? "Roundhouse base: " : "Roundhouse: ")) + text;
			component2.m_description = (flag3 ? ("Vargheim fortification, " + kind.Substring(5).Replace('_', ' ') + " (test build).") : ("Hearth & Hull " + kind.Replace('_', ' ') + " (test build). " + ((meta.radius_m > 0f) ? (meta.radius_m.ToString("0.#", CultureInfo.InvariantCulture) + " m ring, " + meta.angle_degrees.ToString("0", CultureInfo.InvariantCulture) + " degree section.") : "")));
			component2.m_resources = reqs;
			if (!string.IsNullOrEmpty(meta.station))
			{
				if (meta.station.Equals("none", StringComparison.OrdinalIgnoreCase))
				{
					component2.m_craftingStation = null;
				}
				else
				{
					CraftingStation val12 = Station(meta.station, meta.name);
					if ((Object)(object)val12 != (Object)null)
					{
						component2.m_craftingStation = val12;
					}
				}
			}
			if (meta.has_ground_only)
			{
				component2.m_groundOnly = meta.ground_only;
			}
			Door component3 = val.GetComponent<Door>();
			if ((Object)(object)component3 != (Object)null)
			{
				component3.m_name = component2.m_name;
			}
			Fireplace component4 = val.GetComponent<Fireplace>();
			if ((Object)(object)component4 != (Object)null)
			{
				component4.m_name = component2.m_name;
			}
			if (kind == "firepit")
			{
				Hearth.MakeCauldron(val, component2.m_name);
			}
			Sprite val13 = Icon.Render(val, meta.name);
			if ((Object)(object)val13 != (Object)null)
			{
				component2.m_icon = val13;
			}
			Plugin.Note(((Object)val).name + ": " + list.Count + " parts, " + num + " triangles (" + num2 + " reordered to match their normals), " + num3 + " colliders, " + num5 + " snap points, " + num4 + " hinged leaves, " + ((s_boundLog.Length > 0) ? ("bound textures: " + s_boundLog.Trim() + ", ") : "") + "kind " + kind + ", from " + ((Object)basePiece).name + (((Object)(object)component != (Object)null) ? (", health " + component.m_health.ToString("0", CultureInfo.InvariantCulture) + " " + ((object)Unsafe.As<MaterialType, MaterialType>(ref component.m_materialType)/*cast due to .constrained prefix*/).ToString()) : "") + (((Object)(object)component2.m_craftingStation != (Object)null) ? (", station " + ((Object)component2.m_craftingStation).name) : "") + (component2.m_groundOnly ? ", ground only" : "") + (string.IsNullOrEmpty(meta.import_contract_revision) ? "" : (", contract " + meta.import_contract_revision)));
			return val;
		}

		private static List<Transform> FireRoots(GameObject piece)
		{
			List<Transform> list = new List<Transform>();
			Fireplace component = piece.GetComponent<Fireplace>();
			if ((Object)(object)component == (Object)null)
			{
				return list;
			}
			string[] array = new string[3] { "m_enabledObject", "m_enabledObjectLow", "m_enabledObjectHigh" };
			foreach (string name in array)
			{
				FieldInfo field = typeof(Fireplace).GetField(name, BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
				GameObject val = (GameObject)((field != null) ? /*isinst with value type is only supported in some contexts*/: null);
				if ((Object)(object)val != (Object)null && !list.Contains(val.transform))
				{
					list.Add(val.transform);
				}
			}
			FieldInfo field2 = typeof(Fireplace).GetField("m_smokeSpawner", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
			Component val2 = (Component)((field2 != null) ? /*isinst with value type is only supported in some contexts*/: null);
			if ((Object)(object)val2 != (Object)null && !list.Contains(val2.transform))
			{
				list.Add(val2.transform);
			}
			return list;
		}

		private static int AddSeats(GameObject piece, Meta meta, int layer)
		{
			//IL_020f: Unknown result type (might be due to invalid IL or missing references)
			//IL_006e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0075: Expected O, but got Unknown
			//IL_00af: 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_00f2: Unknown result type (might be due to invalid IL or missing references)
			//IL_010b: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b1: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a5: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b6: Unknown result type (might be due to invalid IL or missing references)
			int num = 0;
			MetaSnap[] array = meta.effect_anchors ?? new MetaSnap[0];
			foreach (MetaSnap metaSnap in array)
			{
				if (metaSnap != null && metaSnap.name != null && metaSnap.name.StartsWith("seat", StringComparison.OrdinalIgnoreCase) && metaSnap.position_blender_z_up != null && metaSnap.position_blender_z_up.Length >= 3)
				{
					GameObject val = new GameObject("rh_" + metaSnap.name);
					val.layer = layer;
					val.transform.SetParent(piece.transform, false);
					val.transform.localPosition = Obj.Pos(metaSnap.position_blender_z_up[0], metaSnap.position_blender_z_up[1], metaSnap.position_blender_z_up[2]);
					val.transform.localRotation = Quaternion.Euler(0f, 0f - metaSnap.facing_degrees, 0f);
					BoxCollider obj = val.AddComponent<BoxCollider>();
					obj.center = new Vector3(0f, 0.04f, 0f);
					obj.size = new Vector3(0.45f, 0.08f, 0.45f);
					Chair obj2 = val.AddComponent<Chair>();
					obj2.m_name = (((Object)(object)s_chair != (Object)null) ? s_chair.m_name : "$piece_chair");
					obj2.m_useDistance = (((Object)(object)s_chair != (Object)null) ? s_chair.m_useDistance : 2f);
					obj2.m_attachAnimation = (((Object)(object)s_chair != (Object)null) ? s_chair.m_attachAnimation : "attach_chair");
					obj2.m_detachOffset = (Vector3)(((Object)(object)s_chair != (Object)null) ? s_chair.m_detachOffset : new Vector3(0f, 0.5f, 0f));
					obj2.m_inShip = false;
					obj2.m_attachPoint = Seats.MakeAttach(val.transform);
					num++;
				}
			}
			if (num > 0)
			{
				Piece component = piece.GetComponent<Piece>();
				if ((Object)(object)component != (Object)null)
				{
					if (component.m_comfort < 1)
					{
						component.m_comfort = 1;
					}
					component.m_comfortGroup = (ComfortGroup)4;
				}
				Plugin.Note(meta.name + ": " + num + " seat(s).");
			}
			return num;
		}

		private static void MoveFire(GameObject piece, List<Transform> fire, Meta meta)
		{
			//IL_008b: 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_009e: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a3: Unknown result type (might be due to invalid IL or missing references)
			//IL_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_00b0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bb: Unknown result type (might be due to invalid IL or missing references)
			//IL_0130: 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_0136: Unknown result type (might be due to invalid IL or missing references)
			MetaSnap metaSnap = null;
			MetaSnap[] array = meta.effect_anchors ?? new MetaSnap[0];
			foreach (MetaSnap metaSnap2 in array)
			{
				if (metaSnap2.name == "flame" || metaSnap == null)
				{
					metaSnap = metaSnap2;
				}
			}
			if (metaSnap == null || metaSnap.position_blender_z_up == null || metaSnap.position_blender_z_up.Length < 3)
			{
				Plugin.Note(meta.name + ": no flame anchor; fire left at the template's spot (piece origin for fire pits).");
				return;
			}
			Vector3 val = Obj.Pos(metaSnap.position_blender_z_up[0], metaSnap.position_blender_z_up[1], metaSnap.position_blender_z_up[2]);
			Vector3 val2 = piece.transform.InverseTransformPoint(fire[0].position);
			Vector3 val3 = piece.transform.TransformVector(val - val2);
			HashSet<Transform> hashSet = new HashSet<Transform>();
			foreach (Transform item in fire)
			{
				bool flag = false;
				foreach (Transform item2 in fire)
				{
					if ((Object)(object)item2 != (Object)(object)item && item.IsChildOf(item2))
					{
						flag = true;
					}
				}
				if (!flag && hashSet.Add(item))
				{
					item.position += val3;
				}
			}
			Plugin.Note(meta.name + ": fire moved to flame anchor " + ((Vector3)(ref val)).ToString("F2") + " (" + fire.Count + " fire objects).");
		}

		private static bool AddLeaf(GameObject piece, MetaLeaf leaf, string dir, int layer, string pieceName)
		{
			//IL_0049: Unknown result type (might be due to invalid IL or missing references)
			//IL_004e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0117: Unknown result type (might be due to invalid IL or missing references)
			//IL_011d: Expected O, but got Unknown
			//IL_013c: 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_0165: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b2: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b7: Unknown result type (might be due to invalid IL or missing references)
			//IL_01be: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d0: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d6: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d8: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d9: Unknown result type (might be due to invalid IL or missing references)
			//IL_01e3: Unknown result type (might be due to invalid IL or missing references)
			//IL_01e9: Unknown result type (might be due to invalid IL or missing references)
			//IL_01f5: Unknown result type (might be due to invalid IL or missing references)
			if (leaf.hinge_blender_z_up == null || leaf.hinge_blender_z_up.Length < 3)
			{
				Plugin.Warn(pieceName + ": leaf " + leaf.name + " has no hinge.");
				return false;
			}
			Vector3 val = Obj.Pos(leaf.hinge_blender_z_up[0], leaf.hinge_blender_z_up[1], leaf.hinge_blender_z_up[2]);
			List<KeyValuePair<Mesh, Material>> list = new List<KeyValuePair<Mesh, Material>>();
			MetaPart[] array = leaf.render_parts ?? new MetaPart[0];
			foreach (MetaPart metaPart in array)
			{
				string path = Path.Combine(dir, metaPart.model);
				if (!File.Exists(path))
				{
					Plugin.Warn(pieceName + ": missing leaf model " + metaPart.model);
					continue;
				}
				Obj.Result result = Obj.Load(path, "vrh_" + pieceName + "_leaf_" + metaPart.material_role);
				if (result != null)
				{
					list.Add(new KeyValuePair<Mesh, Material>(result.Mesh, RoleMaterial(metaPart.material_role, dir)));
				}
			}
			if (list.Count == 0)
			{
				return false;
			}
			GameObject val2 = new GameObject("rh_leaf_pivot_" + leaf.name);
			val2.layer = layer;
			val2.transform.SetParent(piece.transform, false);
			val2.transform.localPosition = val;
			Visual(val2.transform, "rh_leaf_" + leaf.name, list, layer).transform.localPosition = -val;
			int num = 0;
			MetaBox[] array2 = leaf.boxes ?? new MetaBox[0];
			for (int i = 0; i < array2.Length; i++)
			{
				if (BoxPose(array2[i], out var c, out var size, out var q))
				{
					GameObject val3 = new GameObject("rh_leaf_col_" + num++)
					{
						layer = layer
					};
					val3.transform.SetParent(val2.transform, false);
					val3.transform.localPosition = c - val;
					val3.transform.localRotation = q;
					val3.AddComponent<BoxCollider>().size = size;
				}
			}
			HingeLeaf hingeLeaf = piece.AddComponent<HingeLeaf>();
			hingeLeaf.m_pivot = val2.transform;
			hingeLeaf.m_openDegrees = leaf.open_degrees;
			return true;
		}

		private static GameObject Visual(Transform parent, string name, List<KeyValuePair<Mesh, Material>> parts, int layer)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0007: Expected O, but got Unknown
			//IL_0047: Unknown result type (might be due to invalid IL or missing references)
			//IL_004c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0053: Unknown result type (might be due to invalid IL or missing references)
			//IL_0065: Unknown result type (might be due to invalid IL or missing references)
			GameObject val = new GameObject(name);
			val.layer = layer;
			val.transform.SetParent(parent, false);
			int num = 0;
			foreach (KeyValuePair<Mesh, Material> part in parts)
			{
				GameObject val2 = new GameObject(name + "_" + num++)
				{
					layer = layer
				};
				val2.transform.SetParent(val.transform, false);
				val2.AddComponent<MeshFilter>().sharedMesh = part.Key;
				((Renderer)val2.AddComponent<MeshRenderer>()).sharedMaterial = part.Value;
			}
			return val;
		}

		private static Material Bound(string role, string dir)
		{
			//IL_00df: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e6: Expected O, but got Unknown
			//IL_01b5: Unknown result type (might be due to invalid IL or missing references)
			//IL_01bc: Expected O, but got Unknown
			//IL_021b: Unknown result type (might be due to invalid IL or missing references)
			//IL_022a: 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_0255: Unknown result type (might be due to invalid IL or missing references)
			string path = Path.Combine(dir, "material_bindings.json");
			if (!File.Exists(path))
			{
				return null;
			}
			if (!(Json.Parse(File.ReadAllText(path)) is Dictionary<string, object> dictionary) || !dictionary.TryGetValue("roles", out var value))
			{
				return null;
			}
			if (!(value is Dictionary<string, object> dictionary2) || !dictionary2.TryGetValue(role, out var value2))
			{
				return null;
			}
			Dictionary<string, object> d = value2 as Dictionary<string, object>;
			string text = Json.S(d, "albedo");
			if (string.IsNullOrEmpty(text))
			{
				return null;
			}
			string text2 = Path.Combine(dir, text);
			if (!File.Exists(text2))
			{
				Plugin.Warn(Path.GetFileName(dir) + ": bound texture " + text + " missing, using the vanilla look.");
				return null;
			}
			string key = role + "|" + text2;
			if (s_bound.TryGetValue(key, out var value3))
			{
				return value3;
			}
			Material val = BaseRole(role);
			if ((Object)(object)val == (Object)null)
			{
				return null;
			}
			Texture2D val2 = new Texture2D(2, 2, (TextureFormat)4, true);
			if (!ImageConversion.LoadImage(val2, File.ReadAllBytes(text2)))
			{
				Plugin.Warn(text2 + ": could not decode.");
				return null;
			}
			Color32[] pixels = val2.GetPixels32();
			for (int i = 0; i < pixels.Length; i++)
			{
				pixels[i].a = byte.MaxValue;
			}
			val2.SetPixels32(pixels);
			val2.Apply(true, false);
			string a = Json.S(d, "filter");
			((Texture)val2).filterMode = (FilterMode)(string.Equals(a, "Bilinear", StringComparison.OrdinalIgnoreCase) ? 1 : 0);
			((Texture)val2).wrapMode = (TextureWrapMode)(string.Equals(Json.S(d, "wrap"), "Clamp", StringComparison.OrdinalIgnoreCase) ? 1 : 0);
			((Object)val2).name = "vrh_" + Path.GetFileName(dir) + "_" + role;
			value3 = new Material(val);
			((Object)value3).name = "vrh_bound_" + role;
			if (value3.HasProperty("_MainTex"))
			{
				value3.SetTexture("_MainTex", (Texture)(object)val2);
				float[] array = Json.Floats(d, "texture_scale");
				float[] array2 = Json.Floats(d, "texture_offset");
				value3.SetTextureScale("_MainTex", (Vector2)((array != null && array.Length >= 2) ? new Vector2(array[0], array[1]) : Vector2.one));
				value3.SetTextureOffset("_MainTex", (Vector2)((array2 != null && array2.Length >= 2) ? new Vector2(array2[0], array2[1]) : Vector2.zero));
			}
			if (value3.HasProperty("_BumpMap"))
			{
				value3.SetTexture("_BumpMap", (Texture)null);
			}
			if (value3.HasProperty("_BumpScale"))
			{
				value3.SetFloat("_BumpScale", 0f);
			}
			value3.DisableKeyword("_NORMALMAP");
			if (value3.HasProperty("_Cutoff"))
			{
				value3.SetFloat("_Cutoff", 0f);
			}
			s_bound[key] = value3;
			return value3;
		}

		private static Material BaseRole(string role)
		{
			switch ((role ?? "").ToLowerInvariant())
			{
			case "stone":
				return s_stone;
			case "thatch":
			case "straw":
				return s_thatch;
			default:
				return s_wood;
			}
		}

		private static Material RoleMaterial(string role, string dir)
		{
			Material val = Bound((role ?? "").ToLowerInvariant(), dir);
			if ((Object)(object)val != (Object)null)
			{
				if (s_boundLog.IndexOf(role + " ", StringComparison.Ordinal) < 0)
				{
					s_boundLog = s_boundLog + role + " ";
				}
				return val;
			}
			switch ((role ?? "").ToLowerInvariant())
			{
			case "stone":
				return s_stone;
			case "thatch":
			case "straw":
				return s_thatch;
			case "daub":
				return Daub(dir);
			default:
				return s_wood;
			}
		}

		private static Material Daub(string dir)
		{
			//IL_0022: Unknown result type (might be due to invalid IL or missing references)
			//IL_0028: Expected O, but got Unknown
			//IL_003f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0045: Expected O, but got Unknown
			//IL_009d: Unknown result type (might be due to invalid IL or missing references)
			string path = Path.Combine(dir, "daub_albedo.png");
			if (s_daub.TryGetValue(dir, out var value))
			{
				return value;
			}
			value = new Material(s_wood);
			((Object)value).name = "vrh_daub";
			if (File.Exists(path))
			{
				Texture2D val = new Texture2D(2, 2, (TextureFormat)4, true);
				ImageConversion.LoadImage(val, File.ReadAllBytes(path));
				((Texture)val).filterMode = (FilterMode)0;
				((Texture)val).wrapMode = (TextureWrapMode)0;
				if (value.HasProperty("_MainTex"))
				{
					value.SetTexture("_MainTex", (Texture)(object)val);
				}
			}
			else if (value.HasProperty("_Color"))
			{
				value.SetColor("_Color", new Color(0.86f, 0.8f, 0.64f));
			}
			s_daub[dir] = value;
			return value;
		}

		private static Material PieceMaterial(GameObject prefab)
		{
			MeshRenderer[] componentsInChildren = prefab.GetComponentsInChildren<MeshRenderer>(true);
			foreach (MeshRenderer val in componentsInChildren)
			{
				if ((Object)(object)((Renderer)val).sharedMaterial != (Object)null && (Object)(object)((Renderer)val).sharedMaterial.shader != (Object)null && ((Object)((Renderer)val).sharedMaterial.shader).name.Contains("Piece"))
				{
					return ((Renderer)val).sharedMaterial;
				}
			}
			componentsInChildren = prefab.GetComponentsInChildren<MeshRenderer>(true);
			foreach (MeshRenderer val2 in componentsInChildren)
			{
				if ((Object)(object)((Renderer)val2).sharedMaterial != (Object)null)
				{
					return ((Renderer)val2).sharedMaterial;
				}
			}
			return null;
		}

		private static Material ThatchMaterial(GameObject roof)
		{
			if ((Object)(object)roof == (Object)null)
			{
				return null;
			}
			MeshRenderer[] componentsInChildren = roof.GetComponentsInChildren<MeshRenderer>(true);
			for (int i = 0; i < componentsInChildren.Length; i++)
			{
				Material[] sharedMaterials = ((Renderer)componentsInChildren[i]).sharedMaterials;
				foreach (Material val in sharedMaterials)
				{
					if ((Object)(object)val != (Object)null && ((Object)val).name.IndexOf("straw", StringComparison.OrdinalIgnoreCase) >= 0)
					{
						return val;
					}
				}
			}
			componentsInChildren = roof.GetComponentsInChildren<MeshRenderer>(true);
			for (int i = 0; i < componentsInChildren.Length; i++)
			{
				Material[] sharedMaterials = ((Renderer)componentsInChildren[i]).sharedMaterials;
				foreach (Material val2 in sharedMaterials)
				{
					if ((Object)(object)val2 != (Object)null && ((Object)val2).name.IndexOf("roof", StringComparison.OrdinalIgnoreCase) >= 0)
					{
						return val2;
					}
				}
			}
			return null;
		}

		private static bool BoxPose(MetaBox b, out Vector3 c, out Vector3 size, out Quaternion q)
		{
			//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_000c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0011: Unknown result type (might be due to invalid IL or missing references)
			//IL_0017: Unknown result type (might be due to invalid IL or missing references)
			//IL_001c: Unknown result type (might be due to invalid IL or missing references)
			//IL_006c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0071: Unknown result type (might be due to invalid IL or missing references)
			//IL_009e: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a3: Unknown result type (might be due to invalid IL or missing references)
			//IL_012e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0133: 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_0165: Unknown result type (might be due to invalid IL or missing references)
			//IL_018c: Unknown result type (might be due to invalid IL or missing references)
			//IL_00dc: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e6: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ac: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a2: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a7: Unknown result type (might be due to invalid IL or missing references)
			c = Vector3.zero;
			size = Vector3.one;
			q = Quaternion.identity;
			if (b.center_unity_xyz != null && b.center_unity_xyz.Length >= 3 && b.size_unity_xyz != null && b.size_unity_xyz.Length >= 3)
			{
				c = new Vector3(b.center_unity_xyz[0], b.center_unity_xyz[1], b.center_unity_xyz[2]);
				size = new Vector3(Mathf.Abs(b.size_unity_xyz[0]), Mathf.Abs(b.size_unity_xyz[1]), Mathf.Abs(b.size_unity_xyz[2]));
				if (b.rotation_unity_xyzw != null && b.rotation_unity_xyzw.Length >= 4)
				{
					q = Norm(new Quaternion(b.rotation_unity_xyzw[0], b.rotation_unity_xyzw[1], b.rotation_unity_xyzw[2], b.rotation_unity_xyzw[3]));
				}
				return true;
			}
			if (b.center == null || b.center.Length < 3 || b.size == null || b.size.Length < 3)
			{
				return false;
			}
			c = Obj.Pos(b.center[0], b.center[1], b.center[2]);
			size = new Vector3(Mathf.Abs(b.size[0]), Mathf.Abs(b.size[2]), Mathf.Abs(b.size[1]));
			float[] rotation_quaternion_blender_wxyz = b.rotation_quaternion_blender_wxyz;
			q = ((rotation_quaternion_blender_wxyz != null && rotation_quaternion_blender_wxyz.Length >= 4) ? Norm(new Quaternion(0f - rotation_quaternion_blender_wxyz[1], 0f - rotation_quaternion_blender_wxyz[3], 0f - rotation_quaternion_blender_wxyz[2], rotation_quaternion_blender_wxyz[0])) : Quaternion.Euler(0f, 0f - b.rotation_z_degrees, 0f));
			return true;
		}

		private static Quaternion Norm(Quaternion q)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_000d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0013: Unknown result type (might be due to invalid IL or missing references)
			//IL_001b: 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_0029: Unknown result type (might be due to invalid IL or missing references)
			//IL_002f: Unknown result type (might be due to invalid IL or missing references)
			//IL_006b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0045: Unknown result type (might be due to invalid IL or missing references)
			//IL_004d: 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_005d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0065: Unknown result type (might be due to invalid IL or missing references)
			float num = Mathf.Sqrt(q.x * q.x + q.y * q.y + q.z * q.z + q.w * q.w);
			if (!(num < 1E-06f))
			{
				return new Quaternion(q.x / num, q.y / num, q.z / num, q.w / num);
			}
			return Quaternion.identity;
		}

		private static string Name(Material m)
		{
			if (!((Object)(object)m == (Object)null))
			{
				return ((Object)m).name + (((Object)(object)m.shader != (Object)null) ? (" (" + ((Object)m.shader).name + ")") : "");
			}
			return "none";
		}

		private static bool IsStone(string material)
		{
			if (!string.IsNullOrEmpty(material))
			{
				if (!material.Equals("stone", StringComparison.OrdinalIgnoreCase) && !material.Equals("marble", StringComparison.OrdinalIgnoreCase))
				{
					return material.Equals("ashstone", StringComparison.OrdinalIgnoreCase);
				}
				return true;
			}
			return false;
		}

		private static Requirement[] CostFromSidecar(ObjectDB db, Meta meta)
		{
			//IL_0057: Unknown result type (might be due to invalid IL or missing references)
			//IL_005c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0068: 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_0082: Unknown result type (might be due to invalid IL or missing references)
			//IL_008e: Expected O, but got Unknown
			List<Requirement> list = new List<Requirement>();
			foreach (KeyValuePair<string, int> item in meta.cost)
			{
				GameObject val = Plugin.FindItem(db, item.Key);
				if ((Object)(object)val == (Object)null)
				{
					Plugin.Warn(meta.name + ": cost item \"" + item.Key + "\" not found, skipped.");
					continue;
				}
				list.Add(new Requirement
				{
					m_resItem = val.GetComponent<ItemDrop>(),
					m_amount = item.Value,
					m_amountPerLevel = item.Value,
					m_recover = true
				});
			}
			return list.ToArray();
		}

		internal static GameObject FindStationPrefab(string prefab)
		{
			if (!((Object)(object)s_db != (Object)null) || !((Object)(object)s_zs != (Object)null))
			{
				return null;
			}
			return Plugin.FindPrefab(s_db, s_zs, prefab);
		}

		private static CraftingStation Station(string name, string pieceName)
		{
			string name2;
			switch (name.ToLowerInvariant())
			{
			case "workbench":
				name2 = "piece_workbench";
				break;
			case "stonecutter":
				name2 = "piece_stonecutter";
				break;
			case "forge":
				name2 = "forge";
				break;
			case "black_forge":
			case "blackforge":
				name2 = "blackforge";
				break;
			case "artisan":
			case "artisan_table":
				name2 = "piece_artisanstation";
				break;
			case "magetable":
			case "galdr_table":
				name2 = "piece_magetable";
				break;
			default:
				name2 = name;
				break;
			}
			GameObject val = (((Object)(object)s_db != (Object)null && (Object)(object)s_zs != (Object)null) ? Plugin.FindPrefab(s_db, s_zs, name2) : null);
			CraftingStation obj = (((Object)(object)val != (Object)null) ? val.GetComponent<CraftingStation>() : null);
			if ((Object)(object)obj == (Object)null)
			{
				Plugin.Warn(pieceName + ": station \"" + name + "\" not found; keeping the template's.");
			}
			return obj;
		}

		private static Requirement[] Reqs(ObjectDB db, string item, int n)
		{
			//IL_0020: Unknown result type (might be due to invalid IL or missing references)
			//IL_0025: Unknown result type (might be due to invalid IL or missing references)
			//IL_0031: Unknown result type (might be due to invalid IL or missing references)
			//IL_0038: Unknown result type (might be due to invalid IL or missing references)
			//IL_003f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0047: Expected O, but got Unknown
			GameObject val = Plugin.FindItem(db, item);
			if ((Object)(object)val == (Object)null)
			{
				return (Requirement[])(object)new Requirement[0];
			}
			return (Requirement[])(object)new Requirement[1]
			{
				new Requirement
				{
					m_resItem = val.GetComponent<ItemDrop>(),
					m_amount = n,
					m_amountPerLevel = n,
					m_recover = true
				}
			};
		}

		private static void SetField(object o, string field, GameObject[] value)
		{
			FieldInfo field2 = o.GetType().GetField(field, BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
			if (!(field2 == null))
			{
				if (field2.FieldType == typeof(GameObject[]))
				{
					field2.SetValue(o, value);
				}
				else if (field2.FieldType == typeof(List<GameObject>))
				{
					field2.SetValue(o, new List<GameObject>(value));
				}
			}
		}

		private static void ClearArray(object o, string field)
		{
			FieldInfo field2 = o.GetType().GetField(field, BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
			if (!(field2 == null))
			{
				if (field2.FieldType.IsArray)
				{
					field2.SetValue(o, Array.CreateInstance(field2.FieldType.GetElementType(), 0));
				}
				else if (field2.FieldType.IsGenericType)
				{
					field2.SetValue(o, Activator.CreateInstance(field2.FieldType));
				}
			}
		}
	}
	internal static class Capture
	{
		internal static class Register
		{
			[Serializable]
			[CompilerGenerated]
			private sealed class <>c
			{
				public static readonly <>c <>9 = new <>c();

				public static ConsoleEvent <>9__0_0;

				internal void <Postfix>b__0_0(ConsoleEventArgs args)
				{
					try
					{
						args.Context.AddString(Run());
					}
					catch (Exception ex)
					{
						args.Context.AddString("vrh_capture failed: " + ex.Message);
					}
				}
			}

			[HarmonyPatch(typeof(Terminal), "InitTerminal")]
			[HarmonyPostfix]
			private static void Postfix()
			{
				//IL_0033: Unknown result type (might be due to invalid IL or missing references)
				//IL_001e: Unknown result type (might be due to invalid IL or missing references)
				//IL_0023: Unknown result type (might be due to invalid IL or missing references)
				//IL_0029: Expected O, but got Unknown
				try
				{
					object obj = <>c.<>9__0_0;
					if (obj == null)
					{
						ConsoleEvent val = delegate(ConsoleEventArgs args)
						{
							try
							{
								args.Context.AddString(Run());
							}
							catch (Exception ex2)
							{
								args.Context.AddString("vrh_capture failed: " + ex2.Message);
							}
						};
						<>c.<>9__0_0 = val;
						obj = (object)val;
					}
					new ConsoleCommand("vrh_capture", "Roundhouse: write a fitbench capture of the two nearest Roundhouse pieces", (ConsoleEvent)obj, false, false, false, false, false, false, (ConsoleOptionsFetcher)null, false, false, false);
				}
				catch (Exception ex)
				{
					Plugin.Warn("vrh_capture not registered: " + ex.Message);
				}
			}
		}

		private static string Run()
		{
			//IL_0092: Unknown result type (might be due to invalid IL or missing references)
			//IL_0097: Unknown result type (might be due to invalid IL or missing references)
			//IL_0127: 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_0133: Unknown result type (might be due to invalid IL or missing references)
			//IL_0138: Unknown result type (might be due to invalid IL or missing references)
			Player localPlayer = Player.m_localPlayer;
			if ((Object)(object)localPlayer == (Object)null)
			{
				return "vrh_capture: no local player.";
			}
			List<Piece> list = new List<Piece>();
			Piece[] array = Object.FindObjectsByType<Piece>((FindObjectsSortMode)0);
			foreach (Piece val in array)
			{
				if ((Object)(object)val != (Object)null && ((Object)((Component)val).gameObject).name.StartsWith("VRH_", StringComparison.Ordinal) && (Object)(object)((Component)val).GetComponent<ZNetView>() != (Object)null && ((Component)val).GetComponent<ZNetView>().IsValid())
				{
					list.Add(val);
				}
			}
			Vector3 me = ((Component)localPlayer).transform.position;
			list.Sort(delegate(Piece a, Piece b)
			{
				//IL_0006: Unknown result type (might be due to invalid IL or missing references)
				//IL_000c: Unknown result type (might be due to invalid IL or missing references)
				//IL_0011: Unknown result type (might be due to invalid IL or missing references)
				//IL_0016: Unknown result type (might be due to invalid IL or missing references)
				//IL_0027: Unknown result type (might be due to invalid IL or missing references)
				//IL_002d: Unknown result type (might be due to invalid IL or missing references)
				//IL_0032: Unknown result type (might be due to invalid IL or missing references)
				//IL_0037: Unknown result type (might be due to invalid IL or missing references)
				Vector3 val5 = ((Component)a).transform.position - me;
				float sqrMagnitude2 = ((Vector3)(ref val5)).sqrMagnitude;
				val5 = ((Component)b).transform.position - me;
				return sqrMagnitude2.CompareTo(((Vector3)(ref val5)).sqrMagnitude);
			});
			if (list.Count < 2)
			{
				return "vrh_capture: need two placed Roundhouse pieces near you (found " + list.Count + ").";
			}
			Piece pc = list[0];
			Piece pc2 = list[1];
			Transform val2 = null;
			Transform val3 = null;
			float num = float.MaxValue;
			foreach (Transform item in Snaps(pc))
			{
				foreach (Transform item2 in Snaps(pc2))
				{
					Vector3 val4 = item.position - item2.position;
					float sqrMagnitude = ((Vector3)(ref val4)).sqrMagnitude;
					if (sqrMagnitude < num)
					{
						num = sqrMagnitude;
						val2 = item;
						val3 = item2;
					}
				}
			}
			if ((Object)(object)val2 == (Object)null)
			{
				return "vrh_capture: the pieces have no snap points.";
			}
			string text = Path.Combine(Paths.ConfigPath, "VargheimRoundhouse");
			Directory.CreateDirectory(text);
			string text2 = Path.Combine(text, "captured_pair_" + DateTime.UtcNow.ToString("yyyyMMdd_HHmmss", CultureInfo.InvariantCulture) + ".json");
			string contents = "{\"provenance\":" + Q("CAPTURED runtime transform pair; VargheimRoundhouse 0.5.6; " + DateTime.UtcNow.ToString("o")) + ",\"instances\":[" + Instance("A", pc) + "," + Instance("B", pc2) + "],\"joints\":[{\"a\":\"A\",\"b\":\"B\",\"a_snap\":" + Q(((Object)val2).name) + ",\"b_snap\":" + Q(((Object)val3).name) + ",\"observed_snap_gap_m\":" + N(Mathf.Sqrt(num)) + "}]}";
			File.WriteAllText(text2, contents);
			return "vrh_capture: " + Name(pc) + " (" + ((Object)val2).name + ") + " + Name(pc2) + " (" + ((Object)val3).name + "), snap gap " + (Mathf.Sqrt(num) * 1000f).ToString("0.0", CultureInfo.InvariantCulture) + " mm -> " + text2;
		}

		private static IEnumerable<Transform> Snaps(Piece pc)
		{
			Transform[] componentsInChildren = ((Component)pc).GetComponentsInChildren<Transform>(true);
			foreach (Transform val in componentsInChildren)
			{
				if ((Object)(object)val != (Object)(object)((Component)pc).transform && ((Component)val).CompareTag("snappoint"))
				{
					yield return val;
				}
			}
		}

		private static string Name(Piece pc)
		{
			string text = ((Object)((Component)pc).gameObject).name.Replace("(Clone)", "").Trim();
			if (!text.StartsWith("VRH_", StringComparison.Ordinal))
			{
				return text;
			}
			return text.Substring("VRH_".Length);
		}

		private static string Instance(string id, Piece pc)
		{
			//IL_0051: Unknown result type (might be due to invalid IL or missing references)
			//IL_0067: Unknown result type (might be due to invalid IL or missing references)
			//IL_007e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0096: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ae: 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_00b9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d0: Unknown result type (might be due to invalid IL or missing references)
			Transform transform = ((Component)pc).transform;
			Transform val = transform.Find("rh_new") ?? transform;
			return "{\"id\":" + Q(id) + ",\"kit\":\"uniform_kit_v1\",\"piece\":" + Q(Name(pc)) + ",\"position_unity\":" + V(transform.position) + ",\"rotation_xyzw\":" + R(transform.rotation) + ",\"scale\":" + V(transform.lossyScale) + ",\"root_world_matrix\":" + M(transform.localToWorldMatrix) + ",\"visual_local_matrix\":" + M(transform.worldToLocalMatrix * val.localToWorldMatrix) + ",\"snaps_local_matrix\":" + M(Matrix4x4.identity) + "}";
		}

		private static string Q(string s)
		{
			StringBuilder stringBuilder = new StringBuilder("\"");
			foreach (char c in s)
			{
				if (c == '\\' || c == '"')
				{
					stringBuilder.Append('\\').Append(c);
				}
				else if (c < ' ')
				{
					StringBuilder stringBuilder2 = stringBuilder.Append("\\u");
					int num = c;
					stringBuilder2.Append(num.ToString("x4"));
				}
				else
				{
					stringBuilder.Append(c);
				}
			}
			return stringBuilder.Append('"').ToString();
		}

		private static string N(float x)
		{
			return x.ToString("R", CultureInfo.InvariantCulture);
		}

		private static string V(Vector3 v)
		{
			//IL_0010: Unknown result type (might be due to invalid IL or missing references)
			//IL_0026: Unknown result type (might be due to invalid IL or missing references)
			//IL_003c: Unknown result type (might be due to invalid IL or missing references)
			return "[" + N(v.x) + "," + N(v.y) + "," + N(v.z) + "]";
		}

		private static string R(Quaternion q)
		{
			//IL_0011: Unknown result type (might be due to invalid IL or missing references)
			//IL_0027: Unknown result type (might be due to invalid IL or missing references)
			//IL_003d: 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)
			return "[" + N(q.x) + "," + N(q.y) + "," + N(q.z) + "," + N(q.w) + "]";
		}

		private static string M(Matrix4x4 m)
		{
			StringBuilder stringBuilder = new StringBuilder("[");
			for (int i = 0; i < 4; i++)
			{
				if (i > 0)
				{
					stringBuilder.Append(',');
				}
				stringBuilder.Append('[');
				for (int j = 0; j < 4; j++)
				{
					if (j > 0)
					{
						stringBuilder.Append(',');
					}
					stringBuilder.Append(N(((Matrix4x4)(ref m))[i, j]));
				}
				stringBuilder.Append(']');
			}
			return stringBuilder.Append(']').ToString();
		}
	}
	internal static class Docks
	{
		internal static class Register
		{
			[Serializable]
			[CompilerGenerated]
			private sealed class <>c
			{
				public static readonly <>c <>9 = new <>c();

				public static ConsoleEvent <>9__0_0;

				internal void <Postfix>b__0_0(ConsoleEventArgs args)
				{
					try
					{
						foreach (string item in Report((args.Length > 1) ? args[1] : null))
						{
							args.Context.AddString(item);
						}
					}
					catch (Exception ex)
					{
						args.Context.AddString("vrh_docks failed: " + ex.Message);
					}
				}
			}

			[HarmonyPatch(typeof(Terminal), "InitTerminal")]
			[HarmonyPostfix]
			private static void Postfix()
			{
				//IL_0033: Unknown result type (might be due to invalid IL or missing references)
				//IL_001e: Unknown result type (might be due to invalid IL or missing references)
				//IL_0023: Unknown result type (might be due to invalid IL or missing references)
				//IL_0029: Expected O, but got Unknown
				try
				{
					object obj = <>c.<>9__0_0;
					if (obj == null)
					{
						ConsoleEvent val = delegate(ConsoleEventArgs args)
						{
							try
							{
								foreach (string item in Report((args.Length > 1) ? args[1] : null))
								{
									args.Context.AddString(item);
								}
							}
							catch (Exception ex2)
							{
								args.Context.AddString("vrh_docks failed: " + ex2.Message);
							}
						};
						<>c.<>9__0_0 = val;
						obj = (object)val;
					}
					new ConsoleCommand("vrh_docks", "Roundhouse: wear report for pieces within 20 m (health %, rain/water wear, wet, underwater, roof)", (ConsoleEvent)obj, false, false, false, false, false, false, (ConsoleOptionsFetcher)null, false, false, false);
				}
				catch (Exception ex)
				{
					Plugin.Warn("vrh_docks not registered: " + ex.Message);
				}
			}
		}

		internal static ConfigEntry<bool> Weatherproof;

		internal static readonly HashSet<string> Proofed = new HashSet<string>(StringComparer.Ordinal);

		private static readonly MethodInfo s_isWet = AccessTools.Method(typeof(WearNTear), "IsWet", (Type[])null, (Type[])null);

		private static readonly MethodInfo s_under = AccessTools.Method(typeof(WearNTear), "IsUnderWater", (Type[])null, (Type[])null);

		private static readonly FieldInfo s_roof = AccessTools.Field(typeof(WearNTear), "m_haveRoof");

		internal static void Bind(ConfigFile cfg)
		{
			Weatherproof = cfg.Bind<bool>("Docks", "Weatherproof", true, "Dock pieces (vd_*) take no wear from rain or standing in water. Support, damage and repair are unchanged. Restart to apply.");
		}

		internal static bool IsDock(string pieceName)
		{
			return pieceName?.StartsWith("vd_", StringComparison.Ordinal) ?? false;
		}

		internal static void Apply(string pieceName, WearNTear wnt)
		{
			if (!((Object)(object)wnt == (Object)null) && IsDock(pieceName) && (Weatherproof == null || Weatherproof.Value))
			{
				wnt.m_noRoofWear = false;
				Proofed.Add(pieceName);
			}
		}

		private static List<string> Report(string filter)
		{
			//IL_00c6: 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)
			List<string> list = new List<string>();
			Player localPlayer = Player.m_localPlayer;
			if ((Object)(object)localPlayer == (Object)null)
			{
				list.Add("vrh_docks: no local player.");
				return list;
			}
			list.Add("vrh_docks: Weatherproof=" + (Weatherproof == null || Weatherproof.Value) + ", dock prefabs proofed=" + Proofed.Count + ", raining/wet weather=" + EnvMan.IsWet());
			List<KeyValuePair<float, string>> list2 = new List<KeyValuePair<float, string>>();
			foreach (WearNTear allInstance in WearNTear.GetAllInstances())
			{
				if ((Object)(object)allInstance == (Object)null)
				{
					continue;
				}
				float num = Vector3.Distance(((Component)allInstance).transform.position, ((Component)localPlayer).transform.position);
				if (!(num > 20f))
				{
					string text = ((Object)((Component)allInstance).gameObject).name;
					int num2 = text.IndexOf("(Clone)");
					if (num2 >= 0)
					{
						text = text.Substring(0, num2);
					}
					if (string.IsNullOrEmpty(filter) || text.IndexOf(filter, StringComparison.OrdinalIgnoreCase) >= 0)
					{
						bool flag = s_isWet != null && (bool)s_isWet.Invoke(allInstance, null);
						bool flag2 = s_under != null && (bool)s_under.Invoke(allInstance, null);
						bool flag3 = s_roof != null && (bool)s_roof.GetValue(allInstance);
						list2.Add(new KeyValuePair<float, string>(num, string.Format(CultureInfo.InvariantCulture, "{0,-26} {1,5:0.0} m  health {2,5:0.0}%  rainWaterWear={3}  wet={4} underwater={5} roof={6}", text, num, allInstance.GetHealthPercentage() * 100f, allInstance.m_noRoofWear ? "ON" : "off", flag, flag2, flag3)));
					}
				}
			}
			list2.Sort((KeyValuePair<float, string> a, KeyValuePair<float, string> b) => a.Key.CompareTo(b.Key));
			int num3 = 0;
			foreach (KeyValuePair<float, string> item in list2)
			{
				if (num3++ >= 25)
				{
					list.Add("… " + (list2.Count - 25) + " more (add a name filter: vrh_docks vd_)");
					break;
				}
				list.Add(item.Value);
			}
			if (list2.Count == 0)
			{
				list.Add("no pieces within 20 m.");
			}
			return list;
		}
	}
	internal static class Dump
	{
		internal static class Register
		{
			[Serializable]
			[CompilerGenerated]
			private sealed class <>c
			{
				public static readonly <>c <>9 = new <>c();

				public static ConsoleEvent <>9__0_0;

				internal void <Postfix>b__0_0(ConsoleEventArgs args)
				{
					try
					{
						args.Context.AddString(Run((args.Args.Length > 1) ? args.Args[1] : "mods"));
					}
					catch (Exception ex)
					{
						args.Context.AddString("vrh_dump failed: " + ex.Message);
					}
				}
			}

			[HarmonyPatch(typeof(Terminal), "InitTerminal")]
			[HarmonyPostfix]
			private static void Postfix()
			{
				//IL_0033: Unknown result type (might be due to invalid IL or missing references)
				//IL_001e: Unknown result type (might be due to invalid IL or missing references)
				//IL_0023: Unknown result type (might be due to invalid IL or missing references)
				//IL_0029: Expected O, but got Unknown
				try
				{
					object obj = <>c.<>9__0_0;
					if (obj == null)
					{
						ConsoleEvent val = delegate(ConsoleEventArgs args)
						{
							try
							{
								args.Context.AddString(Run((args.Args.Length > 1) ? args.Args[1] : "mods"));
							}
							catch (Exception ex2)
							{
								args.Context.AddString("vrh_dump failed: " + ex2.Message);
							}
						};
						<>c.<>9__0_0 = val;
						obj = (object)val;
					}
					new ConsoleCommand("vrh_dump", "Roundhouse: write size/snap/cost reference for another mod's pieces (vrh_dump mods | vrh_dump <GUID or prefab prefix>)", (ConsoleEvent)obj, false, false, false, false, false, false, (ConsoleOptionsFetcher)null, false, false, false);
				}
				catch (Exception ex)
				{
					Plugin.Warn("vrh_dump not registered: " + ex.Message);
				}
			}
		}

		internal static List<KeyValuePair<string, GameObject>> JotunnPieces()
		{
			List<KeyValuePair<string, GameObject>> list = new List<KeyValuePair<string, GameObject>>();
			Type type = AccessTools.TypeByName("Jotunn.Managers.PieceManager");
			if (type == null)
			{
				return list;
			}
			object obj = AccessTools.Property(type, "Instance")?.GetValue(null, null);
			if (obj == null)
			{
				return list;
			}
			foreach (FieldInfo declaredField in AccessTools.GetDeclaredFields(type))
			{
				object value = declaredField.GetValue(declaredField.IsStatic ? null : obj);
				object obj2;
				if (!(value is IDictionary dictionary))
				{
					obj2 = value as IEnumerable;
				}
				else
				{
					IEnumerable values = dictionary.Values;
					obj2 = values;
				}
				IEnumerable enumerable = (IEnumerable)obj2;
				if (enumerable == null || value is string)
				{
					continue;
				}
				foreach (object item in enumerable)
				{
					if (item != null && !(item.GetType().Name != "CustomPiece"))
					{
						object obj3 = AccessTools.Property(item.GetType(), "SourceMod")?.GetValue(item, null);
						string key = ((obj3 == null) ? "?" : ((AccessTools.Property(obj3.GetType(), "GUID")?.GetValue(obj3, null) as string) ?? "?"));
						object? obj4 = AccessTools.Property(item.GetType(), "PiecePrefab")?.GetValue(item, null);
						GameObject val = (GameObject)((obj4 is GameObject) ? obj4 : null);
						if ((Object)(object)val != (Object)null)
						{
							list.Add(new KeyValuePair<string, GameObject>(key, val));
						}
					}
				}
				if (list.Count > 0)
				{
					break;
				}
			}
			return list;
		}

		private static string Run(string arg)
		{
			List<KeyValuePair<string, GameObject>> list = JotunnPieces();
			if (arg == "mods")
			{
				SortedDictionary<string, int> sortedDictionary = new SortedDictionary<string, int>();
				foreach (KeyValuePair<string, GameObject> item in list)
				{
					sortedDictionary.TryGetValue(item.Key, out var value);
					sortedDictionary[item.Key] = value + 1;
				}
				StringBuilder stringBuilder = new StringBuilder("vrh_dump: Jotunn pieces by mod: ");
				foreach (KeyValuePair<string, int> item2 in sortedDictionary)
				{
					stringBuilder.Append(item2.Key).Append(" (").Append(item2.Value)
						.Append(")  ");
				}
				if (sortedDictionary.Count != 0)
				{
					return stringBuilder.ToString();
				}
				return "vrh_dump: no Jotunn pieces found (try a prefab prefix).";
			}
			List<GameObject> list2 = new List<GameObject>();
			foreach (KeyValuePair<string, GameObject> item3 in list)
			{
				if (string.Equals(item3.Key, arg, StringComparison.OrdinalIgnoreCase))
				{
					list2.Add(item3.Value);
				}
			}
			if (list2.Count == 0 && (Object)(object)ZNetScene.instance != (Object)null)
			{
				foreach (GameObject prefab in ZNetScene.instance.m_prefabs)
				{
					if ((Object)(object)prefab != (Object)null && ((Object)prefab).name.StartsWith(arg, StringComparison.OrdinalIgnoreCase) && (Object)(object)prefab.GetComponent<Piece>() != (Object)null)
					{
						list2.Add(prefab);
					}
				}
			}
			if (list2.Count == 0)
			{
				return "vrh_dump: nothing matches '" + arg + "'. Try `vrh_dump mods`.";
			}
			list2.Sort((GameObject a, GameObject b) => string.CompareOrdinal(((Object)a).name, ((Object)b).name));
			StringBuilder stringBuilder2 = new StringBuilder("{\"source\":" + Q(arg) + ",\"tool\":" + Q("VargheimRoundhouse 0.5.6 vrh_dump") + ",\"utc\":" + Q(DateTime.UtcNow.ToString("o")) + ",\"units\":\"metres, Unity axes (x right, y up, z forward), relative to the piece origin\",\"pieces\":[");
			for (int num = 0; num < list2.Count; num++)
			{
				if (num > 0)
				{
					stringBuilder2.Append(',');
				}
				stringBuilder2.Append(PieceJson(list2[num]));
			}
			stringBuilder2.Append("]}");
			string text = Path.Combine(Paths.ConfigPath, "VargheimRoundhouse");
			Directory.CreateDirectory(text);
			string text2 = new string(arg.Replace('.', '-').ToCharArray(), 0, Math.Min(arg.Length, 40));
			char[] invalidFileNameChars = Path.GetInvalidFileNameChars();
			foreach (char oldChar in invalidFileNameChars)
			{
				text2 = text2.Replace(oldChar, '_');
			}
			string text3 = Path.Combine(text, "piece_dump_" + text2 + "_" + DateTime.UtcNow.ToString("yyyyMMdd_HHmmss", CultureInfo.InvariantCulture) + ".json");
			File.WriteAllText(text3, stringBuilder2.ToString());
			return "vrh_dump: " + list2.Count + " pieces -> " + text3;
		}

		private static string PieceJson(GameObject go)
		{
			//IL_0483: Unknown result type (might be due to invalid IL or missing references)
			//IL_0488: Unknown result type (might be due to invalid IL or missing references)
			//IL_048d: Unknown result type (might be due to invalid IL or missing references)
			//IL_04a0: Unknown result type (might be due to invalid IL or missing references)
			//IL_04a5: Unknown result type (might be due to invalid IL or missing references)
			//IL_04a7: Unknown result type (might be due to invalid IL or missing references)
			//IL_049a: Unknown result type (might be due to invalid IL or missing references)
			//IL_05a2: Unknown result type (might be due to invalid IL or missing references)
			//IL_05c8: Unknown result type (might be due to invalid IL or missing references)
			//IL_054d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0552: Unknown result type (might be due to invalid IL or missing references)
			//IL_0557: Unknown result type (might be due to invalid IL or missing references)
			//IL_056a: Unknown result type (might be due to invalid IL or missing references)
			//IL_056f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0571: Unknown result type (might be due to invalid IL or missing references)
			//IL_0564: Unknown result type (might be due to invalid IL or missing references)
			//IL_067a: Unknown result type (might be due to invalid IL or missing references)
			//IL_067f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0684: Unknown result type (might be due to invalid IL or missing references)
			//IL_06ac: Unknown result type (might be due to invalid IL or missing references)
			Piece component = go.GetComponent<Piece>();
			Transform transform = go.transform;
			StringBuilder stringBuilder = new StringBuilder("{");
			stringBuilder.Append("\"prefab\":").Append(Q(((Object)go).name));
			if ((Object)(object)component != (Object)null)
			{
				stringBuilder.Append(",\"name\":").Append(Q(Loc(component.m_name))).Append(",\"description\":")
					.Append(Q(Loc(component.m_description)));
				stringBuilder.Append(",\"category\":").Append(Q(((object)Unsafe.As<PieceCategory, PieceCategory>(ref component.m_category)/*cast due to .constrained prefix*/).ToString()));
				object obj = AccessTools.Field(typeof(Piece), "m_usage")?.GetValue(component);
				if (obj != null)
				{
					stringBuilder.Append(",\"usage\":").Append(Q(obj.ToString()));
				}
				stringBuilder.Append(",\"station\":").Append(Q(((Object)(object)component.m_craftingStation != (Object)null) ? component.m_craftingStation.m_name : ""));
				stringBuilder.Append(",\"comfort\":").Append(component.m_comfort).Append(",\"ground_only\":")
					.Append(component.m_groundOnly ? "true" : "false");
				stringBuilder.Append(",\"cost\":[");
				bool flag = true;
				Requirement[] array = (Requirement[])(((object)component.m_resources) ?? ((object)new Requirement[0]));
				foreach (Requirement val in array)
				{
					if (val != null && !((Object)(object)val.m_resItem == (Object)null))
					{
						if (!flag)
						{
							stringBuilder.Append(',');
						}
						flag = false;
						stringBuilder.Append("{\"item\":").Append(Q(((Object)val.m_resItem).name)).Append(",\"amount\":")
							.Append(val.m_amount)
							.Append(",\"recover\":")
							.Append(val.m_recover ? "true" : "false")
							.Append('}');
					}
				}
				stringBuilder.Append(']');
			}
			WearNTear component2 = go.GetComponent<WearNTear>();
			if ((Object)(object)component2 != (Object)null)
			{
				stringBuilder.Append(",\"health\":").Append(N(component2.m_health)).Append(",\"material\":")
					.Append(Q(((object)Unsafe.As<MaterialType, MaterialType>(ref component2.m_materialType)/*cast due to .constrained prefix*/).ToString()));
			}
			if ((Object)(object)component2 != (Object)null)
			{
				stringBuilder.Append(",\"wear\":").Append(Prims(component2, delegate(string n)
				{
					switch (n)
					{
					default:
						return n.StartsWith("m_damages");
					case "m_supports":
					case "m_noSupportWear":
					case "m_noRoofWear":
					case "m_ashDamageImmune":
						return true;
					}
				}));
			}
			if ((Object)(object)component != (Object)null)
			{
				stringBuilder.Append(",\"placement\":").Append(Prims(component, delegate(string n)
				{
					if (!n.StartsWith("m_notOn") && !n.StartsWith("m_only"))
					{
						switch (n)
						{
						default:
							return n == "m_vegetationGroundOnly";
						case "m_inCeilingOnly":
						case "m_noClipping":
						case "m_groundPiece":
						case "m_groundOnly":
						case "m_cultivatedGroundOnly":
						case "m_allowAltGroundPlacement":
						case "m_clipGround":
						case "m_clipEverything":
						case "m_noInWater":
						case "m_waterPiece":
						case "m_spaceRequirement":
							break;
						}
					}
					return true;
				}));
			}
			Component[] componentsInChildren = go.GetComponentsInChildren<Component>(true);
			foreach (Component val2 in componentsInChildren)
			{
				if ((Object)(object)val2 != (Object)null && ((object)val2).GetType().Name == "Turret")
				{
					stringBuilder.Append(",\"turret\":").Append(Prims(val2, (string n) => true));
					break;
				}
			}
			SortedSet<string> sortedSet = new SortedSet<string>();
			componentsInChildren = go.GetComponentsInChildren<Component>(true);
			foreach (Component val3 in componentsInChildren)
			{
				if ((Object)(object)val3 != (Object)null && !(val3 is Transform) && !(val3 is MeshFilter) && !(val3 is MeshRenderer) && !(val3 is Collider))
				{
					sortedSet.Add(((object)val3).GetType().Name);
				}
			}
			stringBuilder.Append(",\"components\":[");
			bool flag2 = true;
			foreach (string item in sortedSet)
			{
				if (!flag2)
				{
					stringBuilder.Append(',');
				}
				flag2 = false;
				stringBuilder.Append(Q(item));
			}
			stringBuilder.Append(']');
			Bounds? val4 = null;
			Bounds? val5 = null;
			Collider[] componentsInChildren2 = go.GetComponentsInChildren<Collider>(true);
			foreach (Collider val6 in componentsInChildren2)
			{
				if (!val6.isTrigger)
				{
					Bounds val7 = LocalBox(transform, ((Component)val6).transform, ColliderBox(val6));
					val4 = (val4.HasValue ? Enc(val4.Value, val7) : val7);
				}
			}
			int num = 0;
			int num2 = 0;
			MeshFilter[] componentsInChildren3 = go.GetComponentsInChildren<MeshFilter>(true);
			foreach (MeshFilter val8 in componentsInChildren3)
			{
				if ((Object)(object)val8.sharedMesh == (Object)null)
				{
					continue;
				}
				Renderer component3 = ((Component)val8).GetComponent<Renderer>();
				if (!((Object)(object)component3 == (Object)null))
				{
					if ((Object)(object)((Component)val8).GetComponentInParent<LODGroup>() == (Object)null || IsLod0(((Component)val8).transform))
					{
						num += Tris(val8.sharedMesh);
						num2 += component3.sharedMaterials.Length;
					}
					Bounds val9 = LocalBox(transform, ((Component)val8).transform, val8.sharedMesh.bounds);
					val5 = (val5.HasValue ? Enc(val5.Value, val9) : val9);
				}
			}
			if (val5.HasValue)
			{
				stringBuilder.Append(",\"visual_bounds\":").Append(B(val5.Value));
			}
			if (val4.HasValue)
			{
				stringBuilder.Append(",\"collider_bounds\":").Append(B(val4.Value));
			}
			stringBuilder.Append(",\"triangles_lod0\":").Append(num).Append(",\"materials\":")
				.Append(num2);
			stringBuilder.Append(",\"lod_levels\":").Append(((Object)(object)go.GetComponentInChildren<LODGroup>(true) != (Object)null) ? go.GetComponentInChildren<LODGroup>(true).lodCount : 0);
			stringBuilder.Append(",\"snap_points\":[");
			bool flag3 = true;
			Transform[] componentsInChildren4 = go.GetComponentsInChildren<Transform>(true);
			foreach (Transform val10 in componentsInChildren4)
			{
				if (!((Object)(object)val10 == (Object)(object)transform) && ((Component)val10).CompareTag("snappoint"))
				{
					if (!flag3)
					{
						stringBuilder.Append(',');
					}
					flag3 = false;
					Vector3 v = transform.InverseTransformPoint(val10.position);
					stringBuilder.Append("{\"name\":").Append(Q(((Object)val10).name)).Append(",\"pos\":")
						.Append(V(v))
						.Append('}');
				}
			}
			stringBuilder.Append("]}");
			return stringBuilder.ToString();
		}

		internal static string Prims(object o, Func<string, bool> keep)
		{
			StringBuilder stringBuilder = new StringBuilder("{");
			bool flag = true;
			Type type = o.GetType();
			while (type != null && type != typeof(MonoBehaviour))
			{
				FieldInfo[] fields = type.GetFields(BindingFlags.DeclaredOnly | BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
				foreach (FieldInfo fieldInfo in fields)
				{
					Type fieldType = fieldInfo.FieldType;
					if ((fieldType == typeof(bool) || fieldType == typeof(int) || fieldType == typeof(float) || fieldType.IsEnum || fieldType == typeof(string)) && fieldInfo.Name.StartsWith("m_") && keep(fieldInfo.Name))
					{
						object value;
						try
						{
							value = fieldInfo.GetValue(o);
						}
						catch
						{
							continue;
						}
						if (!flag)
						{
							stringBuilder.Append(',');
						}
						flag = false;
						stringBuilder.Append(Q(fieldInfo.Name)).Append(':');
						if (value is bool flag2)
						{
							stringBuilder.Append(flag2 ? "true" : "false");
						}
						else if (value is float f)
						{
							stringBuilder.Append(N(f));
						}
						else if (value is int value2)
						{
							stringBuilder.Append(value2);
						}
						else
						{
							stringBuilder.Append(Q((value == null) ? "" : value.ToString()));
						}
					}
				}
				type = type.BaseType;
			}
			return stringBuilder.Append('}').ToString();
		}

		internal static bool IsLod0(Transform t)
		{
			LOD[] lODs = ((Component)t).GetComponentInParent<LODGroup>().GetLODs();
			if (lODs.Length == 0)
			{
				return true;
			}
			Renderer[] renderers = lODs[0].renderers;
			foreach (Renderer val in renderers)
			{
				if ((Object)(object)val != (Object)null && (Object)(object)((Component)val).transform == (Object)(object)t)
				{
					return true;
				}
			}
			return false;
		}

		internal static int Tris(Mesh m)
		{
			try
			{
				int num = 0;
				for (int i = 0; i < m.subMeshCount; i++)
				{
					num += (int)m.GetIndexCount(i) / 3;
				}
				return num;
			}
			catch
			{
				return 0;
			}
		}

		internal static Bounds ColliderBox(Collider c)
		{
			//IL_000b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0011: Unknown result type (might be due to invalid IL or missing references)
			//IL_0016: Unknown result type (might be due to invalid IL or missing references)
			//IL_004b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0050: Unknown result type (might be due to invalid IL or missing references)
			//IL_005b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0065: Unknown result type (might be due to invalid IL or missing references)
			//IL_006a: Unknown result type (might be due to invalid IL or missing references)
			//IL_003a: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00cd: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d2: Unknown result type (might be due to invalid IL or missing references)
			//IL_007a: 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_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_00bb: 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_00c2: Unknown result type (might be due to invalid IL or missing references)
			BoxCollider val = (BoxCollider)(object)((c is BoxCollider) ? c : null);
			if (val != null)
			{
				return new Bounds(val.center, val.size);
			}
			MeshCollider val2 = (MeshCollider)(object)((c is MeshCollider) ? c : null);
			if (val2 != null && (Object)(object)val2.sharedMesh != (Object)null)
			{
				return val2.sharedMesh.bounds;
			}
			SphereCollider val3 = (SphereCollider)(object)((c is SphereCollider) ? c : null);
			if (val3 != null)
			{
				return new Bounds(val3.center, Vector3.one * val3.radius * 2f);
			}
			CapsuleCollider val4 = (CapsuleCollider)(object)((c is CapsuleCollider) ? c : null);
			if (val4 != null)
			{
				Vector3 val5 = Vector3.one * val4.radius * 2f;
				((Vector3)(ref val5))[val4.direction] = Mathf.Max(val4.height, val4.radius * 2f);
				return new Bounds(val4.center, val5);
			}
			return new Bounds(Vector3.zero, Vector3.zero);
		}

		internal static Bounds LocalBox(Transform root, Transform t, Bounds b)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_000c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0011: Unknown result type (might be due to invalid IL or missing references)
			//IL_0018: Unknown result type (might be due to invalid IL or missing references)
			//IL_001d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0022: 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_0049: Unknown result type (might be due to invalid IL or missing references)
			//IL_003b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0068: Unknown result type (might be due to invalid IL or missing references)
			//IL_005a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0087: 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_0091: Unknown result type (might be due to invalid IL or missing references)
			//IL_0096: Unknown result type (might be due to invalid IL or missing references)
			Matrix4x4 val = root.worldToLocalMatrix * t.localToWorldMatrix;
			Bounds result = default(Bounds);
			((Bounds)(ref result))..ctor(((Matrix4x4)(ref val)).MultiplyPoint3x4(((Bounds)(ref b)).min), Vector3.zero);
			for (int i = 0; i < 8; i++)
			{
				((Bounds)(ref result)).Encapsulate(((Matrix4x4)(ref val)).MultiplyPoint3x4(new Vector3(((i & 1) == 0) ? ((Bounds)(ref b)).min.x : ((Bounds)(ref b)).max.x, ((i & 2) == 0) ? ((Bounds)(ref b)).min.y : ((Bounds)(ref b)).max.y, ((i & 4) == 0) ? ((Bounds)(ref b)).min.z : ((Bounds)(ref b)).max.z)));
			}
			return result;
		}

		internal static Bounds Enc(Bounds a, Bounds b)
		{
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			//IL_0008: Unknown result type (might be due to invalid IL or missing references)
			((Bounds)(ref a)).Encapsulate(b);
			return a;
		}

		internal static string Loc(string s)
		{
			try
			{
				return (Localization.instance != null) ? Localization.instance.Localize(s ?? "") : (s ?? "");
			}
			catch
			{
				return s ?? "";
			}
		}

		internal static string B(Bounds b)
		{
			//IL_0012: 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_0040: Unknown result type (might be due to invalid IL or missing references)
			return "{\"min\":" + V(((Bounds)(ref b)).min) + ",\"max\":" + V(((Bounds)(ref b)).max) + ",\"size\":" + V(((Bounds)(ref b)).size) + "}";
		}

		internal static string V(Vector3 v)
		{
			//IL_0010: Unknown result type (might be due to invalid IL or missing references)
			//IL_0026: Unknown result type (might be due to invalid IL or missing references)
			//IL_003c: Unknown result type (might be due to invalid IL or missing references)
			return "[" + N(v.x) + "," + N(v.y) + "," + N(v.z) + "]";
		}

		internal static string N(float f)
		{
			return f.ToString("0.###", CultureInfo.InvariantCulture);
		}

		internal static string Q(string s)
		{
			StringBuilder stringBuilder = new StringBuilder("\"");
			string text = s ?? "";
			foreach (char c in text)
			{
				if (c == '"' || c == '\\')
				{
					stringBuilder.Append('\\').Append(c);
				}
				else if (c < ' ')
				{
					StringBuilder stringBuilder2 = stringBuilder.Append("\\u");
					int num = c;
					stringBuilder2.Append(num.ToString("x4"));
				}
				else
				{
					stringBuilder.Append(c);
				}
			}
			return stringBuilder.Append('"').ToString();
		}
	}
	internal static class Fort
	{
		internal static class SupportPatch
		{
			[HarmonyPatch(typeof(WearNTear), "GetMaterialProperties")]
			[HarmonyPostfix]
			private static void Postfix(WearNTear __instance, ref float __0, ref float __1, ref float __2, ref float __3)
			{
				if (EarthSupport != null && EarthSupport.Value && !((Object)(object)__instance == (Object)null))
				{
					string text = ((Object)((Component)__instance).gameObject).name;
					int num = text.IndexOf("(Clone)", StringComparison.Ordinal);
					if (num >= 0)
					{
						text = text.Substring(0, num);
					}
					if (EarthFilled.Contains(text.Trim()))
					{
						__0 = 1000f;
						__1 = 20f;
						__2 = 0.2f;
						__3 = 0.1f;
					}
				}
			}
		}

		internal static readonly HashSet<string> EarthFilled = new HashSet<string>(StringComparer.Ordinal);

		internal static ConfigEntry<bool> EarthSupport;

		internal static void Bind(ConfigFile cfg)
		{
			EarthSupport = cfg.Bind<bool>("Fort", "EarthFilledSupport", true, "Fort walls, towers and decks support like stone (max 1000) so stone and wood pieces can be built on top. Off = plain wood support. Restart to apply to pieces already loaded.");
		}
	}
	internal static class Hearth
	{
		internal static void MakeCauldron(GameObject piece, string displayName)
		{
			try
			{
				if ((Object)(object)piece == (Object)null || (Object)(object)piece.GetComponent<CraftingStation>() != (Object)null)
				{
					return;
				}
				GameObject val = Builder.FindStationPrefab("piece_cauldron");
				CraftingStation val2 = (((Object)(object)val != (Object)null) ? val.GetComponent<CraftingStation>() : null);
				if ((Object)(object)val2 == (Object)null)
				{
					Plugin.Warn(((Object)piece).name + ": vanilla cauldron not found; no cooking station added.");
					return;
				}
				CraftingStation val3 = piece.AddComponent<CraftingStation>();
				int num = 0;
				FieldInfo[] fields = typeof(CraftingStation).GetFields(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
				foreach (FieldInfo fieldInfo in fields)
				{
					if (fieldInfo.IsInitOnly || fieldInfo.IsLiteral)
					{
						continue;
					}
					Type fieldType = fieldInfo.FieldType;
					if (!(fieldType == typeof(ZNetView)) && !typeof(Component).IsAssignableFrom(fieldType) && !(fieldType == typeof(GameObject)) && !(fieldType == typeof(Transform)))
					{
						try
						{
							fieldInfo.SetValue(val3, fieldInfo.GetValue(val2));
							num++;
						}
						catch
						{
						}
					}
				}
				SetBool(val3, "m_craftRequireRoof", v: false);
				SetBool(val3, "m_craftRequireFire", v: true);
				SetObj(val3, "m_roofCheckPoint", (Object)(object)piece.transform);
				SetObj(val3, "m_connectionPoint", (Object)(object)piece.transform);
				SetObj(val3, "m_haveFireObject", null);
				SetObj(val3, "m_inUseObject", null);
				SetObj(val3, "m_areaMarker", null);
				Plugin.Note(((Object)piece).name + ": cooking station added (" + val3.m_name + ", " + num + " fields from piece_cauldron, roof check off, fire = own hearth).");
			}
			catch (Exception ex)
			{
				Plugin.Warn(((Object)piece).name + ": cooking station failed: " + ex.Message);
			}
		}

		private static void SetBool(object o, string field, bool v)
		{
			FieldInfo field2 = o.GetType().GetField(field, BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
			if (field2 != null && field2.FieldType == typeof(bool))
			{
				field2.SetValue(o, v);
			}
		}

		private static void SetObj(object o, string field, Object v)
		{
			FieldInfo field2 = o.GetType().GetField(field, BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
			if (!(field2 == null) && (v == (Object)null || field2.FieldType.IsInstanceOfType(v)))
			{
				field2.SetValue(o, v);
			}
		}
	}
	public class HingeLeaf : MonoBehaviour
	{
		public Transform m_pivot;

		public float m_openDegrees = 90f;

		public float m_speed = 200f;

		private ZNetView m_nview;

		private float m_angle;

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

		private void Update()
		{
			//IL_008d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0092: Unknown result type (might be due to invalid IL or missing references)
			if (!((Object)(object)m_pivot == (Object)null))
			{
				int num = 0;
				if ((Object)(object)m_nview != (Object)null && m_nview.IsValid())
				{
					num = m_nview.GetZDO().GetInt("state", 0);
				}
				float num2 = (float)Mathf.Clamp(num, -1, 1) * m_openDegrees;
				if (!Mathf.Approximately(m_angle, num2))
				{
					m_angle = Mathf.MoveTowards(m_angle, num2, m_speed * Time.deltaTime);
					m_pivot.localRotation = Quaternion.AngleAxis(m_angle, Vector3.up);
				}
			}
		}
	}
	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_01c9: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ce: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d5: Unknown result type (might be due to invalid IL or missing references)
			//IL_01db: Expected O, but got Unknown
			//IL_0215: Unknown result type (might be due to invalid IL or missing references)
			//IL_024a: Unknown result type (might be due to invalid IL or missing references)
			//IL_024f: 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_0258: Unknown result type (might be due to invalid IL or missing references)
			//IL_025c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0261: Unknown result type (might be due to invalid IL or missing references)
			//IL_0298: 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_02a1: Unknown result type (might be due to invalid IL or missing references)
			//IL_02a6: Unknown result type (might be due to invalid IL or missing references)
			//IL_02b9: Unknown result type (might be due to invalid IL or missing references)
			//IL_02f6: Unknown result type (might be due to invalid IL or missing references)
			//IL_02fc: Expected O, but got Unknown
			//IL_032e: Unknown result type (might be due to invalid IL or missing references)
			//IL_034d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0352: Unknown result type (might be due to invalid IL or missing references)
			//IL_0356: Unknown result type (might be due to invalid IL or missing references)
			//IL_035b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0360: Unknown result type (might be due to invalid IL or missing references)
			//IL_039f: Unknown result type (might be due to invalid IL or missing references)
			//IL_03a4: Unknown result type (might be due to invalid IL or missing references)
			//IL_03b9: Unknown result type (might be due to invalid IL or missing references)
			//IL_03c6: Unknown result type (might be due to invalid IL or missing references)
			//IL_03ce: Unknown result type (might be due to invalid IL or missing references)
			//IL_03fb: Unknown result type (might be due to invalid IL or missing references)
			//IL_040a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0419: Expected O, but got Unknown
			//IL_00cf: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00dd: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e9: 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_00f6: Unknown result type (might be due to invalid IL or missing references)
			//IL_0108: 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_0116: Unknown result type (might be due to invalid IL or missing references)
			//IL_0120: Unknown result type (might be due to invalid IL or missing references)
			//IL_0128: Unknown result type (might be due to invalid IL or missing references)
			//IL_0132: Unknown result type (might be due to invalid IL or missing references)
			//IL_013a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0144: Unknown result type (might be due to invalid IL or missing references)
			//IL_016f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0174: Unknown result type (might be due to invalid IL or missing references)
			//IL_018c: 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_0195: Unknown result type (might be due to invalid IL or missing references)
			//IL_019e: 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)
			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("VargheimRoundhouse_IconStage");
				val.transform.position =