Decompiled source of Better Tracing v1.0.1
BetterTracing.dll
Decompiled 20 hours 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.Concurrent; using System.Collections.Generic; using System.ComponentModel; using System.Diagnostics; using System.Globalization; using System.IO; using System.Linq; using System.Reflection; using System.Reflection.Emit; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; using System.Runtime.Versioning; using System.Text; using System.Text.RegularExpressions; using System.Threading; using System.Threading.Tasks; using BepInEx; using BepInEx.Bootstrap; using BepInEx.Configuration; using DM; using GamepadUI.StateManager.Core; using HarmonyLib; using InControl; using Landfall.TABS; using Landfall.TABS.AI; using Landfall.TABS.AI.Components; using Landfall.TABS.AI.Components.Modifiers; using Landfall.TABS.AI.Components.Pathfinding; using Landfall.TABS.AI.Components.Tags; using Landfall.TABS.AI.Systems; using Landfall.TABS.GameMode; using Landfall.TABS.GameState; using Landfall.TABS.UnitEditor; using Landfall.TABS.UnitPlacement; using Landfall.TABS.WinConditions; using Landfall.TABS.Workshop; using Landfall.TABS_Input; using Microsoft.CodeAnalysis; using Pathfinding; using TFBGames; using TMPro; using UIStateManager; using Unity.Entities; using Unity.Mathematics; using UnityEngine; using UnityEngine.EventSystems; using UnityEngine.Events; using UnityEngine.SceneManagement; using UnityEngine.UI; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: TargetFramework(".NETFramework,Version=v4.7.2", FrameworkDisplayName = ".NET Framework 4.7.2")] [assembly: AssemblyCompany("BetterTracing")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyFileVersion("1.0.1.0")] [assembly: AssemblyInformationalVersion("1.0.1")] [assembly: AssemblyProduct("BetterTracing")] [assembly: AssemblyTitle("BetterTracing")] [assembly: AssemblyVersion("1.0.1.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 Tabs.PersistentHealth.Mod { internal static class AssassinPoofCompatibility { internal static readonly DatabaseID LegacyAbilityId = new DatabaseID(-2, 1847012603); private static SpecialAbility s_nativeAbility; internal static bool PersonalOverrideEnabled => false; private static SpecialAbility ResolveNativeAbility(LandfallContentDatabase database = null) { if ((Object)(object)s_nativeAbility != (Object)null) { return s_nativeAbility; } if (database == null) { ContentDatabase obj = ContentDatabase.Instance(); database = ((obj != null) ? obj.LandfallContentDatabase : null); } if (database == null) { return null; } s_nativeAbility = (from move in database.GetCombatMoves() where (Object)(object)move != (Object)null && (Object)(object)move.GetComponent<AssassinPoofEffect>() != (Object)null select move.GetComponent<SpecialAbility>() into ability where (Object)(object)ability != (Object)null && ((CharacterItem)ability).Entity != null && ((CharacterItem)ability).Entity.GUID.m_modID == DatabaseID._LANDFALL_CONTENT orderby (((CharacterItem)ability).DisplayName ?? string.Empty).IndexOf("Assassin", StringComparison.OrdinalIgnoreCase) >= 0 descending select ability).FirstOrDefault(); return s_nativeAbility; } internal static bool IsNativeAssassinPoof(AssassinPoofEffect effect) { //IL_0048: Unknown result type (might be due to invalid IL or missing references) //IL_0053: Unknown result type (might be due to invalid IL or missing references) SpecialAbility val = (((Object)(object)effect != (Object)null) ? ((Component)effect).GetComponent<SpecialAbility>() : null); SpecialAbility val2 = (((Object)(object)val != (Object)null) ? ResolveNativeAbility() : null); if (((val != null) ? ((CharacterItem)val).Entity : null) != null && ((val2 != null) ? ((CharacterItem)val2).Entity : null) != null) { return ((CharacterItem)val).Entity.GUID == ((CharacterItem)val2).Entity.GUID; } return false; } internal static bool TryAttachToSpawnedUnit(AssassinPoofEffect effect) { if (!PersonalOverrideEnabled || (Object)(object)effect == (Object)null) { return false; } Unit component = ((Component)((Component)effect).transform.root).GetComponent<Unit>(); if ((Object)(object)component == (Object)null || !IsNativeAssassinPoof(effect)) { return false; } if ((Object)(object)((Component)component).GetComponentInChildren<ModAssassinPoofEffect>(true) == (Object)null) { ((Component)effect).gameObject.AddComponent<ModAssassinPoofEffect>().CopyPresentationFrom(effect); } effect.automatic = false; ((MonoBehaviour)effect).StopAllCoroutines(); ((Behaviour)effect).enabled = false; return true; } internal static void MigrateLegacyAbility(SerializedUnitBlueprint data, LandfallContentDatabase database = null) { //IL_0014: 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) if (data?.m_combatMoves != null && data.m_combatMoves.Contains(LegacyAbilityId)) { SpecialAbility val = ResolveNativeAbility(database); if (((val != null) ? ((CharacterItem)val).Entity : null) == null) { BetterTracingPlugin.LogPluginWarning("Could not convert the old modded Assassin Poof: the vanilla ability is unavailable."); } else { ReplaceLegacyAbilityIds(data, ((CharacterItem)val).Entity.GUID); } } } internal static void ReplaceLegacyAbilityIds(SerializedUnitBlueprint data, DatabaseID nativeId) { //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_0008: Unknown result type (might be due to invalid IL or missing references) //IL_0029: Unknown result type (might be due to invalid IL or missing references) //IL_002e: Unknown result type (might be due to invalid IL or missing references) if (data?.m_combatMoves != null && !((DatabaseID)(ref nativeId)).IsDefaultID() && !(nativeId == LegacyAbilityId)) { data.m_combatMoves = data.m_combatMoves.Select((DatabaseID id) => (!(id == LegacyAbilityId)) ? id : nativeId).ToArray(); } } } public sealed class ModAssassinPoofEffect : MonoBehaviour { private readonly struct BodyShape { internal readonly float BottomY; internal readonly float LowerExtent; internal readonly float UpperExtent; internal readonly float Radius; internal BodyShape(float bottomY, float lowerExtent, float upperExtent, float radius) { BottomY = bottomY; LowerExtent = lowerExtent; UpperExtent = upperExtent; Radius = radius; } } private readonly struct RigidbodySnapshot { internal readonly Rigidbody Rigidbody; internal readonly bool WasKinematic; internal readonly bool DetectedCollisions; internal RigidbodySnapshot(Rigidbody rigidbody, bool wasKinematic, bool detectedCollisions) { Rigidbody = rigidbody; WasKinematic = wasKinematic; DetectedCollisions = detectedCollisions; } } private const int NormalCandidateAttempts = 40; private const int ExpandedCandidateAttempts = 72; private const float GoldenAngleDegrees = 137.50777f; private const float MaximumGroundDrop = 10f; private const float MinimumWalkableNormalY = 0.55f; private const float LandingClearance = 0.08f; private const float WallClearance = 0.14f; private Unit m_unit; private CanDoUnitEvents m_canDo; private ParticleSystem m_particles; private AssassinPoofEffect m_nativePresentation; private UnityEvent m_poofEvent; private float m_counter; private bool m_done; private bool m_initialized; private float TriggerDelaySeconds => UnitAbilityRuntime.Number((Component)(object)m_nativePresentation, "activationDelay", 0.28f); private float MoveDelaySeconds => UnitAbilityRuntime.Number((Component)(object)m_nativePresentation, "moveDelay", 0.015f); private float BacklineFraction => UnitAbilityRuntime.Number((Component)(object)m_nativePresentation, "backlinePercent", 40f) / 100f; private float MinimumTargetRadius => UnitAbilityRuntime.Number((Component)(object)m_nativePresentation, "distanceFromUnit", 2f); private float NormalSearchWidth => UnitAbilityRuntime.Number((Component)(object)m_nativePresentation, "searchWidth", 3.5f); private float ExpandedSearchWidth => NormalSearchWidth + 2.5f; internal void CopyPresentationFrom(AssassinPoofEffect nativeEffect) { m_nativePresentation = nativeEffect; m_poofEvent = (((Object)(object)nativeEffect != (Object)null) ? nativeEffect.poofEvent : null); } private void Start() { //IL_00cd: 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) m_unit = ((Component)((Component)this).transform.root).GetComponent<Unit>(); if ((Object)(object)m_unit == (Object)null) { return; } ModAssassinPoofEffect[] componentsInChildren = ((Component)((Component)m_unit).transform.root).GetComponentsInChildren<ModAssassinPoofEffect>(true); if (componentsInChildren.Length != 0 && (Object)(object)componentsInChildren[0] != (Object)(object)this) { ((Behaviour)this).enabled = false; return; } m_canDo = ((Component)this).GetComponent<CanDoUnitEvents>(); m_nativePresentation = ((Component)this).GetComponent<AssassinPoofEffect>(); if ((Object)(object)m_nativePresentation != (Object)null) { m_nativePresentation.automatic = false; ((Behaviour)m_nativePresentation).enabled = false; m_poofEvent = m_nativePresentation.poofEvent; } DisableNativePoofEffectsOnUnit(m_unit); m_particles = ((Component)this).GetComponentInChildren<ParticleSystem>(); if ((Object)(object)m_particles != (Object)null) { try { ShapeModule shape = m_particles.shape; ((ShapeModule)(ref shape)).skinnedMeshRenderer = ((Component)((Component)this).transform.root).GetComponentInChildren<SkinnedMeshRenderer>(); } catch { } } m_counter = Random.Range(0f, 0.08f); m_initialized = true; } private static void DisableNativePoofEffectsOnUnit(Unit owner) { if ((Object)(object)owner == (Object)null) { return; } AssassinPoofEffect[] componentsInChildren = ((Component)((Component)owner).transform.root).GetComponentsInChildren<AssassinPoofEffect>(true); foreach (AssassinPoofEffect val in componentsInChildren) { if (!((Object)(object)val == (Object)null) && AssassinPoofCompatibility.IsNativeAssassinPoof(val)) { val.automatic = false; ((MonoBehaviour)val).StopAllCoroutines(); ((Behaviour)val).enabled = false; } } } private void Update() { if (m_initialized && !m_done && !((Object)(object)m_unit == (Object)null) && !m_unit.dead && !((Object)(object)m_unit.data == (Object)null) && !m_unit.data.Dead && (!((Object)(object)m_canDo != (Object)null) || m_canDo.canDoStuff)) { m_counter += Time.deltaTime; if (!(m_counter <= TriggerDelaySeconds)) { m_done = true; ((MonoBehaviour)this).StartCoroutine(DoSafePoof()); } } } private IEnumerator DoSafePoof() { if (!TryChooseSafeTeleportDestination(out var target, out var teleportDelta, out var groundPoint, out var groundNormal)) { yield break; } if ((Object)(object)m_particles != (Object)null) { m_particles.Emit(25); } yield return (object)new WaitForSeconds(MoveDelaySeconds); if (IsLiveUnit(m_unit) && TryChooseSafeTeleportDestination(out target, out teleportDelta, out groundPoint, out groundNormal)) { List<RigidbodySnapshot> snapshots = FreezeRagdollForTeleport(m_unit); MoveRagdollAsOne(m_unit, teleportDelta); SnapFeetToGround(m_unit, groundPoint.y); if ((Object)(object)m_unit.data != (Object)null) { m_unit.data.TouchGround(groundPoint, groundNormal, (Rigidbody)null); } UnityEvent poofEvent = m_poofEvent; if (poofEvent != null) { poofEvent.Invoke(); } if ((Object)(object)m_particles != (Object)null) { m_particles.Play(); } yield return (object)new WaitForFixedUpdate(); RestoreRagdollAfterTeleport(m_unit, snapshots); } } private bool TryChooseSafeTeleportDestination(out Unit target, out Vector3 teleportDelta, out Vector3 groundPoint, out Vector3 groundNormal) { //IL_0004: 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_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_001b: 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_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_00d5: 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_00de: 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_0131: Unknown result type (might be due to invalid IL or missing references) //IL_0133: 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_0142: Unknown result type (might be due to invalid IL or missing references) //IL_0144: Unknown result type (might be due to invalid IL or missing references) target = null; teleportDelta = Vector3.zero; groundPoint = Vector3.zero; groundNormal = Vector3.up; if (!IsLiveUnit(m_unit)) { return false; } List<Unit> list = (from candidate in Object.FindObjectsOfType<Unit>() where IsLiveUnit(candidate) && (Object)(object)candidate != (Object)(object)m_unit && candidate.Team != m_unit.Team orderby Vector3.Distance(m_unit.data.mainRig.position, candidate.data.mainRig.position) descending select candidate).ToList(); if (list.Count == 0) { return false; } int num = Mathf.Clamp(Mathf.CeilToInt((float)list.Count * BacklineFraction), 1, list.Count); ShuffleRange(list, 0, num); ShuffleRange(list, num, list.Count - num); foreach (Unit item in list) { if (TryFindSafeDestinationAroundTarget(m_unit, item, expandedSearch: false, out var groundedDelta, out var groundPoint2, out var groundNormal2)) { target = item; teleportDelta = groundedDelta; groundPoint = groundPoint2; groundNormal = groundNormal2; return true; } } foreach (Unit item2 in list) { if (TryFindSafeDestinationAroundTarget(m_unit, item2, expandedSearch: true, out var groundedDelta2, out var groundPoint3, out var groundNormal3)) { target = item2; teleportDelta = groundedDelta2; groundPoint = groundPoint3; groundNormal = groundNormal3; return true; } } return false; } private static void ShuffleRange(List<Unit> units, int start, int count) { for (int num = start + count - 1; num > start; num--) { int num2 = Random.Range(start, num + 1); int index = num; int index2 = num2; Unit value = units[num2]; Unit value2 = units[num]; units[index] = value; units[index2] = value2; } } private bool TryFindSafeDestinationAroundTarget(Unit caster, Unit target, bool expandedSearch, out Vector3 groundedDelta, out Vector3 groundPoint, out Vector3 groundNormal) { //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_000e: Unknown result type (might be due to invalid IL or missing references) //IL_0013: Unknown result type (might be due to invalid IL or missing references) //IL_001a: Unknown result type (might be due to invalid IL or missing references) //IL_001f: Unknown result type (might be due to invalid IL or missing references) //IL_00f8: 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_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_0119: Unknown result type (might be due to invalid IL or missing references) //IL_011d: Unknown result type (might be due to invalid IL or missing references) //IL_0122: Unknown result type (might be due to invalid IL or missing references) //IL_0127: Unknown result type (might be due to invalid IL or missing references) //IL_012c: Unknown result type (might be due to invalid IL or missing references) //IL_0157: Unknown result type (might be due to invalid IL or missing references) //IL_0167: Unknown result type (might be due to invalid IL or missing references) //IL_016c: Unknown result type (might be due to invalid IL or missing references) //IL_0171: 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_01a9: 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_01c0: Unknown result type (might be due to invalid IL or missing references) //IL_01c5: Unknown result type (might be due to invalid IL or missing references) groundedDelta = Vector3.zero; groundPoint = Vector3.zero; groundNormal = Vector3.up; if (!IsLiveUnit(caster) || !IsLiveUnit(target) || !TryGetBodyShape(caster, out var shape)) { return false; } float num = 0.55f; if (TryGetBodyShape(target, out var shape2)) { num = shape2.Radius; } float num2 = Mathf.Max(MinimumTargetRadius, shape.Radius + num + 0.5f); float num3 = (expandedSearch ? ExpandedSearchWidth : NormalSearchWidth); int num4 = (expandedSearch ? 72 : 40); float num5 = Random.Range(0f, 360f); for (int i = 0; i < num4; i++) { float num6 = num5 + (float)i * 137.50777f + Random.Range(-9f, 9f); float num7 = (float)(i % 6) / 5f; float num8 = num2 + num7 * num3 + Random.Range(-0.12f, 0.12f); Vector3 val = Quaternion.Euler(0f, num6, 0f) * Vector3.forward; Vector3 horizontalPoint = target.data.mainRig.position + val * num8; if (TryBuildSafeGroundedDestination(caster, target, shape, horizontalPoint, out groundedDelta, out groundPoint, out groundNormal)) { return true; } } Vector3 val2 = caster.data.mainRig.position - target.data.mainRig.position; val2.y = 0f; if (((Vector3)(ref val2)).sqrMagnitude > 0.001f) { ((Vector3)(ref val2)).Normalize(); for (int j = 0; j < 4; j++) { Vector3 horizontalPoint2 = target.data.mainRig.position + val2 * (num2 + (float)j * 0.8f); if (TryBuildSafeGroundedDestination(caster, target, shape, horizontalPoint2, out groundedDelta, out groundPoint, out groundNormal)) { return true; } } } return false; } private static bool TryBuildSafeGroundedDestination(Unit caster, Unit target, BodyShape casterShape, Vector3 horizontalPoint, out Vector3 groundedDelta, out Vector3 groundPoint, out Vector3 groundNormal) { //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_000e: Unknown result type (might be due to invalid IL or missing references) //IL_0013: Unknown result type (might be due to invalid IL or missing references) //IL_001a: Unknown result type (might be due to invalid IL or missing references) //IL_001f: Unknown result type (might be due to invalid IL or missing references) //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_0035: 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_004c: 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_0067: Unknown result type (might be due to invalid IL or missing references) //IL_0077: Unknown result type (might be due to invalid IL or missing references) //IL_0091: 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_00ab: Unknown result type (might be due to invalid IL or missing references) //IL_00b6: Unknown result type (might be due to invalid IL or missing references) //IL_00c3: 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_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_00de: Unknown result type (might be due to invalid IL or missing references) //IL_00fc: Unknown result type (might be due to invalid IL or missing references) //IL_0101: Unknown result type (might be due to invalid IL or missing references) //IL_010a: Unknown result type (might be due to invalid IL or missing references) //IL_010f: Unknown result type (might be due to invalid IL or missing references) //IL_00ec: Unknown result type (might be due to invalid IL or missing references) //IL_00f1: Unknown result type (might be due to invalid IL or missing references) groundedDelta = Vector3.zero; groundPoint = Vector3.zero; groundNormal = Vector3.up; Vector3 position = caster.data.mainRig.position; if (!TryFindGroundBelow(new Vector3(horizontalPoint.x, Mathf.Max(position.y, target.data.mainRig.position.y) + 2f, horizontalPoint.z), out var ground)) { return false; } float num = position.y - casterShape.BottomY; if (num < 0f) { return false; } Vector3 val = default(Vector3); ((Vector3)(ref val))..ctor(horizontalPoint.x, ((RaycastHit)(ref ground)).point.y + num + 0.08f, horizontalPoint.z); if (!IsLandingVolumeClear(val, casterShape, caster)) { return false; } if (HasEnvironmentBetweenTargetAndDestination(target, val)) { return false; } groundedDelta = val - position; if (!AreTranslatedUnitCollidersClear(caster, groundedDelta)) { groundedDelta = Vector3.zero; return false; } groundPoint = ((RaycastHit)(ref ground)).point; groundNormal = ((RaycastHit)(ref ground)).normal; return true; } private static bool TryFindGroundBelow(Vector3 destination, out RaycastHit ground) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_0008: 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_001c: 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_005e: 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_008b: 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_00a7: Unknown result type (might be due to invalid IL or missing references) //IL_00b1: Unknown result type (might be due to invalid IL or missing references) //IL_00c0: Unknown result type (might be due to invalid IL or missing references) //IL_00c1: Unknown result type (might be due to invalid IL or missing references) ground = default(RaycastHit); RaycastHit[] array = Physics.RaycastAll(destination + Vector3.up * 2f, Vector3.down, 12f, -1, (QueryTriggerInteraction)1); Array.Sort(array, (RaycastHit left, RaycastHit right) => ((RaycastHit)(ref left)).distance.CompareTo(((RaycastHit)(ref right)).distance)); RaycastHit[] array2 = array; for (int num = 0; num < array2.Length; num++) { RaycastHit val = array2[num]; Collider collider = ((RaycastHit)(ref val)).collider; if (!((Object)(object)collider == (Object)null) && !IsUnitCollider(collider) && !(((RaycastHit)(ref val)).normal.y < 0.55f) && !(destination.y - ((RaycastHit)(ref val)).point.y > 10f) && !(((RaycastHit)(ref val)).point.y > destination.y + 0.25f)) { ground = val; return true; } } return false; } private static bool IsLandingVolumeClear(Vector3 mainRigPosition, BodyShape shape, Unit caster) { //IL_000d: 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_0025: 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_0030: Unknown result type (might be due to invalid IL or missing references) //IL_0047: Unknown result type (might be due to invalid IL or missing references) //IL_004c: Unknown result type (might be due to invalid IL or missing references) //IL_0051: 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_00bb: 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_00da: Unknown result type (might be due to invalid IL or missing references) //IL_00df: Unknown result type (might be due to invalid IL or missing references) //IL_00fa: Unknown result type (might be due to invalid IL or missing references) //IL_00fb: Unknown result type (might be due to invalid IL or missing references) float num = shape.Radius + 0.14f; Vector3 val = mainRigPosition + Vector3.down * Mathf.Max(0f, shape.LowerExtent - num); Vector3 val2 = mainRigPosition + Vector3.up * Mathf.Max(0f, shape.UpperExtent - num); Collider[] array = Physics.OverlapCapsule(val, val2, num, -1, (QueryTriggerInteraction)1); foreach (Collider val3 in array) { if (!((Object)(object)val3 == (Object)null) && !((Component)val3).transform.IsChildOf(((Component)caster).transform)) { return false; } } float num2 = Mathf.Max(0.12f, (shape.LowerExtent + shape.UpperExtent) * 0.5f - 0.06f); Vector3 val4 = mainRigPosition + Vector3.up * ((shape.UpperExtent - shape.LowerExtent) * 0.5f + 0.06f); Vector3 val5 = default(Vector3); ((Vector3)(ref val5))..ctor(num * 1.08f, num2, num * 1.08f); array = Physics.OverlapBox(val4, val5, Quaternion.identity, -1, (QueryTriggerInteraction)1); foreach (Collider val6 in array) { if (!((Object)(object)val6 == (Object)null) && !((Component)val6).transform.IsChildOf(((Component)caster).transform)) { return false; } } return true; } private static bool HasEnvironmentBetweenTargetAndDestination(Unit target, Vector3 destination) { //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_001a: Unknown result type (might be due to invalid IL or missing references) //IL_001f: Unknown result type (might be due to invalid IL or missing references) //IL_0024: Unknown result type (might be due to invalid IL or missing references) //IL_0025: Unknown result type (might be due to invalid IL or missing references) //IL_0026: 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_003f: 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_0042: 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_005d: Unknown result type (might be due to invalid IL or missing references) Vector3 val = target.data.mainRig.position + Vector3.up * 0.15f; Vector3 val2 = destination - val; float magnitude = ((Vector3)(ref val2)).magnitude; if (magnitude < 0.25f) { return false; } RaycastHit[] array = Physics.RaycastAll(val, val2 / magnitude, magnitude, -1, (QueryTriggerInteraction)1); for (int i = 0; i < array.Length; i++) { RaycastHit val3 = array[i]; if (!((Object)(object)((RaycastHit)(ref val3)).collider == (Object)null) && !IsUnitCollider(((RaycastHit)(ref val3)).collider) && ((RaycastHit)(ref val3)).distance > 0.15f && ((RaycastHit)(ref val3)).distance < magnitude - 0.1f) { return true; } } return false; } private static bool AreTranslatedUnitCollidersClear(Unit caster, Vector3 delta) { //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_0048: Unknown result type (might be due to invalid IL or missing references) //IL_0054: Unknown result type (might be due to invalid IL or missing references) //IL_006d: Unknown result type (might be due to invalid IL or missing references) //IL_0072: Unknown result type (might be due to invalid IL or missing references) //IL_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_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_0097: 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_00b5: Unknown result type (might be due to invalid IL or missing references) Collider[] componentsInChildren = ((Component)((Component)caster).transform.root).GetComponentsInChildren<Collider>(true); Vector3 val3 = default(Vector3); foreach (Collider val in componentsInChildren) { if ((Object)(object)val == (Object)null || !val.enabled || val.isTrigger) { continue; } Bounds bounds = val.bounds; float num = Mathf.Max(((Bounds)(ref bounds)).extents.x, ((Bounds)(ref bounds)).extents.z) + 0.14f; Vector3 val2 = ((Bounds)(ref bounds)).center + delta + Vector3.up * 0.04f; ((Vector3)(ref val3))..ctor(num, Mathf.Max(0.02f, ((Bounds)(ref bounds)).extents.y - 0.04f), num); Collider[] array = Physics.OverlapBox(val2, val3, Quaternion.identity, -1, (QueryTriggerInteraction)1); foreach (Collider val4 in array) { if (!((Object)(object)val4 == (Object)null) && !((Component)val4).transform.IsChildOf(((Component)caster).transform)) { return false; } } } return true; } private static bool TryGetBodyShape(Unit unit, out BodyShape shape) { //IL_001c: Unknown result type (might be due to invalid IL or missing references) //IL_0021: Unknown result type (might be due to invalid IL or missing references) //IL_0024: Unknown result type (might be due to invalid IL or missing references) //IL_0122: Unknown result type (might be due to invalid IL or missing references) //IL_015d: Unknown result type (might be due to invalid IL or missing references) //IL_016d: Unknown result type (might be due to invalid IL or missing references) //IL_018d: Unknown result type (might be due to invalid IL or missing references) //IL_0197: Unknown result type (might be due to invalid IL or missing references) //IL_01b5: 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_00c5: 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) shape = default(BodyShape); if (!IsLiveUnit(unit)) { return false; } Vector3 position = unit.data.mainRig.position; Bounds val = default(Bounds); bool flag = false; Rigidbody[] array = (((Object)(object)unit.data.allRigs != (Object)null) ? unit.data.allRigs.AllRigs : ((Component)unit).GetComponentsInChildren<Rigidbody>()); foreach (Rigidbody val2 in array) { if ((Object)(object)val2 == (Object)null || (Object)(object)((Component)val2).GetComponentInParent<Weapon>() != (Object)null) { continue; } Collider[] componentsInChildren = ((Component)val2).GetComponentsInChildren<Collider>(); foreach (Collider val3 in componentsInChildren) { if (!((Object)(object)val3 == (Object)null) && val3.enabled && !val3.isTrigger) { if (!flag) { val = val3.bounds; flag = true; } else { ((Bounds)(ref val)).Encapsulate(val3.bounds); } } } } float num = Mathf.Clamp(((Object)(object)unit.unitBlueprint != (Object)null) ? unit.unitBlueprint.sizeMultiplier : 1f, 0.5f, 3f); if (!flag) { shape = new BodyShape(position.y - 0.8f * num, 0.8f * num, 0.8f * num, 0.45f * num); return true; } float bottomY; float num2 = (TryGetActualFootBottomY(unit, out bottomY) ? bottomY : ((Bounds)(ref val)).min.y); float lowerExtent = Mathf.Clamp(position.y - num2, 0.35f * num, 2.5f * num); float upperExtent = Mathf.Clamp(((Bounds)(ref val)).max.y - position.y, 0.35f * num, 2.5f * num); float radius = Mathf.Clamp(Mathf.Max(((Bounds)(ref val)).extents.x, ((Bounds)(ref val)).extents.z) * 0.72f, 0.38f * num, 1.15f * num); shape = new BodyShape(num2, lowerExtent, upperExtent, radius); return true; } private static bool TryGetActualFootBottomY(Unit unit, out float bottomY) { //IL_0155: 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_00d0: Unknown result type (might be due to invalid IL or missing references) //IL_00d4: Unknown result type (might be due to invalid IL or missing references) bottomY = float.PositiveInfinity; if ((Object)(object)unit?.data == (Object)null) { return false; } bool flag = false; Transform[] array = (Transform[])(object)new Transform[2] { unit.data.footLeft, unit.data.footRight }; Transform[] array2 = array; foreach (Transform val in array2) { if ((Object)(object)val == (Object)null) { continue; } Rigidbody component = ((Component)val).GetComponent<Rigidbody>(); Collider[] array3 = (((Object)(object)component != (Object)null) ? ((Component)component).GetComponentsInChildren<Collider>() : ((Component)val).GetComponentsInChildren<Collider>()); foreach (Collider val2 in array3) { if (!((Object)(object)val2 == (Object)null) && val2.enabled && !val2.isTrigger && (!((Object)(object)component != (Object)null) || !((Object)(object)val2.attachedRigidbody != (Object)(object)component))) { float num = bottomY; Bounds bounds = val2.bounds; bottomY = Mathf.Min(num, ((Bounds)(ref bounds)).min.y); flag = true; } } } if (flag) { return true; } float num2 = Mathf.Clamp(((Object)(object)unit.unitBlueprint != (Object)null) ? unit.unitBlueprint.sizeMultiplier : 1f, 0.5f, 3f); array2 = array; foreach (Transform val3 in array2) { if (!((Object)(object)val3 == (Object)null)) { bottomY = Mathf.Min(bottomY, val3.position.y - 0.12f * num2); } } return !float.IsPositiveInfinity(bottomY); } private static bool IsUnitCollider(Collider collider) { if ((Object)(object)collider != (Object)null) { return (Object)(object)((Component)collider).GetComponentInParent<Unit>() != (Object)null; } return false; } private static bool IsLiveUnit(Unit unit) { if ((Object)(object)unit != (Object)null && !unit.dead && (Object)(object)unit.data != (Object)null && !unit.data.Dead && (Object)(object)unit.data.mainRig != (Object)null) { return unit.data.health > 0f; } return false; } private static List<RigidbodySnapshot> FreezeRagdollForTeleport(Unit unit) { //IL_004a: Unknown result type (might be due to invalid IL or missing references) //IL_0055: Unknown result type (might be due to invalid IL or missing references) List<RigidbodySnapshot> list = new List<RigidbodySnapshot>(); Rigidbody[] componentsInChildren = ((Component)((Component)unit).transform.root).GetComponentsInChildren<Rigidbody>(true); foreach (Rigidbody val in componentsInChildren) { if (!((Object)(object)val == (Object)null)) { list.Add(new RigidbodySnapshot(val, val.isKinematic, val.detectCollisions)); if (!val.isKinematic) { val.velocity = Vector3.zero; val.angularVelocity = Vector3.zero; } val.detectCollisions = false; val.isKinematic = true; } } return list; } private static void MoveRagdollAsOne(Unit unit, Vector3 delta) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) MoveRagdollAsOne(unit, delta, rotateBodyChildren: true); } private static void MoveRagdollAsOne(Unit unit, Vector3 delta, bool rotateBodyChildren) { //IL_002b: Unknown result type (might be due to invalid IL or missing references) //IL_0030: Unknown result type (might be due to invalid IL or missing references) //IL_0031: 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: 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_00ec: Unknown result type (might be due to invalid IL or missing references) //IL_0113: Unknown result type (might be due to invalid IL or missing references) //IL_012c: Unknown result type (might be due to invalid IL or missing references) //IL_014a: Unknown result type (might be due to invalid IL or missing references) //IL_014f: Unknown result type (might be due to invalid IL or missing references) //IL_017f: 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_0184: 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_0195: Unknown result type (might be due to invalid IL or missing references) //IL_0196: 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_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_01ad: Unknown result type (might be due to invalid IL or missing references) //IL_01b2: Unknown result type (might be due to invalid IL or missing references) //IL_01be: 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_01c4: 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_01d5: Unknown result type (might be due to invalid IL or missing references) //IL_01da: Unknown result type (might be due to invalid IL or missing references) //IL_01e5: Unknown result type (might be due to invalid IL or missing references) //IL_01eb: Unknown result type (might be due to invalid IL or missing references) //IL_01f0: Unknown result type (might be due to invalid IL or missing references) //IL_01f5: Unknown result type (might be due to invalid IL or missing references) Rigidbody[] componentsInChildren = ((Component)((Component)unit).transform.root).GetComponentsInChildren<Rigidbody>(true); HashSet<Transform> hashSet = new HashSet<Transform>(); Rigidbody[] array = componentsInChildren; foreach (Rigidbody val in array) { if (!((Object)(object)val == (Object)null)) { val.position += delta; hashSet.Add(((Component)val).transform); } } if (rotateBodyChildren && (Object)(object)unit.data != (Object)null) { for (int j = 0; j < ((Component)unit.data).transform.childCount; j++) { ((Component)unit.data).transform.GetChild(j).Rotate(Vector3.up * 180f); } } PhysicsFollowBodyPart[] componentsInChildren2 = ((Component)((Component)unit).transform.root).GetComponentsInChildren<PhysicsFollowBodyPart>(true); foreach (PhysicsFollowBodyPart val2 in componentsInChildren2) { if (!((Object)(object)val2 == (Object)null) && !HasMovedRigidbodyParent(((Component)val2).transform, hashSet)) { Transform transform = ((Component)val2).transform; transform.position += delta; } } MoveNonRigidbodyWeapon(unit.WeaponHandler?.rightWeapon, delta, hashSet); MoveNonRigidbodyWeapon(unit.WeaponHandler?.leftWeapon, delta, hashSet); if ((Object)(object)unit.data != (Object)null) { unit.data.currentVelocity = Vector3.zero; unit.data.lastPos = (((Object)(object)unit.data.mainRig != (Object)null) ? unit.data.mainRig.position : Vector3.zero); DataHandler data = unit.data; data.groundPosition += delta; DataHandler data2 = unit.data; data2.groundMapPosition += delta; DataHandler data3 = unit.data; data3.centerOfMass += delta; DataHandler data4 = unit.data; data4.centerOfMassWithoutY += new Vector3(delta.x, 0f, delta.z); } Physics.SyncTransforms(); } private static void SnapFeetToGround(Unit unit, float groundY) { //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) Physics.SyncTransforms(); if (TryGetActualFootBottomY(unit, out var bottomY)) { float num = groundY + 0.08f - bottomY; if (!(Mathf.Abs(num) < 0.005f)) { MoveRagdollAsOne(unit, Vector3.up * num, rotateBodyChildren: false); } } } private static bool HasMovedRigidbodyParent(Transform transform, HashSet<Transform> movedTransforms) { Transform val = transform; while ((Object)(object)val != (Object)null) { if (movedTransforms.Contains(val)) { return true; } val = val.parent; } return false; } private static void MoveNonRigidbodyWeapon(Weapon weapon, Vector3 delta, HashSet<Transform> movedTransforms) { //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_0025: Unknown result type (might be due to invalid IL or missing references) if (!((Object)(object)weapon == (Object)null) && !HasMovedRigidbodyParent(((Component)weapon).transform, movedTransforms)) { Transform transform = ((Component)weapon).transform; transform.position += delta; } } private static void RestoreRagdollAfterTeleport(Unit unit, List<RigidbodySnapshot> snapshots) { //IL_0036: 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_00a0: Unknown result type (might be due to invalid IL or missing references) //IL_00a5: Unknown result type (might be due to invalid IL or missing references) //IL_00bb: Unknown result type (might be due to invalid IL or missing references) //IL_00c0: Unknown result type (might be due to invalid IL or missing references) foreach (RigidbodySnapshot snapshot in snapshots) { Rigidbody rigidbody = snapshot.Rigidbody; if (!((Object)(object)rigidbody == (Object)null)) { rigidbody.isKinematic = snapshot.WasKinematic; if (!snapshot.WasKinematic) { rigidbody.velocity = Vector3.zero; rigidbody.angularVelocity = Vector3.zero; } rigidbody.detectCollisions = snapshot.DetectedCollisions; } } if ((Object)(object)unit != (Object)null && (Object)(object)unit.data != (Object)null && (Object)(object)unit.data.mainRig != (Object)null) { unit.data.currentVelocity = Vector3.zero; unit.data.lastPos = unit.data.mainRig.position; } Physics.SyncTransforms(); } } [HarmonyPatch(typeof(UnitBlueprint), "DeserializedUnit", new Type[] { typeof(SerializedUnitBlueprint), typeof(AssetLoader), typeof(LandfallContentDatabase) })] internal static class AssassinPoofLegacyLoadPatch { private static void Prefix(SerializedUnitBlueprint data, LandfallContentDatabase landfallContentDatabase) { AssassinPoofCompatibility.MigrateLegacyAbility(data, landfallContentDatabase); } } [HarmonyPatch(typeof(UnitBlueprint), "SerializedUnit", new Type[] { typeof(DatabaseID) })] internal static class AssassinPoofVanillaSavePatch { private static void Postfix(SerializedUnitBlueprint __result) { AssassinPoofCompatibility.MigrateLegacyAbility(__result); } } [HarmonyPatch(typeof(AssassinPoofEffect), "Start")] internal static class NativeAssassinPoofStartOverridePatch { private static bool Prefix(AssassinPoofEffect __instance) { return !AssassinPoofCompatibility.TryAttachToSpawnedUnit(__instance); } } [HarmonyPatch(typeof(AssassinPoofEffect), "Update")] internal static class NativeAssassinPoofUpdateOverridePatch { private static bool Prefix(AssassinPoofEffect __instance) { return !AssassinPoofCompatibility.TryAttachToSpawnedUnit(__instance); } } [HarmonyPatch(typeof(AssassinPoofEffect), "DoThePoof")] internal static class NativeAssassinPoofManualOverridePatch { private static bool Prefix(AssassinPoofEffect __instance) { return !AssassinPoofCompatibility.TryAttachToSpawnedUnit(__instance); } } [BepInPlugin("fero.tabs.better_tracing", "Better Tracing", "1.0.1")] [BepInDependency(/*Could not decode attribute arguments.*/)] [BepInDependency(/*Could not decode attribute arguments.*/)] public sealed class BetterTracingPlugin : BaseUnityPlugin { public const string PluginGuid = "fero.tabs.better_tracing"; private const string SettingKey = "Better Tracing"; private ConfigEntry<bool> _enabled; private Harmony _harmony; private SettingsInstance _setting; internal static BetterTracingPlugin Instance { get; private set; } internal static bool IsEnabled() { if ((Object)(object)Instance != (Object)null) { return Instance._enabled?.Value ?? false; } return false; } internal static void LogPluginInfo(string message) { BetterTracingPlugin instance = Instance; if (instance != null) { ((BaseUnityPlugin)instance).Logger.LogInfo((object)message); } } internal static void LogPluginWarning(string message) { BetterTracingPlugin instance = Instance; if (instance != null) { ((BaseUnityPlugin)instance).Logger.LogWarning((object)message); } } private void Awake() { //IL_002d: Unknown result type (might be due to invalid IL or missing references) //IL_0037: Expected O, but got Unknown Instance = this; _enabled = ((BaseUnityPlugin)this).Config.Bind<bool>("Gameplay", "BetterTracing", true, "Help units navigate obstacles and protect fast-moving ragdolls from tunnelling through terrain."); _harmony = new Harmony("fero.tabs.better_tracing"); int num = 0; Type[] types = typeof(BetterTracingPlugin).Assembly.GetTypes(); foreach (Type type in types) { if (type.GetCustomAttributes(typeof(HarmonyPatch), inherit: true).Any()) { try { _harmony.CreateClassProcessor(type).Patch(); num++; } catch (Exception ex) { ((BaseUnityPlugin)this).Logger.LogWarning((object)("Could not patch " + type.Name + ": " + ex.Message)); } } } ((MonoBehaviour)this).StartCoroutine(InjectSettingWhenReady()); ((MonoBehaviour)this).StartCoroutine(InstallRuntimeWhenReady()); SpawnerAbilityRegistry.EnsureRegistered(); ((BaseUnityPlugin)this).Logger.LogInfo((object)$"Better Tracing loaded ({num} patch classes). Personal Assassin Poof: {AssassinPoofCompatibility.PersonalOverrideEnabled}."); } private IEnumerator InstallRuntimeWhenReady() { yield return null; try { TechnicalAbilityRuntime.Install(_harmony); } catch (Exception ex) { ((BaseUnityPlugin)this).Logger.LogWarning((object)("Could not enable optional Technical Items settings: " + ex.Message)); } try { FleeDistanceRuntime.Install(_harmony); ((BaseUnityPlugin)this).Logger.LogInfo((object)"Per-unit Flee Distance stats enabled."); } catch (Exception ex2) { ((BaseUnityPlugin)this).Logger.LogWarning((object)("Could not enable Flee Distance stats: " + ex2.Message)); } try { UnitBehaviourRuntime.Install(_harmony); ((BaseUnityPlugin)this).Logger.LogInfo((object)"Per-unit movement and targeting stats enabled."); } catch (Exception ex3) { ((BaseUnityPlugin)this).Logger.LogWarning((object)("Could not enable movement/targeting stats: " + ex3.Message)); } try { foreach (UnitBlueprint userUnitBlueprint in ContentDatabase.Instance().GetUserUnitBlueprints()) { SavedUnitSelection.RestoreWeaponFile(userUnitBlueprint); } } catch (Exception ex4) { ((BaseUnityPlugin)this).Logger.LogWarning((object)("Could not recover early-loaded weapon settings: " + ex4.Message)); } } private IEnumerator InjectSettingWhenReady() { for (int i = 0; i < 1200; i++) { GlobalSettingsHandler service = ServiceLocator.GetService<GlobalSettingsHandler>(); if ((Object)(object)service != (Object)null) { InjectSetting(service); break; } yield return null; } } internal static void InjectSetting(GlobalSettingsHandler handler) { //IL_0087: Unknown result type (might be due to invalid IL or missing references) //IL_008d: Expected O, but got Unknown //IL_008f: Unknown result type (might be due to invalid IL or missing references) if (!((Object)(object)Instance == (Object)null) && !((Object)(object)handler == (Object)null)) { FieldInfo fieldInfo = AccessTools.Field(typeof(GlobalSettingsHandler), "m_gameplaySettings"); List<SettingsInstance> list = (((SettingsInstance[])fieldInfo.GetValue(handler)) ?? Array.Empty<SettingsInstance>()).ToList(); Instance._setting = ((IEnumerable<SettingsInstance>)list).FirstOrDefault((Func<SettingsInstance, bool>)((SettingsInstance s) => s?.m_settingsKey == "Better Tracing")); if (Instance._setting == null) { BetterTracingPlugin instance = Instance; SettingsInstance val = new SettingsInstance(); val.settingsType = (SettingsType)0; val.options = new string[2] { "On", "Off" }; val.defaultValue = 0; val.m_settingsKey = "Better Tracing"; val.settingName = "Better Tracing"; val.toolTip = "Helps units move around obstacles and prevents fast units from passing through terrain"; instance._setting = val; list.Add(Instance._setting); fieldInfo.SetValue(handler, list.ToArray()); } Instance._setting.currentValue = ((!IsEnabled()) ? 1 : 0); Instance._setting.OnValueChanged -= Instance.SetEnabled; Instance._setting.OnValueChanged += Instance.SetEnabled; if (AccessTools.Field(typeof(GlobalSettingsHandler), "m_settingsDict")?.GetValue(handler) is Dictionary<string, SettingsInstance> dictionary) { dictionary["Better Tracing"] = Instance._setting; } } } private void SetEnabled(int value) { _enabled.Value = value == 0; ((BaseUnityPlugin)this).Config.Save(); } internal static void OnSettingChanged(SettingsInstance setting) { if (setting?.m_settingsKey == "Better Tracing") { Instance?.SetEnabled(setting.currentValue); } } private void OnDestroy() { SpawnerAbilityEditor.CancelIfOpen(); if (_setting != null) { _setting.OnValueChanged -= SetEnabled; } Harmony harmony = _harmony; if (harmony != null) { harmony.UnpatchSelf(); } TracingGeometry.ReleaseQueryCollider(); FormationUI.ReleaseAssets(); Instance = null; } } [HarmonyPatch(typeof(GlobalSettingsHandler), "Init", new Type[] { typeof(bool) })] internal static class BetterTracingSettingsInitPatch { private static void Postfix(GlobalSettingsHandler __instance) { BetterTracingPlugin.InjectSetting(__instance); } } [HarmonyPatch(typeof(MenuSettingsButton), "UpdateValue", new Type[] { typeof(int) })] internal static class BetterTracingSettingsValuePatch { private static void Postfix(MenuSettingsButton __instance) { BetterTracingPlugin.OnSettingChanged((__instance != null) ? __instance.settingsInstance : null); } } internal sealed class CompanionUnitSession { internal readonly FormationMember Member; internal readonly UnitBlueprint Source; private readonly UnitFormation _formation; private readonly DatabaseID _parent; private readonly DatabaseID _unit; private string _copy; private string _stats; private string _abilities; private string _equipment; internal CompanionUnitSession(UnitFormation formation, int index, DatabaseID parent) { //IL_0059: Unknown result type (might be due to invalid IL or missing references) //IL_005a: Unknown result type (might be due to invalid IL or missing references) //IL_0066: 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) if (formation?.units == null || index < 0 || index >= formation.units.Count || formation.units[index] == null) { throw new ArgumentException("This added unit is no longer available."); } _formation = formation; Member = formation.units[index]; _parent = parent; _unit = Member.unit; Source = UnitFormationData.ResolveMember(Member); UnitBlueprint source = Source; if (((source != null) ? source.Entity : null) == null || (Object)(object)Source.UnitBase == (Object)null) { throw new InvalidOperationException("This added unit is unavailable."); } Remember(); } internal bool Allows(UnitBlueprint unit) { //IL_001e: Unknown result type (might be due to invalid IL or missing references) if (((unit != null) ? unit.Entity : null) != null && (Object)(object)unit.UnitBase != (Object)null) { return !UnitFormationData.WouldCreateCycle(unit, _parent); } return false; } internal bool Save(UnitFormation current, UnitBlueprint edited) { //IL_0032: 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) if (current == _formation) { List<FormationMember> units = current.units; if (units != null && units.Contains(Member) && !(Member.unit != _unit) && !(Member.copyJson != _copy) && !(Member.statsJson != _stats) && !(Member.abilitiesJson != _abilities) && !(Member.equipmentJson != _equipment) && Allows(edited)) { string equipmentJson = JsonUtility.ToJson((object)new SerializedFormationEquipment { fullUnit = true, recipe = RiderRecipe.Capture(edited) }); Member.equipmentJson = equipmentJson; Member.abilitiesJson = null; UnitFormationStats.Commit(Member, null); FormationEquipmentData.Invalidate(Member); Remember(); return true; } } return false; } private void Remember() { _copy = Member.copyJson; _stats = Member.statsJson; _abilities = Member.abilitiesJson; _equipment = Member.equipmentJson; } } internal sealed class EditorTestCycle { private int _start = -10; private int _stop = -10; internal bool Start(bool testing, int frame) { if (testing || frame == _start || frame <= _stop + 1) { return false; } _start = frame; return true; } internal bool Stop(bool testing, int frame) { if (!testing || frame == _stop) { return false; } _stop = frame; return true; } } [StructLayout(LayoutKind.Sequential, Size = 1)] public struct MeleeDistanceMovement : IMovementComponent, IComponentData { } internal static class ExtraStatsCompatibility { internal static string MovementTypeName(string savedTypeName) { if (string.IsNullOrWhiteSpace(savedTypeName)) { return savedTypeName; } int num = savedTypeName.IndexOf(','); if (num < 0 || !string.Equals(savedTypeName.Substring(0, num).Trim(), typeof(MeleeDistanceMovement).FullName, StringComparison.Ordinal)) { return savedTypeName; } return typeof(MeleeDistanceMovement).AssemblyQualifiedName; } } internal sealed class FactionBarRecovery : MonoBehaviour { private static readonly FieldInfo Bar = AccessTools.Field(typeof(PlacementUI), "factionBar"); private static readonly FieldInfo Buttons = AccessTools.Field(typeof(PlacementFactionBar), "factionButtons"); private static readonly FieldInfo SelectedFaction = AccessTools.Field(typeof(PlacementUI), "m_selectedFaction"); private static readonly FieldInfo SelectedUnit = AccessTools.Field(typeof(PlacementUI), "m_lastSelectedUnit"); private static readonly FieldInfo UnitLayout = AccessTools.Field(typeof(PlacementUI), "unitLayoutGroup"); private static readonly FieldInfo Follow = AccessTools.Field(typeof(FactionButton), "lerpTargetTransform"); private static readonly FieldInfo Velocity = AccessTools.Field(typeof(FactionButtonPhlerp), "velocity"); private static readonly FieldInfo SpringTarget = AccessTools.Field(typeof(FactionButtonPhlerp), "target"); private PlacementUI _owner; private PlacementFactionBar _bar; private DatabaseID[] _expected = Array.Empty<DatabaseID>(); private DatabaseID _selectedFaction; private DatabaseID _selectedUnit; private bool _known; private bool _pending; private bool _redraw; private bool _repairing; private bool _restore; private int _frame; private int _spawning; private int _attempts; private List<FactionButton> Current => Buttons.GetValue(_bar) as List<FactionButton>; internal static FactionBarRecovery Of(PlacementUI owner) { PlacementFactionBar val = (PlacementFactionBar)(((Object)(object)owner == (Object)null) ? null : /*isinst with value type is only supported in some contexts*/); if ((Object)(object)val == (Object)null) { return null; } FactionBarRecovery component = ((Component)val).GetComponent<FactionBarRecovery>(); if ((Object)(object)component != (Object)null) { return component; } component = ((Component)val).gameObject.AddComponent<FactionBarRecovery>(); component._owner = owner; component._bar = val; val.OnFactionBarChanged = (Action)Delegate.Combine(val.OnFactionBarChanged, new Action(component.SelectionChanged)); return component; } private static FactionBarRecovery Of(PlacementFactionBar bar) { if ((Object)(object)bar == (Object)null) { return null; } FactionBarRecovery component = ((Component)bar).GetComponent<FactionBarRecovery>(); if ((Object)(object)component != (Object)null) { return component; } return Of(((IEnumerable<PlacementUI>)((Component)bar).GetComponentsInParent<PlacementUI>(true)).FirstOrDefault((Func<PlacementUI, bool>)delegate(PlacementUI ui) { object? value = Bar.GetValue(ui); return (Object)((value is PlacementFactionBar) ? value : null) == (Object)(object)bar; })); } internal static bool BeforeRedraw(PlacementUI owner) { FactionBarRecovery factionBarRecovery = Of(owner); if ((Object)(object)factionBarRecovery == (Object)null || factionBarRecovery._repairing) { return true; } factionBarRecovery.Queue(); if (((Behaviour)factionBarRecovery._bar).isActiveAndEnabled) { return true; } factionBarRecovery.RememberSelection(); factionBarRecovery._redraw = true; return false; } internal static void CheckAfterReturn(PlacementUI owner) { Of(owner)?.Queue(); } internal static FactionBarRecovery BeforeSpawn(PlacementFactionBar bar, ref Faction[] factions) { FactionBarRecovery factionBarRecovery = Of(bar); if ((Object)(object)factionBarRecovery == (Object)null) { return null; } GameModeService service = ServiceLocator.GetService<GameModeService>(); bool online = ((service != null) ? service.CurrentGameMode : null) is OnlineMultiplayerGameMode; Faction[] array = ((IEnumerable<Faction>)((online ? ((object)ContentDatabase.Instance().GetDefaultHotbarFactions().ToArray()) : ((object)factions)) ?? Array.Empty<Faction>())).Where((Faction faction) => Renderable(faction) && (!online || (!faction.IsCustom && !faction.IsModFaction))).ToArray(); factionBarRecovery._expected = array.Select((Faction faction) => faction.Entity.GUID).ToArray(); factionBarRecovery._known = true; if (!online) { factions = array; } factionBarRecovery._spawning++; return factionBarRecovery; } private static bool Renderable(Faction faction) { if ((Object)(object)faction != (Object)null && faction.Entity != null && faction.Units != null) { return faction.Units.All((UnitBlueprint unit) => (Object)(object)unit != (Object)null && !unit.HasMissingComponents); } return false; } internal void AfterSpawn() { _spawning = Math.Max(0, _spawning - 1); if (!_repairing) { Queue(); } } private void SelectionChanged() { if (_spawning != 0 || _repairing) { return; } _expected = (from button in (Current ?? new List<FactionButton>()).Where(delegate(FactionButton button) { if ((Object)(object)button != (Object)null) { Faction faction = button.faction; return ((faction != null) ? faction.Entity : null) != null; } return false; }) select button.faction.Entity.GUID).ToArray(); _known = true; Queue(); } private void Queue() { _pending = true; _frame = Time.frameCount + 2; _attempts = 0; } private void RememberSelection() { //IL_0042: Unknown result type (might be due to invalid IL or missing references) //IL_004f: Unknown result type (might be due to invalid IL or missing references) //IL_0054: Unknown result type (might be due to invalid IL or missing references) //IL_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) if (!_restore) { object? value = SelectedFaction.GetValue(_owner); object? obj = ((value is Faction) ? value : null); DatabaseID? obj2; if (obj == null) { obj2 = null; } else { DatabaseEntity entity = ((Faction)obj).Entity; obj2 = ((entity != null) ? new DatabaseID?(entity.GUID) : ((DatabaseID?)null)); } DatabaseID? val = obj2; _selectedFaction = val.GetValueOrDefault(); _selectedUnit = (DatabaseID)SelectedUnit.GetValue(_owner); _restore = true; } } private static bool Finite(Vector3 value) { //IL_0000: 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_001a: Unknown result type (might be due to invalid IL or missing references) if (Finite(value.x) && Finite(value.y)) { return Finite(value.z); } return false; } private static bool Finite(float value) { if (!float.IsNaN(value)) { return !float.IsInfinity(value); } return false; } private bool RepairButtons() { //IL_005d: 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_00b8: Unknown result type (might be due to invalid IL or missing references) //IL_00f5: Unknown result type (might be due to invalid IL or missing references) //IL_01bb: Unknown result type (might be due to invalid IL or missing references) //IL_01db: Unknown result type (might be due to invalid IL or missing references) //IL_0202: Unknown result type (might be due to invalid IL or missing references) //IL_010a: 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_013a: Unknown result type (might be due to invalid IL or missing references) //IL_0140: Unknown result type (might be due to invalid IL or missing references) //IL_0145: Unknown result type (might be due to invalid IL or missing references) //IL_014a: Unknown result type (might be due to invalid IL or missing references) //IL_0179: Unknown result type (might be due to invalid IL or missing references) List<FactionButton> current = Current; if (!_known) { return true; } if (current == null || current.Count != _expected.Length) { return false; } for (int i = 0; i < current.Count; i++) { FactionButton val = current[i]; if (!((Object)(object)val == (Object)null)) { Faction faction = val.faction; if (((faction != null) ? faction.Entity : null) != null && !(val.faction.Entity.GUID != _expected[i]) && !((Object)(object)((Component)val).transform.parent != (Object)(object)_bar.RealObjectParent)) { Transform followTransform = val.GetFollowTransform(); if ((Object)(object)followTransform == (Object)null || !followTransform.IsChildOf(_bar.FollowTransformParent) || !Finite(followTransform.position)) { return false; } BindIcon(val); FactionButtonPhlerp component = ((Component)val).GetComponent<FactionButtonPhlerp>(); if (((Component)val).gameObject.activeSelf && ((Behaviour)val).enabled && Finite(((Component)val).transform.position) && Finite(((Component)val).transform.localScale)) { Vector3 val2 = ((Component)val).transform.localScale; if (!(((Vector3)(ref val2)).sqrMagnitude < 0.0001f)) { val2 = ((Component)val).transform.position - followTransform.position; if (!(((Vector3)(ref val2)).sqrMagnitude > 4096f) && !((Object)(object)component == (Object)null) && ((Behaviour)component).enabled && Finite((Vector3)Velocity.GetValue(component)) && !((Object)/*isinst with value type is only supported in some contexts*/ != (Object)(object)followTransform)) { continue; } } } ((Component)val).gameObject.SetActive(true); ((Behaviour)val).enabled = true; ((Component)val).transform.position = followTransform.position; ((Component)val).transform.localScale = _bar.prefab.transform.localScale; Follow.SetValue(val, followTransform); val.SetupPhlerp(); Velocity.SetValue(((Component)val).GetComponent<FactionButtonPhlerp>(), Vector3.zero); continue; } } return false; } return true; } private static void BindIcon(FactionButton button) { Faction faction = button.faction; faction.Entity.GetSpriteIconAsync((Action<Sprite>)delegate(Sprite sprite) { if (!((Object)(object)button == (Object)null) && !((Object)(object)button.faction != (Object)(object)faction) && !((Object)(object)button.m_Image == (Object)null) && !((Object)(object)sprite == (Object)null)) { button.m_Image.sprite = sprite; ((Behaviour)button.m_Image).enabled = true; } }); } private void RestoreSelection() { //IL_0048: 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_0094: Unknown result type (might be due to invalid IL or missing references) if (!_restore) { return; } _restore = false; FactionButton val = Current?.FirstOrDefault((Func<FactionButton, bool>)delegate(FactionButton item) { //IL_0032: 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_0043: 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) if ((Object)(object)item != (Object)null) { Faction faction = item.faction; DatabaseID? obj2; if (faction == null) { obj2 = null; } else { DatabaseEntity entity = faction.Entity; obj2 = ((entity != null) ? new DatabaseID?(entity.GUID) : ((DatabaseID?)null)); } DatabaseID? val3 = obj2; DatabaseID selectedFaction = _selectedFaction; if (!val3.HasValue) { return false; } return val3.GetValueOrDefault() == selectedFaction; } return false; }); if (!((Object)(object)val == (Object)null) && ((SimpleButton)val).Unlocked) { _owner.SelectFaction(_selectedFaction, val); object? value = UnitLayout.GetValue(_owner); object? obj = ((value is UILayoutGroup) ? value : null); UnitButton val2 = ((obj != null) ? ((UILayoutGroup)obj).GetUnitButton(_selectedUnit) : null); if ((Object)(object)val2 != (Object)null && ((SimpleButton)val2).Unlocked) { _owner.SelectUnit(_selectedUnit, val2); } } } private void LateUpdate() { //IL_0057: Unknown result type (might be due to invalid IL or missing references) //IL_005d: Invalid comparison between Unknown and I4 if (!_pending || (Object)(object)_owner == (Object)null || (Object)(object)_bar == (Object)null || Time.frameCount < _frame || !((UIComponentBase)_owner).IsActive || !((Behaviour)_bar).isActiveAndEnabled) { return; } GameStateManager service = ServiceLocator.GetService<GameStateManager>(); if (service == null || (int)service.GameState > 0) { return; } try { Canvas.ForceUpdateCanvases(); if (_redraw || !RepairButtons()) { if (++_attempts > 3) { _pending = false; BetterTracingPlugin.LogPluginWarning("Faction bar could not finish rebuilding; saved faction choices were preserved."); return; } RememberSelection(); _repairing = true; try { _owner.RedrawFactions(); _redraw = false; } finally { _repairing = false; } _frame = Time.frameCount + 2; } else { RestoreSelection(); _pending = false; } } catch (Exception ex) { _repairing = false; _frame = Time.frameCount + 2; if (++_attempts > 3) { _pending = false; BetterTracingPlugin.LogPluginWarning("Could not restore the faction bar: " + ex.Message); } } } private void OnDestroy() { if ((Object)(object)_bar != (Object)null) { PlacementFactionBar bar = _bar; bar.OnFactionBarChanged = (Action)Delegate.Remove(bar.OnFactionBarChanged, new Action(SelectionChanged)); } } } [HarmonyPatch(typeof(PlacementUI), "RedrawFactions")] internal static class FactionBarRedrawPatch { private static bool Prefix(PlacementUI __instance) { return FactionBarRecovery.BeforeRedraw(__instance); } } [HarmonyPatch(typeof(PlacementUI), "EnterPlacementState")] internal static class FactionBarReturnPatch { private static void Postfix(PlacementUI __instance) { FactionBarRecovery.CheckAfterReturn(__instance); } } [HarmonyPatch(typeof(PlacementUI), "OnOpen")] internal static class FactionBarOpenPatch { private static void Postfix(PlacementUI __instance) { FactionBarRecovery.CheckAfterReturn(__instance); } } [HarmonyPatch(typeof(PlacementFactionBar), "Spawn", new Type[] { typeof(Faction[]), typeof(bool) })] internal static class FactionBarSpawnPatch { private static void Prefix(PlacementFactionBar __instance, ref Faction[] factions, out FactionBarRecovery __state) { __state = FactionBarRecovery.BeforeSpawn(__instance, ref factions); } private static Exception Finalizer(FactionBarRecovery __state, Exception __exception) { __state?.AfterSpawn(); return __exception; } } [DefaultExecutionOrder(12000)] internal sealed class FastUnitCollisionGuard : MonoBehaviour { private sealed class Body { internal Rigidbody Rig; internal Collider Collider; internal bool HasPrevious; internal Vector3 PreviousCenter; internal float PreviousSpeed; internal bool Core; } private readonly List<Body> _bodies = new List<Body>(); private readonly RaycastHit[] _hits = (RaycastHit[])(object)new RaycastHit[48]; private Unit _unit; private Rigidbody[] _rigs; private Vector3[] _positions; internal void Initialize(Unit unit) { ResetSweep(); _unit = unit; _bodies.Clear(); if ((Object)(object)unit == (Object)null) { return; } _rigs = ((Component)unit).GetComponentsInChildren<Rigidbody>(true); _positions = (Vector3[])(object)new Vector3[_rigs.Length]; Rigidbody[] rigs = _rigs; foreach (Rigidbody val in rigs) { if ((Object)(object)val == (Object)null || (Object)(object)((Component)val).GetComponentInParent<Unit>() != (Object)(object)unit || (Object)(object)((Component)val).GetComponentInParent<Holdable>() != (Object)null) { continue; } Collider val2 = null; Collider[] componentsInChildren = ((Component)val).GetComponentsInChildren<Collider>(true); foreach (Collider val3 in componentsInChildren) { if (!((Object)(object)val3.attachedRigidbody != (Object)(object)val) && !val3.isTrigger && (val3 is SphereCollider || val3 is CapsuleCollider || val3 is BoxCollider)) { val2 = val3; break; } } if (!((Object)(object)val2 == (Object)null)) { _bodies.Add(new Body { Rig = val, Collider = val2, Core = ((Object)(object)val == (Object)(object)unit.data?.mainRig || (Object)(object)((Component)val).transform == (Object)(object)unit.data?.torso || (Object)(object)((Component)val).transform == (Object)(object)unit.data?.head) }); } } } private void FixedUpdate() { //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_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_0295: Unknown result type (might be due to invalid IL or missing references) //IL_029e: Unknown result type (might be due to invalid IL or missing references) //IL_029f: Unknown result type (might be due to invalid IL or missing references) //IL_009d: Unknown result type (might be due to invalid IL or missing references) //IL_00a2: Unknown result type (might be due to invalid IL or missing references) //IL_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_00b4: 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_00bd: Unknown result type (might be due to invalid IL or missing references) //IL_00c2: Unknown result type (might be due to invalid IL or missing references) //IL_00c4: 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_00d2: Unknown result type (might be due to invalid IL or missing references) //IL_00fc: Unknown result type (might be due to invalid IL or missing references) //IL_0101: Unknown result type (might be due to invalid IL or missing references) //IL_0126: Unknown result type (might be due to invalid IL or missing references) //IL_012b: Unknown result type (might be due to invalid IL or missing references) //IL_0147: Unknown result type (might be due to invalid IL or missing references) //IL_014b: Unknown result type (might be due to invalid IL or missing references) //IL_0150: Unknown result type (might be due to invalid IL or missing references) //IL_0155: Unknown result type (might be due to invalid IL or missing references) //IL_0162: Unknown result type (might be due to invalid IL or missing references) //IL_0169: 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_0321: Unknown result type (might be due to invalid IL or missing references) //IL_0326: Unknown result type (might be due to invalid IL or missing references) //IL_032a: Unknown result type (might be due to invalid IL or missing references) //IL_032f: Unknown result type (might be due to invalid IL or missing references) //IL_033d: Unknown result type (might be due to invalid IL or missing references) //IL_0342: Unknown result type (might be due to invalid IL or missing references) //IL_0199: Unknown result type (might be due to invalid IL or missing references) //IL_01a0: Unknown result type (might be due to invalid IL or missing references) //IL_01a4: Unknown result type (might be due to invalid IL or missing references) //IL_01d0: Unknown result type (might be due to invalid IL or missing references) //IL_01d5: Unknown result type (might be due to invalid IL or missing references) //IL_0202: Unknown result type (might be due to invalid IL or missing references) //IL_0207: Unknown result type (might be due to invalid IL or missing references) //IL_020b: Unknown result type (might be due to invalid IL or missing references) //IL_0212: Unknown result type (might be due to invalid IL or missing references) //IL_023f: Unknown result type (might be due to invalid IL or missing references) //IL_0244: Unknown result type (might be due to invalid IL or missing references) //IL_0248: Unknown result type (might be due to invalid IL or missing references) //IL_024d: Unknown result type (might be due to invalid IL or missing references) //IL_0252: Unknown result type (might be due to invalid IL or missing references) //IL_0254: Unknown result type (might be due to invalid IL or missing references) //IL_0259: Unknown result type (might be due to invalid IL or missing references) //IL_025c: Unknown result type (might be due to invalid IL or missing references) //IL_0261: Unknown result type (might be due to invalid IL or missing references) if (!BetterTracingPlugin.IsEnabled() || !TracingGeometry.IsLocallyControlled(_unit)) { ResetSweep(); return; } float num = 1f; Vector3 val = Vector3.zero; Vector3 normal = Vector3.zero; Bounds bounds; Vector3 velocity; foreach (Body body in _bodies) { Rigidbody rig = body.Rig; if ((Object)(object)rig == (Object)null || (Object)(object)body.Collider == (Object)null || !body.Collider.enabled || rig.isKinematic || !rig.detectCollisions) { body.HasPrevious = false; continue; } bounds = body.Collider.bounds; Vector3 center = ((Bounds)(ref bounds)).center; bounds = body.Collider.bounds; Vector3 extents = ((Bounds)(ref bounds)).extents; float num2 = Mathf.Clamp(Mathf.Min(extents.x, Mathf.Min(extents.y, extents.z)) * 0.75f, 0.035f, 0.75f); velocity = rig.velocity; float magnitude = ((Vector3)(ref velocity)).magnitude; if (!body.Core || !body.HasPrevious || !IsPhysicalStep(body.PreviousCenter, center, body.PreviousSpeed, magnitude, Time.fixedDeltaTime, num2)) { continue; } Vector3 val2 = center - body.PreviousCenter; float magnitude2 = ((Vector3)(ref val2)).magnitude; int num3 = Physics.SphereCastNonAlloc(body.PreviousCenter, num2, val2 / magnitude2, _hits, magnitude2, -1, (QueryTriggerInteraction)1); RaycastHit[] array = ((num3 == _hits.Length) ? Physics.SphereCastAll(body.PreviousCenter, num2, val2 / magnitude2, magnitude2, -1, (QueryTriggerInteraction)1) : _hits); if (array != _hits) { num3 = array.Length; } for (int i = 0; i < num3; i++) { RaycastHit val3 = array[i]; if (TracingGeometry.IsEnvironment(((RaycastHit)(ref val3)).collider, _unit, body.Collider) && !(((RaycastHit)(ref val3)).distance <= 0.001f) && CrossedSurface(body.PreviousCenter, center, ((RaycastHit)(ref val3)).point, ((RaycastHit)(ref val3)).normal)) { float num4 = Mathf.Clamp01((((RaycastHit)(ref val3)).distance - 0.02f) / magnitude2); if (!(num4 >= num)) { num = num4; val = body.PreviousCenter + val2 * num4 - center; normal = ((RaycastHit)(ref val3)).normal; } } } } if (num < 1f && TracingGeometry.IsFinite(val)) { RecoverRagdoll(val, normal); } foreach (Body body2 in _bodies) { body2.HasPrevious = (Object)(object)body2.Rig != (Object)null && (Object)(object)body2.Collider != (Object)null && body2.Collider.enabled && !body2.Rig.isKinematic && body2.Rig.detectCollisions; if (body2.HasPrevious) { bounds = body2.Collider.bounds; body2.PreviousCenter = ((Bounds)(ref bounds)).center; velocity = body2.Rig.velocity; body2.PreviousSpeed = ((Vector3)(ref velocity)).magnitude; } } } internal static bool IsPhysicalStep(Vector3 previous, Vector3 current, float previousSpeed, float currentSpeed, float deltaTime, float radius) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0008: Unknown result type (might be due to invalid IL or missing references) //IL_003b: 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_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) if (!TracingGeometry.IsFinite(previous) || !TracingGeometry.IsFinite(current) || float.IsNaN(previousSpeed) || float.IsInfinity(previousSpeed) || float.IsNaN(currentSpeed) || float.IsInfinity(currentSpeed) || deltaTime <= 0f) { return false; } Vector3 val = current - previous; float magnitude = ((Vector3)(ref val)).magnitude; float num = Mathf.Max(previousSpeed, currentSpeed) * deltaTime * 2f + 0.35f; if (magnitude > Mathf.Max(0.04f, radius * 0.5f)) { return magnitude <= num; } return false; } internal static bool CrossedSurface(Vector3 previous, Vector3 current, Vector3 point, Vector3 normal) { //IL_000e: Unknown result type (might be due to invalid IL or missing references) //IL_000f: Unknown result type (might be due to invalid IL or missing references) //IL_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_0022: Unknown result type (might be due to invalid IL or missing references) //IL_0023: Unknown result type (might be due to invalid IL or missing references) //IL_0024: Unknown result type (might be due to invalid IL or missing references) //IL_0029: Unknown result type (might be due to invalid IL or missing references) if (((Vector3)(ref normal)).sqrMagnitude > 0.5f && Vector3.Dot(previous - point, normal) > 0.01f) { return Vector3.Dot(current - point, normal) < -0.01f; } return false; } internal static Vector3 RemoveInwardVelocity(Vector3 velocity, Vector3 normal) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0012: Unknown result type (might be due to invalid IL or missing references) //IL_0013: Unknown result type (might be due to invalid IL or missing references) //IL_0015: 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_0010: Unknown result type (might be due to invalid IL or missing references) float num = Vector3.Dot(velocity, normal); if (!(num < 0f)) { return velocity; } return velocity - normal * num; } private void RecoverRagdoll(Vector3 correction, Vector3 normal) { //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_004e: 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) //IL_0089: Unknown result type (might be due to invalid IL or missing references) //IL_008e: Unknown result type (might be due to invalid IL or missing references) //IL_008f: 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_00a8: 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) for (int i = 0; i < _rigs.Length; i++) { if ((Object)(object)_rigs[i] != (Object)null) { _positions[i] = _rigs[i].position; } } Transform transform = ((Component)_unit).transform; transform.position += correction; for (int j = 0; j < _rigs.Length; j++) { Rigidbody val = _rigs[j]; if (!((Object)(object)val == (Object)null) && !((Object)(object)((Component)val).GetComponentInParent<Unit>() != (Object)(object)_unit)) { val.position = _positions[j] + correction; if (!val.isKinematic) { val.velocity = RemoveInwardVelocity(val.velocity, normal); } } } Physics.SyncTransforms(); } private void ResetSweep() { foreach (Body body in _bodies) { body.HasPrevious = false; } } private void OnDisable() { ResetSweep(); } private void OnDestroy() { ResetSweep(); } } internal sealed class FleeDistanceEditorData { internal FleeDistanceSettings Settings; internal float DefaultDistance; internal FleeDistanceSettings Defaults => new FleeDistanceSettings { distance = DefaultDistance }; internal FleeDistanceSettings Effective => Settings?.Clone() ?? Defaults; } internal static class FleeDistanceData { internal const string JsonKey = "betterTracingFleeDistance"; private static readonly ConditionalWeakTable<UnitBlueprint, FleeDistanceSettings> Blueprints = new ConditionalWeakTable<UnitBlueprint, FleeDistanceSettings>(); private static readonly ConditionalWeakTable<UnitEditorManager, FleeDistanceEditorData> Editors = new ConditionalWeakTable<UnitEditorManager, FleeDistanceEditorData>(); private static readonly ConditionalWeakTable<SerializedUnitBlueprint, FleeDistanceSettings> Serialized = new ConditionalWeakTable<SerializedUnitBlueprint, FleeDistanceSettings>(); [ThreadStatic] private static FleeDistanceSettings s_snapshot; [ThreadStatic] private static DatabaseID s_snapshotId; internal static bool HasFlee(UnitBlueprint unit) { if (unit == null) { return false; } return unit.MovementComponents?.Any((IMovementComponent component) => component is FleeDistance) == true; } internal static float NativeDistance(IEnumerable<IMovementComponent> components) { return (from component in components?.OfType<FleeDistance>() select component.Value).FirstOrDefault() ?? 0f; } internal static bool Selected(UnitEditorManager manager) { if ((Object)(object)manager == (Object)null) { return false; } int num = (int)(AccessTools.Field(typeof(UnitEditorManager), "currentMovementType")?.GetValue(manager) ?? ((object)(-1))); if (manager?.MovementTypesComponents != null && num >= 0 && num < manager.MovementTypesComponents.Count) { return manager.MovementTypesComponents[num] is FleeDistance; } return false; } internal static FleeDistanceEditorData ForEditor(UnitEditorManager manager) { return Editors.GetValue(manager, (UnitEditorManager owner) => new FleeDistanceEditorData { DefaultDistance = NativeDistance(owner.MovementTypesComponents) }); } internal static FleeDistanceSettings Get(UnitBlueprint unit) { if (!((Object)(object)unit != (Object)null) || !Blueprints.TryGetValue(unit, out var value)) { return null; } return value; } internal static void Set(UnitBlueprint unit, FleeDistanceSettings data) { if ((Object)(object)unit == (Object)null) { return; } Blueprints.Remove(unit); if (data != null && HasFlee(unit)) { data = data.Clone(); Blueprints.Add(unit, data); unit.MovementComponents = unit.MovementComponents.Select((IMovementComponent component) => (IMovementComponent)((!(component is FleeDistance)) ? component : ((object)new FleeDistance { Value = data.distance }))).ToList(); } } internal static void Copy(UnitBlueprint unit, UnitBlueprint source) { Set(unit, Get(source)); } internal static void LoadEditor(UnitEditorManager manager, UnitBlueprint unit) { Editors.Remove(manager); Editors.Add(manager, new FleeDistanceEditorData { Settings = Get(unit)?.Clone(), DefaultDistance = NativeDistance(manager.MovementTypesComponents) }); if (Get(unit) == null && HasFlee(unit)) { ForEditor(manager).Settings = new FleeDistanceSettings { distance = NativeDistance(unit.MovementComponents) }; } } internal static void ClearEditor(UnitEditorManager manager) { Editors.Remove(manager); } internal static void EditorBlueprint(UnitEditorManager manager, UnitBlueprint unit) { Set(unit, Selected(manager) ? ForEditor(manager).Settings : null); } internal static void CaptureSerialized(UnitBlueprint unit, SerializedUnitBlueprint serialized) { //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) s_snapshot = null; if (serialized != null) { Serialized.Remove(serialized); FleeDistanceSettings fleeDistanceSettings = Get(unit); if (fleeDistanceSettings != null) { Serialized.Add(serialized, fleeDistanceSettings.Clone()); s_snapshot = fleeDistanceSettings.Clone(); s_snapshotId = serialized.m_id; } } } internal static void ExtendJson(object value, ref string json) { //IL_0024: Unknown result type (might be due to invalid IL or missing references) //IL_0029: Unknown result type (might be due to invalid IL or missing references) SerializedUnitBlueprint val = (SerializedUnitBlueprint)((value is SerializedUnitBlueprint) ? value : null); if (val != null && !string.IsNullOrEmpty(json)) { if (!Serialized.TryGetValue(val, out var value2) && val.m_id == s_snapshotId) { value2 = s_snapshot; } s_snapshot = null; int num = json.LastIndexOf('}'); if (value2 != null && num >= 0) { json = json.Substring(0, num).TrimEnd(Array.Empty<char>()) + ",\n\"betterTracingFleeDistance\":" + JsonUtility.ToJson((object)value2) + "\n}"; } } } internal static void ReadJson(string json, object value) { SerializedUnitBlueprint val = (SerializedUnitBlueprint)((value is SerializedUnitBlueprint) ? value : null); if (val == null) { return; } Serialized.Remove(val); try { string text = UnitFormationData.ExtractPayload(json, "betterTracingFleeDistance"); FleeDistanceSettings fleeDistanceSettings = (string.IsNullOrEmpty(text) ? null : JsonUtility.FromJson<FleeDistanceSettings>(text)); if (fleeDistanceSettings != null && fleeDistanceSettings.version == 1) { Serialized.Add(val, fleeDistanceSettings.Clone()); } } catch (Exception ex) { BetterTracingPlugin.LogPluginWarning("Could not read Flee Distance settings: " + ex.Message); } } internal static void RestoreSerialized(SerializedUnitBlueprint serialized, UnitBlueprint unit) { Set(unit, (serialized != null && Serialized.TryGetValue(serialized, out var value)) ? value : null); } internal static void RestoreFileJson(UnitBlueprint unit, string json) { //IL_003f: 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) if (((unit != null) ? unit.Entity : null) != null && Get(unit) == null && HasFlee(unit) && !string.IsNullOrEmpty(json) && UnitFormationData.ExtractPayload(json, "betterTracingFleeDistance") != null) { SerializedUnitBlueprint val = JsonUtility.FromJson<SerializedUnitBlueprint>(json); if (val != null && !(val.m_id != unit.Entity.GUID)) { ReadJson(json, val); RestoreSerialized(val, unit); } } } } internal sealed class FleeDistanceEditor : MonoBehaviour { internal UnitEditorManager Manager; internal FleeDistanceStatsPage Page; private UnitEditorUnitPage _owner; private Button _movement; private Button _button; private Canvas _canvas; private CanvasGroup _group; private CanvasGroup[] _parents; private Mask[] _masks; private RectMask2D[] _rectMasks; private FormationUI _ui; private readonly Vector3[] _corners = (Vector3[])(object)new Vector3[4]; internal static FleeDistanceEditor Of(UnitEditorManager manager) { if (!((Object)(object)manager == (Object)null)) { return ((Component)manager).GetComponent<FleeDistanceEditor>(); } return null; } internal static void Ensure(UnitEditorBasePageUI page) { //IL_023a: Unknown result type (might be due to invalid IL or missing references) //IL_0253: Expected O, but got Unknown //IL_02bd: Unknown result type (might be due to invalid IL or missing references) //IL_02cf: Unknown result type (might be due to invalid IL or missing references) //IL_02e1: Unknown result type (might be due to invalid IL or missing references) //IL_0301: Unknown result type (might be due to invalid IL or missing references) //IL_031c: Unknown result type (might be due to invalid IL or missing references) //IL_0350: Unknown result type (might be due to invalid IL or missing references) //IL_035f: Unknown result type (might be due to invalid IL or missing references) //IL_0374: Unknown result type (might be due to invalid IL or missing references) //IL_0383: Unknown result type (might be due to invalid IL or missing references) //IL_0281: Unknown result type (might be due to invalid IL or missing references) //IL_028f: Unknown result type (might be due to invalid IL or missing references) UnitEditorUnitPage componentInParent = ((Component)page).GetComponentInParent<UnitEditorUnitPage>(); UnitEditorManager val = componentInParent?.manager ?? Object.FindObjectOfType<UnitEditorManager>(); if ((Object)(object)val == (Object)null || (Object)(object)componentInParent == (Object)null) { return; } FleeDistanceEditor fleeDistanceEditor = Of(val) ?? ((Component)val).gameObject.AddComponent<FleeDistanceEditor>(); fleeDistanceEditor.Manager = val; if ((Object)(object)fleeDistanceEditor._button != (Object)null && (Object)(object)fleeDistanceEditor._owner == (Object)(object)componentInParent) { return; } object? obj = AccessTools.Field(typeof(UnitEditorBasePageUI), "movementType")?.GetValue(page); UnitEditorSelectableItem val2 = (UnitEditorSelectableItem)((obj is UnitEditorSelectableItem) ? obj : null); Button val3 = (Button)(((Object)(object)val2 == (Object)null) ? null : /*isinst with value type is only supported in some contexts*/); TabbedUIPage[] obj2 = AccessTools.Field(typeof(TabbedUIComponent), "TABS")?.GetValue(componentInParent) as TabbedUIPage[]; object obj3; if (obj2 == null) { obj3 = null; } else { TabbedUIPage? obj4 = ((IEnumerable<TabbedUIPage>)obj2).FirstOrDefault((Func<TabbedUIPage, bool>)((TabbedUIPage tab) => tab.tabSubMenu is UnitEditorStatsPageUI)); if (obj4 == null) { obj3 = null; } else { Toggle toggleTab = obj4.toggleTab; obj3 = ((toggleTab != null) ? ((IEnumerable<Image>)((Component)toggleTab).GetComponentsInChildren<Image>(true)).FirstOrDefault((Func<Image, bool>)((Image image) => ((Object)image).name == "Icon" && (Object)(object)image.sprite != (Object)null)) : null); } } Image val4 = (Image)obj3; if ((Object)(object)val3 == (Object)null || (Object)(object)val4 == (Object)null) { return; } if ((Object)(object)fleeDistanceEditor._button != (Object)null) { Object.Destroy((Object)(object)((Component)fleeDistanceEditor._button).gameObject); } fleeDistanceEditor._owner = componentInParent; fleeDistanceEditor._movement = val3; fleeDistanceEditor._canvas = ((Component)val3).GetComponentInParent<Canvas>(); if (!((Object)(object)fleeDistanceEditor._canvas == (Object)null)) { fleeDistanceEditor._parents = ((Component)val3).GetComponentsInParent<CanvasGroup>(true); fleeDistanceEditor._masks = ((Component)val3).GetComponentsInParent<Mask>(true); fleeDistanceEditor._rectMasks = ((Component)val3).GetComponentsInParent<RectMask2D>(true); Graphic targetGraphic = ((Selectable)val3).targetGraphic; Image val5 = (Image)(object)((targetGraphic is Image) ? targetGraphic : null); fleeDistanceEditor._ui = new FormationUI(((Component)componentInParent).GetComponentInChildren<TMP_Text>(true), (val5 != null) ? val5.sprite : null, ((Component)val3).GetComponent<UISounds>()); fleeDistanceEditor._button = fleeDistanceEditor._ui.Button("Flee Distance stats", ((Component)fleeDistanceEditor._canvas.rootCanvas).transform, "", new UnityAction(fleeDistanceEditor.Show)); Image component = ((Component)fleeDistanceEditor._button).GetComponent<Image>(); if ((Object)(object)val5 != (Object)null) { component.sprite = val5.sprite; component.type = val5.type; ((Graphic)component).color = ((Graphic)val5).color; ((Graphic)component).material = ((Graphic)val5).material; component.pixelsPerUnitMultiplier = val5.pixelsPerUnitMultiplier; } ((Selectable)fleeDistanceEditor._button).colors = ((Selectable)val3).colors; ((Selectable)fleeDistanceEditor._button).transition = ((Selectable)val3).transition; ((Selectable)fleeDistanceEditor._button).spriteState = ((Selectable)val3).spriteState; Image obj5 = fleeDistanceEditor._ui.Panel("Stats icon", ((Component)fleeDistanceEditor._button).transform, Color.white, rounded: false); obj5.sprite = val4.sprite; obj5.type = val4.type; ((Graphic)obj5).material = ((Graphic)val4).material; obj5.preserveAspect = true; ((Graphic)obj5).raycastTarget = false; FormationUI.Stretch(((Graphic)obj5).rectTransform, new Vector2(16f, 16f), new Vector2(-16f, -16f)); ((RectTransform)((Component)fleeDistanceEditor._button).transform).pivot = new Vector2(1f, 0.5f); fleeDistanceEditor._group = ((Component)fleeDistanceEditor._button).gameObject.AddComponent<CanvasGroup>(); ((Component)fleeDistanceEditor._button).gameObject.AddComponent<LayoutElement>().ignoreLayout = true; ((Component)fleeDistanceEditor._button).gameObject.SetActive(false); } } private Rect Bounds(RectTransform target, Transform parent) { //IL_0014: Unknown result type (might be due to invalid IL