Decompiled source of ServersideQoL TameAssist v2.1.0

ServersideQoL.TameAssist.dll

Decompiled a month ago
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Linq.Expressions;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using System.Text;
using BepInEx;
using BepInEx.Configuration;
using Microsoft.CodeAnalysis;
using ServersideQoL.Processors;
using ServersideQoL.Utilities;
using UnityEngine;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")]
[assembly: AssemblyCompany("ArgusMagnus")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyCopyright("ArgusMagnus")]
[assembly: AssemblyDescription("Configure various aspects around tameable creatures. Allow all tames to follow you, even through portals and into dungeons. Show taming and growing up/hatching progress to nearby players.")]
[assembly: AssemblyFileVersion("2.1.0.0")]
[assembly: AssemblyInformationalVersion("2.1.0+204f9f33466a3fbfe830fe172b162a96aaba64cd")]
[assembly: AssemblyProduct("ServersideQoL.TameAssist")]
[assembly: AssemblyTitle("ServersideQoL.TameAssist")]
[assembly: AssemblyMetadata("RepositoryUrl", "https://github.com/ArgusMagnus/ValheimServersideQoL")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("2.1.0.0")]
[module: UnverifiableCode]
[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;
		}
	}
}
namespace ServersideQoL.TameAssist
{
	public sealed class Config : ConfigBase<Config>
	{
		public sealed class AdvancedConfig
		{
			public sealed record TeleportFollowPositioningConfig(float MinDistXZ, float MaxDistXZ, float MinOffsetY, float MaxOffsetY, float HalfArcXZ)
			{
				private TeleportFollowPositioningConfig()
					: this(0f, 0f, 0f, 0f, 0f)
				{
				}
			}

			public TeleportFollowPositioningConfig TeleportFollowPositioning { get; init; } = new TeleportFollowPositioningConfig(2f, 4f, 0f, 1f, 45f);
		}

		public sealed class LocalizationConfig
		{
			private string Growing { get; init; } = "$caption_growing {0}%";

			private string Taming { get; init; } = "$hud_tameness {0:P0}";

			private string TamingHungry { get; init; } = "$hud_tameness {0:P0}, $hud_tamehungry";

			private string TameFed { get; init; } = "{0}: $msg_added {1}";

			public string FormatGrowing(int percent)
			{
				return string.Format(Growing, percent);
			}

			public string FormatTaming(float tameness, bool isHungry)
			{
				if (!isHungry)
				{
					return string.Format(Taming, tameness);
				}
				return string.Format(TamingHungry, tameness);
			}

			public string FormatTameFed(string tameName, string itemName)
			{
				return string.Format(TameFed, tameName, itemName);
			}
		}

		private const string DefaultRangeEmoji = "\ud83d\udc17";

		public override ConfigEntry<bool> Enabled { get; } = ConfigBase<Config>.BindEx<bool>(cfg, true, "Enables/disables the entire mod", (AcceptableValueBase)null, (Deprecated<Config>)null, "Enabled");

		public ConfigEntry<bool> MakeCommandable { get; } = ConfigBase<Config>.BindEx<bool>(cfg, false, "True to make all tames commandable (like wolves)", (AcceptableValueBase)null, (Deprecated<Config>)null, "MakeCommandable");

		public ConfigEntry<MessageTypes> TamingProgressMessageType { get; } = ConfigBase<Config>.BindEx<MessageTypes>(cfg, (MessageTypes)5, "Type of taming progress messages to show", (AcceptableValueBase)(object)AcceptableEnum<MessageTypes>.Default, (Deprecated<Config>)null, "TamingProgressMessageType");

		public ConfigEntry<MessageTypes> GrowingProgressMessageType { get; } = ConfigBase<Config>.BindEx<MessageTypes>(cfg, (MessageTypes)5, "Type of growing progress messages to show", (AcceptableValueBase)(object)AcceptableEnum<MessageTypes>.Default, (Deprecated<Config>)null, "GrowingProgressMessageType");

		public ConfigEntry<float> FedDurationMultiplier { get; } = ConfigBase<Config>.BindEx<float>(cfg, 1f, FormattableString.Invariant($"Multiply the time tames stay fed after they have eaten by this factor. {float.PositiveInfinity} to keep them fed indefinitely"), (AcceptableValueBase)null, (Deprecated<Config>)null, "FedDurationMultiplier");

		public ConfigEntry<float> TamingTimeMultiplier { get; } = ConfigBase<Config>.BindEx<float>(cfg, 1f, "Multiply the time it takes to tame a tameable creature by this factor.\r\nE.g. a value of 0.5 means that the taming time is halved.", (AcceptableValueBase)null, (Deprecated<Config>)null, "TamingTimeMultiplier");

		public ConfigEntry<float> PotionTamingBoostMultiplier { get; } = ConfigBase<Config>.BindEx<float>(cfg, 1f, "Multiply the taming boost from the animal whispers potion by this factor.\r\nE.g. a value of 2 means that the effect of the potion is doubled and the resulting taming time is reduced by a factor of 4 per player.", (AcceptableValueBase)null, (Deprecated<Config>)null, "PotionTamingBoostMultiplier");

