Decompiled source of ForsakenBanners v1.0.0

BepInEx/plugins/ForsakenBanners/ForsakenBanners.dll

Decompiled 9 hours ago
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using BepInEx;
using HarmonyLib;
using Jotunn.Configs;
using Jotunn.Entities;
using Jotunn.Managers;
using Jotunn.Utils;
using Microsoft.CodeAnalysis;
using UnityEngine;
using UnityEngine.Rendering;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETFramework,Version=v4.7.2", FrameworkDisplayName = ".NET Framework 4.7.2")]
[assembly: AssemblyCompany("ForsakenBanners")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0")]
[assembly: AssemblyProduct("ForsakenBanners")]
[assembly: AssemblyTitle("ForsakenBanners")]
[assembly: AssemblyVersion("1.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 ForsakenBanners
{
	public static class BannerPreview
	{
		private const int Layer = 31;

		public static Sprite Render(GameObject prefab, int width = 128, int height = 128, bool back = false, bool freezeWind = true)
		{
			//IL_0014: Unknown result type (might be due to invalid IL or missing references)
			//IL_001a: Expected O, but got Unknown
			//IL_002f: 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_007c: 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_0095: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b8: Expected O, but got Unknown
			//IL_00d2: Unknown result type (might be due to invalid IL or missing references)
			//IL_0100: Unknown result type (might be due to invalid IL or missing references)
			//IL_010c: Unknown result type (might be due to invalid IL or missing references)
			//IL_014f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0163: Unknown result type (might be due to invalid IL or missing references)
			//IL_0168: 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_018a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0190: Expected O, but got Unknown
			//IL_01ce: Unknown result type (might be due to invalid IL or missing references)
			//IL_01fc: Unknown result type (might be due to invalid IL or missing references)
			//IL_0203: Expected O, but got Unknown
			//IL_0213: Unknown result type (might be due to invalid IL or missing references)
			//IL_0231: 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_0280: Unknown result type (might be due to invalid IL or missing references)
			//IL_0285: Unknown result type (might be due to invalid IL or missing references)
			//IL_028b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0290: Unknown result type (might be due to invalid IL or missing references)
			//IL_02a8: Unknown result type (might be due to invalid IL or missing references)
			//IL_02af: 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)
			//IL_02c6: Unknown result type (might be due to invalid IL or missing references)
			//IL_02d6: 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_0328: Unknown result type (might be due to invalid IL or missing references)
			//IL_0337: Unknown result type (might be due to invalid IL or missing references)
			GameObject val = null;
			GameObject val2 = null;
			GameObject val3 = null;
			RenderTexture val4 = null;
			RenderTexture active = RenderTexture.active;
			try
			{
				val = new GameObject("Forsaken Banners preview");
				val.transform.position = new Vector3(0f, 10000f, 0f);
				val.transform.rotation = Quaternion.Euler(0f, (float)(back ? 90 : 270), 0f);
				CopyVisuals(prefab.transform, val.transform, freezeWind);
				Renderer[] componentsInChildren = val.GetComponentsInChildren<Renderer>();
				Bounds bounds = componentsInChildren[0].bounds;
				Renderer[] array = componentsInChildren;
				foreach (Renderer val5 in array)
				{
					((Bounds)(ref bounds)).Encapsulate(val5.bounds);
				}
				val2 = new GameObject("Forsaken Banners preview camera");
				Camera val6 = val2.AddComponent<Camera>();
				((Behaviour)val6).enabled = false;
				val6.clearFlags = (CameraClearFlags)2;
				val6.backgroundColor = Color.clear;
				val6.cullingMask = int.MinValue;
				val6.orthographic = true;
				val6.aspect = (float)width / (float)height;
				val6.orthographicSize = Mathf.Max(((Bounds)(ref bounds)).extents.y, ((Bounds)(ref bounds)).extents.x / val6.aspect) * 1.12f;
				val6.nearClipPlane = 0.1f;
				val6.farClipPlane = 30f;
				((Component)val6).transform.position = ((Bounds)(ref bounds)).center + new Vector3(0f, 0f, 10f);
				((Component)val6).transform.LookAt(((Bounds)(ref bounds)).center);
				val3 = new GameObject("Forsaken Banners preview light");
				Light obj = val3.AddComponent<Light>();
				obj.type = (LightType)1;
				obj.intensity = 1.2f;
				obj.shadows = (LightShadows)0;
				obj.cullingMask = int.MinValue;
				((Component)obj).transform.rotation = Quaternion.Euler(15f, 180f, -10f);
				val4 = (val6.targetTexture = RenderTexture.GetTemporary(width, height, 24, (RenderTextureFormat)0));
				val6.Render();
				RenderTexture.active = val4;
				Texture2D val7 = new Texture2D(width, height, (TextureFormat)4, false);
				val7.ReadPixels(new Rect(0f, 0f, (float)width, (float)height), 0, 0);
				val7.Apply();
				Color32[] pixels = val7.GetPixels32();
				val6.backgroundColor = Color.white;
				val6.Render();
				RenderTexture.active = val4;
				val7.ReadPixels(new Rect(0f, 0f, (float)width, (float)height), 0, 0);
				val7.Apply();
				Color32[] pixels2 = val7.GetPixels32();
				for (int j = 0; j < pixels.Length; j++)
				{
					Color32 val8 = pixels[j];
					Color32 val9 = pixels2[j];
					pixels[j].a = (byte)(255 - Mathf.Max(new int[3]
					{
						Mathf.Abs(val9.r - val8.r),
						Mathf.Abs(val9.g - val8.g),
						Mathf.Abs(val9.b - val8.b)
					}));
				}
				val7.SetPixels32(pixels);
				val7.Apply();
				return Sprite.Create(val7, new Rect(0f, 0f, (float)width, (float)height), new Vector2(0.5f, 0.5f));
			}
			finally
			{
				RenderTexture.active = active;
				if (Object.op_Implicit((Object)(object)val2))
				{
					Object.DestroyImmediate((Object)(object)val2);
				}
				if (Object.op_Implicit((Object)(object)val3))
				{
					Object.DestroyImmediate((Object)(object)val3);
				}
				if (Object.op_Implicit((Object)(object)val4))
				{
					RenderTexture.ReleaseTemporary(val4);
				}
				if (Object.op_Implicit((Object)(object)val))
				{
					Renderer[] array = val.GetComponentsInChildren<Renderer>();
					for (int i = 0; i < array.Length; i++)
					{
						Material[] sharedMaterials = array[i].sharedMaterials;
						for (int k = 0; k < sharedMaterials.Length; k++)
						{
							Object.DestroyImmediate((Object)(object)sharedMaterials[k]);
						}
					}
					Object.DestroyImmediate((Object)(object)val);
				}
			}
		}

		private static void CopyVisuals(Transform original, Transform parent, bool freezeWind)
		{
			//IL_0117: Unknown result type (might be due to invalid IL or missing references)
			//IL_011e: Expected O, but got Unknown
			//IL_0133: Unknown result type (might be due to invalid IL or missing references)
			//IL_013a: Expected O, but got Unknown
			//IL_0151: 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_0177: Unknown result type (might be due to invalid IL or missing references)
			//IL_0074: Unknown result type (might be due to invalid IL or missing references)
			//IL_007a: Expected O, but got Unknown
			MeshRenderer component = ((Component)original).GetComponent<MeshRenderer>();
			MeshFilter component2 = ((Component)original).GetComponent<MeshFilter>();
			if (Object.op_Implicit((Object)(object)component) && Object.op_Implicit((Object)(object)component2) && ((Component)original).gameObject.activeSelf && ((Renderer)component).enabled)
			{
				((Component)parent).gameObject.AddComponent<MeshFilter>().sharedMesh = component2.sharedMesh;
				MeshRenderer val = ((Component)parent).gameObject.AddComponent<MeshRenderer>();
				Material[] sharedMaterials = ((Renderer)component).sharedMaterials;
				for (int i = 0; i < sharedMaterials.Length; i++)
				{
					sharedMaterials[i] = new Material(sharedMaterials[i]);
					string[] array = new string[3] { "_SwayDistance", "_RippleDistance", "_PushDistance" };
					foreach (string text in array)
					{
						if (freezeWind && sharedMaterials[i].HasProperty(text))
						{
							sharedMaterials[i].SetFloat(text, 0f);
						}
					}
				}
				((Renderer)val).sharedMaterials = sharedMaterials;
				((Renderer)val).shadowCastingMode = (ShadowCastingMode)0;
				((Renderer)val).receiveShadows = false;
			}
			((Component)parent).gameObject.layer = 31;
			foreach (Transform item in original)
			{
				Transform val2 = item;
				if (((Component)val2).gameObject.activeSelf)
				{
					GameObject val3 = new GameObject(((Object)val2).name);
					val3.transform.SetParent(parent, false);
					val3.transform.localPosition = val2.localPosition;
					val3.transform.localRotation = val2.localRotation;
					val3.transform.localScale = val2.localScale;
					CopyVisuals(val2, val3.transform, freezeWind);
				}
			}
		}
	}
	[BepInPlugin("local.forsakenbanners", "Forsaken Banners", "1.0.0")]
	[BepInDependency("com.jotunn.jotunn", "2.30.2")]
	[NetworkCompatibility(/*Could not decode attribute arguments.*/)]
	public sealed class Plugin : BaseUnityPlugin
	{
		public const string Id = "local.forsakenbanners";

		public const string Version = "1.0.0";

		public const string BasePrefab = "piece_banner05";

		private readonly HashSet<string> registered = new HashSet<string>();

		private readonly Harmony harmony = new Harmony("local.forsakenbanners");

		private static Piece swampPiece;

		private float nextProgressionCheck;

		public static readonly BannerSpec[] Banners = new BannerSpec[9]
		{
			new BannerSpec("Eikthyr", "HardAntler", "Флаг Эйктюра", "Eikthyr Banner", "Оленьи рога и молодые побеги на зелёном полотне.", "Antlers and young shoots on green cloth."),
			new BannerSpec("Elder", "AncientSeed", "Флаг Древнего", "The Elder Banner", "Ель, вороны и древние узоры Чёрного леса.", "A fir tree, ravens and ancient Black Forest knots."),
			new BannerSpec("Bonemass", "BoneFragments", "Флаг Массы костей", "Bonemass Banner", "Истлевшее болотное знамя с черепом, корнями и мхом.", "A tattered swamp banner bearing a skull, roots and moss."),
			new BannerSpec("Moder", "DragonTear", "Флаг Моудер", "Moder Banner", "Волк, снежинка и горные вершины на синем полотне.", "A wolf, snowflake and mountain peaks on blue cloth."),
			new BannerSpec("Yagluth", "YagluthDrop", "Флаг Яглута", "Yagluth Banner", "Солнце, рогатый череп и колосья золотых Равнин.", "The sun, a horned skull and the golden grain of the Plains."),
			new BannerSpec("Serpent", "SerpentScale", "Флаг морского змея", "Sea Serpent Banner", "Морской змей среди волн на бирюзовом полотне.", "A sea serpent rising from the waves on teal cloth."),
			new BannerSpec("Mistlands", "Wisp", "Флаг Туманных земель", "Mistlands Banner", "Фиолетовые кристаллы и узоры на тёмном полотне.", "Violet crystals and angular patterns on dark cloth."),
			new BannerSpec("Ashlands", "CharcoalResin", "Флаг Пепельных земель", "Ashlands Banner", "Обгоревшее рваное знамя с огнём и трещинами лавы.", "A scorched, tattered banner bearing fire and lava cracks."),
			new BannerSpec("Ravens", "Tar", "Флаг двух воронов", "Twin Ravens Banner", "Два ворона и древние руны на чёрном рваном полотне.", "Twin ravens and ancient runes on tattered black cloth.")
		};

		private void Awake()
		{
			//IL_00e9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f7: Expected O, but got Unknown
			Dictionary<string, string> dictionary = new Dictionary<string, string>();
			Dictionary<string, string> dictionary2 = new Dictionary<string, string>();
			BannerSpec[] banners = Banners;
			foreach (BannerSpec bannerSpec in banners)
			{
				dictionary[bannerSpec.NameKey] = bannerSpec.RussianName;
				dictionary[bannerSpec.DescriptionKey] = bannerSpec.RussianDescription;
				dictionary2[bannerSpec.NameKey] = bannerSpec.EnglishName;
				dictionary2[bannerSpec.DescriptionKey] = bannerSpec.EnglishDescription;
			}
			CustomLocalization localization = LocalizationManager.Instance.GetLocalization();
			string text = "English";
			localization.AddTranslation(ref text, dictionary2);
			text = "Russian";
			localization.AddTranslation(ref text, dictionary);
			string[] array = new string[2] { "UpdateKnownRecipesList", "UpdateAvailablePiecesList" };
			foreach (string text2 in array)
			{
				harmony.Patch((MethodBase)AccessTools.Method(typeof(Player), text2, (Type[])null, (Type[])null), new HarmonyMethod(typeof(Plugin), "RefreshGate", (Type[])null), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
			}
			PrefabManager.OnVanillaPrefabsAvailable += Register;
		}

		private void Register()
		{
			GameObject prefab = PrefabManager.Instance.GetPrefab("piece_banner05");
			if (!Object.op_Implicit((Object)(object)prefab))
			{
				((BaseUnityPlugin)this).Logger.LogError((object)"Vanilla green banner is unavailable.");
				return;
			}
			BannerSpec[] banners = Banners;
			foreach (BannerSpec bannerSpec in banners)
			{
				if (!registered.Contains(bannerSpec.PrefabName))
				{
					try
					{
						RegisterOne(bannerSpec, prefab);
						registered.Add(bannerSpec.PrefabName);
					}
					catch (Exception arg)
					{
						((BaseUnityPlugin)this).Logger.LogError((object)$"Could not register {bannerSpec.PrefabName}: {arg}");
					}
				}
			}
			if (registered.Count == Banners.Length)
			{
				PrefabManager.OnVanillaPrefabsAvailable -= Register;
			}
		}

		private void RegisterOne(BannerSpec spec, GameObject source)
		{
			//IL_005b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0061: Expected O, but got Unknown
			//IL_006b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0071: Expected O, but got Unknown
			//IL_007b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0081: Expected O, but got Unknown
			//IL_008b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0091: Expected O, but got Unknown
			//IL_0023: Unknown result type (might be due to invalid IL or missing references)
			//IL_0029: Expected O, but got Unknown
			//IL_0033: Unknown result type (might be due to invalid IL or missing references)
			//IL_0039: Expected O, but got Unknown
			//IL_0043: Unknown result type (might be due to invalid IL or missing references)
			//IL_0049: Expected O, but got Unknown
			//IL_0130: Unknown result type (might be due to invalid IL or missing references)
			//IL_0136: Invalid comparison between Unknown and I4
			//IL_013f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0146: Expected O, but got Unknown
			//IL_01bf: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c5: Invalid comparison between Unknown and I4
			//IL_01fd: Unknown result type (might be due to invalid IL or missing references)
			//IL_0204: Expected O, but got Unknown
			RequirementConfig[] array = (RequirementConfig[])(object)((!(spec.Key == "Bonemass")) ? new RequirementConfig[3]
			{
				new RequirementConfig(spec.Resource, 1, 0, true),
				new RequirementConfig("FineWood", 2, 0, true),
				new RequirementConfig("LeatherScraps", 6, 0, true)
			} : new RequirementConfig[4]
			{
				new RequirementConfig("BoneFragments", 5, 0, true),
				new RequirementConfig("Guck", 2, 0, true),
				new RequirementConfig("FineWood", 2, 0, true),
				new RequirementConfig("LeatherScraps", 6, 0, true)
			});
			string[] array2 = array.Select((RequirementConfig r) => r.Item).ToArray();
			ItemDrop[] array3 = (ItemDrop[])(object)new ItemDrop[array2.Length];
			for (int num = 0; num < array3.Length; num++)
			{
				GameObject prefab = PrefabManager.Instance.GetPrefab(array2[num]);
				array3[num] = (Object.op_Implicit((Object)(object)prefab) ? prefab.GetComponent<ItemDrop>() : null);
				if (!Object.op_Implicit((Object)(object)array3[num]))
				{
					throw new InvalidOperationException("Missing recipe resource: " + array2[num]);
				}
			}
			GameObject val = PrefabManager.Instance.CreateClonedPrefab(spec.PrefabName, source);
			if ((int)SystemInfo.graphicsDeviceType != 4)
			{
				ApplyArtwork(val, spec);
			}
			PieceConfig val2 = new PieceConfig();
			val2.Name = "$" + spec.NameKey;
			val2.Description = "$" + spec.DescriptionKey;
			val2.PieceTable = "Hammer";
			val2.Category = "Furniture";
			val2.Usage = new string[1] { "Decor" };
			val2.AllowedInDungeons = source.GetComponent<Piece>().m_allowedInDungeons;
			val2.Requirements = array;
			PieceConfig val3 = val2;
			if ((int)SystemInfo.graphicsDeviceType != 4)
			{
				val3.Icon = BannerPreview.Render(val);
				if (!Object.op_Implicit((Object)(object)val3.Icon))
				{
					throw new InvalidOperationException("Banner icon render failed");
				}
			}
			CustomPiece val4 = new CustomPiece(val, false, val3);
			Piece component = val.GetComponent<Piece>();
			for (int num2 = 0; num2 < array3.Length; num2++)
			{
				component.m_resources[num2].m_resItem = array3[num2];
			}
			if (spec.Key == "Bonemass")
			{
				swampPiece = component;
				RefreshGate();
			}
			if (!PieceManager.Instance.AddPiece(val4))
			{
				throw new InvalidOperationException("Piece registration rejected");
			}
			((BaseUnityPlugin)this).Logger.LogInfo((object)("Registered " + spec.PrefabName + ": " + string.Join(", ", array.Select((RequirementConfig r) => r.Item + " x" + r.Amount))));
		}

		private static void RefreshGate()
		{
			if (Object.op_Implicit((Object)(object)swampPiece))
			{
				swampPiece.m_enabled = Object.op_Implicit((Object)(object)ZoneSystem.instance) && ZoneSystem.instance.GetGlobalKey("defeated_bonemass");
			}
		}

		private void Update()
		{
			if (!(Time.unscaledTime < nextProgressionCheck) && Object.op_Implicit((Object)(object)swampPiece))
			{
				nextProgressionCheck = Time.unscaledTime + 1f;
				bool enabled = swampPiece.m_enabled;
				RefreshGate();
				if (enabled != swampPiece.m_enabled && Object.op_Implicit((Object)(object)Player.m_localPlayer))
				{
					AccessTools.Method(typeof(Player), "UpdateKnownRecipesList", (Type[])null, (Type[])null).Invoke(Player.m_localPlayer, null);
					AccessTools.Method(typeof(Player), "UpdateAvailablePiecesList", (Type[])null, (Type[])null).Invoke(Player.m_localPlayer, null);
				}
			}
		}

		private static void ApplyArtwork(GameObject clone, BannerSpec spec)
		{
			//IL_00a9: 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_00bb: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e6: 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_010f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0114: Unknown result type (might be due to invalid IL or missing references)
			//IL_013c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0141: Unknown result type (might be due to invalid IL or missing references)
			//IL_0159: Expected O, but got Unknown
			//IL_0163: 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_01b3: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b8: Unknown result type (might be due to invalid IL or missing references)
			//IL_01bc: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c3: 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_01dc: Unknown result type (might be due to invalid IL or missing references)
			//IL_01e8: Unknown result type (might be due to invalid IL or missing references)
			Transform obj = clone.transform.Find("default");
			if (!Object.op_Implicit((Object)(object)obj))
			{
				throw new InvalidOperationException("Vanilla banner cloth is missing");
			}
			MeshFilter component = ((Component)obj).GetComponent<MeshFilter>();
			MeshRenderer component2 = ((Component)obj).GetComponent<MeshRenderer>();
			if (!Object.op_Implicit((Object)(object)component) || !Object.op_Implicit((Object)(object)component2) || !component.sharedMesh.isReadable)
			{
				throw new InvalidOperationException("Vanilla banner cloth cannot be textured");
			}
			Texture2D val = LoadTexture(spec.Key.ToLowerInvariant() + ".png");
			Mesh val2 = Object.Instantiate<Mesh>(component.sharedMesh);
			((Object)val2).name = spec.PrefabName + "_cloth";
			Vector3[] vertices = val2.vertices;
			Vector2[] array = (Vector2[])(object)new Vector2[vertices.Length];
			Bounds bounds = val2.bounds;
			for (int i = 0; i < vertices.Length; i++)
			{
				array[i] = new Vector2(Mathf.InverseLerp(((Bounds)(ref bounds)).min.z, ((Bounds)(ref bounds)).max.z, vertices[i].z), Mathf.InverseLerp(((Bounds)(ref bounds)).min.y, ((Bounds)(ref bounds)).max.y, vertices[i].y));
			}
			val2.uv = array;
			component.sharedMesh = val2;
			Material val3 = new Material(((Renderer)component2).sharedMaterial)
			{
				name = spec.PrefabName + "_cloth_mat"
			};
			val3.mainTexture = (Texture)(object)val;
			val3.mainTextureScale = Vector2.one;
			val3.mainTextureOffset = Vector2.zero;
			if (spec.Key == "Bonemass" || spec.Key == "Ashlands" || spec.Key == "Ravens")
			{
				Vector2 val4 = ClothHorizontalRange(val);
				val3.mainTextureScale = new Vector2(val4.y - val4.x, 1f);
				val3.mainTextureOffset = new Vector2(val4.x, 0f);
			}
			else
			{
				val3.SetFloat("_Cutoff", 0f);
			}
			if (val3.HasProperty("_BumpMap"))
			{
				val3.SetTexture("_BumpMap", (Texture)(object)Texture2D.normalTexture);
			}
			((Renderer)component2).sharedMaterial = val3;
			val.Apply(true, true);
		}

		private static Vector2 ClothHorizontalRange(Texture2D texture)
		{
			//IL_00c9: Unknown result type (might be due to invalid IL or missing references)
			Color32[] pixels = texture.GetPixels32();
			int num = ((Texture)texture).width;
			int num2 = -1;
			for (int i = 0; i < ((Texture)texture).width; i++)
			{
				int num3 = 0;
				for (int j = 0; j < ((Texture)texture).height; j++)
				{
					if (pixels[j * ((Texture)texture).width + i].a >= 128)
					{
						num3++;
					}
				}
				if (num3 > ((Texture)texture).height / 4)
				{
					num = Math.Min(num, i);
					num2 = Math.Max(num2, i);
				}
			}
			if (num2 < num)
			{
				throw new InvalidDataException("Banner image has no opaque cloth");
			}
			int num4 = Math.Max(1, ((Texture)texture).width / 100);
			return new Vector2((float)Math.Max(0, num - num4) / (float)((Texture)texture).width, (float)Math.Min(((Texture)texture).width, num2 + num4 + 1) / (float)((Texture)texture).width);
		}

		private static Texture2D LoadTexture(string filename)
		{
			using Stream stream = typeof(Plugin).Assembly.GetManifestResourceStream("ForsakenBanners." + filename);
			if (stream == null)
			{
				throw new FileNotFoundException("Embedded banner texture missing", filename);
			}
			using MemoryStream memoryStream = new MemoryStream();
			stream.CopyTo(memoryStream);
			Texture2D obj = AssetUtils.LoadImage(memoryStream.ToArray());
			if (!Object.op_Implicit((Object)(object)obj))
			{
				throw new InvalidDataException("Cannot decode " + filename);
			}
			((Object)obj).name = "FB_" + filename;
			((Texture)obj).wrapMode = (TextureWrapMode)1;
			((Texture)obj).filterMode = (FilterMode)1;
			((Texture)obj).anisoLevel = 2;
			return obj;
		}

		private void OnDestroy()
		{
			PrefabManager.OnVanillaPrefabsAvailable -= Register;
			harmony.UnpatchSelf();
			swampPiece = null;
		}
	}
	public sealed class BannerSpec
	{
		public readonly string Key;

		public readonly string Resource;

		public readonly string RussianName;

		public readonly string EnglishName;

		public readonly string RussianDescription;

		public readonly string EnglishDescription;

		public string PrefabName => "FB_Banner" + Key;

		public string NameKey => "fb_banner_" + Key.ToLowerInvariant();

		public string DescriptionKey => NameKey + "_description";

		public BannerSpec(string key, string resource, string ru, string en, string ruDescription, string enDescription)
		{
			Key = key;
			Resource = resource;
			RussianName = ru;
			EnglishName = en;
			RussianDescription = ruDescription;
			EnglishDescription = enDescription;
		}
	}
}