Decompiled source of Offspring Portal v1.4.4

OffspringPortal.dll

Decompiled a month ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.Globalization;
using System.Linq;
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.Bootstrap;
using BepInEx.Configuration;
using BepInEx.Logging;
using HarmonyLib;
using Jotunn.Entities;
using Jotunn.Managers;
using Microsoft.CodeAnalysis;
using OffspringPortal.UI;
using UnityEngine;
using UnityEngine.Events;
using UnityEngine.UI;

[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("OffspringPortal")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyDescription("Automatically teleports juvenile animals from breeding pens to configured grow-up pens.")]
[assembly: AssemblyFileVersion("1.4.4.0")]
[assembly: AssemblyInformationalVersion("1.4.4+f5f268a123fc599d22c0d0c9ecc6bdf9303bf553")]
[assembly: AssemblyProduct("OffspringPortal")]
[assembly: AssemblyTitle("OffspringPortal")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.4.4.0")]
[module: UnverifiableCode]
[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 OffspringPortal
{
	public static class AdultPortalRouter
	{
		public static bool IsAdultRoutingMaturingPortal(OPTeleportWorld portal)
		{
			//IL_002c: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)portal == (Object)null)
			{
				return false;
			}
			ZNetView component = ((Component)portal).GetComponent<ZNetView>();
			ZDO val = ((component != null) ? component.GetZDO() : null);
			if (val == null || !PortalConfigGate.IsConfiguredForAutomation(val))
			{
				return false;
			}
			PortalRecord portalRecord = DestinationRegistry.Get(val.m_uid);
			if (portalRecord != null)
			{
				if (portalRecord.Role == PortalRole.Maturing)
				{
					return portalRecord.AdultDestination != AdultDestination.None;
				}
				return false;
			}
			if (PortalRoleCatalog.FromZdo(val) == PortalRole.Maturing)
			{
				return PortalRoleCatalog.GetAdultDestination(val) != AdultDestination.None;
			}
			return false;
		}

		public static bool TryRoute(OPTeleportWorld portal, Character character, Dictionary<int, float> cooldowns, ref float lastNoDestinationMessageTime)
		{
			//IL_004a: 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_00ce: 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_00e3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f1: Unknown result type (might be due to invalid IL or missing references)
			//IL_0118: Unknown result type (might be due to invalid IL or missing references)
			//IL_0136: Unknown result type (might be due to invalid IL or missing references)
			//IL_012d: 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_013d: Unknown result type (might be due to invalid IL or missing references)
			//IL_013f: 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_014d: Unknown result type (might be due to invalid IL or missing references)
			//IL_016c: Unknown result type (might be due to invalid IL or missing references)
			//IL_016e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0183: Unknown result type (might be due to invalid IL or missing references)
			//IL_0185: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)portal == (Object)null || (Object)(object)character == (Object)null || !OffspringPortalPrefabs.IsOffspringPortal(portal))
			{
				return false;
			}
			if (!SpeciesHelper.IsEligibleAdult(character))
			{
				return false;
			}
			ZNetView component = ((Component)portal).GetComponent<ZNetView>();
			PortalRecord portalRecord = (((Object)(object)component != (Object)null) ? DestinationRegistry.Get(component.GetZDO()?.m_uid ?? ZDOID.None) : null);
			if (portalRecord == null || portalRecord.Role != PortalRole.Maturing || portalRecord.AdultDestination == AdultDestination.None)
			{
				return false;
			}
			int instanceID = ((Object)character).GetInstanceID();
			float time = Time.time;
			if (cooldowns.TryGetValue(instanceID, out var value) && time < value)
			{
				return false;
			}
			string adultSpeciesKey = SpeciesHelper.GetAdultSpeciesKey(character);
			if (!SpeciesHelper.SpeciesKeyMatches(adultSpeciesKey, portalRecord.DeclaredSpeciesKey))
			{
				return false;
			}
			ZNetView nview = character.GetNview();
			ZDOID val = (ZDOID)(((??)((nview == null) ? ((ZDOID?)null) : nview.GetZDO()?.m_uid)) ?? ZDOID.None);
			ZDOID val2 = (ZDOID)(((??)((component == null) ? ((ZDOID?)null) : component.GetZDO()?.m_uid)) ?? ZDOID.None);
			if (val == ZDOID.None || val2 == ZDOID.None)
			{
				return false;
			}
			if (ZNet.instance.IsServer())
			{
				return TryRouteOnServer(portal, character, adultSpeciesKey, portalRecord, val, val2, cooldowns, ref lastNoDestinationMessageTime, time, instanceID);
			}
			if (!RoutingRpc.CanSendRequests())
			{
				return false;
			}
			RoutingRpc.RequestAdultRoute(val, val2, adultSpeciesKey);
			cooldowns[instanceID] = time + ModConfig.TeleportCooldownSec.Value;
			return false;
		}

		public static bool ExecuteApprovedRoute(ZDOID characterId, ZDOID sourcePortalId, PortalRecord destination, Character character = null, OPTeleportWorld sourcePortal = null)
		{
			//IL_0003: Unknown result type (might be due to invalid IL or missing references)
			//IL_000f: Unknown result type (might be due to invalid IL or missing references)
			//IL_002f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0085: Unknown result type (might be due to invalid IL or missing references)
			if (character == null)
			{
				character = ResolveCharacter(characterId);
			}
			if (sourcePortal == null)
			{
				sourcePortal = ResolvePortal(sourcePortalId);
			}
			if ((Object)(object)character == (Object)null || (Object)(object)sourcePortal == (Object)null || destination == null)
			{
				return false;
			}
			PortalRecord portalRecord = DestinationRegistry.Get(sourcePortalId);
			if (portalRecord == null || portalRecord.Role != PortalRole.Maturing)
			{
				return false;
			}
			string adultSpeciesKey = SpeciesHelper.GetAdultSpeciesKey(character);
			if (!SpeciesHelper.SpeciesKeyMatches(adultSpeciesKey, portalRecord.DeclaredSpeciesKey))
			{
				return false;
			}
			if (!JuvenileTeleporter.TryExecuteApproved(character, destination, sourcePortal))
			{
				return false;
			}
			OffspringPortalPlugin.Log.LogInfo((object)$"Teleported {SpeciesKey.GetDisplayName(adultSpeciesKey)} adult to {portalRecord.AdultDestination} portal at {destination.Position}.");
			PlayPortalActivation(sourcePortal);
			return true;
		}

		private static bool TryRouteOnServer(OPTeleportWorld portal, Character character, string speciesKey, PortalRecord source, ZDOID characterId, ZDOID sourcePortalId, Dictionary<int, float> cooldowns, ref float lastNoDestinationMessageTime, float now, int bodyId)
		{
			//IL_0048: Unknown result type (might be due to invalid IL or missing references)
			//IL_004a: Unknown result type (might be due to invalid IL or missing references)
			PortalRecord destination;
			switch (source.AdultDestination)
			{
			case AdultDestination.Farm:
				if (!DestinationRegistry.TryResolveFarmDestination(speciesKey, out destination))
				{
					string message = "No Farm portal exists.";
					return WarnMissingDestination(now, ref lastNoDestinationMessageTime, message);
				}
				break;
			case AdultDestination.Cull:
				if (!DestinationRegistry.TryResolveCullDestination(out destination))
				{
					string message = "No Cull portal exists.";
					return WarnMissingDestination(now, ref lastNoDestinationMessageTime, message);
				}
				break;
			default:
				return false;
			}
			if (ExecuteApprovedRoute(characterId, sourcePortalId, destination, character, portal))
			{
				cooldowns[bodyId] = now + ModConfig.TeleportCooldownSec.Value;
				return true;
			}
			OffspringPortalPlugin.Log.LogWarning((object)("Failed to teleport " + SpeciesKey.GetDisplayName(speciesKey) + " adult."));
			return false;
		}

		private static bool WarnMissingDestination(float now, ref float lastMessageTime, string message)
		{
			if (now - lastMessageTime <= 5f)
			{
				return false;
			}
			lastMessageTime = now;
			OffspringPortalPlugin.Log.LogWarning((object)message);
			Player localPlayer = Player.m_localPlayer;
			if ((Object)(object)localPlayer != (Object)null)
			{
				((Character)localPlayer).Message((MessageType)2, message, 0, (Sprite)null, false);
			}
			return false;
		}

		private static Character ResolveCharacter(ZDOID characterId)
		{
			//IL_000c: Unknown result type (might be due to invalid IL or missing references)
			ZNetScene instance = ZNetScene.instance;
			GameObject val = ((instance != null) ? instance.FindInstance(characterId) : null);
			if (!((Object)(object)val != (Object)null))
			{
				return null;
			}
			return val.GetComponent<Character>();
		}

		private static OPTeleportWorld ResolvePortal(ZDOID portalId)
		{
			//IL_000c: Unknown result type (might be due to invalid IL or missing references)
			ZNetScene instance = ZNetScene.instance;
			GameObject val = ((instance != null) ? instance.FindInstance(portalId) : null);
			if (!((Object)(object)val != (Object)null))
			{
				return null;
			}
			return val.GetComponent<OPTeleportWorld>();
		}

		private static void PlayPortalActivation(OPTeleportWorld portal)
		{
			portal?.PlayActivationEffect();
		}
	}
	public sealed class BreedableSpeciesInfo
	{
		public string Key;

		public string DisplayName;

		public bool IsEggLayer;

		public bool IsDualPurposeEgg;

		public string EggCollectorKey;

		public string EggPrefabName;

		public string AdultPrefabName;

		public string HatchlingPrefabName;
	}
	public static class BreedableSpeciesRegistry
	{
		private static readonly Dictionary<string, BreedableSpeciesInfo> RegisteredSpecies = new Dictionary<string, BreedableSpeciesInfo>(StringComparer.OrdinalIgnoreCase);

		public static void Clear()
		{
			RegisteredSpecies.Clear();
		}

		public static void Register(BreedableSpeciesInfo info)
		{
			if (info != null && !string.IsNullOrWhiteSpace(info.Key))
			{
				info.Key = SpeciesKey.Canonicalize(info.Key);
				if (string.IsNullOrEmpty(info.DisplayName))
				{
					info.DisplayName = SpeciesKey.GetDisplayName(info.Key);
				}
				if (info.IsDualPurposeEgg)
				{
					info.EggCollectorKey = SpeciesKey.BuildEggCollectorKey(info.Key);
				}
				RegisteredSpecies[info.Key] = info;
			}
		}

		public static bool TryGet(string key, out BreedableSpeciesInfo info)
		{
			if (RegisteredSpecies.TryGetValue(key, out info))
			{
				return true;
			}
			if (SpeciesKey.IsEggCollectorKey(key))
			{
				string key2 = key.Substring("Egg:".Length);
				return RegisteredSpecies.TryGetValue(key2, out info);
			}
			return false;
		}

		public static bool TryGetByEggPrefab(string eggPrefabName, out BreedableSpeciesInfo info)
		{
			info = null;
			string value = SpeciesKey.Normalize(eggPrefabName);
			if (string.IsNullOrEmpty(value))
			{
				return false;
			}
			foreach (BreedableSpeciesInfo value2 in RegisteredSpecies.Values)
			{
				if (value2.IsEggLayer && !string.IsNullOrEmpty(value2.EggPrefabName) && value2.EggPrefabName.Equals(value, StringComparison.OrdinalIgnoreCase))
				{
					info = value2;
					return true;
				}
			}
			return false;
		}

		public static bool HasDualPurposeEggLayers()
		{
			return RegisteredSpecies.Values.Any((BreedableSpeciesInfo species) => species.IsDualPurposeEgg);
		}

		public static IReadOnlyList<string> GetMaturingOptionKeys()
		{
			List<string> list = RegisteredSpecies.Values.Select((BreedableSpeciesInfo species) => species.Key).Distinct<string>(StringComparer.OrdinalIgnoreCase).OrderBy<string, string>((string key) => SpeciesKey.GetDisplayName(key), StringComparer.OrdinalIgnoreCase)
				.ToList();
			list.Add("All");
			return list;
		}

		public static IReadOnlyList<string> GetEggCollectorOptionKeys()
		{
			return GetEggCollectorOptionKeys(null);
		}

		public static IReadOnlyList<string> GetEggCollectorOptionKeys(string additionalSpeciesKey)
		{
			HashSet<string> hashSet = new HashSet<string>(StringComparer.OrdinalIgnoreCase);
			foreach (BreedableSpeciesInfo value in RegisteredSpecies.Values)
			{
				if (value.IsDualPurposeEgg && !string.IsNullOrEmpty(value.EggCollectorKey))
				{
					hashSet.Add(value.EggCollectorKey);
				}
			}
			foreach (PortalRecord item in DestinationRegistry.GetAll())
			{
				if (item.Role == PortalRole.EggCollector && !string.IsNullOrWhiteSpace(item.DeclaredSpeciesKey))
				{
					string text = SpeciesKey.BuildEggCollectorKey(item.DeclaredSpeciesKey);
					if (!string.IsNullOrEmpty(text))
					{
						hashSet.Add(text);
					}
				}
			}
			AddEggCollectorOptionKey(hashSet, additionalSpeciesKey);
			return hashSet.OrderBy<string, string>((string key) => SpeciesKey.GetEggCollectorDisplayName(key), StringComparer.OrdinalIgnoreCase).ToList();
		}

		private static void AddEggCollectorOptionKey(HashSet<string> keys, string speciesKey)
		{
			if (!string.IsNullOrWhiteSpace(speciesKey))
			{
				string text = SpeciesKey.BuildEggCollectorKey(speciesKey);
				if (!string.IsNullOrEmpty(text))
				{
					keys.Add(text);
				}
			}
		}

		public static IReadOnlyList<string> GetMaturingOptionKeysWithFallback()
		{
			if (RegisteredSpecies.Count == 0)
			{
				return SpeciesCatalog.LegacyDestinationOptionKeys;
			}
			return GetMaturingOptionKeys();
		}

		public static IReadOnlyList<string> GetDestinationOptionKeysWithFallback()
		{
			return GetMaturingOptionKeysWithFallback();
		}

		public static void DiscoverInRange(Vector3 center, float range)
		{
			//IL_0030: Unknown result type (might be due to invalid IL or missing references)
			//IL_0035: Unknown result type (might be due to invalid IL or missing references)
			//IL_0036: Unknown result type (might be due to invalid IL or missing references)
			//IL_003b: Unknown result type (might be due to invalid IL or missing references)
			float num = range * range;
			foreach (Character allCharacter in Character.GetAllCharacters())
			{
				if (!((Object)(object)allCharacter == (Object)null) && !allCharacter.IsPlayer())
				{
					Vector3 val = ((Component)allCharacter).transform.position - center;
					if (!(((Vector3)(ref val)).sqrMagnitude > num) && (SpeciesDiscovery.TryDiscoverFromCharacter(allCharacter, out var info) || SpeciesDiscovery.TryDiscoverFallback(allCharacter, out info)))
					{
						Register(info);
					}
				}
			}
		}

		public static void RefreshFromAllBreeders()
		{
			//IL_0019: Unknown result type (might be due to invalid IL or missing references)
			float discoveryScanRange = ModConfig.GetDiscoveryScanRange();
			foreach (PortalRecord breederPortal in DestinationRegistry.GetBreederPortals())
			{
				DiscoverInRange(breederPortal.Position, discoveryScanRange);
			}
		}
	}
	public static class BreedingCapData
	{
		public static int GetCapLimit(SpeciesType species)
		{
			return species switch
			{
				SpeciesType.Boar => 5, 
				SpeciesType.Wolf => 4, 
				SpeciesType.Lox => 4, 
				SpeciesType.Chicken => 10, 
				SpeciesType.Asksvin => 10, 
				SpeciesType.Moose => 4, 
				_ => 0, 
			};
		}

		public static float GetCapRadius(SpeciesType species)
		{
			switch (species)
			{
			case SpeciesType.Boar:
			case SpeciesType.Wolf:
			case SpeciesType.Chicken:
			case SpeciesType.Asksvin:
				return 10f;
			case SpeciesType.Lox:
			case SpeciesType.Moose:
				return 20f;
			default:
				return 0f;
			}
		}
	}
	public sealed class PortalRecord
	{
		public ZDOID Id;

		public Vector3 Position;

		public Quaternion Rotation = Quaternion.identity;

		public PortalRole Role;

		public SpeciesType DeclaredSpecies;

		public string DeclaredSpeciesKey;

		public AdultDestination AdultDestination;
	}
	public static class DestinationRegistry
	{
		private static readonly Dictionary<ZDOID, PortalRecord> Portals = new Dictionary<ZDOID, PortalRecord>();

		private static readonly Dictionary<string, int> MaturingRoundRobinIndex = new Dictionary<string, int>(StringComparer.OrdinalIgnoreCase);

		private static readonly Dictionary<string, int> FarmRoundRobinIndex = new Dictionary<string, int>(StringComparer.OrdinalIgnoreCase);

		private static int cullRoundRobinIndex;

		private static readonly Dictionary<string, int> EggCollectorRoundRobinIndex = new Dictionary<string, int>(StringComparer.OrdinalIgnoreCase);

		private static float nextCapWarningRefreshTime;

		public static void Clear()
		{
			Portals.Clear();
		}

		public static void RegisterOrUpdate(ZDOID id, Vector3 position, PortalRole role, SpeciesType declaredSpecies, AdultDestination adultDestination)
		{
			//IL_0011: Unknown result type (might be due to invalid IL or missing references)
			//IL_0012: Unknown result type (might be due to invalid IL or missing references)
			string declaredSpeciesKey = ((declaredSpecies == SpeciesType.None) ? string.Empty : SpeciesCatalog.ToStorageValue(declaredSpecies));
			RegisterOrUpdate(id, position, role, declaredSpeciesKey, adultDestination);
		}

		public static void RegisterOrUpdate(ZDOID id, Vector3 position, PortalRole role, string declaredSpeciesKey, AdultDestination adultDestination)
		{
			//IL_0005: 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_002a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0015: 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_0021: Unknown result type (might be due to invalid IL or missing references)
			if (!Portals.TryGetValue(id, out var value))
			{
				value = new PortalRecord
				{
					Id = id
				};
				Portals[id] = value;
			}
			value.Position = position;
			value.Role = role;
			value.DeclaredSpeciesKey = NormalizeDeclaredSpeciesKey(role, declaredSpeciesKey);
			value.DeclaredSpecies = SpeciesCatalog.FromStorageValue(value.DeclaredSpeciesKey);
			value.AdultDestination = adultDestination;
		}

		public static void RegisterSnapshot(ZDOID id, Vector3 position, Quaternion rotation)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0013: Unknown result type (might be due to invalid IL or missing references)
			//IL_0037: Unknown result type (might be due to invalid IL or missing references)
			//IL_0038: Unknown result type (might be due to invalid IL or missing references)
			//IL_003e: Unknown result type (might be due to invalid IL or missing references)
			//IL_003f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0023: 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_002f: Unknown result type (might be due to invalid IL or missing references)
			if (!(id == ZDOID.None))
			{
				if (!Portals.TryGetValue(id, out var value))
				{
					value = new PortalRecord
					{
						Id = id
					};
					Portals[id] = value;
				}
				value.Position = position;
				value.Rotation = rotation;
			}
		}

		public static void Remove(ZDOID id)
		{
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			Portals.Remove(id);
		}

		public static PortalRecord Get(ZDOID id)
		{
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			Portals.TryGetValue(id, out var value);
			return value;
		}

		public static void RefreshPortalPosition(PortalRecord record)
		{
			//IL_000c: 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_0021: 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_002d: Unknown result type (might be due to invalid IL or missing references)
			if (record != null && ZDOMan.instance != null)
			{
				ZDO val = ZdoIdUtility.TryGetZdo(record.Id);
				if (val != null)
				{
					record.Position = val.GetPosition();
					record.Rotation = val.GetRotation();
				}
			}
		}

		public static bool TryResolveMaturingDestination(SpeciesType juvenileSpecies, out PortalRecord destination)
		{
			return TryResolveMaturingDestination((juvenileSpecies == SpeciesType.None) ? string.Empty : SpeciesCatalog.ToStorageValue(juvenileSpecies), out destination);
		}

		public static bool TryResolveMaturingDestination(string speciesKey, out PortalRecord destination)
		{
			return TryResolveDestination(speciesKey, PortalRole.Maturing, MaturingRoundRobinIndex, out destination);
		}

		public static bool TryResolveFarmDestination(SpeciesType adultSpecies, out PortalRecord destination)
		{
			return TryResolveFarmDestination((adultSpecies == SpeciesType.None) ? string.Empty : SpeciesCatalog.ToStorageValue(adultSpecies), out destination);
		}

		public static bool TryResolveFarmDestination(string speciesKey, out PortalRecord destination)
		{
			return TryResolveDestination(speciesKey, PortalRole.Farm, FarmRoundRobinIndex, out destination);
		}

		public static bool TryResolveCullDestination(out PortalRecord destination)
		{
			destination = null;
			List<PortalRecord> list = (from p in Portals.Values
				where p.Role == PortalRole.Cull
				orderby ZdoIdUtility.Format(p.Id)
				select p).ToList();
			if (list.Count == 0)
			{
				return false;
			}
			destination = list[cullRoundRobinIndex % list.Count];
			cullRoundRobinIndex++;
			RefreshPortalPosition(destination);
			return true;
		}

		public static bool TryResolveEggCollectorDestination(string eggCollectorKey, out PortalRecord destination)
		{
			return TryResolveEggCollectorRoundRobin(new string[1] { eggCollectorKey ?? string.Empty }, BuildEggCollectorRoundRobinKey(eggCollectorKey), out destination);
		}

		public static bool TryResolveEggCollectorRoundRobin(IReadOnlyList<string> eggCollectorKeys, string roundRobinKey, out PortalRecord destination)
		{
			destination = null;
			if (eggCollectorKeys == null || eggCollectorKeys.Count == 0)
			{
				return false;
			}
			List<PortalRecord> list = CollectMatchingEggCollectors(eggCollectorKeys);
			if (list.Count == 0)
			{
				return false;
			}
			string key = (string.IsNullOrWhiteSpace(roundRobinKey) ? BuildEggCollectorRoundRobinKey(eggCollectorKeys[0]) : roundRobinKey);
			destination = PickRoundRobin(key, list, EggCollectorRoundRobinIndex);
			RefreshPortalPosition(destination);
			return destination != null;
		}

		internal static List<PortalRecord> CollectMatchingEggCollectors(IReadOnlyList<string> eggCollectorKeys)
		{
			//IL_0048: Unknown result type (might be due to invalid IL or missing references)
			List<PortalRecord> list = new List<PortalRecord>();
			HashSet<string> hashSet = new HashSet<string>(StringComparer.OrdinalIgnoreCase);
			if (eggCollectorKeys == null)
			{
				return list;
			}
			foreach (string eggCollectorKey in eggCollectorKeys)
			{
				if (string.IsNullOrWhiteSpace(eggCollectorKey))
				{
					continue;
				}
				foreach (PortalRecord matchingEggCollector in GetMatchingEggCollectors(eggCollectorKey))
				{
					string item = ZdoIdUtility.Format(matchingEggCollector.Id);
					if (hashSet.Add(item))
					{
						list.Add(matchingEggCollector);
					}
				}
			}
			list.Sort((PortalRecord left, PortalRecord right) => ZdoIdUtility.Compare(left.Id, right.Id));
			return list;
		}

		private static List<PortalRecord> GetMatchingEggCollectors(string eggCollectorKey)
		{
			string normalizedEggKey = SpeciesKey.BuildEggCollectorKey(eggCollectorKey);
			string speciesKey = (SpeciesKey.IsEggCollectorKey(normalizedEggKey) ? normalizedEggKey.Substring("Egg:".Length) : SpeciesKey.Canonicalize(eggCollectorKey));
			return (from p in Portals.Values
				where IsLivePortalRecord(p) && p.Role == PortalRole.EggCollector && PortalAcceptsEggCollector(p.DeclaredSpeciesKey, normalizedEggKey, speciesKey)
				orderby ZdoIdUtility.Format(p.Id)
				select p).ToList();
		}

		private static string BuildEggCollectorRoundRobinKey(string eggCollectorKey)
		{
			string text = SpeciesKey.BuildEggCollectorKey(eggCollectorKey);
			if (!string.IsNullOrWhiteSpace(text))
			{
				return text;
			}
			return SpeciesKey.Canonicalize(eggCollectorKey);
		}

		public static bool HasCullReceiver()
		{
			return Portals.Values.Any((PortalRecord p) => p.Role == PortalRole.Cull);
		}

		public static bool HasEggCollector()
		{
			return Portals.Values.Any((PortalRecord p) => p.Role == PortalRole.EggCollector);
		}

		public static bool HasFarmReceiver(SpeciesType maturingReceives)
		{
			return HasFarmReceiver((maturingReceives == SpeciesType.None) ? string.Empty : SpeciesCatalog.ToStorageValue(maturingReceives));
		}

		public static bool HasFarmReceiver(string maturingReceivesKey)
		{
			if (!string.IsNullOrEmpty(maturingReceivesKey) && !maturingReceivesKey.Equals("All", StringComparison.OrdinalIgnoreCase) && TryResolveFarmDestination(maturingReceivesKey, out var destination))
			{
				return true;
			}
			if (TryResolveFarmDestination("All", out destination))
			{
				return true;
			}
			if (maturingReceivesKey != null && maturingReceivesKey.Equals("All", StringComparison.OrdinalIgnoreCase))
			{
				return Portals.Values.Any((PortalRecord p) => p.Role == PortalRole.Farm);
			}
			return false;
		}

		public static IEnumerable<PortalRecord> GetBreederPortals()
		{
			return Portals.Values.Where((PortalRecord p) => p.Role == PortalRole.Breeder);
		}

		public static IEnumerable<PortalRecord> GetAll()
		{
			return Portals.Values;
		}

		public static string BuildSummaryCounts()
		{
			int num = 0;
			int num2 = 0;
			int num3 = 0;
			int num4 = 0;
			int num5 = 0;
			using (Dictionary<ZDOID, PortalRecord>.ValueCollection.Enumerator enumerator = Portals.Values.GetEnumerator())
			{
				while (enumerator.MoveNext())
				{
					switch (enumerator.Current.Role)
					{
					case PortalRole.Maturing:
						num2++;
						break;
					case PortalRole.Farm:
						num3++;
						break;
					case PortalRole.Cull:
						num4++;
						break;
					case PortalRole.EggCollector:
						num5++;
						break;
					default:
						num++;
						break;
					}
				}
			}
			return $"{num} breeder(s), {num2} maturing, {num3} farm, {num4} cull, {num5} egg collector(s)";
		}

		public static string FormatPortalRecord(PortalRecord record)
		{
			//IL_0059: Unknown result type (might be due to invalid IL or missing references)
			if (record == null)
			{
				return "  (null portal record)";
			}
			string text = (string.IsNullOrEmpty(record.DeclaredSpeciesKey) ? "(none)" : record.DeclaredSpeciesKey);
			string text2 = (IsLivePortalRecord(record) ? "live" : "missing-zdo");
			return $"  {record.Role} receives={text} id={ZdoIdUtility.Format(record.Id)} pos=({record.Position.x:F1}, {record.Position.y:F1}, {record.Position.z:F1}) [{text2}]";
		}

		public static void LogMaturingResolutionFailure(string speciesKey, string context)
		{
			DiagnosticLog.Warning("No maturing portal registered for '" + speciesKey + "' during " + context + ". Registry: " + BuildSummaryCounts() + ".");
			foreach (PortalRecord item in Portals.Values.Where((PortalRecord p) => p.Role == PortalRole.Maturing))
			{
				DiagnosticLog.Warning(FormatPortalRecord(item));
			}
			if (!Portals.Values.Any((PortalRecord p) => p.Role == PortalRole.Maturing))
			{
				DiagnosticLog.Warning("No Maturing portals are registered on this game instance. Place/configure a Maturing portal and confirm the server log shows it after configuration.");
			}
		}

		public static void RefreshCapWarningsThrottled()
		{
			if (!(Time.time < nextCapWarningRefreshTime))
			{
				nextCapWarningRefreshTime = Time.time + ModConfig.CapWarningRefreshIntervalSec.Value;
				RefreshCapWarnings();
			}
		}

		public static void RefreshCapWarnings()
		{
			//IL_0092: Unknown result type (might be due to invalid IL or missing references)
			if (!ModConfig.EnableCapWarning.Value || ZDOMan.instance == null)
			{
				return;
			}
			foreach (PortalRecord destination in Portals.Values.Where((PortalRecord p) => p.Role == PortalRole.Maturing && !"All".Equals(p.DeclaredSpeciesKey, StringComparison.OrdinalIgnoreCase)))
			{
				SpeciesType species = destination.DeclaredSpecies;
				if (species != SpeciesType.None)
				{
					bool flag = GetBreederPortals().Any((PortalRecord source) => Vector3.Distance(source.Position, destination.Position) <= BreedingCapData.GetCapRadius(species));
					ZDO val = ZdoIdUtility.TryGetZdo(destination.Id);
					if (val != null)
					{
						val.Set("op_cap_warning", flag);
					}
				}
			}
		}

		private static bool TryResolveDestination(string speciesKey, PortalRole requiredRole, Dictionary<string, int> roundRobinIndex, out PortalRecord destination)
		{
			destination = null;
			if (string.IsNullOrWhiteSpace(speciesKey))
			{
				return false;
			}
			List<PortalRecord> list = (from p in Portals.Values
				where IsLivePortalRecord(p) && p.Role == requiredRole && !SpeciesKey.IsAll(p.DeclaredSpeciesKey) && SpeciesKey.PortalAcceptsSpecies(p.DeclaredSpeciesKey, speciesKey)
				orderby ZdoIdUtility.Format(p.Id)
				select p).ToList();
			if (list.Count > 0)
			{
				destination = PickRoundRobin(speciesKey, list, roundRobinIndex);
				RefreshPortalPosition(destination);
				return destination != null;
			}
			List<PortalRecord> list2 = (from p in Portals.Values
				where IsLivePortalRecord(p) && p.Role == requiredRole && "All".Equals(p.DeclaredSpeciesKey, StringComparison.OrdinalIgnoreCase)
				orderby ZdoIdUtility.Format(p.Id)
				select p).ToList();
			if (list2.Count > 0)
			{
				destination = PickRoundRobin("All", list2, roundRobinIndex);
				RefreshPortalPosition(destination);
				return destination != null;
			}
			return false;
		}

		internal static bool IsLivePortalRecord(PortalRecord record)
		{
			//IL_0006: 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)
			if (record == null)
			{
				return false;
			}
			if (!ZdoIdUtility.IsValidId(record.Id))
			{
				return false;
			}
			if (ZDOMan.instance == null)
			{
				return true;
			}
			ZDO val = ZdoIdUtility.TryGetZdo(record.Id);
			if (val == null)
			{
				if ((Object)(object)ZNet.instance != (Object)null)
				{
					return !ZNet.instance.IsServer();
				}
				return false;
			}
			if (!val.IsValid())
			{
				return false;
			}
			bool flag = val.GetPrefab() == StringExtensionMethods.GetStableHashCode("offspring_portal");
			bool flag2 = !string.IsNullOrEmpty(val.GetString("op_portal_role", string.Empty));
			return flag || flag2;
		}

		private static string NormalizeDeclaredSpeciesKey(PortalRole role, string declaredSpeciesKey)
		{
			if (role == PortalRole.EggCollector)
			{
				return SpeciesKey.BuildEggCollectorKey(declaredSpeciesKey);
			}
			return declaredSpeciesKey ?? string.Empty;
		}

		private static bool PortalAcceptsEggCollector(string portalSpeciesKey, string normalizedEggKey, string speciesKey)
		{
			if (string.IsNullOrWhiteSpace(portalSpeciesKey))
			{
				return false;
			}
			if (SpeciesKey.PortalAcceptsEgg(portalSpeciesKey, normalizedEggKey))
			{
				return true;
			}
			if (SpeciesKey.PortalAcceptsSpecies(portalSpeciesKey, speciesKey))
			{
				return true;
			}
			return SpeciesKey.Canonicalize(portalSpeciesKey).Equals(speciesKey, StringComparison.OrdinalIgnoreCase);
		}

		private static PortalRecord PickRoundRobin(string key, List<PortalRecord> candidates, Dictionary<string, int> roundRobinIndex)
		{
			if (candidates.Count == 0)
			{
				return null;
			}
			if (!roundRobinIndex.TryGetValue(key, out var value))
			{
				value = 0;
			}
			PortalRecord result = candidates[value % candidates.Count];
			roundRobinIndex[key] = value + 1;
			return result;
		}
	}
	public static class DiagnosticLog
	{
		public static void Info(string message)
		{
			OPLog.Info(message);
		}

		public static void Warning(string message)
		{
			OPLog.Warning(message);
		}

		public static void Verbose(string message)
		{
			if (ModConfig.VerboseLogging.Value)
			{
				OPLog.Debug(message);
			}
		}

		public static bool ShouldLogRateLimited(ref float lastLogTime, float intervalSeconds)
		{
			float time = Time.time;
			if (time - lastLogTime < intervalSeconds)
			{
				return false;
			}
			lastLogTime = time;
			return true;
		}

		public static void LogPortalRegistry(string context, bool includeAllPortals = true)
		{
			StringBuilder stringBuilder = new StringBuilder();
			stringBuilder.Append("Portal registry snapshot (").Append(context).Append("): ");
			stringBuilder.Append(DestinationRegistry.BuildSummaryCounts());
			Info(stringBuilder.ToString());
			if (!includeAllPortals)
			{
				return;
			}
			foreach (PortalRecord item in DestinationRegistry.GetAll())
			{
				Info(DestinationRegistry.FormatPortalRecord(item));
			}
		}

		public static void LogNetworkContext(string context)
		{
			if ((Object)(object)ZNet.instance == (Object)null)
			{
				Verbose(context + ": ZNet not ready.");
				return;
			}
			string arg = ((!ZNet.instance.IsServer()) ? "client" : (ZNet.instance.IsDedicated() ? "dedicated server" : "listen server"));
			Verbose($"{context}: role={arg}, peers={ZNet.instance.GetNrOfPlayers()}.");
		}
	}
	public static class EggPortalRouter
	{
		public static bool TryRoute(OPTeleportWorld portal, ItemDrop egg, Dictionary<int, float> cooldowns, ref float lastNoDestinationMessageTime)
		{
			//IL_00ef: Unknown result type (might be due to invalid IL or missing references)
			//IL_010d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0104: 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_013f: Unknown result type (might be due to invalid IL or missing references)
			//IL_015d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0154: Unknown result type (might be due to invalid IL or missing references)
			//IL_0162: Unknown result type (might be due to invalid IL or missing references)
			//IL_0164: Unknown result type (might be due to invalid IL or missing references)
			//IL_0166: Unknown result type (might be due to invalid IL or missing references)
			//IL_0172: Unknown result type (might be due to invalid IL or missing references)
			//IL_0174: 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_0194: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a9: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ab: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)portal == (Object)null || (Object)(object)egg == (Object)null || !OffspringPortalPrefabs.IsOffspringPortal(portal))
			{
				return false;
			}
			if ((Object)(object)((Component)egg).GetComponent<EggGrow>() == (Object)null)
			{
				return false;
			}
			if (!JuvenilePortalRouter.IsBreederPortal(portal))
			{
				return false;
			}
			ZNetView component = ((Component)egg).GetComponent<ZNetView>();
			ZDO val = ((component != null) ? component.GetZDO() : null);
			if (val != null && val.GetBool("op_transported", false) && !ModConfig.AllowRetransport.Value)
			{
				return false;
			}
			int instanceID = ((Object)egg).GetInstanceID();
			float time = Time.time;
			if (!SpeciesDiscovery.TryGetEggSpeciesInfo(egg, out var info))
			{
				if (time - lastNoDestinationMessageTime > 5f)
				{
					lastNoDestinationMessageTime = time;
					string text = SpeciesKey.Normalize(((Object)egg).name);
					OffspringPortalPlugin.Log.LogWarning((object)("Breeder portal could not classify egg '" + text + "' for routing (missing EggGrow chain or species not discovered)."));
				}
				return false;
			}
			if (cooldowns.TryGetValue(instanceID, out var value) && time < value)
			{
				return false;
			}
			ZDOID val2 = (ZDOID)(((??)((component == null) ? ((ZDOID?)null) : component.GetZDO()?.m_uid)) ?? ZDOID.None);
			ZNetView component2 = ((Component)portal).GetComponent<ZNetView>();
			ZDOID val3 = (ZDOID)(((??)((component2 == null) ? ((ZDOID?)null) : component2.GetZDO()?.m_uid)) ?? ZDOID.None);
			if (val2 == ZDOID.None || val3 == ZDOID.None)
			{
				return false;
			}
			if (ZNet.instance.IsServer())
			{
				return TryRouteOnServer(portal, egg, info, val2, val3, cooldowns, ref lastNoDestinationMessageTime, time, instanceID);
			}
			if (!RoutingRpc.CanSendRequests())
			{
				return false;
			}
			RoutingRpc.RequestEggRoute(val2, val3, info.Key, info.IsDualPurposeEgg, info.EggCollectorKey);
			cooldowns[instanceID] = time + ModConfig.TeleportCooldownSec.Value;
			return false;
		}

		public static bool ExecuteApprovedRoute(ZDOID eggId, ZDOID sourcePortalId, PortalRecord destination, ItemDrop egg = null, OPTeleportWorld sourcePortal = null)
		{
			//IL_0003: Unknown result type (might be due to invalid IL or missing references)
			//IL_000f: Unknown result type (might be due to invalid IL or missing references)
			//IL_007f: Unknown result type (might be due to invalid IL or missing references)
			if (egg == null)
			{
				egg = ResolveEgg(eggId);
			}
			if (sourcePortal == null)
			{
				sourcePortal = ResolvePortal(sourcePortalId);
			}
			if ((Object)(object)egg == (Object)null || (Object)(object)sourcePortal == (Object)null || destination == null)
			{
				return false;
			}
			if (!JuvenilePortalRouter.IsBreederPortal(sourcePortal))
			{
				return false;
			}
			if (!EggTeleporter.TryExecuteApproved(egg, destination, sourcePortal))
			{
				return false;
			}
			if (SpeciesDiscovery.TryGetEggSpeciesInfo(egg, out var info))
			{
				string arg = ((destination.Role == PortalRole.EggCollector) ? SpeciesKey.GetEggCollectorDisplayName(info.EggCollectorKey) : "maturing portal");
				OffspringPortalPlugin.Log.LogInfo((object)$"Teleported {info.DisplayName} egg to {arg} at {destination.Position}.");
			}
			PlayPortalActivation(sourcePortal);
			return true;
		}

		private static bool TryRouteOnServer(OPTeleportWorld portal, ItemDrop egg, BreedableSpeciesInfo speciesInfo, ZDOID eggId, ZDOID sourcePortalId, Dictionary<int, float> cooldowns, ref float lastNoDestinationMessageTime, float now, int bodyId)
		{
			//IL_004a: 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)
			if (!EggRoutingResolver.TryResolveDestination(speciesInfo, out var destination))
			{
				if (now - lastNoDestinationMessageTime > 5f)
				{
					lastNoDestinationMessageTime = now;
					string eggRoutingFailureMessage = GetEggRoutingFailureMessage(speciesInfo);
					OffspringPortalPlugin.Log.LogWarning((object)eggRoutingFailureMessage);
					Player localPlayer = Player.m_localPlayer;
					if ((Object)(object)localPlayer != (Object)null)
					{
						((Character)localPlayer).Message((MessageType)2, eggRoutingFailureMessage, 0, (Sprite)null, false);
					}
				}
				return false;
			}
			if (ExecuteApprovedRoute(eggId, sourcePortalId, destination, egg, portal))
			{
				cooldowns[bodyId] = now + ModConfig.TeleportCooldownSec.Value;
				return true;
			}
			return false;
		}

		private static string GetEggRoutingFailureMessage(BreedableSpeciesInfo speciesInfo)
		{
			if (speciesInfo.IsDualPurposeEgg && EggRoutingResolver.IsHenEgg(speciesInfo))
			{
				if (DestinationRegistry.HasEggCollector())
				{
					return EggRoutingResolver.GetHenRoutingFailureMessage();
				}
				return "No Egg Collector or Maturing portal registered for Hen eggs.";
			}
			if (speciesInfo.IsDualPurposeEgg)
			{
				string eggCollectorDisplayName = SpeciesKey.GetEggCollectorDisplayName(speciesInfo.EggCollectorKey);
				return "No egg collector for " + eggCollectorDisplayName + " and no maturing fallback registered.";
			}
			return "No maturing portal registered for " + speciesInfo.DisplayName + " eggs.";
		}

		private static ItemDrop ResolveEgg(ZDOID eggId)
		{
			//IL_000c: Unknown result type (might be due to invalid IL or missing references)
			ZNetScene instance = ZNetScene.instance;
			GameObject val = ((instance != null) ? instance.FindInstance(eggId) : null);
			if (!((Object)(object)val != (Object)null))
			{
				return null;
			}
			return val.GetComponent<ItemDrop>();
		}

		private static OPTeleportWorld ResolvePortal(ZDOID portalId)
		{
			//IL_000c: Unknown result type (might be due to invalid IL or missing references)
			ZNetScene instance = ZNetScene.instance;
			GameObject val = ((instance != null) ? instance.FindInstance(portalId) : null);
			if (!((Object)(object)val != (Object)null))
			{
				return null;
			}
			return val.GetComponent<OPTeleportWorld>();
		}

		private static void PlayPortalActivation(OPTeleportWorld portal)
		{
			portal?.PlayActivationEffect();
		}
	}
	public static class EggRecipeHelper
	{
		private static readonly string[] KnownDualPurposeEggPrefabs = new string[1] { "Egg" };

		public static bool IsUsedInRecipe(SharedData shared)
		{
			if (shared == null || (Object)(object)ObjectDB.instance == (Object)null)
			{
				return false;
			}
			string name = shared.m_name;
			foreach (Recipe recipe in ObjectDB.instance.m_recipes)
			{
				if ((Object)(object)recipe == (Object)null || !recipe.m_enabled || recipe.m_resources == null)
				{
					continue;
				}
				Requirement[] resources = recipe.m_resources;
				foreach (Requirement val in resources)
				{
					if (!((Object)(object)val?.m_resItem == (Object)null))
					{
						SharedData val2 = val.m_resItem.m_itemData?.m_shared;
						if (val2 != null && val2.m_name == name)
						{
							return true;
						}
					}
				}
			}
			return false;
		}

		public static bool IsUsedInRecipe(ItemDrop itemDrop)
		{
			if ((Object)(object)itemDrop == (Object)null)
			{
				return false;
			}
			if (IsKnownDualPurposeEggPrefab(((Object)itemDrop).name))
			{
				return true;
			}
			return IsUsedInRecipe(itemDrop.m_itemData?.m_shared);
		}

		private static bool IsKnownDualPurposeEggPrefab(string prefabName)
		{
			string text = SpeciesKey.Normalize(prefabName);
			if (string.IsNullOrEmpty(text))
			{
				return false;
			}
			string[] knownDualPurposeEggPrefabs = KnownDualPurposeEggPrefabs;
			foreach (string value in knownDualPurposeEggPrefabs)
			{
				if (text.Equals(value, StringComparison.OrdinalIgnoreCase))
				{
					return true;
				}
			}
			return false;
		}
	}
	public static class EggRoutingResolver
	{
		private static readonly string[] HenEggCollectorLookupKeys = new string[4] { "Egg:Chicken", "Chicken", "Hen", "Egg:Hen" };

		private const string HenEggCollectorRoundRobinKey = "Egg:Chicken";

		public static bool IsHenEgg(BreedableSpeciesInfo speciesInfo)
		{
			if (speciesInfo == null)
			{
				return false;
			}
			return SpeciesKey.Canonicalize(speciesInfo.Key).Equals(SpeciesCatalog.ToStorageValue(SpeciesType.Chicken), StringComparison.OrdinalIgnoreCase);
		}

		public static bool TryResolveDestination(BreedableSpeciesInfo speciesInfo, out PortalRecord destination)
		{
			destination = null;
			if (speciesInfo == null)
			{
				return false;
			}
			if (speciesInfo.IsDualPurposeEgg && IsHenEgg(speciesInfo))
			{
				if (TryResolveHenEggCollector(out destination))
				{
					return true;
				}
				if (DestinationRegistry.HasEggCollector())
				{
					return false;
				}
				return DestinationRegistry.TryResolveMaturingDestination(speciesInfo.Key, out destination);
			}
			if (speciesInfo.IsDualPurposeEgg)
			{
				if (DestinationRegistry.TryResolveEggCollectorDestination(speciesInfo.EggCollectorKey, out destination) || DestinationRegistry.TryResolveMaturingDestination(speciesInfo.Key, out destination))
				{
					return destination != null;
				}
				return false;
			}
			return DestinationRegistry.TryResolveMaturingDestination(speciesInfo.Key, out destination);
		}

		public static string GetHenRoutingFailureMessage()
		{
			return "Hen egg not routed: an Egg Collector portal exists but none are configured for Hen eggs.";
		}

		private static bool TryResolveHenEggCollector(out PortalRecord destination)
		{
			return DestinationRegistry.TryResolveEggCollectorRoundRobin(HenEggCollectorLookupKeys, "Egg:Chicken", out destination);
		}
	}
	public static class EggTeleporter
	{
		public static bool TryTeleport(ItemDrop egg, PortalRecord destination, OPTeleportWorld sourcePortal)
		{
			return TryExecuteApproved(egg, destination, sourcePortal);
		}

		public static bool TryExecuteApproved(ItemDrop egg, PortalRecord destination, OPTeleportWorld sourcePortal)
		{
			//IL_001e: 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_0029: 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_0031: Unknown result type (might be due to invalid IL or missing references)
			//IL_0036: Unknown result type (might be due to invalid IL or missing references)
			//IL_0075: Unknown result type (might be due to invalid IL or missing references)
			//IL_0076: Unknown result type (might be due to invalid IL or missing references)
			//IL_0077: 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_0090: Unknown result type (might be due to invalid IL or missing references)
			//IL_0095: Unknown result type (might be due to invalid IL or missing references)
			//IL_009a: 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_00ad: 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_00c9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fc: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)egg == (Object)null || destination == null || (Object)(object)sourcePortal == (Object)null)
			{
				return false;
			}
			DestinationRegistry.RefreshPortalPosition(destination);
			Vector3 exitPosition = PortalPlacement.GetExitPosition(destination.Id, sourcePortal);
			Quaternion exitRotation = PortalPlacement.GetExitRotation(destination.Id, sourcePortal);
			ZNetView component = ((Component)egg).GetComponent<ZNetView>();
			if ((Object)(object)component == (Object)null || component.GetZDO() == null)
			{
				return false;
			}
			if (!component.IsOwner())
			{
				component.ClaimOwnership();
				if (!component.IsOwner() && !ZNet.instance.IsServer())
				{
					return false;
				}
			}
			Vector3 position = exitPosition + exitRotation * Vector3.right * Random.Range(-0.15f, 0.15f);
			((Component)egg).transform.position = position;
			((Component)egg).transform.rotation = exitRotation;
			ZDO zDO = component.GetZDO();
			if (zDO != null)
			{
				zDO.SetPosition(position);
				zDO.SetRotation(exitRotation);
				zDO.Set("op_transported", true);
			}
			Rigidbody component2 = ((Component)egg).GetComponent<Rigidbody>();
			if ((Object)(object)component2 != (Object)null)
			{
				component2.linearVelocity = Vector3.zero;
				component2.angularVelocity = Vector3.zero;
			}
			return true;
		}
	}
	public static class JuvenileFollow
	{
		internal const string LetsGoPluginGuid = "hardwire99.letsgo";

		public static bool TryCommand(Character character, Player player, bool showMessage)
		{
			//IL_011e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0124: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)character == (Object)null || (Object)(object)player == (Object)null)
			{
				return false;
			}
			if (!ModConfig.EnableFollowCommand.Value)
			{
				DiagnosticLog.Verbose("Follow command ignored: EnableFollowCommand is off.");
				return false;
			}
			if (IsLetsGoLoaded())
			{
				DiagnosticLog.Verbose("Follow command ignored: LetsGo mod is loaded.");
				return false;
			}
			if (!SpeciesHelper.IsEligibleJuvenile(character) || !character.IsTamed())
			{
				DiagnosticLog.Verbose($"Follow command ignored for {character.GetHoverName()}: eligible={SpeciesHelper.IsEligibleJuvenile(character)}, tamed={character.IsTamed()}.");
				return false;
			}
			ZNetView nview = character.GetNview();
			if ((Object)(object)nview == (Object)null || !nview.IsValid())
			{
				DiagnosticLog.Verbose("Follow command ignored for " + character.GetHoverName() + ": invalid ZNetView.");
				return false;
			}
			JuvenileGroundSnapper.EnsureAttached(character);
			JuvenileFollowController.EnsureAttached(character);
			if (ZNet.instance.IsServer())
			{
				DiagnosticLog.Verbose("Follow command handled locally on server for " + character.GetHoverName() + ".");
				return ApplyFollowToggle(character, player, showMessage);
			}
			string hoverName = character.GetHoverName();
			ZDO zDO = nview.GetZDO();
			DiagnosticLog.Verbose($"Follow command sending RPC for {hoverName} (owner={((zDO != null) ? zDO.GetOwner() : 0)}).");
			JuvenileFollowRpc.RequestToggle(nview.GetZDO().m_uid, ((Character)player).GetZDOID(), showMessage);
			return true;
		}

		public static bool ApplyFollowToggle(Character character, Player player, bool showMessage)
		{
			if ((Object)(object)character == (Object)null || (Object)(object)player == (Object)null)
			{
				return false;
			}
			if ((Object)(object)((Component)character).GetComponent<AnimalAI>() != (Object)null)
			{
				return ApplyAnimalFollowToggle(character, player, showMessage);
			}
			MonsterAI component = ((Component)character).GetComponent<MonsterAI>();
			if ((Object)(object)component != (Object)null)
			{
				Tameable component2 = ((Component)character).GetComponent<Tameable>();
				if ((Object)(object)component2 != (Object)null)
				{
					component2.m_commandable = true;
				}
				ApplyMonsterFollowToggle(character, component, player, showMessage);
				return true;
			}
			return false;
		}

		internal static bool IsLetsGoLoaded()
		{
			return Chainloader.PluginInfos.ContainsKey("hardwire99.letsgo");
		}

		public static bool IsFollowing(Character character)
		{
			//IL_003b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0040: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)character == (Object)null)
			{
				return false;
			}
			MonsterAI component = ((Component)character).GetComponent<MonsterAI>();
			if ((Object)(object)component != (Object)null && (Object)(object)component.GetFollowTarget() != (Object)null)
			{
				return true;
			}
			ZDO zdo = character.GetZdo();
			if (zdo != null)
			{
				return zdo.GetZDOID("op_follow_target") != ZDOID.None;
			}
			return false;
		}

		private static void ApplyMonsterFollowToggle(Character character, MonsterAI monsterAi, Player player, bool showMessage)
		{
			ZNetView component = ((Component)character).GetComponent<ZNetView>();
			if ((Object)(object)component != (Object)null && !component.IsOwner())
			{
				component.ClaimOwnership();
			}
			string hoverName = character.GetHoverName();
			if ((Object)(object)monsterAi.GetFollowTarget() != (Object)null)
			{
				monsterAi.SetFollowTarget((GameObject)null);
				((BaseAI)monsterAi).SetPatrolPoint();
				if ((Object)(object)component != (Object)null && component.IsOwner())
				{
					ZDO zDO = component.GetZDO();
					if (zDO != null)
					{
						zDO.Set(ZDOVars.s_follow, string.Empty);
					}
				}
				if (showMessage)
				{
					((Character)player).Message((MessageType)2, hoverName + " " + Localization.instance.Localize("$hud_tamestay"), 0, (Sprite)null, false);
				}
				return;
			}
			((BaseAI)monsterAi).ResetPatrolPoint();
			monsterAi.SetFollowTarget(((Component)player).gameObject);
			if ((Object)(object)component != (Object)null && component.IsOwner())
			{
				ZDO zDO2 = component.GetZDO();
				if (zDO2 != null)
				{
					zDO2.Set(ZDOVars.s_follow, player.GetPlayerName());
				}
			}
			if (showMessage)
			{
				((Character)player).Message((MessageType)2, hoverName + " " + Localization.instance.Localize("$hud_tamefollow"), 0, (Sprite)null, false);
			}
		}

		public static bool ApplyAnimalFollowToggle(Character character, Player player, bool showMessage)
		{
			//IL_0035: Unknown result type (might be due to invalid IL or missing references)
			//IL_003a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0041: 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_0094: 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)
			ZNetView nview = character.GetNview();
			if ((Object)(object)nview == (Object)null || !nview.IsValid())
			{
				return false;
			}
			if (!nview.IsOwner())
			{
				nview.ClaimOwnership();
			}
			ZDO zdo = character.GetZdo();
			if (zdo == null)
			{
				return false;
			}
			ZDOID zDOID = ((Character)player).GetZDOID();
			ZDOID zDOID2 = zdo.GetZDOID("op_follow_target");
			string hoverName = character.GetHoverName();
			if (zDOID2 == zDOID)
			{
				zdo.Set("op_follow_target", ZDOID.None);
				if (showMessage)
				{
					((Character)player).Message((MessageType)2, hoverName + " " + Localization.instance.Localize("$hud_tamestay"), 0, (Sprite)null, false);
				}
			}
			else
			{
				zdo.Set("op_follow_target", zDOID);
				if (showMessage)
				{
					((Character)player).Message((MessageType)2, hoverName + " " + Localization.instance.Localize("$hud_tamefollow"), 0, (Sprite)null, false);
				}
			}
			return true;
		}
	}
	public sealed class JuvenileFollowController : MonoBehaviour
	{
		public static bool TryApplyAnimalFollow(AnimalAI animalAi, float dt)
		{
			//IL_006f: 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_0075: Unknown result type (might be due to invalid IL or missing references)
			//IL_0076: Unknown result type (might be due to invalid IL or missing references)
			//IL_0084: 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_00aa: Unknown result type (might be due to invalid IL or missing references)
			//IL_00af: 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_00dd: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e1: Unknown result type (might be due to invalid IL or missing references)
			if (!ModConfig.EnableFollowCommand.Value || (Object)(object)animalAi == (Object)null)
			{
				return false;
			}
			Character component = ((Component)animalAi).GetComponent<Character>();
			ZNetView component2 = ((Component)animalAi).GetComponent<ZNetView>();
			if ((Object)(object)component == (Object)null || (Object)(object)component2 == (Object)null || !component2.IsValid())
			{
				return false;
			}
			if (!component2.IsOwner())
			{
				return false;
			}
			if (!SpeciesHelper.IsEligibleJuvenile(component) || !component.IsTamed())
			{
				return false;
			}
			ZDO zdo = component.GetZdo();
			if (zdo == null)
			{
				return false;
			}
			ZDOID zDOID = zdo.GetZDOID("op_follow_target");
			if (zDOID == ZDOID.None)
			{
				return false;
			}
			Player val = ResolvePlayer(zDOID);
			if ((Object)(object)val == (Object)null)
			{
				return false;
			}
			Vector3 val2 = ((Component)val).transform.position - ((Component)component).transform.position;
			val2.y = 0f;
			float magnitude = ((Vector3)(ref val2)).magnitude;
			if (magnitude < 2f)
			{
				((BaseAI)animalAi).StopMoving();
				return true;
			}
			((BaseAI)animalAi).MoveTowards(val2 / magnitude, magnitude > 10f);
			return true;
		}

		public static void EnsureAttached(Character character)
		{
			if (!((Object)(object)character == (Object)null) && !((Object)(object)((Component)character).GetComponent<AnimalAI>() == (Object)null) && (Object)(object)((Component)character).GetComponent<JuvenileFollowController>() == (Object)null)
			{
				((Component)character).gameObject.AddComponent<JuvenileFollowController>();
			}
		}

		private static Player ResolvePlayer(ZDOID followId)
		{
			//IL_000c: Unknown result type (might be due to invalid IL or missing references)
			//IL_006c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0071: Unknown result type (might be due to invalid IL or missing references)
			ZNetScene instance = ZNetScene.instance;
			GameObject val = ((instance != null) ? instance.FindInstance(followId) : null);
			Player val2 = (((Object)(object)val != (Object)null) ? val.GetComponent<Player>() : null);
			if ((Object)(object)val2 != (Object)null)
			{
				return val2;
			}
			foreach (Player allPlayer in Player.GetAllPlayers())
			{
				ZNetView val3 = ((Character)(object)allPlayer)?.GetNview();
				if ((Object)(object)val3 != (Object)null)
				{
					ZDO zDO = val3.GetZDO();
					if (zDO != null && zDO.m_uid == followId)
					{
						return allPlayer;
					}
				}
			}
			return null;
		}
	}
	public static class JuvenileFollowDisplay
	{
		public static void ApplyFollowHover(Character character, ref string hoverText)
		{
			if (ModConfig.EnableFollowCommand.Value && !JuvenileFollow.IsLetsGoLoaded() && !((Object)(object)character == (Object)null) && SpeciesHelper.IsEligibleJuvenile(character) && character.IsTamed() && (!((Object)(object)((Component)character).GetComponent<MonsterAI>() == (Object)null) || !((Object)(object)((Component)character).GetComponent<AnimalAI>() == (Object)null)))
			{
				string text = (JuvenileFollow.IsFollowing(character) ? "$hud_tamestay" : "$hud_tamefollow");
				string newValue = Localization.instance.Localize(text);
				string text2 = Localization.instance.Localize("$hud_pet");
				if (!string.IsNullOrEmpty(hoverText) && hoverText.Contains(text2))
				{
					hoverText = hoverText.Replace(text2, newValue);
				}
				else if (!string.IsNullOrEmpty(hoverText))
				{
					hoverText += Localization.instance.Localize("\n[<color=yellow><b>$KEY_Use</b></color>] " + text);
				}
				else
				{
					hoverText = Localization.instance.Localize(character.GetHoverName() + "\n[<color=yellow><b>$KEY_Use</b></color>] " + text);
				}
			}
		}
	}
	public static class JuvenileFollowRpc
	{
		private const string RpcToggleFollow = "OffspringPortal_ToggleJuvenileFollow";

		private const string RpcExecuteToggleFollow = "OffspringPortal_ExecuteJuvenileFollow";

		private static ZRoutedRpc registeredInstance;

		public static void Register()
		{
			ZRoutedRpc instance = ZRoutedRpc.instance;
			if (instance != null && registeredInstance != instance)
			{
				instance.Register<ZDOID, ZDOID, bool>("OffspringPortal_ToggleJuvenileFollow", (Action<long, ZDOID, ZDOID, bool>)OnToggleFollowRpc);
				instance.Register<ZDOID, ZDOID, bool>("OffspringPortal_ExecuteJuvenileFollow", (Action<long, ZDOID, ZDOID, bool>)OnExecuteToggleFollowRpc);
				registeredInstance = instance;
				DiagnosticLog.Info("Juvenile follow RPC handlers registered on current ZRoutedRpc instance.");
			}
		}

		public static void RequestToggle(ZDOID creatureId, ZDOID playerId, bool showMessage)
		{
			//IL_0045: 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_0060: Unknown result type (might be due to invalid IL or missing references)
			//IL_0061: 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_00a5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00cd: 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)
			if (ZRoutedRpc.instance == null)
			{
				DiagnosticLog.Warning("Cannot request juvenile follow toggle: ZRoutedRpc.instance is null.");
				return;
			}
			try
			{
				Register();
				if ((Object)(object)ZNet.instance == (Object)null)
				{
					DiagnosticLog.Warning("Cannot request juvenile follow toggle: ZNet.instance is null.");
					return;
				}
				if (ZNet.instance.IsServer())
				{
					DiagnosticLog.Verbose($"Local server handling juvenile follow request: creature={creatureId}, player={playerId}.");
					OnToggleFollowRpc(ZNet.GetUID(), creatureId, playerId, showMessage);
					return;
				}
				ZNetPeer serverPeer = ZNet.instance.GetServerPeer();
				if (serverPeer == null || serverPeer.m_uid == 0L)
				{
					DiagnosticLog.Warning("Cannot send juvenile follow RPC: server peer unavailable.");
					return;
				}
				DiagnosticLog.Verbose($"Sending juvenile follow RPC to server peer {serverPeer.m_uid}: creature={creatureId}, player={playerId}.");
				ZRoutedRpc.instance.InvokeRoutedRPC(serverPeer.m_uid, "OffspringPortal_ToggleJuvenileFollow", new object[3] { creatureId, playerId, showMessage });
			}
			catch (Exception exception)
			{
				OPLog.Exception("Failed to send juvenile follow RPC", exception);
			}
		}

		private static void OnToggleFollowRpc(long sender, ZDOID creatureId, ZDOID playerId, bool showMessage)
		{
			//IL_0024: 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_006f: 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_00e7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bd: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c6: Unknown result type (might be due to invalid IL or missing references)
			try
			{
				if ((Object)(object)ZNet.instance == (Object)null || !ZNet.instance.IsServer())
				{
					DiagnosticLog.Warning($"Follow RPC reached a non-server peer unexpectedly. sender={sender}, creature={creatureId}");
					return;
				}
				ZDOMan instance = ZDOMan.instance;
				ZDO obj = ((instance != null) ? instance.GetZDO(creatureId) : null);
				long num = ((obj != null) ? obj.GetOwner() : 0);
				DiagnosticLog.Verbose($"Server received follow request: sender={sender}, creature={creatureId}, owner={num}, player={playerId}.");
				if (num != 0L)
				{
					DiagnosticLog.Verbose($"Routing follow execution to ZDO owner {num}.");
					ZRoutedRpc.instance.InvokeRoutedRPC(num, "OffspringPortal_ExecuteJuvenileFollow", new object[3] { creatureId, playerId, showMessage });
				}
				else
				{
					DiagnosticLog.Verbose("Follow target has no remote owner; applying on server.");
					ApplyToggle(creatureId, playerId, showMessage, sender);
				}
			}
			catch (Exception exception)
			{
				OPLog.Exception($"Server failed processing juvenile follow request from {sender}", exception);
			}
		}

		private static void OnExecuteToggleFollowRpc(long sender, ZDOID creatureId, ZDOID playerId, bool showMessage)
		{
			//IL_000b: 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_0021: 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_0032: Unknown result type (might be due to invalid IL or missing references)
			try
			{
				DiagnosticLog.Verbose($"Executing juvenile follow RPC: sender={sender}, creature={creatureId}, player={playerId}.");
				ApplyToggle(creatureId, playerId, showMessage, sender);
			}
			catch (Exception exception)
			{
				OPLog.Exception($"Failed executing juvenile follow RPC for creature {creatureId}", exception);
			}
		}

		private static void ApplyToggle(ZDOID creatureId, ZDOID playerId, bool showMessage, long sender)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0008: 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_0046: Unknown result type (might be due to invalid IL or missing references)
			Character val = ResolveCreature(creatureId);
			Player val2 = ResolveRequestingPlayer(sender, playerId);
			if ((Object)(object)val == (Object)null || (Object)(object)val2 == (Object)null)
			{
				DiagnosticLog.Warning($"Could not resolve follow RPC targets. creature={creatureId} resolved={(Object)(object)val != (Object)null}, player={playerId} resolved={(Object)(object)val2 != (Object)null}, sender={sender}.");
			}
			else if (!SpeciesHelper.IsEligibleJuvenile(val) || !val.IsTamed())
			{
				DiagnosticLog.Verbose("Ignoring follow RPC for '" + val.GetHoverName() + "': not an eligible tamed juvenile.");
			}
			else
			{
				JuvenileGroundSnapper.EnsureAttached(val);
				JuvenileFollowController.EnsureAttached(val);
				JuvenileFollow.ApplyFollowToggle(val, val2, showMessage);
			}
		}

		private static Character ResolveCreature(ZDOID creatureId)
		{
			//IL_000c: Unknown result type (might be due to invalid IL or missing references)
			ZNetScene instance = ZNetScene.instance;
			GameObject val = ((instance != null) ? instance.FindInstance(creatureId) : null);
			if (!((Object)(object)val != (Object)null))
			{
				return null;
			}
			return val.GetComponent<Character>();
		}

		private static Player ResolveRequestingPlayer(long sender, ZDOID playerId)
		{
			//IL_001e: Unknown result type (might be due to invalid IL or missing references)
			Player player = Player.GetPlayer(sender);
			if ((Object)(object)player != (Object)null)
			{
				return player;
			}
			ZNetScene instance = ZNetScene.instance;
			GameObject val = ((instance != null) ? instance.FindInstance(playerId) : null);
			if (!((Object)(object)val != (Object)null))
			{
				return null;
			}
			return val.GetComponent<Player>();
		}
	}
	public sealed class JuvenileGroundSnapper : MonoBehaviour
	{
		private Character character;

		private ZNetView nview;

		private float nextCheckTime;

		private void Awake()
		{
			character = ((Component)this).GetComponent<Character>();
			nview = ((Component)this).GetComponent<ZNetView>();
		}

		private void Start()
		{
			TrySnapToGround(force: true);
		}

		private void LateUpdate()
		{
			if (!(Time.time < nextCheckTime) && !((Object)(object)character == (Object)null) && !((Object)(object)nview == (Object)null) && nview.IsValid() && ZNet.instance.IsServer() && nview.IsOwner() && SpeciesHelper.IsEligibleJuvenile(character))
			{
				nextCheckTime = Time.time + 1f;
				TrySnapToGround(force: false);
			}
		}

		public static void EnsureAttached(Character character)
		{
			if (!((Object)(object)character == (Object)null) && SpeciesHelper.IsEligibleJuvenile(character))
			{
				JuvenileGroundSnapper juvenileGroundSnapper = ((Component)character).GetComponent<JuvenileGroundSnapper>();
				if ((Object)(object)juvenileGroundSnapper == (Object)null)
				{
					juvenileGroundSnapper = ((Component)character).gameObject.AddComponent<JuvenileGroundSnapper>();
				}
				juvenileGroundSnapper.TrySnapToGround(force: true);
			}
		}

		private void TrySnapToGround(bool force)
		{
			//IL_0006: 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_0025: Unknown result type (might be due to invalid IL or missing references)
			//IL_003f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0046: Unknown result type (might be due to invalid IL or missing references)
			if (JuvenilePlacement.TryGetFloorPosition(((Component)this).transform.position, out var grounded))
			{
				float num = ((Component)this).transform.position.y - grounded.y;
				if (force || !(num < 0.35f))
				{
					JuvenilePlacement.ApplyPosition(character, grounded, ((Component)this).transform.rotation);
				}
			}
		}
	}
	public static class JuvenileInteractHelper
	{
		private static ZDOID lastLoggedResolvedJuvenileId;

		private static bool hasLastLoggedResolvedJuvenileId;

		private static void LogResolvedJuvenile(Character juvenile, string source, float? distance = null)
		{
			//IL_0042: Unknown result type (might be due to invalid IL or missing references)
			//IL_0047: Unknown result type (might be due to invalid IL or missing references)
			//IL_0028: 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_00a2: 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)
			if ((Object)(object)juvenile == (Object)null)
			{
				return;
			}
			ZNetView nview = juvenile.GetNview();
			ZDO val = ((nview != null) ? nview.GetZDO() : null);
			if (val != null && (!hasLastLoggedResolvedJuvenileId || !(lastLoggedResolvedJuvenileId == val.m_uid)))
			{
				hasLastLoggedResolvedJuvenileId = true;
				lastLoggedResolvedJuvenileId = val.m_uid;
				if (distance.HasValue)
				{
					DiagnosticLog.Verbose($"Crosshair search resolved '{juvenile.GetHoverName()}' from {source} at {distance.Value:F2}m (id={val.m_uid}).");
				}
				else
				{
					DiagnosticLog.Verbose($"Crosshair search resolved '{juvenile.GetHoverName()}' from {source} (id={val.m_uid}).");
				}
			}
		}

		public static Character FindJuvenileUnderCrosshair(Player player, float maxDistance = 6f)
		{
			return FindTamedCharacterUnderCrosshair(player, maxDistance, juvenilesOnly: true);
		}

		public static Character FindTamedCharacterUnderCrosshair(Player player, float maxDistance, bool juvenilesOnly)
		{
			//IL_006e: Unknown result type (might be due to invalid IL or missing references)
			//IL_007d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0082: 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_002f: Unknown result type (might be due to invalid IL or missing references)
			//IL_003a: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ce: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fe: 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)
			if ((Object)(object)player == (Object)null || (Object)(object)GameCamera.instance == (Object)null)
			{
				return null;
			}
			Character hoverCreature = player.GetHoverCreature();
			if (IsValidCandidate(hoverCreature, player, juvenilesOnly) && Vector3.Distance(((Character)player).m_eye.position, ((Component)hoverCreature).transform.position) <= maxDistance + 0.5f)
			{
				LogResolvedJuvenile(hoverCreature, "Player.GetHoverCreature()");
				return hoverCreature;
			}
			Vector3 position = ((Component)GameCamera.instance).transform.position;
			Vector3 forward = ((Component)GameCamera.instance).transform.forward;
			RaycastHit[] source = Physics.RaycastAll(position, forward, Mathf.Max(0.1f, maxDistance), -1, (QueryTriggerInteraction)1);
			Character val = null;
			float num = maxDistance;
			foreach (RaycastHit item in source.OrderBy((RaycastHit h) => ((RaycastHit)(ref h)).distance))
			{
				RaycastHit current = item;
				if ((Object)(object)((RaycastHit)(ref current)).collider == (Object)null)
				{
					continue;
				}
				Character characterFromCollider = GetCharacterFromCollider(((RaycastHit)(ref current)).collider);
				if (IsValidCandidate(characterFromCollider, player, juvenilesOnly))
				{
					float num2 = Vector3.Distance(((Character)player).m_eye.position, ((RaycastHit)(ref current)).point);
					if (num2 <= num)
					{
						val = characterFromCollider;
						num = num2;
					}
				}
			}
			if ((Object)(object)val != (Object)null)
			{
				LogResolvedJuvenile(val, "raycast", num);
			}
			return val;
		}

		private static Character GetCharacterFromCollider(Collider collider)
		{
			if ((Object)(object)collider == (Object)null)
			{
				return null;
			}
			Character componentInParent = ((Component)collider).GetComponentInParent<Character>();
			if ((Object)(object)componentInParent != (Object)null)
			{
				return componentInParent;
			}
			if ((Object)(object)collider.attachedRigidbody != (Object)null)
			{
				componentInParent = ((Component)collider.attachedRigidbody).GetComponentInParent<Character>();
			}
			return componentInParent;
		}

		private static bool IsValidCandidate(Character character, Player player, bool juvenilesOnly)
		{
			if ((Object)(object)character == (Object)null || (Object)(object)character == (Object)(object)player || character.IsPlayer() || !character.IsTamed())
			{
				return false;
			}
			if (juvenilesOnly)
			{
				return SpeciesHelper.IsEligibleJuvenile(character);
			}
			return (Object)(object)((Component)character).GetComponent<Tameable>() != (Object)null;
		}
	}
	public static class JuvenilePlacement
	{
		private static readonly int FloorMask = LayerMask.GetMask(new string[6] { "Default", "static_solid", "piece", "piece_nonsolid", "terrain", "water" });

		public static bool TryGetFloorPosition(Vector3 position, out Vector3 grounded)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0002: 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_002f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0036: Unknown result type (might be due to invalid IL or missing references)
			//IL_0046: 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_0055: 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_0083: 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_00a9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ad: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b7: 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_00dc: Unknown result type (might be due to invalid IL or missing references)
			//IL_00eb: Unknown result type (might be due to invalid IL or missing references)
			grounded = position;
			if ((Object)(object)ZoneSystem.instance == (Object)null)
			{
				return false;
			}
			float num = Mathf.Max(position.y + 30f, 128f);
			Vector3 val = default(Vector3);
			((Vector3)(ref val))..ctor(position.x, num, position.z);
			float solidHeight = default(float);
			if (!ZoneSystem.instance.GetGroundHeight(val, ref solidHeight))
			{
				solidHeight = ZoneSystem.instance.GetSolidHeight(position);
			}
			if (position.y - solidHeight > 2f)
			{
				grounded.y = solidHeight + 0.2f;
				return true;
			}
			float num2 = solidHeight + 0.2f;
			RaycastHit[] array = Physics.RaycastAll(val, Vector3.down, num + 100f, FloorMask);
			for (int i = 0; i < array.Length; i++)
			{
				RaycastHit val2 = array[i];
				if (!(((RaycastHit)(ref val2)).point.y > position.y + 1f) && !(((RaycastHit)(ref val2)).point.y < solidHeight - 1f) && ((RaycastHit)(ref val2)).point.y > num2)
				{
					num2 = ((RaycastHit)(ref val2)).point.y + 0.15f;
				}
			}
			grounded.y = num2;
			return true;
		}

		public static void ApplyLivePosition(Character character, Vector3 position, Quaternion rotation)
		{
			//IL_0010: 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_0049: Unknown result type (might be due to invalid IL or missing references)
			//IL_0033: Unknown result type (might be due to invalid IL or missing references)
			//IL_003e: Unknown result type (might be due to invalid IL or missing references)
			if (!((Object)(object)character == (Object)null))
			{
				((Component)character).transform.position = position;
				((Component)character).transform.rotation = rotation;
				Rigidbody component = ((Component)character).GetComponent<Rigidbody>();
				if ((Object)(object)component != (Object)null)
				{
					component.linearVelocity = Vector3.zero;
					component.angularVelocity = Vector3.zero;
				}
				character.SetLookDir(position, 0f);
			}
		}

		public static void ApplyPosition(Character character, Vector3 position, Quaternion rotation)
		{
			//IL_0010: 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_0049: Unknown result type (might be due to invalid IL or missing references)
			//IL_0033: Unknown result type (might be due to invalid IL or missing references)
			//IL_003e: 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_0072: Unknown result type (might be due to invalid IL or missing references)
			if (!((Object)(object)character == (Object)null))
			{
				((Component)character).transform.position = position;
				((Component)character).transform.rotation = rotation;
				Rigidbody component = ((Component)character).GetComponent<Rigidbody>();
				if ((Object)(object)component != (Object)null)
				{
					component.linearVelocity = Vector3.zero;
					component.angularVelocity = Vector3.zero;
				}
				character.SetLookDir(position, 0f);
				ZNetView nview = character.GetNview();
				ZDO val = ((nview != null) ? nview.GetZDO() : null);
				if (val != null)
				{
					val.SetPosition(position);
					val.SetRotation(rotation);
				}
			}
		}
	}
	public static class JuvenilePortalRouter
	{
		public static bool IsBreederPortal(OPTeleportWorld portal)
		{
			//IL_002c: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)portal == (Object)null)
			{
				return false;
			}
			ZNetView component = ((Component)portal).GetComponent<ZNetView>();
			ZDO val = ((component != null) ? component.GetZDO() : null);
			if (val == null || !PortalConfigGate.IsConfiguredForAutomation(val))
			{
				return false;
			}
			PortalRecord portalRecord = DestinationRegistry.Get(val.m_uid);
			if (portalRecord != null)
			{
				return portalRecord.Role == PortalRole.Breeder;
			}
			return PortalRoleCatalog.FromZdo(val) == PortalRole.Breeder;
		}

		public static bool TryRoute(OPTeleportWorld portal, Character character, Dictionary<int, float> cooldowns, ref float lastNoDestinationMessageTime)
		{
			//IL_00b2: 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_00c7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d5: Unknown result type (might be due to invalid IL or missing references)
			//IL_0102: 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)
			//IL_0117: Unknown result type (might be due to invalid IL or missing references)
			//IL_0125: Unknown result type (might be due to invalid IL or missing references)
			//IL_0127: Unknown result type (might be due to invalid IL or missing references)
			//IL_0129: Unknown result type (might be due to invalid IL or missing references)
			//IL_0135: 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_015d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0172: Unknown result type (might be due to invalid IL or missing references)
			//IL_0174: Unknown result type (might be due to invalid IL or missing references)
			//IL_019f: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a6: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b7: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b9: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)portal == (Object)null || (Object)(object)character == (Object)null || !OffspringPortalPrefabs.IsOffspringPortal(portal))
			{
				return false;
			}
			if (!SpeciesHelper.IsEligibleJuvenile(character))
			{
				return false;
			}
			int instanceID = ((Object)character).GetInstanceID();
			float time = Time.time;
			if (cooldowns.TryGetValue(instanceID, out var value) && time < value)
			{
				return false;
			}
			ZDO zdo = character.GetZdo();
			if (zdo != null && zdo.GetBool("op_transported", false) && !ModConfig.AllowRetransport.Value)
			{
				return false;
			}
			if (!IsBreederPortal(portal))
			{
				return false;
			}
			string juvenileSpeciesKey = SpeciesHelper.GetJuvenileSpeciesKey(character);
			if (string.IsNullOrEmpty(juvenileSpeciesKey))
			{
				return false;
			}
			ZNetView nview = character.GetNview();
			ZDOID val = (ZDOID)(((??)((nview == null) ? ((ZDOID?)null) : nview.GetZDO()?.m_uid)) ?? ZDOID.None);
			ZNetView component = ((Component)portal).GetComponent<ZNetView>();
			ZDOID val2 = (ZDOID)(((??)((component == null) ? ((ZDOID?)null) : component.GetZDO()?.m_uid)) ?? ZDOID.None);
			if (val == ZDOID.None || val2 == ZDOID.None)
			{
				return false;
			}
			if (ZNet.instance.IsServer())
			{
				DiagnosticLog.Verbose($"Juvenile scan on server: {SpeciesKey.GetDisplayName(juvenileSpeciesKey)} at breeder {val2}.");
				return TryRouteOnServer(portal, character, juvenileSpeciesKey, val, val2, cooldowns, ref lastNoDestinationMessageTime, time, instanceID);
			}
			if (!RoutingRpc.CanSendRequests())
			{
				DiagnosticLog.Verbose("Juvenile route skipped on client: routing RPC unavailable.");
				return false;
			}
			DiagnosticLog.Verbose($"Juvenile route client request: {SpeciesKey.GetDisplayName(juvenileSpeciesKey)} creature={val}, breeder={val2}.");
			RoutingRpc.RequestJuvenileRoute(val, val2, juvenileSpeciesKey);
			cooldowns[instanceID] = time + ModConfig.TeleportCooldownSec.Value;
			return false;
		}

		public static bool ExecuteApprovedRoute(ZDOID characterId, ZDOID sourcePortalId, PortalRecord destination, Character character = null, OPTeleportWorld sourcePortal = null)
		{
			//IL_0003: Unknown result type (might be due to invalid IL or missing references)
			//IL_000f: Unknown result type (might be due to invalid IL or missing references)
			//IL_012b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0154: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f3: Unknown result type (might be due to invalid IL or missing references)
			//IL_0101: 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_0057: 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_00b1: Unknown result type (might be due to invalid IL or missing references)
			//IL_008f: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c3: Unknown result type (might be due to invalid IL or missing references)
			if (character == null)
			{
				character = ResolveCharacter(characterId);
			}
			if (sourcePortal == null)
			{
				sourcePortal = ResolvePortal(sourcePortalId);
			}
			if (destination == null)
			{
				return false;
			}
			if ((Object)(object)character != (Object)null && (Object)(object)sourcePortal != (Object)null)
			{
				if (!SpeciesHelper.IsEligibleJuvenile(character) || !IsBreederPortal(sourcePortal))
				{
					return false;
				}
				string juvenileSpeciesKey = SpeciesHelper.GetJuvenileSpeciesKey(character);
				Vector3 val = JuvenileTeleporter.ResolveDestinationPosition(destination, sourcePortal);
				bool allowStoredHeight = (Object)(object)ZNetScene.instance == (Object)null || !ZNetScene.instance.IsAreaReady(val);
				if (JuvenileTeleporter.TryExecuteApproved(character, destination, sourcePortal, allowStoredHeight))
				{
					DiagnosticLog.Info($"Teleported {SpeciesKey.GetDisplayName(juvenileSpeciesKey)} juvenile to maturing portal at {destination.Position}.");
					PlayPortalActivation(sourcePortal);
					return true;
				}
				object arg = characterId;
				ZNetScene instance = ZNetScene.instance;
				DiagnosticLog.Verbose($"Juvenile teleport TryExecuteApproved failed for {arg}; areaReady={instance != null && instance.IsAreaReady(val)}.");
			}
			if ((Object)(object)ZNet.instance != (Object)null && ZNet.instance.IsServer() && JuvenileTeleporter.TryMoveZdo(characterId, destination, sourcePortalId))
			{
				DiagnosticLog.Info($"Teleported juvenile via ZDO to maturing portal at {destination.Position}.");
				PlayPortalActivation(sourcePortal);
				return true;
			}
			DiagnosticLog.Verbose($"ExecuteApprovedRoute failed for creature {characterId}: character={(Object)(object)character != (Object)null}, source={(Object)(object)sourcePortal != (Object)null}, destination={destination.Id}.");
			return false;
		}

		private static bool TryRouteOnServer(OPTeleportWorld portal, Character character, string speciesKey, ZDOID characterId, ZDOID sourcePortalId, Dictionary<int, float> cooldowns, ref float lastNoDestinationMessageTime, float now, int bodyId)
		{
			//IL_0055: 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_0085: 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)
			if (!DestinationRegistry.TryResolveMaturingDestination(speciesKey, out var destination))
			{
				if (DiagnosticLog.ShouldLogRateLimited(ref lastNoDestinationMessageTime, 5f))
				{
					string displayName = SpeciesKey.GetDisplayName(speciesKey);
					DestinationRegistry.LogMaturingResolutionFailure(speciesKey, "breeder scan");
					Player localPlayer = Player.m_localPlayer;
					if ((Object)(object)localPlayer != (Object)null)
					{
						((Character)localPlayer).Message((MessageType)2, "No maturing portal registered for " + displayName + ".", 0, (Sprite)null, false);
					}
				}
				return false;
			}
			if (ExecuteApprovedRoute(characterId, sourcePortalId, destination, character, portal))
			{
				cooldowns[bodyId] = now + ModConfig.TeleportCooldownSec.Value;
				return true;
			}
			DiagnosticLog.Warning($"Failed to teleport {SpeciesKey.GetDisplayName(speciesKey)} juvenile from breeder {sourcePortalId} to maturing {destination.Id}.");
			return false;
		}

		private static Character ResolveCharacter(ZDOID characterId)
		{
			//IL_000c: Unknown result type (might be due to invalid IL or missing references)
			ZNetScene instance = ZNetScene.instance;
			GameObject val = ((instance != null) ? instance.FindInstance(characterId) : null);
			if (!((Object)(object)val != (Object)null))
			{
				return null;
			}
			return val.GetComponent<Character>();
		}

		private static OPTeleportWorld ResolvePortal(ZDOID portalId)
		{
			//IL_000c: Unknown result type (might be due to invalid IL or missing references)
			ZNetScene instance = ZNetScene.instance;
			GameObject val = ((instance != null) ? instance.FindInstance(portalId) : null);
			if (!((Object)(object)val != (Object)null))
			{
				return null;
			}
			return val.GetComponent<OPTeleportWorld>();
		}

		private static void PlayPortalActivation(OPTeleportWorld portal)
		{
			portal?.PlayActivationEffect();
		}
	}
	public static class JuvenileTeleporter
	{
		public static bool TryTeleport(Character juvenile, PortalRecord destination, OPTeleportWorld sourcePortal)
		{
			//IL_0034: Unknown result type (might be due to invalid IL or missing references)
			//IL_003a: Unknown result type (might be due to invalid IL or missing references)
			//IL_003f: 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_007f: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)juvenile == (Object)null || destination == null || (Object)(object)sourcePortal == (Object)null)
			{
				return false;
			}
			if (!ZNet.instance.IsServer() && !CanExecuteLocally(juvenile))
			{
				return false;
			}
			DestinationRegistry.RefreshPortalPosition(destination);
			Vector3 exitPosition = PortalPlacement.GetExitPosition(destination.Id, sourcePortal);
			if ((Object)(object)ZNetScene.instance != (Object)null && ZNetScene.instance.IsAreaReady(exitPosition))
			{
				return TryExecuteApproved(juvenile, destination, sourcePortal);
			}
			if (TryExecuteApproved(juvenile, destination, sourcePortal, allowStoredHeight: true))
			{
				DiagnosticLog.Info($"Cross-zone teleport of {SpeciesCatalog.GetDisplayName(SpeciesHelper.GetJuvenileSpecies(juvenile))} to {exitPosition}.");
				return true;
			}
			DiagnosticLog.Info("Deferring teleport of " + SpeciesCatalog.GetDisplayName(SpeciesHelper.GetJuvenileSpecies(juvenile)) + " until pen zone loads.");
			if (ZNet.instance.IsServer())
			{
				return OffspringPortalRuntime.Instance.TryQueueDistantTeleport(juvenile, destination, sourcePortal);
			}
			return false;
		}

		public static bool TryTeleportNow(Character juvenile, PortalRecord destination, OPTeleportWorld sourcePortal, bool allowStoredHeight = false)
		{
			return TryExecuteApproved(juvenile, destination, sourcePortal, allowStoredHeight);
		}

		public static bool TryExecuteApproved(Character juvenile, PortalRecord destination, OPTeleportWorld sourcePortal, bool allowStoredHeight = false)
		{
			//IL_0077: Unknown result type (might be due to invalid IL or missing references)
			//IL_007d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0082: 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_008a: Unknown result type (might be due to invalid IL or missing references)
			//IL_008f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0091: Unknown result type (might be due to invalid IL or missing references)
			//IL_0092: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)juvenile == (Object)null || destination == null || (Object)(object)sourcePortal == (Object)null)
			{
				return false;
			}
			ZNetView nview = juvenile.GetNview();
			if ((Object)(object)nview == (Object)null || !nview.IsValid())
			{
				return false;
			}
			if (!nview.IsOwner())
			{
				nview.ClaimOwnership();
				if (!nview.IsOwner() && !ZNet.instance.IsServer())
				{
					return false;
				}
			}
			Tameable component = ((Component)juvenile).GetComponent<Tameable>();
			if ((Object)(object)component != (Object)null)
			{
				component.m_unsummonDistance = 0f;
			}
			DestinationRegistry.RefreshPortalPosition(destination);
			Vector3 exitPosition = PortalPlacement.GetExitPosition(destination.Id, sourcePortal);
			Quaternion exitRotation = PortalPlacement.GetExitRotation(destination.Id, sourcePortal);
			if (!TryPlaceCharacter(juvenile, exitPosition, exitRotation, allowStoredHeight))
			{
				Player localPlayer = Player.m_localPlayer;
				if ((Object)(object)localPlayer != (Object)null)
				{
					((Character)localPlayer).Message((MessageType)2, "Could not place " + SpeciesCatalog.GetDisplayName(SpeciesHelper.GetJuvenileSpecies(juvenile)) + " at destination.", 0, (Sprite)null, false);
				}
				return false;
			}
			JuvenileGroundSnapper.EnsureAttached(juvenile);
			JuvenileFollowController.EnsureAttached(juvenile);
			ZDO zDO = nview.GetZDO();
			if (zDO != null)
			{
				zDO.Set("op_transported", true);
			}
			return true;
		}

		public static bool TryMoveZdo(ZDOID characterId, PortalRecord destination, ZDOID sourcePortalId)
		{
			//IL_000c: 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_002a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0041: Unknown result type (might be due to invalid IL or missing references)
			//IL_0092: Unknown result type (might be due to invalid IL or missing references)
			//IL_0072: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b0: 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_00bd: Unknown result type (might be due to invalid IL or missing references)
			//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_00dc: Unknown result type (might be due to invalid IL or missing references)
			//IL_010c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0113: Unknown result type (might be due to invalid IL or missing references)
			//IL_012c: 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_014c: Unknown result type (might be due to invalid IL or missing references)
			//IL_015b: Unknown result type (might be due to invalid IL or missing references)
			//IL_00eb: Unknown result type (might be due to invalid IL or missing references)
			//IL_016d: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f7: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ba: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c4: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d1: Unknown result type (might be due to invalid IL or missing references)
			//IL_0197: Unknown result type (might be due to invalid IL or missing references)
			//IL_0198: Unknown result type (might be due to invalid IL or missing references)
			if (!ZNet.instance.IsServer() || characterId == ZDOID.None || destination == null || ZDOMan.instance == null)
			{
				return false;
			}
			ZDO zDO = ZDOMan.instance.GetZDO(characterId);
			if (zDO == null || !zDO.IsValid())
			{
				DiagnosticLog.Verbose($"Authoritative juvenile move failed: creature ZDO {characterId} is unavailable or invalid.");
				return false;
			}
			if (zDO.GetBool("op_transported", false) && !ModConfig.AllowRetransport.Value)
			{
				DiagnosticLog.Verbose($"Authoritative juvenile move skipped: {characterId} is already marked transported.");
				return false;
			}
			OPTeleportWorld fallbackPortal = null;
			ZNetScene instance = ZNetScene.instance;
			GameObject val = ((instance != null) ? instance.FindInstance(sourcePortalId) : null);
			if ((Object)(object)val != (Object)null)
			{
				fallbackPortal = val.GetComponent<OPTeleportWorld>();
			}
			DestinationRegistry.RefreshPortalPosition(destination);
			Vector3 val2 = PortalPlacement.GetExitPosition(destination.Id, fallbackPortal);
			Quaternion exitRotation = PortalPlacement.GetExitRotation(destination.Id, fallbackPortal);
			bool flag = (Object)(object)ZNetScene.instance != (Object)null && ZNetScene.instance.IsAreaReady(val2);
			if (flag && JuvenilePlacement.TryGetFloorPosition(val2, out var grounded))
			{
				val2 = grounded;
			}
			long owner = zDO.GetOwner();
			zDO.SetOwner(ZNet.GetUID());
			zDO.SetPosition(val2);
			zDO.SetRotation(exitRotation);
			zDO.Set("op_transported", true);
			zDO.Set(ZDOVars.s_velHash, Vector3.zero);
			zDO.Set(ZDOVars.s_bodyVelHash, Vector3.zero);
			zDO.Set(ZDOVars.s_bodyAVelHash, Vector3.zero);
			ZDOMan.instance.ForceSendZDO(characterId);
			ZNetScene instance2 = ZNetScene.instance;
			GameObject val3 = ((instance2 != null) ? instance2.FindInstance(characterId) : null);
			Character val4 = (((Object)(object)val3 != (Object)null) ? val3.GetComponent<Character>() : null);
			if ((Object)(object)val4 != (Object)null)
			{
				JuvenilePlacement.ApplyLivePosition(val4, val2, exitRotation);
				JuvenileGroundSnapper.EnsureAttached(val4);
				JuvenileFollowController.EnsureAttached(val4);
			}
			DiagnosticLog.Verbose($"Authoritative juvenile ZDO move: creature={characterId}, destination={destination.Id}, target={val2}, areaReady={flag}, instantiatedOnServer={(Object)(object)val4 != (Object)null}, previousOwner={owner}.");
			return true;
		}

		public static bool TryApplyLiveTransfer(ZDOID characterId, Vector3 targetPos, Quaternion targetRot)
		{
			//IL_000c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0032: 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)
			ZNetScene instance = ZNetScene.instance;
			GameObject val = ((instance != null) ? instance.FindInstance(characterId) : null);
			Character val2 = (((Object)(object)val != (Object)null) ? val.GetComponent<Character>() : null);
			if ((Object)(object)val2 == (Object)null)
			{
				return false;
			}
			JuvenilePlacement.ApplyLivePosition(val2, targetPos, targetRot);
			JuvenileGroundSnapper.EnsureAttached(val2);
			JuvenileFollowController.EnsureAttached(val2);
			return true;
		}

		public static Vector3 ResolveDestinationPosition(PortalRecord destination, OPTeleportWorld sourcePortal)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			return PortalPlacement.GetExitPosition(destination.Id, sourcePortal);
		}

		public static Quaternion ResolveDestinationRotation(PortalRecord destination, OPTeleportWorld sourcePortal)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			return PortalPlacement.GetExitRotation(destination.Id, sourcePortal);
		}

		private static bool CanExecuteLocally(Character juvenile)
		{
			ZNetView val = juvenile?.GetNview();
			if ((Object)(object)val != (Object)null && val.IsValid())
			{
				return val.IsOwner();
			}
			return false;
		}

		private static bool TryPlaceCharacter(Character character, Vector3 destination, Quaternion rotation, bool allowStoredHeight)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_000b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0010: Unknown result type (might be due to invalid IL or missing references)
			//IL_0011: Unknown result type (might be due to invalid IL or missing referenc