		public ConfigEntry<bool> TeleportFollowers { get; } = ConfigBase<Config>.BindEx<bool>(cfg, true, "True to teleport following tames and summons to the players location if the player gets too far away from them", (AcceptableValueBase)null, (Deprecated<Config>)null, "TeleportFollowers");

		public ConfigEntry<float> TeleportFollowersMinDistance { get; } = ConfigBase<Config>.BindEx<float>(cfg, 64f, "Minimum distance from the player at which followers will be teleported to the player's location", (AcceptableValueBase)null, (Deprecated<Config>)null, "TeleportFollowersMinDistance");

		public ConfigEntry<bool> TakeIntoDungeons { get; } = ConfigBase<Config>.BindEx<bool>(cfg, true, "True to take followers into (and out of) dungeons with the player", (AcceptableValueBase)null, (Deprecated<Config>)null, "TakeIntoDungeons");

		public ConfigEntry<bool> FeedFromContainers { get; } = Shared.TameAssistFeedFromContainers = ConfigBase<Config>.BindEx<bool>(cfg, false, "True to automatically feed tames from nearby containers", (AcceptableValueBase)null, (Deprecated<Config>)null, "FeedFromContainers");

		public ConfigEntry<float> FeedFromContainersRange { get; } = ConfigBase<Config>.BindEx<float>(cfg, 0f, "Required proximity of a container to a tame to be used as feeding source.\r\nCan be overridden per chest by putting '<FeedFromContainersRangeSignPrefix><Range>' on a chest sign, e.g. '\ud83d\udc1764'.\r\n  For example, '\ud83d\udc1764' increase the range of that chest to 64m.\r\n  Only works with automatic chest signs added by the ServersideQoL.ContainerSigns mod.", (AcceptableValueBase)null, (Deprecated<Config>)null, "FeedFromContainersRange");

		public ConfigEntry<string> FeedFromContainersRangeSignPrefix { get; } = Shared.TameAssistFeedFromContainersRangeSignPrefix = ConfigBase<Config>.BindEx<string>(cfg, "\ud83d\udc17", "Requires the ServersideQoL.ContainerSigns mod.\r\nThe prefix used to identify the container specifc feed range value in chest sign text.", (AcceptableValueBase)null, (Deprecated<Config>)null, "FeedFromContainersRangeSignPrefix");

		public ConfigEntry<int> FeedFromContainersMaxRange { get; } = Shared.TameAssistFeedFromContainersMaxRange = ConfigBase<Config>.BindEx<int>(cfg, 64, "Requires the ServersideQoL.ContainerSigns mod.\r\nMax feeding range players can set per chest (by putting '<FeedFromContainersRangeSignPrefix><Range>' on a chest sign)", (AcceptableValueBase)null, (Deprecated<Config>)null, "FeedFromContainersMaxRange");

		public ConfigEntry<int> FeedFromContainersLeaveAtLeast { get; } = ConfigBase<Config>.BindEx<int>(cfg, 1, "Minimum amount of any given food item type to leave in a container", (AcceptableValueBase)null, (Deprecated<Config>)null, "FeedFromContainersLeaveAtLeast");

		public ConfigEntry<MessageTypes> TameFedMessageType { get; } = ConfigBase<Config>.BindEx<MessageTypes>(cfg, (MessageTypes)0, "Type of message to show when a time was fed from a container", (AcceptableValueBase)(object)AcceptableEnum<MessageTypes>.Default, (Deprecated<Config>)null, "TameFedMessageType");

		public YamlConfigEntry<AdvancedConfig> Advanced { get; } = ConfigBase<Config>.BindYaml<AdvancedConfig>(cfg, "Advanced");

		public YamlConfigEntry<LocalizationConfig> Localization { get; } = ConfigBase<Config>.BindYaml<LocalizationConfig>(cfg, "Localization");

		public Config(ConfigFile cfg, Logger logger)
			: base(cfg, logger)
		{
		}
	}
	[Processor("b8e21b8f-0264-4f45-9b64-b167627a9079")]
	public sealed class GrowingProcessor : Processor<GrowingProcessor.PrefabInfo>
	{
		public sealed record PrefabInfo(EggGrow? EggGrow, Growup? Growup) : ProcessorPrefabInfo()
		{
			[CompilerGenerated]
			public override string ToString()
			{
				StringBuilder stringBuilder = new StringBuilder();
				stringBuilder.Append("PrefabInfo");
				stringBuilder.Append(" { ");
				if (((ProcessorPrefabInfo)this).PrintMembers(stringBuilder))
				{
					stringBuilder.Append(' ');
				}
				stringBuilder.Append('}');
				return stringBuilder.ToString();
			}

			[CompilerGenerated]
			protected override bool PrintMembers(StringBuilder builder)
			{
				if (((ProcessorPrefabInfo)this).PrintMembers(builder))
				{
					builder.Append(", ");
				}
				builder.Append("EggGrow = ");
				builder.Append(EggGrow);
				builder.Append(", Growup = ");
				builder.Append(Growup);
				return true;
			}

