Decompiled source of FehuAssets v420.0.20

FehuAssets.dll

Decompiled a week ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using FehuAssets.Airships;
using FehuAssets.Parrots;
using HarmonyLib;
using Jotunn.Configs;
using Jotunn.Entities;
using Jotunn.Managers;
using Microsoft.CodeAnalysis;
using UnityEngine;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETFramework,Version=v4.7.2", FrameworkDisplayName = ".NET Framework 4.7.2")]
[assembly: AssemblyCompany("FehuAssets")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0")]
[assembly: AssemblyProduct("FehuAssets")]
[assembly: AssemblyTitle("FehuAssets")]
[assembly: AssemblyVersion("1.0.0.0")]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[Embedded]
	[AttributeUsage(AttributeTargets.Class | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Parameter | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter, AllowMultiple = false, Inherited = false)]
	internal sealed class NullableAttribute : Attribute
	{
		public readonly byte[] NullableFlags;

		public NullableAttribute(byte P_0)
		{
			NullableFlags = new byte[1] { P_0 };
		}

		public NullableAttribute(byte[] P_0)
		{
			NullableFlags = P_0;
		}
	}
	[CompilerGenerated]
	[Embedded]
	[AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Method | AttributeTargets.Interface | AttributeTargets.Delegate, AllowMultiple = false, Inherited = false)]
	internal sealed class NullableContextAttribute : Attribute
	{
		public readonly byte Flag;

		public NullableContextAttribute(byte P_0)
		{
			Flag = P_0;
		}
	}
	[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;
		}
	}
}
public sealed class AirshipConfigHolder : MonoBehaviour
{
}
namespace FehuAssets
{
	[BepInPlugin("fehu.assets", "FehuAssets", "1.0.0")]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	public sealed class FehuAssetsPlugin : BaseUnityPlugin
	{
		[HarmonyPatch(typeof(Player), "RemovePiece")]
		private static class PlayerRemovePiecePatch
		{
			private static readonly FieldInfo? HoveringPieceField = AccessTools.Field(typeof(Player), "m_hoveringPiece");

			private static bool Prefix(Player __instance)
			{
				object? obj = HoveringPieceField?.GetValue(__instance);
				Piece val = (Piece)((obj is Piece) ? obj : null);
				if ((Object)(object)val == (Object)null || !IsFehuPiece(val))
				{
					return true;
				}
				DestroyFehuPiece(val);
				return false;
			}

			private static bool IsFehuPiece(Piece piece)
			{
				return FehuAssetsPlugin.IsFehuPiece(piece);
			}
		}

		private readonly struct DancerPrefabSpec
		{
			public string SourcePath { get; }

			public string SourceName { get; }

			public string ExposedPrefabName { get; }

			public string DisplayName { get; }

			public string Description { get; }

			public DancerGroup Group { get; }

			public DancerPrefabSpec(string sourcePath, string sourceName, string exposedPrefabName, string displayName, string description, DancerGroup group)
			{
				SourcePath = sourcePath;
				SourceName = sourceName;
				ExposedPrefabName = exposedPrefabName;
				DisplayName = displayName;
				Description = description;
				Group = group;
			}
		}

		private readonly struct RequirementSpec
		{
			public string Item { get; }

			public int Amount { get; }

			public bool Recover { get; }

			public RequirementSpec(string item, int amount, bool recover)
			{
				Item = item;
				Amount = amount;
				Recover = recover;
			}
		}

		private enum DancerGroup
		{
			Standing,
			Sitting,
			Laying
		}

		private readonly struct StructurePrefabSpec
		{
			public string PrefabName { get; }

			public string DisplayName { get; }

			public string Description { get; }

			public StructureKind Kind { get; }

			public RequirementSpec[] Requirements { get; }

			public StructurePrefabSpec(string prefabName, string displayName, string description, StructureKind kind, RequirementSpec[] requirements)
			{
				PrefabName = prefabName;
				DisplayName = displayName;
				Description = description;
				Kind = kind;
				Requirements = requirements;
			}
		}

		private enum StructureKind
		{
			Sigil,
			Monument,
			Totem
		}

		public const string ModGuid = "fehu.assets";

		public const string ModName = "FehuAssets";

		public const string ModVersion = "1.0.0";

		public const string JotunnGuid = "com.jotunn.jotunn";

		private const string BundleResourceName = "FehuAssets.Resources.fehu_dancers.bundle";

		private const string WhoreHousePrefabName = "GlitnirWhoreHouse";

		private const string WhoreHousePrefabPath = "assets/bagual/glitnirlocations/whorehouse/glitnirwhorehouse.prefab";

		private static readonly Harmony Harmony = new Harmony("fehu.assets");

		private static readonly DancerPrefabSpec[] DancerPrefabs = new DancerPrefabSpec[11]
		{
			Dancer("Interior/Decor_1Andar/Diane_Dancer", "Diane_Dancer", "Fehu_DianeDancer", "Astrid Firebraid"),
			Dancer("Interior/Mulheres/Emily_Dancing", "Emily_Dancing", "Fehu_EmilyDancer", "Freydis Goldhair"),
			Dancer("Interior/Mulheres/Freya_RedHair_Dancing", "Freya_RedHair_Dancing", "Fehu_FreyaDancer", "Runa Moonveil"),
			Dancer("Interior/Mulheres/Martha_Dancing", "Martha_Dancing", "Fehu_MarthaDancer", "Thyra Silkstep"),
			Dancer("Interior/Mulheres/ElficGirl_Blond_Dancer", "ElficGirl_Blond_Dancer", "Fehu_BlondElfDancer", "Eira Silvermist"),
			Dancer("Interior/Mulheres/ElficGirl_RedHair_Dancer", "ElficGirl_RedHair_Dancer", "Fehu_RedElfDancer", "Ylva Ravenhair"),
			Dancer("Interior/Mulheres/ElficGirl_Brunette_Dancer", "ElficGirl_Brunette_Dancer", "Fehu_BrunetteElfDancer", "Solveig Honeywine"),
			Dancer("Interior/Mulheres/ElficGirl_Brunette_Idle", "ElficGirl_Brunette_Idle", "Fehu_BrunetteIdle", "Ingrid Shadowstep"),
			Sitting("Interior/Mulheres/FreyaSentada01", "FreyaSentada01", "Fehu_FreyaSitting01", "Runa Sitting I"),
			Sitting("Interior/Mulheres/FreyaSentada02", "FreyaSentada02", "Fehu_FreyaSitting02", "Runa Sitting II"),
			Laying("Interior/Mulheres/FreyaDeitada01", "FreyaDeitada01", "Fehu_FreyaLaying", "Runa Laying")
		};

		private static readonly StructurePrefabSpec[] StructurePrefabs = new StructurePrefabSpec[3]
		{
			new StructurePrefabSpec("piece_fehu_sigil", "Fehu Sigil", "A sacred Fehu rune marker.", StructureKind.Sigil, new RequirementSpec[4]
			{
				new RequirementSpec("Stone", 60, recover: true),
				new RequirementSpec("FineWood", 25, recover: true),
				new RequirementSpec("SurtlingCore", 5, recover: true),
				new RequirementSpec("Bronze", 5, recover: true)
			}),
			new StructurePrefabSpec("piece_fehu_monument", "Fehu Monument", "A heavy stone monument bearing the Fehu rune.", StructureKind.Monument, new RequirementSpec[4]
			{
				new RequirementSpec("Stone", 100, recover: true),
				new RequirementSpec("BlackMarble", 30, recover: true),
				new RequirementSpec("SurtlingCore", 8, recover: true),
				new RequirementSpec("Bronze", 10, recover: true)
			}),
			new StructurePrefabSpec("piece_fehu_totem", "Fehu Totem", "A small ritual marker for camps and gathering places.", StructureKind.Totem, new RequirementSpec[4]
			{
				new RequirementSpec("Wood", 30, recover: true),
				new RequirementSpec("RoundLog", 10, recover: true),
				new RequirementSpec("BoneFragments", 10, recover: true),
				new RequirementSpec("SurtlingCore", 1, recover: true)
			})
		};

		private static AssetBundle? _bundle;

		private static GameObject? _whoreHousePrefab;

		private static readonly List<GameObject> RegisteredPrefabs = new List<GameObject>();

		private static readonly Dictionary<string, Sprite> Icons = new Dictionary<string, Sprite>();

		private static ConfigEntry<bool>? _enableBuildPieces;

		private static ConfigEntry<bool>? _enableStandingDancers;

		private static ConfigEntry<bool>? _enableSittingDancers;

		private static ConfigEntry<bool>? _enableLayingDancers;

		private static ConfigEntry<string>? _pieceTable;

		private static ConfigEntry<string>? _pieceCategory;

		private static ConfigEntry<string>? _requiredCraftingStation;

		private static ConfigEntry<float>? _colliderSizeMultiplier;

		private static ConfigEntry<float>? _recipeCostMultiplier;

		private static ConfigEntry<bool>? _recoverResources;

		private static ConfigEntry<bool>? _enableDancerDebugLogs;

		private static ConfigEntry<string>? _standingItem1;

		private static ConfigEntry<int>? _standingItem1Amount;

		private static ConfigEntry<string>? _standingItem2;

		private static ConfigEntry<int>? _standingItem2Amount;

		private static ConfigEntry<string>? _standingItem3;

		private static ConfigEntry<int>? _standingItem3Amount;

		private static ConfigEntry<string>? _standingItem4;

		private static ConfigEntry<int>? _standingItem4Amount;

		private static ConfigEntry<string>? _sittingItem1;

		private static ConfigEntry<int>? _sittingItem1Amount;

		private static ConfigEntry<string>? _sittingItem2;

		private static ConfigEntry<int>? _sittingItem2Amount;

		private static ConfigEntry<string>? _sittingItem3;

		private static ConfigEntry<int>? _sittingItem3Amount;

		private static ConfigEntry<string>? _sittingItem4;

		private static ConfigEntry<int>? _sittingItem4Amount;

		private static ConfigEntry<string>? _layingItem1;

		private static ConfigEntry<int>? _layingItem1Amount;

		private static ConfigEntry<string>? _layingItem2;

		private static ConfigEntry<int>? _layingItem2Amount;

		private static ConfigEntry<string>? _layingItem3;

		private static ConfigEntry<int>? _layingItem3Amount;

		private static ConfigEntry<string>? _layingItem4;

		private static ConfigEntry<int>? _layingItem4Amount;

		private ManualLogSource Log => ((BaseUnityPlugin)this).Logger;

		public ManualLogSource AirshipLog => ((BaseUnityPlugin)this).Logger;

		public ManualLogSource ParrotLog => ((BaseUnityPlugin)this).Logger;

		private void Awake()
		{
			//IL_011a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0124: Expected O, but got Unknown
			//IL_0157: Unknown result type (might be due to invalid IL or missing references)
			//IL_0161: Expected O, but got Unknown
			//IL_01f1: Unknown result type (might be due to invalid IL or missing references)
			//IL_01fb: Expected O, but got Unknown
			//IL_024a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0254: Expected O, but got Unknown
			//IL_02a4: Unknown result type (might be due to invalid IL or missing references)
			//IL_02ae: Expected O, but got Unknown
			//IL_02fd: Unknown result type (might be due to invalid IL or missing references)
			//IL_0307: Expected O, but got Unknown
			//IL_0356: Unknown result type (might be due to invalid IL or missing references)
			//IL_0360: Expected O, but got Unknown
			//IL_03af: Unknown result type (might be due to invalid IL or missing references)
			//IL_03b9: Expected O, but got Unknown
			//IL_0409: Unknown result type (might be due to invalid IL or missing references)
			//IL_0413: Expected O, but got Unknown
			//IL_0462: Unknown result type (might be due to invalid IL or missing references)
			//IL_046c: Expected O, but got Unknown
			//IL_04bb: Unknown result type (might be due to invalid IL or missing references)
			//IL_04c5: Expected O, but got Unknown
			//IL_0514: Unknown result type (might be due to invalid IL or missing references)
			//IL_051e: Expected O, but got Unknown
			//IL_056e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0578: Expected O, but got Unknown
			//IL_05c7: Unknown result type (might be due to invalid IL or missing references)
			//IL_05d1: Expected O, but got Unknown
			try
			{
				_enableBuildPieces = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "Enable build pieces", true, "Register the Fehu dancer build pieces in the Hammer Fehu tab.");
				_enableStandingDancers = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "Enable standing dancers", true, "Register standing and dancing Fehu build pieces.");
				_enableSittingDancers = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "Enable sitting dancers", true, "Register seated Fehu build pieces.");
				_enableLayingDancers = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "Enable laying dancers", true, "Register laying Fehu build pieces.");
				_pieceTable = ((BaseUnityPlugin)this).Config.Bind<string>("Build", "Piece table", "Hammer", "Jotunn piece table used for Fehu pieces. Default: Hammer.");
				_pieceCategory = ((BaseUnityPlugin)this).Config.Bind<string>("Build", "Piece category", "Fehu", "Hammer tab/category name for Fehu pieces.");
				_requiredCraftingStation = ((BaseUnityPlugin)this).Config.Bind<string>("Build", "Required crafting station", string.Empty, "Required station prefab name. Empty means no station requirement. Example: piece_workbench.");
				_colliderSizeMultiplier = ((BaseUnityPlugin)this).Config.Bind<float>("Build", "Collider size multiplier", 1f, new ConfigDescription("Multiplier for Fehu dancer removal/selection collider size.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0.25f, 4f), Array.Empty<object>()));
				_recipeCostMultiplier = ((BaseUnityPlugin)this).Config.Bind<float>("Recipes", "Recipe cost multiplier", 1f, new ConfigDescription("Multiplier applied to all Fehu dancer recipe costs.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 10f), Array.Empty<object>()));
				_recoverResources = ((BaseUnityPlugin)this).Config.Bind<bool>("Recipes", "Recover resources", true, "Recover materials when a Fehu dancer build piece is removed.");
				_enableDancerDebugLogs = ((BaseUnityPlugin)this).Config.Bind<bool>("Debug", "EnableDancerDebugLogs", false, "Enable verbose Fehu dancer registration/loading logs.");
				_standingItem1 = ((BaseUnityPlugin)this).Config.Bind<string>("Recipes - Standing dancers", "Item 1", "FineWood", "First recipe item for standing dancer pieces.");
				_standingItem1Amount = ((BaseUnityPlugin)this).Config.Bind<int>("Recipes - Standing dancers", "Item 1 amount", 10, new ConfigDescription("Amount of item 1 for standing dancer pieces.", (AcceptableValueBase)(object)new AcceptableValueRange<int>(0, 999), Array.Empty<object>()));
				_standingItem2 = ((BaseUnityPlugin)this).Config.Bind<string>("Recipes - Standing dancers", "Item 2", "LinenThread", "Second recipe item for standing dancer pieces.");
				_standingItem2Amount = ((BaseUnityPlugin)this).Config.Bind<int>("Recipes - Standing dancers", "Item 2 amount", 4, new ConfigDescription("Amount of item 2 for standing dancer pieces.", (AcceptableValueBase)(object)new AcceptableValueRange<int>(0, 999), Array.Empty<object>()));
				_standingItem3 = ((BaseUnityPlugin)this).Config.Bind<string>("Recipes - Standing dancers", "Item 3", "Coins", "Third recipe item for standing dancer pieces.");
				_standingItem3Amount = ((BaseUnityPlugin)this).Config.Bind<int>("Recipes - Standing dancers", "Item 3 amount", 25, new ConfigDescription("Amount of item 3 for standing dancer pieces.", (AcceptableValueBase)(object)new AcceptableValueRange<int>(0, 999), Array.Empty<object>()));
				_standingItem4 = ((BaseUnityPlugin)this).Config.Bind<string>("Recipes - Standing dancers", "Item 4", "SurtlingCore", "Fourth recipe item for standing dancer pieces.");
				_standingItem4Amount = ((BaseUnityPlugin)this).Config.Bind<int>("Recipes - Standing dancers", "Item 4 amount", 3, new ConfigDescription("Amount of item 4 for standing dancer pieces.", (AcceptableValueBase)(object)new AcceptableValueRange<int>(0, 999), Array.Empty<object>()));
				_sittingItem1 = ((BaseUnityPlugin)this).Config.Bind<string>("Recipes - Sitting dancers", "Item 1", "FineWood", "First recipe item for sitting dancer pieces.");
				_sittingItem1Amount = ((BaseUnityPlugin)this).Config.Bind<int>("Recipes - Sitting dancers", "Item 1 amount", 8, new ConfigDescription("Amount of item 1 for sitting dancer pieces.", (AcceptableValueBase)(object)new AcceptableValueRange<int>(0, 999), Array.Empty<object>()));
				_sittingItem2 = ((BaseUnityPlugin)this).Config.Bind<string>("Recipes - Sitting dancers", "Item 2", "DeerHide", "Second recipe item for sitting dancer pieces.");
				_sittingItem2Amount = ((BaseUnityPlugin)this).Config.Bind<int>("Recipes - Sitting dancers", "Item 2 amount", 4, new ConfigDescription("Amount of item 2 for sitting dancer pieces.", (AcceptableValueBase)(object)new AcceptableValueRange<int>(0, 999), Array.Empty<object>()));
				_sittingItem3 = ((BaseUnityPlugin)this).Config.Bind<string>("Recipes - Sitting dancers", "Item 3", "Coins", "Third recipe item for sitting dancer pieces.");
				_sittingItem3Amount = ((BaseUnityPlugin)this).Config.Bind<int>("Recipes - Sitting dancers", "Item 3 amount", 20, new ConfigDescription("Amount of item 3 for sitting dancer pieces.", (AcceptableValueBase)(object)new AcceptableValueRange<int>(0, 999), Array.Empty<object>()));
				_sittingItem4 = ((BaseUnityPlugin)this).Config.Bind<string>("Recipes - Sitting dancers", "Item 4", "SurtlingCore", "Fourth recipe item for sitting dancer pieces.");
				_sittingItem4Amount = ((BaseUnityPlugin)this).Config.Bind<int>("Recipes - Sitting dancers", "Item 4 amount", 3, new ConfigDescription("Amount of item 4 for sitting dancer pieces.", (AcceptableValueBase)(object)new AcceptableValueRange<int>(0, 999), Array.Empty<object>()));
				_layingItem1 = ((BaseUnityPlugin)this).Config.Bind<string>("Recipes - Laying dancers", "Item 1", "FineWood", "First recipe item for laying dancer pieces.");
				_layingItem1Amount = ((BaseUnityPlugin)this).Config.Bind<int>("Recipes - Laying dancers", "Item 1 amount", 8, new ConfigDescription("Amount of item 1 for laying dancer pieces.", (AcceptableValueBase)(object)new AcceptableValueRange<int>(0, 999), Array.Empty<object>()));
				_layingItem2 = ((BaseUnityPlugin)this).Config.Bind<string>("Recipes - Laying dancers", "Item 2", "DeerHide", "Second recipe item for laying dancer pieces.");
				_layingItem2Amount = ((BaseUnityPlugin)this).Config.Bind<int>("Recipes - Laying dancers", "Item 2 amount", 6, new ConfigDescription("Amount of item 2 for laying dancer pieces.", (AcceptableValueBase)(object)new AcceptableValueRange<int>(0, 999), Array.Empty<object>()));
				_layingItem3 = ((BaseUnityPlugin)this).Config.Bind<string>("Recipes - Laying dancers", "Item 3", "Coins", "Third recipe item for laying dancer pieces.");
				_layingItem3Amount = ((BaseUnityPlugin)this).Config.Bind<int>("Recipes - Laying dancers", "Item 3 amount", 20, new ConfigDescription("Amount of item 3 for laying dancer pieces.", (AcceptableValueBase)(object)new AcceptableValueRange<int>(0, 999), Array.Empty<object>()));
				_layingItem4 = ((BaseUnityPlugin)this).Config.Bind<string>("Recipes - Laying dancers", "Item 4", "SurtlingCore", "Fourth recipe item for laying dancer pieces.");
				_layingItem4Amount = ((BaseUnityPlugin)this).Config.Bind<int>("Recipes - Laying dancers", "Item 4 amount", 3, new ConfigDescription("Amount of item 4 for laying dancer pieces.", (AcceptableValueBase)(object)new AcceptableValueRange<int>(0, 999), Array.Empty<object>()));
				if (!_enableBuildPieces.Value)
				{
					DancerLogInfo("Fehu dancer build pieces are disabled in config.");
					return;
				}
				_bundle = LoadEmbeddedDancerBundle();
				_whoreHousePrefab = LoadWhoreHousePrefab(_bundle);
				Harmony.PatchAll(typeof(FehuAssetsPlugin).Assembly);
				new FehuAirshipRegistry(this).Register();
				new ParrotRegistry(this).Register();
				EnsurePieceCategory();
				RegisterDancerPrefabs(_whoreHousePrefab);
			}
			catch (Exception arg)
			{
				Log.LogError((object)string.Format("Failed to initialize {0}: {1}", "FehuAssets", arg));
			}
		}

		private void OnDestroy()
		{
			Harmony.UnpatchSelf();
		}

		private void DancerLogInfo(string message)
		{
			ConfigEntry<bool>? enableDancerDebugLogs = _enableDancerDebugLogs;
			if (enableDancerDebugLogs != null && enableDancerDebugLogs.Value)
			{
				Log.LogInfo((object)message);
			}
		}

		private AssetBundle LoadEmbeddedDancerBundle()
		{
			Assembly executingAssembly = Assembly.GetExecutingAssembly();
			using Stream stream = executingAssembly.GetManifestResourceStream("FehuAssets.Resources.fehu_dancers.bundle");
			if (stream == null)
			{
				string text = string.Join(", ", executingAssembly.GetManifestResourceNames());
				throw new InvalidOperationException("Embedded dancer bundle resource 'FehuAssets.Resources.fehu_dancers.bundle' was not found. Available resources: " + text);
			}
			using MemoryStream memoryStream = new MemoryStream();
			stream.CopyTo(memoryStream);
			AssetBundle obj = AssetBundle.LoadFromMemory(memoryStream.ToArray());
			if ((Object)(object)obj == (Object)null)
			{
				throw new InvalidOperationException("Unity failed to load embedded Fehu dancers AssetBundle.");
			}
			DancerLogInfo("Loaded embedded Fehu dancers AssetBundle.");
			return obj;
		}

		private GameObject LoadWhoreHousePrefab(AssetBundle bundle)
		{
			GameObject val = bundle.LoadAsset<GameObject>("GlitnirWhoreHouse");
			if ((Object)(object)val == (Object)null)
			{
				val = bundle.LoadAsset<GameObject>("assets/bagual/glitnirlocations/whorehouse/glitnirwhorehouse.prefab");
			}
			if ((Object)(object)val == (Object)null)
			{
				string text = string.Join(", ", from name in bundle.GetAllAssetNames()
					where name.IndexOf("whorehouse", StringComparison.OrdinalIgnoreCase) >= 0
					select name);
				throw new InvalidOperationException("Could not load 'GlitnirWhoreHouse'. Matching bundle assets: " + text);
			}
			return val;
		}

		private static int RemoveFehuPieces(float? radius)
		{
			//IL_001e: Unknown result type (might be due to invalid IL or missing references)
			//IL_000d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0023: Unknown result type (might be due to invalid IL or missing references)
			//IL_0048: Unknown result type (might be due to invalid IL or missing references)
			//IL_0050: Unknown result type (might be due to invalid IL or missing references)
			Vector3 val = (((Object)(object)Player.m_localPlayer != (Object)null) ? ((Component)Player.m_localPlayer).transform.position : Vector3.zero);
			int num = 0;
			Piece[] array = Object.FindObjectsByType<Piece>((FindObjectsSortMode)0);
			foreach (Piece val2 in array)
			{
				if (IsFehuPiece(val2) && (!radius.HasValue || !(Vector3.Distance(val, ((Component)val2).transform.position) > radius.Value)))
				{
					DestroyFehuPiece(val2);
					num++;
				}
			}
			return num;
		}

		private static void DestroyFehuPiece(Piece piece)
		{
			ZNetView component = ((Component)piece).GetComponent<ZNetView>();
			if ((Object)(object)component != (Object)null && component.IsValid())
			{
				if (!component.IsOwner())
				{
					component.ClaimOwnership();
				}
				component.Destroy();
			}
			else
			{
				Object.Destroy((Object)(object)((Component)piece).gameObject);
			}
		}

		private static bool IsFehuPiece(Piece piece)
		{
			return ((Object)((Component)piece).gameObject).name.StartsWith("Fehu_", StringComparison.Ordinal);
		}

		private void RegisterDancerPrefabs(GameObject whoreHousePrefab)
		{
			//IL_0101: Unknown result type (might be due to invalid IL or missing references)
			DancerPrefabSpec[] dancerPrefabs = DancerPrefabs;
			for (int i = 0; i < dancerPrefabs.Length; i++)
			{
				DancerPrefabSpec spec = dancerPrefabs[i];
				if (!IsGroupEnabled(spec.Group))
				{
					DancerLogInfo("Skipped disabled Fehu build piece '" + spec.ExposedPrefabName + "'.");
					continue;
				}
				Transform val = whoreHousePrefab.transform.Find(spec.SourcePath);
				if ((Object)(object)val == (Object)null)
				{
					val = FindDeepChild(whoreHousePrefab.transform, spec.SourceName);
				}
				if ((Object)(object)val == (Object)null)
				{
					Log.LogError((object)("Missing dancer GameObject '" + spec.SourceName + "' at '" + spec.SourcePath + "'."));
					continue;
				}
				GameObject val2 = CreateDancerPiecePrefab(((Component)val).gameObject, spec);
				Sprite orCreateIcon = GetOrCreateIcon(spec);
				PrepareBuildPiece(val2, spec, orCreateIcon);
				val2.SetActive(true);
				val2.transform.position = new Vector3(0f, -10000f, 0f);
				Object.DontDestroyOnLoad((Object)(object)val2);
				RegisterWithJotunn(val2, spec, orCreateIcon);
				RegisteredPrefabs.Add(val2);
				DancerLogInfo("Registered Fehu build piece '" + spec.ExposedPrefabName + "' from '" + spec.SourceName + "'.");
			}
			DancerLogInfo($"Registered {RegisteredPrefabs.Count}/{DancerPrefabs.Length} Fehu dancer build pieces in the Fehu tab.");
		}

		private void RegisterStructurePrefabs()
		{
			//IL_005c: Unknown result type (might be due to invalid IL or missing references)
			int num = 0;
			StructurePrefabSpec[] structurePrefabs = StructurePrefabs;
			for (int i = 0; i < structurePrefabs.Length; i++)
			{
				StructurePrefabSpec spec = structurePrefabs[i];
				try
				{
					GameObject val = CreateStructurePrefab(spec);
					Sprite icon = CreateStructureIcon(spec);
					PrepareBuildPiece(val, spec.DisplayName, spec.Description, icon);
					val.SetActive(true);
					val.transform.position = new Vector3(0f, -10000f, 0f);
					Object.DontDestroyOnLoad((Object)(object)val);
					RegisterWithJotunn(val, spec.DisplayName, spec.Description, spec.Requirements, icon);
					RegisteredPrefabs.Add(val);
					num++;
					DancerLogInfo("Registered Fehu structure piece '" + spec.PrefabName + "'.");
				}
				catch (Exception arg)
				{
					Log.LogError((object)$"Failed to register Fehu structure '{spec.PrefabName}': {arg}");
				}
			}
			DancerLogInfo($"Registered {num}/{StructurePrefabs.Length} Fehu structure pieces in the Fehu tab.");
		}

		private IEnumerator RegisterStructurePrefabsWhenReady()
		{
			for (int i = 0; i < 300; i++)
			{
				if ((Object)(object)ZNetScene.instance != (Object)null && (Object)(object)ZNetScene.instance.GetPrefab("piece_stonestair") != (Object)null)
				{
					RegisterStructurePrefabs();
					yield break;
				}
				yield return null;
			}
			Log.LogError((object)"Timed out waiting for vanilla Valheim prefabs. Fehu Sigil/Monument/Totem were not registered.");
		}

		private static DancerPrefabSpec Dancer(string sourcePath, string sourceName, string exposedPrefabName, string displayName)
		{
			return new DancerPrefabSpec(sourcePath, sourceName, exposedPrefabName, displayName, DescriptionFor(exposedPrefabName), DancerGroup.Standing);
		}

		private static DancerPrefabSpec Sitting(string sourcePath, string sourceName, string exposedPrefabName, string displayName)
		{
			return new DancerPrefabSpec(sourcePath, sourceName, exposedPrefabName, displayName, DescriptionFor(exposedPrefabName), DancerGroup.Sitting);
		}

		private static DancerPrefabSpec Laying(string sourcePath, string sourceName, string exposedPrefabName, string displayName)
		{
			return new DancerPrefabSpec(sourcePath, sourceName, exposedPrefabName, displayName, DescriptionFor(exposedPrefabName), DancerGroup.Laying);
		}

		private static string DescriptionFor(string exposedPrefabName)
		{
			return exposedPrefabName switch
			{
				"Fehu_DianeDancer" => "Ognistowłosa tancerka Fehu, która wnosi do sali ciepło, rytm i odrobinę niebezpiecznego blasku.", 
				"Fehu_EmilyDancer" => "Złotowłosa ozdoba długiego domu, lekka jak pieśń przy miodzie i jasna jak poranny skarb.", 
				"Fehu_FreyaDancer" => "Runa Moonveil tańczy jak srebrny cień pod księżycem, spokojna i hipnotyczna.", 
				"Fehu_MarthaDancer" => "Thyra Silkstep trzyma rytm z gracją dworskiej artystki i pewnością kogoś, kto zna swoją scenę.", 
				"Fehu_BlondElfDancer" => "Elficka tancerka o jasnych włosach, stworzona do komnat pełnych światła, złota i cichej magii.", 
				"Fehu_RedElfDancer" => "Rudowłosa elfka Fehu, żywa iskra wśród lamp, run i nocnych opowieści.", 
				"Fehu_BrunetteElfDancer" => "Solveig Honeywine porusza się miękko i pewnie, jakby każdy krok był częścią starego rytuału.", 
				"Fehu_BrunetteIdle" => "Ingrid Shadowstep czeka w ciszy, chłodna, elegancka i gotowa do ozdobienia mrocznej sali.", 
				"Fehu_FreyaSitting01" => "Siedząca Runa, spokojna dekoracja do komnat, łaźni i prywatnych zakątków.", 
				"Fehu_FreyaSitting02" => "Druga poza siedzącej Runy, bardziej dworska, idealna przy tronie albo palenisku.", 
				"Fehu_FreyaLaying" => "Leżąca Runa, leniwa ozdoba komnaty odpoczynku, łóżka albo zacisznej alkowy.", 
				_ => "Dekoracyjna tancerka Fehu.", 
			};
		}

		private static void PrepareBuildPiece(GameObject prefab, DancerPrefabSpec spec, Sprite icon)
		{
			PrepareBuildPiece(prefab, spec.DisplayName, spec.Description, icon);
		}

		private static GameObject CreateDancerPiecePrefab(GameObject source, DancerPrefabSpec spec)
		{
			//IL_0050: 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_006b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0070: 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_0078: Unknown result type (might be due to invalid IL or missing references)
			//IL_0088: Unknown result type (might be due to invalid IL or missing references)
			//IL_0094: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bb: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bc: Unknown result type (might be due to invalid IL or missing references)
			GameObject val = CreateBuildPieceRoot(spec.ExposedPrefabName);
			val.SetActive(false);
			GameObject val2 = Object.Instantiate<GameObject>(source);
			((Object)val2).name = spec.SourceName + "_Visual";
			SanitizeDancerPrefab(val2);
			val2.transform.SetParent(val.transform, false);
			val2.transform.localPosition = Vector3.zero;
			val2.transform.localRotation = Quaternion.identity;
			Bounds val3 = CalculateRendererBounds(val);
			if (((Bounds)(ref val3)).size != Vector3.zero)
			{
				Vector3 val4 = default(Vector3);
				((Vector3)(ref val4))..ctor(((Bounds)(ref val3)).center.x, ((Bounds)(ref val3)).min.y, ((Bounds)(ref val3)).center.z);
				Transform transform = val2.transform;
				transform.localPosition -= val4;
			}
			return val;
		}

		private static GameObject CreateBuildPieceRoot(string prefabName)
		{
			//IL_0046: Unknown result type (might be due to invalid IL or missing references)
			ZNetScene instance = ZNetScene.instance;
			GameObject val = (((Object)(object)instance != (Object)null) ? instance.GetPrefab("piece_woodpole") : null);
			if ((Object)(object)val == (Object)null && (Object)(object)instance != (Object)null)
			{
				val = instance.GetPrefab("piece_stonefloor2x2");
			}
			GameObject val2 = (GameObject)(((Object)(object)val != (Object)null) ? ((object)Object.Instantiate<GameObject>(val)) : ((object)new GameObject(prefabName)));
			((Object)val2).name = prefabName;
			Transform[] array = ((IEnumerable)val2.transform).Cast<Transform>().ToArray();
			for (int i = 0; i < array.Length; i++)
			{
				Object.DestroyImmediate((Object)(object)((Component)array[i]).gameObject);
			}
			Renderer[] componentsInChildren = val2.GetComponentsInChildren<Renderer>(true);
			for (int i = 0; i < componentsInChildren.Length; i++)
			{
				Object.DestroyImmediate((Object)(object)componentsInChildren[i]);
			}
			Collider[] componentsInChildren2 = val2.GetComponentsInChildren<Collider>(true);
			for (int i = 0; i < componentsInChildren2.Length; i++)
			{
				Object.DestroyImmediate((Object)(object)componentsInChildren2[i]);
			}
			Rigidbody[] componentsInChildren3 = val2.GetComponentsInChildren<Rigidbody>(true);
			for (int i = 0; i < componentsInChildren3.Length; i++)
			{
				DestroyRigidbodyIfSafe(componentsInChildren3[i]);
			}
			return val2;
		}

		private static Bounds CalculateRendererBounds(GameObject target)
		{
			//IL_001f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0024: Unknown result type (might be due to invalid IL or missing references)
			//IL_000c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0011: Unknown result type (might be due to invalid IL or missing references)
			//IL_0016: Unknown result type (might be due to invalid IL or missing references)
			//IL_002e: 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)
			Renderer[] componentsInChildren = target.GetComponentsInChildren<Renderer>(true);
			if (componentsInChildren.Length == 0)
			{
				return new Bounds(Vector3.zero, Vector3.zero);
			}
			Bounds bounds = componentsInChildren[0].bounds;
			for (int i = 1; i < componentsInChildren.Length; i++)
			{
				((Bounds)(ref bounds)).Encapsulate(componentsInChildren[i].bounds);
			}
			return bounds;
		}

		private static void PrepareBuildPiece(GameObject prefab, string displayName, string description, Sprite icon)
		{
			//IL_0028: 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)
			SetLayerRecursive(prefab, LayerMask.NameToLayer("piece"));
			ZNetView obj = prefab.GetComponent<ZNetView>() ?? prefab.AddComponent<ZNetView>();
			obj.m_persistent = true;
			obj.m_type = (ObjectType)0;
			Piece obj2 = prefab.GetComponent<Piece>() ?? prefab.AddComponent<Piece>();
			obj2.m_name = displayName;
			obj2.m_description = description;
			obj2.m_icon = icon;
			obj2.m_enabled = true;
			obj2.m_category = (PieceCategory)0;
			obj2.m_craftingStation = null;
			obj2.m_resources = Array.Empty<Requirement>();
			MakePlacementPermissive(obj2);
			EnsureRemovalTarget(prefab);
			RemoveProblematicWearNTear(prefab);
		}

		private static void EnsureRemovalTarget(GameObject prefab)
		{
			//IL_003e: 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_0046: Unknown result type (might be due to invalid IL or missing references)
			//IL_004b: Unknown result type (might be due to invalid IL or missing references)
			//IL_009a: Unknown result type (might be due to invalid IL or missing references)
			//IL_009f: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b4: 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)
			//IL_00ec: Unknown result type (might be due to invalid IL or missing references)
			//IL_0101: Unknown result type (might be due to invalid IL or missing references)
			//IL_0107: Unknown result type (might be due to invalid IL or missing references)
			//IL_0067: Unknown result type (might be due to invalid IL or missing references)
			//IL_0081: Unknown result type (might be due to invalid IL or missing references)
			//IL_0087: Unknown result type (might be due to invalid IL or missing references)
			BoxCollider val = prefab.GetComponent<BoxCollider>() ?? prefab.AddComponent<BoxCollider>();
			((Collider)val).isTrigger = false;
			float num = Mathf.Clamp(_colliderSizeMultiplier?.Value ?? 1f, 0.25f, 4f);
			Bounds val2 = CalculateRendererBounds(prefab);
			if (((Bounds)(ref val2)).size == Vector3.zero)
			{
				val.center = new Vector3(0f, 1f, 0f);
				val.size = new Vector3(0.8f, 2f, 0.8f) * num;
			}
			else
			{
				Vector3 center = prefab.transform.InverseTransformPoint(((Bounds)(ref val2)).center);
				val.center = center;
				val.size = new Vector3(Mathf.Max(0.8f, ((Bounds)(ref val2)).size.x + 0.25f), Mathf.Max(0.8f, ((Bounds)(ref val2)).size.y + 0.25f), Mathf.Max(0.8f, ((Bounds)(ref val2)).size.z + 0.25f)) * num;
			}
		}

		private static void SanitizeDancerPrefab(GameObject prefab)
		{
			RemoveComponentsByTypeName(prefab, "Character", "Humanoid", "MonsterAI", "BaseAI", "AnimalAI", "Tameable", "Procreation", "Growup", "Ragdoll", "ZSyncAnimation");
			Collider[] componentsInChildren = prefab.GetComponentsInChildren<Collider>(true);
			for (int i = 0; i < componentsInChildren.Length; i++)
			{
				Object.DestroyImmediate((Object)(object)componentsInChildren[i]);
			}
			Rigidbody[] componentsInChildren2 = prefab.GetComponentsInChildren<Rigidbody>(true);
			for (int i = 0; i < componentsInChildren2.Length; i++)
			{
				DestroyRigidbodyIfSafe(componentsInChildren2[i]);
			}
			ZNetView[] componentsInChildren3 = prefab.GetComponentsInChildren<ZNetView>(true);
			for (int i = 0; i < componentsInChildren3.Length; i++)
			{
				Object.DestroyImmediate((Object)(object)componentsInChildren3[i]);
			}
			Piece[] componentsInChildren4 = prefab.GetComponentsInChildren<Piece>(true);
			for (int i = 0; i < componentsInChildren4.Length; i++)
			{
				Object.DestroyImmediate((Object)(object)componentsInChildren4[i]);
			}
			WearNTear[] componentsInChildren5 = prefab.GetComponentsInChildren<WearNTear>(true);
			for (int i = 0; i < componentsInChildren5.Length; i++)
			{
				Object.DestroyImmediate((Object)(object)componentsInChildren5[i]);
			}
		}

		private static void RemoveComponentsByTypeName(GameObject prefab, params string[] typeNames)
		{
			HashSet<string> hashSet = new HashSet<string>(typeNames, StringComparer.Ordinal);
			Component[] componentsInChildren = prefab.GetComponentsInChildren<Component>(true);
			foreach (Component val in componentsInChildren)
			{
				if ((Object)(object)val != (Object)null && hashSet.Contains(((object)val).GetType().Name))
				{
					Object.DestroyImmediate((Object)(object)val);
				}
			}
		}

		private static void SetLayerRecursive(GameObject target, int layer)
		{
			if (layer >= 0)
			{
				target.layer = layer;
				Transform[] componentsInChildren = target.GetComponentsInChildren<Transform>(true);
				for (int i = 0; i < componentsInChildren.Length; i++)
				{
					((Component)componentsInChildren[i]).gameObject.layer = layer;
				}
			}
		}

		private static GameObject CreateStructurePrefab(StructurePrefabSpec spec)
		{
			//IL_0036: 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_007f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0093: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00be: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d2: 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_00fd: 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_0137: Unknown result type (might be due to invalid IL or missing references)
			//IL_013c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0150: Unknown result type (might be due to invalid IL or missing references)
			//IL_0171: Unknown result type (might be due to invalid IL or missing references)
			//IL_019b: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a0: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b4: Unknown result type (might be due to invalid IL or missing references)
			//IL_01df: 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_01f8: Unknown result type (might be due to invalid IL or missing references)
			//IL_021e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0223: Unknown result type (might be due to invalid IL or missing references)
			//IL_0237: Unknown result type (might be due to invalid IL or missing references)
			//IL_025d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0262: Unknown result type (might be due to invalid IL or missing references)
			//IL_0276: Unknown result type (might be due to invalid IL or missing references)
			//IL_029c: Unknown result type (might be due to invalid IL or missing references)
			//IL_02a1: Unknown result type (might be due to invalid IL or missing references)
			//IL_02b5: Unknown result type (might be due to invalid IL or missing references)
			//IL_02db: Unknown result type (might be due to invalid IL or missing references)
			//IL_02e0: Unknown result type (might be due to invalid IL or missing references)
			//IL_02f4: Unknown result type (might be due to invalid IL or missing references)
			//IL_031a: Unknown result type (might be due to invalid IL or missing references)
			//IL_031f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0333: Unknown result type (might be due to invalid IL or missing references)
			//IL_0359: Unknown result type (might be due to invalid IL or missing references)
			//IL_035e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0372: Unknown result type (might be due to invalid IL or missing references)
			//IL_0398: Unknown result type (might be due to invalid IL or missing references)
			//IL_039d: Unknown result type (might be due to invalid IL or missing references)
			//IL_03b1: Unknown result type (might be due to invalid IL or missing references)
			//IL_03d7: Unknown result type (might be due to invalid IL or missing references)
			//IL_03dc: Unknown result type (might be due to invalid IL or missing references)
			//IL_03f0: Unknown result type (might be due to invalid IL or missing references)
			//IL_0416: Unknown result type (might be due to invalid IL or missing references)
			//IL_041b: Unknown result type (might be due to invalid IL or missing references)
			//IL_042f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0455: Unknown result type (might be due to invalid IL or missing references)
			//IL_045a: Unknown result type (might be due to invalid IL or missing references)
			//IL_046e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0494: Unknown result type (might be due to invalid IL or missing references)
			//IL_0499: Unknown result type (might be due to invalid IL or missing references)
			//IL_04ad: Unknown result type (might be due to invalid IL or missing references)
			//IL_04ce: Unknown result type (might be due to invalid IL or missing references)
			//IL_04fd: Unknown result type (might be due to invalid IL or missing references)
			//IL_0502: Unknown result type (might be due to invalid IL or missing references)
			//IL_0516: Unknown result type (might be due to invalid IL or missing references)
			//IL_053c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0541: Unknown result type (might be due to invalid IL or missing references)
			//IL_0546: Unknown result type (might be due to invalid IL or missing references)
			//IL_056c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0571: Unknown result type (might be due to invalid IL or missing references)
			//IL_0576: Unknown result type (might be due to invalid IL or missing references)
			//IL_059c: Unknown result type (might be due to invalid IL or missing references)
			//IL_05b0: Unknown result type (might be due to invalid IL or missing references)
			//IL_05c4: Unknown result type (might be due to invalid IL or missing references)
			//IL_05ea: Unknown result type (might be due to invalid IL or missing references)
			//IL_05ef: Unknown result type (might be due to invalid IL or missing references)
			//IL_0603: Unknown result type (might be due to invalid IL or missing references)
			//IL_0629: Unknown result type (might be due to invalid IL or missing references)
			//IL_062e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0642: Unknown result type (might be due to invalid IL or missing references)
			//IL_0663: Unknown result type (might be due to invalid IL or missing references)
			GameObject val = CreateBuildPieceRoot(spec.PrefabName);
			val.layer = LayerMask.NameToLayer("piece");
			Material material = CreateMaterial("FehuAssets_RuneGold", new Color(1f, 0.62f, 0.08f, 1f));
			switch (spec.Kind)
			{
			case StructureKind.Sigil:
				AddPrefabChild(val, "piece_stonefloor2x2", "stone_plinth", new Vector3(0f, 0f, 0f), Vector3.zero, new Vector3(1.15f, 0.35f, 0.85f));
				AddPrefabChild(val, "piece_darkwoodpole4", "left_post", new Vector3(-0.62f, 0.95f, -0.08f), Vector3.zero, new Vector3(0.85f, 0.85f, 0.85f));
				AddPrefabChild(val, "piece_darkwoodpole4", "right_post", new Vector3(0.62f, 0.95f, -0.08f), Vector3.zero, new Vector3(0.85f, 0.85f, 0.85f));
				AddPrefabChild(val, "piece_stonewall1x1", "dark_stone_face", new Vector3(0f, 0.92f, -0.16f), Vector3.zero, new Vector3(0.9f, 0.95f, 0.25f));
				AddFehuRuneFromBeams(val, "sigil", new Vector3(0f, 1.02f, -0.36f), 0.78f, material);
				AddPrefabChild(val, "piece_dvergr_lantern", "low_lantern", new Vector3(0.1f, 0.42f, -0.18f), Vector3.zero, new Vector3(0.55f, 0.55f, 0.55f));
				break;
			case StructureKind.Monument:
				AddPrefabChild(val, "piece_stonefloor4x4", "main_base", new Vector3(0f, 0f, 0f), Vector3.zero, new Vector3(1f, 0.35f, 0.75f));
				AddPrefabChild(val, "piece_stonestair", "stair_1", new Vector3(0f, 0.12f, -1.05f), Vector3.zero, new Vector3(0.95f, 0.8f, 0.95f));
				AddPrefabChild(val, "piece_stonestair", "stair_2", new Vector3(0f, 0.34f, -0.75f), Vector3.zero, new Vector3(0.75f, 0.7f, 0.75f));
				AddPrefabChild(val, "piece_stonewall2x1", "left_wall", new Vector3(-0.42f, 1.25f, 0.1f), Vector3.zero, new Vector3(0.65f, 1.2f, 0.65f));
				AddPrefabChild(val, "piece_stonewall2x1", "right_wall", new Vector3(0.42f, 1.25f, 0.1f), Vector3.zero, new Vector3(0.65f, 1.2f, 0.65f));
				AddPrefabChild(val, "piece_stonewall1x1", "cap", new Vector3(0f, 2.35f, 0.1f), Vector3.zero, new Vector3(1.2f, 0.35f, 0.55f));
				AddPrefabChild(val, "piece_darkwoodpole4", "left_pillar", new Vector3(-1.15f, 1.4f, 0f), Vector3.zero, new Vector3(0.9f, 0.9f, 0.9f));
				AddPrefabChild(val, "piece_darkwoodpole4", "right_pillar", new Vector3(1.15f, 1.4f, 0f), Vector3.zero, new Vector3(0.9f, 0.9f, 0.9f));
				AddPrefabChild(val, "piece_banner01", "left_banner", new Vector3(-1.45f, 1.25f, -0.12f), Vector3.zero, new Vector3(0.8f, 0.8f, 0.8f));
				AddPrefabChild(val, "piece_banner01", "right_banner", new Vector3(1.45f, 1.25f, -0.12f), Vector3.zero, new Vector3(0.8f, 0.8f, 0.8f));
				AddPrefabChild(val, "piece_groundtorch", "left_torch", new Vector3(-0.75f, 0.35f, -0.65f), Vector3.zero, new Vector3(0.8f, 0.8f, 0.8f));
				AddPrefabChild(val, "piece_groundtorch", "right_torch", new Vector3(0.75f, 0.35f, -0.65f), Vector3.zero, new Vector3(0.8f, 0.8f, 0.8f));
				AddFehuRuneFromBeams(val, "monument", new Vector3(0f, 1.48f, -0.36f), 0.95f, material);
				break;
			case StructureKind.Totem:
				AddPrefabChild(val, "piece_stonefloor2x2", "rock_base", new Vector3(0f, 0f, 0f), Vector3.zero, new Vector3(0.85f, 0.35f, 0.85f));
				AddPrefabChild(val, "piece_woodpole2", "core_a", new Vector3(-0.12f, 1.05f, 0f), Vector3.zero, Vector3.one);
				AddPrefabChild(val, "piece_woodpole2", "core_b", new Vector3(0.12f, 1.05f, 0f), Vector3.zero, Vector3.one);
				AddPrefabChild(val, "piece_darkwoodbeam", "crossbar", new Vector3(0f, 1.62f, 0f), new Vector3(0f, 90f, 0f), new Vector3(0.95f, 0.95f, 0.95f));
				AddPrefabChild(val, "piece_dvergr_lantern", "left_lantern", new Vector3(-0.95f, 1.05f, 0f), Vector3.zero, new Vector3(0.55f, 0.55f, 0.55f));
				AddPrefabChild(val, "piece_dvergr_lantern", "right_lantern", new Vector3(0.95f, 1.05f, 0f), Vector3.zero, new Vector3(0.55f, 0.55f, 0.55f));
				AddFehuRuneFromBeams(val, "totem", new Vector3(0f, 1.28f, -0.18f), 0.62f, material);
				break;
			}
			return val;
		}

		private static void AddFehuRuneFromBeams(GameObject root, string prefix, Vector3 center, float scale, Material? material)
		{
			//IL_0011: Unknown result type (might be due to invalid IL or missing references)
			//IL_0023: Unknown result type (might be due to invalid IL or missing references)
			//IL_0028: 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_0056: Unknown result type (might be due to invalid IL or missing references)
			//IL_0074: Unknown result type (might be due to invalid IL or missing references)
			//IL_0088: 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_00a1: 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_00d9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ed: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f2: Unknown result type (might be due to invalid IL or missing references)
			//IL_0106: Unknown result type (might be due to invalid IL or missing references)
			//IL_0120: Unknown result type (might be due to invalid IL or missing references)
			AddPrefabChild(root, "piece_darkwoodbeam", prefix + "_fehu_stave", center + new Vector3(-0.12f * scale, 0f, 0f), new Vector3(0f, 0f, 90f), new Vector3(0.42f * scale, 0.42f * scale, 0.42f * scale), material);
			AddPrefabChild(root, "piece_darkwoodbeam", prefix + "_fehu_top_branch", center + new Vector3(0.16f * scale, 0.22f * scale, -0.01f), new Vector3(0f, 0f, 32f), new Vector3(0.36f * scale, 0.36f * scale, 0.36f * scale), material);
			AddPrefabChild(root, "piece_darkwoodbeam", prefix + "_fehu_mid_branch", center + new Vector3(0.13f * scale, -0.02f * scale, -0.01f), new Vector3(0f, 0f, 32f), new Vector3(0.31f * scale, 0.31f * scale, 0.31f * scale), material);
		}

		private static GameObject AddPrefabChild(GameObject parent, string prefabName, string childName, Vector3 localPosition, Vector3 localEuler, Vector3 localScale, Material? material = null)
		{
			//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_0070: 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)
			GameObject val = Object.Instantiate<GameObject>(ZNetScene.instance.GetPrefab(prefabName) ?? throw new InvalidOperationException("Vanilla Valheim prefab '" + prefabName + "' was not found."));
			((Object)val).name = childName;
			StripBuildComponents(val);
			if ((Object)(object)material != (Object)null)
			{
				ApplyMaterial(val, material);
			}
			val.transform.SetParent(parent.transform, false);
			val.transform.localPosition = localPosition;
			val.transform.localRotation = Quaternion.Euler(localEuler);
			val.transform.localScale = localScale;
			SetLayerRecursive(val, parent.layer);
			return val;
		}

		private static void ApplyMaterial(GameObject target, Material material)
		{
			Renderer[] componentsInChildren = target.GetComponentsInChildren<Renderer>(true);
			foreach (Renderer val in componentsInChildren)
			{
				Material[] sharedMaterials = val.sharedMaterials;
				for (int j = 0; j < sharedMaterials.Length; j++)
				{
					sharedMaterials[j] = material;
				}
				val.sharedMaterials = sharedMaterials;
			}
		}

		private static void StripBuildComponents(GameObject prefab)
		{
			ZNetView[] componentsInChildren = prefab.GetComponentsInChildren<ZNetView>(true);
			for (int i = 0; i < componentsInChildren.Length; i++)
			{
				Object.DestroyImmediate((Object)(object)componentsInChildren[i]);
			}
			Piece[] componentsInChildren2 = prefab.GetComponentsInChildren<Piece>(true);
			for (int i = 0; i < componentsInChildren2.Length; i++)
			{
				Object.DestroyImmediate((Object)(object)componentsInChildren2[i]);
			}
			WearNTear[] componentsInChildren3 = prefab.GetComponentsInChildren<WearNTear>(true);
			for (int i = 0; i < componentsInChildren3.Length; i++)
			{
				Object.DestroyImmediate((Object)(object)componentsInChildren3[i]);
			}
			Collider[] componentsInChildren4 = prefab.GetComponentsInChildren<Collider>(true);
			for (int i = 0; i < componentsInChildren4.Length; i++)
			{
				Object.DestroyImmediate((Object)(object)componentsInChildren4[i]);
			}
		}

		private static void AddFehuRune(GameObject parent, Material? main, Material? accent, float width, float height, float z)
		{
			//IL_0018: Unknown result type (might be due to invalid IL or missing references)
			//IL_0029: Unknown result type (might be due to invalid IL or missing references)
			//IL_005a: 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_007f: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ab: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c1: 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)
			AddBox(parent, "fehu_stave", new Vector3((0f - width) * 0.35f, height * 0.55f, z), new Vector3(0.14f, height, 0.12f), main);
			AddBox(parent, "fehu_branch_top", new Vector3(width * 0.08f, height * 0.85f, z - 0.01f), new Vector3(width, 0.12f, 0.13f), accent, (Vector3?)new Vector3(0f, 0f, -35f));
			AddBox(parent, "fehu_branch_mid", new Vector3(width * 0.05f, height * 0.58f, z - 0.01f), new Vector3(width * 0.82f, 0.12f, 0.13f), accent, (Vector3?)new Vector3(0f, 0f, -35f));
		}

		private static void AddBox(GameObject parent, string name, Vector3 localPosition, Vector3 localScale, Material? material, Vector3? localEuler = null)
		{
			//IL_0031: 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_0049: Unknown result type (might be due to invalid IL or missing references)
			//IL_0057: Unknown result type (might be due to invalid IL or missing references)
			//IL_0067: Unknown result type (might be due to invalid IL or missing references)
			GameObject obj = GameObject.CreatePrimitive((PrimitiveType)3);
			((Object)obj).name = name;
			obj.layer = parent.layer;
			obj.transform.SetParent(parent.transform, false);
			obj.transform.localPosition = localPosition;
			obj.transform.localRotation = Quaternion.Euler((Vector3)(((??)localEuler) ?? Vector3.zero));
			obj.transform.localScale = localScale;
			Renderer component = obj.GetComponent<Renderer>();
			if ((Object)(object)material != (Object)null)
			{
				component.material = material;
			}
			Collider component2 = obj.GetComponent<Collider>();
			if ((Object)(object)component2 != (Object)null)
			{
				Object.DestroyImmediate((Object)(object)component2);
			}
		}

		private static Material? CreateMaterial(string name, Color color)
		{
			//IL_004f: 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_005c: Expected O, but got Unknown
			//IL_005d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0076: Unknown result type (might be due to invalid IL or missing references)
			Shader val = Shader.Find("Legacy Shaders/Diffuse") ?? Shader.Find("Diffuse") ?? Shader.Find("Sprites/Default") ?? Shader.Find("Unlit/Color") ?? Shader.Find("Standard");
			if ((Object)(object)val == (Object)null)
			{
				return null;
			}
			Material val2 = new Material(val)
			{
				name = name
			};
			val2.color = color;
			if (val2.HasProperty("_Color"))
			{
				val2.SetColor("_Color", color);
			}
			Object.DontDestroyOnLoad((Object)(object)val2);
			return val2;
		}

		private static void MakePlacementPermissive(Piece piece)
		{
			Type? typeFromHandle = typeof(Piece);
			SetPieceField(typeFromHandle, piece, "m_groundOnly", value: false);
			SetPieceField(typeFromHandle, piece, "m_groundPiece", value: false);
			SetPieceField(typeFromHandle, piece, "m_cultivatedGroundOnly", value: false);
			SetPieceField(typeFromHandle, piece, "m_waterPiece", value: false);
			SetPieceField(typeFromHandle, piece, "m_noInWater", value: false);
			SetPieceField(typeFromHandle, piece, "m_notOnWood", value: false);
			SetPieceField(typeFromHandle, piece, "m_notOnFloor", value: false);
			SetPieceField(typeFromHandle, piece, "m_notOnTiltingSurface", value: false);
			SetPieceField(typeFromHandle, piece, "m_inCeilingOnly", value: false);
			SetPieceField(typeFromHandle, piece, "m_onlyInTeleportArea", value: false);
			SetPieceField(typeFromHandle, piece, "m_allowedInDungeons", value: true);
			SetPieceField(typeFromHandle, piece, "m_canBeRemoved", value: true);
			SetPieceField(typeFromHandle, piece, "m_clipGround", value: false);
			SetPieceField(typeFromHandle, piece, "m_clipEverything", value: false);
		}

		private static void SetPieceField(Type pieceType, Piece piece, string fieldName, bool value)
		{
			FieldInfo field = pieceType.GetField(fieldName, BindingFlags.Instance | BindingFlags.Public);
			if (field?.FieldType == typeof(bool))
			{
				field.SetValue(piece, value);
			}
		}

		private static void SetBoolField(Type type, object instance, string fieldName, bool value)
		{
			FieldInfo field = type.GetField(fieldName, BindingFlags.Instance | BindingFlags.Public);
			if (field?.FieldType == typeof(bool))
			{
				field.SetValue(instance, value);
			}
		}

		private static void SetFloatField(Type type, object instance, string fieldName, float value)
		{
			FieldInfo field = type.GetField(fieldName, BindingFlags.Instance | BindingFlags.Public);
			if (field?.FieldType == typeof(float))
			{
				field.SetValue(instance, value);
			}
		}

		private static void SetEnumField(Type type, object instance, string fieldName, string value)
		{
			FieldInfo field = type.GetField(fieldName, BindingFlags.Instance | BindingFlags.Public);
			if ((object)field != null && field.FieldType.IsEnum)
			{
				field.SetValue(instance, Enum.Parse(field.FieldType, value));
			}
		}

		private static bool IsGroupEnabled(DancerGroup group)
		{
			return group switch
			{
				DancerGroup.Standing => _enableStandingDancers?.Value ?? true, 
				DancerGroup.Sitting => _enableSittingDancers?.Value ?? true, 
				DancerGroup.Laying => _enableLayingDancers?.Value ?? true, 
				_ => true, 
			};
		}

		private static int ScaleAmount(int amount)
		{
			float num = _recipeCostMultiplier?.Value ?? 1f;
			return Mathf.Max(0, Mathf.CeilToInt((float)amount * num));
		}

		private static void RemoveProblematicWearNTear(GameObject prefab)
		{
			WearNTear[] componentsInChildren = prefab.GetComponentsInChildren<WearNTear>(true);
			for (int i = 0; i < componentsInChildren.Length; i++)
			{
				Object.DestroyImmediate((Object)(object)componentsInChildren[i]);
			}
		}

		private static void DestroyRigidbodyIfSafe(Rigidbody rigidbody)
		{
			if (!((Object)(object)rigidbody == (Object)null))
			{
				Debug.Log((object)("[FehuAirships] Rigidbody removal attempt object=" + GetHierarchyPath(((Component)rigidbody).transform) + " prefab=" + ((Object)((Component)rigidbody).transform.root).name + " components=" + DescribeComponents(((Component)rigidbody).gameObject)));
				if (!ShouldPreserveRigidbody(((Component)rigidbody).gameObject))
				{
					Object.DestroyImmediate((Object)(object)rigidbody);
				}
			}
		}

		private static bool ShouldPreserveRigidbody(GameObject go)
		{
			if ((Object)(object)go.GetComponent<FehuAirshipRigidbody>() != (Object)null || (Object)(object)go.GetComponent<FehuAirshipRuntimeBootstrap>() != (Object)null || (Object)(object)go.GetComponent<FehuAirshipControlsPilot>() != (Object)null || (Object)(object)go.GetComponent<FehuAirshipFuelSystem>() != (Object)null || (Object)(object)go.GetComponent<FehuAirshipPersistence>() != (Object)null)
			{
				return true;
			}
			Component[] components = go.GetComponents<Component>();
			foreach (Component val in components)
			{
				if ((Object)(object)val == (Object)null)
				{
					continue;
				}
				foreach (RequireComponent item in Attribute.GetCustomAttributes(((object)val).GetType(), typeof(RequireComponent), inherit: true).OfType<RequireComponent>())
				{
					if (item.m_Type0 == typeof(Rigidbody) || item.m_Type1 == typeof(Rigidbody) || item.m_Type2 == typeof(Rigidbody))
					{
						return true;
					}
				}
			}
			return false;
		}

		private static string DescribeComponents(GameObject go)
		{
			return string.Join(",", from component in go.GetComponents<Component>()
				where (Object)(object)component != (Object)null
				select ((object)component).GetType().Name);
		}

		private static string GetHierarchyPath(Transform transform)
		{
			List<string> list = new List<string>();
			Transform val = transform;
			while ((Object)(object)val != (Object)null)
			{
				list.Add(((Object)val).name);
				val = val.parent;
			}
			list.Reverse();
			return string.Join("/", list);
		}

		private static Sprite GetOrCreateIcon(DancerPrefabSpec spec)
		{
			if (Icons.TryGetValue(spec.ExposedPrefabName, out Sprite value))
			{
				return value;
			}
			Sprite val = LoadEmbeddedIcon(spec) ?? CreateFallbackIcon(spec);
			Icons[spec.ExposedPrefabName] = val;
			return val;
		}

		private static Sprite? LoadEmbeddedIcon(DancerPrefabSpec spec)
		{
			//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)
			//IL_007c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0083: Unknown result type (might be due to invalid IL or missing references)
			//IL_008c: Expected O, but got Unknown
			//IL_00cc: Unknown result type (might be due to invalid IL or missing references)
			//IL_00db: Unknown result type (might be due to invalid IL or missing references)
			string name = "FehuAssets.Resources.Icons." + spec.ExposedPrefabName + ".rgba";
			using Stream stream = Assembly.GetExecutingAssembly().GetManifestResourceStream(name);
			if (stream == null)
			{
				return null;
			}
			using MemoryStream memoryStream = new MemoryStream();
			stream.CopyTo(memoryStream);
			byte[] array = memoryStream.ToArray();
			if (array.Length != 65536)
			{
				return null;
			}
			Texture2D val = new Texture2D(128, 128, (TextureFormat)4, false)
			{
				name = spec.ExposedPrefabName + "_IconTexture",
				filterMode = (FilterMode)1,
				wrapMode = (TextureWrapMode)1
			};
			byte[] array2 = FlipRawRgbaVertically(array, 128, 128);
			val.LoadRawTextureData(array2);
			val.Apply(false, true);
			Sprite obj = Sprite.Create(val, new Rect(0f, 0f, (float)((Texture)val).width, (float)((Texture)val).height), new Vector2(0.5f, 0.5f), (float)((Texture)val).width);
			((Object)obj).name = spec.ExposedPrefabName + "_Icon";
			Object.DontDestroyOnLoad((Object)(object)val);
			Object.DontDestroyOnLoad((Object)(object)obj);
			return obj;
		}

		private static byte[] FlipRawRgbaVertically(byte[] source, int width, int height)
		{
			int num = width * 4;
			byte[] array = new byte[source.Length];
			for (int i = 0; i < height; i++)
			{
				Buffer.BlockCopy(source, i * num, array, (height - 1 - i) * num, num);
			}
			return array;
		}

		private static Sprite CreateFallbackIcon(DancerPrefabSpec spec)
		{
			//IL_000c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0011: Unknown result type (might be due to invalid IL or missing references)
			//IL_0028: 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_0037: Expected O, but got Unknown
			//IL_003e: 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_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_0053: 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_0065: 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_0093: 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_0382: Unknown result type (might be due to invalid IL or missing references)
			//IL_0391: Unknown result type (might be due to invalid IL or missing references)
			//IL_0248: Unknown result type (might be due to invalid IL or missing references)
			//IL_0245: Unknown result type (might be due to invalid IL or missing references)
			//IL_024a: Unknown result type (might be due to invalid IL or missing references)
			//IL_025e: Unknown result type (might be due to invalid IL or missing references)
			//IL_025f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0273: Unknown result type (might be due to invalid IL or missing references)
			//IL_0274: Unknown result type (might be due to invalid IL or missing references)
			//IL_02a4: Unknown result type (might be due to invalid IL or missing references)
			//IL_02a9: Unknown result type (might be due to invalid IL or missing references)
			//IL_02bf: Unknown result type (might be due to invalid IL or missing references)
			//IL_02c1: Unknown result type (might be due to invalid IL or missing references)
			//IL_02e9: Unknown result type (might be due to invalid IL or missing references)
			//IL_02ee: Unknown result type (might be due to invalid IL or missing references)
			//IL_0304: Unknown result type (might be due to invalid IL or missing references)
			//IL_0305: Unknown result type (might be due to invalid IL or missing references)
			//IL_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)
			Texture2D val = new Texture2D(128, 128, (TextureFormat)4, false)
			{
				name = spec.ExposedPrefabName + "_IconTexture",
				filterMode = (FilterMode)1,
				wrapMode = (TextureWrapMode)1
			};
			Color32 val2 = ColorFromName(spec.ExposedPrefabName);
			Color32 val3 = HairColorFor(spec.ExposedPrefabName);
			Color32 val4 = default(Color32);
			((Color32)(ref val4))..ctor((byte)(val2.r / 3), (byte)(val2.g / 3), (byte)(val2.b / 3), byte.MaxValue);
			Color32 val5 = default(Color32);
			((Color32)(ref val5))..ctor((byte)Mathf.Min(255, val2.r + 70), (byte)Mathf.Min(255, val2.g + 70), (byte)Mathf.Min(255, val2.b + 70), byte.MaxValue);
			Color32[] array = (Color32[])(object)new Color32[16384];
			for (int i = 0; i < 128; i++)
			{
				for (int j = 0; j < 128; j++)
				{
					bool flag = j < 5 || i < 5 || j >= 123 || i >= 123;
					bool num = InEllipse(j, i, 64, 34, 21, 23);
					bool flag2 = InEllipse(j, i, 64, 29, 28, 22) && !InEllipse(j, i, 64, 43, 18, 14);
					bool flag3 = j >= 56 && j <= 72 && i >= 52 && i <= 67;
					bool num2 = InEllipse(j, i, 64, 83, 31, 36);
					bool num3 = InEllipse(j, i, 64, 98, 38, 25);
					bool flag4 = i >= 70 && i <= 82 && Mathf.Abs(j - 64) < 18;
					bool flag5 = Mathf.Abs((float)(j - 39) + (float)(i - 74) * 0.35f) < 6f && i >= 58 && i <= 100;
					bool flag6 = Mathf.Abs((float)(j - 89) - (float)(i - 74) * 0.35f) < 6f && i >= 58 && i <= 100;
					bool flag7 = Mathf.Abs(j - 26) + Mathf.Abs(i - 28) < 9 || Mathf.Abs(j - 101) + Mathf.Abs(i - 92) < 8;
					array[i * 128 + j] = (flag ? val5 : val4);
					if (num3)
					{
						array[i * 128 + j] = val4;
					}
					if (num2)
					{
						array[i * 128 + j] = val2;
					}
					if (flag5 || flag6 || flag3)
					{
						array[i * 128 + j] = new Color32((byte)236, (byte)188, (byte)150, byte.MaxValue);
					}
					if (flag4)
					{
						array[i * 128 + j] = val5;
					}
					if (num)
					{
						array[i * 128 + j] = new Color32((byte)236, (byte)188, (byte)150, byte.MaxValue);
					}
					if (flag2)
					{
						array[i * 128 + j] = val3;
					}
					if (flag7)
					{
						array[i * 128 + j] = new Color32(byte.MaxValue, (byte)236, (byte)154, byte.MaxValue);
					}
				}
			}
			val.SetPixels32(array);
			val.Apply(false, true);
			Sprite obj = Sprite.Create(val, new Rect(0f, 0f, 128f, 128f), new Vector2(0.5f, 0.5f), 128f);
			((Object)obj).name = spec.ExposedPrefabName + "_Icon";
			Object.DontDestroyOnLoad((Object)(object)val);
			Object.DontDestroyOnLoad((Object)(object)obj);
			return obj;
		}

		private static Sprite CreateStructureIcon(StructurePrefabSpec spec)
		{
			//IL_000c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0011: Unknown result type (might be due to invalid IL or missing references)
			//IL_0028: 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_0037: Expected O, but got Unknown
			//IL_005e: Unknown result type (might be due to invalid IL or missing references)
			//IL_004c: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fd: Unknown result type (might be due to invalid IL or missing references)
			//IL_0117: Unknown result type (might be due to invalid IL or missing references)
			//IL_0131: Unknown result type (might be due to invalid IL or missing references)
			//IL_014b: Unknown result type (might be due to invalid IL or missing references)
			//IL_015f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0178: Unknown result type (might be due to invalid IL or missing references)
			//IL_0191: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a8: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c2: Unknown result type (might be due to invalid IL or missing references)
			//IL_01db: Unknown result type (might be due to invalid IL or missing references)
			//IL_01f0: Unknown result type (might be due to invalid IL or missing references)
			//IL_021b: Unknown result type (might be due to invalid IL or missing references)
			//IL_022a: Unknown result type (might be due to invalid IL or missing references)
			Texture2D val = new Texture2D(128, 128, (TextureFormat)4, false)
			{
				name = spec.PrefabName + "_IconTexture",
				filterMode = (FilterMode)1,
				wrapMode = (TextureWrapMode)1
			};
			Color32 element = ((spec.Kind == StructureKind.Monument) ? new Color32((byte)54, (byte)62, (byte)66, byte.MaxValue) : new Color32((byte)45, (byte)38, (byte)31, byte.MaxValue));
			Color32 color = default(Color32);
			((Color32)(ref color))..ctor((byte)55, (byte)235, (byte)190, byte.MaxValue);
			Color32 color2 = default(Color32);
			((Color32)(ref color2))..ctor((byte)145, (byte)151, (byte)145, byte.MaxValue);
			Color32 color3 = default(Color32);
			((Color32)(ref color3))..ctor((byte)95, (byte)65, (byte)39, byte.MaxValue);
			Color32[] array = Enumerable.Repeat<Color32>(element, 16384).ToArray();
			DrawRect(array, 128, 12, 108, 104, 8, color2);
			switch (spec.Kind)
			{
			case StructureKind.Sigil:
				DrawRect(array, 128, 54, 24, 10, 76, color3);
				DrawRotatedRect(array, 128, 69, 41, 58, 9, -32f, color);
				DrawRotatedRect(array, 128, 67, 63, 48, 9, -32f, color);
				break;
			case StructureKind.Monument:
				DrawRect(array, 128, 38, 20, 52, 88, color2);
				DrawRect(array, 128, 56, 34, 8, 60, color);
				DrawRotatedRect(array, 128, 72, 48, 43, 7, -32f, color);
				DrawRotatedRect(array, 128, 70, 66, 35, 7, -32f, color);
				break;
			case StructureKind.Totem:
				DrawRect(array, 128, 59, 24, 10, 82, color3);
				DrawRotatedRect(array, 128, 70, 45, 55, 9, -22f, color3);
				DrawRotatedRect(array, 128, 68, 66, 42, 8, -22f, color3);
				DrawRect(array, 128, 54, 84, 20, 20, color);
				break;
			}
			val.SetPixels32(array);
			val.Apply(false, true);
			Sprite obj = Sprite.Create(val, new Rect(0f, 0f, 128f, 128f), new Vector2(0.5f, 0.5f), 128f);
			((Object)obj).name = spec.PrefabName + "_Icon";
			Object.DontDestroyOnLoad((Object)(object)val);
			Object.DontDestroyOnLoad((Object)(object)obj);
			return obj;
		}

		private static void DrawRect(Color32[] pixels, int size, int x, int y, int w, int h, Color32 color)
		{
			//IL_001a: Unknown result type (might be due to invalid IL or missing references)
			//IL_001c: Unknown result type (might be due to invalid IL or missing references)
			for (int i = Mathf.Max(0, y); i < Mathf.Min(size, y + h); i++)
			{
				for (int j = Mathf.Max(0, x); j < Mathf.Min(size, x + w); j++)
				{
					pixels[i * size + j] = color;
				}
			}
		}

		private static void DrawRotatedRect(Color32[] pixels, int size, int cx, int cy, int w, int h, float degrees, Color32 color)
		{
			//IL_008e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0090: Unknown result type (might be due to invalid IL or missing references)
			float num = degrees * ((float)Math.PI / 180f);
			float num2 = Mathf.Cos(num);
			float num3 = Mathf.Sin(num);
			int num4 = Mathf.CeilToInt((float)Mathf.Max(w, h) * 0.75f);
			for (int i = Mathf.Max(0, cy - num4); i < Mathf.Min(size, cy + num4); i++)
			{
				for (int j = Mathf.Max(0, cx - num4); j < Mathf.Min(size, cx + num4); j++)
				{
					float num5 = j - cx;
					float num6 = i - cy;
					float num7 = num5 * num2 + num6 * num3;
					float num8 = (0f - num5) * num3 + num6 * num2;
					if (Mathf.Abs(num7) <= (float)w * 0.5f && Mathf.Abs(num8) <= (float)h * 0.5f)
					{
						pixels[i * size + j] = color;
					}
				}
			}
		}

		private static bool InEllipse(int x, int y, int cx, int cy, int rx, int ry)
		{
			float num = (float)(x - cx) / (float)rx;
			float num2 = (float)(y - cy) / (float)ry;
			return num * num + num2 * num2 <= 1f;
		}

		private static Color32 HairColorFor(string prefabName)
		{
			//IL_002b: 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_0091: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a8: Unknown result type (might be due to invalid IL or missing references)
			if (prefabName.Contains("Blond") || prefabName.Contains("Emily"))
			{
				return new Color32((byte)238, (byte)194, (byte)83, byte.MaxValue);
			}
			if (prefabName.Contains("Red") || prefabName.Contains("Diane") || prefabName.Contains("Freya"))
			{
				return new Color32((byte)165, (byte)62, (byte)42, byte.MaxValue);
			}
			if (prefabName.Contains("Brunette") || prefabName.Contains("Martha"))
			{
				return new Color32((byte)78, (byte)45, (byte)33, byte.MaxValue);
			}
			return new Color32((byte)170, (byte)148, (byte)118, byte.MaxValue);
		}

		private static Color32 ColorFromName(string name)
		{
			//IL_004f: Unknown result type (might be due to invalid IL or missing references)
			uint num = 2166136261u;
			foreach (char c in name)
			{
				num ^= c;
				num *= 16777619;
			}
			return new Color32((byte)(90 + (num & 0x7F)), (byte)(70 + ((num >> 8) & 0x7F)), (byte)(80 + ((num >> 16) & 0x7F)), byte.MaxValue);
		}

		private static Transform? FindDeepChild(Transform parent, string name)
		{
			for (int i = 0; i < parent.childCount; i++)
			{
				Transform child = parent.GetChild(i);
				if (((Object)child).name == name)
				{
					return child;
				}
				Transform val = FindDeepChild(child, name);
				if ((Object)(object)val != (Object)null)
				{
					return val;
				}
			}
			return null;
		}

		private void RegisterWithJotunn(GameObject prefab, DancerPrefabSpec spec, Sprite icon)
		{
			RequirementConfig[] requirements = (from requirement in ((IEnumerable<RequirementSpec>)GetRequirements(spec.Group)).Select((Func<RequirementSpec, RequirementConfig>)((RequirementSpec requirement) => new RequirementConfig(requirement.Item, ScaleAmount(requirement.Amount), 0, _recoverResources?.Value ?? requirement.Recover)))
				where !string.IsNullOrWhiteSpace(requirement.Item) && requirement.Amount > 0
				select requirement).ToArray();
			RegisterWithJotunn(prefab, spec.DisplayName, spec.Description, requirements, icon);
		}

		private void RegisterWithJotunn(GameObject prefab, string displayName, string description, RequirementSpec[] requirementSpecs, Sprite icon)
		{
			RequirementConfig[] requirements = (from requirement in ((IEnumerable<RequirementSpec>)requirementSpecs).Select((Func<RequirementSpec, RequirementConfig>)((RequirementSpec requirement) => new RequirementConfig(requirement.Item, ScaleAmount(requirement.Amount), 0, _recoverResources?.Value ?? requirement.Recover)))
				where !string.IsNullOrWhiteSpace(requirement.Item) && requirement.Amount > 0
				select requirement).ToArray();
			RegisterWithJotunn(prefab, displayName, description, requirements, icon);
		}

		private void RegisterWithJotunn(GameObject prefab, string displayName, string description, RequirementConfig[] requirements, Sprite icon)
		{
			//IL_0016: Unknown result type (might be due to invalid IL or missing references)
			//IL_001b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0022: Unknown result type (might be due to invalid IL or missing references)
			//IL_0029: Unknown result type (might be due to invalid IL or missing references)
			//IL_0030: 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_005a: 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_0077: Unknown result type (might be due to invalid IL or missing references)
			//IL_0080: Expected O, but got Unknown
			//IL_0083: Unknown result type (might be due to invalid IL or missing references)
			//IL_0088: Unknown result type (might be due to invalid IL or missing references)
			//IL_0094: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a1: Expected O, but got Unknown
			if (requirements.Length > 4)
			{
				requirements = requirements.Take(4).ToArray();
			}
			PieceConfig val = new PieceConfig
			{
				Name = displayName,
				Description = description,
				Enabled = true,
				PieceTable = CleanConfigString(_pieceTable, "Hammer"),
				Category = CleanConfigString(_pieceCategory, "Fehu"),
				CraftingStation = CleanConfigString(_requiredCraftingStation, string.Empty),
				Icon = icon,
				Requirements = requirements
			};
			CustomPiece val2 = new CustomPiece(prefab, true, val)
			{
				PieceTable = val.PieceTable,
				Category = val.Category
			};
			PieceManager.Instance.AddPiece(val2);
			DancerLogInfo("Prepared recipe for '" + displayName + "': " + string.Join(", ", requirements.Select((RequirementConfig requirement) => $"{requirement.Item} x{requirement.Amount}")));
		}

		private void EnsurePieceCategory()
		{
			string text = CleanConfigString(_pieceTable, "Hammer");
			string text2 = CleanConfigString(_pieceCategory, "Fehu");
			object instance = PieceManager.Instance;
			foreach (MethodInfo item in from method in instance.GetType().GetMethods(BindingFlags.Instance | BindingFlags.Public)
				where method.Name == "AddPieceCategory"
				select method)
			{
				ParameterInfo[] parameters = item.GetParameters();
				try
				{
					if (parameters.Length == 2 && parameters[0].ParameterType == typeof(string) && parameters[1].ParameterType == typeof(string))
					{
						item.Invoke(instance, new object[2] { text, text2 });
						DancerLogInfo("Ensured Fehu hammer category '" + text2 + "' in table '" + text + "'.");
						return;
					}
					if (parameters.Length == 1 && parameters[0].ParameterType == typeof(string))
					{
						item.Invoke(instance, new object[1] { text2 });
						DancerLogInfo("Ensured Fehu hammer category '" + text2 + "'.");
						return;
					}
				}
				catch (Exception ex)
				{
					Log.LogWarning((object)("Could not add Fehu category using " + item.Name + ": " + ex.Message));
				}
			}
			Log.LogWarning((object)("Could not find Jotunn AddPieceCategory overload. Fehu pieces will fall back to category '" + text2 + "' only."));
		}

		private static RequirementSpec[] GetRequirements(DancerGroup group)
		{
			return group switch
			{
				DancerGroup.Standing => new RequirementSpec[4]
				{
					Requirement(_standingItem1, _standingItem1Amount),
					Requirement(_standingItem2, _standingItem2Amount),
					Requirement(_standingItem3, _standingItem3Amount),
					Requirement(_standingItem4, _standingItem4Amount)
				}, 
				DancerGroup.Sitting => new RequirementSpec[4]
				{
					Requirement(_sittingItem1, _sittingItem1Amount),
					Requirement(_sittingItem2, _sittingItem2Amount),
					Requirement(_sittingItem3, _sittingItem3Amount),
					Requirement(_sittingItem4, _sittingItem4Amount)
				}, 
				DancerGroup.Laying => new RequirementSpec[4]
				{
					Requirement(_layingItem1, _layingItem1Amount),
					Requirement(_layingItem2, _layingItem2Amount),
					Requirement(_layingItem3, _layingItem3Amount),
					Requirement(_layingItem4, _layingItem4Amount)
				}, 
				_ => Array.Empty<RequirementSpec>(), 
			};
		}

		private static RequirementSpec Requirement(ConfigEntry<string>? item, ConfigEntry<int>? amount)
		{
			return new RequirementSpec(CleanConfigString(item, string.Empty), amount?.Value ?? 0, recover: true);
		}

		private static string CleanConfigString(ConfigEntry<string>? entry, string fallback)
		{
			string text = entry?.Value?.Trim() ?? string.Empty;
			if (!string.IsNullOrWhiteSpace(text))
			{
				return text;
			}
			return fallback;
		}
	}
}
namespace FehuAssets.Parrots
{
	[HarmonyPatch(typeof(CharacterDrop), "Start")]
	internal static class CharacterDrop_Start_ParrotDrops
	{
		private static void Postfix(CharacterDrop __instance)
		{
			//IL_0052: Unknown result type (might be due to invalid IL or missing references)
			//IL_005d: Expected O, but got Unknown
			//IL_0076: Unknown result type (might be due to invalid IL or missing references)
			//IL_007b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0082: Unknown result type (might be due to invalid IL or missing references)
			//IL_0089: Unknown result type (might be due to invalid IL or missing references)
			//IL_0090: Unknown result type (might be due to invalid IL or missing references)
			//IL_009b: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ae: Expected O, but got Unknown
			if (((Object)((Component)__instance).gameObject).name.StartsWith("PR_Parrot1") && (__instance.m_drops == null || __instance.m_drops.Count <= 0))
			{
				ZNetScene instance = ZNetScene.instance;
				GameObject val = (((Object)(object)instance != (Object)null) ? instance.GetPrefab("Feathers") : null);
				if ((Object)val == (Object)null)
				{
					ParrotsPlugin.ParrotsLogger.LogWarning((object)"Feathers prefab not found in ZNetScene");
					return;
				}
				__instance.m_drops = new List<Drop>
				{
					new Drop
					{
						m_prefab = val,
						m_amountMin = 2,
						m_amountMax = 4,
						m_chance = 1f,
						m_onePerPlayer = false,
						m_levelMultiplier = true
					}
				};
				ParrotsPlugin.ParrotsLogger.LogDebug((object)"Parrot drops configured: 2-4 Feathers");
			}
		}
	}
	[HarmonyPatch(typeof(Character), "Start")]
	internal static class Character_Start_ParrotColors
	{
		private static readonly int ColorProp = Shader.PropertyToID("_Color");

