Decompiled source of SealsAtHome v1.0.1

SealsAtHome.dll

Decompiled 20 hours ago
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using BepInEx;
using BepInEx.Bootstrap;
using BepInEx.Logging;
using Microsoft.CodeAnalysis;
using UnityEngine;
using UnityEngine.SceneManagement;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETFramework,Version=v4.8", FrameworkDisplayName = ".NET Framework 4.8")]
[assembly: AssemblyCompany("SealsAtHome")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("1.0.1.0")]
[assembly: AssemblyInformationalVersion("1.0.1+57a60122bed72285ed7d897e17cdc3624de0eaeb")]
[assembly: AssemblyProduct("SealsAtHome")]
[assembly: AssemblyTitle("SealsAtHome")]
[assembly: AssemblyVersion("1.0.0.0")]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[Embedded]
	[AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)]
	internal sealed class RefSafetyRulesAttribute : Attribute
	{
		public readonly int Version;

		public RefSafetyRulesAttribute(int P_0)
		{
			Version = P_0;
		}
	}
}
namespace SealsAtHome
{
	internal static class ComponentSwap
	{
		public static TNew Replace<TNew>(GameObject prefab, Component old, Type copyFieldsOf) where TNew : Component
		{
			TNew val = prefab.AddComponent<TNew>();
			foreach (FieldInfo item in UnitySerialization.SerializedFields(copyFieldsOf))
			{
				item.SetValue(val, item.GetValue(old));
			}
			Repoint(prefab, old, (Component)(object)val);
			string name = ((object)old).GetType().Name;
			try
			{
				Object.DestroyImmediate((Object)(object)old, true);
			}
			catch (Exception ex)
			{
				Plugin.Log.LogError((object)("Could not remove " + name + " from " + ((Object)prefab).name + ": " + ex.Message));
			}
			if ((Object)(object)old == (Object)null)
			{
				return val;
			}
			Repoint(prefab, (Component)(object)val, old);
			Object.DestroyImmediate((Object)(object)val, true);
			return default(TNew);
		}

		private static void Repoint(GameObject prefab, Component from, Component to)
		{
			MonoBehaviour[] componentsInChildren = prefab.GetComponentsInChildren<MonoBehaviour>(true);
			foreach (MonoBehaviour val in componentsInChildren)
			{
				if ((Object)(object)val == (Object)null)
				{
					continue;
				}
				foreach (FieldInfo item in UnitySerialization.SerializedFields(((object)val).GetType()))
				{
					if (item.FieldType.IsInstanceOfType(to) && item.GetValue(val) == from)
					{
						item.SetValue(val, to);
					}
				}
			}
		}
	}
	[BepInPlugin("algo7.sealsathome", "SealsAtHome", "1.0.1")]
	public sealed class Plugin : BaseUnityPlugin
	{
		public const string Guid = "algo7.sealsathome";

		public const string Name = "SealsAtHome";

		public const string PluginVersion = "1.0.1";

		internal static ManualLogSource Log;

		private void Awake()
		{
			Log = ((BaseUnityPlugin)this).Logger;
			SceneManager.sceneLoaded += OnSceneLoaded;
			Log.LogInfo((object)"SealsAtHome loaded (v1.0.1)");
		}

		private void OnDestroy()
		{
			SceneManager.sceneLoaded -= OnSceneLoaded;
		}

		private static void OnSceneLoaded(Scene scene, LoadSceneMode mode)
		{
			try
			{
				if (Application.isBatchMode)
				{
					return;
				}
				ZNetScene instance = ZNetScene.instance;
				if (!((Object)(object)instance == (Object)null))
				{
					int num = Character.GetAllCharacters().Count((Character c) => (Object)(object)c != (Object)null && c.m_name.StartsWith("$enemy_seal", StringComparison.Ordinal));
					Log.LogInfo((object)$"Scene '{((Scene)(ref scene)).name}': prefabs registered, {num} seals exist yet (expected 0)");
					if (SealRebuild.Run(instance, out var message))
					{
						Log.LogInfo((object)message);
					}
					else
					{
						Log.LogWarning((object)message);
					}
				}
			}
			catch (Exception arg)
			{
				Log.LogError((object)$"Seal rebuild failed, seals stay vanilla: {arg}");
			}
		}
	}
	public sealed class SealCare : MonoBehaviour
	{
		private const float TickSeconds = 2f;

		private const int GrowEveryTicks = 5;