			[CompilerGenerated]
			public override int GetHashCode()
			{
				return (((ProcessorPrefabInfo)this).GetHashCode() * -1521134295 + EqualityComparer<EggGrow>.Default.GetHashCode(EggGrow)) * -1521134295 + EqualityComparer<Growup>.Default.GetHashCode(Growup);
			}

			[CompilerGenerated]
			public sealed override bool Equals(ProcessorPrefabInfo? other)
			{
				return ((object)this).Equals((object?)other);
			}

			[CompilerGenerated]
			public bool Equals(PrefabInfo? other)
			{
				if ((object)this != other)
				{
					if (((ProcessorPrefabInfo)this).Equals((ProcessorPrefabInfo)(object)other) && EqualityComparer<EggGrow>.Default.Equals(EggGrow, other.EggGrow))
					{
						return EqualityComparer<Growup>.Default.Equals(Growup, other.Growup);
					}
					return false;
				}
				return true;
			}

			[CompilerGenerated]
			private PrefabInfo(PrefabInfo original)
				: base((ProcessorPrefabInfo)(object)original)
			{
				EggGrow = original.EggGrow;
				Growup = original.Growup;
			}
		}

		private sealed class State
		{
			public Timestamp NextMessage { get; set; }

			public int Progress { get; set; } = -1;
		}

		public const string Id = "b8e21b8f-0264-4f45-9b64-b167627a9079";

		private readonly Dictionary<ServersideQoLZDO, State> _states = new Dictionary<ServersideQoLZDO, State>();

		private static float MessageDelay => DamageText.instance.m_textDuration;

		protected override void Initialize()
		{
			_states.Clear();
		}

		protected override ProcessResult Process(ServersideQoLZDO zdo, IReadOnlyList<Peer> peers, PrefabInfo prefabInfo)
		{
			//IL_000a: 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_004d: Unknown result type (might be due to invalid IL or missing references)
			//IL_004f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0054: 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_00b1: 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_007f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0084: Unknown result type (might be due to invalid IL or missing references)
			//IL_016b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0126: Unknown result type (might be due to invalid IL or missing references)
			//IL_015a: Unknown result type (might be due to invalid IL or missing references)
			if ((int)ConfigBase<Config>.Instance.GrowingProgressMessageType.Value == 0)
			{
				return (ProcessResult)2;
			}
			if (!_states.TryGetValue(zdo, out State value))
			{
				_states.Add(zdo, value = new State());
				zdo.Destroyed += delegate(ServersideQoLZDO x)
				{
					_states.Remove(x);
				};
			}
			Timestamp now = Timestamp.Now;
			Timestamp nextMessage = value.NextMessage;
			float num = ((Timestamp)(ref nextMessage)).Seconds - ((Timestamp)(ref now)).Seconds;
			if (num > 0f)
			{
				return ((Processor)this).ScheduleReprocessing(num);
			}
			ZDOVars vars;
			double num2;
			if (prefabInfo.EggGrow == null)
			{
				vars = zdo.Vars;
				num2 = new TimeSpan(((ZDOVars)(ref vars)).GetSpawnTime(default(DateTime)).Ticks).TotalSeconds;
			}
			else
			{
				vars = zdo.Vars;
				num2 = ((ZDOVars)(ref vars)).GetGrowStart(0f);
			}
			double num3 = num2;
			if (num3 == 0.0)
			{
				return (ProcessResult)0;
			}
			float num4 = prefabInfo.EggGrow?.m_growTime ?? prefabInfo.Growup.m_growTime;
			float num5 = (float)(ZNet.instance.GetTimeSeconds() - num3);
			int num6 = (int)(100f * Mathf.Clamp01(num5 / num4));
			if (value.Progress != num6)
			{
				value.NextMessage = ((Timestamp)(ref now)).AddSeconds(MessageDelay);
				value.Progress = num6;
				Processor.ShowMessage((IEnumerable<Peer>)peers, zdo, ConfigBase<Config>.Instance.Localization.Value.FormatGrowing(num6), ConfigBase<Config>.Instance.GrowingProgressMessageType.Value, (TextType)0);
			}
			return ((Processor)this).ScheduleReprocessing(MessageDelay);
		}
	}
	[Processor("72a96de3-a080-4177-ba59-c0142d4632c9")]
	[DependsOn<TameableRegistryProcessor>]
	[RunAfter<PlayerRegistryProcessor>]
	public sealed class PlayerProcessor : Processor<ProcessorPrefabInfo<Player>>
	{
		private sealed class State(PlayerState playerState)
		{
			public PlayerState PlayerState { get; } = playerState;

			public Vector3? InitialInInteriorPosition { get; set; }
		}

		public const string Id = "72a96de3-a080-4177-ba59-c0142d4632c9";

		private readonly Dictionary<ServersideQoLZDO, State> _states = new Dictionary<ServersideQoLZDO, State>();

		protected override void Initialize()
		{
			_states.Clear();
		}

