Please disclose if any significant portion of your mod was created using AI tools by adding the 'AI Generated' category. Failing to do so may result in the mod being removed from Thunderstore.
Decompiled source of Offspring Portal v0.2.9
OffspringPortal.dll
Decompiled 2 days ago
The result has been truncated due to the large size, download it to view full contents!
using System; using System.Collections; using System.Collections.Generic; using System.Diagnostics; using System.Linq; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using System.Security; using System.Security.Permissions; using BepInEx; using BepInEx.Configuration; using BepInEx.Logging; using HarmonyLib; 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("0.1.0.0")] [assembly: AssemblyInformationalVersion("0.1.0+7c1d2c20f20282a1313ac0e61abf2255741dfadf")] [assembly: AssemblyProduct("OffspringPortal")] [assembly: AssemblyTitle("OffspringPortal")] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("0.1.0.0")] [module: UnverifiableCode] [module: RefSafetyRules(11)] namespace Microsoft.CodeAnalysis { [CompilerGenerated] [Embedded] internal sealed class EmbeddedAttribute : Attribute { } } namespace System.Runtime.CompilerServices { [CompilerGenerated] [Embedded] [AttributeUsage(AttributeTargets.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(TeleportWorld portal) { //IL_0024: 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) { 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(TeleportWorld portal, Character character, Dictionary<int, float> cooldowns, ref float lastNoDestinationMessageTime) { //IL_0058: Unknown result type (might be due to invalid IL or missing references) //IL_0051: Unknown result type (might be due to invalid IL or missing references) //IL_0148: 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; } if (!ZNet.instance.IsServer()) { 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; } SpeciesType adultSpecies = SpeciesHelper.GetAdultSpecies(character); if (!SpeciesHelper.SpeciesMatches(adultSpecies, portalRecord.DeclaredSpecies)) { return false; } PortalRecord destination; switch (portalRecord.AdultDestination) { case AdultDestination.Farm: if (!DestinationRegistry.TryResolveFarmDestination(adultSpecies, out destination)) { string message = "No Farm portal exists."; return WarnMissingDestination(time, ref lastNoDestinationMessageTime, message); } break; case AdultDestination.Cull: if (!DestinationRegistry.TryResolveCullDestination(out destination)) { string message = "No Cull portal exists."; return WarnMissingDestination(time, ref lastNoDestinationMessageTime, message); } break; default: return false; } if (!JuvenileTeleporter.TryTeleport(character, destination, portal)) { OffspringPortalPlugin.Log.LogWarning((object)("Failed to teleport " + SpeciesCatalog.GetDisplayName(adultSpecies) + " adult.")); return false; } OffspringPortalPlugin.Log.LogInfo((object)$"Teleported {SpeciesCatalog.GetDisplayName(adultSpecies)} adult to {portalRecord.AdultDestination} portal at {destination.Position}."); cooldowns[instanceID] = time + ModConfig.TeleportCooldownSec.Value; PlayPortalActivation(portal); return true; } 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); } return false; } private static void PlayPortalActivation(TeleportWorld portal) { //IL_001b: Unknown result type (might be due to invalid IL or missing references) //IL_0026: Unknown result type (might be due to invalid IL or missing references) if (portal?.m_connected != null) { portal.m_connected.Create(((Component)portal).transform.position, ((Component)portal).transform.rotation, ((Component)portal).transform, 1f, -1); } } } 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, _ => 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: return 20f; default: return 0f; } } } public sealed class PortalRecord { public ZDOID Id; public Vector3 Position; public PortalRole Role; public SpeciesType DeclaredSpecies; public AdultDestination AdultDestination; } public static class DestinationRegistry { private static readonly Dictionary<ZDOID, PortalRecord> Portals = new Dictionary<ZDOID, PortalRecord>(); private static readonly Dictionary<SpeciesType, int> MaturingRoundRobinIndex = new Dictionary<SpeciesType, int>(); private static readonly Dictionary<SpeciesType, int> FarmRoundRobinIndex = new Dictionary<SpeciesType, int>(); private static int cullRoundRobinIndex; public static void Clear() { Portals.Clear(); } public static void RegisterOrUpdate(ZDOID id, Vector3 position, PortalRole role, SpeciesType declaredSpecies, 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.DeclaredSpecies = declaredSpecies; value.AdultDestination = adultDestination; } 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_000a: Unknown result type (might be due to invalid IL or missing references) //IL_001a: Unknown result type (might be due to invalid IL or missing references) //IL_001f: Unknown result type (might be due to invalid IL or missing references) if (record != null) { ZDO zDO = ZDOMan.instance.GetZDO(record.Id); if (zDO != null) { record.Position = zDO.GetPosition(); } } } public static bool TryResolveMaturingDestination(SpeciesType juvenileSpecies, out PortalRecord destination) { return TryResolveDestination(juvenileSpecies, PortalRole.Maturing, MaturingRoundRobinIndex, out destination); } public static bool TryResolveFarmDestination(SpeciesType adultSpecies, out PortalRecord destination) { return TryResolveDestination(adultSpecies, 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 ((object)Unsafe.As<ZDOID, ZDOID>(ref p.Id)/*cast due to .constrained prefix*/).ToString() select p).ToList(); if (list.Count == 0) { return false; } destination = list[cullRoundRobinIndex % list.Count]; cullRoundRobinIndex++; RefreshPortalPosition(destination); return true; } public static bool HasCullReceiver() { return Portals.Values.Any((PortalRecord p) => p.Role == PortalRole.Cull); } public static bool HasFarmReceiver(SpeciesType maturingReceives) { if (maturingReceives != SpeciesType.None && maturingReceives != SpeciesType.All && TryResolveFarmDestination(maturingReceives, out var destination)) { return true; } if (TryResolveFarmDestination(SpeciesType.All, out destination)) { return true; } if (maturingReceives == SpeciesType.All) { 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 void RefreshCapWarnings() { //IL_0077: Unknown result type (might be due to invalid IL or missing references) if (!ModConfig.EnableCapWarning.Value) { return; } foreach (PortalRecord destination in Portals.Values.Where((PortalRecord p) => p.Role == PortalRole.Maturing && p.DeclaredSpecies != SpeciesType.All)) { bool flag = GetBreederPortals().Any((PortalRecord source) => Vector3.Distance(source.Position, destination.Position) <= BreedingCapData.GetCapRadius(destination.DeclaredSpecies)); ZDO zDO = ZDOMan.instance.GetZDO(destination.Id); if (zDO != null) { zDO.Set("op_cap_warning", flag); } } } private static bool TryResolveDestination(SpeciesType species, PortalRole requiredRole, Dictionary<SpeciesType, int> roundRobinIndex, out PortalRecord destination) { destination = null; if (species == SpeciesType.None) { return false; } List<PortalRecord> list = (from p in Portals.Values where p.Role == requiredRole && p.DeclaredSpecies == species orderby ((object)Unsafe.As<ZDOID, ZDOID>(ref p.Id)/*cast due to .constrained prefix*/).ToString() select p).ToList(); if (list.Count > 0) { destination = PickRoundRobin(species, list, roundRobinIndex); RefreshPortalPosition(destination); return destination != null; } List<PortalRecord> list2 = (from p in Portals.Values where p.Role == requiredRole && p.DeclaredSpecies == SpeciesType.All orderby ((object)Unsafe.As<ZDOID, ZDOID>(ref p.Id)/*cast due to .constrained prefix*/).ToString() select p).ToList(); if (list2.Count > 0) { destination = PickRoundRobin(SpeciesType.All, list2, roundRobinIndex); RefreshPortalPosition(destination); return destination != null; } return false; } private static PortalRecord PickRoundRobin(SpeciesType key, List<PortalRecord> candidates, Dictionary<SpeciesType, 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 JuvenileFollow { public static bool TryCommand(Character character, Player player, bool showMessage) { if ((Object)(object)character == (Object)null || (Object)(object)player == (Object)null) { return false; } if (!SpeciesHelper.IsEligibleJuvenile(character) || !character.IsTamed()) { return false; } ZNetView nview = character.GetNview(); if ((Object)(object)nview == (Object)null || !nview.IsValid()) { return false; } MonsterAI component = ((Component)character).GetComponent<MonsterAI>(); Tameable component2 = ((Component)character).GetComponent<Tameable>(); if ((Object)(object)component2 != (Object)null && (Object)(object)component != (Object)null) { component2.m_commandable = true; if (ZNet.instance.IsServer()) { ApplyMonsterFollowToggle(component2, component, player, showMessage); return true; } component2.Command((Humanoid)(object)player, showMessage); return true; } if ((Object)(object)((Component)character).GetComponent<AnimalAI>() == (Object)null) { return false; } JuvenileFollowController.EnsureAttached(character); JuvenileFollowRpcHandler.EnsureAttached(character); if (ZNet.instance.IsServer()) { return ApplyAnimalFollowToggle(character, player, showMessage); } ((Component)character).GetComponent<JuvenileFollowRpcHandler>()?.RequestToggle(player, showMessage); return true; } 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(Tameable tameable, MonsterAI monsterAi, Player player, bool showMessage) { ZNetView component = ((Component)tameable).GetComponent<ZNetView>(); if ((Object)(object)component != (Object)null && !component.IsOwner()) { component.ClaimOwnership(); } 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, tameable.GetHoverName() + " " + Localization.instance.Localize("$hud_tamestay"), 0, (Sprite)null); } 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, tameable.GetHoverName() + " " + Localization.instance.Localize("$hud_tamefollow"), 0, (Sprite)null); } } 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_0093: 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); } } else { zdo.Set("op_follow_target", zDOID); if (showMessage) { ((Character)player).Message((MessageType)2, hoverName + " " + Localization.instance.Localize("$hud_tamefollow"), 0, (Sprite)null); } } return true; } } public sealed class JuvenileFollowController : MonoBehaviour { public static bool TryApplyAnimalFollow(AnimalAI animalAi, float dt) { //IL_007b: Unknown result type (might be due to invalid IL or missing references) //IL_0080: Unknown result type (might be due to invalid IL or missing references) //IL_0081: 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_0090: Unknown result type (might be due to invalid IL or missing references) //IL_00ab: Unknown result type (might be due to invalid IL or missing references) //IL_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_00c0: Unknown result type (might be due to invalid IL or missing references) //IL_00e9: Unknown result type (might be due to invalid IL or missing references) //IL_00ed: Unknown result type (might be due to invalid IL or missing references) 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 (!ZNet.instance.IsServer() || !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 && !((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 sealed class JuvenileFollowRpcHandler : MonoBehaviour { private const string ToggleFollowRpc = "op_toggle_follow"; private ZNetView nview; private bool registered; private void Awake() { nview = ((Component)this).GetComponent<ZNetView>(); } private void Start() { TryRegister(); } private void TryRegister() { if (!registered && !((Object)(object)nview == (Object)null) && nview.IsValid()) { nview.Register<ZDOID, bool>("op_toggle_follow", (Action<long, ZDOID, bool>)RPC_ToggleFollow); registered = true; } } public void RequestToggle(Player player, bool showMessage) { //IL_003f: Unknown result type (might be due to invalid IL or missing references) TryRegister(); if (!((Object)(object)nview == (Object)null) && nview.IsValid() && !((Object)(object)player == (Object)null)) { nview.InvokeRPC("op_toggle_follow", new object[2] { ((Character)player).GetZDOID(), showMessage }); } } private void RPC_ToggleFollow(long sender, ZDOID playerId, bool showMessage) { //IL_0023: Unknown result type (might be due to invalid IL or missing references) if (ZNet.instance.IsServer()) { Character component = ((Component)this).GetComponent<Character>(); object obj = Player.GetPlayer(sender); if (obj == null) { GameObject obj2 = ZNetScene.instance.FindInstance(playerId); obj = ((obj2 != null) ? obj2.GetComponent<Player>() : null); } Player val = (Player)obj; if (!((Object)(object)component == (Object)null) && !((Object)(object)val == (Object)null)) { JuvenileFollow.ApplyAnimalFollowToggle(component, val, showMessage); } } } 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<JuvenileFollowRpcHandler>() == (Object)null) { ((Component)character).gameObject.AddComponent<JuvenileFollowRpcHandler>(); } } } 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 readonly int InteractMask = LayerMask.GetMask(new string[10] { "item", "piece", "piece_nonsolid", "Default", "static_solid", "Default_small", "character", "character_net", "terrain", "vehicle" }); 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_0022: 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_003d: Unknown result type (might be due to invalid IL or missing references) //IL_0042: Unknown result type (might be due to invalid IL or missing references) //IL_0043: Unknown result type (might be due to invalid IL or missing references) //IL_0089: Unknown result type (might be due to invalid IL or missing references) //IL_008e: Unknown result type (might be due to invalid IL or missing references) //IL_0146: Unknown result type (might be due to invalid IL or missing references) //IL_0149: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)player == (Object)null || (Object)(object)GameCamera.instance == (Object)null) { return null; } Vector3 position = ((Component)GameCamera.instance).transform.position; Vector3 forward = ((Component)GameCamera.instance).transform.forward; Vector3 position2 = ((Character)player).m_eye.position; RaycastHit[] source = Physics.RaycastAll(position, forward, 50f, InteractMask); Character result = 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 || ((Object)(object)((RaycastHit)(ref current)).collider.attachedRigidbody != (Object)null && (Object)(object)((Component)((RaycastHit)(ref current)).collider.attachedRigidbody).gameObject == (Object)(object)((Component)player).gameObject)) { continue; } Character val = (((Object)(object)((RaycastHit)(ref current)).collider.attachedRigidbody != (Object)null) ? ((Component)((RaycastHit)(ref current)).collider.attachedRigidbody).GetComponent<Character>() : ((Component)((RaycastHit)(ref current)).collider).GetComponentInParent<Character>()); if (!((Object)(object)val == (Object)null) && !val.IsPlayer() && val.IsTamed() && (!juvenilesOnly || SpeciesHelper.IsEligibleJuvenile(val)) && (juvenilesOnly || !((Object)(object)((Component)val).GetComponent<Tameable>() == (Object)null))) { float num2 = Vector3.Distance(position2, ((RaycastHit)(ref current)).point); if (num2 <= num) { result = val; num = num2; } } } return result; } } 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 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(TeleportWorld portal) { //IL_0024: 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) { 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(TeleportWorld portal, Character character, Dictionary<int, float> cooldowns, ref float lastNoDestinationMessageTime) { //IL_0136: 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; } if (!ZNet.instance.IsServer()) { 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; } SpeciesType juvenileSpecies = SpeciesHelper.GetJuvenileSpecies(character); if (!DestinationRegistry.TryResolveMaturingDestination(juvenileSpecies, out var destination)) { if (time - lastNoDestinationMessageTime > 5f) { lastNoDestinationMessageTime = time; OffspringPortalPlugin.Log.LogWarning((object)("No maturing portal registered for " + SpeciesCatalog.GetDisplayName(juvenileSpecies) + ".")); Player localPlayer = Player.m_localPlayer; if ((Object)(object)localPlayer != (Object)null) { ((Character)localPlayer).Message((MessageType)2, "No maturing portal registered for " + SpeciesCatalog.GetDisplayName(juvenileSpecies) + ".", 0, (Sprite)null); } } return false; } if (!JuvenileTeleporter.TryTeleport(character, destination, portal)) { OffspringPortalPlugin.Log.LogWarning((object)("Failed to teleport " + SpeciesCatalog.GetDisplayName(juvenileSpecies) + " juvenile.")); return false; } OffspringPortalPlugin.Log.LogInfo((object)$"Teleported {SpeciesCatalog.GetDisplayName(juvenileSpecies)} juvenile to maturing portal at {destination.Position}."); cooldowns[instanceID] = time + ModConfig.TeleportCooldownSec.Value; PlayPortalActivation(portal); return true; } private static void PlayPortalActivation(TeleportWorld portal) { //IL_001b: Unknown result type (might be due to invalid IL or missing references) //IL_0026: Unknown result type (might be due to invalid IL or missing references) if (portal?.m_connected != null) { portal.m_connected.Create(((Component)portal).transform.position, ((Component)portal).transform.rotation, ((Component)portal).transform, 1f, -1); } } } public static class JuvenileTeleporter { public static bool TryTeleport(Character juvenile, PortalRecord destination, TeleportWorld sourcePortal) { //IL_002a: Unknown result type (might be due to invalid IL or missing references) //IL_0030: Unknown result type (might be due to invalid IL or missing references) //IL_0035: Unknown result type (might be due to invalid IL or missing references) //IL_0048: Unknown result type (might be due to invalid IL or missing references) //IL_007a: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)juvenile == (Object)null || destination == null || (Object)(object)sourcePortal == (Object)null || !ZNet.instance.IsServer()) { return false; } DestinationRegistry.RefreshPortalPosition(destination); Vector3 exitPosition = PortalPlacement.GetExitPosition(destination.Id, sourcePortal); if ((Object)(object)ZNetScene.instance != (Object)null && ZNetScene.instance.IsAreaReady(exitPosition)) { return TryTeleportNow(juvenile, destination, sourcePortal); } if (TryTeleportNow(juvenile, destination, sourcePortal, allowStoredHeight: true)) { OffspringPortalPlugin.Log.LogInfo((object)$"Cross-zone teleport of {SpeciesCatalog.GetDisplayName(SpeciesHelper.GetJuvenileSpecies(juvenile))} to {exitPosition}."); return true; } OffspringPortalPlugin.Log.LogInfo((object)("Deferring teleport of " + SpeciesCatalog.GetDisplayName(SpeciesHelper.GetJuvenileSpecies(juvenile)) + " until pen zone loads.")); return OffspringPortalRuntime.Instance.TryQueueDistantTeleport(juvenile, destination, sourcePortal); } public static bool TryTeleportNow(Character juvenile, PortalRecord destination, TeleportWorld sourcePortal, bool allowStoredHeight = false) { //IL_0067: Unknown result type (might be due to invalid IL or missing references) //IL_006d: 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_0074: Unknown result type (might be due to invalid IL or missing references) //IL_007a: Unknown result type (might be due to invalid IL or missing references) //IL_007f: Unknown result type (might be due to invalid IL or missing references) //IL_0081: 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) if ((Object)(object)juvenile == (Object)null || destination == null || (Object)(object)sourcePortal == (Object)null) { return false; } if (!ZNet.instance.IsServer()) { return false; } ZNetView nview = juvenile.GetNview(); if ((Object)(object)nview == (Object)null || !nview.IsValid()) { return false; } nview.ClaimOwnership(); 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); } return false; } JuvenileGroundSnapper.EnsureAttached(juvenile); JuvenileFollowController.EnsureAttached(juvenile); JuvenileFollowRpcHandler.EnsureAttached(juvenile); ZDO zDO = nview.GetZDO(); if (zDO != null) { zDO.Set("op_transported", true); } return true; } public static Vector3 ResolveDestinationPosition(PortalRecord destination, TeleportWorld 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, TeleportWorld 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 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 references) //IL_0021: Unknown result type (might be due to invalid IL or missing references) //IL_0026: Unknown result type (might be due to invalid IL or missing references) //IL_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_0051: Unknown result type (might be due to invalid IL or missing references) //IL_005c: Unknown result type (might be due to invalid IL or missing references) //IL_005d: Unknown result type (might be due to invalid IL or missing references) Vector3 val = rotation * Vector3.right; for (int i = 0; i < 5; i++) { if (JuvenilePlacement.TryGetFloorPosition(destination + val * Random.Range(-0.2f, 0.2f), out var grounded)) { JuvenilePlacement.ApplyPosition(character, grounded, rotation); JuvenileGroundSnapper.EnsureAttached(character); return true; } } if (!allowStoredHeight) { return false; } if (JuvenilePlacement.TryGetFloorPosition(destination, out var grounded2)) { JuvenilePlacement.ApplyPosition(character, grounded2, rotation); return true; } return false; } } public static class ModConfig { public static ConfigEntry<float> TeleportCooldownSec; public static ConfigEntry<float> BreederScanRange; public static ConfigEntry<float> BreederScanIntervalSec; public static ConfigEntry<float> DistantTeleportTimeoutSec; public static ConfigEntry<bool> AllowRetransport; public static ConfigEntry<bool> EnableFollowCommand; public static ConfigEntry<bool> EnableCapWarning; public static ConfigEntry<float> MaturingAdultScanIntervalSec; public static void Bind(ConfigFile config) { TeleportCooldownSec = config.Bind<float>("General", "TeleportCooldownSec", 2f, "Seconds between successive teleports at the same source portal."); BreederScanRange = config.Bind<float>("General", "BreederScanRange", 10f, "Breeder portals automatically teleport tamed juveniles within this radius (meters)."); BreederScanIntervalSec = config.Bind<float>("General", "BreederScanIntervalSec", 0.5f, "How often breeder portals scan for nearby juveniles."); DistantTeleportTimeoutSec = config.Bind<float>("General", "DistantTeleportTimeoutSec", 15f, "How long to wait for a distant pen zone to load before giving up."); AllowRetransport = config.Bind<bool>("General", "AllowRetransport", false, "If true, a juvenile can use the portal more than once."); EnableFollowCommand = config.Bind<bool>("General", "EnableFollowCommand", true, "Press E on tamed juveniles to toggle follow/stay (Boar, Wolf, Lox, Hen, Asksvin)."); EnableCapWarning = config.Bind<bool>("General", "EnableCapWarning", true, "Show warning when a maturing portal is within species cap radius of a breeder portal."); MaturingAdultScanIntervalSec = config.Bind<float>("General", "MaturingAdultScanIntervalSec", 30f, "How often maturing portals scan for nearby adults to forward to cull pens."); } } public class OffspringPortalMarker : MonoBehaviour { private TeleportWorld teleportWorld; private void Awake() { teleportWorld = ((Component)this).GetComponent<TeleportWorld>(); } private void Start() { if ((Object)(object)teleportWorld != (Object)null && !((Behaviour)teleportWorld).enabled) { ((MonoBehaviour)this).StartCoroutine(InitializeTeleportWorldWhenReady()); } } private IEnumerator InitializeTeleportWorldWhenReady() { ZNetView nview = ((Component)this).GetComponent<ZNetView>(); for (int i = 0; i < 30; i++) { if ((Object)(object)nview != (Object)null && nview.GetZDO() != null) { break; } yield return null; } if (!((Object)(object)teleportWorld == (Object)null) && !((Object)(object)nview == (Object)null) && nview.GetZDO() != null && !((Behaviour)teleportWorld).enabled) { OffspringPortalInitializer.CompleteTeleportWorldAwake(teleportWorld, nview); } } } internal static class OffspringPortalInitializer { internal static void CompleteTeleportWorldAwake(TeleportWorld portal, ZNetView nview) { if (!((Behaviour)portal).enabled) { Traverse.Create((object)portal).Field<ZNetView>("m_nview").Value = nview; Traverse.Create((object)portal).Field<bool>("m_hadTarget").Value = (bool)AccessTools.Method(typeof(TeleportWorld), "HaveTarget", (Type[])null, (Type[])null).Invoke(portal, null); nview.Register<string, string>("RPC_SetTag", (Action<long, string, string>)delegate(long sender, string tag, string target) { AccessTools.Method(typeof(TeleportWorld), "RPC_SetTag", (Type[])null, (Type[])null).Invoke(portal, new object[3] { sender, tag, target }); }); nview.Register<ZDOID>("RPC_SetConnected", (Action<long, ZDOID>)delegate(long sender, ZDOID targetId) { //IL_002d: Unknown result type (might be due to invalid IL or missing references) AccessTools.Method(typeof(TeleportWorld), "RPC_SetConnected", (Type[])null, (Type[])null).Invoke(portal, new object[2] { sender, targetId }); }); ((Behaviour)portal).enabled = true; ((MonoBehaviour)portal).InvokeRepeating("UpdatePortal", 0.5f, 0.5f); } } } public static class OffspringPortalPrefabs { private static bool pieceRegistered; public static GameObject Prefab { get; private set; } public static bool Registered { get; private set; } public static void Initialize() { PrefabManager.OnVanillaPrefabsAvailable += RegisterPrefab; PieceManager.OnPiecesRegistered += RegisterPiece; PrefabManager.OnPrefabsRegistered += RegisterPiece; } public static void EnsurePieceRegistered() { RegisterPiece(); } private static void RegisterPrefab() { if (!Registered) { GameObject val = PrefabManager.Instance.CreateClonedPrefab("offspring_portal", "portal_wood"); if ((Object)(object)val == (Object)null) { OffspringPortalPlugin.Log.LogError((object)"Failed to clone portal_wood via Jotunn."); return; } ConfigureClone(val); EnsureRuntimeTriggers(val.GetComponent<TeleportWorld>()); PrefabManager.Instance.AddPrefab(val); Prefab = val; Registered = true; PrefabManager.OnVanillaPrefabsAvailable -= RegisterPrefab; OffspringPortalPlugin.Log.LogInfo((object)"Registered offspring_portal prefab."); RegisterPiece(); } } private static void RegisterPiece() { if (pieceRegistered || !Registered || (Object)(object)Prefab == (Object)null) { return; } try { ApplyRecipe(Prefab); PieceManager.Instance.RegisterPieceInPieceTable(Prefab, "Hammer", (string)null); pieceRegistered = true; PieceManager.OnPiecesRegistered -= RegisterPiece; OffspringPortalPlugin.Log.LogInfo((object)"Registered offspring_portal in Hammer piece table."); } catch (Exception ex) { OffspringPortalPlugin.Log.LogWarning((object)("Deferring offspring_portal piece registration: " + ex.Message)); } } private static void ApplyRecipe(GameObject clone) { Piece component = clone.GetComponent<Piece>(); if (!((Object)(object)component == (Object)null) && !((Object)(object)ObjectDB.instance == (Object)null)) { component.m_resources = (Requirement[])(object)new Requirement[3] { CreateRequirement("FineWood", 20), CreateRequirement("GreydwarfEye", 10), CreateRequirement("SurtlingCore", 2) }; } } private static void ConfigureClone(GameObject clone) { //IL_0006: 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) clone.transform.localScale = Vector3.one * 0.5f; TeleportWorld component = clone.GetComponent<TeleportWorld>(); if ((Object)(object)component != (Object)null) { component.m_exitDistance = 1f; } EnsureRuntimeTriggers(component); if ((Object)(object)clone.GetComponent<OffspringPortalMarker>() == (Object)null) { clone.AddComponent<OffspringPortalMarker>(); } Piece component2 = clone.GetComponent<Piece>(); if ((Object)(object)component2 != (Object)null) { component2.m_name = "$piece_offspring_portal"; component2.m_description = "$piece_offspring_portal_description"; } } public static void EnsureRuntimeTriggers(TeleportWorld teleportWorld) { if ((Object)(object)teleportWorld == (Object)null) { return; } TeleportWorldTrigger[] componentsInChildren = ((Component)teleportWorld).GetComponentsInChildren<TeleportWorldTrigger>(true); foreach (TeleportWorldTrigger obj in componentsInChildren) { GameObject gameObject = ((Component)obj).gameObject; ((Behaviour)obj).enabled = false; if ((Object)(object)gameObject.GetComponent<OffspringPortalTrigger>() == (Object)null) { gameObject.AddComponent<OffspringPortalTrigger>(); } } if ((Object)(object)teleportWorld.m_proximityRoot == (Object)null) { return; } Collider[] componentsInChildren2 = ((Component)teleportWorld.m_proximityRoot).GetComponentsInChildren<Collider>(true); foreach (Collider val in componentsInChildren2) { if (val.isTrigger && !((Object)(object)((Component)val).GetComponent<OffspringPortalTrigger>() != (Object)null)) { ((Component)val).gameObject.AddComponent<OffspringPortalTrigger>(); } } if ((Object)(object)((Component)teleportWorld).GetComponent<OffspringPortalScanner>() == (Object)null) { ((Component)teleportWorld).gameObject.AddComponent<OffspringPortalScanner>(); } } private static Requirement CreateRequirement(string itemName, int amount) { //IL_0013: Unknown result type (might be due to invalid IL or missing references) //IL_0018: Unknown result type (might be due to invalid IL or missing references) //IL_0030: Unknown result type (might be due to invalid IL or missing references) //IL_0037: 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_0046: Expected O, but got Unknown ObjectDB instance = ObjectDB.instance; GameObject val = ((instance != null) ? instance.GetItemPrefab(itemName) : null); return new Requirement { m_resItem = (((Object)(object)val != (Object)null) ? val.GetComponent<ItemDrop>() : null), m_amount = amount, m_amountPerLevel = 0, m_recover = true }; } public static bool IsOffspringPortal(TeleportWorld portal) { if ((Object)(object)portal == (Object)null) { return false; } if ((Object)(object)((Component)portal).GetComponent<OffspringPortalMarker>() != (Object)null) { return true; } if (IsOffspringPiece(((Component)portal).gameObject)) { return true; } ZNetView component = ((Component)portal).GetComponent<ZNetView>(); if ((Object)(object)component == (Object)null || component.GetZDO() == null) { return false; } ZDO zDO = component.GetZDO(); if (zDO.GetPrefab() == StringExtensionMethods.GetStableHashCode("offspring_portal")) { return true; } return !string.IsNullOrEmpty(zDO.GetString("op_portal_role", string.Empty)); } public static bool IsOffspringPortal(GameObject gameObject) { if ((Object)(object)gameObject == (Object)null) { return false; } if ((Object)(object)gameObject.GetComponent<OffspringPortalMarker>() != (Object)null) { return true; } if (IsOffspringPiece(gameObject)) { return true; } return IsOffspringPortal(gameObject.GetComponent<TeleportWorld>()); } public static void EnsureIdentity(TeleportWorld portal) { if (!((Object)(object)portal == (Object)null) && IsOffspringPiece(((Component)portal).gameObject) && (Object)(object)((Component)portal).GetComponent<OffspringPortalMarker>() == (Object)null) { ((Component)portal).gameObject.AddComponent<OffspringPortalMarker>(); } } private static bool IsOffspringPiece(GameObject gameObject) { Piece component = gameObject.GetComponent<Piece>(); if ((Object)(object)component != (Object)null) { return component.m_name == "$piece_offspring_portal"; } return false; } } public sealed class OffspringPortalRuntime : MonoBehaviour { private static OffspringPortalRuntime instance; private readonly HashSet<ZDOID> pendingTeleports = new HashSet<ZDOID>(); public static OffspringPortalRuntime Instance { get { //IL_0012: Unknown result type (might be due to invalid IL or missing references) //IL_0017: Unknown result type (might be due to invalid IL or missing references) //IL_001d: Expected O, but got Unknown if ((Object)(object)instance == (Object)null) { GameObject val = new GameObject("OffspringPortal_Runtime"); Object.DontDestroyOnLoad((Object)val); instance = val.AddComponent<OffspringPortalRuntime>(); } return instance; } } public bool TryQueueDistantTeleport(Character juvenile, PortalRecord destination, TeleportWorld sourcePortal) { //IL_0026: Unknown result type (might be due to invalid IL or missing references) //IL_002b: Unknown result type (might be due to invalid IL or missing references) //IL_0032: Unknown result type (might be due to invalid IL or missing references) //IL_0042: Unknown result type (might be due to invalid IL or missing references) //IL_004e: Unknown result type (might be due to invalid IL or missing references) ZNetView val = juvenile?.GetNview(); if ((Object)(object)val == (Object)null || !val.IsValid()) { return false; } ZDOID uid = val.GetZDO().m_uid; if (pendingTeleports.Contains(uid)) { return false; } pendingTeleports.Add(uid); ((MonoBehaviour)this).StartCoroutine(DeferredTeleport(juvenile, destination, sourcePortal, uid)); return true; } private IEnumerator DeferredTeleport(Character juvenile, PortalRecord destination, TeleportWorld sourcePortal, ZDOID juvenileId) { //IL_0023: 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) float timeout = ModConfig.DistantTeleportTimeoutSec.Value; float elapsed = 0f; Vector3 targetPos = JuvenileTeleporter.ResolveDestinationPosition(destination, sourcePortal); while (elapsed < timeout) { if ((Object)(object)juvenile == (Object)null) { pendingTeleports.Remove(juvenileId); yield break; } if ((Object)(object)ZNetScene.instance != (Object)null && ZNetScene.instance.IsAreaReady(targetPos) && JuvenileTeleporter.TryTeleportNow(juvenile, destination, sourcePortal)) { pendingTeleports.Remove(juvenileId); yield break; } elapsed += 0.25f; yield return (object)new WaitForSeconds(0.25f); } if ((Object)(object)juvenile != (Object)null && JuvenileTeleporter.TryTeleportNow(juvenile, destination, sourcePortal, allowStoredHeight: true)) { pendingTeleports.Remove(juvenileId); yield break; } pendingTeleports.Remove(juvenileId); Player localPlayer = Player.m_localPlayer; if ((Object)(object)localPlayer != (Object)null) { ((Character)localPlayer).Message((MessageType)2, "Could not reach distant pen for " + SpeciesCatalog.GetDisplayName(SpeciesHelper.GetJuvenileSpecies(juvenile)) + ".", 0, (Sprite)null); } } } public class OffspringPortalScanner : MonoBehaviour { private TeleportWorld portal; private readonly Dictionary<int, float> juvenileCooldowns = new Dictionary<int, float>(); private readonly Dictionary<int, float> adultCooldowns = new Dictionary<int, float>(); private float lastNoJuvenileDestinationMessageTime; private float lastNoAdultDestinationMessageTime; private void Start() { portal = ((Component)this).GetComponent<TeleportWorld>(); float value = ModConfig.BreederScanIntervalSec.Value; ((MonoBehaviour)this).InvokeRepeating("ScanForJuveniles", value, value); float value2 = ModConfig.MaturingAdultScanIntervalSec.Value; ((MonoBehaviour)this).InvokeRepeating("ScanForAdults", value2, value2); } private void ScanForJuveniles() { if (ZNet.instance.IsServer() && !((Object)(object)portal == (Object)null) && OffspringPortalPrefabs.IsOffspringPortal(portal) && JuvenilePortalRouter.IsBreederPortal(portal)) { ScanNearbyCharacters((Character character, Dictionary<int, float> cooldowns) => JuvenilePortalRouter.TryRoute(portal, character, cooldowns, ref lastNoJuvenileDestinationMessageTime), juvenileCooldowns); } } private void ScanForAdults() { if (ZNet.instance.IsServer() && !((Object)(object)portal == (Object)null) && OffspringPortalPrefabs.IsOffspringPortal(portal) && AdultPortalRouter.IsAdultRoutingMaturingPortal(portal)) { ScanNearbyCharacters((Character character, Dictionary<int, float> cooldowns) => AdultPortalRouter.TryRoute(portal, character, cooldowns, ref lastNoAdultDestinationMessageTime), adultCooldowns); } } private void ScanNearbyCharacters(Func<Character, Dictionary<int, float>, bool> tryRoute, Dictionary<int, float> cooldowns) { //IL_0030: Unknown result type (might be due to invalid IL or missing references) //IL_001e: Unknown result type (might be due to invalid IL or missing references) //IL_0035: Unknown result type (might be due to invalid IL or missing references) //IL_006f: Unknown result type (might be due to invalid IL or missing references) //IL_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_007a: Unknown result type (might be due to invalid IL or missing references) Vector3 val = (((Object)(object)portal.m_proximityRoot != (Object)null) ? portal.m_proximityRoot.position : ((Component)portal).transform.position); float value = ModConfig.BreederScanRange.Value; float num = value * value; foreach (Character allCharacter in Character.GetAllCharacters()) { if (!((Object)(object)allCharacter == (Object)null) && !allCharacter.IsPlayer()) { Vector3 val2 = ((Component)allCharacter).transform.position - val; if (!(((Vector3)(ref val2)).sqrMagnitude > num)) { tryRoute(allCharacter, cooldowns); } } } } } public class OffspringPortalTrigger : MonoBehaviour { private TeleportWorld portal; private readonly Dictionary<int, float> cooldowns = new Dictionary<int, float>(); private float lastNoDestinationMessageTime; private void Awake() { portal = ((Component)this).GetComponentInParent<TeleportWorld>(); } private void OnTriggerEnter(Collider other) { if ((Object)(object)portal == (Object)null || !OffspringPortalPrefabs.IsOffspringPortal(portal)) { return; } Character character = GetCharacter(other); Player val = (Player)(object)((character is Player) ? character : null); if (val != null) { if ((Object)(object)val == (Object)(object)Player.m_localPlayer) { ((Character)val).Message((MessageType)2, "Offspring portals route juveniles only. Use a standard portal to travel.", 0, (Sprite)null); } } else { TryRouteJuvenile(other); } } private void OnTriggerStay(Collider other) { if (!(GetCharacter(other) is Player)) { TryRouteJuvenile(other); } } private void TryRouteJuvenile(Collider other) { if (!((Object)(object)portal == (Object)null) && OffspringPortalPrefabs.IsOffspringPortal(portal)) { Character character = GetCharacter(other); if (!((Object)(object)character == (Object)null)) { JuvenilePortalRouter.TryRoute(portal, character, cooldowns, ref lastNoDestinationMessageTime); } } } private static Character GetCharacter(Collider other) { Character component = ((Component)other).GetComponent<Character>(); if ((Object)(object)component != (Object)null) { return component; } if ((Object)(object)other.attachedRigidbody != (Object)null) { component = ((Component)other.attachedRigidbody).GetComponent<Character>(); if ((Object)(object)component != (Object)null) { return component; } } return ((Component)other).GetComponentInParent<Character>(); } } [BepInPlugin("offspringportal.mod", "Offspring Portal", "0.2.9")] [BepInDependency(/*Could not decode attribute arguments.*/)] public sealed class OffspringPortalPlugin : BaseUnityPlugin { public const string PluginGuid = "offspringportal.mod"; public const string PluginName = "Offspring Portal"; public const string PluginVersion = "0.2.9"; internal static ManualLogSource Log; private Harmony harmony; private void Awake() { //IL_0027: Unknown result type (might be due to invalid IL or missing references) //IL_0031: Expected O, but got Unknown Log = ((BaseUnityPlugin)this).Logger; ModConfig.Bind(((BaseUnityPlugin)this).Config); OffspringPortalPrefabs.Initialize(); _ = OffspringPortalRuntime.Instance; harmony = new Harmony("offspringportal.mod"); harmony.PatchAll(typeof(OffspringPortalPlugin).Assembly); XPortalCompat.TryApply(harmony); Log.LogInfo((object)"Offspring Portal 0.2.9 loaded."); } private void OnDestroy() { Harmony obj = harmony; if (obj != null) { obj.UnpatchSelf(); } } } public static class PortalDisplayHelper { public const string UnnamedDisplay = "(No Name)"; public const int MaxNameLength = 32; public static string SanitizeName(string name) { if (string.IsNullOrWhiteSpace(name)) { return string.Empty; } name = name.Trim(); if (name.Length > 32) { return name.Substring(0, 32); } return name; } public static string GetDisplayName(ZDO zdo) { if (zdo == null) { return "(No Name)"; } string text = SanitizeName(zdo.GetString("op_portal_name", string.Empty)); if (!string.IsNullOrEmpty(text)) { return text; } return "(No Name)"; } public static string GetDetailLine(PortalRole role, SpeciesType species, AdultDestination adultDestination) { switch (role) { case PortalRole.Maturing: { string text = "Receives: " + SpeciesCatalog.GetDisplayName(species) + " juveniles"; if (adultDestination != AdultDestination.None) { text = text + "\nDestination: " + PortalRoleCatalog.GetDisplayName(adultDestination); } return text; } case PortalRole.Farm: return "Receives: " + SpeciesCatalog.GetDisplayName(species) + " adults"; case PortalRole.Cull: return "Role: Cull yard"; default: return "Role: Breeder"; } } public static string GetHoverText(ZDO zdo, PortalRole role, SpeciesType species, AdultDestination adultDestination, bool capWarning) { string displayName = GetDisplayName(zdo); string detailLine = GetDetailLine(role, species, adultDestination); string text = BuildWarnings(role, species, adultDestination, capWarning); return Localization.instance.Localize("Name: " + displayName + "\n" + detailLine + text + "\n[<color=yellow><b>$KEY_Use</b></color>] Configure"); } private static string BuildWarnings(PortalRole role, SpeciesType species, AdultDestination adultDestination, bool capWarning) { string text = string.Empty; if (capWarning) { text += "\n<color=yellow>Warning: maturing pen is within breeding cap radius of a breeder portal.</color>"; } if (role == PortalRole.Maturing && adultDestination != AdultDestination.None && ((adultDestination == AdultDestination.Cull) ? (!DestinationRegistry.HasCullReceiver()) : (!DestinationRegistry.HasFarmReceiver(species)))) { string displayName = PortalRoleCatalog.GetDisplayName(adultDestination); text = text + "\n<color=yellow>Warning: No " + displayName + " portal exists. Adults will not be teleported.</color>"; } return text; } } public static class PortalHelper { public static bool TryGetPortal(TeleportWorld portal, out ZDOID id, out Vector3 position, out SpeciesType species) { //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_000c: Unknown result type (might be due to invalid IL or missing references) //IL_0011: Unknown result type (might be due to invalid IL or missing references) //IL_0046: Unknown result type (might be due to invalid IL or missing references) //IL_004b: Unknown result type (might be due to invalid IL or missing references) //IL_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) id = ZDOID.None; position = Vector3.zero; species = SpeciesType.None; if ((Object)(object)portal == (Object)null || !OffspringPortalPrefabs.IsOffspringPortal(portal)) { return false; } ZNetView component = ((Component)portal).GetComponent<ZNetView>(); ZDO val = ((component != null) ? component.GetZDO() : null); if (val == null) { return false; } id = val.m_uid; position = val.GetPosition(); species = SpeciesCatalog.FromStorageValue(val.GetString("op_declared_species", string.Empty)); return true; } public static void SyncRegistryFromPortal(TeleportWorld portal) { ZNetView obj = ((portal != null) ? ((Component)portal).GetComponent<ZNetView>() : null); ZDO val = ((obj != null) ? obj.GetZDO() : null); if (val != null && OffspringPortalPrefabs.IsOffspringPortal(portal)) { SyncRegistryFromZdo(val); PortalTravelGuard.ClearTravelBindings(val); DestinationRegistry.RefreshCapWarnings(); } } public static void SyncRegistryFromZdo(ZDO zdo) { //IL_003b: 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) if (zdo != null && zdo.GetPrefab() == StringExtensionMethods.GetStableHashCode("offspring_portal")) { PortalRole role = PortalRoleCatalog.FromZdo(zdo); SpeciesType declaredSpecies = SpeciesCatalog.FromStorageValue(zdo.GetString("op_declared_species", string.Empty)); AdultDestination adultDestination = PortalRoleCatalog.GetAdultDestination(zdo); DestinationRegistry.RegisterOrUpdate(zdo.m_uid, zdo.GetPosition(), role, declaredSpecies, adultDestination); } } public static void RebuildRegistryFromWorld() { DestinationRegistry.Clear(); RebuildRegistryFromLoadedPortals(); RebuildRegistryFromAllPortalZdos(); DestinationRegistry.RefreshCapWarnings(); LogRegistryState("rebuilt"); } private static void LogRegistryState(string reason) { int num = 0; int num2 = 0; int num3 = 0; int num4 = 0; using (IEnumerator<PortalRecord> enumerator = DestinationRegistry.GetAll().GetEnumerator()) { while (enumerator.MoveNext()) { switch (enumerator.Current.Role) { case PortalRole.Maturing: num2++; break; case PortalRole.Farm: num3++; break; case PortalRole.Cull: num4++; break; default: num++; break; } } } OffspringPortalPlugin.Log.LogInfo((object)$"Portal registry {reason}: {num} breeder(s), {num2} maturing, {num3} farm, {num4} cull."); } private static void RebuildRegistryFromLoadedPortals() { if ((Object)(object)ZNetScene.instance == (Object)null) { return; } TeleportWorld[] array = Object.FindObjectsByType<TeleportWorld>((FindObjectsSortMode)0); foreach (TeleportWorld portal in array) { if (OffspringPortalPrefabs.IsOffspringPortal(portal)) { SyncRegistryFromPortal(portal); } } } private static void RebuildRegistryFromAllPortalZdos() { if (ZDOMan.instance == null) { return; } List<ZDO> list = new List<ZDO>(); int num = 0; while (!ZDOMan.instance.GetAllZDOsWithPrefabIterative("offspring_portal", list, ref num)) { } foreach (ZDO item in list) { SyncRegistryFromZdo(item); } } } public static class PortalPlacement { public const float PortalScale = 0.5f; public const float ScaledExitDistance = 1f; public static Vector3 GetExitPosition(ZDOID portalId, TeleportWorld fallbackPortal = null) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0005: 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_001e: 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_002e: Unknown result type (might be due to invalid IL or missing references) //IL_0030: Unknown result type (might be due to invalid IL or missing references) //IL_0035: Unknown result type (might be due to invalid IL or missing references) //IL_0047: Unknown result type (might be due to invalid IL or missing references) //IL_004c: Unknown result type (might be due to invalid IL or missing references) //IL_0053: Unknown result type (might be due to invalid IL or missing references) //IL_0058: Unknown result type (might be due to invalid IL or missing references) //IL_006c: 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_00b7: Unknown result type (might be due to invalid IL or missing references) //IL_00b8: 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_009b: Unknown result type (might be due to invalid IL or missing references) //IL_00a0: Unknown result type (might be due to invalid IL or missing references) //IL_00a8: 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) Vector3 val = Vector3.zero; Quaternion val2 = Quaternion.identity; float num = 1f; ZDOMan instance = ZDOMan.instance; ZDO val3 = ((instance != null) ? instance.GetZDO(portalId) : null); if (val3 != null) { val = val3.GetPosition(); val2 = val3.GetRotation(); } else if ((Object)(object)fallbackPortal != (Object)null) { val = ((Component)fallbackPortal).transform.position; val2 = ((Component)fallbackPortal).transform.rotation; num = fallbackPortal.m_exitDistance; } ZNetScene instance2 = ZNetScene.instance; GameObject val4 = ((instance2 != null) ? instance2.FindInstance(portalId) : null); TeleportWorld val5 = (((Object)(object)val4 != (Object)null) ? val4.GetComponent<TeleportWorld>() : null); if ((Object)(object)val5 != (Object)null) { val = ((Component)val5).transform.position; val2 = ((Component)val5).transform.rotation; num = val5.m_exitDistance; } return val + val2 * Vector3.forward * num; } public static Quaternion GetExitRotation(ZDOID portalId, TeleportWorld fallbackPortal = null) { //IL_000c: Unknown result type (might be due to invalid IL or missing references) //IL_0017: Unknown result type (might be due to invalid IL or missing references) //IL_0029: 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_006d: 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) ZDOMan instance = ZDOMan.instance; ZDO val = ((instance != null) ? instance.GetZDO(portalId) : null); if (val != null) { return val.GetRotation(); } ZNetScene instance2 = ZNetScene.instance; GameObject val2 = ((instance2 != null) ? instance2.FindInstance(portalId) : null); TeleportWorld val3 = (((Object)(object)val2 != (Object)null) ? val2.GetComponent<TeleportWorld>() : null); if ((Object)(object)val3 != (Object)null) { return ((Component)val3).transform.rotation; } if (!((Object)(object)fallbackPortal != (Object)null)) { return Quaternion.identity; } return ((Component)fallbackPortal).transform.rotation; } } public enum PortalRole { Breeder, Maturing, Farm, Cull } public enum AdultDestination { None, Farm, Cull } public static class PortalRoleCatalog { public static PortalRole FromZdo(ZDO zdo) { if (zdo == null) { return PortalRole.Breeder; } string value = zdo.GetString("op_portal_role", string.Empty); if (!string.IsNullOrWhiteSpace(value) && Enum.TryParse<PortalRole>(value, ignoreCase: true, out var result)) { return result; } if (SpeciesCatalog.FromStorageValue(zdo.GetString("op_declared_species", string.Empty)) != SpeciesType.None) { return PortalRole.Maturing; } return PortalRole.Breeder; } public static AdultDestination GetAdultDestination(ZDO zdo) { if (zdo == null) { return AdultDestination.None; } string value = zdo.GetString("op_adult_destination", string.Empty); if (!string.IsNullOrWhiteSpace(value) && Enum.TryParse<AdultDestination>(value, ignoreCase: true, out var result)) { return result; } if (!zdo.GetBool("op_forward_adults", false)) { return AdultDestination.None; } return AdultDestination.Cull; } public static string ToStorageValue(PortalRole role) { return role.ToString(); } public static string ToStorageValue(AdultDestination destination) { return destination.ToString(); } public static string GetDisplayName(PortalRole role) { return role switch { PortalRole.Maturing => "Maturing", PortalRole.Farm => "Farm", PortalRole.Cull => "Cull", _ => "Breeder", }; } public static string GetDisplayName(AdultDestination destination) { return destination.ToString(); } public static SpeciesType ResolveSpecies(PortalRole role, SpeciesType selectedSpecies) { if (role != PortalRole.Breeder && role != PortalRole.Cull) { return selectedSpecies; } return SpeciesType.None; } public static AdultDestination ResolveAdultDestination(PortalRole role, AdultDestination selectedDestination) { if (role != PortalRole.Maturing) { return AdultDestination.None; } return selectedDestination; } public static string GetConfiguredMessage(PortalRole role, SpeciesType species, AdultDestination adultDestination) { switch (role) { case PortalRole.Maturing: { string text = "Maturing (receives " + SpeciesCatalog.GetDisplayName(species) + ")"; if (adultDestination != AdultDestination.None) { return text + ", destination " + GetDisplayName(adultDestination); } return text; } case PortalRole.Farm: return "Farm (receives " + SpeciesCatalog.GetDisplayName(species) + " adults)"; case PortalRole.Cull: return "Cull yard"; default: return "Breeder"; } } } public static class PortalRpc { private const string RpcSetConfig = "OffspringPortal_SetConfigV3"; public static void Register() { ZRoutedRpc.instance.Register<ZDOID, string, string, string, string>("OffspringPortal_SetConfigV3", (Method<ZDOID, string, string, string, string>)OnSetConfigRpc); } public static void SetPortalConfig(ZDOID portalId, PortalRole role, SpeciesType species, string name, AdultDestination adultDestination) { //IL_0039: 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) string text = PortalDisplayHelper.SanitizeName(name); AdultDestination adultDestination2 = PortalRoleCatalog.ResolveAdultDestination(role, adultDestination); if (ZNet.instance.IsServer()) { ApplyPortalConfig(portalId, role, species, text, adultDestination2); return; } ZRoutedRpc.instance.InvokeRoutedRPC("OffspringPortal_SetConfigV3", new object[5] { portalId, PortalRoleCatalog.ToStorageValue(role), SpeciesCatalog.ToStorageValue(species), text, PortalRoleCatalog.ToStorageValue(adultDestination2) }); } private static void OnSetConfigRpc(long sender, ZDOID portalId, string roleValue, string speciesValue, string name, string adultDestinationValue) { //IL_002e: Unknown result type (might be due to invalid IL or missing references) if (ZNet.instance.IsServer()) { PortalRole result; PortalRole role = (Enum.TryParse<PortalRole>(roleValue, ignoreCase: true, out result) ? result : PortalRole.Breeder); AdultDestination result2; AdultDestination adultDestination = (Enum.TryParse<AdultDestination>(adultDestinationValue, ignoreCase: true, out result2) ? result2 : AdultDestination.None); ApplyPortalConfig(portalId, role, SpeciesCatalog.FromStorageValue(speciesValue), PortalDisplayHelper.SanitizeName(name), adultDestination); } } private static void ApplyPortalConfig(ZDOID portalId, PortalRole role, SpeciesType species, string name, AdultDestination adultDestination) { //IL_0005: 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_0077: Unknown result type (might be due to invalid IL or missing references) //IL_0089: Unknown result type (might be due to invalid IL or missing references) ZDO zDO = ZDOMan.instance.GetZDO(portalId); if (zDO != null) { SpeciesType speciesType = PortalRoleCatalog.ResolveSpecies(role, species); AdultDestination adultDestination2 = PortalRoleCatalog.ResolveAdultDestination(role, adultDestination); zDO.Set("op_portal_role", PortalRoleCatalog.ToStorageValue(role)); zDO.Set("op_declared_species", SpeciesCatalog.ToStorageValue(speciesType)); zDO.Set("op_portal_name", name); zDO.Set("op_adult_destination", PortalRoleCatalog.ToStorageValue(adultDestination2)); zDO.Set("op_forward_adults", adultDestination2 == AdultDestination.Cull); PortalTravelGuard.ClearTravelBindings(zDO); DestinationRegistry.RegisterOrUpdate(portalId, zDO.GetPosition(), role, speciesType, adultDestination2); DestinationRegistry.RefreshCapWarnings(); if ((Object)(object)FindPortal(portalId) != (Object)null && (Object)(object)Player.m_localPlayer != (Object)null) { string text = (string.IsNullOrEmpty(name) ? "(No Name)" : name); string configuredMessage = PortalRoleCatalog.GetConfiguredMessage(role, speciesType, adultDestination2); ((Character)Player.m_localPlayer).Message((MessageType)1, "Portal \"" + text + "\" configured as " + configuredMessage + ".", 0, (Sprite)null); } } } private static TeleportWorld FindPortal(ZDOID portalId) { //IL_0005: Unknown result type (might be due to invalid IL or missing references) ZDO zDO = ZDOMan.instance.GetZDO(portalId); if (zDO == null) { return null; } ZNetView val = ZNetScene.instance.FindInstance(zDO); if (!((Object)(object)val != (Object)null)) { return null; } return ((Component)val).GetComponent<TeleportWorld>(); } } public static class PortalTravelGuard { public const string PlayerTravelBlockedMessage = "Offspring portals route juveniles only. Use a standard portal to travel."; private const string XPortalTargetField = "XPortal_TargetId"; private const string XPortalPreviousField = "XPortal_PreviousId"; public static bool IsOffspringPortalZdo(ZDO zdo) { if (zdo == null) { return false; } if (zdo.GetPrefab() == StringExtensionMethods.GetStableHashCode("offspring_portal")) { return true; } return !string.IsNullOrEmpty(zdo.GetString("op_portal_role", string.Empty)); } public static bool TryGetConnectedPortal(TeleportWorld portal, out TeleportWorld connected) { //IL_0028: Unknown result type (might be due to invalid IL or missing references) //IL_002d: Unknown result type (might be due to invalid IL or missing references) //IL_002e: Unknown result type (might be due to invalid IL or missing references) //IL_002f: Unknown result type (might be due to invalid IL or missing references) //IL_0049: Unknown result type (might be due to invalid IL or missing references) connected = null; if ((Object)(object)portal == (Object)null) { return false; } ZNetView component = ((Component)portal).GetComponent<ZNetView>(); ZDO val = ((component != null) ? component.GetZDO() : null); if (val == null) { return false; } ZDOID connectionZDOID = val.GetConnectionZDOID((ConnectionType)1); if (connectionZDOID == ZDOID.None) { return false; } ZNetScene instance = ZNetScene.instance; GameObject val2 = ((instance != null) ? instance.FindInstance(connectionZDOID) : null); connected = (((Object)(object)val2 != (Object)null) ? val2.GetComponent<TeleportWorld>() : null); return (Object)(object)connected != (Object)null; } public static bool BlocksPlayerTravel(TeleportWorld source, Player player, out string message) { message = null; if ((Object)(object)source == (Object)null || (Object)(object)player == (Object)null) { return false; } if (OffspringPortalPrefabs.IsOffspringPortal(source)) { message = "Offspring portals route juveniles only. Use a standard portal to travel."; return true; } if (TryGetConnectedPortal(source, out var connected) && OffspringPortalPrefabs.IsOffspringPortal(connected)) { message = "Offspring portals route juveniles only. Use a standard portal to travel."; return true; } return false; } public static void ClearTravelBindings(ZDO zdo) { //IL_0006: 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_0026: Unknown result type (might be due to invalid IL or missing references) if (zdo != null) { zdo.UpdateConnection((ConnectionType)1, ZDOID.None); zdo.Set("XPortal_TargetId", ZDOID.None); zdo.Set("XPortal_PreviousId", ZDOID.None); } } public static void ClearTravelBindings(TeleportWorld portal) { if (!((Object)(object)portal == (Object)null) && ZNet.instance.IsServer()) { ZNetView component = ((Component)portal).GetComponent<ZNetView>(); ZDO val = ((component != null) ? component.GetZDO() : null); if (val != null && component.IsOwner()) { ClearTravelBindings(val); } } } public static void ClearAllOffspringTravelBindings() { if (!ZNet.instance.IsServer()) { return; } TeleportWorld[] array = Object.FindObjectsByType<TeleportWorld>((FindObjectsSortMode)0); foreach (TeleportWorld portal in array) { if (OffspringPortalPrefabs.IsOffspringPortal(portal)) { ClearTravelBindings(portal); } } } } public static class SpeciesHelper { private static readonly Dictionary<string, SpeciesType> AdultPrefabMap = new Dictionary<string, SpeciesType>(StringComparer.OrdinalIgnoreCase) { { "Boar", SpeciesType.Boar }, { "Wolf", SpeciesType.Wolf }, { "WolfCub", SpeciesType.Wolf }, { "Lox", SpeciesType.Lox }, { "Hen", SpeciesType.Chicken }, { "Chicken", SpeciesType.Chicken }, { "Asksvin", SpeciesType.Asksvin } }; public static bool IsEligibleJuvenile(Character character) { if ((Object)(object)character == (Object)null || !character.IsTamed()) { return false; } if ((Object)(object)((Component)character).GetComponent<Growup>() != (Object)null) { return true; } return (((Object)character).name ?? string.Empty).IndexOf("wolfcub", StringComparison.OrdinalIgnoreCase) >= 0; } public static bool IsEligibleAdult(Character character) { if ((Object)(object)character != (Object)null && character.IsTamed() && (Object)(object)((Component)character).GetComponent<Growup>() == (Object)null) { return GetAdultSpecies(character) != SpeciesType.None; } return false; } public static SpeciesType GetAdultSpecies(Character character) { return MapAdultPrefab((character != null) ? ((Object)character).name : null); } public static SpeciesType GetJuvenileSpecies(Character character) { Growup component = ((Component)character).GetComponent<Growup>(); if ((Object)(object)component == (Object)null) { return SpeciesType.None; } if ((Object)(object)component.m_grownPrefab != (Object)null) { SpeciesType speciesType = MapAdultPrefab(((Object)component.m_grownPrefab).name); if (speciesType != SpeciesType.None) { return speciesType; } } if (component.m_altGrownPrefabs != null) { foreach (GrownEntry altGrownPrefab in component.m_altGrownPrefabs) { if (!((Object)(object)altGrownPrefab?.m_prefab == (Object)null)) { SpeciesType speciesType2 = MapAdultPrefab(((Object)altGrownPrefab.m_prefab).name); if (speciesType2 != SpeciesType.None) { return speciesType2; } } } } return MapAdultPrefab(((Object)character).name); } public static bool SpeciesMatches(SpeciesType juvenile, SpeciesType destination) { return destination switch { SpeciesType.None => false, SpeciesType.All => true, _ => juvenile == destination, }; } private static SpeciesType MapAdultPrefab(string prefabName) { if (string.IsNullOrWhiteSpace(prefabName)) { return SpeciesType.None; } foreach (KeyValuePair<string, SpeciesType> item in AdultPrefabMap) { if (prefabName.IndexOf(item.Key, StringComparison.OrdinalIgnoreCase) >= 0) { return item.Value; } } return SpeciesType.None; } } public enum SpeciesType { None, All, Boar, Wolf, Lox, Chicken, Asksvin } public static class SpeciesCatalog { public static readonly IReadOnlyList<SpeciesType> DestinationOptions = new SpeciesType[6] { SpeciesType.Boar, SpeciesType.Wolf, SpeciesType.Lox, SpeciesType.Chicken, SpeciesType.Asksvin, SpeciesType.All }; public static string ToStorageValue(SpeciesType species) { if (species != SpeciesType.None) { return species.ToString(); } return string.Empty; } public static SpeciesType FromStorageValue(string value) { if (string.IsNullOrWhiteSpace(value)) { return SpeciesType.None; } if (!Enum.TryParse<SpeciesType>(value, ignoreCase: true, out var result)) { return SpeciesType.None; } return result; } public static string GetDisplayName(SpeciesType species) { return species switch { SpeciesType.All => "All", SpeciesType.Boar => "Boar", SpeciesType.Wolf => "Wolf", SpeciesType.Lox => "Lox", SpeciesType.Chicken => "Hen", SpeciesType.Asksvin => "Asksvin", _ => "Breeder", }; } } internal static class ValheimExtensions { public static ZNetView GetNview(this Character character) { if (!((Object)(object)character != (Object)null)) { return null; } return ((Component)character).GetComponent<ZNetView>(); } public static ZDO GetZdo(this Character character) { ZNetView nview = character.GetNview(); if (!((Object)(object)nview != (Object)null)) { return null; } return nview.GetZDO(); } } internal static class XPortalCompat { public static void TryApply(Harmony harmony) { Type type = AccessTools.TypeByName("XPortal.XPortal"); if (!(type == null)) { Patch(harmony, type, "OnPrePortalHover", "OnPrePortalHoverPrefix"); Patch(harmony, type, "OnPortalPlaced", "OnPortalPlacedPrefix"); Patch(harmony, type, "OnPortalRequestText", "OnPortalRequestTextPrefix"); OffspringPortalPlugin.Log.LogInfo((object)"XPortal compatibility enabled: offspring portals excluded from travel network."); } } private static void Patch(Harmony harmony, Type targetType, string methodName, string handlerName) { //IL_0033: Unknown result type (might be due to invalid IL or missing references) //IL_0041: Expected O, but got Unknown MethodInfo methodInfo = AccessTools.Method(targetType, methodName, (Type[])null, (Type[])null); MethodInfo methodInfo2 = AccessTools.Method(typeof(XPortalCompat), handlerName, (Type[])null, (Type[])null); if (!(methodInfo == null) && !(methodInfo2 == null)) { harmony.Patch((MethodBase)methodInfo, new HarmonyMethod(methodInfo2), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null); } } private static bool ShouldBlock(ZDOID portalId) { //IL_000c: Unknown result type (might be due to invalid IL or missing references) ZDOMan instance = ZDOMan.instance; return PortalTravelGuard.IsOffspringPortalZdo((instance != null) ? instance.GetZDO(portalId) : null); } private static bool OnPrePortalHoverPrefix(ZDOID portalId) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) return !ShouldBlock(portalId); } private static bool OnPortalPlacedPrefix(ZDOID portalId) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_000a: Unknown result type (might be due to invalid IL or missing references) if (!ShouldBlock(portalId)) { return true; } PortalTravelGuard.ClearTravelBindings(FindPortal(portalId)); return false; } private static bool OnPortalRequestTextPrefix(ZDOID portalId) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) return !ShouldBlock(portalId); } private static TeleportWorld FindPortal(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<TeleportWorld>(); } } public static class ZdoFields { public const string DeclaredSpecies = "op_declared_species"; public const string PortalName = "op_portal_name"; public const string PortalRole = "op_portal_role"; public const string ForwardAdults = "op_forward_adults"; public const string AdultDestination = "op_adult_destination"; public const string Transported = "op_transported"; public const string FollowTarget = "op_follow_target"; public const string CapWarning = "op_cap_warning"; } public static class PrefabNames { public const string OffspringPortal = "offspring_portal"; public const string VanillaPortalWood = "portal_wood"; } } namespace OffspringPortal.UI { public sealed class SpeciesConfigPanel { private static SpeciesConfigPanel instance; private const float Padding = 24f; private const float LabelWidth = 160f; private const float InputWidth = 460f; private const float RowHeight = 32f; private const float ButtonWidth = 110f; private const float ButtonHeight = 48f; private const float FirstColumnLeft = 24f; private const float SecondColumnLeft = 208f; private const float NameRowTop = -84f; private const float TypeRowTop = -140f; private const float ReceivesRowTop = -196f; private const float DestinationRowTop = -252f; private const float ButtonRowHeight = 72f; private GameObject mainPanel; private GameObject receivesLabelObject; private GameObject destinationLabelObject; private InputField nameInputField; private Dropdown typeDropdown; private Dropdown speciesDropdown; private Dropdown destinationDropdown; private readonly Dictionary<int, PortalRole> indexToRole = new Dictionary<int, PortalRole>(); private readonly Dictionary<int, SpeciesType> indexToSpecies = new Dictionary<int, SpeciesType>(); private readonly Dictionary<int, AdultDestination> indexToDestination = new Dictionary<int, AdultDestination>(); private ZDOID portalId; private SpeciesType savedSpecies = SpeciesType.Boar; private AdultDestination savedDestination; private bool initialized; public static SpeciesConfigPanel Instance => instance ?? (instance = new SpeciesConfigPanel()); public void Open(ZDOID id, PortalRole currentRole, SpeciesType currentSpecies, string currentName, AdultDestination adultDestination) { //IL_0016: Unknown result type (might be due to invalid IL or missing references) //IL_0017: Unknown result type (might be due to invalid IL or missing references) EnsureInitialized(); if (!((Object)(object)mainPanel == (Object)null)) { portalId = id; savedSpecies = ((currentSpecies == SpeciesType.None) ? SpeciesType.Boar : currentSpecies); savedDestination = adultDestination; nameInputField.text = currentName ?? string.Empty; PopulateTypeDropdown(currentRole); PopulateSpeciesDropdown(savedSpecies); PopulateDestinationDropdown(savedDestination); UpdatePanelState(); mainPanel.SetActive(true); GUIManager.BlockInput(true); } } public void Close() { if ((Object)(object)mainPanel != (Object)null) { mainPanel.SetActive(false); } GUIManager.BlockInput(false); } private void EnsureInitialized() { //IL_005b: 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_0079: Unknown result type (might be due to invalid IL or missing references) //IL_00e5: Unknown result type (might be due to invalid IL or missing references) //IL_00f4: Unknown result type (might be due to invalid IL or missing references) //IL_0103: Unknown result type (might be due to invalid IL or missing references) //IL_0119: Unknown result type (might be due to invalid IL or missing references) //IL_011f: Unknown result type (might be due to invalid IL or missing references) //IL_014f: 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) //IL_0194: Unknown result type (might be due to invalid IL or missing references) //IL_01a3: Unknown result type (might be due to invalid IL or missing references) //IL_01d0: Unknown result type (might be due to invalid IL or missing references) //IL_021f: Unknown result type (might be due to invalid IL or missing references) //IL_022e: Unknown result type (might be due to invalid IL or missing references) //IL_023d: Unknown result type (might be due to invalid IL or missing references) //IL_0266: Unknown result type (might be due to invalid IL or missing references) //IL_02d4: Unknown result type (might be due to invalid IL or missing references) //IL_02e3: Unknown result type (might be due to invalid IL or missing references) //IL_02f2: Unknown result type (might be due to invalid IL or missing references) //IL_031b: Unknown result type (might be due to invalid IL or missing references) //IL_0389: Unknown result type (might be due to invalid IL or missing references) //IL_0398: Unknown result type (might be due to invalid IL or missing references) //IL_03a7: Unknown result type (might be due to invalid IL or missing references) //IL_03d0: Unknown result type (might be due to invalid IL or missing references) //IL_0437: Unknown result type (might be due to invalid IL or missing references) //IL_0446: Unknown result type (might be due to invalid IL or missing references) //IL_0455: Unknown result type (might be due to invalid IL or missing references) //IL_0479: Unknown result type (might be due to invalid IL or missing references) //IL_0494: Unknown result type (might be due to invalid IL or missing references) //IL_049e: Expected O, but got Unknown //IL_04c7: Unknown result type (might be due to invalid IL or missing references) //IL_04d6: Unknown result type (might be due to invalid IL or missing references) //IL_04e5: Unknown result type (might be due to invalid IL or missing references) //IL_0509: Unknown result type (might be due to invalid IL or missing references) //IL_0524: Unknown result type (might be due to invalid IL or missing references) //IL_052e: Expected O, but got Unknown if (initialized) { return; } GameObject val = GameObject.Find("_GameMain/LoadingGUI/CustomGUIFront"); if ((Object)(object)val == (Object)null) { OffspringPortalPlugin.Log.LogError((object)"Could not find Valheim custom GUI root."); return; } float num = 692f; float num2 = 308f + 72f + 24f; mainPanel = GUIManager.Instance.CreateWoodpanel(val.transform, new Vector2(0.5f, 0.5f), new Vector2(0.5f, 0.5f), new Vector2(0f, 0f), num, num2, false); ((Object)mainPanel).name = "OffspringPortal_ConfigPanel"; mainPanel.AddComponent<CanvasGroup>(); if ((Object)(object)mainPanel.GetComponentInParent<Localize>() == (Object)null) { mainPanel.AddComponent<Localize>(); } GameObject obj = GUIManager.Instance.CreateText("Configure Portal", mainPanel.transform, new Vector2(0f, 1f), new Vector2(1f, 1f), new Vector2(20f, -15f), GUIManager.Instance.AveriaSerifBold, 32, GUIManager.Instance.ValheimOrange, true, Color.black, 250f, 50f, false); obj.GetComponent<Text>().alignment = (TextAnchor)1; obj.GetComponent<RectTransform>().pivot = new Vector2(0.5f, 1f); CreateLabel("Name", -84f, out var labelObject); GameObject val2 = GUIManager.Instance.CreateInputField(mainPanel.transform, new Vector2(0f, 1f), new Vector2(1f, 1f), new Vector2(208f, -84f), (ContentType)0, "e.g. Boar Farm", 18, 460f, 32f); val2.GetComponent<RectTransform>().pivot = new Vector2(0f, 1f); nameInputField = val2.GetComponent<InputField>(); nameInputField.characterLimit = 32; CreateLabel("Type", -140f, out labelObject); GameObject val3 = GUIManager.Instance.CreateDropDown(mainPanel.transform, new Vector2(0f, 1f), new Vector2(1f, 1f), new Vector2(208f, -140f), 18, 460f, 32f); val3.GetComponent<RectTransform>().pivot = new Vector2(0f, 1f); typeDropdown = val3.GetComponent<Dropdown>(); ((UnityEvent<int>)(object)typeDropdown.onValueChanged).AddListener((UnityAction<int>)OnTypeChanged); ApplyDropdownStyle(typeDropdown); CreateLabel("Receives", -196f, out receivesLabelObject); GameObject val4 = GUIManager.Instance.CreateDropDown(mainPanel.transform, new Vector2(0f, 1f), new Vector2(1f, 1f), new Vector2(208f, -196f), 18, 460f, 32f); val4.GetComponent<RectTransform>().pivot = new Vector2(0f, 1f); speciesDropdown = val4.GetComponent<Dropdown>();