		public bool m_isPup;

		private static readonly int s_tamedAtHash = StringExtensionMethods.GetStableHashCode("SealsAtHome_TamedAt");

		private static readonly int s_beatHash = StringExtensionMethods.GetStableHashCode("SealsAtHome_Beat");

		private static readonly HashSet<long> s_takenFrom = new HashSet<long>();

		private static bool s_errorLogged;

		private ZNetView m_nview;

		private Character m_character;

		private MonsterAI m_ai;

		private bool? m_tamedApplied;

		private int m_ticks;

		private bool m_grown;

		private void Awake()
		{
			m_nview = ((Component)this).GetComponent<ZNetView>();
			m_character = ((Component)this).GetComponent<Character>();
			m_ai = ((Component)this).GetComponent<MonsterAI>();
			((MonoBehaviour)this).InvokeRepeating("Tick", Random.Range(0.5f, 2f), 2f);
		}

		private void Tick()
		{
			try
			{
				if (m_grown || (Object)(object)m_nview == (Object)null || !m_nview.IsValid() || (Object)(object)m_character == (Object)null || (Object)(object)m_ai == (Object)null)
				{
					return;
				}
				bool flag = m_character.IsTamed();
				if (m_tamedApplied != flag)
				{
					SettingsApplier.Apply((Component)(object)m_ai, flag ? SealSettings.TamedSwitch : SealSettings.WildSwitch, null);
					m_tamedApplied = flag;
				}
				if ((Object)(object)ZNet.instance == (Object)null)
				{
					return;
				}
				ZDO zDO = m_nview.GetZDO();
				long ticks = ZNet.instance.GetTime().Ticks;
				long beatTicks = zDO.GetLong(s_beatHash, 0L);
				if (!m_nview.IsOwner())
				{
					long owner = zDO.GetOwner();
					if (Takeover.ShouldClaim(isOwner: false, owner, beatTicks, ticks))
					{
						m_nview.ClaimOwnership();
						zDO.Set(s_beatHash, ticks);
						LogTakeover(owner);
					}
					return;
				}
				if (Takeover.ShouldBeat(beatTicks, ticks))
				{
					zDO.Set(s_beatHash, ticks);
				}
				string text = zDO.GetString(ZDOVars.s_tamedName, "");
				if (NameCopy.ShouldWrite(text, zDO.GetString(ZDOVars.s_overrideHoverName, "")))
				{
					string text2 = NameCopy.Target(text);
					zDO.Set(ZDOVars.s_overrideHoverName, text2);
					Plugin.Log.LogInfo((object)((text2.Length > 0) ? ("Pet name '" + text2 + "' is now shown to players without the mod too") : "Pet name cleared for players without the mod"));
				}
				if (m_isPup && ++m_ticks % 5 == 0)
				{
					switch (PupGrowth.Decide(flag, text, zDO.GetLong(s_tamedAtHash, 0L), ticks))
					{
					case PupGrowth.Step.Stamp:
						zDO.Set(s_tamedAtHash, ticks);
						break;
					case PupGrowth.Step.Grow:
						GrowUp();
						break;
					}
				}
			}
			catch (Exception arg)
			{
				if (!s_errorLogged)
				{
					s_errorLogged = true;
					Plugin.Log.LogError((object)$"SealCare failed (logged once): {arg}");
				}
			}
		}

		private static void LogTakeover(long owner)
		{
			//IL_0028: Unknown result type (might be due to invalid IL or missing references)
			//IL_002d: Unknown result type (might be due to invalid IL or missing references)
			//IL_002e: 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_0034: Unknown result type (might be due to invalid IL or missing references)
			//IL_003f: Unknown result type (might be due to invalid IL or missing references)
			if (!s_takenFrom.Add(owner))
			{
				return;
			}
			string text = "a player";
			foreach (PlayerInfo player in ZNet.instance.GetPlayerList())
			{
				ZDOID characterID = player.m_characterID;
				if (((ZDOID)(ref characterID)).UserID == owner)
				{
					text = player.m_name;
				}
			}
			Plugin.Log.LogInfo((object)("Took over seals from " + text + ": their game doesn't run SealsAtHome (logged once per player)"));
		}

