Decompiled source of VargheimWard v0.2.4

VargheimWard.dll

Decompiled 5 days ago
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Globalization;
using System.IO;
using System.Reflection;
using System.Runtime.CompilerServices;
using 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 VargheimWard
{
	[BepInPlugin("digi.vargheim.ward", "VargheimWard", "0.2.4")]
	public class Plugin : BaseUnityPlugin
	{
		[HarmonyPatch]
		internal static class Patches
		{
			private static bool s_reported;

			private static readonly FieldInfo s_availField = AccessTools.Field(typeof(PieceTable), "m_availablePieces");

			private static readonly FieldInfo s_availByCatField = AccessTools.Field(typeof(PieceTable), "m_availablePiecesByCategory");

			private static bool s_availWarned;

			[HarmonyPatch(typeof(ObjectDB), "Awake")]
			[HarmonyPostfix]
			[HarmonyPriority(200)]
			private static void ObjectDB_Awake(ObjectDB __instance)
			{
				try
				{
					OnObjectDB(__instance);
				}
				catch (Exception ex)
				{
					Warn("content: " + ex);
				}
			}

			[HarmonyPatch(typeof(ObjectDB), "CopyOtherDB")]
			[HarmonyPostfix]
			[HarmonyPriority(200)]
			private static void ObjectDB_Copy(ObjectDB __instance)
			{
				try
				{
					OnObjectDB(__instance);
				}
				catch (Exception ex)
				{
					Warn("content: " + ex);
				}
			}

			[HarmonyPatch(typeof(ZNetScene), "Awake")]
			[HarmonyPostfix]
			private static void ZNetScene_Awake(ZNetScene __instance)
			{
				try
				{
					if ((Object)(object)ObjectDB.instance != (Object)null)
					{
						OnObjectDB(ObjectDB.instance);
					}
					OnZNetScene(__instance);
				}
				catch (Exception ex)
				{
					Warn("content: " + ex);
				}
			}

			[HarmonyPatch(typeof(Piece), "SetCreator")]
			[HarmonyPostfix]
			private static void Piece_SetCreator(Piece __instance)
			{
				if (s_reported || (Object)(object)__instance == (Object)null || !IsWard((Component)(object)__instance))
				{
					return;
				}
				s_reported = true;
				try
				{
					Renderer[] componentsInChildren = ((Component)__instance).GetComponentsInChildren<Renderer>(true);
					foreach (Renderer val in componentsInChildren)
					{
						string text = "";
						Material[] sharedMaterials = val.sharedMaterials;
						foreach (Material val2 in sharedMaterials)
						{
							text += (((Object)(object)val2 != (Object)null) ? (((Object)val2).name + "[" + (((Object)(object)val2.shader != (Object)null) ? ((Object)val2.shader).name : "?") + "] ") : "null ");
						}
						Note("placed: " + ((Object)((Component)val).gameObject).name + " enabled=" + val.enabled + " mats=" + text);
					}
				}
				catch (Exception ex)
				{
					Warn("placed report: " + ex.Message);
				}
			}

			[HarmonyPatch(typeof(Switch), "GetHoverText")]
			[HarmonyPostfix]
			private static void Switch_Hover(Switch __instance, ref string __result)
			{
				if ((Object)(object)__instance != (Object)null && (Object)(object)((Component)__instance).GetComponentInParent<ShieldGenerator>() != (Object)null && IsWard((Component)(object)((Component)__instance).GetComponentInParent<ShieldGenerator>()))
				{
					__result = Localization.instance.Localize("<color=orange>" + Name.Value + "</color>\n" + Radius.Value + " m. Build beneath it.");
				}
			}

			[HarmonyPatch(typeof(Switch), "Interact")]
			[HarmonyPrefix]
			private static bool Switch_Interact(Switch __instance, ref bool __result)
			{
				ShieldGenerator val = (((Object)(object)__instance != (Object)null) ? ((Component)__instance).GetComponentInParent<ShieldGenerator>() : null);
				if ((Object)(object)val != (Object)null && IsWard((Component)(object)val))
				{
					__result = false;
					return false;
				}
				return true;
			}

			[HarmonyPatch(typeof(WearNTear), "Highlight")]
			[HarmonyPrefix]
			private static bool WearNTear_Highlight(WearNTear __instance)
			{
				if ((Object)(object)__instance != (Object)null)
				{
					return !IsWard((Component)(object)__instance);
				}
				return true;
			}

			[HarmonyPatch(typeof(PieceTable), "UpdateAvailable")]
			[HarmonyPostfix]
			private static void PieceTable_UpdateAvailable(PieceTable __instance)
			{
				if ((Object)(object)s_piece == (Object)null || IsAdmin())
				{
					return;
				}
				try
				{
					Piece ward = s_piece.GetComponent<Piece>();
					int num = 0;
					object? obj = ((s_availField != null) ? s_availField.GetValue(__instance) : null);
					HashSet<Piece> hashSet = obj as HashSet<Piece>;
					if (hashSet != null && hashSet.Remove(ward))
					{
						num++;
					}
					List<List<Piece>> list = obj as List<List<Piece>>;
					if (list == null && s_availByCatField != null)
					{
						list = s_availByCatField.GetValue(__instance) as List<List<Piece>>;
					}
					if (list != null)
					{
						foreach (List<Piece> item in list)
						{
							num += item.RemoveAll((Piece p) => (Object)(object)p == (Object)(object)ward);
						}
					}
					if (hashSet == null && list == null && !s_availWarned)
					{
						s_availWarned = true;
						Warn("PieceTable.m_availablePieces has a new shape; the ward stays visible in the hammer (placement is still admin-only).");
					}
				}
				catch (Exception ex)
				{
					if (!s_availWarned)
					{
						s_availWarned = true;
						Warn("hammer hide: " + ex.Message);
					}
				}
			}

			[HarmonyPatch(typeof(Player), "PlacePiece")]
			[HarmonyPrefix]
			private static bool Player_PlacePiece(Player __instance, Piece piece)
			{
				if ((Object)(object)piece == (Object)null || IsAdmin() || !IsWard((Component)(object)piece))
				{
					return true;
				}
				if ((Object)(object)__instance != (Object)null)
				{
					((Character)__instance).Message((MessageType)2, "Only a Vargheim admin can raise Thor's Blessing.", 0, (Sprite)null, false);
				}
				return false;
			}

			[HarmonyPatch(typeof(Player), "RemovePiece")]
			[HarmonyPrefix]
			private static bool Player_RemovePiece(Player __instance, ref bool __result)
			{
				if (IsAdmin() || (Object)(object)__instance == (Object)null)
				{
					return true;
				}
				Piece value = Traverse.Create((object)__instance).Field("m_hoveringPiece").GetValue<Piece>();
				if ((Object)(object)value != (Object)null && IsWard((Component)(object)value))
				{
					((Character)__instance).Message((MessageType)2, "Only a Vargheim admin can lift Thor's Blessing.", 0, (Sprite)null, false);
					__result = false;
					return false;
				}
				return true;
			}
		}

		public const string PluginGuid = "digi.vargheim.ward";

		public const string PluginName = "VargheimWard";

		public const string PluginVersion = "0.2.4";

		internal const string PiecePrefab = "VargheimWard";

		private const string BasePiece = "piece_shieldgenerator";

		private const string BundleFile = "ward.bundle";

		private const string BundlePrefab = "ward_statue";

		private const string ObjFile = "ward_statue.obj";

		internal static Plugin Instance;

		internal static ConfigEntry<float> Radius;

		internal static ConfigEntry<string> Statue;

		internal static ConfigEntry<float> StatueScale;

		internal static ConfigEntry<string> StatueMaterials;

		internal static ConfigEntry<float> TextureScale;

		internal static ConfigEntry<string> StatueParts;

		internal static ConfigEntry<string> Resources;

		internal static ConfigEntry<bool> AdminOnly;

		internal static ConfigEntry<bool> NoSpawns;

		internal static ConfigEntry<Shield.Look> DomeLook;

		internal static ConfigEntry<string> Name;

		internal static ConfigEntry<string> Description;

		private static GameObject s_holder;

		private static GameObject s_piece;

		private static GameObject s_statue;

		private static bool s_tried;

		private void Awake()
		{
			//IL_0034: Unknown result type (might be due to invalid IL or missing references)
			//IL_003e: Expected O, but got Unknown
			//IL_00dd: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e7: Expected O, but got Unknown
			//IL_013e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0148: Expected O, but got Unknown
			//IL_01fa: Unknown result type (might be due to invalid IL or missing references)
			//IL_021b: Expected O, but got Unknown
			Instance = this;
			try
			{
				Radius = ((BaseUnityPlugin)this).Config.Bind<float>("Ward", "Radius", 12f, new ConfigDescription("Radius of the dome in metres.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(5f, 60f), Array.Empty<object>()));
				Name = ((BaseUnityPlugin)this).Config.Bind<string>("Ward", "Name", "Thor's Blessing", "Name shown in the hammer and on hover.");
				Description = ((BaseUnityPlugin)this).Config.Bind<string>("Ward", "Description", "Thor's hammer stands guard. Nothing hostile passes the dome; build beneath it.", "Description shown in the hammer.");
				Statue = ((BaseUnityPlugin)this).Config.Bind<string>("Ward", "Statue", "StatueDeer", "Vanilla prefab whose model stands at the centre when no ward.bundle is beside this DLL (StatueDeer, StatueHare, StatueCorgi, StatueEvil, StatueSeed, or any piece). With a ward.bundle present its 'ward_statue' prefab is used instead.");
				StatueScale = ((BaseUnityPlugin)this).Config.Bind<float>("Ward", "StatueScale", 1f, new ConfigDescription("Scale of the statue model.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0.2f, 5f), Array.Empty<object>()));
				StatueParts = ((BaseUnityPlugin)this).Config.Bind<string>("Ward", "StatueParts", "", "The statue, built from vanilla prefabs: prefab:W,H,D:y[:rotY] entries separated by ';' (sizes in metres, y = bottom of the part). Each part keeps its own vanilla look. Empty (default) = the ward_statue.obj Mjolnir beside the DLL.");
				TextureScale = ((BaseUnityPlugin)this).Config.Bind<float>("Ward", "TextureScale", 3f, new ConfigDescription("How many times the borrowed texture repeats per metre on the statue (higher = finer grain).", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0.25f, 10f), Array.Empty<object>()));
				StatueMaterials = ((BaseUnityPlugin)this).Config.Bind<string>("Ward", "StatueMaterials", "plinth:#5a5651,0,0.15; ring:#c9a24a,0.9,0.6; handle:#6b4a2b,0,0.2; wrap:#3a2a1c,0,0.1; head:#4a4e55,0.85,0.45; cap:#c9a24a,0.9,0.6", "For ward_statue.obj, groups separated by ';': group:#rrggbb[,metallic,smoothness] for a plain colour, or group:prefab[:materialNameContains] to borrow a vanilla material.");
				Resources = ((BaseUnityPlugin)this).Config.Bind<string>("Ward", "Resources", "Stone:10,Wood:5", "Build cost, Item:amount pairs separated by commas (admins only build it, so keep it cheap).");
				AdminOnly = ((BaseUnityPlugin)this).Config.Bind<bool>("Ward", "AdminOnly", true, "Only players with devcommands active (server admins) can place or remove the ward.");
				DomeLook = ((BaseUnityPlugin)this).Config.Bind<Shield.Look>("Ward", "DomeLook", Shield.Look.Clear, "How the dome is drawn on this PC (it is a camera effect, the protection never changes). Clear: the glowing shell without the heat-haze refraction, which smears the top edge of the screen and blurs whatever you see through it. Vanilla: the game's Ashlands look. Hidden: no dome drawn for Thor's Blessing (Ashlands shield generators keep theirs). Clear also applies to vanilla shield generators.");
				NoSpawns = ((BaseUnityPlugin)this).Config.Bind<bool>("Ward", "NoSpawns", true, "Also stop creature spawns and raids from starting inside the dome.");
				SafePatch.Apply(new Harmony("digi.vargheim.ward"), typeof(Patches), delegate(string msg)
				{
					((BaseUnityPlugin)this).Logger.LogWarning((object)msg);
				});
				((BaseUnityPlugin)this).Logger.LogInfo((object)"VargheimWard 0.2.4 loaded.");
			}
			catch (Exception ex)
			{
				((BaseUnityPlugin)this).Logger.LogError((object)("VargheimWard: startup failed, mod inactive: " + ex));
			}
		}

		internal static void Warn(string s)
		{
			if ((Object)(object)Instance != (Object)null)
			{
				((BaseUnityPlugin)Instance).Logger.LogWarning((object)("VargheimWard: " + s));
			}
		}

		internal static void Note(string s)
		{
			if ((Object)(object)Instance != (Object)null)
			{
				((BaseUnityPlugin)Instance).Logger.LogInfo((object)("VargheimWard: " + s));
			}
		}

		internal static bool IsAdmin()
		{
			if (AdminOnly.Value)
			{
				if ((Object)(object)Console.instance != (Object)null)
				{
					return ((Terminal)Console.instance).IsCheatsEnabled();
				}
				return false;
			}
			return true;
		}

		private static GameObject 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("VargheimWard_Prefabs");
				s_holder.SetActive(false);
				Object.DontDestroyOnLoad((Object)(object)s_holder);
			}
			return s_holder;
		}

		private static GameObject FindItem(ObjectDB db, string name)
		{
			foreach (GameObject item in db.m_items)
			{
				if ((Object)(object)item != (Object)null && ((Object)item).name == name)
				{
					return item;
				}
			}
			return null;
		}

		private static GameObject FindPrefab(ObjectDB db, ZNetScene zs, string name)
		{
			if ((Object)(object)zs != (Object)null)
			{
				GameObject prefab = zs.GetPrefab(name);
				if ((Object)(object)prefab != (Object)null)
				{
					return prefab;
				}
			}
			foreach (GameObject item in db.m_items)
			{
				ItemDrop val = (((Object)(object)item != (Object)null) ? item.GetComponent<ItemDrop>() : null);
				PieceTable val2 = (((Object)(object)val != (Object)null && val.m_itemData != null && val.m_itemData.m_shared != null) ? val.m_itemData.m_shared.m_buildPieces : null);
				if ((Object)(object)val2 == (Object)null)
				{
					continue;
				}
				foreach (GameObject piece in val2.m_pieces)
				{
					if ((Object)(object)piece != (Object)null && ((Object)piece).name == name)
					{
						return piece;
					}
				}
			}
			return null;
		}

		private static GameObject FindByComponent<T>(ObjectDB db, ZNetScene zs) where T : Component
		{
			if ((Object)(object)zs != (Object)null)
			{
				foreach (GameObject prefab in zs.m_prefabs)
				{
					if ((Object)(object)prefab != (Object)null && (Object)(object)prefab.GetComponent<T>() != (Object)null && (Object)(object)prefab.GetComponent<Piece>() != (Object)null)
					{
						return prefab;
					}
				}
			}
			foreach (GameObject item in db.m_items)
			{
				ItemDrop val = (((Object)(object)item != (Object)null) ? item.GetComponent<ItemDrop>() : null);
				PieceTable val2 = (((Object)(object)val != (Object)null && val.m_itemData != null && val.m_itemData.m_shared != null) ? val.m_itemData.m_shared.m_buildPieces : null);
				if ((Object)(object)val2 == (Object)null)
				{
					continue;
				}
				foreach (GameObject piece in val2.m_pieces)
				{
					if ((Object)(object)piece != (Object)null && (Object)(object)piece.GetComponent<T>() != (Object)null)
					{
						return piece;
					}
				}
			}
			return null;
		}

		private static Requirement[] Reqs(ObjectDB db, string text)
		{
			//IL_007e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0083: Unknown result type (might be due to invalid IL or missing references)
			//IL_0090: Unknown result type (might be due to invalid IL or missing references)
			//IL_0098: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ac: Expected O, but got Unknown
			List<Requirement> list = new List<Requirement>();
			string[] array = (text ?? string.Empty).Split(',');
			foreach (string text2 in array)
			{
				string[] array2 = text2.Split(':');
				GameObject val = ((array2.Length == 2) ? FindItem(db, array2[0].Trim()) : null);
				if ((Object)(object)val == (Object)null || !int.TryParse(array2[1].Trim(), out var result))
				{
					Warn("unknown material '" + text2 + "'.");
					continue;
				}
				list.Add(new Requirement
				{
					m_resItem = val.GetComponent<ItemDrop>(),
					m_amount = result,
					m_amountPerLevel = result,
					m_recover = true
				});
			}
			return list.ToArray();
		}

		private static GameObject StatueModel(ObjectDB db, ZNetScene zs)
		{
			if ((Object)(object)s_statue != (Object)null || s_tried)
			{
				return s_statue;
			}
			s_tried = true;
			if (!string.IsNullOrEmpty(StatueParts.Value.Trim()))
			{
				try
				{
					GameObject obj = VargheimWard.Statue.Compose(StatueParts.Value, (string n) => FindPrefab(db, zs, n));
					obj.transform.SetParent(Holder().transform, false);
					s_statue = obj;
					Note("statue model from vanilla parts.");
					return s_statue;
				}
				catch (Exception ex)
				{
					Warn("statue parts: " + ex.Message + " - falling back.");
				}
			}
			try
			{
				string text = Path.Combine(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location), "ward.bundle");
				if (File.Exists(text))
				{
					AssetBundle val = AssetBundle.LoadFromFile(text);
					GameObject val2 = (((Object)(object)val != (Object)null) ? val.LoadAsset<GameObject>("ward_statue") : null);
					if ((Object)(object)val2 != (Object)null)
					{
						s_statue = val2;
						Note("statue model from ward.bundle.");
						return s_statue;
					}
					Warn("ward.bundle has no 'ward_statue' prefab; using " + Statue.Value + ".");
				}
			}
			catch (Exception ex2)
			{
				Warn("ward.bundle: " + ex2.Message);
			}
			try
			{
				string text2 = Path.Combine(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location), "ward_statue.obj");
				if (File.Exists(text2))
				{
					GameObject obj2 = VargheimWard.Statue.Load(text2, StatueMaterials.Value, (string n) => FindPrefab(db, zs, n));
					obj2.transform.SetParent(Holder().transform, false);
					s_statue = obj2;
					Note("statue model from ward_statue.obj.");
					return s_statue;
				}
			}
			catch (Exception ex3)
			{
				Warn("ward_statue.obj: " + ex3.Message + " - falling back to " + Statue.Value + ".");
			}
			GameObject val3 = FindPrefab(db, zs, Statue.Value);
			if ((Object)(object)val3 == (Object)null)
			{
				Warn("statue prefab '" + Statue.Value + "' not found; the ward keeps the generator model.");
				return null;
			}
			GameObject val4 = Object.Instantiate<GameObject>(val3, Holder().transform, false);
			((Object)val4).name = "ward_statue_model";
			Component[] componentsInChildren = val4.GetComponentsInChildren<Component>(true);
			foreach (Component val5 in componentsInChildren)
			{
				if (!(val5 is Transform) && !(val5 is MeshFilter) && !(val5 is Renderer) && !(val5 is LODGroup))
				{
					Object.DestroyImmediate((Object)(object)val5);
				}
			}
			s_statue = val4;
			return s_statue;
		}

		internal static void OnObjectDB(ObjectDB db)
		{
			//IL_0117: Unknown result type (might be due to invalid IL or missing references)
			//IL_0171: Unknown result type (might be due to invalid IL or missing references)
			//IL_0176: Unknown result type (might be due to invalid IL or missing references)
			//IL_018c: Unknown result type (might be due to invalid IL or missing references)
			//IL_019c: Unknown result type (might be due to invalid IL or missing references)
			//IL_01bf: Unknown result type (might be due to invalid IL or missing references)
			//IL_029e: Unknown result type (might be due to invalid IL or missing references)
			//IL_02ae: Unknown result type (might be due to invalid IL or missing references)
			//IL_02be: Unknown result type (might be due to invalid IL or missing references)
			//IL_02cd: Unknown result type (might be due to invalid IL or missing references)
			//IL_035e: Unknown result type (might be due to invalid IL or missing references)
			//IL_036b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0378: Unknown result type (might be due to invalid IL or missing references)
			//IL_0385: Unknown result type (might be due to invalid IL or missing references)
			//IL_0392: 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_03ac: 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_03d3: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)db == (Object)null || db.m_items == null || db.m_items.Count == 0 || (Object)(object)FindItem(db, "Wood") == (Object)null)
			{
				return;
			}
			ZNetScene instance = ZNetScene.instance;
			if ((Object)(object)s_piece == (Object)null)
			{
				GameObject val = FindPrefab(db, instance, "piece_shieldgenerator") ?? FindByComponent<ShieldGenerator>(db, instance);
				if ((Object)(object)val == (Object)null)
				{
					if ((Object)(object)instance != (Object)null)
					{
						Warn("no prefab with a ShieldGenerator component found (" + instance.m_prefabs.Count + " prefabs scanned); is the game older than Ashlands?");
					}
					return;
				}
				Note("base piece: " + ((Object)val).name);
				s_piece = Object.Instantiate<GameObject>(val, Holder().transform, false);
				((Object)s_piece).name = "VargheimWard";
				Piece component = s_piece.GetComponent<Piece>();
				component.m_name = Name.Value;
				component.m_description = Description.Value;
				component.m_resources = Reqs(db, Resources.Value);
				component.m_category = (PieceCategory)0;
				component.m_groundOnly = true;
				component.m_noInWater = true;
				component.m_allowedInDungeons = false;
				component.m_comfort = 0;
				ShieldGenerator component2 = s_piece.GetComponent<ShieldGenerator>();
				if ((Object)(object)component2 != (Object)null)
				{
					Shield.Configure(component2);
				}
				else
				{
					Warn("piece_shieldgenerator has no ShieldGenerator component; the dome will not work.");
				}
				if (NoSpawns.Value)
				{
					GameObject val2 = new GameObject("ward_nospawn");
					val2.transform.SetParent(s_piece.transform, false);
					val2.layer = LayerMask.NameToLayer("character_trigger");
					SphereCollider obj = val2.AddComponent<SphereCollider>();
					((Collider)obj).isTrigger = true;
					obj.radius = Radius.Value;
					val2.AddComponent<EffectArea>().m_type = (Type)36;
				}
				GameObject val3 = StatueModel(db, instance);
				int num = 0;
				Renderer[] componentsInChildren = s_piece.GetComponentsInChildren<Renderer>(true);
				foreach (Renderer val4 in componentsInChildren)
				{
					if (!(val4 is ParticleSystemRenderer) && !((Object)((Component)val4).gameObject).name.StartsWith("ward_", StringComparison.Ordinal))
					{
						string text = ((Object)((Component)val4).gameObject).name.ToLowerInvariant();
						if (!text.Contains("forcefield") && !text.Contains("dome"))
						{
							val4.enabled = false;
							num++;
						}
					}
				}
				Note("generator body hidden (" + num + " renderers).");
				if ((Object)(object)val3 != (Object)null)
				{
					GameObject obj2 = Object.Instantiate<GameObject>(val3, s_piece.transform, false);
					((Object)obj2).name = "ward_statue";
					obj2.transform.localPosition = Vector3.zero;
					obj2.transform.localRotation = Quaternion.identity;
					obj2.transform.localScale = Vector3.one * StatueScale.Value;
					obj2.SetActive(true);
				}
				Switch[] componentsInChildren2 = s_piece.GetComponentsInChildren<Switch>(true);
				foreach (Switch obj3 in componentsInChildren2)
				{
					obj3.m_name = Name.Value;
					obj3.m_hoverText = Name.Value;
				}
				WearNTear component3 = s_piece.GetComponent<WearNTear>();
				if ((Object)(object)component3 != (Object)null)
				{
					component3.m_health = 100000f;
					component3.m_noRoofWear = true;
					component3.m_noSupportWear = true;
					component3.m_damages.m_blunt = (DamageModifier)3;
					component3.m_damages.m_slash = (DamageModifier)3;
					component3.m_damages.m_pierce = (DamageModifier)3;
					component3.m_damages.m_chop = (DamageModifier)3;
					component3.m_damages.m_pickaxe = (DamageModifier)3;
					component3.m_damages.m_fire = (DamageModifier)3;
					component3.m_damages.m_frost = (DamageModifier)3;
					component3.m_damages.m_lightning = (DamageModifier)3;
					component3.m_damages.m_poison = (DamageModifier)3;
					component3.m_damages.m_spirit = (DamageModifier)3;
				}
			}
			GameObject val5 = FindItem(db, "Hammer");
			PieceTable val6 = (((Object)(object)val5 != (Object)null) ? val5.GetComponent<ItemDrop>().m_itemData.m_shared.m_buildPieces : null);
			if ((Object)(object)val6 != (Object)null && !val6.m_pieces.Contains(s_piece))
			{
				val6.m_pieces.Add(s_piece);
			}
			if ((Object)(object)instance != (Object)null)
			{
				OnZNetScene(instance);
			}
		}

		internal static void OnZNetScene(ZNetScene zs)
		{
			if (!((Object)(object)zs == (Object)null) && !((Object)(object)s_piece == (Object)null))
			{
				if (!zs.m_prefabs.Contains(s_piece))
				{
					zs.m_prefabs.Add(s_piece);
				}
				Dictionary<int, GameObject> value = Traverse.Create((object)zs).Field("m_namedPrefabs").GetValue<Dictionary<int, GameObject>>();
				if (value != null)
				{
					value[StringExtensionMethods.GetStableHashCode(((Object)s_piece).name)] = s_piece;
				}
			}
		}

		internal static bool IsWard(Component c)
		{
			if ((Object)(object)c != (Object)null)
			{
				return ((Object)c.gameObject).name.StartsWith("VargheimWard", StringComparison.Ordinal);
			}
			return false;
		}
	}
	public static class SafePatch
	{
		public delegate void Logger(string message);

		public static int Apply(Harmony harmony, Type patchClass, Logger warn, string name = null)
		{
			//IL_0117: Unknown result type (might be due to invalid IL or missing references)
			//IL_011c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0129: Unknown result type (might be due to invalid IL or missing references)
			//IL_0136: Unknown result type (might be due to invalid IL or missing references)
			//IL_0145: Expected O, but got Unknown
			name = name ?? patchClass.Name;
			int num = 0;
			MethodInfo[] methods = patchClass.GetMethods(BindingFlags.DeclaredOnly | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic);
			foreach (MethodInfo methodInfo in methods)
			{
				List<HarmonyMethod> fromMethod = HarmonyMethodExtensions.GetFromMethod((MethodBase)methodInfo);
				if (fromMethod == null || fromMethod.Count == 0)
				{
					continue;
				}
				HarmonyMethod val = HarmonyMethod.Merge(fromMethod);
				bool flag = ((MemberInfo)methodInfo).GetCustomAttribute<HarmonyPrefix>() != null;
				bool flag2 = ((MemberInfo)methodInfo).GetCustomAttribute<HarmonyPostfix>() != null;
				bool flag3 = ((MemberInfo)methodInfo).GetCustomAttribute<HarmonyFinalizer>() != null;
				if (!flag && !flag2 && !flag3)
				{
					continue;
				}
				string text = ((val.declaringType != null) ? val.declaringType.Name : "?") + "." + (val.methodName ?? "?");
				try
				{
					MethodBase methodBase = Resolve(val);
					if (methodBase == null)
					{
						num++;
						warn(name + ": " + text + " not found (game update?) - " + methodInfo.Name + " is OFF.");
						continue;
					}
					PatchProcessor val2 = harmony.CreateProcessor(methodBase);
					HarmonyMethod val3 = new HarmonyMethod(methodInfo)
					{
						priority = val.priority,
						before = val.before,
						after = val.after
					};
					if (flag)
					{
						val2.AddPrefix(val3);
					}
					if (flag2)
					{
						val2.AddPostfix(val3);
					}
					if (flag3)
					{
						val2.AddFinalizer(val3);
					}
					val2.Patch();
				}
				catch (Exception ex)
				{
					num++;
					warn(name + ": " + text + " could not be patched (" + ex.GetType().Name + ": " + ex.Message + ") - " + methodInfo.Name + " is OFF.");
				}
			}
			return num;
		}

		public static FieldRef<T, F> FieldRef<T, F>(string field, Logger warn)
		{
			try
			{
				return AccessTools.FieldRefAccess<T, F>(field);
			}
			catch (Exception ex)
			{
				warn?.Invoke(typeof(T).Name + "." + field + " not found (game update?): " + ex.Message);
				return null;
			}
		}

		public static FieldRef<F> StaticFieldRef<F>(Type type, string field, Logger warn)
		{
			try
			{
				FieldInfo fieldInfo = AccessTools.Field(type, field);
				if (fieldInfo == null)
				{
					warn?.Invoke(type.Name + "." + field + " not found (game update?).");
					return null;
				}
				return AccessTools.StaticFieldRefAccess<F>(fieldInfo);
			}
			catch (Exception ex)
			{
				warn?.Invoke(type.Name + "." + field + ": " + ex.Message);
				return null;
			}
		}

		private static MethodBase Resolve(HarmonyMethod info)
		{
			//IL_0016: Unknown result type (might be due to invalid IL or missing references)
			//IL_001b: Unknown result type (might be due to invalid IL or missing references)
			//IL_001c: 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_0034: Expected I4, but got Unknown
			if (info.declaringType == null)
			{
				return null;
			}
			MethodType valueOrDefault = info.methodType.GetValueOrDefault();
			switch (valueOrDefault - 1)
			{
			case 2:
				return AccessTools.Constructor(info.declaringType, info.argumentTypes, false);
			case 3:
				return AccessTools.Constructor(info.declaringType, (Type[])null, true);
			case 0:
				if (info.methodName != null)
				{
					return AccessTools.PropertyGetter(info.declaringType, info.methodName);
				}
				return null;
			case 1:
				if (info.methodName != null)
				{
					return AccessTools.PropertySetter(info.declaringType, info.methodName);
				}
				return null;
			default:
				if (info.methodName == null)
				{
					return null;
				}
				if (info.argumentTypes != null)
				{
					return AccessTools.Method(info.declaringType, info.methodName, info.argumentTypes, (Type[])null);
				}
				try
				{
					return AccessTools.Method(info.declaringType, info.methodName, (Type[])null, (Type[])null);
				}
				catch (AmbiguousMatchException)
				{
					return null;
				}
			}
		}
	}
	internal static class Shield
	{
		internal enum Look
		{
			Clear,
			Vanilla,
			Hidden
		}

		private static readonly HashSet<int> s_wards = new HashSet<int>();

		private static bool s_patched;

		private static float s_maxFuel = -1f;

		private static bool s_domePatched;

		private static readonly Dictionary<int, float[]> s_vanilla = new Dictionary<int, float[]>();

		private static readonly string[] Warps = new string[2] { "m_refractStrength", "m_curlStrength" };

		internal static bool IsWard(ShieldGenerator sg)
		{
			if ((Object)(object)sg != (Object)null)
			{
				return ((Object)((Component)sg).gameObject).name.StartsWith("VargheimWard", StringComparison.Ordinal);
			}
			return false;
		}

		internal static void Configure(ShieldGenerator sg)
		{
			int num = 0;
			string[] array = new string[4] { "m_maxShieldRadius", "m_minShieldRadius", "m_shieldRadius", "m_radius" };
			foreach (string field in array)
			{
				if (Set(sg, field, Plugin.Radius.Value))
				{
					num++;
				}
			}
			array = new string[2] { "m_maxFuel", "m_startFuel" };
			foreach (string field2 in array)
			{
				Set(sg, field2, 100f);
			}
			array = new string[3] { "m_fuelPerSecond", "m_fuelPerDamage", "m_damagePerFuel" };
			foreach (string field3 in array)
			{
				Set(sg, field3, 0f);
			}
			if (num == 0)
			{
				Plugin.Warn("ShieldGenerator has no radius field I recognise; dome radius left at the Ashlands default.");
			}
			Plugin.Note("ward radius " + Plugin.Radius.Value + " m (" + num + " radius fields set).");
			PatchFuel();
			PatchDome();
		}

		private static bool Set(ShieldGenerator sg, string field, float value)
		{
			FieldInfo fieldInfo = AccessTools.Field(typeof(ShieldGenerator), field);
			if (fieldInfo == null)
			{
				return false;
			}
			try
			{
				fieldInfo.SetValue(sg, Convert.ChangeType(value, fieldInfo.FieldType));
				return true;
			}
			catch (Exception ex)
			{
				Plugin.Warn(field + " (" + fieldInfo.FieldType.Name + "): " + ex.Message);
				return false;
			}
		}

		internal static bool IsBodyPart(ShieldGenerator sg, Transform t)
		{
			if ((Object)(object)t == (Object)null)
			{
				return false;
			}
			string text = ((Object)t).name.ToLowerInvariant();
			if (text.StartsWith("ward_") || text.Contains("dome") || text.Contains("shield") || text.Contains("bubble") || text.Contains("force"))
			{
				return false;
			}
			if ((Object)(object)sg != (Object)null)
			{
				Traverse val = Traverse.Create((object)sg);
				string[] array = new string[3] { "m_shieldDome", "m_dome", "m_shieldObject" };
				foreach (string text2 in array)
				{
					if (val.Field(text2).FieldExists())
					{
						GameObject value = val.Field(text2).GetValue<GameObject>();
						if ((Object)(object)value != (Object)null && ((Object)(object)value.transform == (Object)(object)t || value.transform.IsChildOf(t)))
						{
							return false;
						}
					}
				}
			}
			return true;
		}

		private static void PatchFuel()
		{
			//IL_0013: Unknown result type (might be due to invalid IL or missing references)
			//IL_0019: Expected O, but got Unknown
			//IL_008c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0099: Expected O, but got Unknown
			//IL_0174: Unknown result type (might be due to invalid IL or missing references)
			//IL_0181: Expected O, but got Unknown
			//IL_0129: Unknown result type (might be due to invalid IL or missing references)
			//IL_0137: Expected O, but got Unknown
			if (s_patched)
			{
				return;
			}
			s_patched = true;
			Harmony val = new Harmony("digi.vargheim.ward.fuel");
			Type typeFromHandle = typeof(ShieldGenerator);
			int num = 0;
			string[] array = new string[2] { "GetFuel", "GetFuelRemaining" };
			foreach (string text in array)
			{
				MethodInfo methodInfo = AccessTools.Method(typeFromHandle, text, (Type[])null, (Type[])null);
				if (methodInfo != null && methodInfo.ReturnType == typeof(float))
				{
					val.Patch((MethodBase)methodInfo, (HarmonyMethod)null, new HarmonyMethod(typeof(Shield), "FullFuel", (Type[])null), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
					num++;
				}
			}
			array = new string[5] { "UseFuel", "DamageShield", "ConsumeFuel", "OnDamaged", "RemoveFuel" };
			foreach (string text2 in array)
			{
				MethodInfo methodInfo2 = AccessTools.Method(typeFromHandle, text2, (Type[])null, (Type[])null);
				if (methodInfo2 != null && methodInfo2.ReturnType == typeof(void))
				{
					val.Patch((MethodBase)methodInfo2, new HarmonyMethod(typeof(Shield), "NoFuelUse", (Type[])null), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
					num++;
				}
			}
			MethodInfo methodInfo3 = AccessTools.Method(typeFromHandle, "GetHoverText", (Type[])null, (Type[])null);
			if (methodInfo3 != null)
			{
				val.Patch((MethodBase)methodInfo3, (HarmonyMethod)null, new HarmonyMethod(typeof(Shield), "HoverText", (Type[])null), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
			}
			Plugin.Note("fuel patches: " + num + ".");
		}

		private static void FullFuel(ShieldGenerator __instance, ref float __result)
		{
			if (!IsWard(__instance))
			{
				return;
			}
			if (s_maxFuel < 0f)
			{
				FieldInfo fieldInfo = AccessTools.Field(typeof(ShieldGenerator), "m_maxFuel");
				object obj = ((fieldInfo != null) ? fieldInfo.GetValue(__instance) : null);
				s_maxFuel = ((obj != null) ? Convert.ToSingle(obj) : 100f);
				if (s_maxFuel <= 0f)
				{
					s_maxFuel = 100f;
				}
			}
			__result = s_maxFuel;
		}

		private static bool NoFuelUse(ShieldGenerator __instance)
		{
			return !IsWard(__instance);
		}

		private static void HoverText(ShieldGenerator __instance, ref string __result)
		{
			if (IsWard(__instance))
			{
				__result = Localization.instance.Localize("<color=orange>" + Plugin.Name.Value + "</color>\n" + Plugin.Radius.Value + " m. Build beneath it.");
			}
		}

		private static void PatchDome()
		{
			//IL_0046: Unknown result type (might be due to invalid IL or missing references)
			//IL_004c: Expected O, but got Unknown
			//IL_007b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0088: Expected O, but got Unknown
			//IL_00e5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f3: Expected O, but got Unknown
			if (s_domePatched)
			{
				return;
			}
			s_domePatched = true;
			try
			{
				Type fx = AccessTools.TypeByName("ShieldDomeImageEffect");
				if (fx == null)
				{
					Plugin.Warn("ShieldDomeImageEffect not found (game update?) - dome look left vanilla.");
					return;
				}
				Harmony val = new Harmony("digi.vargheim.ward.dome");
				MethodInfo methodInfo = AccessTools.Method(fx, "Awake", (Type[])null, (Type[])null);
				if (methodInfo != null)
				{
					val.Patch((MethodBase)methodInfo, (HarmonyMethod)null, new HarmonyMethod(typeof(Shield), "EffectAwake", (Type[])null), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
				}
				MethodInfo methodInfo2 = AccessTools.Method(fx, "SetShieldData", (Type[])null, (Type[])null);
				ParameterInfo[] array = ((methodInfo2 != null) ? methodInfo2.GetParameters() : null);
				if (array != null && array.Length != 0 && array[0].ParameterType == typeof(ShieldGenerator))
				{
					val.Patch((MethodBase)methodInfo2, new HarmonyMethod(typeof(Shield), "SetData", (Type[])null), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
				}
				else
				{
					Plugin.Warn("ShieldDomeImageEffect.SetShieldData has a new shape - DomeLook Hidden is not available.");
				}
				Object[] array2 = Object.FindObjectsOfType(fx);
				for (int i = 0; i < array2.Length; i++)
				{
					Apply(array2[i]);
				}
				Plugin.DomeLook.SettingChanged += delegate
				{
					Object[] array3 = Object.FindObjectsOfType(fx);
					for (int j = 0; j < array3.Length; j++)
					{
						Apply(array3[j]);
					}
				};
				Plugin.Note("dome look: " + Plugin.DomeLook.Value.ToString() + ".");
			}
			catch (Exception ex)
			{
				Plugin.Warn("dome look: " + ex.Message);
			}
		}

		private static void EffectAwake(object __instance)
		{
			Apply((Object)((__instance is Object) ? __instance : null));
		}

		private static void Apply(Object fx)
		{
			if (fx == (Object)null)
			{
				return;
			}
			try
			{
				Type type = ((object)fx).GetType();
				int instanceID = fx.GetInstanceID();
				if (!s_vanilla.TryGetValue(instanceID, out var value))
				{
					value = new float[Warps.Length];
					for (int i = 0; i < Warps.Length; i++)
					{
						FieldInfo fieldInfo = AccessTools.Field(type, Warps[i]);
						value[i] = ((fieldInfo != null) ? Convert.ToSingle(fieldInfo.GetValue(fx)) : 0f);
					}
					s_vanilla[instanceID] = value;
				}
				bool flag = Plugin.DomeLook.Value == Look.Clear;
				for (int j = 0; j < Warps.Length; j++)
				{
					FieldInfo fieldInfo2 = AccessTools.Field(type, Warps[j]);
					if (fieldInfo2 != null)
					{
						fieldInfo2.SetValue(fx, Convert.ChangeType(flag ? 0f : value[j], fieldInfo2.FieldType));
					}
				}
			}
			catch (Exception ex)
			{
				Plugin.Warn("dome look apply: " + ex.Message);
			}
		}

		private static bool SetData(ShieldGenerator __0)
		{
			if (Plugin.DomeLook.Value == Look.Hidden)
			{
				return !IsWard(__0);
			}
			return true;
		}
	}
	internal static class Statue
	{
		internal const string DefaultMaterials = "plinth:#5a5651,0,0.15; ring:#c9a24a,0.9,0.6; handle:#6b4a2b,0,0.2; wrap:#3a2a1c,0,0.1; head:#4a4e55,0.85,0.45; cap:#c9a24a,0.9,0.6";

		internal const string DefaultParts = "stone_floor_2x2:1.9,0.22,1.9:0; stone_floor_2x2:1.35,0.18,1.35:0.22; piece_dvergr_metal_wall_2x2:1.0,0.07,1.0:0.40; stone_floor_2x2:0.8,0.08,0.8:0.47; wood_pole:0.17,0.78,0.17:0.52; darkwood_pole:0.21,0.06,0.21:0.70; darkwood_pole:0.21,0.06,0.21:0.84; darkwood_pole:0.21,0.06,0.21:0.98; darkwood_pole:0.21,0.06,0.21:1.12; stone_wall_2x1:0.96,0.66,0.56:1.27; piece_dvergr_metal_wall_2x2:0.4,0.05,0.36:1.93; piece_dvergr_metal_wall_2x2:0.3,0.05,0.3:1.22";

		private static Material s_base;

		private static bool s_dumped;

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

		internal static GameObject Compose(string parts, Func<string, GameObject> findPrefab)
		{
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			//IL_000b: Expected O, but got Unknown
			//IL_0547: Unknown result type (might be due to invalid IL or missing references)
			//IL_0560: Unknown result type (might be due to invalid IL or missing references)
			//IL_02bb: Unknown result type (might be due to invalid IL or missing references)
			//IL_02c7: Unknown result type (might be due to invalid IL or missing references)
			//IL_0323: Unknown result type (might be due to invalid IL or missing references)
			//IL_0305: Unknown result type (might be due to invalid IL or missing references)
			//IL_02f5: Unknown result type (might be due to invalid IL or missing references)
			//IL_02fa: Unknown result type (might be due to invalid IL or missing references)
			//IL_0336: Unknown result type (might be due to invalid IL or missing references)
			//IL_0349: Unknown result type (might be due to invalid IL or missing references)
			//IL_0387: Unknown result type (might be due to invalid IL or missing references)
			//IL_0396: Unknown result type (might be due to invalid IL or missing references)
			//IL_03a5: Unknown result type (might be due to invalid IL or missing references)
			//IL_03c3: Unknown result type (might be due to invalid IL or missing references)
			//IL_03c8: Unknown result type (might be due to invalid IL or missing references)
			//IL_03ca: Unknown result type (might be due to invalid IL or missing references)
			//IL_03d6: Unknown result type (might be due to invalid IL or missing references)
			//IL_0430: Unknown result type (might be due to invalid IL or missing references)
			//IL_043f: Unknown result type (might be due to invalid IL or missing references)
			//IL_044c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0464: Unknown result type (might be due to invalid IL or missing references)
			//IL_0469: Unknown result type (might be due to invalid IL or missing references)
			//IL_046b: Unknown result type (might be due to invalid IL or missing references)
			//IL_04e5: Unknown result type (might be due to invalid IL or missing references)
			//IL_04ea: Unknown result type (might be due to invalid IL or missing references)
			//IL_0414: Unknown result type (might be due to invalid IL or missing references)
			//IL_0404: Unknown result type (might be due to invalid IL or missing references)
			//IL_0409: Unknown result type (might be due to invalid IL or missing references)
			GameObject val = new GameObject("ward_statue_model");
			int num = 0;
			string[] array = (parts ?? "stone_floor_2x2:1.9,0.22,1.9:0; stone_floor_2x2:1.35,0.18,1.35:0.22; piece_dvergr_metal_wall_2x2:1.0,0.07,1.0:0.40; stone_floor_2x2:0.8,0.08,0.8:0.47; wood_pole:0.17,0.78,0.17:0.52; darkwood_pole:0.21,0.06,0.21:0.70; darkwood_pole:0.21,0.06,0.21:0.84; darkwood_pole:0.21,0.06,0.21:0.98; darkwood_pole:0.21,0.06,0.21:1.12; stone_wall_2x1:0.96,0.66,0.56:1.27; piece_dvergr_metal_wall_2x2:0.4,0.05,0.36:1.93; piece_dvergr_metal_wall_2x2:0.3,0.05,0.3:1.22").Split(';');
			Vector3 val9 = default(Vector3);
			Vector3 val12 = default(Vector3);
			for (int i = 0; i < array.Length; i++)
			{
				string text = array[i].Trim();
				if (text.Length == 0)
				{
					continue;
				}
				string[] array2 = text.Split(':');
				if (array2.Length < 3)
				{
					Plugin.Warn("statue part '" + text + "': expected prefab:W,H,D:y");
					continue;
				}
				GameObject val2 = null;
				string[] array3 = array2[0].Split('|');
				foreach (string text2 in array3)
				{
					val2 = findPrefab(text2.Trim());
					if ((Object)(object)val2 != (Object)null)
					{
						break;
					}
				}
				if ((Object)(object)val2 == (Object)null)
				{
					Plugin.Warn("statue part: prefab '" + array2[0] + "' not found.");
					continue;
				}
				string[] array4 = array2[1].Split(',');
				float num2 = F(array4[0]);
				float num3 = ((array4.Length > 1) ? F(array4[1]) : num2);
				float num4 = ((array4.Length > 2) ? F(array4[2]) : num2);
				float num5 = F(array2[2]);
				float num6 = ((array2.Length > 3) ? F(array2[3]) : 0f);
				GameObject val3 = Object.Instantiate<GameObject>(val2, val.transform, false);
				((Object)val3).name = "part_" + ((Object)val2).name;
				val3.SetActive(true);
				Component[] componentsInChildren = val3.GetComponentsInChildren<Component>(true);
				foreach (Component val4 in componentsInChildren)
				{
					if (!((Object)(object)val4 == (Object)null) && !(val4 is Transform) && !(val4 is MeshFilter) && !(val4 is MeshRenderer) && !(val4 is LODGroup))
					{
						Object.DestroyImmediate((Object)(object)val4);
					}
				}
				MeshRenderer[] componentsInChildren2 = val3.GetComponentsInChildren<MeshRenderer>(true);
				foreach (MeshRenderer val5 in componentsInChildren2)
				{
					string text3 = ((Object)((Component)val5).gameObject).name.ToLowerInvariant();
					bool flag = text3.Contains("worn") || text3.Contains("broken") || text3.Contains("snow") || text3.Contains("destruction");
					Material[] sharedMaterials = ((Renderer)val5).sharedMaterials;
					foreach (Material val6 in sharedMaterials)
					{
						if ((Object)(object)val6 != (Object)null && (Object)(object)val6.shader != (Object)null && ((Object)val6.shader).name.ToLowerInvariant().Contains("snow"))
						{
							flag = true;
						}
					}
					if (flag)
					{
						((Renderer)val5).enabled = false;
					}
				}
				val3.transform.localRotation = Quaternion.Euler(0f, num6, 0f);
				Bounds val7 = default(Bounds);
				bool flag2 = false;
				componentsInChildren2 = val3.GetComponentsInChildren<MeshRenderer>(true);
				foreach (MeshRenderer val8 in componentsInChildren2)
				{
					if (((Renderer)val8).enabled)
					{
						if (!flag2)
						{
							val7 = ((Renderer)val8).bounds;
							flag2 = true;
						}
						else
						{
							((Bounds)(ref val7)).Encapsulate(((Renderer)val8).bounds);
						}
					}
				}
				if (!flag2 || ((Bounds)(ref val7)).size.x < 0.0001f || ((Bounds)(ref val7)).size.y < 0.0001f || ((Bounds)(ref val7)).size.z < 0.0001f)
				{
					Plugin.Warn("statue part " + ((Object)val2).name + ": no visible mesh.");
					Object.DestroyImmediate((Object)(object)val3);
					continue;
				}
				((Vector3)(ref val9))..ctor(num2 / ((Bounds)(ref val7)).size.x, num3 / ((Bounds)(ref val7)).size.y, num4 / ((Bounds)(ref val7)).size.z);
				val3.transform.localScale = Vector3.Scale(val3.transform.localScale, val9);
				Bounds val10 = default(Bounds);
				flag2 = false;
				componentsInChildren2 = val3.GetComponentsInChildren<MeshRenderer>(true);
				foreach (MeshRenderer val11 in componentsInChildren2)
				{
					if (((Renderer)val11).enabled)
					{
						if (!flag2)
						{
							val10 = ((Renderer)val11).bounds;
							flag2 = true;
						}
						else
						{
							((Bounds)(ref val10)).Encapsulate(((Renderer)val11).bounds);
						}
					}
				}
				((Vector3)(ref val12))..ctor(0f - ((Bounds)(ref val10)).center.x, num5 - ((Bounds)(ref val10)).min.y, 0f - ((Bounds)(ref val10)).center.z);
				Transform transform = val3.transform;
				transform.localPosition += val12;
				string[] obj = new string[13]
				{
					"statue part ",
					((Object)val2).name,
					" -> ",
					num2.ToString(),
					"x",
					num3.ToString(),
					"x",
					num4.ToString(),
					" m at y=",
					num5.ToString(),
					" (prefab bounds ",
					null,
					null
				};
				Vector3 size = ((Bounds)(ref val7)).size;
				obj[11] = ((Vector3)(ref size)).ToString("F2");
				obj[12] = ")";
				Plugin.Note(string.Concat(obj));
				num++;
			}
			if (num == 0)
			{
				Object.DestroyImmediate((Object)(object)val);
				throw new Exception("no statue parts could be built");
			}
			BoxCollider obj2 = val.AddComponent<BoxCollider>();
			obj2.center = new Vector3(0f, 0.25f, 0f);
			obj2.size = new Vector3(1.9f, 0.5f, 1.9f);
			val.layer = LayerMask.NameToLayer("piece");
			Plugin.Note("statue: " + num + " vanilla parts.");
			return val;
		}

		internal static GameObject Load(string objPath, string materialMap, Func<string, GameObject> findPrefab)
		{
			//IL_0097: Unknown result type (might be due to invalid IL or missing references)
			//IL_03a0: Unknown result type (might be due to invalid IL or missing references)
			//IL_03a7: Expected O, but got Unknown
			//IL_01f9: Unknown result type (might be due to invalid IL or missing references)
			//IL_01fe: Unknown result type (might be due to invalid IL or missing references)
			//IL_0205: Unknown result type (might be due to invalid IL or missing references)
			//IL_020a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0211: Unknown result type (might be due to invalid IL or missing references)
			//IL_0216: Unknown result type (might be due to invalid IL or missing references)
			//IL_0218: Unknown result type (might be due to invalid IL or missing references)
			//IL_021a: Unknown result type (might be due to invalid IL or missing references)
			//IL_021f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0221: Unknown result type (might be due to invalid IL or missing references)
			//IL_0226: Unknown result type (might be due to invalid IL or missing references)
			//IL_022b: Unknown result type (might be due to invalid IL or missing references)
			//IL_022d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0232: Unknown result type (might be due to invalid IL or missing references)
			//IL_0234: Unknown result type (might be due to invalid IL or missing references)
			//IL_0239: Unknown result type (might be due to invalid IL or missing references)
			//IL_023e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0243: Unknown result type (might be due to invalid IL or missing references)
			//IL_0247: Unknown result type (might be due to invalid IL or missing references)
			//IL_024c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0257: Unknown result type (might be due to invalid IL or missing references)
			//IL_0265: Unknown result type (might be due to invalid IL or missing references)
			//IL_0273: Unknown result type (might be due to invalid IL or missing references)
			//IL_028f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0294: Unknown result type (might be due to invalid IL or missing references)
			//IL_0299: 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_02a6: Unknown result type (might be due to invalid IL or missing references)
			//IL_02f9: Unknown result type (might be due to invalid IL or missing references)
			//IL_0300: Unknown result type (might be due to invalid IL or missing references)
			//IL_0307: Unknown result type (might be due to invalid IL or missing references)
			//IL_02dd: Unknown result type (might be due to invalid IL or missing references)
			//IL_02e4: Unknown result type (might be due to invalid IL or missing references)
			//IL_02eb: Unknown result type (might be due to invalid IL or missing references)
			//IL_02bb: Unknown result type (might be due to invalid IL or missing references)
			//IL_02c2: Unknown result type (might be due to invalid IL or missing references)
			//IL_02c9: Unknown result type (might be due to invalid IL or missing references)
			//IL_05ac: Unknown result type (might be due to invalid IL or missing references)
			//IL_05b3: Expected O, but got Unknown
			List<Vector3> list = new List<Vector3>();
			Dictionary<string, List<int[]>> dictionary = new Dictionary<string, List<int[]>>();
			List<string> list2 = new List<string>();
			string text = "default";
			string[] array = File.ReadAllLines(objPath);
			for (int i = 0; i < array.Length; i++)
			{
				string text2 = array[i].Trim();
				if (text2.Length == 0 || text2[0] == '#')
				{
					continue;
				}
				string[] array2 = text2.Split(new char[1] { ' ' }, StringSplitOptions.RemoveEmptyEntries);
				if (array2[0] == "v" && array2.Length >= 4)
				{
					list.Add(new Vector3(F(array2[1]), F(array2[2]), F(array2[3])));
				}
				else if (array2[0] == "g" && array2.Length >= 2)
				{
					text = array2[1];
				}
				else if (array2[0] == "f" && array2.Length >= 4)
				{
					int[] array3 = new int[array2.Length - 1];
					for (int j = 1; j < array2.Length; j++)
					{
						string text3 = array2[j];
						int num = text3.IndexOf('/');
						array3[j - 1] = int.Parse((num >= 0) ? text3.Substring(0, num) : text3, CultureInfo.InvariantCulture) - 1;
					}
					if (!dictionary.TryGetValue(text, out var value))
					{
						value = (dictionary[text] = new List<int[]>());
						list2.Add(text);
					}
					value.Add(array3);
				}
			}
			if (list.Count == 0 || list2.Count == 0)
			{
				throw new Exception("no geometry in " + Path.GetFileName(objPath));
			}
			List<Vector3> list4 = new List<Vector3>();
			List<Vector3> list5 = new List<Vector3>();
			List<Vector2> list6 = new List<Vector2>();
			List<int[]> list7 = new List<int[]>();
			foreach (string item in list2)
			{
				List<int> list8 = new List<int>();
				foreach (int[] item2 in dictionary[item])
				{
					Vector3 v = list[item2[0]];
					Vector3 v2 = list[item2[1]];
					Vector3 v3 = list[item2[2]];
					Vector3 val = Vector3.Cross(Flip(v2) - Flip(v), Flip(v3) - Flip(v));
					Vector3 normalized = ((Vector3)(ref val)).normalized;
					int count = list4.Count;
					float num2 = Mathf.Abs(normalized.x);
					float num3 = Mathf.Abs(normalized.y);
					float num4 = Mathf.Abs(normalized.z);
					for (int k = 0; k < item2.Length; k++)
					{
						Vector3 val2 = Flip(list[item2[k]]);
						list4.Add(val2);
						list5.Add(normalized);
						if (num3 >= num2 && num3 >= num4)
						{
							list6.Add(new Vector2(val2.x, val2.z));
						}
						else if (num2 >= num4)
						{
							list6.Add(new Vector2(val2.z, val2.y));
						}
						else
						{
							list6.Add(new Vector2(val2.x, val2.y));
						}
					}
					for (int l = 1; l + 1 < item2.Length; l++)
					{
						list8.Add(count);
						list8.Add(count + l);
						list8.Add(count + l + 1);
					}
				}
				list7.Add(list8.ToArray());
			}
			Mesh val3 = new Mesh();
			((Object)val3).name = "ward_statue";
			val3.indexFormat = (IndexFormat)(list4.Count > 65000);
			val3.SetVertices(list4);
			val3.SetNormals(list5);
			val3.SetUVs(0, list6);
			val3.RecalculateTangents();
			val3.subMeshCount = list7.Count;
			for (int m = 0; m < list7.Count; m++)
			{
				val3.SetTriangles(list7[m], m);
			}
			val3.RecalculateBounds();
			Dictionary<string, string> dictionary2 = new Dictionary<string, string>();
			array = (materialMap ?? "plinth:#5a5651,0,0.15; ring:#c9a24a,0.9,0.6; handle:#6b4a2b,0,0.2; wrap:#3a2a1c,0,0.1; head:#4a4e55,0.85,0.45; cap:#c9a24a,0.9,0.6").Split(';');
			foreach (string text4 in array)
			{
				int num5 = text4.IndexOf(':');
				if (num5 > 0)
				{
					dictionary2[text4.Substring(0, num5).Trim()] = text4.Substring(num5 + 1).Trim();
				}
			}
			Material[] array4 = (Material[])(object)new Material[list2.Count];
			DumpShader(Resolve("stone_wall_2x1", findPrefab));
			Material val4 = null;
			for (int n = 0; n < list2.Count; n++)
			{
				dictionary2.TryGetValue(list2[n], out var value2);
				array4[n] = Triplanar(Resolve(value2, findPrefab) ?? val4 ?? (val4 = Resolve("stone_wall_2x1", findPrefab)));
				Plugin.Note("statue material " + list2[n] + " <- " + (value2 ?? "(default)") + " = " + (((Object)(object)array4[n] != (Object)null) ? (((Object)array4[n]).name + " [" + (((Object)(object)array4[n].shader != (Object)null) ? ((Object)array4[n].shader).name : "?") + "]") : "NONE"));
			}
			GameObject val5 = new GameObject("ward_statue_model");
			val5.AddComponent<MeshFilter>().sharedMesh = val3;
			MeshRenderer obj = val5.AddComponent<MeshRenderer>();
			((Renderer)obj).sharedMaterials = array4;
			((Renderer)obj).shadowCastingMode = (ShadowCastingMode)1;
			MeshCollider obj2 = val5.AddComponent<MeshCollider>();
			obj2.sharedMesh = val3;
			obj2.convex = false;
			val5.layer = LayerMask.NameToLayer("piece");
			Plugin.Note("statue: " + list4.Count + " vertices, " + list2.Count + " groups (" + string.Join(", ", list2.ToArray()) + ").");
			return val5;
		}

		private static Material Solid(string spec, Func<string, GameObject> findPrefab)
		{
			//IL_001b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0020: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ca: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d1: Expected O, but got Unknown
			//IL_00f5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fc: Expected O, but got Unknown
			//IL_00be: Unknown result type (might be due to invalid IL or missing references)
			//IL_010e: Unknown result type (might be due to invalid IL or missing references)
			//IL_010f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0156: Unknown result type (might be due to invalid IL or missing references)
			//IL_017b: Unknown result type (might be due to invalid IL or missing references)
			//IL_018c: Unknown result type (might be due to invalid IL or missing references)
			//IL_02e7: Unknown result type (might be due to invalid IL or missing references)
			//IL_02a0: Unknown result type (might be due to invalid IL or missing references)
			//IL_0364: Unknown result type (might be due to invalid IL or missing references)
			string[] array = spec.Split(',');
			Color gray = default(Color);
			if (!ColorUtility.TryParseHtmlString(array[0].Trim(), ref gray))
			{
				gray = Color.gray;
			}
			float result = 0f;
			float result2 = 0.3f;
			if (array.Length > 1)
			{
				float.TryParse(array[1].Trim(), NumberStyles.Float, CultureInfo.InvariantCulture, out result);
			}
			if (array.Length > 2)
			{
				float.TryParse(array[2].Trim(), NumberStyles.Float, CultureInfo.InvariantCulture, out result2);
			}
			if ((Object)(object)s_base == (Object)null)
			{
				s_base = Resolve("stone_wall_2x1", findPrefab) ?? Resolve("wood_pole", findPrefab);
			}
			Material val = (((Object)(object)s_base != (Object)null) ? new Material(s_base) : new Material(Shader.Find("Custom/Piece") ?? Shader.Find("Standard")));
			((Object)val).name = "ward_solid_" + array[0].Trim().TrimStart('#');
			Texture2D val2 = new Texture2D(4, 4, (TextureFormat)4, false);
			Color[] array2 = (Color[])(object)new Color[16];
			for (int i = 0; i < array2.Length; i++)
			{
				array2[i] = gray;
			}
			val2.SetPixels(array2);
			val2.Apply();
			((Object)val2).name = ((Object)val).name;
			Texture2D val3 = Flat(new Color(Mathf.Clamp01(result), 0f, 0f, Mathf.Clamp01(result2)), "metal");
			Texture2D val4 = Flat(new Color(0.5f, 0.5f, 1f, 1f), "normal");
			Texture2D val5 = Flat(Color.black, "black");
			string[] array3 = new string[13]
			{
				"_MainTex", "_BumpMap", "_MetallicGlossMap", "_EmissiveTex", "_EmissionMap", "_OcclusionMap", "_DetailAlbedoMap", "_DetailNormalMap", "_MossTex", "_SnowTex",
				"_RustTex", "_Mask", "_MaskTex"
			};
			foreach (string text in array3)
			{
				if (val.HasProperty(text))
				{
					switch (text)
					{
					case "_MainTex":
						val.SetTexture(text, (Texture)(object)val2);
						break;
					case "_BumpMap":
					case "_DetailNormalMap":
						val.SetTexture(text, (Texture)(object)val4);
						break;
					case "_MetallicGlossMap":
						val.SetTexture(text, (Texture)(object)val3);
						break;
					case "_OcclusionMap":
						val.SetTexture(text, (Texture)(object)Flat(Color.white, "white"));
						break;
					default:
						val.SetTexture(text, (Texture)(object)val5);
						break;
					}
				}
			}
			if (val.HasProperty("_Color"))
			{
				val.SetColor("_Color", Color.white);
			}
			if (val.HasProperty("_Metallic"))
			{
				val.SetFloat("_Metallic", Mathf.Clamp01(result));
			}
			if (val.HasProperty("_Glossiness"))
			{
				val.SetFloat("_Glossiness", Mathf.Clamp01(result2));
			}
			array3 = new string[2] { "_EmissionColor", "_EmissiveColor" };
			foreach (string text2 in array3)
			{
				if (val.HasProperty(text2))
				{
					val.SetColor(text2, Color.black);
				}
			}
			array3 = new string[5] { "_MossAlpha", "_SnowAlpha", "_RustAlpha", "_UseGlossmap", "_EmissionEnabled" };
			foreach (string text3 in array3)
			{
				if (val.HasProperty(text3))
				{
					val.SetFloat(text3, 0f);
				}
			}
			return val;
		}

		private static void DumpShader(Material m)
		{
			//IL_0176: Unknown result type (might be due to invalid IL or missing references)
			//IL_0081: Unknown result type (might be due to invalid IL or missing references)
			//IL_0086: Unknown result type (might be due to invalid IL or missing references)
			//IL_008f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0092: Invalid comparison between Unknown and I4
			//IL_00fe: Unknown result type (might be due to invalid IL or missing references)
			//IL_011d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0120: Invalid comparison between Unknown and I4
			//IL_0105: Unknown result type (might be due to invalid IL or missing references)
			//IL_010a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0125: Unknown result type (might be due to invalid IL or missing references)
			//IL_012a: Unknown result type (might be due to invalid IL or missing references)
			if (s_dumped || (Object)(object)m == (Object)null || (Object)(object)m.shader == (Object)null)
			{
				return;
			}
			s_dumped = true;
			try
			{
				Shader shader = m.shader;
				StringBuilder stringBuilder = new StringBuilder();
				stringBuilder.Append("shader ").Append(((Object)shader).name).Append(" via ")
					.Append(((Object)m).name)
					.Append(":");
				int propertyCount = shader.GetPropertyCount();
				for (int i = 0; i < propertyCount; i++)
				{
					string propertyName = shader.GetPropertyName(i);
					ShaderPropertyType propertyType = shader.GetPropertyType(i);
					string value = "";
					try
					{
						if ((int)propertyType != 4)
						{
							value = (((int)propertyType == 0) ? ((object)m.GetColor(propertyName)/*cast due to .constrained prefix*/).ToString() : (((int)propertyType != 1) ? m.GetFloat(propertyName).ToString(CultureInfo.InvariantCulture) : ((object)m.GetVector(propertyName)/*cast due to .constrained prefix*/).ToString()));
						}
						else
						{
							Texture texture = m.GetTexture(propertyName);
							value = (((Object)(object)texture != (Object)null) ? (((Object)texture).name + " " + texture.width + "x" + texture.height) : "null");
						}
					}
					catch
					{
					}
					stringBuilder.Append("\n  ").Append(propertyName).Append(" (")
						.Append(propertyType)
						.Append(") = ")
						.Append(value);
				}
				stringBuilder.Append("\n  keywords: ").Append(string.Join(" ", m.shaderKeywords));
				Plugin.Note(stringBuilder.ToString());
			}
			catch (Exception ex)
			{
				Plugin.Warn("shader dump: " + ex.Message);
			}
		}

		private static Material Triplanar(Material src)
		{
			//IL_0038: Unknown result type (might be due to invalid IL or missing references)
			//IL_003e: Expected O, but got Unknown
			if ((Object)(object)src == (Object)null || !src.HasProperty("_TriplanarMap"))
			{
				return src;
			}
			if (s_tri.TryGetValue(((Object)src).GetInstanceID(), out var value) && (Object)(object)value != (Object)null)
			{
				return value;
			}
			value = new Material(src);
			((Object)value).name = ((Object)src).name + "_ward_tri";
			value.SetFloat("_TriplanarMap", 1f);
			if (value.HasProperty("_TriplanarScale"))
			{
				value.SetFloat("_TriplanarScale", Mathf.Max(0.1f, Plugin.TextureScale.Value));
			}
			if (value.HasProperty("_TriplanarLocalPos"))
			{
				value.SetFloat("_TriplanarLocalPos", 1f);
			}
			if (value.HasProperty("_RippleDistance"))
			{
				value.SetFloat("_RippleDistance", 0f);
			}
			if (value.HasProperty("_Cull"))
			{
				value.SetFloat("_Cull", 0f);
			}
			s_tri[((Object)src).GetInstanceID()] = value;
			return value;
		}

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

		private static Vector3 Flip(Vector3 v)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_000c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0013: Unknown result type (might be due to invalid IL or missing references)
			return new Vector3(v.x, v.y, 0f - v.z);
		}

		private static float F(string s)
		{
			return float.Parse(s, CultureInfo.InvariantCulture);
		}

		private static Material Resolve(string spec, Func<string, GameObject> findPrefab)
		{
			//IL_0273: Unknown result type (might be due to invalid IL or missing references)
			//IL_027a: Expected O, but got Unknown
			//IL_02a3: Unknown result type (might be due to invalid IL or missing references)
			//IL_02bf: Unknown result type (might be due to invalid IL or missing references)
			if (string.IsNullOrEmpty(spec))
			{
				return null;
			}
			spec = spec.Trim();
			if (spec.StartsWith("#", StringComparison.Ordinal))
			{
				return Solid(spec, findPrefab);
			}
			if (spec.IndexOf('|') >= 0)
			{
				string[] array = spec.Split('|');
				for (int i = 0; i < array.Length; i++)
				{
					Material val = Resolve(array[i].Trim(), findPrefab);
					if ((Object)(object)val != (Object)null)
					{
						return val;
					}
				}
				return null;
			}
			string text = null;
			int num = spec.IndexOf('#');
			if (num >= 0)
			{
				text = spec.Substring(num + 1);
				spec = spec.Substring(0, num);
			}
			string[] array2 = spec.Split(':');
			GameObject val2 = findPrefab(array2[0].Trim());
			if ((Object)(object)val2 == (Object)null)
			{
				Plugin.Warn("statue material: prefab '" + array2[0] + "' not found.");
				return null;
			}
			Material val3 = null;
			Material val4 = null;
			string text2 = ((array2.Length > 1) ? array2[1].Trim().ToLowerInvariant() : null);
			Renderer[] componentsInChildren = val2.GetComponentsInChildren<Renderer>(true);
			for (int i = 0; i < componentsInChildren.Length; i++)
			{
				Material[] sharedMaterials = componentsInChildren[i].sharedMaterials;
				foreach (Material val5 in sharedMaterials)
				{
					if ((Object)(object)val5 == (Object)null)
					{
						continue;
					}
					string text3 = ((Object)val5).name.ToLowerInvariant();
					string text4 = (((Object)(object)val5.shader != (Object)null) ? ((Object)val5.shader).name : "");
					string text5 = text4.ToLowerInvariant();
					if (!text5.Contains("snow") && !text5.Contains("forcefield") && !text5.Contains("transparent") && !text5.Contains("particle") && !text5.Contains("invis") && !text5.Contains("unlit") && !text3.Contains("shield_") && !text3.Contains("dome") && (text2 == null || text3.Contains(text2)))
					{
						if (text4 == "Custom/Piece")
						{
							val3 = val5;
							break;
						}
						if ((Object)(object)val4 == (Object)null)
						{
							val4 = val5;
						}
					}
				}
				if ((Object)(object)val3 != (Object)null)
				{
					break;
				}
			}
			if ((Object)(object)val3 == (Object)null)
			{
				val3 = val4;
			}
			if ((Object)(object)val3 == (Object)null)
			{
				return null;
			}
			if (string.IsNullOrEmpty(text))
			{
				return val3;
			}
			Color color = default(Color);
			if (!ColorUtility.TryParseHtmlString("#" + text, ref color))
			{
				return val3;
			}
			Material val6 = new Material(val3);
			((Object)val6).name = ((Object)val3).name + "_ward_" + text;
			if (val6.HasProperty("_Color"))
			{
				val6.color = color;
			}
			if (val6.HasProperty("_EmissionColor"))
			{
				val6.SetColor("_EmissionColor", Color.black);
			}
			return val6;
		}
	}
}