Decompiled source of UglyYuleSweaters v1.3.1

plugins/UglyYuleSweaters.dll

Decompiled 2 weeks ago
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Threading.Tasks;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using HarmonyLib;
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 = "")]
[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 UglyYuleSweaters
{
	internal enum Slot
	{
		Chest,
		Legs,
		Head
	}
	internal enum FestiveSet
	{
		None,
		UglyYule,
		Santa,
		Summer
	}
	internal class Req
	{
		public string Item;

		public int Amount;

		public int PerLevel;

		public Req(string item, int amount, int perLevel)
		{
			Item = item;
			Amount = amount;
			PerLevel = perLevel;
		}
	}
	internal class FestiveItem
	{
		public string PrefabName;

		public string BaseGroup;

		public string RecipeSource;

		public string DisplayName;

		public string Description;

		public FestivePattern Pattern;

		public Slot Slot;

		public bool IsSummer;

		public float ShadeStrength = 1f;

		public FestiveSet Set;

		public Req[] Recipe;
	}
	internal static class FestiveItems
	{
		internal static readonly List<FestiveItem> All = new List<FestiveItem>
		{
			new FestiveItem
			{
				PrefabName = "YD_UglySweaterSnowflake",
				Set = FestiveSet.UglyYule,
				BaseGroup = "Sweater Base",
				RecipeSource = "ArmorLeatherChest",
				DisplayName = "Ugly Sweater (Snowflake)",
				Description = "Knitted by a Dverger grandmother who has clearly never seen real snow. Itchy, warm, and loud.",
				Pattern = FestivePattern.Snowflake,
				Slot = Slot.Chest,
				Recipe = new Req[2]
				{
					new Req("LeatherScraps", 6, 2),
					new Req("Raspberry", 8, 0)
				}
			},
			new FestiveItem
			{
				PrefabName = "YD_UglySweaterTannenbaum",
				Set = FestiveSet.UglyYule,
				BaseGroup = "Sweater Base",
				RecipeSource = "ArmorLeatherChest",
				DisplayName = "Ugly Sweater (Tannenbaum)",
				Description = "Every Greydwarf in the Black Forest is offended by this sweater. Wear it proudly.",
				Pattern = FestivePattern.Tannenbaum,
				Slot = Slot.Chest,
				Recipe = new Req[3]
				{
					new Req("LeatherScraps", 6, 2),
					new Req("FirCone", 4, 0),
					new Req("Raspberry", 2, 0)
				}
			},
			new FestiveItem
			{
				PrefabName = "YD_UglySweaterCandyCane",
				Set = FestiveSet.UglyYule,
				BaseGroup = "Sweater Base",
				RecipeSource = "ArmorLeatherChest",
				DisplayName = "Ugly Sweater (Candy Cane)",
				Description = "Striped like the treats Odin hangs from the Yggdrasil branches. Do not lick.",
				Pattern = FestivePattern.CandyCane,
				Slot = Slot.Chest,
				Recipe = new Req[3]
				{
					new Req("LeatherScraps", 6, 2),
					new Req("Raspberry", 4, 0),
					new Req("Dandelion", 4, 0)
				}
			},
			new FestiveItem
			{
				PrefabName = "YD_UglySweaterSnowman",
				Set = FestiveSet.UglyYule,
				BaseGroup = "Sweater Base",
				RecipeSource = "ArmorLeatherChest",
				DisplayName = "Ugly Sweater (Snowman)",
				Description = "A row of jolly snowmen in top hats. Their coal eyes follow you around the longhouse.",
				Pattern = FestivePattern.Snowman,
				Slot = Slot.Chest,
				Recipe = new Req[3]
				{
					new Req("LeatherScraps", 6, 2),
					new Req("Dandelion", 4, 0),
					new Req("Coal", 2, 0)
				}
			},
			new FestiveItem
			{
				PrefabName = "YD_UglySweaterReindeer",
				Set = FestiveSet.UglyYule,
				BaseGroup = "Sweater Base",
				RecipeSource = "ArmorLeatherChest",
				DisplayName = "Ugly Sweater (Reindeer)",
				Description = "A herd of leaping reindeer, knitted from the very deer you hunted. The irony is festive.",
				Pattern = FestivePattern.Reindeer,
				Slot = Slot.Chest,
				Recipe = new Req[3]
				{
					new Req("LeatherScraps", 6, 2),
					new Req("DeerHide", 2, 0),
					new Req("Raspberry", 4, 0)
				}
			},
			new FestiveItem
			{
				PrefabName = "YD_FestivePantsCandyCane",
				Set = FestiveSet.UglyYule,
				BaseGroup = "Festive Pants Base",
				RecipeSource = "ArmorLeatherLegs",
				DisplayName = "Candy Cane Leggings",
				Description = "Red and white from hip to heel. The trolls will see you coming.",
				Pattern = FestivePattern.CandyCane,
				Slot = Slot.Legs,
				Recipe = new Req[3]
				{
					new Req("LeatherScraps", 6, 2),
					new Req("Raspberry", 4, 0),
					new Req("Dandelion", 4, 0)
				}
			},
			new FestiveItem
			{
				PrefabName = "YD_FestivePantsTartan",
				Set = FestiveSet.UglyYule,
				BaseGroup = "Festive Pants Base",
				RecipeSource = "ArmorLeatherLegs",
				DisplayName = "Yule Tartan Trousers",
				Description = "Holiday plaid, as worn by every uncle at every Yule feast since the dawn of Midgard.",
				Pattern = FestivePattern.Tartan,
				Slot = Slot.Legs,
				Recipe = new Req[3]
				{
					new Req("DeerHide", 3, 1),
					new Req("Raspberry", 4, 0),
					new Req("FirCone", 2, 0)
				}
			},
			new FestiveItem
			{
				PrefabName = "YD_KnittedYuleHat",
				Set = FestiveSet.UglyYule,
				BaseGroup = "Yule Hat Base",
				RecipeSource = "HelmetLeather",
				DisplayName = "Knitted Yule Hat",
				Description = "Craftable all year round, Midwinter be damned. Completes the ugly sweater set.",
				Pattern = FestivePattern.Snowflake,
				Slot = Slot.Head,
				Recipe = new Req[3]
				{
					new Req("LeatherScraps", 4, 1),
					new Req("Raspberry", 4, 0),
					new Req("Dandelion", 2, 0)
				}
			},
			new FestiveItem
			{
				PrefabName = "YD_SantaCoat",
				Set = FestiveSet.Santa,
				BaseGroup = "Santa Coat Base",
				RecipeSource = "ArmorLeatherChest",
				DisplayName = "Santa's Coat",
				Description = "Red velvet, white fur, one heroic belt. Somebody has to deliver the mead.",
				Pattern = FestivePattern.SantaCoat,
				Slot = Slot.Chest,
				Recipe = new Req[3]
				{
					new Req("LeatherScraps", 6, 2),
					new Req("Raspberry", 8, 0),
					new Req("DeerHide", 2, 0)
				}
			},
			new FestiveItem
			{
				PrefabName = "YD_SantaTrousers",
				Set = FestiveSet.Santa,
				BaseGroup = "Santa Trousers Base",
				RecipeSource = "ArmorLeatherLegs",
				DisplayName = "Santa's Trousers",
				Description = "Roomy in the middle. For the Yule feast that comes after.",
				Pattern = FestivePattern.SantaTrousers,
				Slot = Slot.Legs,
				Recipe = new Req[3]
				{
					new Req("LeatherScraps", 6, 2),
					new Req("Raspberry", 6, 0),
					new Req("DeerHide", 1, 0)
				}
			},
			new FestiveItem
			{
				PrefabName = "YD_SantaHat",
				Set = FestiveSet.Santa,
				BaseGroup = "Yule Hat Base",
				RecipeSource = "HelmetLeather",
				DisplayName = "Santa's Hat",
				Description = "The genuine Yule hat, available all year. Pom-pom included.",
				Pattern = FestivePattern.None,
				Slot = Slot.Head,
				Recipe = new Req[3]
				{
					new Req("LeatherScraps", 2, 1),
					new Req("Raspberry", 4, 0),
					new Req("Feathers", 2, 0)
				}
			},
			new FestiveItem
			{
				PrefabName = "YD_SummerShirtBondiSanta",
				Set = FestiveSet.Summer,
				BaseGroup = "Summer Shirt Base",
				RecipeSource = "ArmorLeatherChest",
				DisplayName = "Bondi Santa Shirt",
				Description = "Christmas lunch is prawns on the barbie and a swim at the beach. Dress accordingly.",
				Pattern = FestivePattern.BondiSanta,
				Slot = Slot.Chest,
				IsSummer = true,
				ShadeStrength = 0.35f,
				Recipe = new Req[3]
				{
					new Req("LeatherScraps", 4, 1),
					new Req("Raspberry", 4, 0),
					new Req("Dandelion", 4, 0)
				}
			},
			new FestiveItem
			{
				PrefabName = "YD_SummerShirtKoala",
				Set = FestiveSet.Summer,
				BaseGroup = "Summer Shirt Base",
				RecipeSource = "ArmorLeatherChest",
				DisplayName = "Christmas Koala Shirt",
				Description = "A koala in a Santa hat. He's been up the gum tree waiting for Santa since November.",
				Pattern = FestivePattern.Koala,
				Slot = Slot.Chest,
				IsSummer = true,
				ShadeStrength = 0.35f,
				Recipe = new Req[3]
				{
					new Req("LeatherScraps", 4, 1),
					new Req("Blueberries", 6, 0),
					new Req("Dandelion", 2, 0)
				}
			},
			new FestiveItem
			{
				PrefabName = "YD_SummerBoardiesBondiSanta",
				Set = FestiveSet.Summer,
				BaseGroup = "Boardies Base",
				RecipeSource = "ArmorLeatherLegs",
				DisplayName = "Bondi Santa Boardies",
				Description = "Kangaroos in Santa hats from waist to knee. Matches the shirt, as all good Christmas lunches should.",
				Pattern = FestivePattern.BondiSanta,
				Slot = Slot.Legs,
				IsSummer = true,
				ShadeStrength = 0.35f,
				Recipe = new Req[3]
				{
					new Req("LeatherScraps", 4, 1),
					new Req("Raspberry", 4, 0),
					new Req("Dandelion", 2, 0)
				}
			},
			new FestiveItem
			{
				PrefabName = "YD_SummerBoardiesKoala",
				Set = FestiveSet.Summer,
				BaseGroup = "Boardies Base",
				RecipeSource = "ArmorLeatherLegs",
				DisplayName = "Gum Leaf Boardies",
				Description = "Gum leaves from waist to knee. Matches the Christmas Koala Shirt, and smells faintly of eucalyptus.",
				Pattern = FestivePattern.Koala,
				Slot = Slot.Legs,
				IsSummer = true,
				ShadeStrength = 0.35f,
				Recipe = new Req[2]
				{
					new Req("LeatherScraps", 4, 1),
					new Req("Blueberries", 6, 0)
				}
			},
			new FestiveItem
			{
				PrefabName = "YD_SummerStrawHat",
				Set = FestiveSet.Summer,
				BaseGroup = "Summer Hat Base",
				RecipeSource = "HelmetLeather",
				DisplayName = "Sunburnt Santa's Straw Hat",
				Description = "Slip, slop, slap. Santa does his rounds at dawn down south, before the heat kicks in.",
				Pattern = FestivePattern.None,
				Slot = Slot.Head,
				IsSummer = true,
				Recipe = new Req[3]
				{
					new Req("Wood", 4, 1),
					new Req("Dandelion", 4, 0),
					new Req("Raspberry", 2, 0)
				}
			}
		};

		internal static readonly Dictionary<string, string> BaseDefaults = new Dictionary<string, string>
		{
			{ "Sweater Base", "ArmorPaddedCuirass, ArmorTunic1, ArmorLoxChest, ArmorLeatherChest" },
			{ "Festive Pants Base", "ArmorWolfLegs, ArmorLoxLegs, ArmorLeatherLegs" },
			{ "Yule Hat Base", "HelmetYule" },
			{ "Santa Coat Base", "ArmorFenringChest, ArmorLoxChest, ArmorLeatherChest" },
			{ "Santa Trousers Base", "ArmorWolfLegs, ArmorLoxLegs, ArmorLeatherLegs" },
			{ "Summer Shirt Base", "ArmorTunic1, ArmorRagsChest" },
			{ "Boardies Base", "ArmorWolfLegs, ArmorRagsLegs" },
			{ "Summer Hat Base", "HelmetStrawHat" }
		};

		private static readonly HashSet<string> FlatTunics = new HashSet<string> { "ArmorLeatherChest", "ArmorRagsChest" };

		private static readonly string[] BodyTexProps = new string[3] { "_ChestTex", "_LegsTex", "_MainTex" };

		private static GameObject _holder;

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

		private static readonly Dictionary<FestiveSet, SE_Stats> SetEffects = new Dictionary<FestiveSet, SE_Stats>();

		private static SkinnedMeshRenderer _bodyModel;

		private static MethodInfo _updateRegisters;

		private static bool _dumped;

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

		internal static IEnumerable<GameObject> Prefabs
		{
			get
			{
				foreach (FestiveItem item in All)
				{
					if (Clones.TryGetValue(item.PrefabName, out var value) && (Object)(object)value != (Object)null)
					{
						yield return value;
					}
				}
			}
		}

		internal static string SetName(FestiveSet set)
		{
			return "YD_" + set.ToString() + "Set";
		}

		internal static SE_Stats SetEffect(FestiveSet set)
		{
			//IL_0046: Unknown result type (might be due to invalid IL or missing references)
			//IL_0058: Unknown result type (might be due to invalid IL or missing references)
			//IL_0060: Unknown result type (might be due to invalid IL or missing references)
			//IL_0065: Unknown result type (might be due to invalid IL or missing references)
			if (SetEffects.TryGetValue(set, out var value) && (Object)(object)value != (Object)null)
			{
				return value;
			}
			value = ScriptableObject.CreateInstance<SE_Stats>();
			((Object)value).name = "SetEffect_YD_" + set;
			value.m_mods = new List<DamageModPair>
			{
				new DamageModPair
				{
					m_type = (DamageType)((set == FestiveSet.Summer) ? 32 : 64),
					m_modifier = (DamageModifier)1
				}
			};
			switch (set)
			{
			case FestiveSet.Summer:
				((StatusEffect)value).m_name = "Slip, Slop, Slap";
				((StatusEffect)value).m_tooltip = "Shirt, boardies and straw hat on, sunscreen slapped on. Resistant to Fire.";
				break;
			case FestiveSet.Santa:
				((StatusEffect)value).m_name = "Sleigh Ready";
				value.m_addMaxCarryWeight = Plugin.SantaCarryBonus.Value;
				((StatusEffect)value).m_tooltip = $"Full Santa suit. Resistant to Frost (no Freezing) and +{Plugin.SantaCarryBonus.Value} carry weight for the sack of presents.";
				break;
			default:
				((StatusEffect)value).m_name = "Holiday Cheer";
				((StatusEffect)value).m_tooltip = "Fully bundled up in Yule knitwear. Resistant to Frost: no Freezing in the Mountains.";
				break;
			}
			SetEffects[set] = value;
			return value;
		}

		internal static void EnsureClones(Func<string, GameObject> findSource)
		{
			bool flag = false;
			DateTime now = DateTime.Now;
			foreach (FestiveItem item in All)
			{
				if (Clones.TryGetValue(item.PrefabName, out var value) && (Object)(object)value != (Object)null)
				{
					continue;
				}
				ConfigEntry<string> value2;
				string text = (Plugin.Bases.TryGetValue(item.BaseGroup, out value2) ? value2.Value : BaseDefaults[item.BaseGroup]);
				GameObject val = null;
				string[] array = text.Split(',');
				for (int i = 0; i < array.Length; i++)
				{
					string text2 = array[i].Trim();
					if (text2.Length != 0)
					{
						val = findSource(text2);
						if ((Object)(object)val != (Object)null)
						{
							break;
						}
						Plugin.Log.LogInfo((object)(item.BaseGroup + ": '" + text2 + "' not in this game version, trying next"));
					}
				}
				if ((Object)(object)val == (Object)null)
				{
					Plugin.Log.LogWarning((object)(item.BaseGroup + ": none of [" + text + "] found, skipping " + item.PrefabName));
					continue;
				}
				Plugin.Log.LogInfo((object)(item.PrefabName + " built from " + ((Object)val).name));
				GameObject val2 = Object.Instantiate<GameObject>(val, Holder.transform, false);
				((Object)val2).name = item.PrefabName;
				try
				{
					Configure(val2, item, ((Object)val).name, findSource);
				}
				catch (Exception arg)
				{
					Plugin.Log.LogError((object)$"Failed to set up {item.PrefabName}: {arg}");
				}
				Clones[item.PrefabName] = val2;
				flag = true;
			}
			if (flag)
			{
				FestiveTextures.ReleaseAtlasCache();
				Plugin.Log.LogInfo((object)$"Festive armor knitted in {(DateTime.Now - now).TotalSeconds:F1} s.");
			}
		}

		private static void Configure(GameObject clone, FestiveItem def, string baseName, Func<string, GameObject> findSource)
		{
			//IL_04d4: Unknown result type (might be due to invalid IL or missing references)
			//IL_04d9: Unknown result type (might be due to invalid IL or missing references)
			//IL_04f1: Expected O, but got Unknown
			//IL_0a47: Unknown result type (might be due to invalid IL or missing references)
			//IL_0a4c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0a74: Expected O, but got Unknown
			ItemDrop component = clone.GetComponent<ItemDrop>();
			SharedData shared = component.m_itemData.m_shared;
			component.m_itemData.m_dropPrefab = clone;
			shared.m_name = def.DisplayName;
			shared.m_description = def.Description;
			shared.m_maxQuality = Plugin.MaxUpgradeLevel.Value;
			shared.m_armorPerLevel = Plugin.ArmorPerUpgrade.Value;
			switch (def.Slot)
			{
			case Slot.Chest:
				shared.m_armor = Plugin.ChestArmor.Value;
				break;
			case Slot.Legs:
				shared.m_armor = Plugin.LegsArmor.Value;
				break;
			default:
				shared.m_armor = Plugin.HatArmor.Value;
				break;
			}
			shared.m_setName = "";
			shared.m_setSize = 0;
			shared.m_setStatusEffect = null;
			shared.m_equipStatusEffect = null;
			shared.m_movementModifier = 0f;
			shared.m_damageModifiers = new List<DamageModPair>();
			if (def.Set != FestiveSet.None && Plugin.FullSetBonuses.Value)
			{
				if (Plugin.TimedSetBonuses.Value)
				{
					shared.m_description = def.Description + SetTimers.Describe(def.Set);
				}
				else
				{
					shared.m_setName = SetName(def.Set);
					shared.m_setSize = 3;
					shared.m_setStatusEffect = (StatusEffect)(object)SetEffect(def.Set);
				}
			}
			if (def.Slot == Slot.Chest && Plugin.HideTunicSkirt.Value && FlatTunics.Contains(baseName))
			{
				Transform val = clone.transform.Find("attach_skin");
				if ((Object)(object)val != (Object)null)
				{
					for (int num = val.childCount - 1; num >= 0; num--)
					{
						GameObject gameObject = ((Component)val.GetChild(num)).gameObject;
						Plugin.Log.LogInfo((object)(def.PrefabName + ": removed tunic part '" + ((Object)gameObject).name + "'"));
						Object.DestroyImmediate((Object)(object)gameObject);
					}
				}
			}
			if (!FestiveTextures.CanRender)
			{
				return;
			}
			if (def.Pattern == FestivePattern.None)
			{
				if (def.Set == FestiveSet.Santa)
				{
					MatchSantaRed(clone, shared);
				}
				if (def.Set != FestiveSet.None && shared.m_icons != null && shared.m_icons.Length != 0 && (Object)(object)((StatusEffect)SetEffect(def.Set)).m_icon == (Object)null)
				{
					((StatusEffect)SetEffect(def.Set)).m_icon = shared.m_icons[0];
				}
				return;
			}
			string text = ((def.Slot == Slot.Chest) ? "_ChestTex" : ((def.Slot == Slot.Legs) ? "_LegsTex" : null));
			bool num2 = def.Set == FestiveSet.UglyYule && def.Slot == Slot.Chest && Plugin.SweaterSleeves.Value;
			if (def.IsSummer && def.Slot != Slot.Head)
			{
				GameObject val2 = findSource((def.Slot == Slot.Chest) ? "ArmorRagsChest" : "ArmorRagsLegs");
				Material val3 = ((!((Object)(object)val2 != (Object)null)) ? null : val2.GetComponent<ItemDrop>()?.m_itemData.m_shared.m_armorMaterial);
				if ((Object)(object)val3 != (Object)null && val3.HasProperty(text))
				{
					shared.m_armorMaterial = val3;
				}
			}
			if (num2)
			{
				GameObject val4 = findSource("ArmorLeatherChest");
				Material val5 = ((!((Object)(object)val4 != (Object)null)) ? null : val4.GetComponent<ItemDrop>()?.m_itemData.m_shared.m_armorMaterial);
				if ((Object)(object)val5 != (Object)null && val5.HasProperty("_ChestTex"))
				{
					shared.m_armorMaterial = val5;
					Plugin.Log.LogInfo((object)(def.PrefabName + ": knitted sleeves from ArmorLeatherChest body paint"));
				}
			}
			if (text != null && ((Object)(object)shared.m_armorMaterial == (Object)null || !shared.m_armorMaterial.HasProperty(text)))
			{
				string text2 = ((def.Slot == Slot.Chest) ? "ArmorLeatherChest" : "ArmorLeatherLegs");
				GameObject val6 = findSource(text2);
				Material val7 = ((!((Object)(object)val6 != (Object)null)) ? null : val6.GetComponent<ItemDrop>()?.m_itemData.m_shared.m_armorMaterial);
				if ((Object)(object)shared.m_armorMaterial != (Object)null)
				{
					Plugin.Log.LogInfo((object)(def.PrefabName + ": base '" + baseName + "' has no " + text + " body paint, using " + text2 + "'s"));
				}
				shared.m_armorMaterial = (((Object)(object)val7 != (Object)null && val7.HasProperty(text)) ? val7 : null);
			}
			else if (text == null && (Object)(object)shared.m_armorMaterial != (Object)null && !shared.m_armorMaterial.HasProperty("_ChestTex"))
			{
				shared.m_armorMaterial = null;
			}
			if (def.IsSummer && def.Slot == Slot.Legs && baseName != "ArmorRagsLegs")
			{
				shared.m_armorMaterial = null;
				Plugin.Log.LogInfo((object)(def.PrefabName + ": no leg body paint, bare shins under the shorts"));
			}
			Texture val8 = null;
			if ((Object)(object)shared.m_armorMaterial != (Object)null)
			{
				Material val9 = new Material(shared.m_armorMaterial)
				{
					name = def.PrefabName + "_armor"
				};
				if (Plugin.KillGlow.Value)
				{
					RemoveGlow(val9);
				}
				string[] bodyTexProps = BodyTexProps;
				foreach (string text3 in bodyTexProps)
				{
					if (!val9.HasProperty(text3))
					{
						continue;
					}
					Texture texture = val9.GetTexture(text3);
					if (!((Object)(object)texture == (Object)null))
					{
						bool flag = def.Set == FestiveSet.UglyYule && def.Slot == Slot.Chest && Plugin.SweaterSleeves.Value;
						bool num3 = text3 == "_ChestTex" && (def.Pattern == FestivePattern.SantaCoat || flag);
						bool flag2 = Plugin.WrapPatterns.Value && (text3 == "_ChestTex" || text3 == "_LegsTex");
						SkinnedMeshRenderer regionMesh = ((num3 || flag2) ? BodyModel() : null);
						Garment garment = ((!num3) ? Garment.Plain : (flag ? Garment.BodySweater : Garment.BodyCoat));
						bool flag3 = false;
						if (flag3)
						{
							val8 = texture;
						}
						val9.SetTexture(text3, (Texture)(object)FestiveTextures.KnitTexture(texture, def.Pattern, 280, def.ShadeStrength, regionMesh, garment, def.PrefabName + " body", tileX2: false, tileY2: false, !flag3));
					}
				}
				shared.m_armorMaterial = val9;
			}
			if (shared.m_icons != null)
			{
				for (int j = 0; j < shared.m_icons.Length; j++)
				{
					float keepTop = ((def.IsSummer && def.Slot == Slot.Legs) ? 0.55f : 1f);
					try
					{
						shared.m_icons[j] = FestiveTextures.KnitIcon(shared.m_icons[j], def.Pattern, def.ShadeStrength, keepTop);
					}
					catch (Exception ex)
					{
						Plugin.Log.LogWarning((object)("Icon recolour failed for " + def.PrefabName + ", keeping vanilla icon: " + ex.Message));
					}
				}
				if (def.Slot == Slot.Head && def.Set != FestiveSet.None && shared.m_icons.Length != 0 && (Object)(object)((StatusEffect)SetEffect(def.Set)).m_icon == (Object)null)
				{
					((StatusEffect)SetEffect(def.Set)).m_icon = shared.m_icons[0];
				}
			}
			string[] array = Plugin.HideParts.Value.Split(new char[1] { ',' }, StringSplitOptions.RemoveEmptyEntries);
			List<string> list = new List<string>();
			Renderer[] componentsInChildren = clone.GetComponentsInChildren<Renderer>(true);
			foreach (Renderer val10 in componentsInChildren)
			{
				if ((Object)(object)((Component)val10).transform.parent == (Object)(object)clone.transform)
				{
					continue;
				}
				list.Add(((Object)val10).name);
				string[] bodyTexProps = array;
				for (int k = 0; k < bodyTexProps.Length; k++)
				{
					string text4 = bodyTexProps[k].Trim();
					if (text4.Length > 0 && ((Object)val10).name.IndexOf(text4, StringComparison.OrdinalIgnoreCase) >= 0)
					{
						val10.enabled = false;
						Plugin.Log.LogInfo((object)(def.PrefabName + ": hid part '" + ((Object)val10).name + "'"));
						break;
					}
				}
			}
			if (list.Count > 0)
			{
				Plugin.Log.LogInfo((object)(def.PrefabName + " (" + baseName + ") worn parts: " + string.Join(", ", list)));
			}
			Dictionary<Material, Material> dictionary = new Dictionary<Material, Material>();
			List<Renderer> list2 = new List<Renderer>(clone.GetComponentsInChildren<Renderer>(true));
			list2.Sort((Renderer a, Renderer b) => ((b is SkinnedMeshRenderer) ? 1 : 0) - ((a is SkinnedMeshRenderer) ? 1 : 0));
			bool flag4 = def.Pattern == FestivePattern.SantaCoat || def.Pattern == FestivePattern.SantaTrousers;
			bool flag5 = def.Set == FestiveSet.UglyYule && def.Slot == Slot.Chest && Plugin.CropSweaters.Value;
			bool flag6 = def.IsSummer && def.Slot != Slot.Head && !FlatTunics.Contains(baseName) && baseName != "ArmorRagsLegs";
			foreach (Renderer item in list2)
			{
				if (flag4)
				{
					List<string> list3 = new List<string>();
					Material[] sharedMaterials = item.sharedMaterials;
					foreach (Material val11 in sharedMaterials)
					{
						if ((Object)(object)val11 != (Object)null)
						{
							string name = ((Object)val11).name;
							Shader shader = val11.shader;
							list3.Add(string.Format("{0} [{1}] main={2}", name, (shader != null) ? ((Object)shader).name : null, val11.HasProperty("_MainTex")));
						}
					}
					Plugin.Log.LogInfo((object)(def.PrefabName + ": renderer '" + ((Object)item).name + "' (" + ((object)item).GetType().Name + ") materials: " + string.Join("; ", list3)));
				}
				bool flag7 = false;
				Material[] sharedMaterials2 = item.sharedMaterials;
				bool flag8 = false;
				for (int num4 = 0; num4 < sharedMaterials2.Length; num4++)
				{
					Material val12 = sharedMaterials2[num4];
					if ((Object)(object)val12 == (Object)null)
					{
						continue;
					}
					Material value = null;
					if (flag7 || !dictionary.TryGetValue(val12, out value))
					{
						value = null;
						string[] bodyTexProps = BodyTexProps;
						foreach (string text5 in bodyTexProps)
						{
							if (!val12.HasProperty(text5) || (Object)(object)val12.GetTexture(text5) == (Object)null)
							{
								continue;
							}
							if ((Object)(object)value == (Object)null)
							{
								value = new Material(val12)
								{
									name = "YD_UglyYule_" + def.Pattern.ToString() + "_mesh"
								};
							}
							SkinnedMeshRenderer val13 = (SkinnedMeshRenderer)(object)((flag4 || flag5 || flag6 || Plugin.WrapPatterns.Value) ? ((item is SkinnedMeshRenderer) ? item : null) : null);
							Garment garment2 = (flag5 ? Garment.Sweater : ((!flag6) ? ((!flag4) ? Garment.Plain : ((def.Slot == Slot.Legs) ? Garment.Trousers : Garment.Coat)) : ((def.Slot == Slot.Legs) ? Garment.Shorts : Garment.Shirt)));
							value.SetTexture(text5, (Texture)(object)FestiveTextures.KnitTexture(val12.GetTexture(text5), def.Pattern, 110, def.ShadeStrength, val13, garment2, def.PrefabName, flag7, flag7));
							if (flag7)
							{
								ClearOtherTextures(value, text5);
							}
							if ((flag5 || flag6) && (Object)(object)val13 != (Object)null)
							{
								bool flag9 = value.HasProperty("_Cutoff") || value.IsKeywordEnabled("_ALPHATEST_ON");
								if (value.HasProperty("_Cutoff") && value.GetFloat("_Cutoff") <= 0.01f)
								{
									value.SetFloat("_Cutoff", 0.5f);
								}
								ManualLogSource log = Plugin.Log;
								object[] obj = new object[4]
								{
									def.PrefabName,
									((Object)val12).name,
									null,
									null
								};
								Shader shader2 = val12.shader;
								obj[2] = ((shader2 != null) ? ((Object)shader2).name : null);
								obj[3] = flag9;
								log.LogInfo((object)string.Format("{0}: material '{1}' shader '{2}' alpha cut-out={3}", obj));
							}
						}
						if ((Object)(object)value != (Object)null && Plugin.KillGlow.Value)
						{
							RemoveGlow(value);
						}
						if (!flag7)
						{
							dictionary[val12] = value;
						}
					}
					if (!((Object)(object)value == (Object)null))
					{
						sharedMaterials2[num4] = value;
						flag8 = true;
					}
				}
				if (flag8)
				{
					item.sharedMaterials = sharedMaterials2;
				}
			}
			if ((Object)(object)val8 != (Object)null)
			{
				_ = Plugin.WrapPatterns.Value;
			}
			if (def.Set == FestiveSet.UglyYule && def.Slot == Slot.Chest && Plugin.SweaterSleeves.Value && Plugin.SleevePuffMm.Value > 0)
			{
				AddKnitSleeves(clone, def, shared.m_armorMaterial);
			}
		}

		private static void ClearOtherTextures(Material m, string keep)
		{
			//IL_0017: Unknown result type (might be due to invalid IL or missing references)
			//IL_001d: Invalid comparison between Unknown and I4
			Shader shader = m.shader;
			if ((Object)(object)shader == (Object)null)
			{
				return;
			}
			for (int i = 0; i < shader.GetPropertyCount(); i++)
			{
				if ((int)shader.GetPropertyType(i) == 4)
				{
					string propertyName = shader.GetPropertyName(i);
					if (!(propertyName == keep) && !((Object)(object)m.GetTexture(propertyName) == (Object)null))
					{
						m.SetTexture(propertyName, (Texture)null);
					}
				}
			}
		}

		private static void AddCrossShell(GameObject clone, FestiveItem def, Texture bodySrc)
		{
			//IL_00dd: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e2: Unknown result type (might be due to invalid IL or missing references)
			//IL_0121: Unknown result type (might be due to invalid IL or missing references)
			//IL_0126: Unknown result type (might be due to invalid IL or missing references)
			//IL_0133: Expected O, but got Unknown
			//IL_00c0: Unknown result type (might be due to invalid IL or missing references)
			//IL_0191: Unknown result type (might be due to invalid IL or missing references)
			SkinnedMeshRenderer val = BodyModel();
			if ((Object)(object)val == (Object)null)
			{
				return;
			}
			Material val2 = null;
			SkinnedMeshRenderer[] componentsInChildren = clone.GetComponentsInChildren<SkinnedMeshRenderer>(true);
			foreach (SkinnedMeshRenderer val3 in componentsInChildren)
			{
				if ((Object)(object)((Renderer)val3).sharedMaterial != (Object)null && ((Renderer)val3).sharedMaterial.HasProperty("_MainTex"))
				{
					val2 = ((Renderer)val3).sharedMaterial;
					break;
				}
			}
			if ((Object)(object)val2 == (Object)null)
			{
				Plugin.Log.LogWarning((object)(def.PrefabName + ": no shirt material for the Southern Cross shell"));
				return;
			}
			Mesh val4 = MeshRegions.TorsoShell(val, 0.006f, def.PrefabName);
			if (!((Object)(object)val4 == (Object)null))
			{
				Transform val5 = clone.transform.Find("attach_skin");
				if ((Object)(object)val5 == (Object)null)
				{
					val5 = new GameObject("attach_skin").transform;
					val5.SetParent(clone.transform, false);
				}
				GameObject val6 = new GameObject("YD_SouthernCrossShell");
				val6.transform.SetParent(val5, false);
				SkinnedMeshRenderer val7 = val6.AddComponent<SkinnedMeshRenderer>();
				val7.sharedMesh = val4;
				val7.bones = val.bones;
				val7.rootBone = val.rootBone;
				val7.updateWhenOffscreen = true;
				Material val8 = new Material(val2)
				{
					name = "YD_UglyYule_SouthernCross_shell"
				};
				Texture2D val9 = FestiveTextures.KnitTexture(bodySrc, def.Pattern, 280, def.ShadeStrength, val7, Garment.Plain, def.PrefabName + " shell", tileX2: true);
				val8.SetTexture("_MainTex", (Texture)(object)val9);
				ClearOtherTextures(val8, "_MainTex");
				if (val8.HasProperty("_Color"))
				{
					val8.SetColor("_Color", Color.white);
				}
				if (val8.HasProperty("_Cutoff"))
				{
					val8.SetFloat("_Cutoff", 0.5f);
				}
				if (Plugin.KillGlow.Value)
				{
					RemoveGlow(val8);
				}
				((Renderer)val7).sharedMaterial = val8;
				ManualLogSource log = Plugin.Log;
				string prefabName = def.PrefabName;
				Shader shader = val8.shader;
				log.LogInfo((object)(prefabName + ": Southern Cross drawn on a torso shell (shader '" + ((shader != null) ? ((Object)shader).name : null) + "')"));
			}
		}

		private static void AddKnitSleeves(GameObject clone, FestiveItem def, Material armorMat)
		{
			//IL_0058: Unknown result type (might be due to invalid IL or missing references)
			//IL_005d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0084: Expected O, but got Unknown
			//IL_0161: Unknown result type (might be due to invalid IL or missing references)
			//IL_0166: Unknown result type (might be due to invalid IL or missing references)
			//IL_0142: Unknown result type (might be due to invalid IL or missing references)
			SkinnedMeshRenderer val = BodyModel();
			if ((Object)(object)val == (Object)null || (Object)(object)armorMat == (Object)null || !armorMat.HasProperty("_ChestTex"))
			{
				return;
			}
			Mesh val2 = MeshRegions.PuffySleeves(val, Plugin.SleevePuffMm.Value, def.PrefabName);
			Material sharedMaterial = ((Renderer)val).sharedMaterial;
			if ((Object)(object)val2 == (Object)null || (Object)(object)sharedMaterial == (Object)null)
			{
				return;
			}
			Material val3 = new Material(sharedMaterial)
			{
				name = "YD_UglyYule_" + def.Pattern.ToString() + "_sleeves"
			};
			int num = 0;
			string[] array = new string[3] { "_ChestTex", "_ChestBumpMap", "_ChestMetal" };
			foreach (string text in array)
			{
				if (val3.HasProperty(text) && armorMat.HasProperty(text))
				{
					val3.SetTexture(text, armorMat.GetTexture(text));
					num++;
				}
			}
			if (num == 0)
			{
				ManualLogSource log = Plugin.Log;
				string prefabName = def.PrefabName;
				Shader shader = sharedMaterial.shader;
				log.LogWarning((object)(prefabName + ": body shader '" + ((shader != null) ? ((Object)shader).name : null) + "' has no _ChestTex, sleeves skipped"));
				return;
			}
			Transform val4 = clone.transform.Find("attach_skin");
			if ((Object)(object)val4 == (Object)null)
			{
				val4 = new GameObject("attach_skin").transform;
				val4.SetParent(clone.transform, false);
			}
			GameObject val5 = new GameObject("YD_KnitSleeves");
			val5.transform.SetParent(val4, false);
			SkinnedMeshRenderer obj = val5.AddComponent<SkinnedMeshRenderer>();
			obj.sharedMesh = val2;
			((Renderer)obj).sharedMaterial = val3;
			obj.bones = val.bones;
			obj.rootBone = val.rootBone;
			obj.updateWhenOffscreen = true;
			ManualLogSource log2 = Plugin.Log;
			string prefabName2 = def.PrefabName;
			object arg = Plugin.SleevePuffMm.Value;
			Shader shader2 = sharedMaterial.shader;
			log2.LogInfo((object)$"{prefabName2}: added knitted sleeves ({arg} mm bulk, shader '{((shader2 != null) ? ((Object)shader2).name : null)}')");
		}

		private static void MatchSantaRed(GameObject clone, SharedData shared)
		{
			//IL_0182: Unknown result type (might be due to invalid IL or missing references)
			//IL_004e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0053: Unknown result type (might be due to invalid IL or missing references)
			//IL_006c: Expected O, but got Unknown
			//IL_0088: Unknown result type (might be due to invalid IL or missing references)
			//IL_007a: Unknown result type (might be due to invalid IL or missing references)
			//IL_008d: 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_009d: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ba: Unknown result type (might be due to invalid IL or missing references)
			//IL_0111: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d0: Unknown result type (might be due to invalid IL or missing references)
			Dictionary<Material, Material> dictionary = new Dictionary<Material, Material>();
			Renderer[] componentsInChildren = clone.GetComponentsInChildren<Renderer>(true);
			foreach (Renderer val in componentsInChildren)
			{
				Material[] sharedMaterials = val.sharedMaterials;
				for (int j = 0; j < sharedMaterials.Length; j++)
				{
					Material val2 = sharedMaterials[j];
					if ((Object)(object)val2 == (Object)null)
					{
						continue;
					}
					if (!dictionary.TryGetValue(val2, out var value))
					{
						value = new Material(val2)
						{
							name = ((Object)val2).name + "_SantaRed"
						};
						Color val3 = (value.HasProperty("_Color") ? value.GetColor("_Color") : Color.white);
						if (val3.r > 0.15f && val3.r > val3.g * 1.5f && val3.r > val3.b * 1.5f)
						{
							value.SetColor("_Color", FestivePatterns.Velvet);
						}
						else if (value.HasProperty("_MainTex") && (Object)(object)value.GetTexture("_MainTex") != (Object)null)
						{
							value.SetTexture("_MainTex", (Texture)(object)FestiveTextures.RecolorTexture(value.GetTexture("_MainTex"), FestivePatterns.Velvet, "YD_UglyYule_SantaHat"));
						}
						RemoveGlow(value);
						dictionary[val2] = value;
					}
					sharedMaterials[j] = value;
				}
				val.sharedMaterials = sharedMaterials;
			}
			if (shared.m_icons != null)
			{
				for (int k = 0; k < shared.m_icons.Length; k++)
				{
					try
					{
						shared.m_icons[k] = FestiveTextures.RecolorIcon(shared.m_icons[k], FestivePatterns.Velvet);
					}
					catch (Exception ex)
					{
						Plugin.Log.LogWarning((object)("Santa hat icon recolour failed: " + ex.Message));
					}
				}
			}
			Plugin.Log.LogInfo((object)"YD_SantaHat: recoloured to Santa velvet red");
		}

		private static SkinnedMeshRenderer BodyModel()
		{
			if ((Object)(object)_bodyModel != (Object)null)
			{
				return _bodyModel;
			}
			VisEquipment[] array = Resources.FindObjectsOfTypeAll<VisEquipment>();
			foreach (VisEquipment val in array)
			{
				if (!((Object)(object)val == (Object)null) && !((Object)(object)((Component)val).GetComponent<Player>() == (Object)null))
				{
					SkinnedMeshRenderer value = Traverse.Create((object)val).Field("m_bodyModel").GetValue<SkinnedMeshRenderer>();
					if (!((Object)(object)value == (Object)null) && !((Object)(object)value.sharedMesh == (Object)null))
					{
						_bodyModel = value;
						Plugin.Log.LogInfo((object)("Body model for Santa's belt: '" + ((Object)value.sharedMesh).name + "' on '" + ((Object)val).name + "'"));
						break;
					}
				}
			}
			if ((Object)(object)_bodyModel == (Object)null)
			{
				Plugin.Log.LogWarning((object)"Couldn't find the player body model; Santa's belt on the chest is skipped");
			}
			return _bodyModel;
		}

		private static void RemoveGlow(Material m)
		{
			//IL_001e: Unknown result type (might be due to invalid IL or missing references)
			m.DisableKeyword("_EMISSION");
			if (m.HasProperty("_EmissionColor"))
			{
				m.SetColor("_EmissionColor", Color.black);
			}
			if (m.HasProperty("_EmissionMap"))
			{
				m.SetTexture("_EmissionMap", (Texture)null);
			}
			m.globalIlluminationFlags = (MaterialGlobalIlluminationFlags)4;
		}

		internal static void RegisterInObjectDB(ObjectDB db)
		{
			if ((Object)(object)db == (Object)null || db.m_items == null || db.m_items.Count == 0)
			{
				return;
			}
			if (Plugin.LogArmorBases.Value)
			{
				DumpArmorBases(db);
			}
			EnsureClones((string name) => db.GetItemPrefab(name));
			bool flag = false;
			foreach (GameObject prefab in Prefabs)
			{
				if (!db.m_items.Contains(prefab))
				{
					db.m_items.Add(prefab);
					flag = true;
				}
			}
			if (Plugin.FullSetBonuses.Value && db.m_StatusEffects != null)
			{
				FestiveSet[] array = new FestiveSet[2]
				{
					FestiveSet.UglyYule,
					FestiveSet.Santa
				};
				for (int num = 0; num < array.Length; num++)
				{
					SE_Stats item = SetEffect(array[num]);
					if (!db.m_StatusEffects.Contains((StatusEffect)(object)item))
					{
						db.m_StatusEffects.Add((StatusEffect)(object)item);
					}
				}
			}
			if (flag)
			{
				if (_updateRegisters == null)
				{
					_updateRegisters = AccessTools.Method(typeof(ObjectDB), "UpdateRegisters", (Type[])null, (Type[])null) ?? AccessTools.Method(typeof(ObjectDB), "UpdateItemHashes", (Type[])null, (Type[])null);
				}
				if (_updateRegisters != null)
				{
					_updateRegisters.Invoke(db, null);
				}
				else
				{
					Plugin.Log.LogError((object)"Couldn't find ObjectDB.UpdateRegisters — items won't resolve by hash.");
				}
			}
			foreach (FestiveItem item2 in All)
			{
				AddRecipe(db, item2);
			}
		}

		private static void DumpArmorBases(ObjectDB db)
		{
			//IL_006c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0071: Unknown result type (might be due to invalid IL or missing references)
			//IL_0073: Unknown result type (might be due to invalid IL or missing references)
			//IL_0076: Invalid comparison between Unknown and I4
			//IL_0078: Unknown result type (might be due to invalid IL or missing references)
			//IL_007c: Invalid comparison between Unknown and I4
			//IL_007e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0081: Invalid comparison between Unknown and I4
			//IL_00fc: Unknown result type (might be due to invalid IL or missing references)
			if (_dumped)
			{
				return;
			}
			_dumped = true;
			List<string> list = new List<string>();
			foreach (GameObject item in db.m_items)
			{
				if ((Object)(object)item == (Object)null || ((Object)item).name.StartsWith("YD_"))
				{
					continue;
				}
				ItemDrop component = item.GetComponent<ItemDrop>();
				if ((Object)(object)component == (Object)null)
				{
					continue;
				}
				ItemType itemType = component.m_itemData.m_shared.m_itemType;
				if ((int)itemType == 7 || (int)itemType == 11 || (int)itemType == 6)
				{
					int num = 0;
					int num2 = 0;
					Transform val = item.transform.Find("attach_skin");
					if ((Object)(object)val != (Object)null)
					{
						num = ((Component)val).GetComponentsInChildren<Renderer>(true).Length;
					}
					Transform val2 = item.transform.Find("attach");
					if ((Object)(object)val2 != (Object)null)
					{
						num2 = ((Component)val2).GetComponentsInChildren<Renderer>(true).Length;
					}
					string name = component.m_itemData.m_shared.m_name;
					list.Add($"{itemType,-7} {((Object)item).name,-32} {name,-30} 3D parts: skin={num} attach={num2}");
				}
			}
			list.Sort();
			Plugin.Log.LogInfo((object)("==== Armor bases (skin = cloth/fur meshes that add bulk) ====\n" + string.Join("\n", list)));
		}

		private static void AddRecipe(ObjectDB db, FestiveItem def)
		{
			//IL_00e6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00eb: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f8: Unknown result type (might be due to invalid IL or missing references)
			//IL_0105: Unknown result type (might be due to invalid IL or missing references)
			//IL_0112: Unknown result type (might be due to invalid IL or missing references)
			//IL_011e: Expected O, but got Unknown
			if (!Clones.TryGetValue(def.PrefabName, out var value) || (Object)(object)value == (Object)null)
			{
				return;
			}
			string recipeName = "Recipe_" + def.PrefabName;
			if (db.m_recipes.Exists((Recipe r) => (Object)(object)r != (Object)null && ((Object)r).name == recipeName))
			{
				return;
			}
			Recipe val = db.m_recipes.Find((Recipe r) => (Object)(object)r != (Object)null && (Object)(object)r.m_item != (Object)null && ((Object)r.m_item).name == def.RecipeSource);
			List<Requirement> list = new List<Requirement>();
			Req[] recipe = def.Recipe;
			foreach (Req req in recipe)
			{
				GameObject itemPrefab = db.GetItemPrefab(req.Item);
				if ((Object)(object)itemPrefab == (Object)null)
				{
					Plugin.Log.LogWarning((object)("Recipe ingredient '" + req.Item + "' not found for " + def.PrefabName));
					continue;
				}
				list.Add(new Requirement
				{
					m_resItem = itemPrefab.GetComponent<ItemDrop>(),
					m_amount = req.Amount,
					m_amountPerLevel = req.PerLevel,
					m_recover = true
				});
			}
			Recipe val2 = ScriptableObject.CreateInstance<Recipe>();
			((Object)val2).name = recipeName;
			val2.m_item = value.GetComponent<ItemDrop>();
			val2.m_amount = 1;
			val2.m_enabled = true;
			val2.m_craftingStation = (((Object)(object)val != (Object)null) ? val.m_craftingStation : null);
			val2.m_repairStation = (((Object)(object)val != (Object)null) ? val.m_repairStation : null);
			val2.m_minStationLevel = ((!((Object)(object)val != (Object)null)) ? 1 : val.m_minStationLevel);
			val2.m_resources = list.ToArray();
			db.m_recipes.Add(val2);
			if ((Object)(object)val == (Object)null)
			{
				Plugin.Log.LogWarning((object)("No vanilla recipe for '" + def.RecipeSource + "', " + def.PrefabName + " is craftable without a station"));
			}
		}

		internal static void RegisterInZNetScene(ZNetScene scene)
		{
			if ((Object)(object)scene == (Object)null || scene.m_prefabs == null)
			{
				return;
			}
			EnsureClones((string name) => scene.m_prefabs.Find((GameObject p) => (Object)(object)p != (Object)null && ((Object)p).name == name));
			Dictionary<int, GameObject> value = Traverse.Create((object)scene).Field("m_namedPrefabs").GetValue<Dictionary<int, GameObject>>();
			foreach (GameObject prefab in Prefabs)
			{
				if (!scene.m_prefabs.Contains(prefab))
				{
					scene.m_prefabs.Add(prefab);
				}
				int stableHashCode = StringExtensionMethods.GetStableHashCode(((Object)prefab).name);
				if (value != null && !value.ContainsKey(stableHashCode))
				{
					value[stableHashCode] = prefab;
				}
			}
		}
	}
	[HarmonyPatch(typeof(ObjectDB), "Awake")]
	internal static class ObjectDB_Awake_Patch
	{
		private static void Postfix(ObjectDB __instance)
		{
			FestiveItems.RegisterInObjectDB(__instance);
		}
	}
	[HarmonyPatch(typeof(ObjectDB), "CopyOtherDB")]
	internal static class ObjectDB_CopyOtherDB_Patch
	{
		private static void Postfix(ObjectDB __instance)
		{
			FestiveItems.RegisterInObjectDB(__instance);
		}
	}
	[HarmonyPatch(typeof(ZNetScene), "Awake")]
	internal static class ZNetScene_Awake_Patch
	{
		private static void Postfix(ZNetScene __instance)
		{
			FestiveItems.RegisterInZNetScene(__instance);
		}
	}
	public enum FestivePattern
	{
		Snowflake,
		Tannenbaum,
		CandyCane,
		Tartan,
		Snowman,
		Reindeer,
		BondiSanta,
		Koala,
		Boardies,
		SantaCoat,
		SantaTrousers,
		None
	}
	internal static class FestivePatterns
	{
		internal static readonly Color Red = new Color(0.72f, 0.07f, 0.09f);

		internal static readonly Color DarkRed = new Color(0.42f, 0.03f, 0.05f);

		internal static readonly Color Green = new Color(0.05f, 0.4f, 0.16f);

		internal static readonly Color DarkGreen = new Color(0.03f, 0.24f, 0.1f);

		internal static readonly Color White = new Color(0.95f, 0.93f, 0.88f);

		internal static readonly Color Gold = new Color(0.98f, 0.76f, 0.18f);

		internal static readonly Color Teal = new Color(0.02f, 0.55f, 0.58f);

		internal static readonly Color Navy = new Color(0.05f, 0.1f, 0.33f);

		internal static readonly Color SurfBlue = new Color(0.08f, 0.38f, 0.86f);

		internal static readonly Color Sand = new Color(0.96f, 0.84f, 0.5f);

		internal static readonly Color Trunk = new Color(0.45f, 0.27f, 0.12f);

		internal static readonly Color Leaf = new Color(0.2f, 0.72f, 0.22f);

		private static readonly string[] Snowflake9 = new string[9] { "....#....", ".#..#..#.", "..#.#.#..", "...###...", "#########", "...###...", "..#.#.#..", ".#..#..#.", "....#...." };

		private static readonly string[] Tree9 = new string[9] { "....*....", "...###...", "..#####..", "...###...", ".#######.", "..#####..", "#########", "....|....", "....|...." };

		private static readonly string[] Palm9 = new string[9] { ".gg...gg.", "g..g.g..g", "...ggg...", "..g.t.g..", "....t....", "....t....", "...t.....", "...t.....", ".sssssss." };

		private static readonly string[] SantaHat9 = new string[9] { "......ww.", "......ww.", ".....r...", "....rr...", "...rrr...", "..rrrr...", ".rrrrrr..", "wwwwwwwww", "wwwwwwwww" };

		private static readonly string[] Star5 = new string[5] { "..#..", ".###.", "#####", ".###.", "..#.." };

		private static readonly string[] Star3 = new string[3] { ".#.", "###", ".#." };

		private const int Period = 36;

		private const int ZoneTop = 7;

		private const int ZoneRows = 21;

		internal const int RowPeriod = 36;

		internal static bool ChestMotifs = true;

		private static readonly string[] HeroTree = new string[19]
		{
			"g", "gg", "g", "x", "xx", "xxx", "xx", "xxxx", "xxrx", "xxx",
			"xxxxx", "xxxxrx", "xxxxxxx", "xxxxx", "xrxxxxx", "xxxxxxxr", "xxxxxxxxxx", "t", "tt"
		};

		private static readonly string[] HeroSnowflake = new string[19]
		{
			"x", "xx.x", "x.x", "xx", "x.....x", "x.x.xx.x", "xx.x.xx", "x.x.x", "xxx..x", "xxxxxxxxx",
			"xxx..x", "x.x.x", "xx.x.xx", "x.x.xx.x", "x.....x", "xx", "x.x", "xx.x", "x"
		};

		private static readonly string[] HeroReindeer = new string[19]
		{
			"......x.x", ".....x.x..x", "......xx.x", "..x....xx", "...x...x", "....xxxx", ".....x", "xx..x", "xxxxxxx", "xxxxx",
			"xkxx", "xxxx", "xxxx", "xxx", "xxx", "xxx", "xxx", "rr", "rr"
		};

		private static readonly string[] HeroSnowman = new string[19]
		{
			"kk", "kk", "kk", "kk", "kkkkk", "www", "wwkw", "owww", "wwww", "www",
			"gggggg", "wwwggg", "kwwwwgg", "wwwwwwg", "kwwwwww", "wwwwwww", "kwwwwww", "wwwwww", "wwwww"
		};

		private static readonly string[] HeroBondi = new string[21]
		{
			"w..........k", "ww........kkk", "rr.......kkdkk", "rr......kkddkk", "rrr....kkdddk", "rrr...kkdddkk", "rrrr.kkdddkk", "rrrrkkdddkk", "wwwwwwkdkk", "wwwwwwkk",
			"kkkkkkk", "kkkkkk", "kkkekk", "kkkekk", "lkkkk", "lkkk", "llkk", "nnk", "nlk", "llk",
			"l"
		};

		private static readonly string[] Snowman11 = new string[14]
		{
			"....kkk....", "....kkk....", "...kkkkk...", "....www....", "...wkwkw...", "...wwoow...", "....www....", "...ggggg...", "..wwwwgww..", "..wwwkwww..",
			".wwwwwwwww.", ".wwwwkwwww.", ".wwwwwwwww.", "..wwwwwww.."
		};

		internal static readonly Color Carrot = new Color(0.95f, 0.45f, 0.08f);

		internal static readonly Color Coal = new Color(0.07f, 0.06f, 0.06f);

		private static readonly string[] Reindeer17 = new string[14]
		{
			"..x...x..........", "..x.x.x.x........", "...xxxxx.........", "....xxx..........", ".....xx..........", "....xxxx.........", "...xxxxx.........", "..xx..xxxxxxxxxx.", "......xxxxxxxxxxx", "......xxxxxxxxxxx",
			"......xxxxxxxxxx.", "......x.x.....x.x", "......x.x.....x.x", ".....x..x....x..x"
		};

		private static readonly string[] Roo15 = new string[19]
		{
			"......ww.......", "......rrr...kk.", ".....rrrr.kkk..", "....rrrrrkkk...", "...rrrrrrkk....", "..wwwwwwwkk....", "..kkkekkkk.....", "kkkkkkkkk......", "...kkkk........", ".....kkk.......",
			"..k.kkllk......", "..kkklllk......", "....klllkk.....", "....klllkk.....", "...kkklkkkk....", "...kkkkkkkk....", "....kkk.kkkkk..", "...kkk.....kkk.", "kkkkkk.......kk"
		};

		internal static readonly Color Roo = new Color(0.78f, 0.5f, 0.26f);

		internal static readonly Color RooEar = new Color(0.55f, 0.31f, 0.2f);

		internal static readonly Color RooBelly = new Color(0.93f, 0.77f, 0.55f);

		internal static readonly Color Board = new Color(0.98f, 0.85f, 0.3f);

		private static readonly string[] Star7 = new string[7] { "...#...", "..###..", "#######", ".#####.", "..###..", ".##.##.", "#.....#" };

		private static readonly string[] StarSmall5 = new string[5] { "..#..", ".###.", "#####", ".#.#.", "#...#" };

		private static readonly string[] HeroKoala = new string[21]
		{
			"w", "ww", "r", "rr", "rrr.......ggg", "rrr.....ggwwgg", "rrrr...gwwppwg", "rrrr..gwwpppwg", "WWWWWWgwwpppwg", "WWWWWWggwwppwg",
			"gggggggggwwgg", "ggggggggggg", "ggeegggggg", "ggeegggggg", "nggggggggg", "nnnggggggl", "nnnnggggl", "nnnngggll", "nnnggggl", "lggggl",
			"llll"
		};

		private static readonly string[] GumLeaf = new string[8] { "..L....", ".LL..L.", ".LL.LL.", "..LBLL.", "...B...", "..LB...", ".LLB...", ".LL...." };

		internal static readonly Color KoalaGrey = new Color(0.55f, 0.57f, 0.61f);

		internal static readonly Color KoalaLight = new Color(0.8f, 0.82f, 0.83f);

		internal static readonly Color KoalaPink = new Color(0.9f, 0.75f, 0.75f);

		internal static readonly Color GumLeafGreen = new Color(0.59f, 0.78f, 0.55f);

		private static readonly int[] Swell = new int[10] { 0, 1, 2, 2, 1, 0, -1, -2, -2, -1 };

		internal static readonly Color Black = new Color(0.06f, 0.05f, 0.05f);

		internal static readonly Color Fur = new Color(0.86f, 0.85f, 0.83f);

		internal static readonly Color FurShadow = new Color(0.74f, 0.74f, 0.76f);

		internal static readonly Color Velvet = new Color(0.78f, 0.04f, 0.06f);

		internal static readonly Color VelvetDark = new Color(0.64f, 0.03f, 0.05f);

		private static int Mod(int a, int m)
		{
			int num = a % m;
			if (num >= 0)
			{
				return num;
			}
			return num + m;
		}

		private static char Motif(string[] motif, int col, int rowFromTop)
		{
			if (rowFromTop < 0 || rowFromTop >= motif.Length)
			{
				return '.';
			}
			string text = motif[rowFromTop];
			if (col < 0 || col >= text.Length)
			{
				return '.';
			}
			return text[col];
		}

		private static bool Zigzag(int i, int r)
		{
			if (Mod(i + r, 4) != 0)
			{
				return Mod(i - r, 4) == 0;
			}
			return true;
		}

		private static Color Band(int i, int r, Color a, Color b)
		{
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_0011: Unknown result type (might be due to invalid IL or missing references)
			//IL_0020: 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)
			switch (r)
			{
			case 0:
			case 6:
				return a;
			case 1:
			case 5:
				return b;
			default:
				if (!Zigzag(i, r - 2))
				{
					return b;
				}
				return a;
			}
		}

		private static Color Zone(int i, int j, string[] hero, string[] small, int smallPeriod, Func<char, Color?> ink, Color bg, bool mirrorHero = true, int heroTop = -1)
		{
			//IL_0128: Unknown result type (might be due to invalid IL or missing references)
			//IL_0123: Unknown result type (might be due to invalid IL or missing references)
			//IL_00dc: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d6: Unknown result type (might be due to invalid IL or missing references)
			int num = Mod(j, 36);
			int num2 = Mathf.Abs(i);
			bool flag = ChestMotifs && j >= 0 && j < 36 && hero != null;
			int num3 = 0;
			if (flag)
			{
				foreach (string text in hero)
				{
					num3 = Mathf.Max(num3, mirrorHero ? (text.Length - 1) : (text.Length / 2));
				}
				int num4 = ((heroTop >= 0) ? heroTop : (7 + (21 - hero.Length) / 2));
				if (num2 <= num3 + 1)
				{
					int num5 = num - num4;
					int num6 = (mirrorHero ? num2 : (i + num3));
					if (num5 >= 0 && num5 < hero.Length && num6 >= 0 && num6 < hero[num5].Length)
					{
						Color? val = ink(hero[num5][num6]);
						if (val.HasValue)
						{
							return val.Value;
						}
					}
					return bg;
				}
			}
			int num7 = (flag ? (num3 + 2) : 0);
			int col = Mod(num2 - num7, smallPeriod) - 1;
			int num8 = 7 + (21 - small.Length) / 2;
			return (Color)(((??)ink(Motif(small, col, num - num8))) ?? bg);
		}

		internal static Color Stitch(FestivePattern pattern, int i, int j)
		{
			//IL_0032: Unknown result type (might be due to invalid IL or missing references)
			//IL_003a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0042: Unknown result type (might be due to invalid IL or missing references)
			//IL_004a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0052: Unknown result type (might be due to invalid IL or missing references)
			//IL_005a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0062: Unknown result type (might be due to invalid IL or missing references)
			//IL_006a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0072: Unknown result type (might be due to invalid IL or missing references)
			//IL_007a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0082: Unknown result type (might be due to invalid IL or missing references)
			return (Color)(pattern switch
			{
				FestivePattern.Snowflake => SnowflakeChart(i, j), 
				FestivePattern.Tannenbaum => TannenbaumChart(i, j), 
				FestivePattern.CandyCane => CandyCaneChart(i, j), 
				FestivePattern.Tartan => TartanChart(i, j), 
				FestivePattern.Snowman => SnowmanChart(i, j), 
				FestivePattern.Reindeer => ReindeerChart(i, j), 
				FestivePattern.BondiSanta => BondiSantaChart(i, j), 
				FestivePattern.Koala => KoalaChart(i, j), 
				FestivePattern.Boardies => BoardiesChart(i, j), 
				FestivePattern.SantaCoat => SantaCoatChart(i, j), 
				_ => SantaTrousersChart(i, j), 
			});
		}

		private static Color SnowmanChart(int i, int j)
		{
			//IL_000f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0014: Unknown result type (might be due to invalid IL or missing references)
			//IL_0019: Unknown result type (might be due to invalid IL or missing references)
			//IL_0043: Unknown result type (might be due to invalid IL or missing references)
			//IL_002e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0033: Unknown result type (might be due to invalid IL or missing references)
			//IL_0038: Unknown result type (might be due to invalid IL or missing references)
			//IL_0072: Unknown result type (might be due to invalid IL or missing references)
			//IL_0079: Unknown result type (might be due to invalid IL or missing references)
			int num = Mod(j, 36);
			if (num < 7)
			{
				return Band(i, num, White, Red);
			}
			if (num >= 28 && num < 35)
			{
				return Band(i, num - 28, White, Red);
			}
			if (num >= 35)
			{
				return Navy;
			}
			return Zone(i, j, HeroSnowman, Snowman11, 14, SnowmanInk, Navy);
		}

		private static Color? SnowmanInk(char c)
		{
			//IL_0033: Unknown result type (might be due to invalid IL or missing references)
			//IL_003e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0028: Unknown result type (might be due to invalid IL or missing references)
			//IL_001d: Unknown result type (might be due to invalid IL or missing references)
			return c switch
			{
				'k' => Coal, 
				'w' => White, 
				'o' => Carrot, 
				'g' => Green, 
				_ => null, 
			};
		}

		private static Color ReindeerChart(int i, int j)
		{
			//IL_000f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0014: Unknown result type (might be due to invalid IL or missing references)
			//IL_0019: Unknown result type (might be due to invalid IL or missing references)
			//IL_0043: Unknown result type (might be due to invalid IL or missing references)
			//IL_002e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0033: Unknown result type (might be due to invalid IL or missing references)
			//IL_0038: Unknown result type (might be due to invalid IL or missing references)
			//IL_0076: Unknown result type (might be due to invalid IL or missing references)
			//IL_007d: Unknown result type (might be due to invalid IL or missing references)
			int num = Mod(j, 36);
			if (num < 7)
			{
				return Band(i, num, White, Green);
			}
			if (num >= 28 && num < 35)
			{
				return Band(i, num - 28, White, Green);
			}
			if (num >= 35)
			{
				return DarkRed;
			}
			return Zone(i, j, HeroReindeer, Reindeer17, 20, (char c) => c switch
			{
				'r' => Red, 
				'k' => Coal, 
				'x' => White, 
				_ => null, 
			}, DarkRed);
		}

		private static Color SnowflakeChart(int i, int j)
		{
			//IL_000f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0014: Unknown result type (might be due to invalid IL or missing references)
			//IL_0019: Unknown result type (might be due to invalid IL or missing references)
			//IL_0043: Unknown result type (might be due to invalid IL or missing references)
			//IL_002e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0033: Unknown result type (might be due to invalid IL or missing references)
			//IL_0038: Unknown result type (might be due to invalid IL or missing references)
			//IL_0076: Unknown result type (might be due to invalid IL or missing references)
			//IL_007d: Unknown result type (might be due to invalid IL or missing references)
			int num = Mod(j, 36);
			if (num < 7)
			{
				return Band(i, num, White, Green);
			}
			if (num >= 28 && num < 35)
			{
				return Band(i, num - 28, White, Green);
			}
			if (num >= 35)
			{
				return Red;
			}
			return Zone(i, j, HeroSnowflake, Snowflake9, 12, (char c) => (c != 'x' && c != '#') ? ((Color?)null) : new Color?(White), Red);
		}

		private static Color TannenbaumChart(int i, int j)
		{
			//IL_000f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0014: Unknown result type (might be due to invalid IL or missing references)
			//IL_0019: Unknown result type (might be due to invalid IL or missing references)
			//IL_0043: Unknown result type (might be due to invalid IL or missing references)
			//IL_002e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0033: Unknown result type (might be due to invalid IL or missing references)
			//IL_0038: Unknown result type (might be due to invalid IL or missing references)
			//IL_0076: Unknown result type (might be due to invalid IL or missing references)
			//IL_007d: Unknown result type (might be due to invalid IL or missing references)
			int num = Mod(j, 36);
			if (num < 7)
			{
				return Band(i, num, Red, White);
			}
			if (num >= 28 && num < 35)
			{
				return Band(i, num - 28, Red, White);
			}
			if (num >= 35)
			{
				return Green;
			}
			return Zone(i, j, HeroTree, Tree9, 12, delegate(char c)
			{
				//IL_003e: Unknown result type (might be due to invalid IL or missing references)
				//IL_0049: Unknown result type (might be due to invalid IL or missing references)
				//IL_0033: Unknown result type (might be due to invalid IL or missing references)
				//IL_0054: Unknown result type (might be due to invalid IL or missing references)
				switch (c)
				{
				case '*':
				case 'g':
					return Gold;
				case '#':
				case 'x':
					return White;
				case 'r':
					return Red;
				case 't':
				case '|':
					return DarkRed;
				default:
					return (Color?)null;
				}
			}, Green);
		}

		private static Color CandyCaneChart(int i, int j)
		{
			//IL_0015: Unknown result type (might be due to invalid IL or missing references)
			//IL_0025: Unknown result type (might be due to invalid IL or missing references)
			//IL_001f: Unknown result type (might be due to invalid IL or missing references)
			int num = Mod((i + j) / 3, 8);
			if (Mod(num, 2) == 0)
			{
				return White;
			}
			if (num != 3)
			{
				return Red;
			}
			return Green;
		}

		private static Color TartanChart(int i, int j)
		{
			//IL_0021: Unknown result type (might be due to invalid IL or missing references)
			//IL_002c: Unknown result type (might be due to invalid IL or missing references)
			//IL_003c: Unknown result type (might be due to invalid IL or missing references)
			//IL_005c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0056: Unknown result type (might be due to invalid IL or missing references)
			int num = Mod(i, 16);
			int num2 = Mod(j, 16);
			bool flag = num < 4;
			bool flag2 = num2 < 4;
			if (flag && flag2)
			{
				return DarkRed;
			}
			if (flag || flag2)
			{
				return Red;
			}
			if (num == 9 || num2 == 9)
			{
				return White;
			}
			if ((num >= 11 && num < 14) || (num2 >= 11 && num2 < 14))
			{
				return DarkGreen;
			}
			return Green;
		}

		private static Color? BondiInk(char c)
		{
			//IL_009a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0084: Unknown result type (might be due to invalid IL or missing references)
			//IL_0079: Unknown result type (might be due to invalid IL or missing references)
			//IL_0063: Unknown result type (might be due to invalid IL or missing references)
			//IL_006e: Unknown result type (might be due to invalid IL or missing references)
			//IL_004d: 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_0058: Unknown result type (might be due to invalid IL or missing references)
			switch (c)
			{
			case 'r':
				return Red;
			case 'w':
				return White;
			case 'k':
				return Roo;
			case 'l':
				return RooBelly;
			case 'e':
			case 'n':
				return Coal;
			case 'd':
				return RooEar;
			case 's':
				return Board;
			case 'b':
				return Red;
			default:
				return null;
			}
		}

		private static Color BondiSantaChart(int i, int j)
		{
			//IL_0011: 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_002f: Unknown result type (might be due to invalid IL or missing references)
			//IL_005e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0065: Unknown result type (might be due to invalid IL or missing references)
			switch (Mod(j, 36))
			{
			case 0:
			case 35:
				return Red;
			case 1:
			case 34:
				return White;
			default:
				return Teal;
			case 2:
			case 3:
			case 4:
			case 5:
			case 6:
			case 7:
			case 8:
			case 9:
			case 10:
			case 11:
			case 12:
			case 13:
			case 14:
			case 15:
			case 16:
			case 17:
			case 18:
			case 19:
			case 20:
			case 21:
			case 22:
			case 23:
			case 24:
			case 25:
			case 26:
			case 27:
			case 28:
			case 29:
			case 30:
			case 31:
			case 32:
			case 33:
				return Zone(i, j, HeroBondi, Roo15, 18, BondiInk, Teal, mirrorHero: true, 3);
			}
		}

		private static bool Stamp(string[] m, int i, int j, int cx, int cy)
		{
			int num = m.Length / 2;
			return Motif(m, i - (cx - num), j - (cy - num)) == '#';
		}

		private static Color? KoalaInk(char c)
		{
			//IL_00ac: Unknown result type (might be due to invalid IL or missing references)
			//IL_006a: Unknown result type (might be due to invalid IL or missing references)
			//IL_008b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0080: Unknown result type (might be due to invalid IL or missing references)
			//IL_0096: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a1: Unknown result type (might be due to invalid IL or missing references)
			//IL_0075: Unknown result type (might be due to invalid IL or missing references)
			//IL_005f: Unknown result type (might be due to invalid IL or missing references)
			switch (c)
			{
			case 'g':
				return KoalaGrey;
			case 'l':
				return KoalaLight;
			case 'W':
			case 'w':
				return White;
			case 'p':
				return KoalaPink;
			case 'e':
			case 'n':
				return Coal;
			case 'r':
				return Red;
			case 'L':
				return GumLeafGreen;
			case 'B':
				return Trunk;
			default:
				return null;
			}
		}

		private static Color KoalaChart(int i, int j)
		{
			//IL_000c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0016: Unknown result type (might be due to invalid IL or missing references)
			//IL_0040: Unknown result type (might be due to invalid IL or missing references)
			//IL_002b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0030: Unknown result type (might be due to invalid IL or missing references)
			//IL_0035: Unknown result type (might be due to invalid IL or missing references)
			//IL_006f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0076: Unknown result type (might be due to invalid IL or missing references)
			int num = Mod(j, 36);
			switch (num)
			{
			case 0:
				return Red;
			case 1:
				return White;
			case 25:
			case 26:
			case 27:
			case 28:
			case 29:
			case 30:
			case 31:
				return Band(i, num - 25, White, Red);
			default:
				if (num >= 32)
				{
					return Green;
				}
				return Zone(i, j, HeroKoala, GumLeaf, 12, KoalaInk, Green, mirrorHero: true, 3);
			}
		}

		private static Color BoardiesChart(int i, int j)
		{
			//IL_0044: Unknown result type (might be due to invalid IL or missing references)
			//IL_004a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0050: Unknown result type (might be due to invalid IL or missing references)
			//IL_0056: Unknown result type (might be due to invalid IL or missing references)
			//IL_0062: Unknown result type (might be due to invalid IL or missing references)
			//IL_005c: Unknown result type (might be due to invalid IL or missing references)
			switch (Mod(j + Swell[Mod(i, 10)], 12))
			{
			case 0:
			case 1:
				return Red;
			case 2:
				return White;
			case 3:
			case 4:
				return Green;
			case 5:
				return White;
			case 8:
				return Teal;
			default:
				return SurfBlue;
			}
		}

		internal static Color RegionColor(Region r, int i, int j)
		{
			//IL_0039: Unknown result type (might be due to invalid IL or missing references)
			//IL_003f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0054: Unknown result type (might be due to invalid IL or missing references)
			//IL_0033: Unknown result type (might be due to invalid IL or missing references)
			//IL_002d: Unknown result type (might be due to invalid IL or missing references)
			//IL_005c: Unknown result type (might be due to invalid IL or missing references)
			switch (r)
			{
			case Region.Trim:
			case Region.BootTrim:
				if (Mod(i * 7 + j * 3, 5) != 0)
				{
					return Fur;
				}
				return FurShadow;
			case Region.Belt:
				return Black;
			case Region.Buckle:
				return Gold;
			case Region.Boot:
				return new Color(0.09f, 0.08f, 0.08f);
			default:
				return VelvetAt(i, j);
			}
		}

		internal static Color RibColor(FestivePattern p, int i)
		{
			//IL_0036: Unknown result type (might be due to invalid IL or missing references)
			//IL_003b: Unknown result type (might be due to invalid IL or missing references)
			//IL_002f: Unknown result type (might be due to invalid IL or missing references)
			//IL_006f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0045: Unknown result type (might be due to invalid IL or missing references)
			//IL_0051: Unknown result type (might be due to invalid IL or missing references)
			//IL_005d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0069: Unknown result type (might be due to invalid IL or missing references)
			//IL_0028: Unknown result type (might be due to invalid IL or missing references)
			//IL_0021: Unknown result type (might be due to invalid IL or missing references)
			//IL_001a: 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)
			Color val = (Color)(p switch
			{
				FestivePattern.CandyCane => Red, 
				FestivePattern.Snowflake => Green, 
				FestivePattern.Tannenbaum => Red, 
				FestivePattern.Snowman => Red, 
				FestivePattern.Reindeer => Green, 
				_ => DarkGreen, 
			});
			if (Mod(i, 2) != 0)
			{
				return new Color(val.r * 0.75f, val.g * 0.75f, val.b * 0.75f);
			}
			return val;
		}

		internal static Color SleeveColor(FestivePattern p, int j)
		{
			//IL_0020: Unknown result type (might be due to invalid IL or missing references)
			//IL_0025: Unknown result type (might be due to invalid IL or missing references)
			//IL_0026: Unknown result type (might be due to invalid IL or missing references)
			//IL_002b: Unknown result type (might be due to invalid IL or missing references)
			//IL_002e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0033: Unknown result type (might be due to invalid IL or missing references)
			//IL_0034: Unknown result type (might be due to invalid IL or missing references)
			//IL_0039: Unknown result type (might be due to invalid IL or missing references)
			//IL_003c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0041: Unknown result type (might be due to invalid IL or missing references)
			//IL_0042: Unknown result type (might be due to invalid IL or missing references)
			//IL_0047: Unknown result type (might be due to invalid IL or missing references)
			//IL_0066: Unknown result type (might be due to invalid IL or missing references)
			//IL_006b: Unknown result type (might be due to invalid IL or missing references)
			//IL_006c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0071: Unknown result type (might be due to invalid IL or missing references)
			//IL_004a: Unknown result type (might be due to invalid IL or missing references)
			//IL_004f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0050: Unknown result type (might be due to invalid IL or missing references)
			//IL_0055: Unknown result type (might be due to invalid IL or missing references)
			//IL_0058: Unknown result type (might be due to invalid IL or missing references)
			//IL_005d: Unknown result type (might be due to invalid IL or missing references)
			//IL_005e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0063: Unknown result type (might be due to invalid IL or missing references)
			//IL_007f: Unknown result type (might be due to invalid IL or missing references)
			//IL_007d: Unknown result type (might be due to invalid IL or missing references)
			Color result;
			Color result2;
			switch (p)
			{
			case FestivePattern.Snowflake:
				result = Red;
				result2 = White;
				break;
			case FestivePattern.Tannenbaum:
				result = Green;
				result2 = White;
				break;
			case FestivePattern.CandyCane:
				result = Red;
				result2 = White;
				break;
			case FestivePattern.Snowman:
				result = Navy;
				result2 = White;
				break;
			case FestivePattern.Reindeer:
				result = DarkRed;
				result2 = White;
				break;
			default:
				result = DarkGreen;
				result2 = Red;
				break;
			}
			if (Mod(j, 12) >= 2)
			{
				return result;
			}
			return result2;
		}

		internal static bool IsKnitted(FestivePattern p)
		{
			if (p != FestivePattern.SantaCoat)
			{
				return p != FestivePattern.SantaTrousers;
			}
			return false;
		}

		private static Color FurTrim(int i, int j)
		{
			//IL_0015: Unknown result type (might be due to invalid IL or missing references)
			//IL_000f: Unknown result type (might be due to invalid IL or missing references)
			if (Mod(i * 7 + j * 3, 5) != 0)
			{
				return Fur;
			}
			return FurShadow;
		}

		private static Color VelvetAt(int i, int j)
		{
			//IL_0016: Unknown result type (might be due to invalid IL or missing references)
			//IL_0010: Unknown result type (might be due to invalid IL or missing references)
			if (Mod(i * 3 + j * 5, 11) != 0)
			{
				return Velvet;
			}
			return VelvetDark;
		}

		private static Color SantaCoatChart(int i, int j)
		{
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			return VelvetAt(i, j);
		}

		private static Color SantaCoatChartOld(int i, int j)
		{
			//IL_0014: Unknown result type (might be due to invalid IL or missing references)
			//IL_0097: Unknown result type (might be due to invalid IL or missing references)
			//IL_008f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0069: Unknown result type (might be due to invalid IL or missing references)
			//IL_0063: Unknown result type (might be due to invalid IL or missing references)
			int num = Mod(j, 50);
			switch (num)
			{
			default:
				return FurTrim(i, j);
			case 22:
			case 23:
			case 24:
			case 25:
			case 26:
			{
				int num2 = Mod(i, 36);
				bool num3 = num2 >= 14 && num2 <= 21 && (num == 22 || num == 26 || num2 == 14 || num2 == 21);
				bool flag = num2 == 17 && num == 24;
				if (num3 || flag)
				{
					return Gold;
				}
				return Black;
			}
			case 5:
			case 6:
			case 7:
			case 8:
			case 9:
			case 10:
			case 11:
			case 12:
			case 13:
			case 14:
			case 15:
			case 16:
			case 17:
			case 18:
			case 19:
			case 20:
			case 21:
			case 27:
			case 28:
			case 29:
			case 30:
			case 31:
			case 32:
			case 33:
			case 34:
			case 35:
			case 36:
			case 37:
			case 38:
			case 39:
			case 40:
			case 41:
			case 42:
			case 43:
			case 44:
			case 45:
				if (Mod(i, 36) == 17 && (num == 12 || num == 18 || num == 32 || num == 38))
				{
					return Black;
				}
				return VelvetAt(i, j);
			}
		}

		private static Color SantaTrousersChart(int i, int j)
		{
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			return VelvetAt(i, j);
		}

		private static Color SantaTrousersChartOld(int i, int j)
		{
			//IL_000f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0022: Unknown result type (might be due to invalid IL or missing references)
			//IL_001a: Unknown result type (might be due to invalid IL or missing references)
			int num = Mod(j, 50);
			if (num < 6)
			{
				return FurTrim(i, j);
			}
			if (num < 9)
			{
				return Black;
			}
			return VelvetAt(i, j);
		}

		internal static float KnitShade(float u, float v)
		{
			float num = Mathf.Abs(u - 0.5f) * 2f;
			float num2 = Mathf.Repeat(v + num * 0.5f, 1f);
			float num3 = 1f - Mathf.Abs(num2 - 0.5f) * 2f;
			float num4 = ((Mathf.Abs(u - 0.5f) < 0.06f) ? 0.9f : 1f);
			return Mathf.Lerp(0.86f, 1.05f, num3) * num4;
		}
	}
	internal static class FestiveTextures
	{
		private static readonly Dictionary<string, Texture2D> TextureCache = new Dictionary<string, Texture2D>();

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

		private const int GridCells = 16;

		private static readonly Dictionary<char, int[]> Font = new Dictionary<char, int[]>
		{
			{
				'0',
				new int[5] { 7, 5, 5, 5, 7 }
			},
			{
				'1',
				new int[5] { 2, 6, 2, 2, 7 }
			},
			{
				'2',
				new int[5] { 7, 1, 7, 4, 7 }
			},
			{
				'3',
				new int[5] { 7, 1, 7, 1, 7 }
			},
			{
				'4',
				new int[5] { 5, 5, 7, 1, 1 }
			},
			{
				'5',
				new int[5] { 7, 4, 7, 1, 7 }
			},
			{
				'6',
				new int[5] { 7, 4, 7, 5, 7 }
			},
			{
				'7',
				new int[5] { 7, 1, 1, 1, 1 }
			},
			{
				'8',
				new int[5] { 7, 5, 7, 5, 7 }
			},
			{
				'9',
				new int[5] { 7, 5, 7, 1, 7 }
			},
			{
				'A',
				new int[5] { 2, 5, 7, 5, 5 }
			},
			{
				'B',
				new int[5] { 6, 5, 6, 5, 6 }
			},
			{
				'C',
				new int[5] { 7, 4, 4, 4, 7 }
			},
			{
				'D',
				new int[5] { 6, 5, 5, 5, 6 }
			},
			{
				'E',
				new int[5] { 7, 4, 6, 4, 7 }
			},
			{
				'F',
				new int[5] { 7, 4, 6, 4, 4 }
			},
			{
				'G',
				new int[5] { 7, 4, 5, 5, 7 }
			},
			{
				'H',
				new int[5] { 5, 5, 7, 5, 5 }
			},
			{
				'I',
				new int[5] { 7, 2, 2, 2, 7 }
			},
			{
				'J',
				new int[5] { 1, 1, 1, 5, 7 }
			},
			{
				'K',
				new int[5] { 5, 5, 6, 5, 5 }
			},
			{
				'L',
				new int[5] { 4, 4, 4, 4, 7 }
			},
			{
				'M',
				new int[5] { 5, 7, 7, 5, 5 }
			},
			{
				'N',
				new int[5] { 6, 5, 5, 5, 5 }
			},
			{
				'O',
				new int[5] { 7, 5, 5, 5, 7 }
			},
			{
				'P',
				new int[5] { 7, 5, 7, 4, 4 }
			}
		};

		private static readonly Color32[] GridColors = (Color32[])(object)new Color32[6]
		{
			new Color32((byte)230, (byte)60, (byte)60, byte.MaxValue),
			new Color32((byte)60, (byte)170, (byte)70, byte.MaxValue),
			new Color32((byte)60, (byte)110, (byte)230, byte.MaxValue),
			new Color32((byte)240, (byte)200, (byte)40, byte.MaxValue),
			new Color32((byte)200, (byte)80, (byte)220, byte.MaxValue),
			new Color32((byte)40, (byte)200, (byte)210, byte.MaxValue)
		};

		internal static bool CanRender => (int)SystemInfo.graphicsDeviceType != 4;

		private static Color32[] ReadPixels(Texture src)
		{
			return ReadPixels(src, src.width, src.height);
		}

		private static Color32[] ReadPixels(Texture src, int w, int h)
		{
			//IL_0022: Unknown result type (might be due to invalid IL or missing references)
			//IL_0027: Unknown result type (might be due to invalid IL or missing references)
			//IL_0036: Unknown result type (might be due to invalid IL or missing references)
			//IL_0042: Unknown result type (might be due to invalid IL or missing references)
			//IL_0055: Unknown result type (might be due to invalid IL or missing references)
			//IL_0061: Expected O, but got Unknown
			RenderTexture temporary = RenderTexture.GetTemporary(w, h, 0, (RenderTextureFormat)0, (RenderTextureReadWrite)0);
			RenderTexture active = RenderTexture.active;
			Graphics.Blit(src, temporary);
			RenderTexture.active = temporary;
			Texture2D val = new Texture2D(w, h, (TextureFormat)4, false);
			val.ReadPixels(new Rect(0f, 0f, (float)w, (float)h), 0, 0);
			val.Apply(false);
			RenderTexture.active = active;
			RenderTexture.ReleaseTemporary(temporary);
			Color32[] pixels = val.GetPixels32();
			Object.Destroy((Object)val);
			return pixels;
		}

		private static int StitchSize(int textureWidth, int stitchesAcross)
		{
			int num = Mathf.RoundToInt((float)textureWidth / (float)stitchesAcross * ((float)Plugin.PatternScale.Value / 100f));
			return Mathf.Max(2, num);
		}

		private static void Knit(Color32[] px, int w, int h, FestivePattern pattern, int stitch, float minShade, float shadeStrength, MeshMap map = null, bool broadShade = false, int offI = 0, int offJ = 0)
		{
			//IL_008d: Unknown result type (might be due to invalid IL or missing references)
			//IL_032f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0334: Unknown result type (might be due to invalid IL or missing references)
			bool hasMask = false;
			double num = 0.0;
			int num2 = 0;
			for (int i = 0; i < px.Length; i++)
			{
				if (px[i].a < 128)
				{
					hasMask = true;
					continue;
				}
				num += (double)Lum(px[i]);
				num2++;
			}
			float meanLum = ((num2 > 0) ? ((float)(num / (double)num2)) : 0.5f);
			if (meanLum < 0.02f)
			{
				meanLum = 0.02f;
			}
			byte[] regions = map?.Regions;
			float[] mapU = map?.PU;
			float[] mapV = map?.PV;
			bool flip = Plugin.FlipPatternVertically.Value;
			bool knitted = FestivePatterns.IsKnitted(pattern);
			bool grid = Plugin.DebugUvGrid.Value;
			bool furTrim = pattern == FestivePattern.SantaCoat && Plugin.SantaFurFromBase.Value;
			float furCut = meanLum * 1.45f;
			float inv = 1f / (float)stitch;
			float[] broad = (broadShade ? BroadLum(px, w, h, meanLum) : null);
			int iMin = offI;
			int iMax = (w - 1) / stitch + offI;
			int jMin = offJ;
			int jMax = (h - 1) / stitch + offJ;
			if (mapU != null)
			{
				for (int j = 0; j < mapU.Length; j++)
				{
					float num3 = mapU[j];
					if (!float.IsNaN(num3))
					{
						int num4 = Mathf.FloorToInt(num3 + 0.5f);
						int num5 = Mathf.FloorToInt(mapV[j]);
						if (num4 < iMin)
						{
							iMin = num4;
						}
						if (num4 > iMax)
						{
							iMax = num4;
						}
						if (num5 < jMin)
						{
							jMin = num5;
						}
						if (num5 > jMax)
						{
							jMax = num5;
						}
					}
				}
			}
			int tw = iMax - iMin + 1;
			int num6 = jMax - jMin + 1;
			Color[] table = null;
			if ((long)tw * (long)num6 <= 4000000)
			{
				table = (Color[])(object)new Color[tw * num6];
				for (int k = 0; k < num6; k++)
				{
					for (int l = 0; l < tw; l++)
					{
						table[k * tw + l] = FestivePatterns.Stitch(pattern, l + iMin, k + jMin);
					}
				}
			}
			Parallel.For(0, h, delegate(int y)
			{
				//IL_004b: Unknown result type (might be due to invalid IL or missing references)
				//IL_0050: Unknown result type (might be due to invalid IL or missing references)
				//IL_0079: Unknown result type (might be due to invalid IL or missing references)
				//IL_009f: Unknown result type (might be due to invalid IL or missing references)
				//IL_014e: Unknown result type (might be due to invalid IL or missing references)
				//IL_0155: Unknown result type (might be due to invalid IL or missing references)
				//IL_015a: Unknown result type (might be due to invalid IL or missing references)
				//IL_0187: Unknown result type (might be due to invalid IL or missing references)
				//IL_018e: Unknown result type (might be due to invalid IL or missing references)
				//IL_0195: Unknown result type (might be due to invalid IL or missing references)
				//IL_019d: Unknown result type (might be due to invalid IL or missing references)
				//IL_01a2: Unknown result type (might be due to invalid IL or missing references)
				//IL_01b9: Unknown result type (might be due to invalid IL or missing references)
				//IL_01be: Unknown result type (might be due to invalid IL or missing references)
				//IL_01cd: Unknown result type (might be due to invalid IL or missing references)
				//IL_01d2: Unknown result type (might be due to invalid IL or missing references)
				//IL_01e4: Unknown result type (might be due to invalid IL or missing references)
				//IL_01e9: Unknown result type (might be due to invalid IL or missing references)
				//IL_0233: Unknown result type (might be due to invalid IL or missing references)
				//IL_01f8: Unknown result type (might be due to invalid IL or missing references)
				//IL_01fd: Unknown result type (might be due to invalid IL or missing references)
				//IL_021d: Unknown result type (might be due to invalid IL or missing references)
				//IL_0209: Unknown result type (might be due to invalid IL or missing references)
				//IL_0229: Unknown result type (might be due to invalid IL or missing references)
				//IL_0224: Unknown result type (might be due to invalid IL or missing references)
				//IL_0293: Unknown result type (might be due to invalid IL or missing references)
				//IL_02b3: Unknown result type (might be due to invalid IL or missing references)
				//IL_02d3: Unknown result type (might be due to invalid IL or missing references)
				//IL_02f3: 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_02ff: Unknown result type (might be due to invalid IL or missing references)
				int num7 = (flip ? y : (h - 1 - y));
				int num8 = num7 / stitch;
				float num9 = (float)(num7 % stitch) * inv;
				for (int m = 0; m < w; m++)
				{
					int num10 = y * w + m;
					Color32 val = px[num10];
					byte b = (byte)((regions != null) ? regions[num10] : 0);
					if (b == 9 || b == 10 || (b == 7 && val.a < 8))
					{
						val.a = byte.MaxValue;
					}
					if (!hasMask || val.a >= 8)
					{
						int num11 = m / stitch + offI;
						float u = (float)(m % stitch) * inv;
						int num12 = num8 + offJ;
						float v = num9;
						if (mapU != null && !float.IsNaN(mapU[num10]))
						{
							float num13 = mapU[num10] + 0.5f;
							num11 = Mathf.FloorToInt(num13);
							u = num13 - (float)num11;
							num12 = Mathf.FloorToInt(mapV[num10]);
							v = mapV[num10] - (float)num12;
						}
						if (grid)
						{
							px[num10] = GridPixel(m, num7, w, h, val.a);
						}
						else
						{
							byte b2 = (byte)((regions != null) ? regions[num10] : 0);
							if (b2 == 8)
							{
								px[num10] = new Color32(val.r, val.g, val.b, (byte)0);
							}
							else
							{
								Color val2 = ((b2 == 7) ? FestivePatterns.RibColor(pattern, num11) : ((b2 == 9) ? Chart(num11, num12) : ((b2 == 10) ? FestivePatterns.SleeveColor(pattern, num12) : ((b2 <= 1) ? ((furTrim && Lum(val) > furCut) ? FestivePatterns.Fur : Chart(num11, num12)) : FestivePatterns.RegionColor((Region)b2, num11, num12)))));
								float num14 = ((broad != null) ? broad[num10] : (Lum(val) / meanLum));
								float num15 = Mathf.Lerp(1f, Mathf.Clamp(num14, minShade, 1.25f), shadeStrength) * (knitted ? FestivePatterns.KnitShade(u, v) : 1f);
								px[num10] = new Color32((byte)Mathf.Clamp(val2.r * num15 * 255f, 0f, 255f), (byte)Mathf.Clamp(val2.g * num15 * 255f, 0f, 255f), (byte)Mathf.Clamp(val2.b * num15 * 255f, 0f, 255f), val.a);
							}
						}
					}
				}
			});
			Color Chart(int ci, int cj)
			{
				//IL_0034: Unknown result type (might be due to invalid IL or missing references)
				//IL_0058: Unknown result type (might be due to invalid IL or missing references)
				if (table == null || ci < iMin || ci > iMax || cj < jMin || cj > jMax)
				{
					return FestivePatterns.Stitch(pattern, ci, cj);
				}
				return table[(cj - jMin) * tw + (ci - iMin)];
			}
		}

		private static float[] BroadLum(Color32[] px, int w, int h, float meanLum)
		{
			//IL_00a0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00da: Unknown result type (might be due to invalid IL or missing references)
			int cw = Mathf.Max(1, w / 48);
			int ch = Mathf.Max(1, h / 48);
			int gw = (w + cw - 1) / cw;
			int gh = (h + ch - 1) / ch;
			float[] array = new float[gw * gh];
			int[] array2 = new int[gw * gh];
			for (int i = 0; i < h; i++)
			{
				for (int j = 0; j < w; j++)
				{
					Color32 val = px[i * w + j];
					if (val.a >= 128)
					{
						int num = i / ch * gw + j / cw;
						array[num] += Lum(val);
						array2[num]++;
					}
				}
			}
			float[] cell = new float[gw * gh];
			for (int k = 0; k < cell.Length; k++)
			{
				cell[k] = ((array2[k] > 0) ? (array[k] / (float)array2[k] / meanLum) : 1f);
			}
			float[] outv = new float[w * h];
			Parallel.For(0, h, delegate(int y)
			{
				float num2 = Mathf.Clamp(((float)y + 0.5f) / (float)ch - 0.5f, 0f, (float)(gh - 1));
				int num3 = (int)num2;
				int num4 = Mathf.Min(gh - 1, num3 + 1);
				float num5 = num2 - (float)num3;
				for (int l = 0; l < w; l++)
				{
					float num6 = Mathf.Clamp(((float)l + 0.5f) / (float)cw - 0.5f, 0f, (float)(gw - 1));
					int num7 = (int)num6;
					int num8 = Mathf.Min(gw - 1, num7 + 1);
					float num9 = num6 - (float)num7;
					float num10 = Mathf.Lerp(cell[num3 * gw + num7], cell[num3 * gw + num8], num9);
					float num11 = Mathf.Lerp(cell[num4 * gw + num7], cell[num4 * gw + num8], num9);
					outv[y * w + l] = Mathf.Lerp(num10, num11, num5);
				}
			});
			return outv;
		}

		private static Color32 GridPixel(int x, int rowFromTop, int w, int h, byte alpha)
		{
			//IL_0049: Unknown result type (might be due to invalid IL or missing references)
			//IL_016e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0173: Unknown result type (might be due to invalid IL or missing references)
			//IL_0175: Unknown result type (might be due to invalid IL or missing references)
			//IL_017c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0183: Unknown result type (might be due to invalid IL or missing references)
			//IL_018c: 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_014b: Unknown result type (might be due to invalid IL or missing references)
			int num = Mathf.Max(1, w / 16);
			int num2 = Mathf.Max(1, h / 16);
			int num3 = Mathf.Min(15, x / num);
			int num4 = Mathf.Min(15, rowFromTop / num2);
			int num5 = x - num3 * num;
			int num6 = rowFromTop - num4 * num2;
			if (num5 < 2 || num6 < 2)
			{
				return new Color32((byte)0, (byte)0, (byte)0, alpha);
			}
			string text = ((char)(65 + num3)).ToString() + (num4 + 1);
			int num7 = Mathf.Max(1, num / 16);
			int num8 = 4 * num7;
			int num9 = text.Length * num8 - num7;
			int num10 = 5 * num7;
			int num11 = (num - num9) / 2;
			int num12 = (num2 - num10) / 2;
			int num13 = num5 - num11;
			int num14 = num6 - num12;
			if (num13 >= -num7 && num14 >= -num7 && num13 < num9 + num7 && num14 < num10 + num7)
			{
				if (num13 >= 0 && num14 >= 0 && num13 < num9 && num14 < num10)
				{
					int index = num13 / num8;
					int num15 = num13 % num8 / num7;
					int num16 = num14 / num7;
					if (num15 < 3 && Font.TryGetValue(text[index], out var value) && ((value[num16] >> 2 - num15) & 1) == 1)
					{
						return new Color32(byte.MaxValue, byte.MaxValue, byte.MaxValue, alpha);
					}
				}
				return new Color32((byte)0, (byte)0, (byte)0, alpha);
			}
			Color32 val = GridColors[(num3 + num4 * 2) % GridColors.Length];
			return new Color32(val.r, val.g, val.b, alpha);
		}

		private static float Lum(Color32 c)
		{
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			//IL_0012: Unknown result type (might be due to invalid IL or missing references)
			//IL_0020: Unknown result type (might be due to invalid IL or missing references)
			return (0.299f * (float)(int)c.r + 0.587f * (float)(int)c.g + 0.114f * (float)(int)c.b) / 255f;
		}

		internal static Texture2D KnitTexture(Texture src, FestivePattern pattern, int stitchesAcross, float shadeStrength, SkinnedMeshRenderer regionMesh = null, Garment garment = Garment.Coat, string label = null, bool tileX2 = false, bool tileY2 = false, bool chestMotifs = true)
		{
			//IL_0272: Unknown result type (might be due to invalid IL or missing references)
			//IL_0277: Unknown result type (might be due to invalid IL or missing references)
			//IL_029a: Unknown result type (might be due to invalid IL or missing references)
			//IL_029c: 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_02a8: Unknown result type (might be due to invalid IL or missing references)
			//IL_02b2: Unknown result type (might be due to invalid IL or missing references)
			//IL_02c0: Expected O, but got Unknown
			//IL_0351: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)src == (Object)null)
			{
				return null;
			}
			string key = $"{((Object)src).GetInstanceID()}_{tileX2}_{tileY2}_{chestMotifs}_{pattern}_{stitchesAcross}_{shadeStrength:F2}_{Plugin.DebugUvGrid.Value}_{(((Object)(object)regionMesh != (Object)null && (Object)(object)regionMesh.sharedMesh != (Object)null) ? ((Object)regionMesh.sharedMesh).GetInstanceID() : 0)}_{garment}";
			if (TextureCache.TryGetValue(key, out var value) && (Object)(object)value != (Object)null)
			{
				return value;
			}
			Stopwatch stopwatch = Stopwatch.StartNew();
			int num = src.width;
			int num2 = src.height;
			if ((Object)(object)regionMesh != (Object)null && Mathf.Max(num, num2) > 64)
			{
				int value2 = Plugin.TextureSize.Value;
				while (Mathf.Max(tileX2 ? (num * 2) : num, tileY2 ? (num2 * 2) : num2) * 2 <= value2)
				{
					num *= 2;
					num2 *= 2;
				}
			}
			Color32[] array = ReadPixels(src, num, num2);
			if (tileX2 || tileY2)
			{
				int num3 = ((!tileX2) ? 1 : 2);
				int num4 = ((!tileY2) ? 1 : 2);
				Color32[] array2 = (Color32[])(object)new Color32[num * num3 * num2 * num4];
				for (int i = 0; i < num4; i++)
				{
					for (int j = 0; j < num2; j++)
					{
						for (int k = 0; k < num3; k++)
						{
							Array.Copy(array, j * num, array2, (i * num2 + j) * num * num3 + k * num, num);
						}
					}
				}
				array = array2;
				num *= num3;
				num2 *= num4;
			}
			MeshMap map = null;
			if ((Object)(object)regionMesh != (Object)null && !Plugin.DebugUvGrid.Value)
			{
				try
				{
					map = MeshRegions.Build(regionMesh, garment, num, num2, label ?? pattern.ToString());
				}
				catch (Exception ex)
				{
					Plugin.Log.LogWarning((object)("Region map failed for " + label + ": " + ex.Message));
				}
			}
			FestivePatterns.ChestMotifs = chestMotifs && garment != Garment.Trousers && garment != Garment.Shorts;
			try
			{
				Knit(array, num, num2, pattern, StitchSize(num, stitchesAcross), 0.5f, shadeStrength, map, broadShade: true);
			}
			finally
			{
				FestivePatterns.ChestMotifs = true;
			}
			Texture2D val = new Texture2D(num, num2, (TextureFormat)4, true)
			{
				name = $"YD_UglyYule_{pattern}_{num}x{num2}",
				wrapMode = src.wrapMode,
				filterMode = src.filterMode,
				anisoLevel = src.anisoLevel
			};
			val.SetPixels32(array);
			val.Apply(true, false);
			if (num >= 1024 && num % 4 == 0 && num2 % 4 == 0 && SystemInfo.SupportsTextureFormat((TextureFormat)12))
			{
				val.Compress(false);
			}
			val.Apply(false, true);
			if ((Object)(object)regionMesh != (Object)null)
			{
				Plugin.Log.LogInfo((object)$"{label}: knitted at {num}x{num2} (source {src.width}x{src.height}), {val.format} in {stopwatch.ElapsedMilliseconds} ms");
			}
			TextureCache[key] = val;
			return val;
		}

		internal static Sprite KnitIcon(Sprite icon, FestivePattern pattern, float shadeStrength, float keepTop = 1f)
		{
			//IL_004a: Unknown result type (might be due to invalid IL or missing references)
			//IL_004f: 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_013b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0151: Unknown result type (might be due to invalid IL or missing references)
			//IL_0158: Unknown result type (might be due to invalid IL or missing references)
			//IL_0161: Expected O, but got Unknown
			//IL_0185: Unknown result type (might be due to invalid IL or missing references)
			//IL_0194: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bb: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c0: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)icon == (Object)null || (Object)(object)icon.texture == (Object)null)
			{
				return icon;
			}
			Texture2D texture = icon.texture;
			int instanceID = ((Object)texture).GetInstanceID();
			if (!AtlasCache.TryGetValue(instanceID, out var value))
			{
				value = ReadPixels((Texture)(object)texture);
				AtlasCache[instanceID] = value;
			}
			Rect textureRect = icon.textureRect;
			int num = Mathf.RoundToInt(((Rect)(ref textureRect)).x);
			int num2 = Mathf.RoundToInt(((Rect)(ref textureRect)).y);
			int num3 = Mathf.RoundToInt(((Rect)(ref textureRect)).width);
			int num4 = Mathf.RoundToInt(((Rect)(ref textureRect)).height);
			Color32[] array = (Color32[])(object)new Color32[num3 * num4];
			for (int i = 0; i < num4; i++)
			{
				for (int j = 0; j < num3; j++)
				{
					array[i * num3 + j] = value[(num2 + i) * ((Texture)texture).width + (num + j)];
				}
			}
			int num5 = Mathf.Max(2, Mathf.RoundToInt((float)num3 / 22f));
			Knit(array, num3, num4, pattern, num5, 0.2f, Mathf.Max(0.7f, shadeStrength), null, broadShade: false, -(num3 / num5) / 2, 7);
			if (keepTop < 1f)
			{
				CropBelow(array, num3, num4, keepTop);
			}
			Texture2D val = new Texture2D(num3, num4, (TextureFormat)4, false)
			{
				name = $"YD_UglyYule_{pattern}_icon",
				wrapMode = (TextureWrapMode)1,
				filterMode = (FilterMode)1
			};
			val.SetPixels32(array);
			val.Apply(false, true);
			Sprite obj = Sprite.Create(val, new Rect(0f, 0f, (float)num3, (float)num4), new Vector2(0.5f, 0.5f), icon.pixelsPerUnit);
			((Object)obj).name = ((Object)val).name;
			return obj;
		}

		private static void CropBelow(Color32[] px, int w, int h, float keepTop)
		{
			//IL_00b7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bc: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fa: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ff: Unknown result type (might be due to invalid IL or missing references)
			int num = -1;
			int num2 = -1;
			for (int i = 0; i < h; i++)
			{
				int num3 = h - 1 - i;
				for (int j = 0; j < w; j++)
				{
					if (px[num3 * w + j].a > 16)
					{
						if (num < 0)
						{
							num = i;
						}
						num2 = i;
						break;
					}
				}
			}
			if (num < 0)
			{
				return;
			}
			int num4 = num + Mathf.RoundToInt((float)(num2 - num) * keepTop);
			for (int k = num4; k < h; k++)
			{
				int num5 = h - 1 - k;
				for (int l = 0; l < w; l++)
				{
					px[num5 * w + l].a = 0;
				}
			}
			for (int m = Mathf.Max(num, num4 - 2); m < num4; m++)
			{
				int num6 = h - 1 - m;
				for (int n = 0; n < w; n++)
				{
					Color32 val = px[num6 * w + n];
					px[num6 * w + n] = new Color32((byte)((float)(int)val.r * 0.6f), (byte)((float)(int)val.g * 0.6f), (byte)((float)(int)val.b * 0.6f), val.a);
				}
			}
		}

		private static void RecolorReds(Color32[] px, Color target)
		{
			//IL_0012: Unknown result type (might be due to invalid IL or missing references)
			//IL_0021: Unknown result type (might be due to invalid IL or missing references)
			//IL_005b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0060: Unknown result type (might be due to invalid IL or missing references)
			//IL_0062: Unknown result type (might be due to invalid IL or missing references)
			//IL_006e: Unknown result type (might be due to invalid IL or missing references)
			//IL_008b: Unknown result type (might be due to invalid IL or missing references)
			//IL_00aa: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ef: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f4: Unknown result type (might be due to invalid IL or missing references)
			double num = 0.0;
			int num2 = 0;
			for (int i = 0; i < px.Length; i++)
			{
				if (IsRed(px[i]))
				{
					num += (double)Lum(px[i]);
					num2++;
				}
			}
			if (num2 == 0)
			{
				return;
			}
			float num3 = Mathf.Max(0.02f, (float)(num / (double)num2));
			for (int j = 0; j < px.Length; j++)
			{
				Color32 val = px[j];
				if (IsRed(val))
				{
					float num4 = Mathf.Clamp(Lum(val) / num3, 0.55f, 1.25f);
					px[j] = new Color32((byte)Mathf.Clamp(ta