		private void GrowUp()
		{
			//IL_0038: 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)
			GameObject val = (((Object)(object)ZNetScene.instance != (Object)null) ? ZNetScene.instance.GetPrefab("Seal") : null);
			if (!((Object)(object)val == (Object)null))
			{
				m_grown = true;
				Character component = Object.Instantiate<GameObject>(val, ((Component)this).transform.position, ((Component)this).transform.rotation).GetComponent<Character>();
				if ((Object)(object)component != (Object)null)
				{
					component.SetTamed(true);
					component.SetLevel(m_character.GetLevel());
				}
				m_nview.Destroy();
			}
		}
	}
	internal static class SealRebuild
	{
		private const string TameableSealsGuid = "pseudopulse.TameableSeals";

		public static bool Run(ZNetScene scene, out string message)
		{
			GameObject prefab = scene.GetPrefab("Seal");
			GameObject prefab2 = scene.GetPrefab("Seal_Pup");
			if (IsRebuilt(prefab) && IsRebuilt(prefab2))
			{
				message = "Seals already rebuilt (the prefabs survived the scene change)";
				return true;
			}
			string text = PreFlight(scene, prefab, prefab2);
			if (text != null)
			{
				message = "SealsAtHome leaves the seals alone: " + text;
				return false;
			}
			(GameObject, bool)[] array = new(GameObject, bool)[2]
			{
				(prefab, false),
				(prefab2, true)
			};
			for (int i = 0; i < array.Length; i++)
			{
				(GameObject, bool) tuple = array[i];
				GameObject item = tuple.Item1;
				bool item2 = tuple.Item2;
				text = Rebuild(scene, item, item2);
				if (text != null)
				{
					message = "Seals stay (partly) vanilla: " + text;
					return false;
				}
			}
			message = "Seal and Seal_Pup rebuilt: seals are tameable";
			return true;
		}

		private static bool IsRebuilt(GameObject prefab)
		{
			if ((Object)(object)prefab != (Object)null)
			{
				return (Object)(object)prefab.GetComponent<SealCare>() != (Object)null;
			}
			return false;
		}

		private static string PreFlight(ZNetScene scene, GameObject seal, GameObject pup)
		{
			if (Chainloader.PluginInfos.ContainsKey("pseudopulse.TameableSeals"))
			{
				return "TameableSeals (pseudopulse) is installed and changes seals too: remove one of the two mods";
			}
			foreach (string requiredPrefab in SealSettings.RequiredPrefabs)
			{
				if ((Object)(object)scene.GetPrefab(requiredPrefab) == (Object)null)
				{
					return "the game has no prefab '" + requiredPrefab + "' (game update?)";
				}
			}
			if ((Object)(object)scene.GetPrefab("FishRaw").GetComponent<ItemDrop>() == (Object)null)
			{
				return "FishRaw is not an item (game update?)";
			}
			foreach (FieldSetting item in SealSettings.All)
			{
				string text = SealSettings.Check(item);
				if (text != null)
				{
					return text + " (game update?)";
				}
			}
			GameObject[] array = (GameObject[])(object)new GameObject[2] { seal, pup };
			foreach (GameObject val in array)
			{
				if ((Object)(object)val.GetComponent<Tameable>() != (Object)null || (Object)(object)val.GetComponent<MonsterAI>() != (Object)null || (Object)(object)val.GetComponent<Procreation>() != (Object)null)
				{
					return ((Object)val).name + " was already changed by another mod (it has a Tameable, MonsterAI or Procreation)";
				}
				Character[] components = val.GetComponents<Character>();
				if (components.Length != 1 || ((object)components[0]).GetType() != typeof(Character))
				{
					return ((Object)val).name + "'s body isn't a plain Character (game update or another mod)";
				}
				if (val.GetComponents<BaseAI>().Length != 1 || (Object)(object)val.GetComponent<AnimalAI>() == (Object)null)
				{
					return ((Object)val).name + "'s AI isn't a single AnimalAI (game update or another mod)";
				}
			}
			return null;
		}