		private static readonly Color StarOneColor = new Color(0.4f, 0.85f, 0.3f, 1f);

		private static readonly Color StarTwoColor = new Color(0.9f, 0.15f, 0.1f, 1f);

		private static void Postfix(Character __instance)
		{
			//IL_0036: Unknown result type (might be due to invalid IL or missing references)
			//IL_0041: Expected O, but got Unknown
			//IL_004c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0057: Expected O, but got Unknown
			//IL_0059: Unknown result type (might be due to invalid IL or missing references)
			//IL_005f: Expected O, but got Unknown
			//IL_0070: Unknown result type (might be due to invalid IL or missing references)
			//IL_009b: Unknown result type (might be due to invalid IL or missing references)
			if (!((Object)((Component)__instance).gameObject).name.StartsWith("PR_Parrot1"))
			{
				return;
			}
			int level = __instance.GetLevel();
			if (level <= 1)
			{
				return;
			}
			Transform val = ((Component)__instance).transform.Find("Visual");
			if ((Object)val == (Object)null)
			{
				return;
			}
			SkinnedMeshRenderer componentInChildren = ((Component)val).GetComponentInChildren<SkinnedMeshRenderer>();
			if (!((Object)componentInChildren == (Object)null))
			{
				MaterialPropertyBlock val2 = new MaterialPropertyBlock();
				((Renderer)componentInChildren).GetPropertyBlock(val2);
				if (level == 2)
				{
					val2.SetColor(ColorProp, StarOneColor);
					((Renderer)componentInChildren).SetPropertyBlock(val2);
					ParrotsPlugin.ParrotsLogger.LogDebug((object)"1-star parrot: green variant");
				}
				else if (level >= 3)
				{
					val2.SetColor(ColorProp, StarTwoColor);
					((Renderer)componentInChildren).SetPropertyBlock(val2);
					ParrotsPlugin.ParrotsLogger.LogDebug((object)"2-star parrot: scarlet variant");
				}
			}
		}
	}
	[HarmonyPatch(typeof(Character), "UpdateMotion")]
	internal static class Character_UpdateMotion_ParrotFixes
	{
		private static bool Prefix(Character __instance)
		{
			//IL_0010: Unknown result type (might be due to invalid IL or missing references)
			//IL_001b: Expected O, but got Unknown
			if (ParrotFlightBehavior.IsInFollowFlight(__instance))
			{
				ZNetView component = ((Component)__instance).GetComponent<ZNetView>();
				if ((Object)component != (Object)null && component.IsOwner())
				{
					return false;
				}
			}
			return true;
		}
	}
	[HarmonyPatch(typeof(FejdStartup), "Awake")]
	internal static class FejdStartup_Awake_DeferredLocalizations
	{
		private static void Postfix()
		{
			if (ParrotsPlugin.s_localizationsRegistered)
			{
				return;
			}
			try
			{
				ParrotsPlugin.RegisterLocalizations();
			}
			catch (Exception ex)
			{
				ParrotsPlugin.ParrotsLogger.LogError((object)("Deferred RegisterLocalizations() failed: " + ex.Message));
			}
		}
	}
	[HarmonyPatch(typeof(Humanoid), "Awake")]
	internal static class Humanoid_Awake_ParrotFaction
	{
		private static void Postfix(Humanoid __instance)
		{
			//IL_001c: 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_003e: Expected O, but got Unknown
			if (((Object)((Component)__instance).gameObject).name.StartsWith("PR_Parrot1"))
			{
				((Character)__instance).m_faction = (Faction)1;
				__instance.m_defaultItems = Array.Empty<GameObject>();
				ZNetScene instance = ZNetScene.instance;
				if (!((Object)instance == (Object)null))
				{
					GameObject prefab = instance.GetPrefab("PR_SFX_Hit");
					GameObject val = instance.GetPrefab("vfx_HitSparks") ?? instance.GetPrefab("vfx_clubhit");
					((Character)__instance).m_hitEffects = MakeEffects(prefab, val);
					GameObject prefab2 = instance.GetPrefab("PR_SFX_Death");
					GameObject prefab3 = instance.GetPrefab("Boar");
					GameObject val2 = FindVisualEffect(((Object)(object)prefab3 == (Object)null) ? null : ((Character)(prefab3.GetComponent<Humanoid>()?)).m_deathEffects);
					((Character)__instance).m_deathEffects = MakeEffects(prefab2, val2);
					ParrotDebugLog.Info(ParrotsPlugin.ParrotsLogger, "Parrot VFX: hit=" + ((((Object)(object)val != (Object)null) ? ((Object)val).name : null) ?? "none") + ", death=" + ((((Object)(object)val2 != (Object)null) ? ((Object)val2).name : null) ?? "none"));
				}
			}
		}

