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 DundrPortalGun v0.11.2
plugins\DundrPortalGun.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.Globalization; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; using System.Runtime.Versioning; using System.Text; using BepInEx; using BepInEx.Configuration; using BepInEx.Logging; using DundrPortalGun.Config; using DundrPortalGun.Controls; using DundrPortalGun.Items; using DundrPortalGun.Networking; using DundrPortalGun.Portals; using DundrPortalGun.Projectiles; using HarmonyLib; using Jotunn.Configs; using Jotunn.Entities; using Jotunn.Managers; using Jotunn.Utils; using Microsoft.CodeAnalysis; using UnityEngine; using UnityEngine.Rendering; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: AssemblyTitle("DundrPortalGun")] [assembly: AssemblyDescription("A multiplayer momentum-preserving Portal Gun mod for Valheim.")] [assembly: AssemblyConfiguration("")] [assembly: AssemblyCompany("")] [assembly: AssemblyProduct("DundrPortalGun")] [assembly: AssemblyCopyright("")] [assembly: AssemblyTrademark("")] [assembly: ComVisible(false)] [assembly: Guid("6d0ffaa9-48fb-4eb7-bf17-4d61e6da9daa")] [assembly: AssemblyFileVersion("0.11.2.0")] [assembly: TargetFramework(".NETFramework,Version=v4.6.2", FrameworkDisplayName = ".NET Framework 4.6.2")] [assembly: AssemblyVersion("0.11.2.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 DundrPortalGun { [BepInPlugin("samuel.valheim.dundrportalgun", "DundrPortalGun", "0.11.2")] [BepInDependency(/*Could not decode attribute arguments.*/)] [NetworkCompatibility(/*Could not decode attribute arguments.*/)] public sealed class Plugin : BaseUnityPlugin { public const string PluginGuid = "samuel.valheim.dundrportalgun"; public const string PluginName = "DundrPortalGun"; public const string PluginVersion = "0.11.2"; private static readonly string[] RequiredPrefabNames = new string[5] { "StaffLightning", "staff_lightning_projectile", "portal_wood", "portal", "fx_portal_connected" }; private static readonly string[] AttackFieldTerms = new string[12] { "attack", "projectile", "spawn", "animation", "stamina", "eitr", "accuracy", "burst", "charge", "draw", "recoil", "velocity" }; private static readonly string[] MovementFieldTerms = new string[11] { "body", "velocity", "move", "ground", "fall", "jump", "dodge", "teleport", "maxair", "lastground", "sliding" }; private ConfigEntry<bool> researchHarnessEnabled; private ConfigEntry<KeyboardShortcut> relocationShortcut; private ConfigEntry<float> relocationDistance; private ModConfig modConfig; private Harmony harmony; private bool playerMovementLogged; private Coroutine relocationRoutine; internal static ManualLogSource Log { get; private set; } internal static PortalManager Portals { get; private set; } internal static PortalNetwork Network { get; private set; } private void Awake() { //IL_0011: Unknown result type (might be due to invalid IL or missing references) //IL_001b: Expected O, but got Unknown //IL_00a7: Unknown result type (might be due to invalid IL or missing references) //IL_00ea: Unknown result type (might be due to invalid IL or missing references) //IL_00f4: Expected O, but got Unknown //IL_0163: Unknown result type (might be due to invalid IL or missing references) //IL_0168: Unknown result type (might be due to invalid IL or missing references) Log = ((BaseUnityPlugin)this).Logger; harmony = new Harmony("samuel.valheim.dundrportalgun"); harmony.PatchAll(typeof(Plugin).Assembly); modConfig = new ModConfig(((BaseUnityPlugin)this).Config); Portals = new PortalManager(modConfig); Network = new PortalNetwork(modConfig, Portals); researchHarnessEnabled = ((BaseUnityPlugin)this).Config.Bind<bool>("Research Harness", "Enabled", false, "Resolve and inspect the Dundr/portal prefabs and enable the explicit relocation test shortcut."); relocationShortcut = ((BaseUnityPlugin)this).Config.Bind<KeyboardShortcut>("Research Harness", "Direct Relocation Test", new KeyboardShortcut((KeyCode)291, Array.Empty<KeyCode>()), "In a safe open area, move the local player directly forward without calling Player.TeleportTo and log Rigidbody velocity over the following physics ticks. Extra held keys such as sprint do not block this test."); relocationDistance = ((BaseUnityPlugin)this).Config.Bind<float>("Research Harness", "Direct Relocation Distance", 5f, new ConfigDescription("Horizontal distance in metres used by the F10 direct-relocation test.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(1f, 15f), Array.Empty<object>())); PrefabManager.OnVanillaPrefabsAvailable += InspectRequiredPrefabs; PrefabManager.OnVanillaPrefabsAvailable += RegisterMilestoneOneContent; Log.LogInfo((object)"DundrPortalGun 0.11.2 loaded."); Log.LogInfo((object)("Runtime inspection is enabled=" + researchHarnessEnabled.Value + ". Direct relocation test=" + ((object)relocationShortcut.Value/*cast due to .constrained prefix*/).ToString() + ".")); } private void Update() { //IL_005c: Unknown result type (might be due to invalid IL or missing references) //IL_0061: Unknown result type (might be due to invalid IL or missing references) //IL_0064: Unknown result type (might be due to invalid IL or missing references) Player localPlayer = Player.m_localPlayer; if (Network != null) { Network.Tick(localPlayer); } PortalGunInput.Tick(localPlayer); Portals.Tick(localPlayer); if (researchHarnessEnabled.Value && !((Object)(object)localPlayer == (Object)null)) { if (!playerMovementLogged) { playerMovementLogged = true; InspectPlayerMovement(localPlayer); } KeyboardShortcut value = relocationShortcut.Value; if (Input.GetKeyDown(((KeyboardShortcut)(ref value)).MainKey)) { StartDirectRelocationTest(localPlayer); } } } private void FixedUpdate() { if (Portals != null) { Portals.FixedTick(Player.m_localPlayer); } } private void LateUpdate() { if (Portals != null) { Portals.LateTick(Player.m_localPlayer, Camera.main); } } private void OnDestroy() { PortalGunInput.Reset(); if (harmony != null) { harmony.UnpatchSelf(); harmony = null; } PrefabManager.OnVanillaPrefabsAvailable -= InspectRequiredPrefabs; PrefabManager.OnVanillaPrefabsAvailable -= RegisterMilestoneOneContent; if (Portals != null) { Portals.ClearAll("plugin shutdown"); Portals = null; } if (Network != null) { Network.Shutdown(); Network = null; } } private void RegisterMilestoneOneContent() { PrefabManager.OnVanillaPrefabsAvailable -= RegisterMilestoneOneContent; try { PortalProjectilePrefabs portalProjectilePrefabs = PortalProjectileFactory.Register(); PortalGunItem.Register(modConfig, portalProjectilePrefabs.Standard, portalProjectilePrefabs.Blue); Log.LogInfo((object)"Milestone 1 content registered successfully."); } catch (Exception ex) { Log.LogError((object)("Milestone 1 content registration failed: " + ex)); } } private void InspectRequiredPrefabs() { PrefabManager.OnVanillaPrefabsAvailable -= InspectRequiredPrefabs; if (!researchHarnessEnabled.Value) { Log.LogInfo((object)"Runtime prefab inspection skipped because the research harness is disabled."); return; } Log.LogInfo((object)"=== Dundr Portal Gun required prefab inspection ==="); Dictionary<string, GameObject> dictionary = new Dictionary<string, GameObject>(); string[] requiredPrefabNames = RequiredPrefabNames; foreach (string text in requiredPrefabNames) { GameObject val = (dictionary[text] = PrefabManager.Instance.GetPrefab(text)); if ((Object)(object)val == (Object)null) { Log.LogError((object)("Required prefab did not resolve: " + text)); continue; } Log.LogInfo((object)("Resolved prefab '" + text + "': instance=" + ((Object)val).GetInstanceID() + ", activeSelf=" + val.activeSelf + ".")); } if (dictionary.TryGetValue("StaffLightning", out var value) && (Object)(object)value != (Object)null) { InspectStaff(value); } DumpPrefabHierarchy("staff_lightning_projectile", dictionary); DumpPrefabHierarchy("portal_wood", dictionary); DumpPrefabHierarchy("portal", dictionary); DumpPrefabHierarchy("fx_portal_connected", dictionary); Log.LogInfo((object)"=== End required prefab inspection ==="); } private static void InspectStaff(GameObject staff) { Log.LogInfo((object)"--- StaffLightning item and attack inspection ---"); ItemDrop component = staff.GetComponent<ItemDrop>(); if ((Object)(object)component == (Object)null || component.m_itemData == null || component.m_itemData.m_shared == null) { Log.LogError((object)"StaffLightning has no readable ItemDrop shared data."); DumpHierarchy(staff); return; } SharedData shared = component.m_itemData.m_shared; Log.LogInfo((object)("Shared item name=" + shared.m_name + ", itemType=" + ((object)Unsafe.As<ItemType, ItemType>(ref shared.m_itemType)/*cast due to .constrained prefix*/).ToString() + ".")); LogFields("StaffLightning.SharedData", shared, AttackFieldTerms); LogFields("StaffLightning.PrimaryAttack", shared.m_attack, AttackFieldTerms); LogFields("StaffLightning.SecondaryAttack", shared.m_secondaryAttack, AttackFieldTerms); DumpHierarchy(staff); } private static void DumpPrefabHierarchy(string prefabName, IDictionary<string, GameObject> resolved) { if (resolved.TryGetValue(prefabName, out var value) && !((Object)(object)value == (Object)null)) { Log.LogInfo((object)("--- Hierarchy inspection: " + prefabName + " ---")); DumpHierarchy(value); } } private static void DumpHierarchy(GameObject root) { StringBuilder stringBuilder = new StringBuilder(); AppendTransform(stringBuilder, root.transform, ((Object)root.transform).name, 0); Log.LogInfo((object)stringBuilder.ToString()); } private static void AppendTransform(StringBuilder output, Transform transform, string path, int depth) { //IL_0040: Unknown result type (might be due to invalid IL or missing references) //IL_005e: Unknown result type (might be due to invalid IL or missing references) //IL_007c: Unknown result type (might be due to invalid IL or missing references) output.Append(' ', depth * 2); output.Append(path); output.Append(" [activeSelf="); output.Append(((Component)transform).gameObject.activeSelf); output.Append(", localPosition="); output.Append(FormatVector(transform.localPosition)); output.Append(", localRotation="); output.Append(FormatVector(transform.localEulerAngles)); output.Append(", localScale="); output.Append(FormatVector(transform.localScale)); output.Append(", components="); Component[] components = ((Component)transform).GetComponents<Component>(); for (int i = 0; i < components.Length; i++) { if (i > 0) { output.Append(','); } Component val = components[i]; output.Append(((Object)(object)val == (Object)null) ? "<missing>" : ((object)val).GetType().FullName); } output.AppendLine("]"); for (int j = 0; j < transform.childCount; j++) { Transform child = transform.GetChild(j); AppendTransform(output, child, path + "/" + ((Object)child).name, depth + 1); } } private static void InspectPlayerMovement(Player player) { //IL_00dc: Unknown result type (might be due to invalid IL or missing references) //IL_00e1: Unknown result type (might be due to invalid IL or missing references) //IL_00fd: Unknown result type (might be due to invalid IL or missing references) //IL_0102: Unknown result type (might be due to invalid IL or missing references) //IL_011f: Unknown result type (might be due to invalid IL or missing references) //IL_0124: Unknown result type (might be due to invalid IL or missing references) //IL_0141: Unknown result type (might be due to invalid IL or missing references) //IL_0159: Unknown result type (might be due to invalid IL or missing references) Log.LogInfo((object)"=== Local Player/Character movement inspection ==="); Rigidbody component = ((Component)player).GetComponent<Rigidbody>(); if ((Object)(object)component == (Object)null) { Log.LogError((object)"Local player has no Rigidbody component."); } else { Log.LogInfo((object)("Rigidbody: instance=" + ((Object)component).GetInstanceID() + ", isKinematic=" + component.isKinematic + ", useGravity=" + component.useGravity + ", mass=" + FormatFloat(component.mass) + ", linearDamping=" + FormatFloat(component.linearDamping) + ", angularDamping=" + FormatFloat(component.angularDamping) + ", interpolation=" + ((object)component.interpolation/*cast due to .constrained prefix*/).ToString() + ", collisionDetection=" + ((object)component.collisionDetectionMode/*cast due to .constrained prefix*/).ToString() + ", constraints=" + ((object)component.constraints/*cast due to .constrained prefix*/).ToString() + ", position=" + FormatVector(component.position) + ", velocity=" + FormatVector(component.linearVelocity) + ".")); } LogDeclaredFields("Player", player, typeof(Player), MovementFieldTerms); LogDeclaredFields("Character", player, typeof(Character), MovementFieldTerms); Log.LogInfo((object)"=== End Local Player/Character movement inspection ==="); } private void StartDirectRelocationTest(Player player) { //IL_003e: 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_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) //IL_0073: Unknown result type (might be due to invalid IL or missing references) //IL_0078: 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_007a: Unknown result type (might be due to invalid IL or missing references) //IL_0086: Unknown result type (might be due to invalid IL or missing references) //IL_008b: 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_00a8: Unknown result type (might be due to invalid IL or missing references) //IL_00b9: Unknown result type (might be due to invalid IL or missing references) //IL_00cb: Unknown result type (might be due to invalid IL or missing references) //IL_0107: Unknown result type (might be due to invalid IL or missing references) //IL_0114: Unknown result type (might be due to invalid IL or missing references) //IL_0121: Unknown result type (might be due to invalid IL or missing references) //IL_0149: Unknown result type (might be due to invalid IL or missing references) //IL_015f: Unknown result type (might be due to invalid IL or missing references) //IL_0175: Unknown result type (might be due to invalid IL or missing references) //IL_018b: Unknown result type (might be due to invalid IL or missing references) //IL_0190: Unknown result type (might be due to invalid IL or missing references) //IL_01c1: Unknown result type (might be due to invalid IL or missing references) //IL_01c3: Unknown result type (might be due to invalid IL or missing references) //IL_005e: Unknown result type (might be due to invalid IL or missing references) //IL_0063: Unknown result type (might be due to invalid IL or missing references) if (relocationRoutine != null) { Log.LogWarning((object)"Direct relocation test ignored because a prior test is still being measured."); return; } Rigidbody component = ((Component)player).GetComponent<Rigidbody>(); if ((Object)(object)component == (Object)null) { Log.LogError((object)"Direct relocation test failed: local player has no Rigidbody."); return; } Vector3 forward = ((Component)player).transform.forward; forward.y = 0f; if (((Vector3)(ref forward)).sqrMagnitude < 0.001f) { forward = Vector3.forward; } ((Vector3)(ref forward)).Normalize(); Vector3 position = component.position; Vector3 linearVelocity = component.linearVelocity; Vector3 val = position + forward * relocationDistance.Value; Log.LogInfo((object)("DIRECT_MOVE begin: position=" + FormatVector(position) + ", target=" + FormatVector(val) + ", velocity=" + FormatVector(linearVelocity) + ", speed=" + FormatFloat(((Vector3)(ref linearVelocity)).magnitude) + ". Player.TeleportTo will not be called.")); LogTeleportFields(player, "before"); component.position = val; ((Component)player).transform.position = val; Physics.SyncTransforms(); component.linearVelocity = linearVelocity; component.WakeUp(); ManualLogSource log = Log; string[] obj = new string[9] { "DIRECT_MOVE immediate: transform=", FormatVector(((Component)player).transform.position), ", body=", FormatVector(component.position), ", velocity=", FormatVector(component.linearVelocity), ", speed=", null, null }; Vector3 linearVelocity2 = component.linearVelocity; obj[7] = FormatFloat(((Vector3)(ref linearVelocity2)).magnitude); obj[8] = "."; log.LogInfo((object)string.Concat(obj)); LogTeleportFields(player, "immediate"); relocationRoutine = ((MonoBehaviour)this).StartCoroutine(MeasureRelocation(player, component, val, linearVelocity)); } private IEnumerator MeasureRelocation(Player player, Rigidbody body, Vector3 target, Vector3 velocityBefore) { //IL_001c: Unknown result type (might be due to invalid IL or missing references) //IL_001d: Unknown result type (might be due to invalid IL or missing references) //IL_0023: Unknown result type (might be due to invalid IL or missing references) //IL_0025: Unknown result type (might be due to invalid IL or missing references) yield return (object)new WaitForFixedUpdate(); LogRelocationSample("fixed+1", player, body, target, velocityBefore); yield return (object)new WaitForFixedUpdate(); LogRelocationSample("fixed+2", player, body, target, velocityBefore); relocationRoutine = null; Log.LogInfo((object)"DIRECT_MOVE measurement complete. Report whether any black/loading screen appeared."); } private static void LogRelocationSample(string stage, Player player, Rigidbody body, Vector3 target, Vector3 velocityBefore) { //IL_002e: 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_005c: 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_0088: Unknown result type (might be due to invalid IL or missing references) //IL_008d: Unknown result type (might be due to invalid IL or missing references) //IL_00a4: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)player == (Object)null || (Object)(object)body == (Object)null) { Log.LogWarning((object)("DIRECT_MOVE " + stage + ": player or Rigidbody was destroyed.")); return; } Vector3 linearVelocity = body.linearVelocity; Log.LogInfo((object)("DIRECT_MOVE " + stage + ": transform=" + FormatVector(((Component)player).transform.position) + ", body=" + FormatVector(body.position) + ", targetError=" + FormatFloat(Vector3.Distance(body.position, target)) + ", velocity=" + FormatVector(linearVelocity) + ", speed=" + FormatFloat(((Vector3)(ref linearVelocity)).magnitude) + ", speedDelta=" + FormatFloat(((Vector3)(ref linearVelocity)).magnitude - ((Vector3)(ref velocityBefore)).magnitude) + ".")); LogTeleportFields(player, stage); } private static void LogTeleportFields(Player player, string stage) { List<string> list = new List<string>(); Type type = typeof(Player); while (type != null && type != typeof(MonoBehaviour)) { FieldInfo[] fields = type.GetFields(BindingFlags.DeclaredOnly | BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); foreach (FieldInfo fieldInfo in fields) { if (fieldInfo.Name.IndexOf("teleport", StringComparison.OrdinalIgnoreCase) >= 0) { try { list.Add(type.Name + "." + fieldInfo.Name + "=" + FormatValue(fieldInfo.GetValue(player))); } catch (Exception ex) { list.Add(type.Name + "." + fieldInfo.Name + "=<" + ex.GetType().Name + ">"); } } } type = type.BaseType; } Log.LogInfo((object)("DIRECT_MOVE " + stage + " teleport fields: " + ((list.Count == 0) ? "<none>" : string.Join(", ", list.ToArray())) + ".")); } private static void LogFields(string label, object instance, string[] terms) { if (instance == null) { Log.LogInfo((object)(label + "=<null>.")); return; } Type type = instance.GetType(); while (type != null && type != typeof(object)) { LogDeclaredFields(label, instance, type, terms); type = type.BaseType; } } private static void LogDeclaredFields(string label, object instance, Type declaredType, string[] terms) { FieldInfo[] fields = declaredType.GetFields(BindingFlags.DeclaredOnly | BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); Array.Sort(fields, (FieldInfo left, FieldInfo right) => string.Compare(left.Name, right.Name, StringComparison.Ordinal)); FieldInfo[] array = fields; foreach (FieldInfo fieldInfo in array) { if (ContainsAny(fieldInfo.Name, terms)) { try { Log.LogInfo((object)(label + "." + declaredType.Name + "." + fieldInfo.Name + "=" + FormatValue(fieldInfo.GetValue(instance)) + ".")); } catch (Exception ex) { Log.LogWarning((object)(label + "." + declaredType.Name + "." + fieldInfo.Name + " could not be read: " + ex.Message)); } } } } private static bool ContainsAny(string value, string[] terms) { foreach (string value2 in terms) { if (value.IndexOf(value2, StringComparison.OrdinalIgnoreCase) >= 0) { return true; } } return false; } private static string FormatValue(object value) { //IL_006e: 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_0087: Unknown result type (might be due to invalid IL or missing references) //IL_008b: Unknown result type (might be due to invalid IL or missing references) if (value == null) { return "<null>"; } Object val = (Object)((value is Object) ? value : null); if (val != (Object)null) { return ((object)val).GetType().Name + "('" + val.name + "', instance=" + val.GetInstanceID() + ")"; } if (value is Vector3) { return FormatVector((Vector3)value); } if (value is Quaternion val2) { return FormatVector(((Quaternion)(ref val2)).eulerAngles); } if (value is ICollection collection) { return value.GetType().Name + "[count=" + collection.Count + "]"; } Type type = value.GetType(); if (type.IsPrimitive || value is decimal || value is string || type.IsEnum) { return Convert.ToString(value, CultureInfo.InvariantCulture); } return type.FullName; } private static string FormatVector(Vector3 value) { //IL_0010: 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_003c: Unknown result type (might be due to invalid IL or missing references) return "(" + FormatFloat(value.x) + "," + FormatFloat(value.y) + "," + FormatFloat(value.z) + ")"; } private static string FormatFloat(float value) { return value.ToString("0.###", CultureInfo.InvariantCulture); } } } namespace DundrPortalGun.Projectiles { internal sealed class PortalProjectilePrefabs { internal GameObject Standard { get; private set; } internal GameObject Blue { get; private set; } internal PortalProjectilePrefabs(GameObject standard, GameObject blue) { Standard = standard; Blue = blue; } } internal static class PortalProjectileFactory { internal const string StandardProjectileName = "DundrPortalGun_StandardProjectile"; internal const string BlueProjectileName = "DundrPortalGun_BlueProjectile"; private const string SourceProjectileName = "staff_lightning_projectile"; internal static PortalProjectilePrefabs Register() { //IL_001a: 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) GameObject standard = CreateProjectile("DundrPortalGun_StandardProjectile", PortalEndpointType.Standard, new Color(1f, 0.35f, 0.05f, 1f)); GameObject blue = CreateProjectile("DundrPortalGun_BlueProjectile", PortalEndpointType.Blue, new Color(0.05f, 0.35f, 1f, 1f)); Plugin.Log.LogInfo((object)"Registered harmless portal projectiles: DundrPortalGun_StandardProjectile and DundrPortalGun_BlueProjectile."); return new PortalProjectilePrefabs(standard, blue); } private static GameObject CreateProjectile(string prefabName, PortalEndpointType endpointType, Color color) { //IL_0050: 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_0073: Expected O, but got Unknown GameObject val = PrefabManager.Instance.CreateClonedPrefab(prefabName, "staff_lightning_projectile"); if ((Object)(object)val == (Object)null) { throw new InvalidOperationException("Could not clone required projectile prefab 'staff_lightning_projectile'."); } Projectile component = val.GetComponent<Projectile>(); if ((Object)(object)component == (Object)null) { throw new InvalidOperationException("Cloned projectile '" + prefabName + "' has no Projectile component."); } MakeHarmless(component); TintVisuals(val, color); val.AddComponent<PortalProjectileImpact>().EndpointType = endpointType; PrefabManager.Instance.AddPrefab(new CustomPrefab(val, true)); return val; } private static void MakeHarmless(Projectile projectile) { //IL_0006: 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_0084: Expected O, but got Unknown projectile.m_damage = default(DamageTypes); projectile.m_aoe = 0f; projectile.m_attackForce = 0f; projectile.m_adrenaline = 0f; projectile.m_backstabBonus = 1f; projectile.m_statusEffect = string.Empty; projectile.m_healthReturn = 0f; projectile.m_hitNoise = 0f; projectile.m_spawnOnHit = null; projectile.m_spawnCount = 0; projectile.m_randomSpawnOnHit = new List<GameObject>(); projectile.m_randomSpawnOnHitCount = 0; projectile.m_spawnOnHitEffects = new EffectList(); projectile.m_respawnItemOnHit = false; projectile.m_showBreakMessage = false; projectile.m_bounce = false; projectile.m_maxBounces = 0; } private static void TintVisuals(GameObject prefab, Color color) { //IL_000f: Unknown result type (might be due to invalid IL or missing references) //IL_0014: 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_0018: Unknown result type (might be due to invalid IL or missing references) //IL_003b: Unknown result type (might be due to invalid IL or missing references) ParticleSystem[] componentsInChildren = prefab.GetComponentsInChildren<ParticleSystem>(true); for (int i = 0; i < componentsInChildren.Length; i++) { MainModule main = componentsInChildren[i].main; ((MainModule)(ref main)).startColor = MinMaxGradient.op_Implicit(color); } Light[] componentsInChildren2 = prefab.GetComponentsInChildren<Light>(true); for (int i = 0; i < componentsInChildren2.Length; i++) { componentsInChildren2[i].color = color; } } } internal sealed class PortalProjectileImpact : MonoBehaviour { private static readonly FieldInfo OwnerField = typeof(Projectile).GetField("m_owner", BindingFlags.Instance | BindingFlags.NonPublic); private static readonly FieldInfo VelocityField = typeof(Projectile).GetField("m_vel", BindingFlags.Instance | BindingFlags.NonPublic); private Projectile projectile; private bool handledImpact; [SerializeField] internal PortalEndpointType EndpointType; private void Awake() { //IL_004f: Unknown result type (might be due to invalid IL or missing references) //IL_0059: Expected O, but got Unknown //IL_0059: Unknown result type (might be due to invalid IL or missing references) //IL_0063: Expected O, but got Unknown projectile = ((Component)this).GetComponent<Projectile>(); if ((Object)(object)projectile == (Object)null) { Plugin.Log.LogError((object)(((Object)this).name + " has PortalProjectileImpact but no Projectile component.")); ((Behaviour)this).enabled = false; } else { Projectile obj = projectile; obj.m_onHit = (OnProjectileHit)Delegate.Combine((Delegate?)(object)obj.m_onHit, (Delegate?)new OnProjectileHit(HandleImpact)); } } private void OnDestroy() { //IL_0021: Unknown result type (might be due to invalid IL or missing references) //IL_002b: Expected O, but got Unknown //IL_002b: Unknown result type (might be due to invalid IL or missing references) //IL_0035: Expected O, but got Unknown if ((Object)(object)projectile != (Object)null) { Projectile obj = projectile; obj.m_onHit = (OnProjectileHit)Delegate.Remove((Delegate?)(object)obj.m_onHit, (Delegate?)new OnProjectileHit(HandleImpact)); } } private void HandleImpact(Collider collider, Vector3 hitPoint, bool hitWater) { //IL_0018: Unknown result type (might be due to invalid IL or missing references) //IL_001d: 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) //IL_0020: 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_007d: 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_0141: Unknown result type (might be due to invalid IL or missing references) //IL_0142: Unknown result type (might be due to invalid IL or missing references) if (!handledImpact) { handledImpact = true; Character val = ReadOwner(); Vector3 incomingVelocity = ReadVelocity(); Vector3 val2 = ResolveHitNormal(collider, hitPoint, incomingVelocity); GameObject val3 = (((Object)(object)collider == (Object)null) ? null : ((Component)collider).gameObject); Plugin.Log.LogInfo((object)("PORTAL_PROJECTILE_IMPACT type=" + EndpointType.ToString() + ", owner=" + DescribeOwner(val) + ", point=" + FormatVector(hitPoint) + ", normal=" + FormatVector(val2) + ", object=" + (((Object)(object)val3 == (Object)null) ? "<none>" : ((Object)val3).name) + ", collider=" + (((Object)(object)collider == (Object)null) ? "<none>" : ((object)collider).GetType().Name) + ", layer=" + (((Object)(object)val3 == (Object)null) ? (-1) : val3.layer) + ", water=" + hitWater + ".")); if (Plugin.Portals != null) { Plugin.Portals.TryPlace(val, EndpointType, hitPoint, val2, collider, hitWater); } } } private Character ReadOwner() { if (!(OwnerField == null) && !((Object)(object)projectile == (Object)null)) { object? value = OwnerField.GetValue(projectile); return (Character)((value is Character) ? value : null); } return null; } private Vector3 ReadVelocity() { //IL_0051: 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_003a: 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) if (VelocityField != null && (Object)(object)projectile != (Object)null && VelocityField.GetValue(projectile) is Vector3 result && ((Vector3)(ref result)).sqrMagnitude > 0.0001f) { return result; } return ((Component)this).transform.forward; } private static Vector3 ResolveHitNormal(Collider collider, Vector3 hitPoint, Vector3 incomingVelocity) { //IL_0017: Unknown result type (might be due to invalid IL or missing references) //IL_000e: 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_0057: 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_0028: 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_002f: Unknown result type (might be due to invalid IL or missing references) //IL_0034: Unknown result type (might be due to invalid IL or missing references) //IL_0039: 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_0051: Unknown result type (might be due to invalid IL or missing references) Vector3 val = ((((Vector3)(ref incomingVelocity)).sqrMagnitude > 0.0001f) ? ((Vector3)(ref incomingVelocity)).normalized : Vector3.forward); if ((Object)(object)collider != (Object)null) { Ray val2 = default(Ray); ((Ray)(ref val2))..ctor(hitPoint - val * 0.5f, val); RaycastHit val3 = default(RaycastHit); if (collider.Raycast(val2, ref val3, 1f)) { return ((RaycastHit)(ref val3)).normal; } } return -val; } private static string DescribeOwner(Character owner) { if ((Object)(object)owner == (Object)null) { return "<none>"; } Player val = (Player)(object)((owner is Player) ? owner : null); if ((Object)(object)val != (Object)null) { return "Player('" + val.GetPlayerName() + "')"; } return ((object)owner).GetType().Name + "('" + ((Object)owner).name + "')"; } private static string FormatVector(Vector3 value) { return "(" + value.x.ToString("0.###", CultureInfo.InvariantCulture) + "," + value.y.ToString("0.###", CultureInfo.InvariantCulture) + "," + value.z.ToString("0.###", CultureInfo.InvariantCulture) + ")"; } } internal sealed class PortalProjectileTraversal { private struct Crossing { internal PortalEndpoint Entrance; internal PortalEndpoint Exit; internal float Fraction; internal Vector3 LocalPoint; } private struct ExitSweep { internal PortalEndpoint Exit; internal float RayRadius; } private const float MinimumSpeed = 0.01f; private const float SurfaceSafety = 0.025f; private const float ExitSafety = 0.05f; private const float ExitWallRearDepth = 1.5f; private static readonly Quaternion PortalFrameTurn = Quaternion.Euler(0f, 180f, 0f); private static readonly FieldInfo VelocityField = typeof(Projectile).GetField("m_vel", BindingFlags.Instance | BindingFlags.NonPublic); private static readonly FieldInfo RayRadiusField = typeof(Projectile).GetField("m_rayRadius", BindingFlags.Instance | BindingFlags.NonPublic); private static readonly FieldInfo HaveStartPointField = typeof(Projectile).GetField("m_haveStartPoint", BindingFlags.Instance | BindingFlags.NonPublic); private readonly Dictionary<int, ExitSweep> activeExitSweeps = new Dictionary<int, ExitSweep>(); internal bool TryTraverse(Projectile projectile, PortalPair pair) { //IL_002c: 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_0042: Unknown result type (might be due to invalid IL or missing references) //IL_0048: Unknown result type (might be due to invalid IL or missing references) //IL_004d: Unknown result type (might be due to invalid IL or missing references) //IL_005b: Unknown result type (might be due to invalid IL or missing references) //IL_0060: Unknown result type (might be due to invalid IL or missing references) //IL_007d: Unknown result type (might be due to invalid IL or missing references) //IL_0082: Unknown result type (might be due to invalid IL or missing references) //IL_00cd: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)projectile == (Object)null || pair == null || !pair.IsComplete || VelocityField == null || !HasNetworkAuthority(projectile)) { return false; } Vector3 velocity = projectile.GetVelocity(); if (((Vector3)(ref velocity)).sqrMagnitude < 0.0001f) { return false; } Vector3 step = velocity * Time.fixedDeltaTime; float rayRadius = ReadRayRadius(projectile); Crossing crossing; bool flag = TryFindCrossing(((Component)projectile).transform.position, step, rayRadius, pair.Standard, pair.Blue, out crossing); Crossing crossing2; bool flag2 = TryFindCrossing(((Component)projectile).transform.position, step, rayRadius, pair.Blue, pair.Standard, out crossing2); if (!flag && !flag2) { return false; } Crossing crossing3 = ((!(flag && flag2)) ? (flag ? crossing : crossing2) : ((crossing.Fraction <= crossing2.Fraction) ? crossing : crossing2)); Traverse(projectile, velocity, rayRadius, crossing3); return true; } internal bool ShouldSuppressExitWallHit(Projectile projectile, Collider collider, Vector3 hitPoint, bool water, Vector3 hitNormal) { //IL_0048: 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_004e: 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_0086: Unknown result type (might be due to invalid IL or missing references) //IL_008d: Unknown result type (might be due to invalid IL or missing references) //IL_0093: Unknown result type (might be due to invalid IL or missing references) //IL_00a6: Unknown result type (might be due to invalid IL or missing references) //IL_00b3: Unknown result type (might be due to invalid IL or missing references) //IL_0177: Unknown result type (might be due to invalid IL or missing references) //IL_018a: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)projectile == (Object)null || (Object)(object)collider == (Object)null || water || !activeExitSweeps.TryGetValue(((Object)projectile).GetInstanceID(), out var value) || (Object)(object)value.Exit == (Object)null) { return false; } Vector3 val = ((Component)value.Exit).transform.InverseTransformPoint(hitPoint); float num = Mathf.Min(value.Exit.Width, value.Exit.Height) * 0.5f - value.RayRadius; bool num2 = num > 0f && val.x * val.x + val.y * val.y <= num * num; bool flag = val.z >= -1.5f && val.z <= 0.075f; bool flag2 = (Object)(object)collider == (Object)(object)value.Exit.SourceCollider; bool flag3 = (Object)(object)collider.attachedRigidbody == (Object)null || collider.attachedRigidbody.isKinematic; if (!num2 || !flag || (!flag2 && !flag3)) { return false; } Plugin.Log.LogInfo((object)("PORTAL_PROJECTILE_EXIT_WALL_HIT_SUPPRESSED name=" + ((Object)projectile).name + ", exit=" + value.Exit.EndpointType.ToString() + ", collider=" + ((Object)collider).name + ", sourceCollider=" + flag2 + ", localHit=" + FormatVector(val) + ", hitNormal=" + FormatVector(hitNormal) + ".")); return true; } internal void FinishFixedUpdate(Projectile projectile) { if ((Object)(object)projectile != (Object)null) { activeExitSweeps.Remove(((Object)projectile).GetInstanceID()); } } private static bool TryFindCrossing(Vector3 position, Vector3 step, float rayRadius, PortalEndpoint entrance, PortalEndpoint exit, out Crossing crossing) { //IL_0023: 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_0031: Unknown result type (might be due to invalid IL or missing references) //IL_0038: Unknown result type (might be due to invalid IL or missing references) //IL_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_004b: 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_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_0086: Unknown result type (might be due to invalid IL or missing references) //IL_008b: 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_0098: Unknown result type (might be due to invalid IL or missing references) //IL_009a: Unknown result type (might be due to invalid IL or missing references) //IL_009c: Unknown result type (might be due to invalid IL or missing references) //IL_00a1: Unknown result type (might be due to invalid IL or missing references) //IL_00a6: 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_00d1: Unknown result type (might be due to invalid IL or missing references) //IL_00d8: 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) //IL_00e7: Unknown result type (might be due to invalid IL or missing references) //IL_0115: Unknown result type (might be due to invalid IL or missing references) //IL_011c: Unknown result type (might be due to invalid IL or missing references) //IL_0128: Unknown result type (might be due to invalid IL or missing references) //IL_012d: Unknown result type (might be due to invalid IL or missing references) crossing = default(Crossing); if ((Object)(object)entrance == (Object)null || (Object)(object)exit == (Object)null) { return false; } Vector3 forward = ((Component)entrance).transform.forward; float num = rayRadius + 0.025f; float num2 = Vector3.Dot(position - ((Component)entrance).transform.position, forward) - num; float num3 = Vector3.Dot(step, forward); if (num2 < 0f || num3 >= -0.0001f) { return false; } float num4 = num2 + num3; if (num4 > 0f) { return false; } float num5 = Mathf.Clamp01(num2 / (num2 - num4)); Vector3 val = position + step * num5; Vector3 val2 = ((Component)entrance).transform.InverseTransformPoint(val - forward * num); float num6 = Mathf.Min(entrance.Width, entrance.Height) * 0.5f - rayRadius; if (num6 <= 0f || val2.x * val2.x + val2.y * val2.y > num6 * num6) { return false; } crossing.Entrance = entrance; crossing.Exit = exit; crossing.Fraction = num5; crossing.LocalPoint = new Vector3(val2.x, val2.y, 0f); return true; } private void Traverse(Projectile projectile, Vector3 velocity, float rayRadius, Crossing crossing) { //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_001d: 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_0033: Unknown result type (might be due to invalid IL or missing references) //IL_0038: Unknown result type (might be due to invalid IL or missing references) //IL_003d: 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_0045: Unknown result type (might be due to invalid IL or missing references) //IL_004a: Unknown result type (might be due to invalid IL or missing references) //IL_004f: Unknown result type (might be due to invalid IL or missing references) //IL_0050: Unknown result type (might be due to invalid IL or missing references) //IL_0052: Unknown result type (might be due to invalid IL or missing references) //IL_0057: Unknown result type (might be due to invalid IL or missing references) //IL_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) //IL_005e: Unknown result type (might be due to invalid IL or missing references) //IL_005f: Unknown result type (might be due to invalid IL or missing references) //IL_0064: 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_0073: Unknown result type (might be due to invalid IL or missing references) //IL_0084: Unknown result type (might be due to invalid IL or missing references) //IL_0090: Unknown result type (might be due to invalid IL or missing references) //IL_0095: Unknown result type (might be due to invalid IL or missing references) //IL_009a: Unknown result type (might be due to invalid IL or missing references) //IL_011e: Unknown result type (might be due to invalid IL or missing references) //IL_0120: Unknown result type (might be due to invalid IL or missing references) //IL_012c: Unknown result type (might be due to invalid IL or missing references) //IL_0139: Unknown result type (might be due to invalid IL or missing references) //IL_013b: Unknown result type (might be due to invalid IL or missing references) //IL_00b8: Unknown result type (might be due to invalid IL or missing references) //IL_00bf: Unknown result type (might be due to invalid IL or missing references) //IL_00c4: Unknown result type (might be due to invalid IL or missing references) //IL_00c9: Unknown result type (might be due to invalid IL or missing references) //IL_00cd: Unknown result type (might be due to invalid IL or missing references) //IL_00cf: Unknown result type (might be due to invalid IL or missing references) //IL_00d0: Unknown result type (might be due to invalid IL or missing references) //IL_00d2: Unknown result type (might be due to invalid IL or missing references) //IL_00d7: Unknown result type (might be due to invalid IL or missing references) //IL_00e3: Unknown result type (might be due to invalid IL or missing references) //IL_00e6: Unknown result type (might be due to invalid IL or missing references) //IL_00eb: Unknown result type (might be due to invalid IL or missing references) //IL_00f7: Unknown result type (might be due to invalid IL or missing references) //IL_00fa: Unknown result type (might be due to invalid IL or missing references) //IL_00ff: Unknown result type (might be due to invalid IL or missing references) //IL_010b: Unknown result type (might be due to invalid IL or missing references) //IL_010e: Unknown result type (might be due to invalid IL or missing references) //IL_0113: Unknown result type (might be due to invalid IL or missing references) Transform transform = ((Component)projectile).transform; Quaternion val = ((Component)crossing.Exit).transform.rotation * PortalFrameTurn * Quaternion.Inverse(((Component)crossing.Entrance).transform.rotation); Vector3 val2 = PortalFrameTurn * crossing.LocalPoint; Quaternion val3 = val * transform.rotation; Vector3 val4 = val * velocity; Vector3 val5 = ((Component)crossing.Exit).transform.TransformPoint(val2) + ((Component)crossing.Exit).transform.forward * (rayRadius + 0.05f); Rigidbody component = ((Component)projectile).GetComponent<Rigidbody>(); if ((Object)(object)component != (Object)null && !component.isKinematic) { Vector3 val6 = transform.position - component.position; component.position = val5 - val * val6; component.rotation = val * component.rotation; component.linearVelocity = val * component.linearVelocity; component.angularVelocity = val * component.angularVelocity; } transform.SetPositionAndRotation(val5, val3); VelocityField.SetValue(projectile, val4); projectile.m_startPoint = val5; if (HaveStartPointField != null) { HaveStartPointField.SetValue(projectile, true); } activeExitSweeps[((Object)projectile).GetInstanceID()] = new ExitSweep { Exit = crossing.Exit, RayRadius = rayRadius }; ClearTrails(transform); Physics.SyncTransforms(); Plugin.Log.LogInfo((object)("PORTAL_PROJECTILE_TRAVERSED name=" + ((Object)projectile).name + ", entrance=" + crossing.Entrance.EndpointType.ToString() + ", exit=" + crossing.Exit.EndpointType.ToString() + ", speedBefore=" + FormatFloat(((Vector3)(ref velocity)).magnitude) + ", speedAfter=" + FormatFloat(((Vector3)(ref val4)).magnitude) + ", crossingFraction=" + FormatFloat(crossing.Fraction) + ", rayRadius=" + FormatFloat(rayRadius) + ", collisionOrigin=exactExit, rigidbody=" + (((Object)(object)component == (Object)null) ? "none" : (component.isKinematic ? "kinematic" : "dynamic")) + ".")); } private static bool HasNetworkAuthority(Projectile projectile) { ZNetView val = ((Component)projectile).GetComponent<ZNetView>(); if ((Object)(object)val == (Object)null) { val = ((Component)projectile).GetComponentInParent<ZNetView>(); } if (!((Object)(object)val == (Object)null) && val.IsValid()) { return val.IsOwner(); } return true; } private static float ReadRayRadius(Projectile projectile) { if (RayRadiusField == null) { return 0f; } object value = RayRadiusField.GetValue(projectile); if (!(value is float)) { return 0f; } return Mathf.Max(0f, (float)value); } private static void ClearTrails(Transform root) { TrailRenderer[] componentsInChildren = ((Component)root).GetComponentsInChildren<TrailRenderer>(true); foreach (TrailRenderer val in componentsInChildren) { if ((Object)(object)val != (Object)null) { val.Clear(); } } } private static string FormatFloat(float value) { return value.ToString("0.###", CultureInfo.InvariantCulture); } private static string FormatVector(Vector3 value) { //IL_0010: 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_003c: Unknown result type (might be due to invalid IL or missing references) return "(" + FormatFloat(value.x) + "," + FormatFloat(value.y) + "," + FormatFloat(value.z) + ")"; } } } namespace DundrPortalGun.Portals { internal sealed class PortalEndpoint : MonoBehaviour { private GameObject visualRoot; internal long OwnerId { get; private set; } internal PortalEndpointType EndpointType { get; private set; } internal float Width { get; private set; } internal float Height { get; private set; } internal Collider SourceCollider { get; private set; } internal PortalViewSurface ViewSurface { get; private set; } internal Renderer[] VisualRenderers { get; private set; } internal Light[] VisualLights { get; private set; } internal void Initialize(long ownerId, PortalEndpointType endpointType, float width, float height, Collider sourceCollider, float viewDiameter, float viewEdgeFeatherFraction) { OwnerId = ownerId; EndpointType = endpointType; Width = width; Height = height; SourceCollider = sourceCollider; visualRoot = PortalVisualFactory.Create(((Component)this).transform, endpointType, width, height); VisualRenderers = (Renderer[])(((Object)(object)visualRoot == (Object)null) ? ((Array)new Renderer[0]) : ((Array)visualRoot.GetComponentsInChildren<Renderer>(true))); VisualLights = (Light[])(((Object)(object)visualRoot == (Object)null) ? ((Array)new Light[0]) : ((Array)visualRoot.GetComponentsInChildren<Light>(true))); ViewSurface = PortalViewSurface.Create(((Component)this).transform, Mathf.Min(viewDiameter, Mathf.Min(width, height)), viewEdgeFeatherFraction); } internal void SetLinked(bool linked) { if ((Object)(object)visualRoot != (Object)null && !visualRoot.activeSelf) { visualRoot.SetActive(true); } } internal bool TryIntersectAimRay(Ray ray, float maxDistance, out float distance) { //IL_0009: Unknown result type (might be due to invalid IL or missing references) //IL_0014: 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_003c: 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_004c: Unknown result type (might be due to invalid IL or missing references) //IL_0073: Unknown result type (might be due to invalid IL or missing references) //IL_0078: Unknown result type (might be due to invalid IL or missing references) //IL_007d: Unknown result type (might be due to invalid IL or missing references) //IL_0096: Unknown result type (might be due to invalid IL or missing references) //IL_009c: Unknown result type (might be due to invalid IL or missing references) //IL_00a3: 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) distance = 0f; float num = Vector3.Dot(((Ray)(ref ray)).direction, ((Component)this).transform.forward); if (Mathf.Abs(num) < 0.0001f) { return false; } distance = Vector3.Dot(((Component)this).transform.position - ((Ray)(ref ray)).origin, ((Component)this).transform.forward) / num; if (distance < 0f || distance > maxDistance) { return false; } Vector3 val = ((Component)this).transform.InverseTransformPoint(((Ray)(ref ray)).GetPoint(distance)); float num2 = Mathf.Min(Width, Height) * 0.5f; return val.x * val.x + val.y * val.y <= num2 * num2; } } internal enum PortalEndpointType { Standard, Blue } internal sealed class PortalEntityTraversal { private enum EntityKind { None, DroppedItem, Mob } private sealed class EntityTraversalState { internal Rigidbody Body; internal PortalEndpoint BlockedExit; internal float CooldownUntil; internal int ReapplyTicks; internal Vector3 OutgoingVelocity; internal Vector3 OutgoingAngularVelocity; } private struct BodyShape { internal Vector3 Center; internal Vector3 Extents; internal Quaternion Orientation; internal Vector3 BodyToCenter; internal float GetExtent(Vector3 direction) { //IL_0002: 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) //IL_0014: Unknown result type (might be due to invalid IL or missing references) //IL_0019: 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_0023: Unknown result type (might be due to invalid IL or missing references) //IL_003b: Unknown result type (might be due to invalid IL or missing references) //IL_0040: Unknown result type (might be due to invalid IL or missing references) //IL_0045: Unknown result type (might be due to invalid IL or missing references) //IL_004a: Unknown result type (might be due to invalid IL or missing references) //IL_0063: Unknown result type (might be due to invalid IL or missing references) //IL_0068: 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) Vector3 normalized = ((Vector3)(ref direction)).normalized; return Extents.x * Mathf.Abs(Vector3.Dot(Orientation * Vector3.right, normalized)) + Extents.y * Mathf.Abs(Vector3.Dot(Orientation * Vector3.up, normalized)) + Extents.z * Mathf.Abs(Vector3.Dot(Orientation * Vector3.forward, normalized)); } internal BodyShape Rotate(Quaternion rotation) { //IL_0009: 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_0015: Unknown result type (might be due to invalid IL or missing references) //IL_001c: Unknown result type (might be due to invalid IL or missing references) //IL_001e: Unknown result type (might be due to invalid IL or missing references) //IL_0023: 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) BodyShape result = this; result.Orientation = rotation * Orientation; result.BodyToCenter = rotation * BodyToCenter; return result; } internal static bool TryCreate(Rigidbody body, out BodyShape shape) { //IL_001d: Unknown result type (might be due to invalid IL or missing references) //IL_0087: Unknown result type (might be due to invalid IL or missing references) //IL_008c: Unknown result type (might be due to invalid IL or missing references) //IL_0094: Unknown result type (might be due to invalid IL or missing references) //IL_0099: Unknown result type (might be due to invalid IL or missing references) //IL_009f: Unknown result type (might be due to invalid IL or missing references) //IL_00a4: Unknown result type (might be due to invalid IL or missing references) //IL_00ac: Unknown result type (might be due to invalid IL or missing references) //IL_00b2: 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_00bc: 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_005d: Unknown result type (might be due to invalid IL or missing references) //IL_0062: Unknown result type (might be due to invalid IL or missing references) shape = default(BodyShape); if ((Object)(object)body == (Object)null) { return false; } Collider[] componentsInChildren = ((Component)body).GetComponentsInChildren<Collider>(true); bool flag = false; Bounds val = default(Bounds); Collider[] array = componentsInChildren; foreach (Collider val2 in array) { if (!((Object)(object)val2 == (Object)null) && val2.enabled && !val2.isTrigger && !((Object)(object)val2.attachedRigidbody != (Object)(object)body)) { if (!flag) { val = val2.bounds; flag = true; } else { ((Bounds)(ref val)).Encapsulate(val2.bounds); } } } if (!flag) { return false; } shape.Center = ((Bounds)(ref val)).center; shape.Extents = ((Bounds)(ref val)).extents; shape.Orientation = Quaternion.identity; shape.BodyToCenter = ((Bounds)(ref val)).center - body.position; return true; } } private const float ExitNudgeStep = 0.1f; private const float ApproachHalfDepth = 0.85f; private const float ApproachCenterDepth = 0.7f; private static readonly Quaternion PortalFrameTurn = Quaternion.Euler(0f, 180f, 0f); private static readonly Collider[] CandidateColliders = (Collider[])(object)new Collider[128]; private readonly ModConfig config; private readonly Dictionary<int, EntityTraversalState> states = new Dictionary<int, EntityTraversalState>(); private readonly List<int> staleStateIds = new List<int>(); private readonly HashSet<int> examinedBodies = new HashSet<int>(); private float nextBlockedLogTime; internal PortalEntityTraversal(ModConfig config) { this.config = config; } internal void FixedTick(IEnumerable<PortalPair> pairs) { UpdateStates(); if (pairs == null || (!config.TransportDroppedItems.Value && !config.TransportMobs.Value)) { return; } examinedBodies.Clear(); foreach (PortalPair pair in pairs) { if (pair != null && pair.IsComplete) { ScanEndpoint(pair.Standard, pair.Blue); ScanEndpoint(pair.Blue, pair.Standard); } } } internal void Reset() { states.Clear(); staleStateIds.Clear(); examinedBodies.Clear(); nextBlockedLogTime = 0f; } private void ScanEndpoint(PortalEndpoint entrance, PortalEndpoint exit) { //IL_005f: 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_0074: 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_008a: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)entrance == (Object)null || (Object)(object)exit == (Object)null) { return; } Vector3 val = default(Vector3); ((Vector3)(ref val))..ctor(entrance.Width * 0.5f + config.EntryApertureMargin.Value, entrance.Height * 0.5f + config.EntryApertureMargin.Value, 0.85f); int num = Physics.OverlapBoxNonAlloc(((Component)entrance).transform.position + ((Component)entrance).transform.forward * 0.7f, val, CandidateColliders, ((Component)entrance).transform.rotation, -5, (QueryTriggerInteraction)1); for (int i = 0; i < num; i++) { Collider val2 = CandidateColliders[i]; CandidateColliders[i] = null; Rigidbody val3 = (((Object)(object)val2 == (Object)null) ? null : val2.attachedRigidbody); if (!((Object)(object)val3 == (Object)null) && !val3.isKinematic) { int instanceID = ((Object)val3).GetInstanceID(); if (examinedBodies.Add(instanceID) && !states.ContainsKey(instanceID) && TryClassify(val3, out var character, out var kind) && HasNetworkAuthority(val3) && BodyShape.TryCreate(val3, out var shape) && IsEntryCandidate(val3, shape, entrance)) { TryTraverse(val3, character, kind, shape, entrance, exit); } } } } private bool TryClassify(Rigidbody body, out Character character, out EntityKind kind) { character = ((Component)body).GetComponent<Character>(); if ((Object)(object)character == (Object)null) { character = ((Component)body).GetComponentInParent<Character>(); } if ((Object)(object)character != (Object)null) { if (!config.TransportMobs.Value || character is Player || character.IsDead() || character.IsTeleporting() || (Object)(object)((Component)character).GetComponent<Rigidbody>() != (Object)(object)body) { kind = EntityKind.None; return false; } kind = EntityKind.Mob; return true; } if (!config.TransportDroppedItems.Value || (Object)(object)((Component)body).GetComponent<Projectile>() != (Object)null || (Object)(object)((Component)body).GetComponentInParent<Projectile>() != (Object)null || (Object)(object)((Component)body).GetComponentInParent<Ship>() != (Object)null || (Object)(object)((Component)body).GetComponentInParent<Vagon>() != (Object)null) { kind = EntityKind.None; return false; } ItemDrop val = ((Component)body).GetComponent<ItemDrop>(); if ((Object)(object)val == (Object)null) { val = ((Component)body).GetComponentInParent<ItemDrop>(); } if ((Object)(object)val == (Object)null || (Object)(object)((Component)val).GetComponent<Rigidbody>() != (Object)(object)body) { kind = EntityKind.None; return false; } kind = EntityKind.DroppedItem; return true; } private static bool HasNetworkAuthority(Rigidbody body) { ZNetView val = ((Component)body).GetComponent<ZNetView>(); if ((Object)(object)val == (Object)null) { val = ((Component)body).GetComponentInParent<ZNetView>(); } if (!((Object)(object)val == (Object)null) && val.IsValid()) { return val.IsOwner(); } return true; } private bool IsEntryCandidate(Rigidbody body, BodyShape shape, PortalEndpoint entrance) { //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_000d: 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_001d: Unknown result type (might be due to invalid IL or missing references) //IL_0022: Unknown result type (might be due to invalid IL or missing references) //IL_002a: Unknown result type (might be due to invalid IL or missing references) //IL_002f: Unknown result type (might be due to invalid IL or missing references) //IL_0056: Unknown result type (might be due to invalid IL or missing references) //IL_008c: Unknown result type (might be due to invalid IL or missing references) //IL_0091: Unknown result type (might be due to invalid IL or missing references) //IL_0096: Unknown result type (might be due to invalid IL or missing references) //IL_00c6: Unknown result type (might be due to invalid IL or missing references) //IL_00cd: Unknown result type (might be due to invalid IL or missing references) //IL_00d5: Unknown result type (might be due to invalid IL or missing references) //IL_00dc: Unknown result type (might be due to invalid IL or missing references) Vector3 forward = ((Component)entrance).transform.forward; float num = Vector3.Dot(shape.Center - ((Component)entrance).transform.position, forward); float num2 = 0f - Vector3.Dot(body.linearVelocity, forward); if (num2 < config.MinimumEntrySpeed.Value || num < -0.05f) { return false; } float extent = shape.GetExtent(forward); float num3 = num - num2 * Time.fixedDeltaTime; float num4 = extent + config.EntrySkin.Value; if (num > num4 && num3 > num4) { return false; } Vector3 val = ((Component)entrance).transform.InverseTransformPoint(shape.Center); float value = config.EntryApertureMargin.Value; float num5 = Mathf.Min(entrance.Width, entrance.Height) * 0.5f + value; return val.x * val.x + val.y * val.y <= num5 * num5; } private void TryTraverse(Rigidbody body, Character character, EntityKind kind, BodyShape shape, PortalEndpoint entrance, PortalEndpoint exit) { //IL_0007: 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_001d: Unknown result type (might be due to invalid IL or missing references) //IL_0022: Unknown result type (might be due to invalid IL or missing references) //IL_0027: Unknown result type (might be due to invalid IL or missing references) //IL_002c: 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_0033: 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_0044: Unknown result type (might be due to invalid IL or missing references) //IL_0038: Unknown result type (might be due to invalid IL or missing references) //IL_0039: 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_0049: Unknown result type (might be due to invalid IL or missing references) //IL_004a: Unknown result type (might be due to invalid IL or missing references) //IL_004b: 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_0051: Unknown result type (might be due to invalid IL or missing references) //IL_0056: Unknown result type (might be due to invalid IL or missing references) //IL_0059: 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_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_0076: Unknown result type (might be due to invalid IL or missing references) //IL_007b: 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_008e: 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_0098: Unknown result type (might be due to invalid IL or missing references) //IL_00b0: Unknown result type (might be due to invalid IL or missing references) //IL_00d3: Unknown result type (might be due to invalid IL or missing references) //IL_0106: Unknown result type (might be due to invalid IL or missing references) //IL_011e: Unknown result type (might be due to invalid IL or missing references) //IL_013b: Unknown result type (might be due to invalid IL or missing references) //IL_013d: Unknown result type (might be due to invalid IL or missing references) //IL_0142: Unknown result type (might be due to invalid IL or missing references) //IL_0149: Unknown result type (might be due to invalid IL or missing references) //IL_018b: Unknown result type (might be due to invalid IL or missing references) //IL_0190: Unknown result type (might be due to invalid IL or missing references) //IL_0193: Unknown result type (might be due to invalid IL or missing references) //IL_0198: Unknown result type (might be due to invalid IL or missing references) //IL_019a: Unknown result type (might be due to invalid IL or missing references) //IL_019b: Unknown result type (might be due to invalid IL or missing references) //IL_019d: Unknown result type (might be due to invalid IL or missing references) //IL_01a2: Unknown result type (might be due to invalid IL or missing references) //IL_01a4: Unknown result type (might be due to invalid IL or missing references) //IL_01a5: Unknown result type (might be due to invalid IL or missing references) //IL_01a7: Unknown result type (might be due to invalid IL or missing references) //IL_01ac: Unknown result type (might be due to invalid IL or missing references) //IL_01ae: Unknown result type (might be due to invalid IL or missing references) //IL_01b1: Unknown result type (might be due to invalid IL or missing references) //IL_01b6: Unknown result type (might be due to invalid IL or missing references) //IL_01bb: Unknown result type (might be due to invalid IL or missing references) //IL_01bd: Unknown result type (might be due to invalid IL or missing references) //IL_01bf: Unknown result type (might be due to invalid IL or missing references) //IL_01c1: Unknown result type (might be due to invalid IL or missing references) //IL_01c6: Unknown result type (might be due to invalid IL or missing references) //IL_01c9: Unknown result type (might be due to invalid IL or missing references) //IL_01d1: Unknown result type (might be due to invalid IL or missing references) //IL_01fc: Unknown result type (might be due to invalid IL or missing references) //IL_0204: Unknown result type (might be due to invalid IL or missing references) //IL_0249: Unknown result type (might be due to invalid IL or missing references) //IL_024b: Unknown result type (might be due to invalid IL or missing references) //IL_0251: Unknown result type (might be due to invalid IL or missing references) //IL_0253: Unknown result type (might be due to invalid IL or missing references) //IL_01e1: Unknown result type (might be due to invalid IL or missing references) //IL_01e2: Unknown result type (might be due to invalid IL or missing references) //IL_01e7: Unknown result type (might be due to invalid IL or missing references) Quaternion val = ((Component)exit).transform.rotation * PortalFrameTurn * Quaternion.Inverse(((Component)entrance).transform.rotation); Quaternion rotation = body.rotation; Quaternion val2 = ((kind == EntityKind.Mob) ? GetUprightMobRotation(character, val, rotation) : (val * rotation)); Quaternion val3 = val2 * Quaternion.Inverse(rotation); BodyShape targetShape = shape.Rotate(val3); Vector3 val4 = ((Component)entrance).transform.InverseTransformPoint(shape.Center); Vector3 val5 = PortalFrameTurn * new Vector3(val4.x, val4.y, 0f); float num = exit.Width * 0.5f - targetShape.GetExtent(((Component)exit).transform.right); float num2 = exit.Height * 0.5f - targetShape.GetExtent(((Component)exit).transform.up); if (num < 0f || num2 < 0f) { LogRejected(body, kind, entrance, exit, "the body does not fit through the exit aperture"); return; } val5.x = Mathf.Clamp(val5.x, 0f - num, num); val5.y = Mathf.Clamp(val5.y, 0f - num2, num2); Vector3 exitPlaneCenter = ((Component)exit).transform.TransformPoint(val5); if (!TryFindClearExit(body, targetShape, exit, exitPlaneCenter, config.ExitMargin.Value, config.ExitNudgeLimit.Value, out var targetCenter, out var usedNudge, out var usedApertureScale)) { LogRejected(body, kind, entrance, exit, "no collision-free exit volume was found"); return; } Vector3 linearVelocity = body.linearVelocity; Vector3 angularVelocity = body.angularVelocity; Vector3 val6 = val * linearVelocity; Vector3 val7 = val * angularVelocity; Vector3 val8 = val3 * shape.BodyToCenter; Vector3 position = targetCenter - val8; body.position = position; body.rotation = val2; if ((Object)(object)character != (Object)null) { character.SetLookDir(val2 * Vector3.forward, 0f); } Physics.SyncTransforms(); body.linearVelocity = val6; body.angularVelocity = val7; body.WakeUp(); EntityTraversalState value = new EntityTraversalState { Body = body, BlockedExit = exit, CooldownUntil = Time.fixedTime + config.ReentryCooldown.Value, ReapplyTicks = 1, OutgoingVelocity = val6, OutgoingAngularVelocity = val7 }; states[((Object)body).GetInstanceID()] = value; Plugin.Log.LogInfo((object)("PORTAL_ENTITY_TRAVERSED kind=" + kind.ToString() + ", name=" + ((Object)body).name + ", entrance=" + entrance.EndpointType.ToString() + ", exit=" + exit.EndpointType.ToString() + ", speedBefore=" + FormatFloat(((Vector3)(ref linearVelocity)).magnitude) + ", speedAfter=" + FormatFloat(((Vector3)(ref val6)).magnitude) + ", exitNudge=" + FormatFloat(usedNudge) + ", exitApertureScale=" + FormatFloat(usedApertureScale) + ".")); } private static Quaternion GetUprightMobRotation(Character character, Quaternion frameRotation, Quaternion fallback) { //IL_0011: Unknown result type (might be due to invalid IL or missing references) //IL_0012: Unknown result type (might be due to invalid IL or missing references) //IL_0017: 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) //IL_001c: Unknown result type (might be due to invalid IL or missing references) //IL_001d: 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_001f: Unknown result type (might be due to invalid IL or missing references) //IL_0024: Unknown result type (might be due to invalid IL or missing references) //IL_0043: Unknown result type (might be due to invalid IL or missing references) //IL_0048: Unknown result type (might be due to invalid IL or missing references) //IL_004d: Unknown result type (might be due to invalid IL or missing references) //IL_003f: Unknown result type (might be due to invalid IL or missing references) Vector3 val = (((Object)(object)character == (Object)null) ? (fallback * Vector3.forward) : character.GetLookDir()); Vector3 val2 = frameRotation * val; val2.y = 0f; if (((Vector3)(ref val2)).sqrMagnitude < 0.0001f) { return fallback; } return Quaternion.LookRotation(((Vector3)(ref val2)).normalized, Vector3.up); } private static bool TryFindClearExit(Rigidbody body, BodyShape targetShape, PortalEndpoint exit, Vector3 exitPlaneCenter, float exitMargin, float nudgeLimit, out Vector3 targetCenter, out float usedNudge, out float usedApertureScale) { //IL_0000: 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) //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_001a: 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_004e: 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_0056: 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) //IL_00cc: Unknown result type (might be due to invalid IL or missing references) //IL_00d1: Unknown result type (might be due to invalid IL or missing references) //IL_0068: Unknown result type (might be due to invalid IL or missing references) //IL_0070: Unknown result type (might be due to invalid IL or missing references) //IL_007c: 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_0086: Unknown result type (might be due to invalid IL or missing references) //IL_008f: Unknown result type (might be due to invalid IL or missing references) Vector3 val = exitPlaneCenter - ((Component)exit).transform.position; float extent = targetShape.GetExtent(((Component)exit).transform.forward); float[] array = new float[5] { 1f, 0.75f, 0.5f, 0.25f, 0f }; foreach (float num in array) { Vector3 val2 = ((Component)exit).transform.position + val * num; for (float num2 = 0f; num2 <= nudgeLimit + 0.001f; num2 += 0.1f) { targetCenter = val2 + ((Component)exit).transform.forward * (extent + exitMargin + num2); if (IsVolumeClear(body, targetShape, targetCenter)) { usedNudge = num2; usedApertureScale = num; return true; } } } targetCenter = Vector3.zero; usedNudge = 0f; usedApertureScale = 0f; return false; } private static bool IsVolumeClear(Rigidbody body, BodyShape shape, Vector3 center) { //IL_0008: Unknown result type (might be due to invalid IL or missing references) //IL_0023: Unknown result type (might be due to invalid IL or missing references) //IL_003e: 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_0059: 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) Vector3 val = default(Vector3); ((Vector3)(ref val))..ctor(Mathf.Max(0.01f, shape.Extents.x - 0.02f), Mathf.Max(0.01f, shape.Extents.y - 0.02f), Mathf.Max(0.01f, shape.Extents.z - 0.02f)); Collider[] array = Physics.OverlapBox(center, val, shape.Orientation, -5, (QueryTriggerInteraction)1); foreach (Collider val2 in array) { if (!((Object)(object)val2 == (Object)null) && !((Object)(object)val2.attachedRigidbody == (Object)(object)body) && !IsChildOf(((Component)val2).transform, ((Component)body).transform)) { return false; } } return true; } private void UpdateStates() { //IL_005e: 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) staleStateIds.Clear(); foreach (KeyValuePair<int, EntityTraversalState> state in states) { EntityTraversalState value = state.Value; if ((Object)(object)value.Body == (Object)null) { staleStateIds.Add(state.Key); continue; } if (value.ReapplyTicks > 0) { value.Body.linearVelocity = value.OutgoingVelocity; value.Body.angularVelocity = value.OutgoingAngularVelocity; value.ReapplyTicks--; } if (Time.fixedTime >= value.CooldownUntil && HasClearedExit(value.Body, value.BlockedExit)) { staleStateIds.Add(state.Key); } } foreach (int staleStateId in staleStateIds) { states.Remove(staleStateId); } } private bool HasClearedExit(Rigidbody body, PortalEndpoint exit) { //IL_0021: Unknown result type (might be due to invalid IL or missing references) //IL_002c: 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_003c: 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) //IL_0074: 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_007f: Unknown result type (might be due to invalid IL or missing references) //IL_009e: 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_00ca: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)body == (Object)null || (Object)(object)exit == (Object)null) { return true; } if (!BodyShape.TryCreate(body, out var shape)) { return true; } if (Vector3.Dot(shape.Center - ((Component)exit).transform.position, ((Component)exit).transform.forward) > shape.GetExtent(((Component)exit).transform.forward) + config.RearmDistance.Value) { return true; } Vector3 val = ((Component)exit).transform.InverseTransformPoint(shape.Center); if (!(Mathf.Abs(val.x) > exit.Width * 0.5f + shape.GetExtent(((Component)exit).transform.right))) { return Mathf.Abs(val.y) > exit.Height * 0.5f + shape.GetExtent(((Component)exit).transform.up); } return true; } private static bool IsChildOf(Transform child, Transform parent) { while ((Object)(object)child != (Object)null) { if ((Object)(object)child == (Object)(object)parent) { return true; } child = child.parent; } return false; } private void LogRejected(Rigidbody body, EntityKind kind, PortalEndpoint entrance, PortalEndpoint exit, string reason) { if (!(Time.fixedTime < nextBlockedLogTime)) { nextBlockedLogTime = Time.fixedTime + 0.75f; Plugin.Log.LogInfo((object)("PORTAL_ENTITY_BLOCKED kind=" + kind.ToString() + ", name=" + (((Object)(object)body == (Object)null) ? "<destroyed>" : ((Object)body).name) + ", entrance=" + entrance.EndpointType.ToString() + ", exit=" + exit.EndpointType.ToString() + ", reason=" + reason + ".")); } } private static string FormatFloat(float value) { return value.ToString("0.###", CultureInfo.InvariantCulture); } } internal sealed class PortalManager { private readonly ModConfig config; private readonly PortalEntityTraversal entityTraversal; private readonly PortalProjectileTraversal projectileTraversal; private readonly PortalViewSystem viewSystem; private readonly Dictionary<long, PortalPair> pairs = new Dictionary<long, PortalPair>(); private bool hadLocalPlayer; private PortalEndpoint blockedExit; private bool exitRegionCleared; private float traversalCooldownUntil; private float nextBlockedLogTime; private bool hasPreviousCenter; private Vector3 previousCenter; private Player fallDamageGracePlayer; private float fallDamageGraceUntil; internal PortalManager(ModConfig config) { this.config = config; entityTraversal = new PortalEntityTraversal(config); projectileTraversal = new PortalProjectileTraversal(); viewSystem = new PortalViewSystem(config); } internal void LateTick(Player localPlayer, Camera viewer) { viewSystem.LateTick(pairs.Values, viewer); } internal void Tick(Player localPlayer) { if ((Object)(object)localPlayer == (Object)null) { if (hadLocalPlayer) { ClearAll("local player left the world"); hadLocalPlayer = false; } } else { hadLocalPlayer = true; HandleDeleteInput(localPlayer); } } internal void FixedTick(Player localPlayer) { //IL_00d1: Unknown result type (might be due to invalid IL or missing references) //IL_00d6: Unknown result type (might be due to invalid IL or missing references) //IL_00d8: Unknown result type (might be due to invalid IL or missing references) //IL_00dd: Unknown result type (might be due to invalid IL or missing references) //IL_00f2: 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_00f9: 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_0108: 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_011a: Unknown result type (might be due to invalid IL or missing references) //IL_019a: Unknown result type (might be due to invalid IL or missing references) //IL_019b: Unknown result type (might be due to invalid IL or missing references) //IL_0150: Unknown result type (might be due to invalid IL or missing references) //IL_016d: Unknown result type (might be due to invalid IL or missing references) //IL_0172: Unknown result type (might be due to invalid IL or missing references) //IL_0163: Unknown result type (might be due to invalid IL or missing references) if (!config.TraversalEnabled.Value) { hasPreviousCenter = false; return; } entityTraversal.FixedTick(pairs.Values); if ((Object)(object)localPlayer == (Object)null || ((Character)localPlayer).IsDead() || ((Character)localPlayer).IsTeleporting()) { hasPreviousCenter = false; return; } if ((Object)(object)blockedExit != (Object)null && !exitRegionCleared) { exitRegionCleared = PortalTraversal.HasClearedExit(localPlayer, blockedExit, config); } if ((Object)(object)blockedExit == (Object)null) { exitRegionCleared = true; } if (Time.fixedTime < traversalCooldownUntil || !exitRegionCleared) { RememberCenter(localPlayer); return; } blockedExit = null; Rigidbody component = ((Component)localPlayer).GetComponent<Rigidbody>(); if ((Object)(object)component == (Object)null) { hasPreviousCenter = false; return; } Vector3 centerPoint = ((Character)localPlayer).GetCenterPoint(); Vector3 observedVelocity = component.linearVelocity; if (hasPreviousCenter && Time.fixedDeltaTime > 0f) { Vector3 val = (centerPoint - previousCenter) / Time.fixedDeltaTime; if (((Vector3)(ref val)).sqrMagnitude > ((Vector3)(ref observedVelocity)).sqrMagnitude) { observedVelocity = val; } } foreach (PortalPair value in pairs.Values) { if (value != null && value.IsComplete && (TryTraverseFrom(localPlayer, value, value.Standard, observedVelocity) || TryTraverseFrom(localPlayer, value, value.Blue, observedVelocity))) { previousCenter = ((Character)localPlayer).GetCenterPoint(); hasPreviousCenter = true; return; } } previousCenter = centerPoint; hasPreviousCenter = true; } internal void TryTraverseProjectile(Projectile projectile) { if (!config.TraversalEnabled.Value || !config.TransportProjectiles.Value || (Object)(object)projectile == (Object)null) { return; } foreach (PortalPair value in pairs.Values) { if (value != null && value.IsComplete && projectileTraversal.TryTraverse(projectile, value)) { break; } } } internal bool ShouldSuppressProjectileExitWallHit(Projectile projectile, Collider collider, Vector3 hitPoint, bool water, Vector3 hitNormal) { //IL_0008: 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) return projectileTraversal.ShouldSuppressExitWallHit(projectile, collider, hitPoint, water, hitNormal); } internal void FinishProjectileFixedUpdate(Projectile projectile) { projectileTraversal.FinishFixedUpdate(projectile); } internal bool IsFallDamageGraceActive(Player player) { if (!config.FallDamageGraceEnabled.Value || (Object)(object)player == (Object)null || (Object)(object)player != (Object)(object)fallDamageGracePlayer || Time.time >= fallDamageGraceUntil) { if ((Object)(object)player == (Object)(object)fallDamageGracePlayer && Time.time >= fallDamageGraceUntil) { fallDamageGracePlayer = null; fallDamageGraceUntil = 0f; } return false; } return true; } internal void TryPlace(Character ownerCharacter, PortalEndpointType endpointType, Vector3 hitPoint, Vector3 hitNormal, Collider hitCollider, bool hitWater) { //IL_0008: Unknown result type (might be due to invalid IL or missing references) //IL_0009: 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_0094: Unknown result type (might be due to invalid IL or missing references) //IL_007b: Unknown result type (might be due to invalid IL or missing references) //IL_007c: Unknown result type (might be due to invalid IL or missing references) Player val = (Player)(object)((ownerCharacter is Player) ? ownerCharacter : null); if (!PortalPlacement.TryResolve(val, hitPoint, hitNormal, hitCollider, hitWater, config, out var position, out var rotation, out var rejection)) { Plugin.Log.LogInfo((object)("PORTAL_PLACEMENT_REJECTED type=" + endpointType.ToString() + ", reason=" + rejection + ".")); } else { string targetPrefab = PortalPlacement.ResolveTargetPrefabName(hitCollider); if (Plugin.Network != null) { Plugin.Network.RequestPlacement(val, endpointType, position, rotation, targetPrefab); } else { ApplyReplicatedPlacement(val.GetPlayerID(), val.GetPlayerName(), endpointType, position, rotation, config.ApertureWidth.Value, config.ApertureHeight.Value, targetPrefab, hitCollider); } } } internal void ApplyReplicatedPlacement(long ownerId, string ownerName, PortalEndpointType endpointType, Vector3 position, Quaternion rotation, float width, float height, string targetPrefab, Collider sourceCollider = null) { //IL_005b: Unknown result type (might be due to invalid IL or missing references) //IL_0061: Expected O, but got Unknown //IL_006f: 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) //IL_0107: Unknown result type (might be due to invalid IL or missing references) //IL_0120: Unknown result type (might be due to invalid IL or missing references) //IL_013d: Unknown result type (might be due to invalid IL or missing references) if (!pairs.TryGetValue(ownerId, out var value)) { value = new PortalPair(); pairs.Add(ownerId, value); } PortalEndpoint portalEndpoint = value.Get(endpointType); if ((Object)(object)portalEndpoint != (Object)null) { Object.Destroy((Object)(object)((Component)portalEndpoint).gameObject); } GameObject val = new GameObject("DundrPortalGun_" + endpointType.ToString() + "Endpoint"); ((Object)val).hideFlags = (HideFlags)52; val.transform.SetPositionAndRotation(position, rotation); PortalEndpoint portalEndpoint2 = val.AddComponent<PortalEndpoint>(); portalEndpoint2.Initialize(ownerId, endpointType, width, height, sourceCollider, config.PortalViewDiameter.Value, config.PortalViewEdgeFeatherFraction.Value); value.Set(endpointType, portalEndpoint2); value.RefreshLinkedState(); Plugin.Log.LogInfo((object)("PORTAL_PLACED type=" + endpointType.ToString() + ", owner=" + ownerName + ", ownerId=" + ownerId + ", position=" + FormatVector(position) + ", forward=" + FormatVector(val.transform.forward) + ", up=" + FormatVector(val.transform.up) + ", targetPrefab=" + targetPrefab + ", replaced=" + ((Object)(object)portalEndpoint != (Object)null) + ", pairComplete=" + value.IsComplete + ".")); } internal void ApplyReplicatedDeletion(long ownerId, PortalEndpointType endpointType, string ownerName) { if (!pairs.TryGetValue(ownerId, out var value)) { return; } PortalEndpoint portalEndpoint = value.Get(endpointType); if (!((Object)(object)portalEndpoint == (Object)null)) { value.Remove(portalEndpoint); Object.Destroy((Object)(object)((Component)portalEndpoint).gameObject); value.RefreshLinkedState(); bool isComplete = value.IsComplete; if ((Object)(object)value.Standard == (Object)null && (Object)(object)value.Blue == (Object)null) { pairs.Remove(ownerId); } Plugin.Log.LogInfo((object)("PORTAL_DELETED type=" + endpointType.ToString() + ", owner=" + ownerName + ", ownerId=" + ownerId + ", pairComplete=" + isComplete + ".")); } } internal void ClearAll(string reason) { int num = 0; foreach (PortalPair value in pairs.Values) { num += DestroyIfPresent(value.Standard); num += DestroyIfPresent(value.Blue); } pairs.Clear(); entityTraversal.Reset(); viewSystem.Reset(); ResetTraversalState(); if (num > 0) { Plugin.Log.LogInfo((object)("Removed " + num + " portal endpoint(s): " + reason + ".")); } } private bool TryTraverseFrom(Player player, PortalPair pair, PortalEndpoint entrance, Vector3 observedVelocity) { //IL_000b: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)entrance == (Object)null || !PortalTraversal.IsEntryCandidate(player, entrance, observedVelocity, config, out var planeDistance)) { return false; } PortalEndpoint other = pair.GetOther(entrance); if (!PortalTraversal.TryTraverse(player, entrance, other, config, out var rejection)) { if (Time.fixedTime >= nextBlockedLogTime) { nextBlockedLogTime = Time.fixedTime + 0.75f; Plugin.Log.LogWarning((object)("PORTAL_TRAVERSAL_BLOCKED entrance=" + entrance.EndpointType.ToString() + ", exit=" + other.EndpointType.ToString() + ", planeDistance=" + planeDistance.ToString("0.###", CultureInfo.InvariantCulture) + ", reason=" + rejection + ".")); } return false; } blockedExit = other; exitRegionCleared = false; traversalCooldownUntil = Time.fixedTime + config.ReentryCooldown.Value; BeginFallDamageGrace(player); return true; } private void BeginFallDamageGrace(Player player) { float value = config.FallDamageGraceSeconds.Value; if (config.FallDamageGraceEnabled.Value && !((Object)(object)player == (Object)null) && !(value <= 0f)) { fallDamageGracePlayer = player; fallDamageGraceUntil = Time.time + value; Plugin.Log.LogInfo((object)("PORTAL_FALL_GRACE started duration=" + value.ToString("0.###", CultureInfo.InvariantCulture) + "s.")); } } private void RememberCenter(Player player) { //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) if ((Object)(object)player == (Object)null) { hasPreviousCenter = false; return; } previousCenter = ((Character)player).GetCenterPoint(); hasPreviousCenter = true; } private void ResetTraversalState() { //IL_002c: 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) blockedExit = null; exitRegionCleared = false; traversalCooldownUntil = 0f; nextBlockedLogTime = 0f; hasPreviousCenter = false; previousCenter = Vector3.zero; fallDamageGracePlayer = null; fallDamageGraceUntil = 0f; } private void HandleDeleteInput(Player player) { //IL_005f: 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_0085: 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) if (!Input.GetMouseButtonDown(2) || !PortalGunInput.CanUsePortalGun(player)) { return; } long playerID = player.GetPlayerID(); if (!pairs.TryGetValue(playerID, out var value)) { Plugin.Log.LogInfo((object)"PORTAL_DELETE no owned endpoints exist."); return; } Camera main = Camera.main; if ((Object)(object)main == (Object)null) { Plugin.Log.LogWarning((object)"PORTAL_DELETE failed because Camera.main is null."); return; } Ray ray = default(Ray); ((Ray)(ref ray))..ctor(((Component)main).transform.position, ((Component)main).transform.forward); PortalEndpoint aimed = null; float aimedDistance = float.MaxValue; TrySelect(value.Standard, ray, ref aimed, ref aimedDistance); TrySelect(value.Blue, ray, ref aimed, ref aimedDistance); if ((Object)(object)aimed == (Object)null) { Plugin.Log.LogInfo((object)"PORTAL_DELETE no owned endpoint was under the crosshair."); return; } PortalEndpointType endpointType = aimed.EndpointType; if (Plugin.Network != null) { Plugin.Network.RequestDeletion(player, endpointType); } else { ApplyReplicatedDeletion(playerID, endpointType, player.GetPlayerName()); } } private void TrySelect(PortalEndpoint endpoint, Ray ray, ref PortalEndpoint aimed, ref float aimedDistance) { //IL_000b: Unknown result type (might be due to invalid IL or missing references) if (!((Object)(object)endpoint == (Object)null) && endpoint.TryIntersectAimRay(ray, config.DeleteAimDistance.Value, out var distance) && distance < aimedDistance) { aimed = endpoint; aimedDistance = distance; } } private static int DestroyIfPresent(PortalEndpoint endpoint) { if ((Object)(object)endpoint == (Object)null) { return 0; } Object.Destroy((Object)(object)((Component)endpoint).gameObject); return 1; } private static string FormatVector(Vector3 value) { return "(" + value.x.ToString("0.###", CultureInfo.InvariantCulture) + "," + value.y.ToString("0.###", CultureInfo.InvariantCulture) + "," + value.z.ToString("0.###", CultureInfo.InvariantCulture) + ")"; } } internal sealed class PortalPair { internal PortalEndpoint Standard { get; set; } internal PortalEndpoint Blue { get; set; } internal bool IsComplete { get { if ((Object)(object)Standard != (Object)null) { return (Object)(object)Blue != (Object)null; } return false; } } internal PortalEndpoint Get(PortalEndpointType endpointType) { if (endpointType != PortalEndpointType.Standard) { return Blue; } return Standard; } i