Please disclose if any significant portion of your mod was created using AI tools by adding the 'AI Generated' category. Failing to do so may result in the mod being removed from Thunderstore.
Decompiled source of EnemyOrbMerge v4.0.0
EnemyOrbMerge.dll
Decompiled a month agousing System; using System.Collections; using System.Collections.Generic; using System.Diagnostics; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using System.Security; using System.Security.Permissions; using BepInEx; using BepInEx.Configuration; using HarmonyLib; using Microsoft.CodeAnalysis; using Photon.Pun; using UnityEngine; using UnityEngine.SceneManagement; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)] [assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")] [assembly: IgnoresAccessChecksTo("")] [assembly: AssemblyCompany("REPOJP")] [assembly: AssemblyConfiguration("Debug")] [assembly: AssemblyFileVersion("1.0.0.0")] [assembly: AssemblyInformationalVersion("1.0.0")] [assembly: AssemblyProduct("zabuMod")] [assembly: AssemblyTitle("zabuMod")] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("1.0.0.0")] [module: UnverifiableCode] [module: RefSafetyRules(11)] namespace Microsoft.CodeAnalysis { [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] internal sealed class EmbeddedAttribute : Attribute { } } namespace System.Runtime.CompilerServices { [CompilerGenerated] [Microsoft.CodeAnalysis.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 REPOJP.EnemyOrbMerge { [BepInPlugin("REPOJP.EnemyOrbMerge", "EnemyOrbMerge", "4.0.0")] public sealed class EnemyOrbMergePlugin : BaseUnityPlugin { private struct PendingPair { public readonly int FirstId; public readonly int SecondId; public readonly ulong Key; public PendingPair(int firstId, int secondId, ulong key) { FirstId = firstId; SecondId = secondId; Key = key; } } private sealed class OrbEntry { public readonly EnemyValuable EnemyValuable; public readonly ValuableObject ValuableObject; public readonly PhysGrabObject PhysGrabObject; public readonly PhysGrabObjectImpactDetector ImpactDetector; public readonly PhotonView PhotonView; public readonly GameObject GameObject; public readonly int Id; public readonly int SortToken; public readonly float RegisteredTime; public readonly List<Collider> Colliders = new List<Collider>(); public int MergeCount; public float NextMergeAllowedTime; public float InvincibilityEffectEndTime; public float NextInvincibilityEffectRefreshTime; public Bounds CachedBounds; public bool HasCachedBounds; public float CachedRadius; private OrbEntry(EnemyValuable enemyValuable) { //IL_00d5: Unknown result type (might be due to invalid IL or missing references) EnemyValuable = enemyValuable; GameObject = ((Component)enemyValuable).gameObject; ValuableObject = ((Component)enemyValuable).GetComponent<ValuableObject>(); PhysGrabObject = ((Component)enemyValuable).GetComponent<PhysGrabObject>(); ImpactDetector = ((Component)enemyValuable).GetComponent<PhysGrabObjectImpactDetector>(); PhotonView = ((Component)enemyValuable).GetComponent<PhotonView>(); Id = (((Object)(object)PhotonView != (Object)null && PhotonView.ViewID > 0) ? PhotonView.ViewID : ((Object)GameObject).GetInstanceID()); SortToken = Id; RegisteredTime = Time.time; MergeCount = 0; NextMergeAllowedTime = 0f; InvincibilityEffectEndTime = 0f; NextInvincibilityEffectRefreshTime = 0f; CachedBounds = default(Bounds); HasCachedBounds = false; CachedRadius = 0f; RefreshColliders(); UpdateCachedBounds(); } public static OrbEntry Create(EnemyValuable enemyValuable) { if ((Object)(object)enemyValuable == (Object)null) { return null; } ValuableObject component = ((Component)enemyValuable).GetComponent<ValuableObject>(); PhysGrabObject component2 = ((Component)enemyValuable).GetComponent<PhysGrabObject>(); if ((Object)(object)component == (Object)null || (Object)(object)component2 == (Object)null) { return null; } return new OrbEntry(enemyValuable); } public void RefreshColliders() { Colliders.Clear(); if ((Object)(object)GameObject == (Object)null) { return; } Collider[] componentsInChildren = GameObject.GetComponentsInChildren<Collider>(true); foreach (Collider val in componentsInChildren) { if (IsColliderUsable(val)) { Colliders.Add(val); } } } public void UpdateCachedBounds() { //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_0045: Unknown result type (might be due to invalid IL or missing references) //IL_004a: Unknown result type (might be due to invalid IL or missing references) //IL_0028: Unknown result type (might be due to invalid IL or missing references) HasCachedBounds = TryGetCombinedBounds(Colliders, out var bounds); if (!HasCachedBounds) { CachedBounds = default(Bounds); CachedRadius = 0f; } else { CachedBounds = bounds; Vector3 extents = ((Bounds)(ref bounds)).extents; CachedRadius = ((Vector3)(ref extents)).magnitude; } } public string Describe() { string text = (((Object)(object)GameObject != (Object)null) ? ((Object)GameObject).name : "null"); return text + "#" + Id + "(mergeCount=" + MergeCount + ")"; } } [HarmonyPatch(typeof(EnemyValuable), "Start")] private static class EnemyValuableStartPatch { private static void Postfix(EnemyValuable __instance) { EnemyOrbMergePlugin instance = Instance; if (!((Object)(object)instance == (Object)null)) { instance.RegisterEnemyOrb(__instance); } } } [HarmonyPatch(typeof(PhysGrabObjectImpactDetector), "OnCollisionStay")] private static class PhysGrabObjectImpactDetectorOnCollisionStayPatch { private static bool Prefix(PhysGrabObjectImpactDetector __instance, Collision collision) { EnemyOrbMergePlugin instance = Instance; if ((Object)(object)instance == (Object)null) { return true; } if (instance.ShouldIgnoreOrbToOrbBreak(__instance, collision)) { instance.LogDebug("Queued orb-to-orb merge pair"); return false; } return true; } } public const string PluginGuid = "REPOJP.EnemyOrbMerge"; public const string PluginName = "EnemyOrbMerge"; public const string PluginVersion = "4.0.0"; internal static EnemyOrbMergePlugin Instance; private static readonly FieldInfo ValuableCurrentField = AccessTools.Field(typeof(ValuableObject), "dollarValueCurrent"); private static readonly FieldInfo ValuableOriginalField = AccessTools.Field(typeof(ValuableObject), "dollarValueOriginal"); private static readonly FieldInfo ValuableSetField = AccessTools.Field(typeof(ValuableObject), "dollarValueSet"); private static readonly FieldInfo EnemyValuableIndestructibleTimerField = AccessTools.Field(typeof(EnemyValuable), "indestructibleTimer"); private static readonly FieldInfo EnemyValuableIndestructibleLerpField = AccessTools.Field(typeof(EnemyValuable), "indestructibleLerp"); private static readonly FieldInfo EnemyValuableOuterMaterialField = AccessTools.Field(typeof(EnemyValuable), "outerMaterial"); private static readonly FieldInfo ImpactDetectorIndestructibleSpawnTimerField = AccessTools.Field(typeof(PhysGrabObjectImpactDetector), "indestructibleSpawnTimer"); private static readonly FieldInfo ImpactDetectorIsIndestructibleField = AccessTools.Field(typeof(PhysGrabObjectImpactDetector), "isIndestructible"); private Harmony harmony; private ConfigEntry<float> mergeCheckInterval; private ConfigEntry<float> mergeArmDelay; private ConfigEntry<float> remergeCooldown; private ConfigEntry<float> contactSkin; private ConfigEntry<int> maxOrbValue; private ConfigEntry<int> maxOrbMergeCount; private ConfigEntry<int> maxQueuedPairsPerTick; private ConfigEntry<float> fallbackPairScanInterval; private ConfigEntry<float> indestructibleTargetCacheInterval; private ConfigEntry<bool> enableFallbackPairScan; private ConfigEntry<bool> debugLog; private ConfigEntry<bool> playNetworkMergeEffect; private ConfigEntry<bool> playInvincibilityElectricityEffect; private readonly Dictionary<int, OrbEntry> trackedOrbs = new Dictionary<int, OrbEntry>(); private readonly HashSet<int> busyOrbIds = new HashSet<int>(); private readonly List<int> removeBuffer = new List<int>(); private readonly List<OrbEntry> scanBuffer = new List<OrbEntry>(); private readonly Queue<PendingPair> pendingPairQueue = new Queue<PendingPair>(32); private readonly HashSet<ulong> pendingPairKeys = new HashSet<ulong>(); private readonly HashSet<PhysGrabObject> indestructibleTargets = new HashSet<PhysGrabObject>(); private float mergeCheckTimer; private float rescanTimer; private float fallbackPairScanTimer; private float nextIndestructibleTargetCacheRefreshTime; private Type itemOrbIndestructibleType; private Type itemOrbType; private Type itemDroneIndestructibleType; private Type itemDroneType; private FieldInfo itemOrbIndestructibleItemOrbField; private FieldInfo itemOrbItemActiveField; private FieldInfo itemOrbObjectAffectedField; private FieldInfo itemDroneIndestructibleItemDroneField; private FieldInfo itemDroneItemActivatedField; private FieldInfo itemDroneMagnetActiveField; private FieldInfo itemDroneMagnetTargetPhysGrabObjectField; private void Awake() { //IL_0043: Unknown result type (might be due to invalid IL or missing references) //IL_004d: Expected O, but got Unknown try { Instance = this; ((Component)this).transform.parent = null; ((Object)((Component)this).gameObject).hideFlags = (HideFlags)61; Object.DontDestroyOnLoad((Object)(object)((Component)this).gameObject); BindConfig(); CacheIndestructibleReflection(); harmony = new Harmony("REPOJP.EnemyOrbMerge"); harmony.PatchAll(); SceneManager.sceneLoaded += OnSceneLoaded; ResetTrackingState(); LogInfo("Plugin loaded v4.0.0"); } catch (Exception ex) { ((BaseUnityPlugin)this).Logger.LogError((object)("Awake failed\n" + ex)); } } private void OnDestroy() { if ((Object)(object)Instance == (Object)(object)this) { Instance = null; } try { SceneManager.sceneLoaded -= OnSceneLoaded; } catch { } if (harmony != null) { harmony.UnpatchSelf(); harmony = null; } } private void BindConfig() { //IL_0030: Unknown result type (might be due to invalid IL or missing references) //IL_003a: Expected O, but got Unknown //IL_006e: Unknown result type (might be due to invalid IL or missing references) //IL_0078: Expected O, but got Unknown //IL_00ac: Unknown result type (might be due to invalid IL or missing references) //IL_00b6: Expected O, but got Unknown //IL_00ea: Unknown result type (might be due to invalid IL or missing references) //IL_00f4: Expected O, but got Unknown //IL_0120: Unknown result type (might be due to invalid IL or missing references) //IL_012a: Expected O, but got Unknown //IL_0156: Unknown result type (might be due to invalid IL or missing references) //IL_0160: Expected O, but got Unknown //IL_0189: Unknown result type (might be due to invalid IL or missing references) //IL_0193: Expected O, but got Unknown //IL_01e8: Unknown result type (might be due to invalid IL or missing references) //IL_01f2: Expected O, but got Unknown //IL_0226: Unknown result type (might be due to invalid IL or missing references) //IL_0230: Expected O, but got Unknown mergeCheckInterval = ((BaseUnityPlugin)this).Config.Bind<float>("General", "MergeCheckInterval", 0.05f, new ConfigDescription("Interval in seconds for processing queued orb merge contacts.接触済みオーブのマージ処理間隔", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0.01f, 1f), Array.Empty<object>())); mergeArmDelay = ((BaseUnityPlugin)this).Config.Bind<float>("General", "MergeArmDelay", 0.2f, new ConfigDescription("Delay in seconds after orb spawn before merge checks begin.オーブ生成後にマージ判定を開始するまでの待機秒数", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 10f), Array.Empty<object>())); remergeCooldown = ((BaseUnityPlugin)this).Config.Bind<float>("General", "ReMergeCooldown", 0.05f, new ConfigDescription("Cooldown in seconds before a merged orb can merge again.マージ後のオーブが再度マージ可能になるまでの待機秒数", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 10f), Array.Empty<object>())); contactSkin = ((BaseUnityPlugin)this).Config.Bind<float>("General", "ContactSkin", 0.02f, new ConfigDescription("Extra contact distance used only by fallback pair scan.フォールバック全ペア判定時のみ使う接触余裕距離", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0.001f, 0.5f), Array.Empty<object>())); maxOrbValue = ((BaseUnityPlugin)this).Config.Bind<int>("General", "MaxOrbValue", 0, new ConfigDescription("Maximum merged orb value. 0 = unlimited.マージ後オーブの金額上限 0 = 無制限", (AcceptableValueBase)(object)new AcceptableValueRange<int>(0, 1000000), Array.Empty<object>())); maxOrbMergeCount = ((BaseUnityPlugin)this).Config.Bind<int>("General", "MaxOrbMergeCount", 0, new ConfigDescription("Maximum number of successful merges allowed per orb lineage. 0 = unlimited.オーブ系統ごとの成功マージ回数上限 0 = 無制限", (AcceptableValueBase)(object)new AcceptableValueRange<int>(0, 1000), Array.Empty<object>())); maxQueuedPairsPerTick = ((BaseUnityPlugin)this).Config.Bind<int>("Performance", "MaxQueuedPairsPerTick", 8, new ConfigDescription("Maximum queued orb contact pairs processed per tick. 1 tickあたりの接触ペア処理上限", (AcceptableValueBase)(object)new AcceptableValueRange<int>(1, 64), Array.Empty<object>())); enableFallbackPairScan = ((BaseUnityPlugin)this).Config.Bind<bool>("Performance", "EnableFallbackPairScan", true, "Enable a slow fallback pair scan for rare cases where collision callbacks do not enqueue contact pairs.接触イベントが入らない稀な状況用の低頻度全ペア判定"); fallbackPairScanInterval = ((BaseUnityPlugin)this).Config.Bind<float>("Performance", "FallbackPairScanInterval", 0.5f, new ConfigDescription("Fallback all-pair scan interval seconds. Lower values are heavier.フォールバック全ペア判定間隔 秒数が小さいほど重い", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0.1f, 5f), Array.Empty<object>())); indestructibleTargetCacheInterval = ((BaseUnityPlugin)this).Config.Bind<float>("Performance", "IndestructibleTargetCacheInterval", 0.15f, new ConfigDescription("Interval seconds for refreshing indestructible orb/drone target cache.不滅オーブ/ドローン対象キャッシュ更新間隔", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0.05f, 2f), Array.Empty<object>())); debugLog = ((BaseUnityPlugin)this).Config.Bind<bool>("Debug", "DebugLog", false, "Enable debug logging.デバッグログ出力"); playNetworkMergeEffect = ((BaseUnityPlugin)this).Config.Bind<bool>("Effect", "PlayNetworkMergeEffect", true, "Play a built-in network visible impact effect at merge position.マージ位置で既存のネットワーク可視衝突エフェクトを再生"); playInvincibilityElectricityEffect = ((BaseUnityPlugin)this).Config.Bind<bool>("Effect", "PlayInvincibilityElectricityEffect", true, "Play built-in death pit electricity visuals while merged orb invincibility is active.マージ後無敵中に既存の穴落下ビリビリ演出を再生"); } private void CacheIndestructibleReflection() { itemOrbIndestructibleType = AccessTools.TypeByName("ItemOrbIndestructible"); itemOrbType = AccessTools.TypeByName("ItemOrb"); if (itemOrbIndestructibleType != null) { itemOrbIndestructibleItemOrbField = AccessTools.Field(itemOrbIndestructibleType, "itemOrb"); } if (itemOrbType != null) { itemOrbItemActiveField = AccessTools.Field(itemOrbType, "itemActive"); itemOrbObjectAffectedField = AccessTools.Field(itemOrbType, "objectAffected"); } itemDroneIndestructibleType = AccessTools.TypeByName("ItemDroneIndestructible"); itemDroneType = AccessTools.TypeByName("ItemDrone"); if (itemDroneIndestructibleType != null) { itemDroneIndestructibleItemDroneField = AccessTools.Field(itemDroneIndestructibleType, "itemDrone"); } if (itemDroneType != null) { itemDroneItemActivatedField = AccessTools.Field(itemDroneType, "itemActivated"); itemDroneMagnetActiveField = AccessTools.Field(itemDroneType, "magnetActive"); itemDroneMagnetTargetPhysGrabObjectField = AccessTools.Field(itemDroneType, "magnetTargetPhysGrabObject"); } } private void OnSceneLoaded(Scene scene, LoadSceneMode mode) { ResetTrackingState(); } private void Update() { if (CanRunLogic()) { UpdateInvincibilityElectricityEffects(); if (rescanTimer > 0f) { rescanTimer -= Time.deltaTime; } else { rescanTimer = 1f; RescanSceneOrbs(); CleanupTrackedOrbs(); } if (mergeCheckTimer > 0f) { mergeCheckTimer -= Time.deltaTime; return; } mergeCheckTimer = Mathf.Max(0.01f, mergeCheckInterval.Value); ProcessOrbMerges(); } } internal void RegisterEnemyOrb(EnemyValuable enemyValuable) { if (CanTrackEnemyOrb(enemyValuable)) { OrbEntry orbEntry = OrbEntry.Create(enemyValuable); if (orbEntry != null && !trackedOrbs.ContainsKey(orbEntry.Id)) { trackedOrbs.Add(orbEntry.Id, orbEntry); LogDebug("Tracked orb added: " + orbEntry.Describe()); } } } internal bool ShouldIgnoreOrbToOrbBreak(PhysGrabObjectImpactDetector selfDetector, Collision collision) { if (!CanRunLogic()) { return false; } EnemyValuable enemyValuableFromDetector = GetEnemyValuableFromDetector(selfDetector); if ((Object)(object)enemyValuableFromDetector == (Object)null) { return false; } PhysGrabObjectImpactDetector impactDetectorFromCollision = GetImpactDetectorFromCollision(collision); EnemyValuable enemyValuableFromDetector2 = GetEnemyValuableFromDetector(impactDetectorFromCollision); if ((Object)(object)enemyValuableFromDetector2 == (Object)null) { return false; } if ((Object)(object)enemyValuableFromDetector == (Object)(object)enemyValuableFromDetector2) { return false; } if (!CanTrackEnemyOrb(enemyValuableFromDetector) || !CanTrackEnemyOrb(enemyValuableFromDetector2)) { return false; } RegisterEnemyOrb(enemyValuableFromDetector); RegisterEnemyOrb(enemyValuableFromDetector2); EnqueueContactPair(enemyValuableFromDetector, enemyValuableFromDetector2); return true; } private bool CanRunLogic() { if ((Object)(object)GameManager.instance == (Object)null) { return false; } return SemiFunc.IsMasterClientOrSingleplayer(); } private void ResetTrackingState() { trackedOrbs.Clear(); busyOrbIds.Clear(); removeBuffer.Clear(); scanBuffer.Clear(); pendingPairQueue.Clear(); pendingPairKeys.Clear(); indestructibleTargets.Clear(); mergeCheckTimer = 0f; rescanTimer = 0f; fallbackPairScanTimer = 0f; nextIndestructibleTargetCacheRefreshTime = 0f; } private void RescanSceneOrbs() { EnemyValuable[] array = Object.FindObjectsOfType<EnemyValuable>(true); for (int i = 0; i < array.Length; i++) { RegisterEnemyOrb(array[i]); } } private void CleanupTrackedOrbs() { removeBuffer.Clear(); foreach (KeyValuePair<int, OrbEntry> trackedOrb in trackedOrbs) { if (!IsEntryValid(trackedOrb.Value)) { removeBuffer.Add(trackedOrb.Key); } } for (int i = 0; i < removeBuffer.Count; i++) { int num = removeBuffer[i]; trackedOrbs.Remove(num); busyOrbIds.Remove(num); } } private void ProcessOrbMerges() { CleanupTrackedOrbs(); RefreshIndestructibleTargetCacheIfNeeded(); int num = Mathf.Clamp(maxQueuedPairsPerTick.Value, 1, 64); int num2 = 0; while (pendingPairQueue.Count > 0 && num2 < num) { PendingPair pendingPair = pendingPairQueue.Dequeue(); pendingPairKeys.Remove(pendingPair.Key); num2++; if (!trackedOrbs.TryGetValue(pendingPair.FirstId, out var value) || !trackedOrbs.TryGetValue(pendingPair.SecondId, out var value2) || !IsEntryReady(value) || !IsEntryReady(value2) || !TryMerge(value, value2)) { continue; } return; } if (enableFallbackPairScan.Value) { if (fallbackPairScanTimer > 0f) { fallbackPairScanTimer -= Mathf.Max(0.01f, mergeCheckInterval.Value); return; } fallbackPairScanTimer = Mathf.Max(0.1f, fallbackPairScanInterval.Value); ProcessFallbackPairScan(); } } private void ProcessFallbackPairScan() { scanBuffer.Clear(); foreach (KeyValuePair<int, OrbEntry> trackedOrb in trackedOrbs) { OrbEntry value = trackedOrb.Value; if (IsEntryReady(value)) { value.UpdateCachedBounds(); scanBuffer.Add(value); } } for (int i = 0; i < scanBuffer.Count; i++) { OrbEntry orbEntry = scanBuffer[i]; if (!IsEntryReady(orbEntry)) { continue; } for (int j = i + 1; j < scanBuffer.Count; j++) { OrbEntry orbEntry2 = scanBuffer[j]; if (IsEntryReady(orbEntry2) && AreOrbsTouchingFallback(orbEntry, orbEntry2) && TryMerge(orbEntry, orbEntry2)) { return; } } } } private void EnqueueContactPair(EnemyValuable firstEnemyValuable, EnemyValuable secondEnemyValuable) { OrbEntry trackedEntry = GetTrackedEntry(firstEnemyValuable); OrbEntry trackedEntry2 = GetTrackedEntry(secondEnemyValuable); if (trackedEntry != null && trackedEntry2 != null && trackedEntry.Id != trackedEntry2.Id) { ulong num = BuildPairKey(trackedEntry.Id, trackedEntry2.Id); if (!pendingPairKeys.Contains(num)) { pendingPairKeys.Add(num); pendingPairQueue.Enqueue(new PendingPair(trackedEntry.Id, trackedEntry2.Id, num)); } } } private OrbEntry GetTrackedEntry(EnemyValuable enemyValuable) { if ((Object)(object)enemyValuable == (Object)null) { return null; } OrbEntry orbEntry = OrbEntry.Create(enemyValuable); if (orbEntry == null) { return null; } if (trackedOrbs.TryGetValue(orbEntry.Id, out var value)) { return value; } trackedOrbs.Add(orbEntry.Id, orbEntry); return orbEntry; } private static ulong BuildPairKey(int firstId, int secondId) { uint num = (uint)Mathf.Min(firstId, secondId); uint num2 = (uint)Mathf.Max(firstId, secondId); return ((ulong)num << 32) | num2; } private bool TryMerge(OrbEntry first, OrbEntry second) { //IL_01f9: Unknown result type (might be due to invalid IL or missing references) //IL_01fe: Unknown result type (might be due to invalid IL or missing references) //IL_0217: Unknown result type (might be due to invalid IL or missing references) if (!IsEntryValid(first) || !IsEntryValid(second)) { return false; } if (busyOrbIds.Contains(first.Id) || busyOrbIds.Contains(second.Id)) { return false; } int num = Mathf.Max(0, Mathf.FloorToInt(GetDollarValueCurrent(first.ValuableObject))); int num2 = Mathf.Max(0, Mathf.FloorToInt(GetDollarValueCurrent(second.ValuableObject))); int mergedValue = num + num2; int num3 = Mathf.Max(first.MergeCount, second.MergeCount) + 1; if (IsMergeBlockedByMaxValue(num, num2, mergedValue)) { ApplyBlockedInvincibility(first, second); LogDebug("Merge blocked by max value: first=" + first.Describe() + " second=" + second.Describe() + " mergedValue=" + mergedValue + " max=" + GetConfiguredMaxOrbValue()); return true; } if (IsMergeBlockedByMaxMergeCount(first.MergeCount, second.MergeCount, num3)) { ApplyBlockedInvincibility(first, second); LogDebug("Merge blocked by max merge count: first=" + first.Describe() + " second=" + second.Describe() + " mergedCount=" + num3 + " max=" + GetConfiguredMaxOrbMergeCount()); return true; } OrbEntry orbEntry = SelectWinner(first, second); OrbEntry orbEntry2 = ((orbEntry.Id == first.Id) ? second : first); busyOrbIds.Add(orbEntry.Id); busyOrbIds.Add(orbEntry2.Id); try { Vector3 mergeEffectPosition = GetMergeEffectPosition(orbEntry, orbEntry2); ApplyMergedValue(orbEntry, mergedValue); ReapplyVanillaEnemyOrbInvincibility(orbEntry, allowElectricityEffect: true); PlayMergeEffects(orbEntry, mergeEffectPosition); ZeroOutLocalValue(orbEntry2); RemoveLoserFromDollarHaulList(orbEntry2); DestroyLoser(orbEntry2); trackedOrbs.Remove(orbEntry2.Id); indestructibleTargets.Remove(orbEntry2.PhysGrabObject); orbEntry.MergeCount = num3; orbEntry.NextMergeAllowedTime = Time.time + Mathf.Max(0f, remergeCooldown.Value); LogDebug("Merged orbs: winner=" + orbEntry.Describe() + " loser=" + orbEntry2.Describe() + " mergedValue=" + mergedValue + " mergedCount=" + num3); return true; } catch (Exception ex) { ((BaseUnityPlugin)this).Logger.LogError((object)("Merge failed\n" + ex)); return false; } finally { busyOrbIds.Remove(orbEntry2.Id); busyOrbIds.Remove(orbEntry.Id); } } private OrbEntry SelectWinner(OrbEntry first, OrbEntry second) { bool flag = IsIndestructibleEffectTarget(first); bool flag2 = IsIndestructibleEffectTarget(second); if (flag != flag2) { return flag ? first : second; } bool flag3 = IsHeldByAnyPlayer(first); bool flag4 = IsHeldByAnyPlayer(second); if (flag3 != flag4) { return flag3 ? first : second; } float dollarValueCurrent = GetDollarValueCurrent(first.ValuableObject); float dollarValueCurrent2 = GetDollarValueCurrent(second.ValuableObject); if (dollarValueCurrent > dollarValueCurrent2) { return first; } if (dollarValueCurrent2 > dollarValueCurrent) { return second; } return (first.SortToken <= second.SortToken) ? first : second; } private bool IsIndestructibleEffectTarget(OrbEntry entry) { if (entry == null || (Object)(object)entry.PhysGrabObject == (Object)null) { return false; } if (indestructibleTargets.Contains(entry.PhysGrabObject)) { return true; } if ((Object)(object)entry.ImpactDetector != (Object)null && GetBoolField(ImpactDetectorIsIndestructibleField, entry.ImpactDetector, defaultValue: false)) { return true; } return false; } private void RefreshIndestructibleTargetCacheIfNeeded() { if (!(Time.time < nextIndestructibleTargetCacheRefreshTime)) { nextIndestructibleTargetCacheRefreshTime = Time.time + Mathf.Max(0.05f, indestructibleTargetCacheInterval.Value); indestructibleTargets.Clear(); CacheIndestructibleOrbTargets(); CacheIndestructibleDroneTargets(); } } private void CacheIndestructibleOrbTargets() { if (itemOrbIndestructibleType == null || itemOrbType == null || itemOrbItemActiveField == null || itemOrbObjectAffectedField == null) { return; } Object[] array = Object.FindObjectsOfType(itemOrbIndestructibleType); foreach (Object obj in array) { Component val = (Component)(object)((obj is Component) ? obj : null); if ((Object)(object)val == (Object)null || !val.gameObject.activeInHierarchy) { continue; } object obj2 = null; try { if (itemOrbIndestructibleItemOrbField != null) { obj2 = itemOrbIndestructibleItemOrbField.GetValue(val); } if (obj2 == null) { obj2 = val.GetComponent(itemOrbType); } } catch { obj2 = null; } if (obj2 == null) { continue; } try { object value = itemOrbItemActiveField.GetValue(obj2); if (!(value is bool) || !(bool)value) { continue; } object value2 = itemOrbObjectAffectedField.GetValue(obj2); if (!(value2 is IEnumerable enumerable)) { continue; } foreach (object item in enumerable) { PhysGrabObject val2 = (PhysGrabObject)((item is PhysGrabObject) ? item : null); if ((Object)(object)val2 != (Object)null) { indestructibleTargets.Add(val2); } } } catch { } } } private void CacheIndestructibleDroneTargets() { if (itemDroneIndestructibleType == null || itemDroneType == null || itemDroneItemActivatedField == null || itemDroneMagnetActiveField == null || itemDroneMagnetTargetPhysGrabObjectField == null) { return; } Object[] array = Object.FindObjectsOfType(itemDroneIndestructibleType); foreach (Object obj in array) { Component val = (Component)(object)((obj is Component) ? obj : null); if ((Object)(object)val == (Object)null || !val.gameObject.activeInHierarchy) { continue; } object obj2 = null; try { if (itemDroneIndestructibleItemDroneField != null) { obj2 = itemDroneIndestructibleItemDroneField.GetValue(val); } if (obj2 == null) { obj2 = val.GetComponent(itemDroneType); } } catch { obj2 = null; } if (obj2 == null) { continue; } try { object value = itemDroneItemActivatedField.GetValue(obj2); object value2 = itemDroneMagnetActiveField.GetValue(obj2); if (value is bool && (bool)value && value2 is bool && (bool)value2) { object value3 = itemDroneMagnetTargetPhysGrabObjectField.GetValue(obj2); PhysGrabObject val2 = (PhysGrabObject)((value3 is PhysGrabObject) ? value3 : null); if ((Object)(object)val2 != (Object)null) { indestructibleTargets.Add(val2); } } } catch { } } } private void ApplyMergedValue(OrbEntry winner, int mergedValue) { float num = Mathf.Max(0, mergedValue); SetDollarValuesLocal(winner.ValuableObject, num); if (SemiFunc.IsMultiplayer()) { PhotonView photonView = winner.PhotonView; if ((Object)(object)photonView != (Object)null) { photonView.RPC("DollarValueSetRPC", (RpcTarget)3, new object[1] { num }); } } } private void ReapplyVanillaEnemyOrbInvincibility(OrbEntry winner, bool allowElectricityEffect) { try { if (winner != null && !((Object)(object)winner.EnemyValuable == (Object)null) && !((Object)(object)winner.ImpactDetector == (Object)null)) { EnemyValuable enemyValuable = winner.EnemyValuable; PhysGrabObjectImpactDetector impactDetector = winner.ImpactDetector; impactDetector.destroyDisable = true; SetImpactDetectorIndestructibleSpawnTimer(impactDetector, 0.1f); if ((Object)(object)winner.PhysGrabObject != (Object)null) { winner.PhysGrabObject.OverrideIndestructible(0.1f); } if (EnemyValuableIndestructibleTimerField != null) { EnemyValuableIndestructibleTimerField.SetValue(enemyValuable, 5f); } if (EnemyValuableIndestructibleLerpField != null) { EnemyValuableIndestructibleLerpField.SetValue(enemyValuable, 0f); } ApplyEnemyOrbIndestructibleVisuals(enemyValuable); if (allowElectricityEffect) { BeginInvincibilityElectricityEffect(winner); } else if (winner != null) { winner.InvincibilityEffectEndTime = 0f; winner.NextInvincibilityEffectRefreshTime = 0f; } } } catch (Exception ex) { ((BaseUnityPlugin)this).Logger.LogError((object)("ReapplyVanillaEnemyOrbInvincibility failed\n" + ex)); } } private void BeginInvincibilityElectricityEffect(OrbEntry winner) { if (!playInvincibilityElectricityEffect.Value) { if (winner != null) { winner.InvincibilityEffectEndTime = 0f; winner.NextInvincibilityEffectRefreshTime = 0f; } } else if (winner != null) { winner.InvincibilityEffectEndTime = Time.time + 5f; winner.NextInvincibilityEffectRefreshTime = 0f; RefreshInvincibilityElectricityEffect(winner); } } private void UpdateInvincibilityElectricityEffects() { if (!playInvincibilityElectricityEffect.Value) { return; } foreach (OrbEntry value in trackedOrbs.Values) { if (value != null && !(value.InvincibilityEffectEndTime <= Time.time) && !(value.NextInvincibilityEffectRefreshTime > Time.time)) { RefreshInvincibilityElectricityEffect(value); } } } private void RefreshInvincibilityElectricityEffect(OrbEntry entry) { try { if (IsEntryValid(entry) && !((Object)(object)entry.PhysGrabObject == (Object)null)) { entry.PhysGrabObject.DeathPitEffectCreate(); entry.NextInvincibilityEffectRefreshTime = Time.time + 2.4f; } } catch (Exception ex) { ((BaseUnityPlugin)this).Logger.LogError((object)("RefreshInvincibilityElectricityEffect failed\n" + ex)); } } private static void SetImpactDetectorIndestructibleSpawnTimer(PhysGrabObjectImpactDetector impactDetector, float seconds) { if (!((Object)(object)impactDetector == (Object)null) && !(ImpactDetectorIndestructibleSpawnTimerField == null)) { ImpactDetectorIndestructibleSpawnTimerField.SetValue(impactDetector, Mathf.Max(0f, seconds)); } } private static void ApplyEnemyOrbIndestructibleVisuals(EnemyValuable enemyValuable) { //IL_004d: Unknown result type (might be due to invalid IL or missing references) if (!((Object)(object)enemyValuable == (Object)null)) { Material enemyOrbOuterMaterial = GetEnemyOrbOuterMaterial(enemyValuable); if (!((Object)(object)enemyOrbOuterMaterial == (Object)null)) { int num = Shader.PropertyToID("_FresnelPower"); int num2 = Shader.PropertyToID("_FresnelColor"); enemyOrbOuterMaterial.SetFloat(num, enemyValuable.fresnelPowerIndestructible); enemyOrbOuterMaterial.SetColor(num2, enemyValuable.fresnelColorIndestructible); } } } private static Material GetEnemyOrbOuterMaterial(EnemyValuable enemyValuable) { if ((Object)(object)enemyValuable == (Object)null) { return null; } if (EnemyValuableOuterMaterialField != null) { object? value = EnemyValuableOuterMaterialField.GetValue(enemyValuable); Material val = (Material)((value is Material) ? value : null); if ((Object)(object)val != (Object)null) { return val; } } if ((Object)(object)enemyValuable.outerMeshRenderer == (Object)null) { return null; } Material material = ((Renderer)enemyValuable.outerMeshRenderer).material; if ((Object)(object)material != (Object)null && EnemyValuableOuterMaterialField != null) { EnemyValuableOuterMaterialField.SetValue(enemyValuable, material); } return material; } private void ZeroOutLocalValue(OrbEntry loser) { SetDollarValuesLocal(loser.ValuableObject, 0f); } private void RemoveLoserFromDollarHaulList(OrbEntry loser) { if (loser == null || (Object)(object)loser.GameObject == (Object)null) { return; } try { if ((Object)(object)RoundDirector.instance != (Object)null && RoundDirector.instance.dollarHaulList != null) { RoundDirector.instance.dollarHaulList.Remove(loser.GameObject); } } catch (Exception ex) { ((BaseUnityPlugin)this).Logger.LogError((object)("RemoveLoserFromDollarHaulList failed\n" + ex)); } } private void DestroyLoser(OrbEntry loser) { if (SemiFunc.IsMultiplayer()) { if ((Object)(object)loser.GameObject != (Object)null) { PhotonNetwork.Destroy(loser.GameObject); } } else if ((Object)(object)loser.GameObject != (Object)null) { Object.Destroy((Object)(object)loser.GameObject); } } private int GetConfiguredMaxOrbValue() { if (maxOrbValue == null) { return 0; } return Mathf.Max(0, maxOrbValue.Value); } private bool IsMergeBlockedByMaxValue(int firstValue, int secondValue, int mergedValue) { int configuredMaxOrbValue = GetConfiguredMaxOrbValue(); if (configuredMaxOrbValue <= 0) { return false; } if (firstValue >= configuredMaxOrbValue || secondValue >= configuredMaxOrbValue) { return true; } return mergedValue > configuredMaxOrbValue; } private int GetConfiguredMaxOrbMergeCount() { if (maxOrbMergeCount == null) { return 0; } return Mathf.Max(0, maxOrbMergeCount.Value); } private bool IsMergeBlockedByMaxMergeCount(int firstMergeCount, int secondMergeCount, int mergedCount) { int configuredMaxOrbMergeCount = GetConfiguredMaxOrbMergeCount(); if (configuredMaxOrbMergeCount <= 0) { return false; } if (firstMergeCount >= configuredMaxOrbMergeCount || secondMergeCount >= configuredMaxOrbMergeCount) { return true; } return mergedCount > configuredMaxOrbMergeCount; } private void ApplyBlockedInvincibility(OrbEntry first, OrbEntry second) { try { ReapplyVanillaEnemyOrbInvincibility(first, allowElectricityEffect: false); ReapplyVanillaEnemyOrbInvincibility(second, allowElectricityEffect: false); float nextMergeAllowedTime = Time.time + Mathf.Max(0f, remergeCooldown.Value); if (first != null) { first.NextMergeAllowedTime = nextMergeAllowedTime; } if (second != null) { second.NextMergeAllowedTime = nextMergeAllowedTime; } } catch (Exception ex) { ((BaseUnityPlugin)this).Logger.LogError((object)("ApplyBlockedInvincibility failed\n" + ex)); } } private static bool IsHeldByAnyPlayer(OrbEntry entry) { if (entry == null || (Object)(object)entry.PhysGrabObject == (Object)null) { return false; } PhysGrabObject physGrabObject = entry.PhysGrabObject; if (physGrabObject.playerGrabbing != null && physGrabObject.playerGrabbing.Count > 0) { return true; } if (physGrabObject.grabbed || physGrabObject.grabbedLocal) { return true; } return false; } private bool AreOrbsTouchingFallback(OrbEntry first, OrbEntry second) { //IL_005e: 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_006e: 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_008e: Unknown result type (might be due to invalid IL or missing references) //IL_0093: Unknown result type (might be due to invalid IL or missing references) //IL_0095: Unknown result type (might be due to invalid IL or missing references) //IL_009a: Unknown result type (might be due to invalid IL or missing references) //IL_00bb: Unknown result type (might be due to invalid IL or missing references) first.UpdateCachedBounds(); second.UpdateCachedBounds(); if (!first.HasCachedBounds || !second.HasCachedBounds) { return false; } float num = Mathf.Max(0.001f, contactSkin.Value); float num2 = first.CachedRadius + second.CachedRadius + num; Vector3 val = ((Bounds)(ref first.CachedBounds)).center - ((Bounds)(ref second.CachedBounds)).center; if (((Vector3)(ref val)).sqrMagnitude > num2 * num2) { return false; } Bounds cachedBounds = first.CachedBounds; Bounds cachedBounds2 = second.CachedBounds; ((Bounds)(ref cachedBounds)).Expand(num * 2f); ((Bounds)(ref cachedBounds2)).Expand(num * 2f); if (!((Bounds)(ref cachedBounds)).Intersects(cachedBounds2)) { return false; } return AreEntryCollidersCloseEnough(first, second, num); } private static bool AreEntryCollidersCloseEnough(OrbEntry first, OrbEntry second, float skin) { for (int i = 0; i < first.Colliders.Count; i++) { Collider val = first.Colliders[i]; if (!IsColliderUsable(val)) { continue; } for (int j = 0; j < second.Colliders.Count; j++) { Collider val2 = second.Colliders[j]; if (IsColliderUsable(val2) && AreCollidersCloseEnough(val, val2, skin)) { return true; } } } return false; } private bool IsEntryReady(OrbEntry entry) { if (!IsEntryValid(entry)) { return false; } if (busyOrbIds.Contains(entry.Id)) { return false; } if (Time.time < entry.RegisteredTime + Mathf.Max(0f, mergeArmDelay.Value)) { return false; } if (Time.time < entry.NextMergeAllowedTime) { return false; } return true; } private bool IsEntryValid(OrbEntry entry) { //IL_005c: Unknown result type (might be due to invalid IL or missing references) //IL_0061: Unknown result type (might be due to invalid IL or missing references) if (entry == null) { return false; } if ((Object)(object)entry.EnemyValuable == (Object)null || (Object)(object)entry.GameObject == (Object)null || (Object)(object)entry.ValuableObject == (Object)null || (Object)(object)entry.PhysGrabObject == (Object)null) { return false; } Scene scene = entry.GameObject.scene; if (!((Scene)(ref scene)).IsValid()) { return false; } if (!entry.GameObject.activeInHierarchy) { return false; } if (entry.PhysGrabObject.dead) { return false; } if (entry.Colliders == null || entry.Colliders.Count == 0) { entry.RefreshColliders(); } return entry.Colliders != null && entry.Colliders.Count > 0; } private bool CanTrackEnemyOrb(EnemyValuable enemyValuable) { //IL_002c: Unknown result type (might be due to invalid IL or missing references) //IL_0031: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)enemyValuable == (Object)null) { return false; } if ((Object)(object)((Component)enemyValuable).gameObject == (Object)null) { return false; } Scene scene = ((Component)enemyValuable).gameObject.scene; if (!((Scene)(ref scene)).IsValid()) { return false; } if ((Object)(object)((Component)enemyValuable).GetComponent<ValuableObject>() == (Object)null) { return false; } if ((Object)(object)((Component)enemyValuable).GetComponent<PhysGrabObject>() == (Object)null) { return false; } return true; } private void PlayMergeEffects(OrbEntry winner, Vector3 mergeEffectPosition) { //IL_0013: Unknown result type (might be due to invalid IL or missing references) if (playNetworkMergeEffect.Value) { PlayNetworkVisibleMergeEffect(winner, mergeEffectPosition); } } private void PlayNetworkVisibleMergeEffect(OrbEntry winner, Vector3 mergeEffectPosition) { //IL_0047: Unknown result type (might be due to invalid IL or missing references) //IL_006c: Unknown result type (might be due to invalid IL or missing references) try { if (winner != null && !((Object)(object)winner.PhotonView == (Object)null) && !((Object)(object)winner.ImpactDetector == (Object)null)) { if (SemiFunc.IsMultiplayer()) { winner.PhotonView.RPC("ImpactEffectRPC", (RpcTarget)0, new object[1] { mergeEffectPosition }); } else if ((Object)(object)AssetManager.instance != (Object)null) { AssetManager.instance.PhysImpactEffect(mergeEffectPosition); } } } catch (Exception ex) { ((BaseUnityPlugin)this).Logger.LogError((object)("PlayNetworkVisibleMergeEffect failed\n" + ex)); } } private Vector3 GetMergeEffectPosition(OrbEntry first, OrbEntry second) { //IL_0011: Unknown result type (might be due to invalid IL or missing references) //IL_0012: Unknown result type (might be due to invalid IL or missing references) //IL_0013: Unknown result type (might be due to invalid IL or missing references) //IL_001d: Unknown result type (might be due to invalid IL or missing references) //IL_0022: Unknown result type (might be due to invalid IL or missing references) //IL_00de: 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_0063: Unknown result type (might be due to invalid IL or missing references) //IL_0068: Unknown result type (might be due to invalid IL or missing references) //IL_0072: 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_00d6: Unknown result type (might be due to invalid IL or missing references) //IL_00db: Unknown result type (might be due to invalid IL or missing references) //IL_00af: Unknown result type (might be due to invalid IL or missing references) //IL_00bf: Unknown result type (might be due to invalid IL or missing references) //IL_00c4: Unknown result type (might be due to invalid IL or missing references) //IL_00ce: Unknown result type (might be due to invalid IL or missing references) //IL_00d3: Unknown result type (might be due to invalid IL or missing references) if (TryGetClosestPointsBetweenEntries(first, second, out var firstPoint, out var secondPoint)) { return (firstPoint + secondPoint) * 0.5f; } if (first != null && second != null && (Object)(object)first.PhysGrabObject != (Object)null && (Object)(object)second.PhysGrabObject != (Object)null) { return (first.PhysGrabObject.centerPoint + second.PhysGrabObject.centerPoint) * 0.5f; } if (first != null && second != null && (Object)(object)first.GameObject != (Object)null && (Object)(object)second.GameObject != (Object)null) { return (first.GameObject.transform.position + second.GameObject.transform.position) * 0.5f; } return Vector3.zero; } private static bool TryGetClosestPointsBetweenEntries(OrbEntry first, OrbEntry second, out Vector3 firstPoint, out Vector3 secondPoint) { //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_000d: 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_0092: 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_009b: Unknown result type (might be due to invalid IL or missing references) //IL_00a0: Unknown result type (might be due to invalid IL or missing references) //IL_00a5: Unknown result type (might be due to invalid IL or missing references) //IL_00a9: Unknown result type (might be due to invalid IL or missing references) //IL_00ab: Unknown result type (might be due to invalid IL or missing references) //IL_00b0: Unknown result type (might be due to invalid IL or missing references) //IL_00b2: 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_00b6: Unknown result type (might be due to invalid IL or missing references) //IL_00bb: Unknown result type (might be due to invalid IL or missing references) //IL_00dc: 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_00e4: 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) firstPoint = Vector3.zero; secondPoint = Vector3.zero; if (first == null || second == null) { return false; } float num = float.MaxValue; bool flag = false; for (int i = 0; i < first.Colliders.Count; i++) { Collider val = first.Colliders[i]; if (!IsColliderUsable(val)) { continue; } for (int j = 0; j < second.Colliders.Count; j++) { Collider val2 = second.Colliders[j]; if (IsColliderUsable(val2)) { Bounds bounds = val2.bounds; Vector3 val3 = val.ClosestPoint(((Bounds)(ref bounds)).center); Vector3 val4 = val2.ClosestPoint(val3); Vector3 val5 = val3 - val4; float sqrMagnitude = ((Vector3)(ref val5)).sqrMagnitude; if (!flag || sqrMagnitude < num) { num = sqrMagnitude; firstPoint = val3; secondPoint = val4; flag = true; } } } } return flag; } private void LogInfo(string message) { ((BaseUnityPlugin)this).Logger.LogInfo((object)message); } private void LogDebug(string message) { if (debugLog.Value) { ((BaseUnityPlugin)this).Logger.LogInfo((object)message); } } private static PhysGrabObjectImpactDetector GetImpactDetectorFromCollision(Collision collision) { if (collision == null) { return null; } if ((Object)(object)collision.gameObject != (Object)null) { PhysGrabObjectImpactDetector component = collision.gameObject.GetComponent<PhysGrabObjectImpactDetector>(); if ((Object)(object)component != (Object)null) { return component; } } if ((Object)(object)collision.transform != (Object)null) { PhysGrabObjectImpactDetector componentInParent = ((Component)collision.transform).GetComponentInParent<PhysGrabObjectImpactDetector>(); if ((Object)(object)componentInParent != (Object)null) { return componentInParent; } } if ((Object)(object)collision.collider != (Object)null) { PhysGrabObjectImpactDetector componentInParent2 = ((Component)collision.collider).GetComponentInParent<PhysGrabObjectImpactDetector>(); if ((Object)(object)componentInParent2 != (Object)null) { return componentInParent2; } } return null; } private static EnemyValuable GetEnemyValuableFromDetector(PhysGrabObjectImpactDetector detector) { if ((Object)(object)detector == (Object)null) { return null; } EnemyValuable component = ((Component)detector).GetComponent<EnemyValuable>(); if ((Object)(object)component != (Object)null) { return component; } return ((Component)detector).GetComponentInParent<EnemyValuable>(); } private static bool AreCollidersCloseEnough(Collider firstCollider, Collider secondCollider, float skin) { //IL_0003: 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_000b: Unknown result type (might be due to invalid IL or missing references) //IL_0010: Unknown result type (might be due to invalid IL or missing references) //IL_0015: Unknown result type (might be due to invalid IL or missing references) //IL_0017: Unknown result type (might be due to invalid IL or missing references) //IL_0018: Unknown result type (might be due to invalid IL or missing references) //IL_001d: Unknown result type (might be due to invalid IL or missing references) //IL_001e: Unknown result type (might be due to invalid IL or missing references) //IL_001f: Unknown result type (might be due to invalid IL or missing references) //IL_0020: 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) Bounds bounds = secondCollider.bounds; Vector3 val = firstCollider.ClosestPoint(((Bounds)(ref bounds)).center); Vector3 val2 = secondCollider.ClosestPoint(val); Vector3 val3 = val - val2; return ((Vector3)(ref val3)).sqrMagnitude <= skin * skin; } private static bool TryGetCombinedBounds(List<Collider> colliders, out Bounds bounds) { //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_0046: Unknown result type (might be due to invalid IL or missing references) //IL_0034: Unknown result type (might be due to invalid IL or missing references) //IL_0039: Unknown result type (might be due to invalid IL or missing references) bounds = default(Bounds); bool flag = false; for (int i = 0; i < colliders.Count; i++) { Collider val = colliders[i]; if (IsColliderUsable(val)) { if (!flag) { bounds = val.bounds; flag = true; } else { ((Bounds)(ref bounds)).Encapsulate(val.bounds); } } } return flag; } private static bool IsColliderUsable(Collider collider) { return (Object)(object)collider != (Object)null && collider.enabled && !collider.isTrigger && ((Component)collider).gameObject.activeInHierarchy; } private static bool GetBoolField(FieldInfo fieldInfo, object instance, bool defaultValue) { if (fieldInfo == null || instance == null) { return defaultValue; } try { object value = fieldInfo.GetValue(instance); if (value is bool) { return (bool)value; } } catch { return defaultValue; } return defaultValue; } private static float GetDollarValueCurrent(ValuableObject valuableObject) { if ((Object)(object)valuableObject == (Object)null || ValuableCurrentField == null) { return 0f; } object value = ValuableCurrentField.GetValue(valuableObject); if (value == null) { return 0f; } return Convert.ToSingle(value); } private static void SetDollarValuesLocal(ValuableObject valuableObject, float value) { if (!((Object)(object)valuableObject == (Object)null)) { if (ValuableOriginalField != null) { ValuableOriginalField.SetValue(valuableObject, value); } if (ValuableCurrentField != null) { ValuableCurrentField.SetValue(valuableObject, value); } if (ValuableSetField != null) { ValuableSetField.SetValue(valuableObject, true); } } } } }