		private static GameObject FindVisualEffect(EffectList effects)
		{
			//IL_0025: Unknown result type (might be due to invalid IL or missing references)
			//IL_0030: Expected O, but got Unknown
			//IL_003d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0048: Expected O, but got Unknown
			if (effects?.m_effectPrefabs == null)
			{
				return null;
			}
			EffectData[] effectPrefabs = effects.m_effectPrefabs;
			foreach (EffectData val in effectPrefabs)
			{
				if (!((Object)val.m_prefab == (Object)null) && (Object)val.m_prefab.GetComponent<AudioSource>() == (Object)null)
				{
					return val.m_prefab;
				}
			}
			return null;
		}

		private static EffectList MakeEffects(params GameObject[] prefabs)
		{
			//IL_0011: Unknown result type (might be due to invalid IL or missing references)
			//IL_001c: Expected O, but got Unknown
			//IL_0041: Unknown result type (might be due to invalid IL or missing references)
			//IL_0046: Unknown result type (might be due to invalid IL or missing references)
			//IL_0053: Expected O, but got Unknown
			//IL_001f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0024: 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_0037: Expected O, but got Unknown
			List<EffectData> list = new List<EffectData>();
			foreach (GameObject val in prefabs)
			{
				if ((Object)val != (Object)null)
				{
					list.Add(new EffectData
					{
						m_prefab = val,
						m_enabled = true
					});
				}
			}
			return new EffectList
			{
				m_effectPrefabs = list.ToArray()
			};
		}
	}
	[HarmonyPatch(typeof(ItemDrop), "Awake")]
	internal static class ItemDrop_Awake_ParrotEgg
	{
		private static void Postfix(ItemDrop __instance)
		{
			//IL_0013: Unknown result type (might be due to invalid IL or missing references)
			//IL_001e: Expected O, but got Unknown
			if (ParrotRegistry.IsParrotEggItem(__instance.m_itemData) && (Object)((Component)__instance).GetComponent<ParrotEggHatch>() == (Object)null)
			{
				((Component)__instance).gameObject.AddComponent<ParrotEggHatch>();
			}
		}
	}
	[HarmonyPatch(typeof(ItemDrop), "GetHoverText")]
	internal static class ItemDrop_GetHoverText_EggProgress
	{
		private static void Postfix(ItemDrop __instance, ref string __result)
		{
			//IL_0016: Unknown result type (might be due to invalid IL or missing references)
			//IL_0021: Expected O, but got Unknown
			if (!ParrotRegistry.IsParrotEggItem(__instance.m_itemData))
			{
				return;
			}
			ZNetView component = ((Component)__instance).GetComponent<ZNetView>();
			if (!((Object)component == (Object)null) && component.IsValid())
			{
				float num = component.GetZDO().GetFloat("PR_HatchTimer", 0f);
				float hatchTime = ParrotEggHatch.HatchTime;
				if (num >= 0f)
				{
					float num2 = Mathf.Clamp01(num / hatchTime) * 100f;
					string arg = Localization.instance.Localize("$parrot_hatching");
					__result += $"\n<color=#FFA500>{arg}: {num2:F0}%</color>";
				}
			}
		}
	}
	[HarmonyPatch(typeof(MonsterAI), "Awake")]
	internal static class MonsterAI_Awake_ParrotSetup
	{
		private static void Postfix(MonsterAI __instance)
		{
			//IL_002f: Unknown result type (might be due to invalid IL or missing references)
			//IL_003a: Expected O, but got Unknown
			if (((Object)((Component)__instance).gameObject).name.StartsWith("PR_Parrot1"))
			{
				SetupParrotAI(__instance);
				SetupParrotCharacter(__instance);
				FixAnimatorController(__instance);
				if ((Object)((Component)__instance).GetComponent<ParrotFlightBehavior>() == (Object)null)
				{
					((Component)__instance).gameObject.AddComponent<ParrotFlightBehavior>();
				}
			}
		}

