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 ImprovedTames v0.1.3
ImprovedTames.dll
Decompiled 4 days agousing System; using System.Collections; using System.Collections.Generic; using System.Diagnostics; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using BepInEx; using BepInEx.Bootstrap; using BepInEx.Configuration; using BepInEx.Logging; using HarmonyLib; using ImprovedTames.Logic; using Jotunn.Utils; using Microsoft.CodeAnalysis; using UnityEngine; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: TargetFramework(".NETFramework,Version=v4.8", FrameworkDisplayName = ".NET Framework 4.8")] [assembly: AssemblyVersion("0.0.0.0")] [module: RefSafetyRules(11)] namespace Microsoft.CodeAnalysis { [CompilerGenerated] [Embedded] internal sealed class EmbeddedAttribute : Attribute { } } namespace System.Runtime.CompilerServices { [CompilerGenerated] [Embedded] [AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)] internal sealed class RefSafetyRulesAttribute : Attribute { public readonly int Version; public RefSafetyRulesAttribute(int P_0) { Version = P_0; } } } namespace ImprovedTames { internal static class ImprovedTamesConfig { public static ConfigEntry<bool> Enabled; public static ConfigEntry<float> MaxDistance; public static ConfigEntry<float> ArrivalRadius; public static ConfigEntry<bool> DebugLogging; public static void Bind(ConfigFile config) { Enabled = config.Bind<bool>("1 - Portal teleport", "Enabled", true, AdminOnly("Tames following you go through portals with you.")); MaxDistance = config.Bind<float>("1 - Portal teleport", "MaxDistance", 50f, AdminOnly("How far from the portal (metres) a following tame can be and still come along.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(5f, 128f))); ArrivalRadius = config.Bind<float>("1 - Portal teleport", "ArrivalRadius", 4f, AdminOnly("How far from you (metres) tames appear after the teleport.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(1f, 15f))); DebugLogging = config.Bind<bool>("9 - Debug", "DebugLogging", false, "Log every tame moved through a portal (local only)."); } private static ConfigDescription AdminOnly(string description, AcceptableValueBase range = null) { //IL_000a: Unknown result type (might be due to invalid IL or missing references) //IL_000f: Unknown result type (might be due to invalid IL or missing references) //IL_0017: Expected O, but got Unknown //IL_0017: Unknown result type (might be due to invalid IL or missing references) //IL_001d: Expected O, but got Unknown return new ConfigDescription(description, range, new object[1] { (object)new ConfigurationManagerAttributes { IsAdminOnly = true } }); } } [BepInPlugin("com.robert.improvedtames", "ImprovedTames", "0.1.3")] [BepInDependency(/*Could not decode attribute arguments.*/)] [BepInDependency(/*Could not decode attribute arguments.*/)] [NetworkCompatibility(/*Could not decode attribute arguments.*/)] public class ImprovedTamesPlugin : BaseUnityPlugin { internal static ManualLogSource Log; internal static TameTeleporter Teleporter; 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; ImprovedTamesConfig.Bind(((BaseUnityPlugin)this).Config); Teleporter = new TameTeleporter((MonoBehaviour)(object)this); _harmony = new Harmony("com.robert.improvedtames"); _harmony.PatchAll(typeof(ImprovedTamesPlugin).Assembly); } private void OnDestroy() { Harmony harmony = _harmony; if (harmony != null) { harmony.UnpatchSelf(); } } } [HarmonyPatch] internal static class PotalMapTeleportPatch { public const string PotalMapGuid = "com.korcaptain.potalmap"; private static MethodBase Target() { return AccessTools.Method("PortalMap.PortalTeleporter:TryTeleport", (Type[])null, (Type[])null); } private static bool Prepare() { if (!Chainloader.PluginInfos.ContainsKey("com.korcaptain.potalmap")) { return false; } if (Target() == null) { ImprovedTamesPlugin.Log.LogWarning((object)"PotalMap's TryTeleport was not found, so tames won't follow its teleports."); return false; } return true; } private static MethodBase TargetMethod() { return Target(); } private static void Prefix(out bool __state) { Player localPlayer = Player.m_localPlayer; __state = (Object)(object)localPlayer != (Object)null && ((Character)localPlayer).IsTeleporting(); } private static void Postfix(bool __state) { Player localPlayer = Player.m_localPlayer; if (!__state && (Object)(object)localPlayer != (Object)null && ((Character)localPlayer).IsTeleporting()) { ImprovedTamesPlugin.Teleporter.OnPortalEntered(localPlayer); } } } internal sealed class TameTeleporter { private const float ArrivalTimeout = 40f; private const int PlaceAttempts = 3; private const float RetryDelay = 2f; private const float ArrivedDistance = 15f; private const float MaxFloorDifference = 3f; private const float SpawnLift = 0.5f; private readonly MonoBehaviour _host; private Coroutine _running; public TameTeleporter(MonoBehaviour host) { _host = host; } public void OnPortalEntered(Player player) { if (!ImprovedTamesConfig.Enabled.Value) { return; } List<ZDOID> list = ClaimFollowers(player); if (list.Count != 0) { if (_running != null) { _host.StopCoroutine(_running); } _running = _host.StartCoroutine(BringAfterArrival(player, list)); } } private static List<ZDOID> ClaimFollowers(Player player) { //IL_00b7: Unknown result type (might be due to invalid IL or missing references) //IL_00c2: Unknown result type (might be due to invalid IL or missing references) //IL_00d9: Unknown result type (might be due to invalid IL or missing references) List<ZDOID> list = new List<ZDOID>(); string playerName = player.GetPlayerName(); float value = ImprovedTamesConfig.MaxDistance.Value; foreach (Character allCharacter in Character.GetAllCharacters()) { if (allCharacter.IsPlayer() || !allCharacter.IsTamed()) { continue; } Tameable component = ((Component)allCharacter).GetComponent<Tameable>(); if (!((Object)(object)component == (Object)null) && !(component.m_unsummonDistance > 0f) && !component.HaveRider()) { ZNetView component2 = ((Component)allCharacter).GetComponent<ZNetView>(); if (!((Object)(object)component2 == (Object)null) && component2.IsValid() && FollowerRules.IsFollowing(component2.GetZDO().GetString(ZDOVars.s_follow, ""), playerName) && !(Vector3.Distance(((Component)allCharacter).transform.position, ((Component)player).transform.position) > value)) { component2.ClaimOwnership(); list.Add(allCharacter.GetZDOID()); } } } return list; } private static IEnumerator BringAfterArrival(Player player, List<ZDOID> followers) { float waited = 0f; while ((Object)(object)player != (Object)null && ((Character)player).IsTeleporting() && waited < 40f) { waited += Time.deltaTime; yield return null; } if ((Object)(object)player == (Object)null || (Object)(object)player != (Object)(object)Player.m_localPlayer || ((Character)player).IsTeleporting() || ((Character)player).IsDead()) { yield break; } for (int attempt = 0; attempt < 3; attempt++) { if (!((Object)(object)player != (Object)null)) { break; } if (PlaceAll(player, followers) == 0) { break; } yield return (object)new WaitForSeconds(2f); } } private static int PlaceAll(Player player, List<ZDOID> followers) { //IL_0017: Unknown result type (might be due to invalid IL or missing references) //IL_0044: Unknown result type (might be due to invalid IL or missing references) //IL_004f: Unknown result type (might be due to invalid IL or missing references) //IL_0069: 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) //IL_0088: Unknown result type (might be due to invalid IL or missing references) //IL_0096: Unknown result type (might be due to invalid IL or missing references) //IL_00b3: Unknown result type (might be due to invalid IL or missing references) //IL_00d6: Unknown result type (might be due to invalid IL or missing references) //IL_00e0: Unknown result type (might be due to invalid IL or missing references) string playerName = player.GetPlayerName(); int num = 0; for (int i = 0; i < followers.Count; i++) { ZDO zDO = ZDOMan.instance.GetZDO(followers[i]); if (zDO != null && FollowerRules.IsFollowing(zDO.GetString(ZDOVars.s_follow, ""), playerName) && !(Vector3.Distance(zDO.GetPosition(), ((Component)player).transform.position) <= 15f)) { Vector3 val = ArrivalSpot(((Component)player).transform.position, i, followers.Count); zDO.SetOwner(ZDOMan.GetSessionID()); zDO.SetPosition(val); GameObject val2 = ZNetScene.instance.FindInstance(followers[i]); if ((Object)(object)val2 != (Object)null) { val2.transform.position = val; } num++; if (ImprovedTamesConfig.DebugLogging.Value) { ImprovedTamesPlugin.Log.LogInfo((object)$"Moved tame {followers[i]} to {val} for {playerName}"); } } } return num; } private static Vector3 ArrivalSpot(Vector3 center, int index, int count) { //IL_0020: Unknown result type (might be due to invalid IL or missing references) //IL_0028: Unknown result type (might be due to invalid IL or missing references) //IL_002e: Unknown result type (might be due to invalid IL or missing references) //IL_0040: Unknown result type (might be due to invalid IL or missing references) //IL_006e: Unknown result type (might be due to invalid IL or missing references) //IL_006f: 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_007e: 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_006c: Unknown result type (might be due to invalid IL or missing references) var (num, num2) = FollowerRules.ArrivalOffset(index, count, ImprovedTamesConfig.ArrivalRadius.Value); Vector3 val = default(Vector3); ((Vector3)(ref val))..ctor(center.x + num, center.y, center.z + num2); float num3 = default(float); if (ZoneSystem.instance.FindFloor(val, ref num3) && Mathf.Abs(num3 - center.y) <= 3f) { val.y = num3 + 0.5f; return val; } return center + Vector3.up * 0.5f; } } [HarmonyPatch(typeof(TeleportWorld), "Teleport")] internal static class TeleportWorldPatch { private static void Prefix(Player player, out bool __state) { __state = (Object)(object)player != (Object)null && ((Character)player).IsTeleporting(); } private static void Postfix(Player player, bool __state) { if (!__state && (Object)(object)player != (Object)null && (Object)(object)player == (Object)(object)Player.m_localPlayer && ((Character)player).IsTeleporting()) { ImprovedTamesPlugin.Teleporter.OnPortalEntered(player); } } } internal static class ModInfo { public const string Guid = "com.robert.improvedtames"; public const string Name = "ImprovedTames"; public const string Version = "0.1.3"; } } namespace ImprovedTames.Logic { public static class FollowerRules { public static bool IsFollowing(string followName, string playerName) { if (!string.IsNullOrEmpty(followName)) { return string.Equals(followName, playerName, StringComparison.Ordinal); } return false; } public static (float X, float Z) ArrivalOffset(int index, int count, float radius) { double num = Math.PI * 2.0 * (double)index / (double)Math.Max(count, 1); return (X: (float)(Math.Cos(num) * (double)radius), Z: (float)(Math.Sin(num) * (double)radius)); } } }