		protected override ProcessResult Process(ServersideQoLZDO zdo, IReadOnlyList<Peer> peers, ProcessorPrefabInfo<Player> prefabInfo)
		{
			//IL_007b: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ea: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ef: Unknown result type (might be due to invalid IL or missing references)
			//IL_0112: 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_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_0144: Unknown result type (might be due to invalid IL or missing references)
			//IL_0149: Unknown result type (might be due to invalid IL or missing references)
			//IL_014e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0153: Unknown result type (might be due to invalid IL or missing references)
			//IL_016b: Unknown result type (might be due to invalid IL or missing references)
			//IL_018b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0190: Unknown result type (might be due to invalid IL or missing references)
			//IL_0192: Unknown result type (might be due to invalid IL or missing references)
			//IL_01aa: Unknown result type (might be due to invalid IL or missing references)
			//IL_01af: 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_01e0: Unknown result type (might be due to invalid IL or missing references)
			Config instance = ConfigBase<Config>.Instance;
			if (instance != null)
			{
				ConfigEntry<bool> teleportFollowers = instance.TeleportFollowers;
				if (teleportFollowers != null && !teleportFollowers.Value)
				{
					ConfigEntry<bool> takeIntoDungeons = instance.TakeIntoDungeons;
					if (takeIntoDungeons != null && !takeIntoDungeons.Value)
					{
						return (ProcessResult)2;
					}
				}
			}
			if (!_states.TryGetValue(zdo, out State value))
			{
				_states.Add(zdo, value = new State(Processor.Instance<PlayerRegistryProcessor>().GetState(zdo)));
				zdo.Destroyed += delegate(ServersideQoLZDO x)
				{
					_states.Remove(x);
				};
			}
			if (!Character.InInterior(zdo.ZDO.GetPosition()))
			{
				value.InitialInInteriorPosition = null;
			}
			else if (!value.InitialInInteriorPosition.HasValue)
			{
				value.InitialInInteriorPosition = zdo.ZDO.GetPosition();
			}
			IReadOnlyList<TameableState> followers = Processor.Instance<TameableRegistryProcessor>().GetFollowers(value.PlayerState.PlayerName);
			if (followers != null && followers.Count > 0)
			{
				Vector2s playerZone = zdo.ZDO.GetSector();
				foreach (TameableState item in followers)
				{
					if (ShouldTeleport(in playerZone, item.ZDO.ZDO.GetSector(), zdo, item.ZDO, value))
					{
						Vector3 position = zdo.ZDO.GetPosition();
						Vector3 val = zdo.ZDO.GetRotation() * Vector3.forward;
						Config.AdvancedConfig.TeleportFollowPositioningConfig teleportFollowPositioning = ConfigBase<Config>.Instance.Advanced.Value.TeleportFollowPositioning;
						position += Quaternion.Euler(0f, Random.Range(0f - teleportFollowPositioning.HalfArcXZ, teleportFollowPositioning.HalfArcXZ), 0f) * val * Random.Range(teleportFollowPositioning.MinDistXZ, teleportFollowPositioning.MaxDistXZ);
						position.y += Random.Range(teleportFollowPositioning.MinOffsetY, teleportFollowPositioning.MaxOffsetY);
						item.ZDO.ZDO.SetPosition(position);
						item.ZDO.Recreate();
					}
				}
				return (ProcessResult)0;
			}
			return (ProcessResult)0;
		}

		private bool ShouldTeleport(in Vector2s playerZone, in Vector2s tameZone, ServersideQoLZDO player, ServersideQoLZDO tame, State state)
		{
			//IL_0017: 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_0088: 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_00a6: Unknown result type (might be due to invalid IL or missing references)
			//IL_0051: Unknown result type (might be due to invalid IL or missing references)
			//IL_005c: Unknown result type (might be due to invalid IL or missing references)
			if (ConfigBase<Config>.Instance.TakeIntoDungeons.Value && Character.InInterior(player.ZDO.GetPosition()) != Character.InInterior(tame.ZDO.GetPosition()))
			{
				if (!state.InitialInInteriorPosition.HasValue)
				{
					return true;
				}
				if (Utils.DistanceXZ(state.InitialInInteriorPosition.Value, player.ZDO.GetPosition()) > 0.5f)
				{
					return true;
				}
				return false;
			}
			if (ConfigBase<Config>.Instance.TeleportFollowers.Value && !Character.InInterior(player.ZDO.GetPosition()))
			{
				if (Utils.DistanceXZ(player.ZDO.GetPosition(), tame.ZDO.GetPosition()) >= ConfigBase<Config>.Instance.TeleportFollowersMinDistance.Value)
				{
					return true;
				}
				return false;
			}
			return false;
		}
	}
	[Processor("4386fb2c-2092-4f88-a173-9f01fadcbc6c")]
	[RunAfter<TameableRegistryProcessor>]
	[DependsOn<ContainerRegistryProcessor>]
	public sealed class TameableProcessor : Processor<PrefabInfo>
	{
		public sealed class TamingState
		{
			public Timestamp NextMessage { get; set; }
		}

		public const string Id = "4386fb2c-2092-4f88-a173-9f01fadcbc6c";