		private static void FixAnimatorController(MonsterAI ai)
		{
			//IL_0012: Unknown result type (might be due to invalid IL or missing references)
			//IL_001d: Expected O, but got Unknown
			//IL_0028: Unknown result type (might be due to invalid IL or missing references)
			//IL_0033: Expected O, but got Unknown
			//IL_003e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0049: Expected O, but got Unknown
			//IL_00ad: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b8: Expected O, but got Unknown
			//IL_0050: Unknown result type (might be due to invalid IL or missing references)
			//IL_005b: Expected O, but got Unknown
			Transform val = ((Component)ai).transform.Find("Visual");
			if ((Object)val == (Object)null)
			{
				return;
			}
			Animator component = ((Component)val).GetComponent<Animator>();
			if (!((Object)component == (Object)null))
			{
				if ((Object)component.runtimeAnimatorController == (Object)null && (Object)ParrotsPlugin.CachedAnimatorController != (Object)null)
				{
					component.runtimeAnimatorController = ParrotsPlugin.CachedAnimatorController;
					ParrotDebugLog.Info(ParrotsPlugin.ParrotsLogger, "[ParrotPatches] Fixed missing AnimatorController: assigned '" + ((Object)ParrotsPlugin.CachedAnimatorController).name + "' " + $"({ParrotsPlugin.CachedAnimatorController.animationClips.Length} clips)");
				}
				else if ((Object)component.runtimeAnimatorController == (Object)null)
				{
					ParrotsPlugin.ParrotsLogger.LogWarning((object)"[ParrotPatches] Animator has no controller AND no cached controller available!");
				}
			}
		}