		private static string Rebuild(ZNetScene scene, GameObject prefab, bool isPup)
		{
			Humanoid val = ComponentSwap.Replace<Humanoid>(prefab, (Component)(object)prefab.GetComponent<Character>(), typeof(Character));
			if ((Object)(object)val == (Object)null)
			{
				return "Unity refused to swap " + ((Object)prefab).name + "'s Character for a Humanoid";
			}
			EmptyItemLists(val);
			MonsterAI val2 = ComponentSwap.Replace<MonsterAI>(prefab, (Component)(object)prefab.GetComponent<AnimalAI>(), typeof(BaseAI));
			if ((Object)(object)val2 == (Object)null)
			{
				return "Unity refused to swap " + ((Object)prefab).name + "'s AnimalAI for a MonsterAI";
			}
			SettingsApplier.Apply((Component)(object)val, SealSettings.HumanoidFor(isPup), Prefab);
			SettingsApplier.Apply((Component)(object)val2, SealSettings.WildSwitch.Concat(SealSettings.AI), Prefab);
			SettingsApplier.Apply((Component)(object)prefab.AddComponent<Tameable>(), SealSettings.TameableFor(isPup), Prefab);
			if (!isPup)
			{
				SettingsApplier.Apply((Component)(object)prefab.AddComponent<Procreation>(), SealSettings.Breeding, Prefab);
			}
			prefab.AddComponent<SealCare>().m_isPup = isPup;
			return null;
			GameObject Prefab(string name)
			{
				return scene.GetPrefab(name);
			}
		}

		private static void EmptyItemLists(Humanoid body)
		{
			body.m_defaultItems = (GameObject[])(object)new GameObject[0];
			body.m_randomWeapon = (GameObject[])(object)new GameObject[0];
			body.m_randomArmor = (GameObject[])(object)new GameObject[0];
			body.m_randomShield = (GameObject[])(object)new GameObject[0];
			body.m_randomSets = (ItemSet[])(object)new ItemSet[0];
			body.m_randomItems = (RandomItem[])(object)new RandomItem[0];
		}
	}
	internal static class PupGrowth
	{
		public enum Step
		{
			Wait,
			Stamp,
			Grow
		}

		public static Step Decide(bool tamed, string name, long tamedAtTicks, long nowTicks)
		{
			if (!tamed)
			{
				return Step.Wait;
			}
			if (tamedAtTicks <= 0 || tamedAtTicks > nowTicks)
			{
				return Step.Stamp;
			}
			if (!string.IsNullOrWhiteSpace(name))
			{
				return Step.Wait;
			}
			if (nowTicks - tamedAtTicks < 30000000000L)
			{
				return Step.Wait;
			}
			return Step.Grow;
		}
	}
	internal static class NameCopy
	{
		public static string Target(string tamedName)
		{
			string text = ((tamedName != null) ? StringExtensionMethods.RemoveRichTextTags(tamedName) : null);
			if (!string.IsNullOrWhiteSpace(text))
			{
				return text;
			}
			return "";
		}

		public static bool ShouldWrite(string tamedName, string shown)
		{
			return Target(tamedName) != (shown ?? "");
		}
	}
	internal static class Takeover
	{
		private static readonly long BeatTicks = 100000000L;

		private static readonly long StaleTicks = 300000000L;

		public static bool ShouldBeat(long beatTicks, long nowTicks)
		{
			if (beatTicks > 0 && beatTicks <= nowTicks)
			{
				return nowTicks - beatTicks >= BeatTicks;
			}
			return true;
		}

		public static bool ShouldClaim(bool isOwner, long owner, long beatTicks, long nowTicks)
		{
			if (!isOwner && owner != 0L)
			{
				if (beatTicks > 0 && beatTicks <= nowTicks)
				{
					return nowTicks - beatTicks > StaleTicks;
				}
				return true;
			}
			return false;
		}
	}
	internal enum SettingKind
	{
		Value,
		Effects,
		Prefab,
		Items
	}
	internal sealed class FieldSetting
	{
		public readonly Type Component;

		public readonly string Field;

		public readonly SettingKind Kind;

		public readonly object Value;

		public Type ExpectedFieldType => Kind switch
		{
			SettingKind.Effects => typeof(EffectList), 
			SettingKind.Prefab => typeof(GameObject), 
			SettingKind.Items => typeof(List<ItemDrop>), 
			_ => Value.GetType(), 
		};

		public IEnumerable<string> PrefabNames
		{
			get
			{
				switch (Kind)
				{
				case SettingKind.Effects:
				case SettingKind.Items:
					return (string[])Value;
				case SettingKind.Prefab:
					return new string[1] { (string)Value };
				default:
					return Enumerable.Empty<string>();
				}
			}
		}

		private FieldSetting(Type component, string field, SettingKind kind, object value)
		{
			Component = component;
			Field = field;
			Kind = kind;
			Value = value;
		}

		public static FieldSetting Of<T>(string field, object value)
		{
			return new FieldSetting(typeof(T), field, SettingKind.Value, value);
		}

