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 RepoMutantEnemies v1.3.4
Matsu.MergedEnemyMod.dll
Decompiled 3 days ago
The result has been truncated due to the large size, download it to view full contents!
using System; using System.Collections; using System.Collections.Generic; using System.Diagnostics; using System.Globalization; using System.Linq; using System.Reflection; using System.Reflection.Emit; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using System.Text; using BepInEx; using BepInEx.Bootstrap; using BepInEx.Configuration; using BepInEx.Logging; using ExitGames.Client.Photon; using HarmonyLib; using Microsoft.CodeAnalysis; using Photon.Pun; using Photon.Realtime; using REPOLib.Modules; using UnityEngine; using UnityEngine.AI; using UnityEngine.Events; using UnityEngine.Rendering; using UnityEngine.SceneManagement; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: TargetFramework(".NETFramework,Version=v4.8", FrameworkDisplayName = ".NET Framework 4.8")] [assembly: AssemblyCompany("Matsu.MergedEnemyMod")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyFileVersion("1.3.4.0")] [assembly: AssemblyInformationalVersion("1.3.4")] [assembly: AssemblyProduct("Matsu.MergedEnemyMod")] [assembly: AssemblyTitle("Matsu.MergedEnemyMod")] [assembly: AssemblyVersion("1.3.4.0")] [module: RefSafetyRules(11)] namespace Microsoft.CodeAnalysis { [CompilerGenerated] [Embedded] internal sealed class EmbeddedAttribute : Attribute { } } namespace System.Runtime.CompilerServices { [CompilerGenerated] [Embedded] [AttributeUsage(AttributeTargets.Class | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Parameter | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter, AllowMultiple = false, Inherited = false)] internal sealed class NullableAttribute : Attribute { public readonly byte[] NullableFlags; public NullableAttribute(byte P_0) { NullableFlags = new byte[1] { P_0 }; } public NullableAttribute(byte[] P_0) { NullableFlags = P_0; } } [CompilerGenerated] [Embedded] [AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Method | AttributeTargets.Interface | AttributeTargets.Delegate, AllowMultiple = false, Inherited = false)] internal sealed class NullableContextAttribute : Attribute { public readonly byte Flag; public NullableContextAttribute(byte P_0) { Flag = P_0; } } [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 Matsu.MergedEnemyMod { internal static class AttackGeometry { public static float ClosestFraction(float px, float py, float pz, float ax, float ay, float az, float bx, float by, float bz) { float num = bx - ax; float num2 = by - ay; float num3 = bz - az; float num4 = num * num + num2 * num2 + num3 * num3; if (num4 <= 1E-06f) { return 0f; } return Math.Max(0f, Math.Min(1f, ((px - ax) * num + (py - ay) * num2 + (pz - az) * num3) / num4)); } public static bool SweptSegment(float previous, float current, int segment, out float start, out float end) { start = Math.Max(0f, previous - (float)segment); end = Math.Min(1f, current - (float)segment); if (current >= previous && start <= end && start <= 1f) { return end >= 0f; } return false; } public static bool ExpandingRingCrossed(float distance, float height, float previousRadius, float currentRadius, float halfWidth, float minimumHeight, float maximumHeight) { if (currentRadius < previousRadius || height < minimumHeight || height > maximumHeight) { return false; } halfWidth = Math.Max(0f, halfWidth); if (distance >= Math.Max(0f, previousRadius - halfWidth)) { return distance <= currentRadius + halfWidth; } return false; } public static float NormalizeRadians(float angle) { float num = (float)Math.PI * 2f; angle %= num; if (!(angle < 0f)) { return angle; } return angle + num; } public static bool AngleInPositiveSweep(float angle, float start, float end, float tolerance) { if (end < start) { return false; } float num = (float)Math.PI * 2f; float num2 = end - start; tolerance = Math.Max(0f, tolerance); if (num2 + tolerance * 2f >= num) { return true; } float num3 = NormalizeRadians(angle - start); if (!(num3 <= num2 + tolerance)) { return num3 >= num - tolerance; } return true; } public static float SafeOrbitRadius(float participantDistance, float challengeRadius, float pocketRadius) { participantDistance = Math.Max(0f, participantDistance); challengeRadius = Math.Max(0.5f, challengeRadius); pocketRadius = Math.Max(0.1f, pocketRadius); float val = Math.Max(0.5f, pocketRadius * 0.5f); float val2 = Math.Max(val, challengeRadius - pocketRadius * 0.5f); return Math.Max(val, Math.Min(val2, participantDistance)); } } public sealed class BelladonnaFloorWave : MonoBehaviour { private Enemy? _source; private Transform _owner; private LineRenderer _ring; private Material? _material; private float _age; private float _radius; private float _previousRadius; private float _delay; private int _damage; private bool _hit; private bool _echo; private const float Warning = 0.9f; private const float Speed = 7f; private const float HalfWidth = 0.35f; public void Initialize(Vector3 origin, Enemy? source, Transform owner, float radius, int damage, float delay = 0f, bool echo = false) { //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_00ba: Unknown result type (might be due to invalid IL or missing references) //IL_00c4: Expected O, but got Unknown ((Component)this).transform.position = origin; _source = source; _owner = owner; _radius = radius; _damage = damage; _delay = Mathf.Max(0f, delay); _echo = echo; _ring = ((Component)this).gameObject.AddComponent<LineRenderer>(); _ring.useWorldSpace = false; _ring.loop = true; _ring.positionCount = 64; _ring.widthMultiplier = 0.7f; ((Renderer)_ring).shadowCastingMode = (ShadowCastingMode)0; Shader val = Shader.Find("Sprites/Default") ?? Shader.Find("Unlit/Color"); if ((Object)(object)val != (Object)null) { _material = new Material(val); ((Renderer)_ring).material = _material; } } private void Update() { //IL_00f8: 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_0116: 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_015c: 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_015d: Unknown result type (might be due to invalid IL or missing references) //IL_015e: Unknown result type (might be due to invalid IL or missing references) //IL_0165: Unknown result type (might be due to invalid IL or missing references) //IL_01c8: Unknown result type (might be due to invalid IL or missing references) //IL_01d3: Unknown result type (might be due to invalid IL or missing references) //IL_01d8: Unknown result type (might be due to invalid IL or missing references) //IL_01dd: Unknown result type (might be due to invalid IL or missing references) //IL_01df: Unknown result type (might be due to invalid IL or missing references) //IL_01e6: Unknown result type (might be due to invalid IL or missing references) //IL_01ed: Unknown result type (might be due to invalid IL or missing references) //IL_01f2: Unknown result type (might be due to invalid IL or missing references) //IL_01fb: Unknown result type (might be due to invalid IL or missing references) //IL_0228: Unknown result type (might be due to invalid IL or missing references) //IL_022d: Unknown result type (might be due to invalid IL or missing references) //IL_0237: Unknown result type (might be due to invalid IL or missing references) //IL_023c: 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_0257: 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_0291: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)_owner == (Object)null || !((Component)_owner).gameObject.activeInHierarchy) { Object.Destroy((Object)(object)((Component)this).gameObject); return; } _age += Time.deltaTime; float num = _age - _delay; float num2 = Mathf.Min(_radius, Mathf.Max(0f, num - 0.9f) * 7f); float num3 = ((num < 0.9f) ? Mathf.Lerp(0.18f, _echo ? 0.8f : 0.55f, Mathf.Clamp01((num + _delay) / Mathf.Max(0.1f, _delay + 0.9f))) : num2); for (int i = 0; i < 64; i++) { float num4 = (float)i * (float)Math.PI * 2f / 64f; _ring.SetPosition(i, new Vector3(Mathf.Cos(num4) * num3, 0.2f, Mathf.Sin(num4) * num3)); } Color val = (Color)(_echo ? new Color(0.35f, 0.9f, 1f) : Color.yellow); LineRenderer ring = _ring; Color startColor = (_ring.endColor = (Color)((num < 0.9f) ? val : new Color(1f, 0.35f, 0.8f))); ring.startColor = startColor; if (!_hit && num >= 0.9f) { foreach (PlayerAvatar item in FusionShared.AllPlayers()) { if (!((Object)(object)item == (Object)null) && FusionShared.IsLocalPlayer(item) && !FusionShared.IsPlayerDisabled(item)) { Vector3 val3 = ((Component)item).transform.position - ((Component)this).transform.position; Vector2 val4 = new Vector2(val3.x, val3.z); if (AttackGeometry.ExpandingRingCrossed(((Vector2)(ref val4)).magnitude, val3.y, _previousRadius, num2, 0.35f, -0.6f, 0.65f) && !Physics.Linecast(((Component)this).transform.position + Vector3.up * 0.3f, ((Component)item).transform.position + Vector3.up * 0.3f, LayerMask.GetMask(new string[1] { "Default" }), (QueryTriggerInteraction)1)) { _hit = true; FusionShared.HurtOwnedPlayer(item, _damage, ((Component)this).transform.position, _source); break; } } } } _previousRadius = num2; if (num >= 0.9f && num2 >= _radius) { Object.Destroy((Object)(object)((Component)this).gameObject); } } private void OnDestroy() { if ((Object)(object)_material != (Object)null) { Object.Destroy((Object)(object)_material); } } } public sealed class BloodDebt : MonoBehaviour { private Enemy? _source; private EnemyHealth? _health; private LineRenderer? _line; private Material? _material; private float _remaining; private float _duration; private int _damage; private bool _finished; public PlayerAvatar? Target { get; private set; } public void Initialize(PlayerAvatar target, Enemy? source, EnemyHealth? health, float seconds, int damage) { //IL_0097: Unknown result type (might be due to invalid IL or missing references) //IL_00a1: Expected O, but got Unknown Target = target; _source = source; _health = health; _remaining = (_duration = seconds); _damage = damage; _line = ((Component)this).gameObject.AddComponent<LineRenderer>(); _line.useWorldSpace = true; _line.positionCount = 2; _line.widthMultiplier = 0.09f; ((Renderer)_line).shadowCastingMode = (ShadowCastingMode)0; Shader val = Shader.Find("Sprites/Default") ?? Shader.Find("Unlit/Color"); if ((Object)(object)val != (Object)null) { _material = new Material(val); ((Renderer)_line).material = _material; } } private void Update() { //IL_0091: Unknown result type (might be due to invalid IL or missing references) //IL_0096: Unknown result type (might be due to invalid IL or missing references) //IL_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_00aa: 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_00db: 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_00ea: Unknown result type (might be due to invalid IL or missing references) //IL_00ef: Unknown result type (might be due to invalid IL or missing references) //IL_0112: Unknown result type (might be due to invalid IL or missing references) //IL_0117: 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_012f: Unknown result type (might be due to invalid IL or missing references) //IL_0130: 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_0137: 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) if (_finished) { return; } if ((Object)(object)Target == (Object)null || FusionShared.IsPlayerDisabled(Target) || (Object)(object)_source == (Object)null || !((Component)_source).gameObject.activeInHierarchy || _source.IsStunned() || ((Object)(object)_health != (Object)null && FusionShared.GetHealthCurrent(_health) <= 0)) { Finish(); return; } _remaining -= Time.deltaTime; Vector3 val = ((Component)_source).transform.position + Vector3.up * 0.8f; if ((Object)(object)_line != (Object)null) { _line.SetPosition(0, val); _line.SetPosition(1, ((Component)Target).transform.position + Vector3.up * 0.8f); float num = 1f - Mathf.Clamp01(_remaining / _duration); Color val2 = Color.Lerp(Color.white, Color.red, num); LineRenderer? line = _line; Color startColor = (_line.endColor = val2); line.startColor = startColor; _line.widthMultiplier = 0.09f + num * 0.06f + (Mathf.Sin(Time.time * (6f + num * 8f)) + 1f) * 0.0125f; } if (!(_remaining > 0f)) { _finished = true; FusionShared.HurtOwnedPlayer(Target, _damage, val, _source); Finish(); } } private void Finish() { _finished = true; ((Component)this).gameObject.SetActive(false); Object.Destroy((Object)(object)((Component)this).gameObject); } private void OnDestroy() { if ((Object)(object)_material != (Object)null) { Object.Destroy((Object)(object)_material); } } } public sealed class ContagionSporeCloud : MonoBehaviour { private const float WarningSeconds = 1f; private readonly RaycastHit[] _hits = (RaycastHit[])(object)new RaycastHit[24]; private static readonly int CoverMask = LayerMask.GetMask(new string[1] { "Default" }); private Enemy? _source; private Transform? _sourceRoot; private PlayerAvatar? _victim; private LineRenderer? _boundary; private Material? _material; private Light? _light; private float _radius; private float _lifetime; private float _threshold; private float _age; private float _exposure; private int _damage; private bool _victimExposed; public void Initialize(Vector3 center, Enemy? source, float radius, float lifetime, float exposureSeconds, int damage) { //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_00cc: Unknown result type (might be due to invalid IL or missing references) //IL_00d6: Expected O, but got Unknown //IL_011c: Unknown result type (might be due to invalid IL or missing references) //IL_0134: Unknown result type (might be due to invalid IL or missing references) //IL_013a: Expected O, but got Unknown //IL_0152: Unknown result type (might be due to invalid IL or missing references) //IL_017a: Unknown result type (might be due to invalid IL or missing references) ((Component)this).transform.position = center; _source = source; object sourceRoot; if (!((Object)(object)source != (Object)null)) { sourceRoot = null; } else { EnemyParent componentInParent = ((Component)source).GetComponentInParent<EnemyParent>(); sourceRoot = ((componentInParent != null) ? ((Component)componentInParent).transform : null); } _sourceRoot = (Transform?)sourceRoot; _radius = radius; _lifetime = lifetime; _threshold = exposureSeconds; _damage = damage; _boundary = ((Component)this).gameObject.AddComponent<LineRenderer>(); _boundary.useWorldSpace = false; _boundary.loop = true; _boundary.positionCount = 48; _boundary.widthMultiplier = 0.1f; ((Renderer)_boundary).shadowCastingMode = (ShadowCastingMode)0; Shader val = Shader.Find("Sprites/Default") ?? Shader.Find("Unlit/Color"); if ((Object)(object)val != (Object)null) { _material = new Material(val); ((Renderer)_boundary).material = _material; } for (int i = 0; i < 48; i++) { float num = (float)i * (float)Math.PI * 2f / 48f; _boundary.SetPosition(i, new Vector3(Mathf.Cos(num) * radius, 0.12f, Mathf.Sin(num) * radius)); } GameObject val2 = new GameObject("SporeGlow"); val2.transform.SetParent(((Component)this).transform, false); val2.transform.localPosition = Vector3.up; _light = val2.AddComponent<Light>(); _light.type = (LightType)2; _light.color = ContagionFusion.AuraColor; _light.range = radius * 2f; _light.shadows = (LightShadows)0; } private void Update() { //IL_0128: 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_0167: 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_015b: Unknown result type (might be due to invalid IL or missing references) //IL_0172: Unknown result type (might be due to invalid IL or missing references) //IL_01b3: 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_01b6: Unknown result type (might be due to invalid IL or missing references) //IL_01bd: Unknown result type (might be due to invalid IL or missing references) float age = _age; _age += Time.deltaTime; if (_age >= 1f + _lifetime) { Object.Destroy((Object)(object)((Component)this).gameObject); return; } if ((Object)(object)_victim == (Object)null) { foreach (PlayerAvatar item in FusionShared.AllPlayers()) { if ((Object)(object)item != (Object)null && FusionShared.IsLocalPlayer(item)) { _victim = item; break; } } } bool flag = _age >= 1f; bool flag2 = (Object)(object)_victim != (Object)null && !FusionShared.IsPlayerDisabled(_victim); _victimExposed = flag2 && IsExposed(_victim); if (flag2 && flag) { float elapsed = HazardTiming.ActiveDelta(age, _age, 1f, _lifetime); if (HazardTiming.Exposure(ref _exposure, elapsed, _threshold, _victimExposed)) { FusionShared.HurtOwnedPlayer(_victim, _damage, ((Component)this).transform.position, _source); } } else { _exposure = 0f; } float num = Mathf.Clamp01(_exposure / _threshold); Color val = (flag ? Color.Lerp(ContagionFusion.AuraColor, Color.red, num) : Color.yellow); val.a = Mathf.Clamp01((1f + _lifetime - _age) / 0.6f); if ((Object)(object)_boundary != (Object)null) { LineRenderer? boundary = _boundary; Color startColor = (_boundary.endColor = val); boundary.startColor = startColor; _boundary.widthMultiplier = 0.1f + num * 0.2f; } if ((Object)(object)_light != (Object)null) { _light.intensity = (flag ? (3f + num * 5f) : 1f); } } private bool IsExposed(PlayerAvatar player) { //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_0011: Unknown result type (might be due to invalid IL or missing references) //IL_0016: 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_001c: Unknown result type (might be due to invalid IL or missing references) //IL_002e: Unknown result type (might be due to invalid IL or missing references) //IL_0034: 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_0041: Unknown result type (might be due to invalid IL or missing references) //IL_0060: Unknown result type (might be due to invalid IL or missing references) //IL_0065: Unknown result type (might be due to invalid IL or missing references) //IL_006a: Unknown result type (might be due to invalid IL or missing references) //IL_006f: Unknown result type (might be due to invalid IL or missing references) //IL_0076: Unknown result type (might be due to invalid IL or missing references) //IL_007b: Unknown result type (might be due to invalid IL or missing references) //IL_0085: Unknown result type (might be due to invalid IL or missing references) //IL_008a: Unknown result type (might be due to invalid IL or missing references) //IL_008f: Unknown result type (might be due to invalid IL or missing references) //IL_0090: Unknown result type (might be due to invalid IL or missing references) //IL_0095: Unknown result type (might be due to invalid IL or missing references) //IL_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) //IL_00ab: Unknown result type (might be due to invalid IL or missing references) Vector3 val = ((Component)player).transform.position - ((Component)this).transform.position; if (Mathf.Abs(val.y) > 2.5f || val.x * val.x + val.z * val.z > _radius * _radius) { return false; } Vector3 val2 = ((Component)this).transform.position + Vector3.up; Vector3 val3 = ((Component)player).transform.position + Vector3.up * 0.8f - val2; float magnitude = ((Vector3)(ref val3)).magnitude; if (magnitude < 0.01f) { return true; } int num = Physics.RaycastNonAlloc(val2, val3 / magnitude, _hits, magnitude, CoverMask, (QueryTriggerInteraction)1); if (num == _hits.Length) { return false; } for (int i = 0; i < num; i++) { Transform transform = ((RaycastHit)(ref _hits[i])).transform; if (!((Object)(object)transform == (Object)null) && !transform.IsChildOf(((Component)player).transform) && (!((Object)(object)_sourceRoot != (Object)null) || !transform.IsChildOf(_sourceRoot))) { return false; } } return true; } private void OnDestroy() { if ((Object)(object)_material != (Object)null) { Object.Destroy((Object)(object)_material); } } } public sealed class EffigyAnimationGuard : MonoBehaviour { private readonly Dictionary<Animator, RuntimeAnimatorController> _originals = new Dictionary<Animator, RuntimeAnimatorController>(); private readonly Dictionary<Animator, AnimatorOverrideController> _overrides = new Dictionary<Animator, AnimatorOverrideController>(); private readonly List<AnimationClip> _copies = new List<AnimationClip>(); internal int RemovedEvents { get; private set; } internal void Initialize() { //IL_003f: Unknown result type (might be due to invalid IL or missing references) //IL_0046: Expected O, but got Unknown if (_overrides.Count > 0) { return; } Dictionary<AnimationClip, AnimationClip> dictionary = new Dictionary<AnimationClip, AnimationClip>(); Animator[] componentsInChildren = ((Component)this).GetComponentsInChildren<Animator>(true); foreach (Animator val in componentsInChildren) { RuntimeAnimatorController runtimeAnimatorController = val.runtimeAnimatorController; if ((Object)(object)runtimeAnimatorController == (Object)null) { continue; } AnimatorOverrideController val2 = new AnimatorOverrideController(runtimeAnimatorController); List<KeyValuePair<AnimationClip, AnimationClip>> list = new List<KeyValuePair<AnimationClip, AnimationClip>>(); val2.GetOverrides(list); bool flag = false; for (int j = 0; j < list.Count; j++) { AnimationClip val3 = (((Object)(object)list[j].Value != (Object)null) ? list[j].Value : list[j].Key); AnimationEvent[] events = val3.events; AnimationEvent[] array = events.Where((AnimationEvent e) => e.functionName != "EliminateTarget").ToArray(); if (events.Length != array.Length) { if (!dictionary.TryGetValue(val3, out var value)) { value = Object.Instantiate<AnimationClip>(val3); ((Object)value).name = ((Object)val3).name + " (Effigy safe copy)"; value.events = array; dictionary[val3] = value; _copies.Add(value); RemovedEvents += events.Length - array.Length; } list[j] = new KeyValuePair<AnimationClip, AnimationClip>(list[j].Key, value); flag = true; } } if (!flag) { Object.Destroy((Object)(object)val2); continue; } val2.ApplyOverrides((IList<KeyValuePair<AnimationClip, AnimationClip>>)list); _originals[val] = runtimeAnimatorController; _overrides[val] = val2; val.runtimeAnimatorController = (RuntimeAnimatorController)(object)val2; } } private void OnDestroy() { foreach (KeyValuePair<Animator, AnimatorOverrideController> @override in _overrides) { if ((Object)(object)@override.Key != (Object)null && (Object)(object)@override.Key.runtimeAnimatorController == (Object)(object)@override.Value) { @override.Key.runtimeAnimatorController = _originals[@override.Key]; } if ((Object)(object)@override.Value != (Object)null) { Object.Destroy((Object)(object)@override.Value); } } foreach (AnimationClip copy in _copies) { if ((Object)(object)copy != (Object)null) { Object.Destroy((Object)(object)copy); } } _originals.Clear(); _overrides.Clear(); _copies.Clear(); } } internal readonly struct GluttonMealGrowth { internal readonly int Points; internal readonly int Damage; internal readonly int Hp; internal readonly float Mass; internal GluttonMealGrowth(int points, int damage, float mass, int hp) { Points = points; Damage = damage; Mass = mass; Hp = hp; } } internal sealed class GluttonReturnedValuable : MonoBehaviour { internal double EatAllowedAt; private AnimalFusion? _swallowedBy; private PhysGrabObject? _item; internal static bool IsProtected(PhysGrabObject item) { GluttonReturnedValuable component = ((Component)item).GetComponent<GluttonReturnedValuable>(); if (component != null) { if (!((Object)(object)component._swallowedBy != (Object)null)) { return ReworkAccess.Now < component.EatAllowedAt; } return true; } return false; } internal static void Hold(PhysGrabObject item, AnimalFusion owner) { GluttonReturnedValuable gluttonReturnedValuable = Get(item); gluttonReturnedValuable._item = item; gluttonReturnedValuable._swallowedBy = owner; item.OverrideDeactivate(0.5f); } internal static void Release(PhysGrabObject item, AnimalFusion owner) { GluttonReturnedValuable component = ((Component)item).GetComponent<GluttonReturnedValuable>(); if ((Object)(object)component != (Object)null && (Object)(object)component._swallowedBy == (Object)(object)owner) { component._swallowedBy = null; } } private static GluttonReturnedValuable Get(PhysGrabObject item) { return ((Component)item).GetComponent<GluttonReturnedValuable>() ?? ((Component)item).gameObject.AddComponent<GluttonReturnedValuable>(); } private void Update() { if ((Object)(object)_swallowedBy != (Object)null && (Object)(object)_item != (Object)null) { _item.OverrideDeactivate(0.5f); } } internal static void Protect(PhysGrabObject item, double until) { GluttonReturnedValuable gluttonReturnedValuable = Get(item); gluttonReturnedValuable.EatAllowedAt = Math.Max(gluttonReturnedValuable.EatAllowedAt, until); } } public class AnimalFusion : MonoBehaviour { private readonly Dictionary<PhysGrabObject, GluttonMealGrowth> _mealGrowth = new Dictionary<PhysGrabObject, GluttonMealGrowth>(); private double _eatBlockedUntil; internal static readonly Color AuraColor = new Color(1f, 0.8f, 0.15f); private EnemyHealth? _health; private PhotonView? _pv; private bool _hpDone; private bool _killed; private bool _deathHooked; private float _glowTimer; private float _eatTimer; private int _totalPoints; private int _totalDamageAdded; private float _totalMassAdded; private int _totalHpAdded; private readonly List<PhysGrabObject> _belly = new List<PhysGrabObject>(); internal void PrepareHealthForDamage() { EnsureHpDoubled(); HookDeath(); } internal void Damaged() { //IL_0263: Unknown result type (might be due to invalid IL or missing references) //IL_0269: 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) //IL_00de: Unknown result type (might be due to invalid IL or missing references) //IL_00e3: Unknown result type (might be due to invalid IL or missing references) //IL_00ed: Unknown result type (might be due to invalid IL or missing references) //IL_00f2: Unknown result type (might be due to invalid IL or missing references) //IL_00fe: Unknown result type (might be due to invalid IL or missing references) //IL_0105: 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) if (!SemiFunc.IsMasterClientOrSingleplayer() || !((Behaviour)this).isActiveAndEnabled || (Object)(object)_health == (Object)null || FusionShared.GetHealthCurrent(_health) <= 0 || ReworkAccess.Read(_health, "dead", fallback: false) || ReworkAccess.Read(_health, "deadImpulse", fallback: false)) { return; } double val = ReworkAccess.Now + (double)Plugin.GluttonHurtEatCooldownSeconds.Value; _eatBlockedUntil = Math.Max(_eatBlockedUntil, val); GluttonMealGrowth value = default(GluttonMealGrowth); int num = 0; bool flag = false; for (int i = 0; i < _belly.Count; i++) { PhysGrabObject val2 = _belly[i]; if ((Object)(object)val2 == (Object)null) { continue; } try { GluttonReturnedValuable.Protect(val2, _eatBlockedUntil); FusionShared.ProtectValuable(val2, Plugin.GluttonDropInvincibleSeconds.Value); GluttonReturnedValuable.Release(val2, this); val2.OverrideDeactivateReset(); Vector2 val3 = Random.insideUnitCircle * 1.2f; val2.Teleport(((Component)this).transform.position + new Vector3(val3.x, 0.7f, val3.y), Quaternion.identity); _mealGrowth.TryGetValue(val2, out value); _mealGrowth.Remove(val2); _belly.RemoveAt(i); PhotonView component = ((Component)val2).GetComponent<PhotonView>(); num = (((Object)(object)component != (Object)null) ? component.ViewID : 0); flag = true; } catch (Exception arg) { try { GluttonReturnedValuable.Hold(val2, this); } catch { } Plugin.Log.LogError((object)$"[Glutton] Could not return a valuable after damage: {arg}"); } break; } if (SemiFunc.IsMultiplayer() && (Object)(object)_pv != (Object)null) { _pv.RPC("GluttonHurtRPC", (RpcTarget)0, new object[7] { value.Points, value.Damage, value.Mass, value.Hp, _eatBlockedUntil, num, Plugin.GluttonDropInvincibleSeconds.Value }); } else { GluttonHurtRPC(value.Points, value.Damage, value.Mass, value.Hp, _eatBlockedUntil, num, Plugin.GluttonDropInvincibleSeconds.Value); } if (flag) { Plugin.Log.LogInfo((object)$"[Glutton] Returned one swallowed valuable after damage; {_belly.Count} remain. Eating paused for {Plugin.GluttonHurtEatCooldownSeconds.Value:0.##}s."); } } [PunRPC] private void GluttonHurtRPC(int points, int damage, float mass, int hp, double blockedUntil, int valuableViewId, float protectionSeconds, PhotonMessageInfo _info = default(PhotonMessageInfo)) { //IL_0007: Unknown result type (might be due to invalid IL or missing references) if (SemiFunc.IsMultiplayer() && !SemiFunc.MasterOnlyRPC(_info)) { return; } _eatBlockedUntil = Math.Max(_eatBlockedUntil, blockedUntil); PhotonView val = ((valuableViewId != 0) ? PhotonView.Find(valuableViewId) : null); PhysGrabObject val2 = (((Object)(object)val != (Object)null) ? ((Component)val).GetComponent<PhysGrabObject>() : null); if ((Object)(object)val2 != (Object)null) { GluttonReturnedValuable.Protect(val2, _eatBlockedUntil); val2.OverrideDeactivateReset(); FusionShared.ProtectValuable(val2, protectionSeconds); } int num = Mathf.Min(Mathf.Max(0, damage), _totalDamageAdded); float num2 = Mathf.Min(Mathf.Max(0f, mass), _totalMassAdded); int num3 = Mathf.Min(Mathf.Max(0, hp), _totalHpAdded); EnemyParent componentInParent = ((Component)this).GetComponentInParent<EnemyParent>(); if (num != 0 && (Object)(object)componentInParent != (Object)null) { HurtCollider[] componentsInChildren = ((Component)componentInParent).GetComponentsInChildren<HurtCollider>(true); foreach (HurtCollider obj in componentsInChildren) { obj.playerDamage -= num; } } ApplyMassGrowth(0f - num2); if (num3 != 0 && SemiFunc.IsMasterClientOrSingleplayer() && (Object)(object)_health != (Object)null) { _health.health = Mathf.Max(1, _health.health - num3); int healthCurrent = FusionShared.GetHealthCurrent(_health); if (healthCurrent > 0) { FusionShared.SetHealthCurrent(_health, Mathf.Max(1, healthCurrent - num3)); } } _totalPoints = Mathf.Max(0, _totalPoints - points); _totalDamageAdded -= num; _totalMassAdded = Mathf.Max(0f, _totalMassAdded - num2); _totalHpAdded -= num3; } private void ApplyMassGrowth(float delta) { if (delta == 0f) { return; } PhysGrabObject val = ReworkAccess.Find<PhysGrabObject>((Component)(object)this); if ((Object)(object)val != (Object)null && (Object)(object)val.rb != (Object)null) { val.massOriginal = Mathf.Max(0.1f, val.massOriginal + delta); if (ReworkAccess.Read(val, "timerAlterMass", 0f) <= 0f) { val.rb.mass = Mathf.Max(0.1f, val.rb.mass + delta); } return; } EnemyParent componentInParent = ((Component)this).GetComponentInParent<EnemyParent>(); Rigidbody val2 = (((Object)(object)componentInParent != (Object)null) ? ((Component)componentInParent).GetComponentInChildren<Rigidbody>() : ((Component)this).GetComponentInParent<Rigidbody>()); if ((Object)(object)val2 != (Object)null) { val2.mass = Mathf.Max(0.1f, val2.mass + delta); } } private void Awake() { //IL_007e: Unknown result type (might be due to invalid IL or missing references) _health = ((Component)this).GetComponentInParent<EnemyHealth>() ?? ((Component)this).GetComponentInChildren<EnemyHealth>(); _pv = ((Component)this).GetComponent<PhotonView>(); if ((Object)(object)_pv != (Object)null) { _pv.RefreshRpcMonoBehaviourCache(); } if (SemiFunc.IsMasterClientOrSingleplayer() && (Object)(object)_health != (Object)null) { _health.health = Mathf.Max(1, Mathf.RoundToInt((float)_health.health * Plugin.CurrentHealthMultiplier())); } FusionShared.ApplyMutationGlow(((Component)this).transform, AuraColor); } private void HookDeath() { //IL_0030: Unknown result type (might be due to invalid IL or missing references) //IL_003a: Expected O, but got Unknown if (_deathHooked || (Object)(object)_health == (Object)null) { return; } _deathHooked = true; try { _health.onDeathStart.AddListener((UnityAction)delegate { _killed = true; }); } catch { } } private void Update() { //IL_0030: Unknown result type (might be due to invalid IL or missing references) _glowTimer -= Time.deltaTime; if (_glowTimer <= 0f) { _glowTimer = 2f; FusionShared.ApplyMutationGlow(((Component)this).transform, AuraColor); } HookDeath(); EnsureHpDoubled(); if (!SemiFunc.IsMasterClientOrSingleplayer()) { return; } for (int num = _belly.Count - 1; num >= 0; num--) { if ((Object)(object)_belly[num] == (Object)null) { _belly.RemoveAt(num); } } _eatTimer -= Time.deltaTime; if (!(_eatTimer > 0f)) { _eatTimer = 0.6f; TryEat(); } } private void TryEat() { //IL_0086: Unknown result type (might be due to invalid IL or missing references) //IL_01f1: Unknown result type (might be due to invalid IL or missing references) //IL_01f7: Unknown result type (might be due to invalid IL or missing references) if (!SemiFunc.IsMasterClientOrSingleplayer() || !((Behaviour)this).isActiveAndEnabled || ReworkAccess.Now < _eatBlockedUntil || _killed || ((Object)(object)_health != (Object)null && (FusionShared.GetHealthCurrent(_health) <= 0 || ReworkAccess.Read(_health, "dead", fallback: false) || ReworkAccess.Read(_health, "deadImpulse", fallback: false))) || _belly.Count >= Plugin.GluttonMaxSwallowed.Value) { return; } try { Collider[] array = Physics.OverlapSphere(((Component)this).transform.position, Plugin.GluttonEatRadius.Value); for (int i = 0; i < array.Length; i++) { ValuableObject componentInParent = ((Component)array[i]).GetComponentInParent<ValuableObject>(); if ((Object)(object)componentInParent == (Object)null) { continue; } PhysGrabObject component = ((Component)componentInParent).GetComponent<PhysGrabObject>(); if (!((Object)(object)component == (Object)null) && !_belly.Contains(component) && !GluttonReturnedValuable.IsProtected(component) && !component.grabbed && !((Object)(object)((Component)componentInParent).GetComponentInParent<EnemyParent>() != (Object)null)) { _belly.Add(component); GluttonReturnedValuable.Hold(component, this); int num = SizePoints(componentInParent); GluttonMealGrowth value = new GluttonMealGrowth(num, Mathf.Max(0, Plugin.GluttonDamagePerPoint.Value) * num, Mathf.Max(0f, Plugin.GluttonMassPerPoint.Value) * (float)num, Mathf.Max(0, Plugin.GluttonHpPerPoint.Value) * num); _mealGrowth[component] = value; if (SemiFunc.IsMultiplayer() && (Object)(object)_pv != (Object)null) { _pv.RPC("GluttonBuffRPC", (RpcTarget)0, new object[4] { num, value.Damage, value.Mass, value.Hp }); } else { GluttonBuffRPC(num, value.Damage, value.Mass, value.Hp); } Plugin.Log.LogInfo((object)$"[Glutton] Swallowed '{((Object)componentInParent).name}' (+{num}pt, {_belly.Count} in the belly)."); if (_belly.Count >= Plugin.GluttonMaxSwallowed.Value) { break; } } } } catch { } } private static int SizePoints(ValuableObject val) { //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_002e: Unknown result type (might be due to invalid IL or missing references) //IL_0050: Unknown result type (might be due to invalid IL or missing references) //IL_005f: 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) try { Collider[] componentsInChildren = ((Component)val).GetComponentsInChildren<Collider>(); if (componentsInChildren.Length == 0) { return 1; } Bounds bounds = componentsInChildren[0].bounds; Collider[] array = componentsInChildren; foreach (Collider val2 in array) { ((Bounds)(ref bounds)).Encapsulate(val2.bounds); } float num = Mathf.Max(new float[3] { ((Bounds)(ref bounds)).size.x, ((Bounds)(ref bounds)).size.y, ((Bounds)(ref bounds)).size.z }); if (num < 0.4f) { return 1; } if (num < 0.9f) { return 2; } if (num < 1.6f) { return 3; } return 4; } catch { return 1; } } [PunRPC] private void GluttonBuffRPC(int points, int dmgAdd, float massAdd, int hpAdd, PhotonMessageInfo _info = default(PhotonMessageInfo)) { //IL_0007: Unknown result type (might be due to invalid IL or missing references) if (SemiFunc.IsMultiplayer() && !SemiFunc.MasterOnlyRPC(_info)) { return; } try { _totalPoints += points; EnemyParent componentInParent = ((Component)this).GetComponentInParent<EnemyParent>(); if ((Object)(object)componentInParent != (Object)null) { HurtCollider[] componentsInChildren = ((Component)componentInParent).GetComponentsInChildren<HurtCollider>(true); foreach (HurtCollider obj in componentsInChildren) { obj.playerDamage += dmgAdd; } } _totalDamageAdded += dmgAdd; ApplyMassGrowth(massAdd); _totalMassAdded += massAdd; if (SemiFunc.IsMasterClientOrSingleplayer() && (Object)(object)_health != (Object)null) { EnemyHealth? health = _health; health.health += hpAdd; int healthCurrent = FusionShared.GetHealthCurrent(_health); if (healthCurrent > 0) { FusionShared.SetHealthCurrent(_health, healthCurrent + hpAdd); } } _totalHpAdded += hpAdd; Plugin.Log.LogInfo((object)$"[Glutton#{((Object)this).GetInstanceID()}] Grew stronger (+{points}pt, total {_totalPoints}) — this individual only."); } catch (Exception arg) { Plugin.Log.LogError((object)$"[Glutton] buff error: {arg}"); } } private void OnDisable() { if (_killed) { Regurgitate(withInvincibility: true); ResetGrowth(); _killed = false; } } private void OnDestroy() { Regurgitate(withInvincibility: false); } private void ResetGrowth() { if (_totalPoints == 0) { return; } try { EnemyParent componentInParent = ((Component)this).GetComponentInParent<EnemyParent>(); if (_totalDamageAdded != 0 && (Object)(object)componentInParent != (Object)null) { HurtCollider[] componentsInChildren = ((Component)componentInParent).GetComponentsInChildren<HurtCollider>(true); foreach (HurtCollider obj in componentsInChildren) { obj.playerDamage -= _totalDamageAdded; } } if (_totalMassAdded != 0f) { ApplyMassGrowth(0f - _totalMassAdded); } if (_totalHpAdded != 0 && SemiFunc.IsMasterClientOrSingleplayer() && (Object)(object)_health != (Object)null) { _health.health = Mathf.Max(1, _health.health - _totalHpAdded); } Plugin.Log.LogInfo((object)$"[Glutton#{((Object)this).GetInstanceID()}] Killed — growth reset (-{_totalPoints}pt undone)."); } catch (Exception arg) { Plugin.Log.LogError((object)$"[Glutton] growth reset error: {arg}"); } finally { _totalPoints = 0; _totalDamageAdded = 0; _totalMassAdded = 0f; _totalHpAdded = 0; } } private void OnEnable() { if (!SemiFunc.IsMasterClientOrSingleplayer()) { return; } foreach (PhysGrabObject item in _belly) { if (!((Object)(object)item == (Object)null)) { try { GluttonReturnedValuable.Hold(item, this); } catch { } } } } private void Regurgitate(bool withInvincibility) { //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_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_0034: 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_0071: Unknown result type (might be due to invalid IL or missing references) //IL_0076: Unknown result type (might be due to invalid IL or missing references) //IL_0079: Unknown result type (might be due to invalid IL or missing references) //IL_007a: Unknown result type (might be due to invalid IL or missing references) //IL_0086: Unknown result type (might be due to invalid IL or missing references) //IL_008d: 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) if (!SemiFunc.IsMasterClientOrSingleplayer() || _belly.Count == 0) { return; } Vector3 val = ((Component)this).transform.position + Vector3.up * 0.5f; int num = 0; foreach (PhysGrabObject item in _belly) { if ((Object)(object)item == (Object)null) { continue; } try { GluttonReturnedValuable.Release(item, this); item.OverrideDeactivateReset(); Vector2 val2 = Random.insideUnitCircle * 1.2f; item.Teleport(val + new Vector3(val2.x, 0.2f, val2.y), Quaternion.identity); if (withInvincibility) { FusionShared.ProtectValuable(item, Plugin.GluttonDropInvincibleSeconds.Value); GluttonReturnedValuable.Protect(item, ReworkAccess.Now + (double)Plugin.GluttonHurtEatCooldownSeconds.Value); } num++; } catch { } } _belly.Clear(); _mealGrowth.Clear(); if (num > 0) { Plugin.Log.LogInfo((object)$"[Glutton] Coughed up {num} valuables (killed={_killed})."); } } private void EnsureHpDoubled() { if (!_hpDone && !((Object)(object)_health == (Object)null)) { _hpDone = true; if (SemiFunc.IsMasterClientOrSingleplayer()) { FusionShared.SetHealthCurrent(_health, _health.health); } } } } [HarmonyPatch(typeof(EnemyHealth), "Hurt")] internal static class GluttonDamagePatch { private readonly struct HitState { internal readonly AnimalFusion? Glutton; internal readonly int Health; internal HitState(AnimalFusion glutton, int health) { Glutton = glutton; Health = health; } } private static void Prefix(EnemyHealth __instance, out HitState __state) { __state = default(HitState); if (SemiFunc.IsMasterClientOrSingleplayer() && !ReworkAccess.Read(__instance, "dead", fallback: false) && !ReworkAccess.Read(__instance, "deadImpulse", fallback: false)) { AnimalFusion animalFusion = ReworkAccess.Find<AnimalFusion>((Component)(object)__instance); if (!((Object)(object)animalFusion == (Object)null) && ((Behaviour)animalFusion).isActiveAndEnabled) { animalFusion.PrepareHealthForDamage(); __state = new HitState(animalFusion, FusionShared.GetHealthCurrent(__instance)); } } } private static void Postfix(EnemyHealth __instance, HitState __state) { if (!((Object)(object)__state.Glutton == (Object)null)) { int healthCurrent = FusionShared.GetHealthCurrent(__instance); if (healthCurrent > 0 && healthCurrent < __state.Health) { __state.Glutton.Damaged(); } } } } internal static class GroundHazard { internal static bool TryProject(Vector3 position, Vector3 reference, Transform? ignore, out Vector3 floor) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_0007: 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_0019: 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_002b: Unknown result type (might be due to invalid IL or missing references) //IL_0031: Unknown result type (might be due to invalid IL or missing references) //IL_0036: Unknown result type (might be due to invalid IL or missing references) //IL_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_009d: 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_00af: 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_00da: 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_00e9: Unknown result type (might be due to invalid IL or missing references) //IL_00ee: Unknown result type (might be due to invalid IL or missing references) floor = position; if (!Finite(position) || !Finite(reference)) { return false; } RaycastHit[] array = Physics.RaycastAll(new Vector3(position.x, reference.y + 0.35f, position.z), Vector3.down, 5f, LayerMask.GetMask(new string[1] { "Default" }), (QueryTriggerInteraction)1); float num = float.PositiveInfinity; RaycastHit[] array2 = array; for (int i = 0; i < array2.Length; i++) { RaycastHit val = array2[i]; if (!((Object)(object)((RaycastHit)(ref val)).collider == (Object)null) && (!((Object)(object)ignore != (Object)null) || !((Component)((RaycastHit)(ref val)).collider).transform.IsChildOf(ignore)) && GroundHazardRules.ValidFloor(((RaycastHit)(ref val)).point.y, reference.y, ((RaycastHit)(ref val)).normal.y) && !(((RaycastHit)(ref val)).distance >= num)) { num = ((RaycastHit)(ref val)).distance; floor = ((RaycastHit)(ref val)).point + Vector3.up * 0.08f; } } return !float.IsPositiveInfinity(num); } private static bool Finite(Vector3 p) { //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) //IL_0027: 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_0041: Unknown result type (might be due to invalid IL or missing references) if (!float.IsNaN(p.x) && !float.IsNaN(p.y) && !float.IsNaN(p.z) && !float.IsInfinity(p.x) && !float.IsInfinity(p.y)) { return !float.IsInfinity(p.z); } return false; } } internal static class HazardTiming { public static float ActiveDelta(float previous, float current, float warning, float lifetime) { return Math.Max(0f, Math.Min(current, warning + lifetime) - Math.Max(previous, warning)); } public static bool Exposure(ref float exposure, float elapsed, float threshold, bool exposed) { exposure = Math.Max(0f, exposure + Math.Max(0f, elapsed) * (exposed ? 1f : (-2f))); if (exposure < threshold) { return false; } exposure = 0f; return true; } public static int NextCut(ref float age, ref int next, float warning, float interval) { if (next >= 2 || age < warning + (float)next * interval) { return -1; } int result = next++; if (next == 1) { age = warning; } return result; } } public sealed class ChatterjawFusion : ReworkedMutation { internal static readonly Color AuraColor = new Color(1f, 0.36f, 0.45f); private EnemyHeadController _head; private double _nextCast; private ChatterjawSweep? _trap; private void Awake() { //IL_000d: Unknown result type (might be due to invalid IL or missing references) _head = ((Component)this).GetComponent<EnemyHeadController>(); Setup(AuraColor); _nextCast = ReworkAccess.Now + 2.0; } protected override void Update() { //IL_005b: Unknown result type (might be due to invalid IL or missing references) //IL_0061: Invalid comparison between Unknown and I4 //IL_0069: Unknown result type (might be due to invalid IL or missing references) //IL_006f: Invalid comparison between Unknown and I4 //IL_00a4: 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_00a9: Unknown result type (might be due to invalid IL or missing references) //IL_00aa: 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_00c1: Unknown result type (might be due to invalid IL or missing references) //IL_00d9: Unknown result type (might be due to invalid IL or missing references) //IL_00e4: Unknown result type (might be due to invalid IL or missing references) //IL_00ff: Unknown result type (might be due to invalid IL or missing references) //IL_0104: Unknown result type (might be due to invalid IL or missing references) //IL_0105: 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_0135: Unknown result type (might be due to invalid IL or missing references) //IL_0136: Unknown result type (might be due to invalid IL or missing references) //IL_013d: Unknown result type (might be due to invalid IL or missing references) //IL_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_0125: Unknown result type (might be due to invalid IL or missing references) //IL_012a: Unknown result type (might be due to invalid IL or missing references) base.Update(); if (!base.Living || base.Stunned) { ClearEffects(); _trap = null; } else { if (!base.Host || (Object)(object)_trap != (Object)null || (Object)(object)Enemy == (Object)null || ReworkAccess.Now < _nextCast || ((int)Enemy.CurrentState != 4 && (int)Enemy.CurrentState != 5)) { return; } Vector3 val = (((Object)(object)Body?.rb != (Object)null) ? Body.rb.position : ((Component)this).transform.position); PlayerAvatar val2 = FusionShared.NearestPlayer(val, 12f); if (!((Object)(object)val2 == (Object)null) && ReworkAccess.Clear(val, ReworkAccess.Chest(val2), Root) && GroundHazard.TryProject(((Component)val2).transform.position, ((Component)val2).transform.position, Root, out var floor)) { Vector3 val3 = ((Component)val2).transform.position - val; val3.y = 0f; if (((Vector3)(ref val3)).sqrMagnitude < 0.01f) { val3 = Vector3.forward; } Send(1, (Vector3[]?)(object)new Vector3[2] { floor, floor + ((Vector3)(ref val3)).normalized }); _nextCast = ReworkAccess.Now + 8.0; } } } internal void Bite() { if (base.Host && base.Living && !base.Stunned && (Object)(object)_trap != (Object)null) { Send(2); } } internal void BreakTrap() { if (base.Host && (Object)(object)_trap != (Object)null) { Send(3); } } protected override void Receive(int kind, Vector3[] points, int[] ids, double time, float value) { //IL_0046: 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_0054: 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_009b: Unknown result type (might be due to invalid IL or missing references) if (kind == 1 && points.Length == 2 && base.Living && !base.Stunned) { ClearEffects(); _trap = Effect<ChatterjawSweep>("Chatterjaw open floor jaw"); _trap.Initialize(this, points[0], points[1] - points[0], time); _nextCast = time + 8.0; EnemyHeadController head = _head; if (head != null) { EnemyHeadAnimationSystem animationSystem = head.AnimationSystem; if (animationSystem != null) { Sound teethChatter = animationSystem.TeethChatter; if (teethChatter != null) { teethChatter.Play(points[0], 1f, 1f, 1f, 1f); } } } } if (kind == 2) { _trap?.BeginSnap(time); } if (kind == 3) { ClearEffects(); _trap = null; } } } public sealed class ChatterjawSweep : MonoBehaviour { private ChatterjawFusion _source; private Vector3 _origin; private double _time; private double _snapTime; private bool _biting; private bool _resolved; private readonly Transform[] _upper = (Transform[])(object)new Transform[10]; private readonly Transform[] _lower = (Transform[])(object)new Transform[10]; private readonly Vector3[] _positions = (Vector3[])(object)new Vector3[10]; private LineRenderer _rim; internal void Initialize(ChatterjawFusion source, Vector3 origin, Vector3 forward, double time) { //IL_0008: Unknown result type (might be due to invalid IL or missing references) //IL_0009: Unknown result type (might be due to invalid IL or missing references) //IL_003b: 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_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_0063: Unknown result type (might be due to invalid IL or missing references) //IL_0079: Unknown result type (might be due to invalid IL or missing references) //IL_00b9: 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_00d7: 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_00e1: Unknown result type (might be due to invalid IL or missing references) //IL_00fd: Unknown result type (might be due to invalid IL or missing references) //IL_0102: Unknown result type (might be due to invalid IL or missing references) //IL_010c: Unknown result type (might be due to invalid IL or missing references) //IL_0111: Unknown result type (might be due to invalid IL or missing references) //IL_0125: Unknown result type (might be due to invalid IL or missing references) //IL_012a: Unknown result type (might be due to invalid IL or missing references) //IL_0151: Unknown result type (might be due to invalid IL or missing references) //IL_0156: Unknown result type (might be due to invalid IL or missing references) //IL_0160: Unknown result type (might be due to invalid IL or missing references) //IL_0165: 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) //IL_017e: Unknown result type (might be due to invalid IL or missing references) //IL_01a8: Unknown result type (might be due to invalid IL or missing references) //IL_01ae: Expected O, but got Unknown //IL_01c6: Unknown result type (might be due to invalid IL or missing references) //IL_01c7: Unknown result type (might be due to invalid IL or missing references) //IL_01d1: Unknown result type (might be due to invalid IL or missing references) //IL_01d6: Unknown result type (might be due to invalid IL or missing references) //IL_0253: Unknown result type (might be due to invalid IL or missing references) //IL_0267: Unknown result type (might be due to invalid IL or missing references) //IL_026c: Unknown result type (might be due to invalid IL or missing references) _source = source; _origin = origin; _time = time; Vector3[] array = (Vector3[])(object)new Vector3[33]; for (int i = 0; i < array.Length; i++) { float num = (float)i * (float)Math.PI * 2f / (float)(array.Length - 1); array[i] = origin + new Vector3(Mathf.Cos(num), 0f, Mathf.Sin(num)) * 2f; } _rim = ReworkVisual.Line(((Component)this).transform, ChatterjawFusion.AuraColor, 0.16f, array); for (int j = 0; j < _positions.Length; j++) { float num2 = (float)j * (float)Math.PI * 2f / (float)_positions.Length; _positions[j] = origin + new Vector3(Mathf.Cos(num2), 0f, Mathf.Sin(num2)) * 1.8f; _upper[j] = ReworkVisual.Shape(((Component)this).transform, (PrimitiveType)3, _positions[j] + Vector3.up * 1.3f, new Vector3(0.35f, 0.5f, 0.35f), Color.white).transform; _lower[j] = ReworkVisual.Shape(((Component)this).transform, (PrimitiveType)3, _positions[j] + Vector3.up * 0.2f, new Vector3(0.35f, 0.4f, 0.35f), Color.white).transform; } GameObject val = new GameObject("Breakable jaw molar"); val.transform.SetParent(((Component)this).transform, false); val.transform.position = origin + Vector3.up * 0.45f; val.layer = LayerMask.NameToLayer("PhysGrabObject"); ReworkTarget reworkTarget = val.AddComponent<ReworkTarget>(); reworkTarget.HitPoints = 20; reworkTarget.Radius = 0.45f; SphereCollider val2 = val.AddComponent<SphereCollider>(); val2.radius = 0.45f; reworkTarget.Hitbox = (Collider?)(object)val2; reworkTarget.Broken = source.BreakTrap; Rigidbody obj = val.AddComponent<Rigidbody>(); obj.isKinematic = true; obj.useGravity = false; ReworkVisual.Shape(val.transform, (PrimitiveType)3, val.transform.position, new Vector3(0.6f, 0.65f, 0.6f), ChatterjawFusion.AuraColor); } internal void BeginSnap(double time) { if (!_biting) { _biting = true; _snapTime = time; } } private bool Contact(PlayerAvatar player) { //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_000c: Unknown result type (might be due to invalid IL or missing references) //IL_0011: Unknown result type (might be due to invalid IL or missing references) //IL_0016: Unknown result type (might be due to invalid IL or missing references) //IL_0017: Unknown result type (might be due to invalid IL or missing references) //IL_001d: Unknown result type (might be due to invalid IL or missing references) //IL_0023: Unknown result type (might be due to invalid IL or missing references) //IL_0028: 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_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_004d: 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_0058: Unknown result type (might be due to invalid IL or missing references) Vector3 val = ((Component)player).transform.position - _origin; Vector2 val2 = new Vector2(val.x, val.z); if (JawTrapRules.Contact(((Vector2)(ref val2)).magnitude, val.y)) { return ReworkAccess.Clear(_origin + Vector3.up * 0.4f, ReworkAccess.Chest(player), _source.Root); } return false; } private void Update() { //IL_0115: Unknown result type (might be due to invalid IL or missing references) //IL_010e: Unknown result type (might be due to invalid IL or missing references) //IL_011a: Unknown result type (might be due to invalid IL or missing references) //IL_011b: 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_013f: 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) //IL_0159: Unknown result type (might be due to invalid IL or missing references) //IL_015e: 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) //IL_017e: Unknown result type (might be due to invalid IL or missing references) //IL_0193: Unknown result type (might be due to invalid IL or missing references) //IL_0198: Unknown result type (might be due to invalid IL or missing references) //IL_0236: Unknown result type (might be due to invalid IL or missing references) //IL_023b: Unknown result type (might be due to invalid IL or missing references) //IL_0216: 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) if (!((Behaviour)this).isActiveAndEnabled || (Object)(object)_source == (Object)null || !_source.Living || _source.Stunned) { ((Component)this).gameObject.SetActive(false); Object.Destroy((Object)(object)((Component)this).gameObject); return; } double num = ReworkAccess.Now - _time; if (!_biting && _source.Host && num >= 1.5 && num < 8.0) { foreach (PlayerAvatar item in FusionShared.AllPlayers()) { if (ReworkAccess.Alive(item) && Contact(item)) { _source.Bite(); break; } } } float num2 = (_biting ? Mathf.Clamp01((float)((ReworkAccess.Now - _snapTime) / 0.6499999761581421)) : 0f); LineRenderer rim = _rim; Color startColor = (_rim.endColor = (_biting ? Color.red : ChatterjawFusion.AuraColor)); rim.startColor = startColor; for (int i = 0; i < _positions.Length; i++) { _upper[i].position = _positions[i] + Vector3.up * Mathf.Lerp(1.3f, 0.45f, num2); _lower[i].position = _positions[i] + Vector3.up * Mathf.Lerp(0.2f, 0.45f, num2); } if (_biting && !_resolved && ReworkAccess.Now - _snapTime >= 0.6499999761581421) { _resolved = true; EnemyHeadController component = ((Component)_source).GetComponent<EnemyHeadController>(); if (component != null) { EnemyHeadAnimationSystem animationSystem = component.AnimationSystem; if (animationSystem != null) { Sound teethChatter = animationSystem.TeethChatter; if (teethChatter != null) { teethChatter.Play(_origin, 1f, 1f, 1f, 1f); } } } ReworkVisual.Burst(_origin, ChatterjawFusion.AuraColor, 2f); foreach (PlayerAvatar item2 in FusionShared.AllPlayers()) { if (ReworkAccess.Alive(item2) && FusionShared.IsLocalPlayer(item2) && Contact(item2)) { FusionShared.HurtOwnedPlayer(item2, 75, _origin, _source.Enemy); } } } if (num >= 8.649999618530273 || (_resolved && ReworkAccess.Now - _snapTime > 1.049999976158142)) { ((Component)this).gameObject.SetActive(false); Object.Destroy((Object)(object)((Component)this).gameObject); } } } public sealed class KaleidoscopePrismSweep : MonoBehaviour { private static readonly Color[] BladeColors = (Color[])(object)new Color[3] { new Color(0.05f, 1f, 1f), new Color(1f, 0.12f, 0.8f), new Color(1f, 0.85f, 0.08f) }; private readonly LineRenderer[] _blades = (LineRenderer[])(object)new LineRenderer[3]; private readonly Material?[] _materials = (Material?[])(object)new Material[3]; private readonly HashSet<int> _hitPlayers = new HashSet<int>(); private Vector3 _center; private float _baseAngle; private float _warning; private float _sweepSeconds; private float _radius; private float _halfWidth; private int _damage; private Enemy? _source; private Transform? _sourceRoot; private float _age; public void Initialize(Vector3 center, Vector3 forward, float warning, float sweepSeconds, float radius, float halfWidth, int damage, Enemy? source) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_0030: Unknown result type (might be due to invalid IL or missing references) //IL_0036: Unknown result type (might be due to invalid IL or missing references) //IL_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_00c7: Unknown result type (might be due to invalid IL or missing references) //IL_00cc: Unknown result type (might be due to invalid IL or missing references) //IL_0153: Unknown result type (might be due to invalid IL or missing references) //IL_0158: 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_0132: Expected O, but got Unknown _center = center; forward.y = 0f; if (((Vector3)(ref forward)).sqrMagnitude < 0.01f) { forward = Vector3.forward; } ((Vector3)(ref forward)).Normalize(); _baseAngle = Mathf.Atan2(forward.z, forward.x); _warning = warning; _sweepSeconds = sweepSeconds; _radius = radius; _halfWidth = halfWidth; _damage = damage; _source = source; object sourceRoot; if (source == null) { sourceRoot = null; } else { EnemyParent componentInParent = ((Component)source).GetComponentInParent<EnemyParent>(); sourceRoot = ((componentInParent != null) ? ((Component)componentInParent).transform : null); } _sourceRoot = (Transform?)sourceRoot; Shader val = Shader.Find("Sprites/Default") ?? Shader.Find("Unlit/Color"); for (int i = 0; i < _blades.Length; i++) { GameObject val2 = new GameObject($"PrismBlade{i + 1}"); val2.transform.SetParent(((Component)this).transform, false); LineRenderer val3 = val2.AddComponent<LineRenderer>(); _blades[i] = val3; val3.useWorldSpace = true; val3.positionCount = 2; val3.widthMultiplier = _halfWidth * 2f; ((Renderer)val3).shadowCastingMode = (ShadowCastingMode)0; ((Renderer)val3).receiveShadows = false; if ((Object)(object)val != (Object)null) { _materials[i] = new Material(val); ((Renderer)val3).material = _materials[i]; } } FusionShared.SpawnWarningRing(_center, KaleidoscopeFusion.AuraColor, 0.2f, _radius, Mathf.Min(0.8f, _warning)); UpdateBlades(_baseAngle, active: false); } private void Update() { float age = _age; _age += Time.deltaTime; float num = Mathf.Clamp01((age - _warning) / _sweepSeconds); float num2 = Mathf.Clamp01((_age - _warning) / _sweepSeconds); float num3 = (float)Math.PI * 2f / 3f; float previousAngle = _baseAngle + num * num3; float num4 = _baseAngle + num2 * num3; bool flag = num2 > 0f; UpdateBlades(num4, flag); if (flag) { TestSweptBlades(previousAngle, num4); } if (_age >= _warning + _sweepSeconds) { Object.Destroy((Object)(object)((Component)this).gameObject); } } private void UpdateBlades(float angle, bool active) { //IL_0037: 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_0046: Unknown result type (might be due to invalid IL or missing references) //IL_004b: Unknown result type (might be due to invalid IL or missing references) //IL_0050: Unknown result type (might be due to invalid IL or missing references) //IL_0052: Unknown result type (might be due to invalid IL or missing references) //IL_0053: 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_005f: 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_0081: 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_00cc: 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_00cf: 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) Vector3 direction = default(Vector3); for (int i = 0; i < _blades.Length; i++) { float num = angle + (float)i / 3f * (float)Math.PI * 2f; ((Vector3)(ref direction))..ctor(Mathf.Cos(num), 0f, Mathf.Sin(num)); Vector3 val = _center + Vector3.up * 0.5f; Vector3 val2 = Clip(val, direction, _radius); LineRenderer val3 = _blades[i]; if (!((Object)(object)val3 == (Object)null)) { val3.SetPosition(0, val); val3.SetPosition(1, val2); Color val4 = BladeColors[i]; val4.a = (active ? 0.9f : (0.28f + Mathf.Abs(Mathf.Sin(_age * 9f)) * 0.35f)); Color startColor = (val3.endColor = val4); val3.startColor = startColor; } } } private Vector3 Clip(Vector3 start, Vector3 direction, float distance) { //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_0013: Unknown result type (might be due to invalid IL or missing references) return FusionShared.ClipToDefaultCover(start, direction, distance, _sourceRoot); } private void TestSweptBlades(float previousAngle, float currentAngle) { //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) //IL_0067: Unknown result type (might be due to invalid IL or missing references) //IL_006c: Unknown result type (might be due to invalid IL or missing references) //IL_0071: Unknown result type (might be due to invalid IL or missing references) //IL_0072: Unknown result type (might be due to invalid IL or missing references) //IL_0074: Unknown result type (might be due to invalid IL or missing references) //IL_0079: Unknown result type (might be due to invalid IL or missing references) //IL_0083: Unknown result type (might be due to invalid IL or missing references) //IL_0088: Unknown result type (might be due to invalid IL or missing references) //IL_008d: Unknown result type (might be due to invalid IL or missing references) //IL_0092: Unknown result type (might be due to invalid IL or missing references) //IL_0094: Unknown result type (might be due to invalid IL or missing references) //IL_00d4: Unknown result type (might be due to invalid IL or missing references) //IL_00d9: Unknown result type (might be due to invalid IL or missing references) //IL_00e3: Unknown result type (might be due to invalid IL or missing references) //IL_00e8: Unknown result type (might be due to invalid IL or missing references) //IL_00ed: Unknown result type (might be due to invalid IL or missing references) //IL_0108: 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_01a8: 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_01c9: Unknown result type (might be due to invalid IL or missing references) //IL_01ea: Unknown result type (might be due to invalid IL or missing references) //IL_01e3: Unknown result type (might be due to invalid IL or missing references) //IL_01ec: Unknown result type (might be due to invalid IL or missing references) foreach (PlayerAvatar item in FusionShared.AllPlayers()) { if ((Object)(object)item == (Object)null || !FusionShared.IsLocalPlayer(item) || FusionShared.IsPlayerDisabled(item)) { continue; } int instanceID = ((Object)item).GetInstanceID(); if (_hitPlayers.Contains(instanceID)) { continue; } Vector3 val = ((Component)item).transform.position + Vector3.up * 0.5f; Vector3 val2 = val - (_center + Vector3.up * 0.5f); float num = Mathf.Abs(val2.y); val2.y = 0f; float magnitude = ((Vector3)(ref val2)).magnitude; if (num > 2.3f || magnitude > _radius + _halfWidth || FusionShared.HasDefaultCover(_center + Vector3.up * 0.5f, val, _sourceRoot)) { continue; } float angle = Mathf.Atan2(val2.z, val2.x); float tolerance = ((magnitude <= _halfWidth) ? ((float)Math.PI) : Mathf.Asin(Mathf.Clamp(_halfWidth / magnitude, 0f, 1f))); bool flag = false; for (int i = 0; i < 3; i++) { float num2 = (float)i / 3f * (float)Math.PI * 2f; if (AttackGeometry.AngleInPositiveSweep(angle, previousAngle + num2, currentAngle + num2, tolerance)) { flag = true; break; } } if (flag) { _hitPlayers.Add(instanceID); FusionShared.HurtOwnedPlayer(item, _damage, _center, _source); FusionShared.SpawnWarningRing(GroundHazard.TryProject(((Component)item).transform.position, ((Component)item).transform.position, _sourceRoot, out var floor) ? floor : ((Component)item).transform.position, Color.white, 1.25f, 0.1f, 0.28f); } } } private void OnDestroy() { Material[] materials = _materials; foreach (Material val in materials) { if ((Object)(object)val != (Object)null) { Object.Destroy((Object)(object)val); } } } } internal sealed class MutationGenerationSettings { internal const int WireVersion = 1; internal readonly int HostActor; internal readonly float ChancePerLevel; internal readonly float MaxChance; internal readonly int MaxMutantsPerLevel; internal readonly int SurgeInterval; internal readonly string DisabledMutants; internal MutationGenerationSettings(int hostActor, float chancePerLevel, float maxChance, int maxMutantsPerLevel, int surgeInterval, string disabledMutants) { HostActor = hostActor; ChancePerLevel = chancePerLevel; MaxChance = maxChance; MaxMutantsPerLevel = maxMutantsPerLevel; SurgeInterval = surgeInterval; DisabledMutants = disabledMutants ?? ""; } internal object[] ToWire() { return new object[7] { 1, HostActor, ChancePerLevel, MaxChance, MaxMutantsPerLevel, SurgeInterval, DisabledMutants }; } internal static bool TryFromWire(object raw, int expectedHostActor, out MutationGenerationSettings settings) { settings = null; if (!(raw is object[] array) || array.Length != 7 || !(array[0] is int num) || num != 1 || !(array[1] is int num2) || num2 <= 0 || num2 != expectedHostActor || !(array[2] is float num3) || float.IsNaN(num3) || float.IsInfinity(num3) || !(array[3] is float num4) || float.IsNaN(num4) || float.IsInfinity(num4) || !(array[4] is int num5) || num5 < 0 || !(array[5] is int num6) || num6 < 0 || !(array[6] is string disabledMutants)) { return false; } settings = new MutationGenerationSettings(num2, num3, num4, num5, num6, disabledMutants); return true; } internal bool SameRulesAs(MutationGenerationSettings other) { if (other != null && ChancePerLevel == other.ChancePerLevel && MaxChance == other.MaxChance && MaxMutantsPerLevel == other.MaxMutantsPerLevel && SurgeInterval == other.SurgeInterval) { return string.Equals(DisabledMutants, other.DisabledMutants, StringComparison.Ordinal); } return false; } } internal static class MutationHostSync { internal const string RoomPropertyKey = "com.matsu.repomutations.generation.v1"; private static Room? _room; private static int _hostActor; private static MutationGenerationSettings? _hostFrozen; private static MutationGenerationSettings? _effective; private static float _nextPublishAttempt; private static bool _loggedHostRules; private static bool _loggedGuestRules; private static bool _loggedLocalDifference; private static MutationHostSyncDriver? _driver; internal static MutationGenerationSettings Current => _effective ?? Local(0); internal static void Install() { SceneManager.sceneLoaded -= OnSceneLoaded; SceneManager.sceneLoaded += OnSceneLoaded; EnsureDriver(); } private static void OnSceneLoaded(Scene _, LoadSceneMode __) { EnsureDriver(); } private static void EnsureDriver() { //IL_0013: Unknown result type (might be due to invalid IL or missing references) //IL_0018: Unknown result type (might be due to invalid IL or missing references) //IL_001e: Expected O, but got Unknown if (!((Object)(object)_driver != (Object)null)) { GameObject val = new GameObject("REPO Mutant Enemies host settings"); Object.DontDestroyOnLoad((Object)val); _driver = val.AddComponent<MutationHostSyncDriver>(); Plugin.Log.LogInfo((object)"[Mutation Sync] Persistent room-settings driver ready."); } } internal static bool TryGet(out MutationGenerationSettings settings) { if (!PhotonNetwork.InRoom || PhotonNetwork.CurrentRoom == null) { ResetRoom(); settings = Local(0); _effective = settings; return true; } Room currentRoom = PhotonNetwork.CurrentRoom; int num = ((PhotonNetwork.MasterClient != null) ? PhotonNetwork.MasterClient.ActorNumber : 0); if (_room != currentRoom || _hostActor != num) { _room = currentRoom; _hostActor = num; _hostFrozen = null; _effective = null; _nextPublishAttempt = 0f; _loggedHostRules = false; _loggedGuestRules = false; _loggedLocalDifference = false; } if (num <= 0) { settings = null; return false; } if (PhotonNetwork.IsMasterClient) { if (_hostFrozen == null) { _hostFrozen = Local(num); } settings = _hostFrozen; _effective = settings; Publish(currentRoom, settings); return true; } if (((Dictionary<object, object>)(object)((RoomInfo)currentRoom).CustomProperties).TryGetValue((object)"com.matsu.repomutations.generation.v1", out object value) && MutationGenerationSettings.TryFromWire(value, num, out settings)) { _effective = settings; if (!_loggedGuestRules) { _loggedGuestRules = true; Plugin.Log.LogInfo((object)($"[Mutation Sync] Using host {num}'s level cap {settings.MaxMutantsPerLevel}, " + $"surge interval {settings.SurgeInterval}, chance {settings.ChancePerLevel}, " + $"max chance {settings.MaxChance} and disabled-mutant list.")); } if (!_loggedLocalDifference && !settings.SameRulesAs(Local(num))) { _loggedLocalDifference = true; Plugin.Log.LogInfo((object)"[Mutation Sync] Local mutation-generation settings differ; the host's settings take precedence for this room."); } return true; } _effective = null; settings = null; return false; } private static MutationGenerationSettings Local(int actor) { return new MutationGenerationSettings(actor, Plugin.MutationChancePerLevel.Value, Plugin.MutationMaxChance.Value, Mathf.Max(0, Plugin.MutationMaxMutantsPerLevel.Value), Mathf.Max(0, Plugin.MutationSurgeInterval.Value), Plugin.MutationDisabledMutants.Value ?? ""); } private static void Publish(Room room, MutationGenerationSettings settings) { //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_0062: Expected O, but got Unknown //IL_0069: Expected O, but got Unknown if ((!((Dictionary<object, object>)(object)((RoomInfo)room).CustomProperties).TryGetValue((object)"com.matsu.repomutations.generation.v1", out object value) || !MutationGenerationSettings.TryFromWire(value, settings.HostActor, out MutationGenerationSettings settings2) || !settings2.SameRulesAs(settings)) && !(Time.realtimeSinceStartup < _nextPublishAttempt)) { _nextPublishAttempt = Time.realtimeSinceStartup + 2f; Hashtable val = new Hashtable(); ((Dictionary<object, object>)val).Add((object)"com.matsu.repomutations.generation.v1", (object)settings.ToWire()); if (room.SetCustomProperties(val, (Hashtable)null, (WebFlags)null) && !_loggedHostRules) { _loggedHostRules = true; Plugin.Log.LogInfo((object)($"[Mutation Sync] Host published level cap {settings.MaxMutantsPerLevel}, " + $"surge interval {settings.SurgeInterval} and mutation-selection settings for this room.")); } } } private static void ResetRoom() { if (_room != null) { _room = null; _hostActor = 0; _hostFrozen = null; _effective = null; _loggedHostRules = false; _loggedGuestRules = false; _loggedLocalDifference = false; MutationAttach.ClearPending(); } } internal static void Tick() { if (TryGet(out MutationGenerationSettings _)) { MutationAttach.FlushPending(); } } } internal sealed class MutationHostSyncDriver : MonoBehaviour { private void Update() { MutationHostSync.Tick(); } } internal static class MutationRules { public static bool IsSurge(int displayedLevel, int interval) { if (displayedLevel > 0 && interval > 0) { return displayedLevel % interval == 0; } return false; } public static float Chance(int displayedLevel, int interval, float perLevel, float cap) { if (IsSurge(displayedLevel, interval)) { return 1f; } return Math.Min((float)displayedLevel * perLevel, cap); } public static float Roll(int id, uint salt) { int num = (int)((uint)id ^ salt) * -1640531535; int num2 = (num ^ (num >>> 13)) * -1640531535; return (float)(uint)((num2 ^ (num2 >>> 16)) & 0xFFFFFF) / 16777216f; } public static int HunterVariant(int id, bool deadeyeEnabled, bool ricochetEnabled) { if (!deadeyeEnabled) { if (!ricochetEnabled) { return 0; } return 2; } if (!ricochetEnabled) { return 1; } if (!(Roll(id, 2713765095u) < 0.5f)) { return 1; } return 2; } public static int TickVariant(int id, bool bloodBankEnabled, bool powerLeechEnabled) { if (!bloodBankEnabled) { if (!powerLeechEnabled) { return 0; } return 2; } if (!powerLeechEnabled) { return 1; } if (!(Roll(id, 1909172081u) < 0.5f)) { return 1; } return 2; } public static bool ShouldExplodeBalloonRemoval(bool manualRemove, bool isAuthority) { if (isAuthority) { return !manualRemove; } return false; } } internal sealed class MutationBudget { private readonly Dictionary<int, int> reservations = new Dictionary<int, int>(); private int level = -1; private int sceneHandle = int.MinValue; internal int Used { get; private set; } internal void BeginLevel(int displayedLevel, int currentSceneHandle) { if (level != displayedLevel || sceneHandle != currentSceneHandle) { level = displayedLevel; sceneHandle = currentSceneHandle; reservations.Clear(); Used = 0; } } internal bool TryReserve(int id, int bodies, int maximum) { if (reservations.ContainsKey(id)) { return true; } bodies = Math.Max(1, bodies); maximum = Math.Max(0, maximum); if (maximum != 0 && (bodies > maximum || Used > maximum - bodies)) { return false; } reservations.Add(id, bodies); Used = ((Used > int.MaxValue - bodies) ? int.MaxValue : (Used + bodies)); return true; } internal int Remaining(int maximum) { if (maximum > 0) { return Math.Max(0, maximum - Used); } return int.MaxValue; } } internal static class FusionShared { private static ParticleScriptExplosion? _sharedExplosion; private static GameObject? _explosionPrefab; private static readonly List<PlayerAvatar> _noPlayers = new List<PlayerAvatar>(); private static FieldInfo? _healthCurrentField; private static FieldInfo? _impactDetectorField; private static MethodInfo? _hurtMultiplierMethod; private static FieldInfo? _explSizeField; private static FieldInfo? _explDmgField; private static FieldInfo? _explDmgEnemyField; private const string AuraLightName = "MatsuMutationAura"; private static readonly List<Renderer> AuraRenderers = new List<Renderer>(64); private static readonly List<Material> AuraMaterials = new List<Material>(8); private static PropertyInfo? _navAgentProp; private static FieldInfo? _navAgentField; private static MethodInfo? _navDisableMethod; private static FieldInfo? _wrapAgentField; private static FieldInfo? _damageResistanceField; private static FieldInfo? _damageResistanceTimerField; private static FieldInfo? _tumbleField; private static FieldInfo? _tumblePhysGrabObjectField; private static FieldInfo? _clientPositionField; private static FieldInfo? _clientPositionCurrentField; private static FieldInfo? _visualPositionField; private static FieldInfo? _isDisabledField; private static readonly RaycastHit[] CoverHits = (RaycastHit[])(object)new RaycastHit[32]; public static List<PlayerAvatar> AllPlayers() { GameDirector instance = GameDirector.instance; if (!((Object)(object)instance != (Object)null) || instance.PlayerList == null) { return _noPlayers; } return instance.PlayerList; } public static bool NearestPlayerWithin(Vector3 from, float range) { //IL_003e: Unknown result type (might be due to invalid IL or missing references) //IL_0045: Unknown result type (might be due to invalid IL or missing references) //IL_004a: Unknown result type (might be due to invalid IL or missing references) //IL_004f: Unknown result type (might be due to invalid IL or missing references) float num = Mathf.Max(0f, range) * Mathf.Max(0f, range); foreach (PlayerAvatar item in AllPlayers()) { if (!((Object)(object)item == (Object)null) && !IsPlayerDisabled(item)) { Vector3 val = from - ((Component)item).transform.position; if (((Vector3)(ref val)).sqrMagnitude <= num) { return true; } } } return false; } public static List<PlayerAvatar> PlayersInRadius(Vector3 center, float radius) { //IL_0044: Unknown result type (might be due to invalid IL or missing references) //IL_004b: Unknown result type (might be due to invalid IL or missing references) //IL_0050: 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<PlayerAvatar> list = new List<PlayerAvatar>(); float num = Mathf.Max(0f, radius) * Mathf.Max(0f, radius); foreach (PlayerAvatar item in AllPlayers()) { if (!((Object)(object)item == (Object)null) && !IsPlayerDisabled(item)) { Vector3 val = center - ((Component)item).transform.position; if (((Vector3)(ref val)).sqrMagnitude <= num) { list.Add(item); } } } return list; } public static PlayerAvatar? NearestPlayer(Vector3 from, float maxDistance) { //IL_0040: 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) PlayerAvatar result = null; float num = Mathf.Max(0f, maxDistance) * Mathf.Max(0f, maxDistance); foreach (PlayerAvatar item in AllPlayers()) { if (!((Object)(object)item == (Object)null) && !IsPlayerDisabled(item)) { Vector3 val = from - ((Component)item).transform.position; float sqrMagnitude = ((Vector3)(ref val)).sqrMagnitude; if (sqrMagnitude <= num) { num = sqrMagnitude; result = item; } } } return result; } public static List<PhysGrabObject> PhysObjectsInRadius(Vector3 center, float radius) { //IL_0006: Unknown result type (might be due to invalid IL or missing references) HashSet<PhysGrabObject> hashSet = new HashSet<PhysGrabObject>(); Collider[] array = Physics.OverlapSphere(center, radius); foreach (Collider val in array) { if (!((Object)(object)val == (Object)null)) { PhysGrabObject componentInParent = ((Component)val).GetComponentInParent<PhysGrabObject>(); if ((Object)(object)componentInParent != (Object)null && (Object)(object)componentInParent.rb != (Object)null && !componentInParent.grabbed && (Object)(object)((Component)componentInParent).GetComponentInParent<EnemyParent>() == (Object)null) { hashSet.Add(componentInParent); } } } return new List<PhysGrabObject>(hashSet); } private static void SetExplField(ParticlePrefabExplosion pe, ref FieldInfo? cache, string name, object val) { try { if ((object)cache == null) { cache = typeof(ParticlePrefabExplosion).GetField(name, BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); } cache?.SetValue(pe, val); } catch { } } public static ParticlePrefabExplosion? ExplodeAuthoritative(Vector3 pos, float size, int playerDmg, int enemyDmg, PhysGrabObject? ignoreSelf = null, Enemy? enemyHost = null, float force = 1f) { //IL_002c: Unknown result type (might be due to invalid IL or missing references) //IL_0083: Unknown result type (might be due to invalid IL or missing references) //IL_0084: Unknown result type (might be due to invalid IL or missing references) ParticlePrefabExplosion val = null; if ((Object)(object)_sharedExplosion == (Object)null) { _sharedExplosion = Object.FindObjectOfType<ParticleScriptExplosion>(true); } if ((Object)(object)_sharedExplosion != (Object)null) { try { val = _sharedExplosion.Spawn(pos, size, playerDmg, enemyDmg, force, false, false, 1f); } catch { val = null; } } if ((Object)(object)val == (Object)null) { if ((Object)(object)_explosionPrefab == (Object)null) { _explosionPrefab = Resources.Load<GameObject>("Effects/Part Prefab Explosion"); } if ((Object)(object)_explosionPrefab != (Object)null) { val = Object.Instantiate<GameObject>(_explosionPrefab, pos, Quaternion.identity).GetComponent<ParticlePrefabExplosion>(); if ((Object)(object)val != (Object)null) { SetExplField(val, ref _explSizeField, "explosionSize", size); SetExplField(val, ref _explDmgField, "explosionDamage", playerDmg); SetExplField(val, ref _explDmgEnemyField, "explosionDamageEnemy", enemyDmg); try { ParticleSystem particleFire = val.particleFire; if (particleFire != null) { particleFire.Play(); } ParticleSystem particleSmoke = val.particleSmoke; if (particleSmoke != null) { particleSmoke.Play(); } if ((Object)(object)val.light != (Object)null) { ((Behaviour)val.light).enabled = true; } } catch { } } } } if ((Object)(object)val != (Object)null && (Object)(object)val.HurtCollider != (Object)null) { try { if ((Object)(object)ignoreSelf != (Object)null && val.HurtCollider.ignoreObjects != null) { val.HurtCollider.ignoreObjects.Add(ignoreSelf); } if ((Object)(object)enemyHost != (Object)null) { val.HurtCollider.enemyHost = enemyHost; } } catch { } } return val; } public static void ApplyMutationGlow(Transform root, Color color) { //IL_00bb: 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_002e: Unknown result type (might be due to invalid IL or missing references) //IL_0033: Unknown result type (might be due to invalid IL or missing references) //IL_0040: 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_006e: 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_0184: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)root == (Object)null) { return; } try { Transform val = root.Find("MatsuMutationAura"); Light val2; if ((Object)(object)val != (Object)null) { val2 = ((Component)val).GetComponent<Light>(); } else { GameObject val3 = new GameObject("MatsuMutationAura"); val3.transform.SetParent(root, false); val3.transform.localPosition = Vector3.zero; val2 = val3.AddComponent<Light>(); val2.type = (LightType)2; val2.shadows = (LightShadows)0; } if ((Object)(object)val2 != (Object)null) { val2.color = color; val2.range = Plugin.MutationAuraRange.Value; val2.intensity = Plugin.MutationAuraIntensity.Value; val2.renderMode = (LightRenderMode)1; } } catch { } float num = Mathf.Max(1f, Plugin.MutationAuraIntensity.Value * 0.6f); Color val4 = color * num; EnemyParent componentInParent = ((Component)root).GetComponentInParent<EnemyParent>(); ((Component)(((componentInParent != null) ? ((Component)componentInParent).transform : null) ?? root)).GetComponentsInChildren<Renderer>(true, AuraRenderers); foreach (Renderer auraRenderer in AuraRenderers) { if ((Object)(object)auraRenderer == (Object)null || ((Object)((Component)auraRenderer).gameObject).name == "MatsuMutationAura") { continue; } auraRenderer.GetMaterials(AuraMaterials); foreach (Material auraMaterial in AuraMaterials) { if ((Object)(object)auraMaterial == (Object)null) { continue; } try { if (auraMaterial.HasProperty("_EmissionColor")) { auraMaterial.EnableKeyword("_EMISSION"); auraMaterial.globalIlluminationFlags = (MaterialGlobalIlluminationFlags)1; auraMaterial.SetColor("_EmissionColor", val4); } auraMaterial.SetFloat("_FresnelAmount", 1f); auraMaterial.SetFloat("_FresnelScale", 1f); auraMaterial.SetFloat("_FresnelPower", 5f); auraMaterial.SetFloat("_FresnelBias", 0f); auraMaterial.SetColor("_FresnelColor", color); auraMaterial.SetFloat("_FresnelEmission", 1f); } catch { } } } AuraMaterials.Clear(); AuraRenderers.Clear(); } public static void SetHealthCurrent(EnemyHealth health, int value) { try { if (_healthCurrentField == null) { _healthCurrentField = typeof(EnemyHealth).GetField("healthCurrent", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); } _healthCurrentField?.SetValue(health, value); } catch { } } public static void ProtectValuable(PhysGrabObject pgo, float seconds) { try { if (pgo != null) { pgo.OverrideIndestructible(Mathf.Max(0.1f, seconds)); } } catch { } } public static void ExplodePlayerOnly(Vector3 pos, float size, int playerDamage, float force, Enemy? source = null) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) ParticlePrefabExplosion val = ExplodeAuthoritative(pos, size, playerDamage, 0, null, source, force); try { if ((Object)(object)val == (Object)null || (Object)(object)val.HurtCollider == (Object)null || val.HurtCollider.ignoreObjects == null) { return; } EnemyDirector instance = EnemyDirector.instance; if ((Object)(object)instance == (Object)null || instance.enemiesSpawned == null) { return; } foreach (EnemyParent item2 in instance.enemiesSpawned) { if (!((Object)(object)item2 == (Object)null)) { PhysGrabObject[] componentsInChildren = ((Component)item2).GetComponentsInChildren<PhysGrabObject>(true); foreach (PhysGrabObject item in componentsInChildren) { val.HurtCollider.ignoreObjects.Add(item); } } } } catch { } } public static void ExplodeGrenadePlayerOnly(Vector3 pos) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) ExplodePlayerOnly(pos, 0.8f, 50, 2f); } public static void FreezeAgent(Enemy enemy) { try { if ((Object)(object)enemy == (Object)null) { return; } object obj = null; if ((object)_navAgentProp == null) { _navAgentProp = typeof(Enemy).GetProperty("NavMeshAgent", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); } if (_navAgentProp != null) { obj = _navAgentProp.GetValue(enemy);