		private static void SetupParrotAI(MonsterAI ai)
		{
			//IL_008a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0095: Expected O, but got Unknown
			//IL_00a7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b2: Expected O, but got Unknown
			//IL_011a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0125: Expected O, but got Unknown
			//IL_00b4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ba: Expected O, but got Unknown
			//IL_00c3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00cf: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d7: Expected O, but got Unknown
			//IL_0127: Unknown result type (might be due to invalid IL or missing references)
			//IL_012e: Expected O, but got Unknown
			//IL_0138: Unknown result type (might be due to invalid IL or missing references)
			//IL_013d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0144: Unknown result type (might be due to invalid IL or missing references)
			//IL_014c: Expected O, but got Unknown
			ai.m_consumeRange = 2f;
			ai.m_consumeSearchInterval = 2f;
			ai.m_enableHuntPlayer = false;
			ai.m_attackPlayerObjects = false;
			ai.m_interceptTimeMax = 0f;
			ai.m_interceptTimeMin = 0f;
			ai.m_maxChaseDistance = 1f;
			ai.m_fleeIfNotAlerted = true;
			ai.m_fleeIfLowHealth = 1f;
			((BaseAI)ai).m_viewRange = 10f;
			((BaseAI)ai).m_viewAngle = 90f;
			((BaseAI)ai).m_hearRange = 6f;
			ai.m_alertRange = 5f;
			ZNetScene instance = ZNetScene.instance;
			if ((Object)instance != (Object)null)
			{
				GameObject prefab = instance.GetPrefab("PR_SFX_Chirp");
				if ((Object)prefab != (Object)null)
				{
					EffectList val = new EffectList();
					val.m_effectPrefabs = (EffectData[])(object)new EffectData[1]
					{
						new EffectData
						{
							m_prefab = prefab,
							m_enabled = true
						}
					};
					((BaseAI)ai).m_idleSound = val;
					((BaseAI)ai).m_idleSoundInterval = 8f;
					((BaseAI)ai).m_idleSoundChance = 0.5f;
					ParrotsPlugin.ParrotsLogger.LogDebug((object)"Parrot SFX: idle chirp wired (every 8s, 50% chance)");
				}
				GameObject prefab2 = instance.GetPrefab("PR_SFX_Squawk");
				if ((Object)prefab2 != (Object)null)
				{
					EffectList val2 = new EffectList();
					val2.m_effectPrefabs = (EffectData[])(object)new EffectData[1]
					{
						new EffectData
						{
							m_prefab = prefab2,
							m_enabled = true
						}
					};
					((BaseAI)ai).m_alertedEffects = val2;
					ParrotsPlugin.ParrotsLogger.LogDebug((object)"Parrot SFX: alerted squawk wired");
				}
			}
			ParrotsPlugin.ParrotsLogger.LogDebug((object)"Parrot AI configured: randomFly=true, range=60, airDuration=45, altitude=prefab(5/15/3), consumeSearchInterval=2, fleeIfNotAlerted=true, viewRange=10");
		}