		public static FieldSetting Effects<T>(string field, params string[] prefabs)
		{
			return new FieldSetting(typeof(T), field, SettingKind.Effects, prefabs);
		}

		public static FieldSetting Prefab<T>(string field, string prefab)
		{
			return new FieldSetting(typeof(T), field, SettingKind.Prefab, prefab);
		}

		public static FieldSetting Items<T>(string field, params string[] items)
		{
			return new FieldSetting(typeof(T), field, SettingKind.Items, items);
		}

		public override string ToString()
		{
			return Component.Name + "." + Field;
		}
	}
	internal static class SealSettings
	{
		public const string SealPrefab = "Seal";

		public const string PupPrefab = "Seal_Pup";

		public const string RawFish = "FishRaw";

		public const string SealSound = "sfx_seal_idle";

		public const string PupSound = "sfx_babyseal_idle";

		public const string Hearts = "vfx_creature_soothed";

		public const string TamedEffect = "fx_creature_tamed";

		public const string PetHearts = "vfx_lox_love";

		public const string LoveHearts = "vfx_boar_love";

		public const string BirthSplash = "vfx_boar_birth";

		public const double GrowSeconds = 3000.0;

		public const string TamedAtKey = "SealsAtHome_TamedAt";

		public const string BeatKey = "SealsAtHome_Beat";

		public const double BeatSeconds = 10.0;

		public const double StaleSeconds = 30.0;

		public static readonly FieldSetting[] WildSwitch = new FieldSetting[2]
		{
			FieldSetting.Of<MonsterAI>("m_alertRange", 0f),
			FieldSetting.Of<MonsterAI>("m_fleeIfNotAlerted", true)
		};

		public static readonly FieldSetting[] TamedSwitch = new FieldSetting[2]
		{
			FieldSetting.Of<MonsterAI>("m_alertRange", 10f),
			FieldSetting.Of<MonsterAI>("m_fleeIfNotAlerted", false)
		};

		public static readonly FieldSetting[] AI = new FieldSetting[11]
		{
			FieldSetting.Of<MonsterAI>("m_fleeIfLowHealth", 1f),
			FieldSetting.Of<MonsterAI>("m_fleeTimeSinceHurt", 15f),
			FieldSetting.Of<MonsterAI>("m_aggravatable", false),
			FieldSetting.Of<MonsterAI>("m_attackPlayerObjects", false),
			FieldSetting.Of<MonsterAI>("m_enableHuntPlayer", false),
			FieldSetting.Of<MonsterAI>("m_sleeping", false),
			FieldSetting.Of<MonsterAI>("m_avoidLand", false),
			FieldSetting.Of<MonsterAI>("m_consumeRange", 1f),
			FieldSetting.Of<MonsterAI>("m_consumeSearchRange", 10f),
			FieldSetting.Of<MonsterAI>("m_consumeSearchInterval", 10f),
			FieldSetting.Items<MonsterAI>("m_consumeItems", new string[1] { "FishRaw" })
		};

		public static readonly FieldSetting[] Breeding = new FieldSetting[12]
		{
			FieldSetting.Of<Procreation>("m_updateInterval", 30f),
			FieldSetting.Of<Procreation>("m_totalCheckRange", 10f),
			FieldSetting.Of<Procreation>("m_maxCreatures", 5),
			FieldSetting.Of<Procreation>("m_partnerCheckRange", 3f),
			FieldSetting.Of<Procreation>("m_pregnancyChance", 0.33f),
			FieldSetting.Of<Procreation>("m_pregnancyDuration", 60f),
			FieldSetting.Of<Procreation>("m_requiredLovePoints", 3),
			FieldSetting.Prefab<Procreation>("m_offspring", "Seal_Pup"),
			FieldSetting.Of<Procreation>("m_minOffspringLevel", 0),
			FieldSetting.Of<Procreation>("m_spawnOffset", 1f),
			FieldSetting.Effects<Procreation>("m_loveEffects", new string[2] { "vfx_boar_love", "sfx_seal_idle" }),
			FieldSetting.Effects<Procreation>("m_birthEffects", new string[2] { "vfx_boar_birth", "sfx_babyseal_idle" })
		};

		public static IEnumerable<FieldSetting> All => WildSwitch.Concat(TamedSwitch).Concat(AI).Concat(TameableFor(pup: false))
			.Concat(TameableFor(pup: true))
			.Concat(Breeding)
			.Concat(HumanoidFor(pup: false))
			.Concat(HumanoidFor(pup: true));