		private readonly Dictionary<ServersideQoLZDO, TamingState> _tamingStates = new Dictionary<ServersideQoLZDO, TamingState>();

		private SectorDictionary<SharedItemDataKey, HashSet<ServersideQoLZDO>>? _containersByItemName;

		protected override void Initialize()
		{
			_tamingStates.Clear();
			_containersByItemName = (ConfigBase<Config>.Instance.FeedFromContainers.Value ? Processor.Instance<ContainerRegistryProcessor>().GetContainersByItemName(Mathf.Max(ConfigBase<Config>.Instance.FeedFromContainersRange.Value, (float)ConfigBase<Config>.Instance.FeedFromContainersMaxRange.Value)) : null);
		}

		protected override ProcessResult Process(ServersideQoLZDO zdo, IReadOnlyList<Peer> peers, PrefabInfo prefabInfo)
		{
			//IL_0014: 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_001b: Unknown result type (might be due to invalid IL or missing references)
			//IL_001c: Unknown result type (might be due to invalid IL or missing references)
			//IL_001e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0020: Invalid comparison between Unknown and I4
			//IL_0108: Unknown result type (might be due to invalid IL or missing references)
			//IL_010e: Invalid comparison between Unknown and I4
			//IL_0044: 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_004b: Unknown result type (might be due to invalid IL or missing references)
			//IL_01e3: Unknown result type (might be due to invalid IL or missing references)
			//IL_01e9: Invalid comparison between Unknown and I4
			//IL_004f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0053: Invalid comparison between Unknown and I4
			//IL_0437: Unknown result type (might be due to invalid IL or missing references)
			//IL_043d: Invalid comparison between Unknown and I4
			//IL_046e: Unknown result type (might be due to invalid IL or missing references)
			//IL_043f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0441: Unknown result type (might be due to invalid IL or missing references)
			//IL_0444: Unknown result type (might be due to invalid IL or missing references)
			//IL_0447: Unknown result type (might be due to invalid IL or missing references)
			//IL_0448: Unknown result type (might be due to invalid IL or missing references)
			//IL_0103: Unknown result type (might be due to invalid IL or missing references)
			//IL_0105: Unknown result type (might be due to invalid IL or missing references)
			//IL_0106: Unknown result type (might be due to invalid IL or missing references)
			//IL_018c: Unknown result type (might be due to invalid IL or missing references)
			//IL_018e: Unknown result type (might be due to invalid IL or missing references)
			//IL_018f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0286: Unknown result type (might be due to invalid IL or missing references)
			//IL_0288: Unknown result type (might be due to invalid IL or missing references)
			//IL_0289: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c9: Unknown result type (might be due to invalid IL or missing references)
			//IL_01cc: Unknown result type (might be due to invalid IL or missing references)
			//IL_01cd: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ce: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d3: Unknown result type (might be due to invalid IL or missing references)
			//IL_01da: 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_01dc: Unknown result type (might be due to invalid IL or missing references)
			//IL_0326: Unknown result type (might be due to invalid IL or missing references)
			//IL_0318: 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_031b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0330: 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_0334: Unknown result type (might be due to invalid IL or missing references)
			//IL_036b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0370: Unknown result type (might be due to invalid IL or missing references)
			//IL_0374: Unknown result type (might be due to invalid IL or missing references)
			//IL_0379: Unknown result type (might be due to invalid IL or missing references)
			//IL_0393: Unknown result type (might be due to invalid IL or missing references)
			//IL_03ab: Unknown result type (might be due to invalid IL or missing references)
			//IL_03b0: Unknown result type (might be due to invalid IL or missing references)
			//IL_042b: Unknown result type (might be due to invalid IL or missing references)
			ComponentFieldAccessor<Tameable> val = null;
			TameableState state = Processor.Instance<TameableRegistryProcessor>().GetState(zdo);
			if (state == null)
			{
				return (ProcessResult)2;
			}
			ProcessResult val2 = (ProcessResult)2;
			States state2 = state.State;
			bool flag = state2 - 1 <= 1;
			bool flag2 = flag;
			bool flag3 = flag2;
			bool flag4;
			if (flag3)
			{
				Humanoid humanoid = prefabInfo.Humanoid;
				if (humanoid != null)
				{
					Faction faction = ((Character)humanoid).m_faction;
					if ((int)faction == 0 || (int)faction == 11)
					{
						flag4 = true;
						goto IL_005d;
					}
				}
				flag4 = false;
				goto IL_005d;
			}
			goto IL_0064;
			IL_0064:
			if (flag3)
			{
				if (val == null)
				{
					val = zdo.Fields<Tameable>();
				}
				if (ConfigBase<Config>.Instance.FedDurationMultiplier.Value == 1f)
				{
					val.Reset((Func<Expression<Func<Tameable, float>>>)(() => (Tameable x) => x.m_fedDuration), "C:\\repos\\Valheim.ServersideQoL\\ServersideQoL.TameAssist\\TameableProcessor.cs", 40);
				}
				else if (val.UpdateValue((Func<Expression<Func<Tameable, float>>>)(() => (Tameable x) => x.m_fedDuration), prefabInfo.Tameable.m_fedDuration * ConfigBase<Config>.Instance.FedDurationMultiplier.Value, "C:\\repos\\Valheim.ServersideQoL\\ServersideQoL.TameAssist\\TameableProcessor.cs", 41))
				{
					val2 = (ProcessResult)(val2 | 8);
				}
			}
			if ((int)state.State == 2)
			{
				if (val == null)
				{
					val = zdo.Fields<Tameable>();
				}
				if (!ConfigBase<Config>.Instance.MakeCommandable.Value)
				{
					val.Reset((Func<Expression<Func<Tameable, bool>>>)(() => (Tameable x) => x.m_commandable), "C:\\repos\\Valheim.ServersideQoL\\ServersideQoL.TameAssist\\TameableProcessor.cs", 50);
				}
				else if (val.UpdateValue((Func<Expression<Func<Tameable, bool>>>)(() => (Tameable x) => x.m_commandable), true, "C:\\repos\\Valheim.ServersideQoL\\ServersideQoL.TameAssist\\TameableProcessor.cs", 51))
				{
					val2 = (ProcessResult)(val2 | 8);
				}
				_tamingStates.Remove(zdo);
				if (_containersByItemName != null)
				{
					List<ItemDrop> consumeItems = prefabInfo.MonsterAI.m_consumeItems;
					if (consumeItems != null && consumeItems.Count > 0)
					{
						val2 = (ProcessResult)(val2 & -3);
						val2 = (ProcessResult)(val2 | (FeedFromContainer(zdo, peers, prefabInfo) | 0x40));
					}
				}
			}
			else if ((int)state.State == 1)
			{
				if (val == null)
				{
					val = zdo.Fields<Tameable>();
				}
				if (ConfigBase<Config>.Instance.TamingTimeMultiplier.Value == 1f)
				{
					val.Reset((Func<Expression<Func<Tameable, float>>>)(() => (Tameable x) => x.m_tamingTime), "C:\\repos\\Valheim.ServersideQoL\\ServersideQoL.TameAssist\\TameableProcessor.cs", 67);
				}
				else if (val.UpdateValue((Func<Expression<Func<Tameable, float>>>)(() => (Tameable x) => x.m_tamingTime), prefabInfo.Tameable.m_tamingTime * ConfigBase<Config>.Instance.TamingTimeMultiplier.Value, "C:\\repos\\Valheim.ServersideQoL\\ServersideQoL.TameAssist\\TameableProcessor.cs", 68))
				{
					val2 = (ProcessResult)(val2 | 8);
				}
				if (ConfigBase<Config>.Instance.PotionTamingBoostMultiplier.Value == 1f)
				{
					val.Reset((Func<Expression<Func<Tameable, float>>>)(() => (Tameable x) => x.m_tamingBoostMultiplier), "C:\\repos\\Valheim.ServersideQoL\\ServersideQoL.TameAssist\\TameableProcessor.cs", 72);
				}
				else if (val.UpdateValue((Func<Expression<Func<Tameable, float>>>)(() => (Tameable x) => x.m_tamingBoostMultiplier), prefabInfo.Tameable.m_tamingBoostMultiplier * ConfigBase<Config>.Instance.PotionTamingBoostMultiplier.Value, "C:\\repos\\Valheim.ServersideQoL\\ServersideQoL.TameAssist\\TameableProcessor.cs", 73))
				{
					val2 = (ProcessResult)(val2 | 8);
				}
				if ((int)ConfigBase<Config>.Instance.TamingProgressMessageType.Value != 0)
				{
					val2 = (ProcessResult)(val2 & -3);
					if (!_tamingStates.TryGetValue(zdo, out TamingState value))
					{
						_tamingStates.Add(zdo, value = new TamingState());
						zdo.Destroyed += delegate(ServersideQoLZDO x)
						{
							_tamingStates.Remove(x);
						};
					}
					Timestamp now = Timestamp.Now;
					if (value.NextMessage < now)
					{
						value.NextMessage = ((Timestamp)(ref now)).AddSeconds(DamageText.instance.m_textDuration);
						bool isHungry = false;
						DateTime time = ZNet.instance.GetTime();
						ZDOVars vars = zdo.Vars;
						if ((time - ((ZDOVars)(ref vars)).GetTameLastFeeding(default(DateTime))).TotalSeconds > (double)val.GetFloat((Func<Expression<Func<Tameable, float>>>)(() => (Tameable x) => x.m_fedDuration), "C:\\repos\\Valheim.ServersideQoL\\ServersideQoL.TameAssist\\TameableProcessor.cs", 93))
						{
							isHungry = true;
						}
						Processor.ShowMessage((IEnumerable<Peer>)peers, zdo, ConfigBase<Config>.Instance.Localization.Value.FormatTaming(state.Tameness, isHungry), ConfigBase<Config>.Instance.TamingProgressMessageType.Value, (TextType)0);
					}
				}
			}
			if ((int)state.State != 2 && (val2 & 2) != 0)
			{
				val2 = (ProcessResult)(val2 | 0x40);
				state.StateChanged += delegate(TameableState val3)
				{
					val3.ZDO.ReregisterAll();
				};
			}
			return val2;
			IL_005d:
			flag3 = !flag4;
			goto IL_0064;
		}