		private static void SetupParrotCharacter(MonsterAI ai)
		{
			//IL_0008: Unknown result type (might be due to invalid IL or missing references)
			//IL_0013: Expected O, but got Unknown
			Character component = ((Component)ai).GetComponent<Character>();
			if (!((Object)component == (Object)null))
			{
				ParrotsPlugin.ParrotsLogger.LogDebug((object)$"Parrot Character: keeping prefab fly speeds (slow={component.m_flySlowSpeed}, fast={component.m_flyFastSpeed}, turn={component.m_flyTurnSpeed}, accel={component.m_acceleration})");
			}
		}
	}
	[HarmonyPatch(typeof(MonsterAI), "FindClosestConsumableItem")]
	internal static class MonsterAI_FindClosestConsumableItem_ParrotFix
	{
		private static bool Prefix(MonsterAI __instance, float maxRange, ref ItemDrop __result)
		{
			//IL_0021: Unknown result type (might be due to invalid IL or missing references)
			//IL_002c: Expected O, but got Unknown
			//IL_0055: Unknown result type (might be due to invalid IL or missing references)
			//IL_0081: Unknown result type (might be due to invalid IL or missing references)
			//IL_008c: Expected O, but got Unknown
			//IL_00a1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ac: Expected O, but got Unknown
			//IL_00bc: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c7: Expected O, but got Unknown
			//IL_00f5: Unknown result type (might be due to invalid IL or missing references)
			//IL_0100: Expected O, but got Unknown
			//IL_0154: Unknown result type (might be due to invalid IL or missing references)
			//IL_015f: Unknown result type (might be due to invalid IL or missing references)
			if (!((Object)((Component)__instance).gameObject).name.StartsWith("PR_Parrot1"))
			{
				return true;
			}
			Character component = ((Component)__instance).GetComponent<Character>();
			if ((Object)component != (Object)null && component.m_flying)
			{
				__result = null;
				return false;
			}
			int mask = LayerMask.GetMask(new string[1] { "item" });
			Collider[] array = Physics.OverlapSphere(((Component)__instance).transform.position, maxRange, mask);
			ItemDrop val = null;
			float num = 999999f;
			Collider[] array2 = array;
			foreach (Collider val2 in array2)
			{
				if ((Object)val2.attachedRigidbody == (Object)null)
				{
					continue;
				}
				ItemDrop component2 = ((Component)val2.attachedRigidbody).GetComponent<ItemDrop>();
				if ((Object)component2 == (Object)null)
				{
					continue;
				}
				ZNetView component3 = ((Component)component2).GetComponent<ZNetView>();
				if ((Object)component3 == (Object)null || !component3.IsValid())
				{
					continue;
				}
				bool flag = false;
				foreach (ItemDrop consumeItem in __instance.m_consumeItems)
				{
					if ((Object)consumeItem != (Object)null && component2.m_itemData.m_shared.m_name == consumeItem.m_itemData.m_shared.m_name)
					{
						flag = true;
						break;
					}
				}
				if (flag)
				{
					float num2 = Vector3.Distance(((Component)component2).transform.position, ((Component)__instance).transform.position);
					if (num2 < num)
					{
						val = component2;
						num = num2;
					}
				}
			}
			__result = val;
			return false;
		}
	}
	public sealed class ParrotAssetLoader
	{
		private readonly ManualLogSource _log;

		private AssetBundle? _bundle;

		public ParrotAssetLoader(ManualLogSource log)
		{
			_log = log;
		}

		public AssetBundle LoadBundle()
		{
			if ((Object)(object)_bundle != (Object)null)
			{
				return _bundle;
			}
			Assembly executingAssembly = Assembly.GetExecutingAssembly();
			using Stream stream = executingAssembly.GetManifestResourceStream("FehuAssets.Parrots.Resources.mar_parrots");
			if (stream == null)
			{
				string text = string.Join(", ", executingAssembly.GetManifestResourceNames());
				throw new InvalidOperationException("Embedded Parrots AssetBundle resource 'FehuAssets.Parrots.Resources.mar_parrots' was not found. Available resources: " + text);
			}
			using MemoryStream memoryStream = new MemoryStream();
			stream.CopyTo(memoryStream);
			_bundle = AssetBundle.LoadFromMemory(memoryStream.ToA