		public static IEnumerable<string> RequiredPrefabs => new string[2] { "Seal", "Seal_Pup" }.Concat(All.SelectMany((FieldSetting s) => s.PrefabNames)).Distinct();

		public static FieldSetting[] TameableFor(bool pup)
		{
			return new FieldSetting[11]
			{
				FieldSetting.Of<Tameable>("m_tamingTime", 1800f),
				FieldSetting.Of<Tameable>("m_fedDuration", 600f),
				FieldSetting.Of<Tameable>("m_commandable", true),
				FieldSetting.Of<Tameable>("m_startsTamed", false),
				FieldSetting.Of<Tameable>("m_unsummonDistance", 0f),
				FieldSetting.Of<Tameable>("m_unsummonOnOwnerLogoutSeconds", 0f),
				FieldSetting.Of<Tameable>("m_tamingSpeedMultiplierRange", 60f),
				FieldSetting.Of<Tameable>("m_tamingBoostMultiplier", 2f),
				FieldSetting.Effects<Tameable>("m_sootheEffect", new string[1] { "vfx_creature_soothed" }),
				FieldSetting.Effects<Tameable>("m_tamedEffect", new string[1] { "fx_creature_tamed" }),
				FieldSetting.Effects<Tameable>("m_petEffect", new string[2]
				{
					"vfx_lox_love",
					pup ? "sfx_babyseal_idle" : "sfx_seal_idle"
				})
			};
		}

		public static FieldSetting[] HumanoidFor(bool pup)
		{
			return new FieldSetting[1] { FieldSetting.Effects<Humanoid>("m_consumeItemEffects", new string[1] { pup ? "sfx_babyseal_idle" : "sfx_seal_idle" }) };
		}

		public static string Check(FieldSetting setting)
		{
			FieldInfo field = setting.Component.GetField(setting.Field, BindingFlags.Instance | BindingFlags.Public);
			if (field == null)
			{
				return $"{setting} doesn't exist";
			}
			if (field.FieldType != setting.ExpectedFieldType)
			{
				return $"{setting} is a {field.FieldType.Name}, not a {setting.ExpectedFieldType.Name}";
			}
			return null;
		}
	}
	internal static class SettingsApplier
	{
		public static void Apply(Component target, IEnumerable<FieldSetting> settings, Func<string, GameObject> prefab)
		{
			foreach (FieldSetting setting in settings)
			{
				setting.Component.GetField(setting.Field, BindingFlags.Instance | BindingFlags.Public).SetValue(target, Resolve(setting, prefab));
			}
		}

		private static object Resolve(FieldSetting setting, Func<string, GameObject> prefab)
		{
			//IL_002a: 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_0052: Expected O, but got Unknown
			return setting.Kind switch
			{
				SettingKind.Effects => (object)new EffectList
				{
					m_effectPrefabs = setting.PrefabNames.Select((Func<string, EffectData>)((string n) => new EffectData
					{
						m_prefab = prefab(n)
					})).ToArray()
				}, 
				SettingKind.Prefab => prefab((string)setting.Value), 
				SettingKind.Items => setting.PrefabNames.Select((string n) => prefab(n).GetComponent<ItemDrop>()).ToList(), 
				_ => setting.Value, 
			};
		}
	}
	internal static class UnitySerialization
	{
		public static bool IsSerialized(FieldInfo field)
		{
			if (field.IsStatic || field.IsInitOnly || field.IsLiteral)
			{
				return false;
			}
			if (typeof(Delegate).IsAssignableFrom(field.FieldType))
			{
				return false;
			}
			if (field.IsPublic)
			{
				return !field.IsNotSerialized;
			}
			return ((MemberInfo)field).GetCustomAttribute<SerializeField>() != null;
		}

		public static IEnumerable<FieldInfo> SerializedFields(Type type)
		{
			Type t = type;
			while (t != null && t != typeof(MonoBehaviour) && t != typeof(object))
			{
				FieldInfo[] fields = t.GetFields(BindingFlags.DeclaredOnly | BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
				foreach (FieldInfo fieldInfo in fields)
				{
					if (IsSerialized(fieldInfo))
					{
						yield return fieldInfo;
					}
				}
				t = t.BaseType;
			}
		}
	}
	internal static class PluginInfo
	{
		public const string Version = "1.0.1";
	}
}