		private ProcessResult FeedFromContainer(ServersideQoLZDO zdo, IReadOnlyList<Peer> peers, PrefabInfo prefabInfo)
		{
			//IL_0012: Unknown result type (might be due to invalid IL or missing references)
			//IL_0017: Unknown result type (might be due to invalid IL or missing references)
			//IL_0531: Unknown result type (might be due to invalid IL or missing references)
			//IL_0533: Unknown result type (might be due to invalid IL or missing references)
			//IL_0535: Unknown result type (might be due to invalid IL or missing references)
			//IL_0537: Unknown result type (might be due to invalid IL or missing references)
			//IL_053b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0542: 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_00b6: 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_00d1: 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)
			//IL_00da: Unknown result type (might be due to invalid IL or missing references)
			//IL_00df: 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_0444: Unknown result type (might be due to invalid IL or missing references)
			//IL_0449: Unknown result type (might be due to invalid IL or missing references)
			//IL_0485: Unknown result type (might be due to invalid IL or missing references)
			//IL_0495: Unknown result type (might be due to invalid IL or missing references)
			//IL_049a: Unknown result type (might be due to invalid IL or missing references)
			//IL_049c: Unknown result type (might be due to invalid IL or missing references)
			//IL_04bc: Unknown result type (might be due to invalid IL or missing references)
			//IL_04c1: Unknown result type (might be due to invalid IL or missing references)
			//IL_04c9: 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_04d2: Unknown result type (might be due to invalid IL or missing references)
			//IL_04d9: Unknown result type (might be due to invalid IL or missing references)
			//IL_04f6: Unknown result type (might be due to invalid IL or missing references)
			//IL_04fb: Unknown result type (might be due to invalid IL or missing references)
			//IL_0509: Unknown result type (might be due to invalid IL or missing references)
			//IL_050f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0554: Unknown result type (might be due to invalid IL or missing references)
			//IL_013b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0140: Unknown result type (might be due to invalid IL or missing references)
			//IL_0597: Unknown result type (might be due to invalid IL or missing references)
			//IL_0194: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a0: Unknown result type (might be due to invalid IL or missing references)
			//IL_02fa: Unknown result type (might be due to invalid IL or missing references)
			//IL_0305: Unknown result type (might be due to invalid IL or missing references)
			//IL_030b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0312: Unknown result type (might be due to invalid IL or missing references)
			//IL_0317: Unknown result type (might be due to invalid IL or missing references)
			//IL_0318: Unknown result type (might be due to invalid IL or missing references)
			ComponentFieldAccessor<Tameable> val = zdo.Fields<Tameable>();
			DateTime time = ZNet.instance.GetTime();
			ZDOVars vars = zdo.Vars;
			if ((time - ((ZDOVars)(ref vars)).GetTameLastFeeding(default(DateTime))).TotalSeconds <= (double)val.GetFloat((Func<Expression<Func<Tameable, float>>>)(() => (Tameable x) => x.m_fedDuration), "C:\\repos\\Valheim.ServersideQoL\\ServersideQoL.TameAssist\\TameableProcessor.cs", 114))
			{
				return (ProcessResult)0;
			}
			ProcessResult val2 = (ProcessResult)0;
			List<ServersideQoLZDO> list = null;
			List<ItemData> list2 = null;
			int num = 1;
			foreach (ItemDrop consumeItem in prefabInfo.MonsterAI.m_consumeItems)
			{
				ItemData foodItem = consumeItem.m_itemData;
				int num2 = 0;
				AdjacentEnumerator<SharedItemDataKey, HashSet<ServersideQoLZDO>> enumerator2 = _containersByItemName.EnumerateAdjacent((zdo.ZDO.GetPosition(), SharedItemDataKey.op_Implicit(foodItem.m_shared))).GetEnumerator();
				try
				{
					while (enumerator2.MoveNext())
					{
						HashSet<ServersideQoLZDO> current2 = enumerator2.Current;
						list?.Clear();
						foreach (ServersideQoLZDO item in current2)
						{
							ContainerState state = Processor.Instance<ContainerRegistryProcessor>().GetState(item);
							if (state == null)
							{
								(list ?? (list = new List<ServersideQoLZDO>())).Add(item);
								continue;
							}
							vars = item.Vars;
							if (((ZDOVars)(ref vars)).GetInUse(false))
							{
								continue;
							}
							float num3 = state.TameAssistFeedRange ?? ConfigBase<Config>.Instance.FeedFromContainersRange.Value;
							num3 *= num3;
							if (num3 == 0f || Utils.DistanceSqr(zdo.ZDO.GetPosition(), item.ZDO.GetPosition()) > num3)
							{
								continue;
							}
							IInventory inventory = state.GetInventory();
							list2?.Clear();
							int num4 = 0;
							int num5 = ConfigBase<Config>.Instance.FeedFromContainersLeaveAtLeast.Value;
							bool flag = false;
							bool flag2 = false;
							foreach (ItemData item2 in from x in inventory.Items
								where new ItemDataKey(x) == ItemDataKey.op_Implicit(foodItem)
								orderby x.m_stack
								select x)
							{
								flag = flag || (item2 != null && item2.m_stack > 0);
								int num6 = Math.Min(item2.m_stack, num5);
								int num7 = Math.Min(num, item2.m_stack - num6);
								num5 -= num6;
								if (num7 != 0)
								{
									if (!item.IsOwnerOrUnassigned())
									{
										flag2 = true;
										break;
									}
									num4 += num7;
									item2.m_stack -= num7;
									if (item2.m_stack == 0)
									{
										(list2 ?? (list2 = new List<ItemData>())).Add(item2);
									}
									num -= num7;
									if (num == 0)
									{
										break;
									}
								}
							}
							if (flag2)
							{
								val2 |= ((Processor)this).ScheduleReprocessing(Processor.Instance<ContainerRegistryProcessor>().RequestOwnership(item, default(PlayerID)));
								continue;
							}
							if (num4 == 0)
							{
								if (!flag)
								{
									(list ?? (list = new List<ServersideQoLZDO>())).Add(item);
								}
								continue;
							}
							if (list2 != null && list2.Count > 0)
							{
								foreach (ItemData item3 in list2)
								{
									inventory.Items.Remove(item3);
								}
								List<ItemData> items = inventory.Items;
								if (items != null && items.Count == 0)
								{
									(list ?? (list = new List<ServersideQoLZDO>())).Add(item);
								}
							}
							inventory.Save();
							num2 += num4;
							if (num != 0)
							{
								continue;
							}
							break;
						}
						if (list != null)
						{
							foreach (ServersideQoLZDO item4 in list)
							{
								current2.Remove(item4);
							}
						}
						if (num == 0)
						{
							break;
						}
					}
				}
				finally
				{
					((IDisposable)enumerator2/*cast due to .constrained prefix*/).Dispose();
				}
				if (num2 != 0)
				{
					vars = zdo.Vars;
					((ZDOVars)(ref vars)).SetTameLastFeeding(ZNet.instance.GetTime(), "C:\\repos\\Valheim.ServersideQoL\\ServersideQoL.TameAssist\\TameableProcessor.cs", 215);
					ZDO zDO = zdo.ZDO;
					zDO.DataRevision += 100;
					Vector3 position = ((Component)prefabInfo.Humanoid).transform.position;
					Quaternion rotation = ((Component)prefabInfo.Humanoid).transform.rotation;
					Vector3 val3 = position;
					try
					{
						Transform transform = ((Component)prefabInfo.Humanoid).transform;
						Transform transform2 = ((Component)prefabInfo.Humanoid).transform;
						Vector3 position2 = zdo.ZDO.GetPosition();
						Quaternion rotation2 = zdo.ZDO.GetRotation();
						transform.position = position2;
						transform2.rotation = rotation2;
						prefabInfo.Humanoid.m_consumeItemEffects.Create(((Component)prefabInfo.Humanoid).transform.position, Quaternion.identity, (Transform)null, 1f, -1, default(ZDOID));
					}
					finally
					{
						Transform transform = ((Component)prefabInfo.Humanoid).transform;
						Transform transform3 = ((Component)prefabInfo.Humanoid).transform;
						Vector3 position2 = val3;
						Quaternion rotation2 = rotation;
						transform.position = position2;
						transform3.rotation = rotation2;
					}
					if ((int)ConfigBase<Config>.Instance.TameFedMessageType.Value != 0)
					{
						Processor.ShowMessage((IEnumerable<Peer>)peers, zdo, ConfigBase<Config>.Instance.Localization.Value.FormatTameFed(((Character)prefabInfo.Humanoid).m_name, foodItem.m_shared.m_name), ConfigBase<Config>.Instance.TameFedMessageType.Value, (TextType)0);
					}
				}
				if (num == 0)
				{
					break;
				}
			}
			return val2;
		}
	}
	[BepInPlugin("ArgusMagnus.ServersideQoL.TameAssist", "ServersideQoL.TameAssist", "2.1.0")]
	public sealed class TameAssistPlugin : ServersideQoLPluginBase<TameAssistPlugin, Config>
	{
		public const string Author = "ArgusMagnus";

		public const string PluginName = "ServersideQoL.TameAssist";

		public const string PluginGuid = "ArgusMagnus.ServersideQoL.TameAssist";

		public const string PluginVersion = "2.1.0";

		public const string PluginInformationalVersion = "2.1.0";

		private DateTimeOffset BuildTimestamp { get; } = new DateTimeOffset(639259375579415519L, default(TimeSpan));

		protected override Config CreateConfigSingleton(ConfigFile configFile, Logger logger)
		{
			return new Config(configFile, logger);
		}

		protected override void RegisterProcessors(IProcessorCollection processors)
		{
			processors.Add<TameableProcessor>().Add<PlayerProcessor>().Add<GrowingProcessor>();
		}

		private void Awake()
		{
		}
	}
}