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 PresentMimic v0.4.1
BepInEx/plugins/PresentMimic/WyattMorse.PresentMimic.dll
Decompiled 12 hours ago
The result has been truncated due to the large size, download it to view full contents!
using System; using System.Collections.Generic; using System.Diagnostics; using System.Linq; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using System.Security; using System.Security.Permissions; using BepInEx; using BepInEx.Configuration; using BepInEx.Logging; using GameNetcodeStuff; using HarmonyLib; using LethalLib.Modules; using Microsoft.CodeAnalysis; using PresentMimic.Visuals; using Unity.Collections; using Unity.Netcode; using UnityEngine; using UnityEngine.AI; using UnityEngine.InputSystem; using UnityEngine.InputSystem.Controls; using UnityEngine.Rendering; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)] [assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")] [assembly: AssemblyCompany("WyattMorse.PresentMimic")] [assembly: AssemblyConfiguration("Debug")] [assembly: AssemblyFileVersion("0.4.0.0")] [assembly: AssemblyInformationalVersion("0.4.0")] [assembly: AssemblyProduct("PresentMimic")] [assembly: AssemblyTitle("WyattMorse.PresentMimic")] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("0.4.0.0")] [module: UnverifiableCode] [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 PresentMimic { internal static class MimicAssets { internal static GameObject Prefab; internal static GameObject OpenedPrefab; internal static Item Definition; internal static AudioClip Creak; internal static AudioClip Reveal; internal static AudioClip Bite; internal static AudioClip Growl; internal static AudioClip Footstep; internal static void Build() { //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) Definition = ScriptableObject.CreateInstance<Item>(); ((Object)Definition).name = "PresentMimicItem"; Definition.itemId = 940502; Definition.itemName = "Present"; Definition.isScrap = false; Definition.minValue = (Definition.maxValue = 0); Definition.requiresBattery = false; Definition.weight = 1.04f; Definition.canBeInspected = false; Definition.itemSpawnsOnGround = true; Definition.restingRotation = Vector3.zero; Definition.verticalOffset = 0.02f; Definition.syncGrabFunction = false; Definition.syncUseFunction = false; Definition.syncDiscardFunction = false; Definition.toolTips = new string[1] { "Something shifts inside..." }; Definition.grabAnimationTime = 0.25f; Prefab = BuildPrefab("WyattMorse.PresentMimic.Gift.v1", opened: false); OpenedPrefab = BuildPrefab("WyattMorse.PresentMimic.OpenedGift.v1", opened: true); Definition.spawnPrefab = Prefab; Creak = Sound("Original cardboard creak", 0.45f, 155f, 0.15f); Reveal = CreatureSound("Mimic fallback chest roar", 2.1f, loop: false, 712); Growl = CreatureSound("Mimic fallback breathing growl", 3.6f, loop: true, 918); Bite = CreatureSound("Mimic fallback jaw impact", 0.22f, loop: false, 310); Footstep = Sound("Mimic footfall", 0.12f, 48f, 0.6f); Items.RegisterItem(Definition); } private static GameObject BuildPrefab(string name, bool opened) { //IL_003f: 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_00b2: Unknown result type (might be due to invalid IL or missing references) //IL_00b9: Expected O, but got Unknown //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) GameObject val = NetworkPrefabs.CreateNetworkPrefab(name); val.GetComponent<NetworkObject>().AutoObjectParentSync = false; val.layer = 6; val.tag = "PhysicsProp"; BoxCollider val2 = val.AddComponent<BoxCollider>(); val2.size = new Vector3(0.55f, 0.55f, 0.55f); val2.center = new Vector3(0f, 0.27f, 0f); Rigidbody val3 = val.AddComponent<Rigidbody>(); val3.isKinematic = true; val3.useGravity = false; MimicGift mimicGift = val.AddComponent<MimicGift>(); ((GrabbableObject)mimicGift).itemProperties = Definition; ((GrabbableObject)mimicGift).grabbable = !opened; ((GrabbableObject)mimicGift).grabbableToEnemies = false; ((GrabbableObject)mimicGift).propBody = val3; mimicGift.RevealOnSpawn = opened; GameObject val4 = new GameObject("Suspicious scanner tell"); val4.transform.SetParent(val.transform, false); val4.transform.localPosition = Vector3.up * 0.28f; val4.layer = 22; val4.tag = "DoNotSet"; SphereCollider val5 = val4.AddComponent<SphereCollider>(); val5.radius = 0.3f; ((Collider)val5).isTrigger = true; ScanNodeProperties val6 = val4.AddComponent<ScanNodeProperties>(); val6.headerText = "Unsettling present"; val6.subText = "No sale value"; val6.nodeType = 0; val6.scrapValue = 0; val6.minRange = 1; val6.maxRange = 12; val6.requiresLineOfSight = true; AudioSource val7 = val.AddComponent<AudioSource>(); val7.spatialBlend = 1f; val7.minDistance = 1f; val7.maxDistance = 13f; val7.rolloffMode = (AudioRolloffMode)1; return val; } internal static Item VanillaGift() { AllItemsList val = (((Object)(object)StartOfRound.Instance != (Object)null) ? StartOfRound.Instance.allItemsList : null); if ((Object)(object)val == (Object)null) { return null; } foreach (Item items in val.itemsList) { if ((Object)(object)items != (Object)null && (Object)(object)items.spawnPrefab != (Object)null && (Object)(object)items.spawnPrefab.GetComponent<GiftBoxItem>() != (Object)null) { return items; } } return null; } private static AudioClip Sound(string name, float duration, float frequency, float volume) { float[] array = new float[(int)(duration * 22050f)]; Random random = new Random(1709); for (int i = 0; i < array.Length; i++) { float num = (float)i / 22050f; float num2 = Mathf.Sin(MathF.PI * (float)i / (float)array.Length); array[i] = (Mathf.Sin(num * frequency * MathF.PI * 2f * (1f - num * 0.25f)) * 0.5f + ((float)random.NextDouble() * 2f - 1f) * 0.28f) * num2 * volume; } AudioClip val = AudioClip.Create(name, array.Length, 1, 22050, false); val.SetData(array, 0); return val; } private static AudioClip CreatureSound(string name, float duration, bool loop, int seed) { float[] array = new float[(int)(duration * 22050f)]; Random random = new Random(seed); float num = 0f; float num2 = 0f; float num3 = 0f; for (int i = 0; i < array.Length; i++) { float num4 = (float)i / 22050f; float num5 = num4 / duration; float num6 = (float)random.NextDouble() * 2f - 1f; num += 0.06f * (num6 - num); num2 += 0.3f * (num6 - num2); float num7 = (float)(loop ? 46 : 68) + 13f * Mathf.Sin(num4 * 2.7f) + num * 23f; num3 += MathF.PI * 2f * num7 / 22050f; float num8 = Mathf.Sin(num3) + 0.55f * Mathf.Sin(num3 * 2f + num) + 0.22f * Mathf.Sin(num3 * 3.03f); float num9 = (loop ? ((0.56f + 0.23f * Mathf.Sin(MathF.PI * 2f * num5)) * Mathf.Clamp01(Mathf.Min(num5, 1f - num5) * 80f)) : Mathf.Pow(Mathf.Sin(MathF.PI * num5), 0.65f)); array[i] = Mathf.Clamp((num8 * (0.18f + Mathf.Abs(num)) + num2 * 0.35f) * num9, -0.85f, 0.85f); } AudioClip val = AudioClip.Create(name, array.Length, 1, 22050, false); val.SetData(array, 0); return val; } } public sealed class MimicGift : GrabbableObject, IHittable { public bool RevealOnSpawn; internal int Phase; internal int Health; internal double RevealedAt; internal double PhaseAt; internal double AttackAt; internal double NextAttack; internal double NextPath; internal ulong Target = ulong.MaxValue; internal Vector3 LastGroundPosition; internal Vector3 ServerPosition; internal Quaternion ServerRotation; internal float BoxGrowth = 2.4f; internal float RevealDuration = 1.8f; internal float PursuitSpeed = 3f; internal float TravelDistance; internal float MoveSpeed; internal float SnapshotAt; internal bool AttackLanded; internal NavMeshAgent Agent; private PresentMimicVisual visual; private AudioSource voice; private MimicVoice vocals; private BoxCollider hitbox; private float nextCreak; private float nextRequest; private float visualDistance; private float visualSpeed; public override void Start() { //IL_0010: Unknown result type (might be due to invalid IL or missing references) //IL_0015: Unknown result type (might be due to invalid IL or missing references) //IL_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_001c: Unknown result type (might be due to invalid IL or missing references) //IL_001d: Unknown result type (might be due to invalid IL or missing references) //IL_0029: Unknown result type (might be due to invalid IL or missing references) //IL_002e: Unknown result type (might be due to invalid IL or missing references) //IL_0045: Unknown result type (might be due to invalid IL or missing references) //IL_004a: Unknown result type (might be due to invalid IL or missing references) //IL_004f: Unknown result type (might be due to invalid IL or missing references) //IL_00d5: Unknown result type (might be due to invalid IL or missing references) //IL_00db: Expected O, but got Unknown //IL_0107: 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_012f: 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_014f: Unknown result type (might be due to invalid IL or missing references) //IL_0170: Unknown result type (might be due to invalid IL or missing references) //IL_0189: Unknown result type (might be due to invalid IL or missing references) //IL_018e: Unknown result type (might be due to invalid IL or missing references) ((GrabbableObject)this).Start(); LastGroundPosition = (ServerPosition = ((Component)this).transform.position); ServerRotation = ((Component)this).transform.rotation; if (RevealOnSpawn) { LastGroundPosition = ((GrabbableObject)this).GetItemFloorPosition(((Component)this).transform.position); } hitbox = ((Component)this).GetComponent<BoxCollider>(); voice = ((Component)this).GetComponent<AudioSource>(); nextCreak = Time.time + 15f; vocals = ((Component)this).gameObject.AddComponent<MimicVoice>(); vocals.Initialize(voice); try { Item val = MimicAssets.VanillaGift(); if ((Object)(object)val == (Object)null) { throw new InvalidOperationException("Vanilla present prefab was not found."); } base.itemProperties.itemIcon = val.itemIcon; GameObject val2 = new GameObject("Present mimic visual"); val2.transform.SetParent(((Component)this).transform, false); visual = val2.AddComponent<PresentMimicVisual>(); visual.Initialize(val.spawnPrefab, Quaternion.Euler(val.restingRotation), BoxGrowth); base.mainObjectRenderer = val2.GetComponentInChildren<MeshRenderer>(); Bounds bounds = ((Renderer)base.mainObjectRenderer).bounds; MeshRenderer[] componentsInChildren = val2.GetComponentsInChildren<MeshRenderer>(); foreach (MeshRenderer val3 in componentsInChildren) { ((Bounds)(ref bounds)).Encapsulate(((Renderer)val3).bounds); } hitbox.size = ((Bounds)(ref bounds)).size; hitbox.center = ((Component)this).transform.InverseTransformPoint(((Bounds)(ref bounds)).center); if (((NetworkBehaviour)this).IsServer) { Agent = ((Component)this).gameObject.AddComponent<NavMeshAgent>(); ((Behaviour)Agent).enabled = false; Agent.radius = 0.35f; Agent.height = 2.1f; Agent.speed = 3f; Agent.acceleration = 18f; Agent.angularSpeed = 300f; Agent.stoppingDistance = 1.15f; Agent.updatePosition = false; Agent.updateRotation = false; Health = Mathf.Clamp(Plugin.Health.Value, 1, 8); } MimicService.Instance?.Register(this); } catch (Exception ex) { Plugin.Log.LogError((object)("Mimic visual could not initialize; disabling this mimic: " + ex)); base.grabbable = false; ((Collider)hitbox).enabled = false; if (((NetworkBehaviour)this).IsServer && ((NetworkBehaviour)this).IsSpawned) { ((NetworkBehaviour)this).NetworkObject.Despawn(true); } } } public override void GrabItem() { if (((NetworkBehaviour)this).IsOwner && (Object)(object)base.playerHeldBy != (Object)null) { MimicService.Instance?.RequestReveal(this); } } public override void Update() { //IL_0158: 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_0038: Unknown result type (might be due to invalid IL or missing references) //IL_003d: Unknown result type (might be due to invalid IL or missing references) //IL_018e: Unknown result type (might be due to invalid IL or missing references) //IL_0194: Unknown result type (might be due to invalid IL or missing references) //IL_01b0: 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_01cd: Unknown result type (might be due to invalid IL or missing references) //IL_01e9: Unknown result type (might be due to invalid IL or missing references) //IL_020e: Unknown result type (might be due to invalid IL or missing references) //IL_0213: Unknown result type (might be due to invalid IL or missing references) //IL_0385: Unknown result type (might be due to invalid IL or missing references) if (Phase == 0) { ((GrabbableObject)this).Update(); if (!base.isHeld && !RevealOnSpawn) { LastGroundPosition = ((Component)this).transform.position; } if (base.isHeld && ((NetworkBehaviour)this).IsOwner && Time.time >= nextRequest) { nextRequest = Time.time + 0.3f; MimicService.Instance?.RequestReveal(this); } if (Time.time >= nextCreak) { nextCreak = Time.time + 18f + (float)(((NetworkBehaviour)this).NetworkObjectId % 7); AudioSource obj = voice; if (obj != null) { obj.PlayOneShot(MimicAssets.Creak, 0.3f); } } return; } base.grabbable = false; base.grabbableToEnemies = false; if (base.isHeld && ((NetworkBehaviour)this).IsOwner && (Object)(object)base.playerHeldBy != (Object)null && (Object)(object)StartOfRound.Instance != (Object)null && (Object)(object)base.playerHeldBy == (Object)(object)StartOfRound.Instance.localPlayerController && (Object)(object)base.playerHeldBy.currentlyHeldObjectServer == (Object)(object)this) { base.playerHeldBy.DiscardHeldObject(false, (NetworkObject)null, default(Vector3), true); } if (!((NetworkBehaviour)this).IsServer && !base.isHeld) { ((Component)this).transform.position = Vector3.Lerp(((Component)this).transform.position, ServerPosition, 1f - Mathf.Exp((0f - Time.deltaTime) * 18f)); ((Component)this).transform.rotation = Quaternion.Slerp(((Component)this).transform.rotation, ServerRotation, 1f - Mathf.Exp((0f - Time.deltaTime) * 18f)); } double num; if (!((Object)(object)NetworkManager.Singleton != (Object)null)) { num = Time.timeAsDouble; } else { NetworkTime serverTime = NetworkManager.Singleton.ServerTime; num = ((NetworkTime)(ref serverTime)).Time; } double num2 = num; float num3 = (float)Math.Max(0.0, num2 - RevealedAt); float num4 = (((NetworkBehaviour)this).IsServer ? 0f : Mathf.Clamp(Time.unscaledTime - SnapshotAt, 0f, 0.15f)); visualDistance = Mathf.Lerp(visualDistance, TravelDistance + MoveSpeed * num4, 1f - Mathf.Exp((0f - Time.deltaTime) * 18f)); visualSpeed = Mathf.Lerp(visualSpeed, (Phase == 2 && AttackAt <= 0.0) ? MoveSpeed : 0f, 1f - Mathf.Exp((0f - Time.deltaTime) * 12f)); visual?.SetMotion(visualDistance, visualSpeed, (AttackAt > 0.0) ? ((float)(num2 - AttackAt)) : (-1f)); visual?.SetPose(Mathf.Clamp01(num3 / RevealDuration), num3); if (Phase == 4 && (Object)(object)visual != (Object)null) { ((Component)visual).transform.localRotation = Quaternion.Euler(0f, 0f, 65f); } vocals?.Animate(Phase, AttackAt, num2, visualDistance, visualSpeed); } public override void LateUpdate() { if (Phase == 0 || base.isHeld) { ((GrabbableObject)this).LateUpdate(); } } internal void BeginReveal(Vector3 position, double time, float growth, float duration) { //IL_004d: Unknown result type (might be due to invalid IL or missing references) //IL_004e: Unknown result type (might be due to invalid IL or missing references) //IL_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) //IL_0073: 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_0103: Unknown result type (might be due to invalid IL or missing references) //IL_009a: Unknown result type (might be due to invalid IL or missing references) //IL_00a8: Unknown result type (might be due to invalid IL or missing references) if (Phase == 0) { Phase = 1; RevealedAt = (PhaseAt = time); BoxGrowth = growth; RevealDuration = duration; visual?.SetGrowth(growth); ServerPosition = position; ServerRotation = Quaternion.Euler(0f, ((Component)this).transform.eulerAngles.y, 0f); base.grabbable = false; base.grabbableToEnemies = false; if (!base.isHeld) { ((Component)this).transform.position = position; ((Component)this).transform.rotation = ServerRotation; } ((Component)this).gameObject.layer = 19; ((Component)this).gameObject.tag = "Enemy"; hitbox.center = Vector3.up * 1.35f; hitbox.size = new Vector3(1f, 2.7f, 0.9f); ((Collider)hitbox).isTrigger = false; ((Collider)hitbox).enabled = true; ScanNodeProperties componentInChildren = ((Component)this).GetComponentInChildren<ScanNodeProperties>(); if ((Object)(object)componentInChildren != (Object)null) { componentInChildren.headerText = "Present mimic"; componentInChildren.subText = "Ambush predator"; componentInChildren.nodeType = 1; } vocals?.Roar(time); } } bool IHittable.Hit(int force, Vector3 direction, PlayerControllerB attacker, bool playHitSFX, int hitID) { if (Phase == 0 || Phase == 4 || (Object)(object)attacker == (Object)null || (Object)(object)attacker != (Object)(object)StartOfRound.Instance.localPlayerController) { return false; } MimicService.Instance?.RequestHit(this); return true; } public override void OnDestroy() { MimicService.Instance?.Unregister(this); ((GrabbableObject)this).OnDestroy(); } } internal static class MimicRules { internal const float BiteContact = 0.38f; internal const float BiteDuration = 0.8f; internal const float BiteInterval = 1.05f; internal const float BiteRange = 1.8f; internal static bool CanBite(double now, double revealedAt, double revealDuration, double attackAt, float distance, bool liveIndoorPlayer, bool clearLine) { return liveIndoorPlayer && clearLine && double.IsFinite(now) && double.IsFinite(revealedAt) && double.IsFinite(revealDuration) && double.IsFinite(attackAt) && float.IsFinite(distance) && distance >= 0f && distance <= 1.8f && revealDuration >= 0.5 && now - revealedAt >= revealDuration + 0.8 && attackAt > 0.0 && now - attackAt >= 0.3799999952316284 && now - attackAt <= 0.800000011920929; } } internal sealed class MimicService : MonoBehaviour { [Serializable] private sealed class Packet { public int version = 2; public int kind; public int phase; public int health; public int damage; public ulong id; public ulong target; public uint sequence; public Vector3 position; public Quaternion rotation; public double revealed; public double phaseAt; public double attackAt; public float growth; public float duration; public float travel; public float speed; } internal static MimicService Instance; private const string Channel = "WyattMorse.PresentMimic.v2"; private readonly HashSet<MimicGift> gifts = new HashSet<MimicGift>(); private readonly Dictionary<ulong, float> strikes = new Dictionary<ulong, float>(); private readonly Dictionary<ulong, uint> latest = new Dictionary<ulong, uint>(); private readonly Dictionary<ulong, float> helloTimes = new Dictionary<ulong, float>(); private NetworkManager manager; private StartOfRound round; private bool rolled; private float nextSnapshot; private float nextHello; private uint sequence; private uint attackSequence; private uint lastAttack; private void Awake() { Instance = this; } internal void Register(MimicGift gift) { gifts.Add(gift); } internal void Unregister(MimicGift gift) { gifts.Remove(gift); } private void Update() { //IL_0068: Unknown result type (might be due to invalid IL or missing references) //IL_0072: Expected O, but got Unknown NetworkManager singleton = NetworkManager.Singleton; if ((Object)(object)singleton == (Object)null || !singleton.IsListening || singleton.ShutdownInProgress) { Disconnect(); return; } if ((Object)(object)manager != (Object)(object)singleton) { Disconnect(); manager = singleton; manager.CustomMessagingManager.RegisterNamedMessageHandler("WyattMorse.PresentMimic.v2", new HandleNamedMessageDelegate(Receive)); MimicGift[] array = Object.FindObjectsOfType<MimicGift>(); foreach (MimicGift mimicGift in array) { if (((NetworkBehaviour)mimicGift).IsSpawned) { gifts.Add(mimicGift); } } } if ((Object)(object)round != (Object)(object)StartOfRound.Instance) { round = StartOfRound.Instance; rolled = false; } if ((Object)(object)round == (Object)null) { return; } if (manager.IsServer) { PresentCommand.TickPickupAmbushes(); if (round.inShipPhase) { rolled = false; } if (!rolled && Plugin.Enabled.Value && round.shipHasLanded && !round.inShipPhase && (Object)(object)RoundManager.Instance != (Object)null && RoundManager.Instance.dungeonFinishedGeneratingForAllPlayers) { rolled = true; TrySpawn(); } MimicGift[] array2 = gifts.ToArray(); foreach (MimicGift mimicGift2 in array2) { if ((Object)(object)mimicGift2 == (Object)null || !((NetworkBehaviour)mimicGift2).IsSpawned) { gifts.Remove(mimicGift2); } else if ((!Plugin.Enabled.Value || round.shipIsLeaving || (round.inShipPhase && !mimicGift2.RevealOnSpawn)) && !((GrabbableObject)mimicGift2).isHeld) { ((NetworkBehaviour)mimicGift2).NetworkObject.Despawn(true); } else { Tick(mimicGift2); } } if (Time.unscaledTime >= nextSnapshot) { nextSnapshot = Time.unscaledTime + 0.12f; Broadcast(); } } else if (Time.unscaledTime >= nextHello) { nextHello = Time.unscaledTime + 5f; Send(0uL, new Packet { kind = 0 }); } } private void TrySpawn() { //IL_012c: Unknown result type (might be due to invalid IL or missing references) //IL_0180: Unknown result type (might be due to invalid IL or missing references) //IL_0185: Unknown result type (might be due to invalid IL or missing references) //IL_018f: Unknown result type (might be due to invalid IL or missing references) //IL_0194: Unknown result type (might be due to invalid IL or missing references) //IL_01a0: Unknown result type (might be due to invalid IL or missing references) //IL_01a5: Unknown result type (might be due to invalid IL or missing references) //IL_01af: Unknown result type (might be due to invalid IL or missing references) //IL_01b4: 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_01e8: 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_01f7: Unknown result type (might be due to invalid IL or missing references) //IL_0212: Unknown result type (might be due to invalid IL or missing references) Random random = new Random(round.randomMapSeed ^ 0x4D1A934); if (random.NextDouble() >= (double)Mathf.Clamp01(Plugin.SpawnChance.Value)) { Plugin.Log.LogInfo((object)"This round's rare mimic spawn roll did not pass."); } else { if (gifts.Any((MimicGift g) => (Object)(object)g != (Object)null && ((NetworkBehaviour)g).IsSpawned)) { return; } List<RandomScrapSpawn> list = (from s in Object.FindObjectsOfType<RandomScrapSpawn>() where !s.spawnUsed orderby ((Component)s).transform.position.x, ((Component)s).transform.position.z select s).ToList(); NavMeshHit hit = default(NavMeshHit); while (list.Count > 0) { int index = random.Next(list.Count); RandomScrapSpawn val = list[index]; list.RemoveAt(index); if (!NavMesh.SamplePosition(((Component)val).transform.position, ref hit, 1.3f, -1) || round.allPlayerScripts.Any((PlayerControllerB p) => (Object)(object)p != (Object)null && p.isPlayerControlled && !p.isPlayerDead && Vector3.Distance(((Component)p).transform.position, ((NavMeshHit)(ref hit)).position) < 7f) || Physics.CheckCapsule(((NavMeshHit)(ref hit)).position + Vector3.up * 0.35f, ((NavMeshHit)(ref hit)).position + Vector3.up * 1.4f, 0.3f, round.collidersAndRoomMaskAndDefault, (QueryTriggerInteraction)1)) { continue; } GameObject val2 = Object.Instantiate<GameObject>(MimicAssets.Prefab, ((NavMeshHit)(ref hit)).position + Vector3.up * 0.02f, Quaternion.Euler(0f, (float)random.Next(360), 0f)); val2.GetComponent<NetworkObject>().Spawn(false); Plugin.Log.LogInfo((object)"Spawned one independent indoor mimic at a loot marker."); return; } Plugin.Log.LogInfo((object)"Mimic spawn skipped: no clear, unoccupied indoor loot marker."); } } internal void RequestReveal(MimicGift gift) { Request(new Packet { kind = 1, id = ((NetworkBehaviour)gift).NetworkObjectId }); } internal void RequestHit(MimicGift gift) { Request(new Packet { kind = 2, id = ((NetworkBehaviour)gift).NetworkObjectId }); } private void Request(Packet packet) { if (!((Object)(object)manager == (Object)null)) { if (manager.IsServer) { Handle(manager.LocalClientId, packet); } else { Send(0uL, packet); } } } private MimicGift Find(ulong id) { return gifts.FirstOrDefault((MimicGift g) => (Object)(object)g != (Object)null && ((NetworkBehaviour)g).IsSpawned && ((NetworkBehaviour)g).NetworkObjectId == id); } private PlayerControllerB Player(ulong id) { return ((IEnumerable<PlayerControllerB>)round?.allPlayerScripts).FirstOrDefault((Func<PlayerControllerB, bool>)((PlayerControllerB p) => (Object)(object)p != (Object)null && p.actualClientId == id && p.isPlayerControlled && !p.isPlayerDead)); } private void Handle(ulong sender, Packet packet) { //IL_0135: 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_015d: Unknown result type (might be due to invalid IL or missing references) //IL_0168: Unknown result type (might be due to invalid IL or missing references) //IL_016d: Unknown result type (might be due to invalid IL or missing references) //IL_0172: Unknown result type (might be due to invalid IL or missing references) //IL_01ce: 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) MimicGift mimicGift = Find(packet.id); PlayerControllerB val = Player(sender); if ((Object)(object)mimicGift == (Object)null || (Object)(object)val == (Object)null || !Plugin.Enabled.Value) { return; } if (packet.kind == 1 && mimicGift.Phase == 0 && ((GrabbableObject)mimicGift).isHeld && (Object)(object)((GrabbableObject)mimicGift).playerHeldBy == (Object)(object)val && val.ItemSlots != null && val.ItemSlots.Contains((GrabbableObject)(object)mimicGift)) { RevealGift(mimicGift); } if (packet.kind != 2 || mimicGift.Phase < 1 || mimicGift.Phase >= 4 || (strikes.TryGetValue(sender, out var value) && Time.unscaledTime - value < 0.5f)) { return; } GrabbableObject val2 = ((val.ItemSlots != null && val.currentItemSlot >= 0 && val.currentItemSlot < val.ItemSlots.Length) ? val.ItemSlots[val.currentItemSlot] : null); if ((Object)(object)val2 == (Object)null || !val2.itemProperties.isDefensiveWeapon || Vector3.Distance(((Component)val).transform.position, ((Component)mimicGift).transform.position) > 3.5f || !Clear(((Component)val.gameplayCamera).transform.position, ((Component)mimicGift).transform.position + Vector3.up)) { return; } strikes[sender] = Time.unscaledTime; if (--mimicGift.Health <= 0) { mimicGift.Phase = 4; NetworkTime serverTime = manager.ServerTime; mimicGift.PhaseAt = ((NetworkTime)(ref serverTime)).Time; if ((Object)(object)mimicGift.Agent != (Object)null && ((Behaviour)mimicGift.Agent).enabled) { mimicGift.Agent.isStopped = true; } ((Collider)((Component)mimicGift).GetComponent<BoxCollider>()).enabled = false; } Broadcast(); } private void RevealGift(MimicGift gift) { //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_0032: Unknown result type (might be due to invalid IL or missing references) //IL_0039: Unknown result type (might be due to invalid IL or missing references) //IL_003e: 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_0030: Unknown result type (might be due to invalid IL or missing references) if (gift.Phase == 0) { Vector3 val = gift.LastGroundPosition; NavMeshHit val2 = default(NavMeshHit); if (NavMesh.SamplePosition(val, ref val2, 2f, -1)) { val = ((NavMeshHit)(ref val2)).position; } Vector3 position = val; NetworkTime serverTime = manager.ServerTime; gift.BeginReveal(position, ((NetworkTime)(ref serverTime)).Time, Mathf.Clamp(Plugin.RevealedBoxScale.Value, 1.1f, 4f), Mathf.Clamp(Plugin.RevealSeconds.Value, 0.5f, 5f)); Broadcast(); } } private void Tick(MimicGift gift) { //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_0136: Unknown result type (might be due to invalid IL or missing references) //IL_0152: Unknown result type (might be due to invalid IL or missing references) //IL_02d8: Unknown result type (might be due to invalid IL or missing references) //IL_02e8: Unknown result type (might be due to invalid IL or missing references) //IL_032d: Unknown result type (might be due to invalid IL or missing references) //IL_0332: Unknown result type (might be due to invalid IL or missing references) //IL_033c: Unknown result type (might be due to invalid IL or missing references) //IL_0341: Unknown result type (might be due to invalid IL or missing references) //IL_0351: Unknown result type (might be due to invalid IL or missing references) //IL_04ee: Unknown result type (might be due to invalid IL or missing references) //IL_04f3: Unknown result type (might be due to invalid IL or missing references) //IL_046a: Unknown result type (might be due to invalid IL or missing references) //IL_06dc: Unknown result type (might be due to invalid IL or missing references) //IL_06e1: Unknown result type (might be due to invalid IL or missing references) //IL_06e3: Unknown result type (might be due to invalid IL or missing references) //IL_06e8: Unknown result type (might be due to invalid IL or missing references) //IL_06ed: Unknown result type (might be due to invalid IL or missing references) //IL_06f2: Unknown result type (might be due to invalid IL or missing references) //IL_04a2: Unknown result type (might be due to invalid IL or missing references) //IL_0774: Unknown result type (might be due to invalid IL or missing references) //IL_079a: Unknown result type (might be due to invalid IL or missing references) //IL_079f: Unknown result type (might be due to invalid IL or missing references) //IL_07a1: Unknown result type (might be due to invalid IL or missing references) //IL_07a6: Unknown result type (might be due to invalid IL or missing references) //IL_07ab: Unknown result type (might be due to invalid IL or missing references) //IL_073e: Unknown result type (might be due to invalid IL or missing references) //IL_0743: Unknown result type (might be due to invalid IL or missing references) //IL_0748: Unknown result type (might be due to invalid IL or missing references) //IL_074d: Unknown result type (might be due to invalid IL or missing references) //IL_0783: Unknown result type (might be due to invalid IL or missing references) //IL_0788: Unknown result type (might be due to invalid IL or missing references) //IL_078d: Unknown result type (might be due to invalid IL or missing references) //IL_07b0: Unknown result type (might be due to invalid IL or missing references) //IL_0618: Unknown result type (might be due to invalid IL or missing references) //IL_061d: Unknown result type (might be due to invalid IL or missing references) //IL_061f: Unknown result type (might be due to invalid IL or missing references) //IL_0624: Unknown result type (might be due to invalid IL or missing references) //IL_0581: Unknown result type (might be due to invalid IL or missing references) //IL_080f: Unknown result type (might be due to invalid IL or missing references) //IL_0814: Unknown result type (might be due to invalid IL or missing references) //IL_082a: Unknown result type (might be due to invalid IL or missing references) //IL_082f: Unknown result type (might be due to invalid IL or missing references) //IL_07dc: Unknown result type (might be due to invalid IL or missing references) //IL_07e1: Unknown result type (might be due to invalid IL or missing references) //IL_07e3: Unknown result type (might be due to invalid IL or missing references) //IL_07f3: Unknown result type (might be due to invalid IL or missing references) //IL_059a: Unknown result type (might be due to invalid IL or missing references) //IL_05a1: Expected O, but got Unknown //IL_05ae: Unknown result type (might be due to invalid IL or missing references) //IL_05be: Unknown result type (might be due to invalid IL or missing references) //IL_05c4: Invalid comparison between Unknown and I4 //IL_06c5: Unknown result type (might be due to invalid IL or missing references) //IL_0641: Unknown result type (might be due to invalid IL or missing references) //IL_0643: Unknown result type (might be due to invalid IL or missing references) //IL_064d: Unknown result type (might be due to invalid IL or missing references) //IL_0652: Unknown result type (might be due to invalid IL or missing references) //IL_065e: Unknown result type (might be due to invalid IL or missing references) //IL_069c: Unknown result type (might be due to invalid IL or missing references) //IL_06a1: Unknown result type (might be due to invalid IL or missing references) //IL_06a3: Unknown result type (might be due to invalid IL or missing references) //IL_08d5: Unknown result type (might be due to invalid IL or missing references) //IL_08e5: Unknown result type (might be due to invalid IL or missing references) //IL_091a: Unknown result type (might be due to invalid IL or missing references) //IL_091f: Unknown result type (might be due to invalid IL or missing references) //IL_0929: Unknown result type (might be due to invalid IL or missing references) //IL_092e: Unknown result type (might be due to invalid IL or missing references) //IL_093f: Unknown result type (might be due to invalid IL or missing references) if (gift.Phase == 0) { if (gift.RevealOnSpawn || (((GrabbableObject)gift).isHeld && (Object)(object)((GrabbableObject)gift).playerHeldBy != (Object)null && !((GrabbableObject)gift).playerHeldBy.isPlayerDead)) { RevealGift(gift); } return; } NetworkTime serverTime = manager.ServerTime; double time = ((NetworkTime)(ref serverTime)).Time; if (gift.Phase == 4) { if (!((GrabbableObject)gift).isHeld && time - gift.PhaseAt > 2.0) { ((NetworkBehaviour)gift).NetworkObject.Despawn(true); } } else { if (((GrabbableObject)gift).isHeld) { return; } if (gift.Phase == 1) { ((Component)gift).transform.position = gift.ServerPosition; ((Component)gift).transform.rotation = gift.ServerRotation; if (time - gift.RevealedAt < (double)gift.RevealDuration + 0.8) { return; } gift.Phase = 2; gift.PhaseAt = time; gift.PursuitSpeed = 3f; } PlayerControllerB val = Player(gift.Target); if ((Object)(object)val == (Object)null || !val.isInsideFactory || val.isInHangarShipRoom) { val = ((gift.AttackAt > 0.0) ? null : (from p in round.allPlayerScripts where (Object)(object)p != (Object)null && p.isPlayerControlled && !p.isPlayerDead && p.isInsideFactory && !p.isInHangarShipRoom where Vector3.Distance(((Component)p).transform.position, ((Component)gift).transform.position) < 24f && Clear(((Component)gift).transform.position + Vector3.up * 1.4f, ((Component)p.gameplayCamera).transform.position) select p).OrderBy(delegate(PlayerControllerB p) { //IL_0006: 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_0020: Unknown result type (might be due to invalid IL or missing references) Vector3 val11 = ((Component)p).transform.position - ((Component)gift).transform.position; return ((Vector3)(ref val11)).sqrMagnitude; }).FirstOrDefault()); if (gift.AttackAt <= 0.0) { gift.Target = (((Object)(object)val != (Object)null) ? val.actualClientId : ulong.MaxValue); } } gift.Phase = (((Object)(object)val == (Object)null) ? 3 : 2); bool flag = gift.AttackAt > 0.0; bool flag2 = (Object)(object)val != (Object)null && Vector3.Distance(((Component)val).transform.position, ((Component)gift).transform.position) <= 1.8f; if (!flag && (Object)(object)val != (Object)null && flag2 && time >= gift.NextAttack && Clear(((Component)gift).transform.position + Vector3.up * 1.3f, ((Component)val.gameplayCamera).transform.position)) { gift.AttackAt = time; gift.AttackLanded = false; flag = true; Broadcast(); } gift.PursuitSpeed = (((Object)(object)val != (Object)null && !flag) ? Mathf.Min(Mathf.Clamp(Plugin.ChaseSpeed.Value, 3f, 12f), gift.PursuitSpeed + 1.2f * Time.deltaTime) : 3f); bool flag3 = (Object)(object)gift.Agent != (Object)null && ((Behaviour)gift.Agent).enabled && gift.Agent.isOnNavMesh; if (!flag3 && (Object)(object)gift.Agent != (Object)null && time >= gift.NextPath) { gift.NextPath = time + 1.0; NavMeshHit val2 = default(NavMeshHit); if (NavMesh.SamplePosition(((Component)gift).transform.position, ref val2, 1.5f, -1)) { ((Behaviour)gift.Agent).enabled = true; flag3 = gift.Agent.Warp(((NavMeshHit)(ref val2)).position); if (!flag3) { ((Behaviour)gift.Agent).enabled = false; } else { gift.NextPath = 0.0; } } } Vector3 position = ((Component)gift).transform.position; bool flag4 = false; if (flag3) { gift.Agent.speed = gift.PursuitSpeed; gift.Agent.isStopped = flag || (Object)(object)val == (Object)null; if ((Object)(object)val != (Object)null && time >= gift.NextPath) { gift.NextPath = time + 0.2; NavMeshHit val3 = default(NavMeshHit); if (NavMesh.SamplePosition(((Component)val).transform.position, ref val3, 1.5f, -1)) { NavMeshPath val4 = new NavMeshPath(); if (gift.Agent.CalculatePath(((NavMeshHit)(ref val3)).position, val4) && (int)val4.status != 2) { gift.Agent.SetPath(val4); } else { gift.Agent.ResetPath(); } } else { gift.Agent.ResetPath(); } } Vector3 val5 = gift.Agent.nextPosition - position; if (!flag && ((Vector3)(ref val5)).sqrMagnitude > 1E-06f) { RaycastHit val6 = default(RaycastHit); flag4 = Physics.SphereCast(position + Vector3.up * 0.6f, 0.3f, ((Vector3)(ref val5)).normalized, ref val6, ((Vector3)(ref val5)).magnitude + 0.03f, round.collidersAndRoomMaskAndDefault, (QueryTriggerInteraction)1); if (!flag4) { Transform transform = ((Component)gift).transform; transform.position += val5; } } gift.Agent.nextPosition = ((Component)gift).transform.position; } Vector3 val7 = Vector3.ProjectOnPlane(((Component)gift).transform.position - position, Vector3.up); gift.TravelDistance += ((Vector3)(ref val7)).magnitude; MimicGift mimicGift = gift; float moveSpeed; if (!flag3 || !((Object)(object)val != (Object)null) || flag || flag4) { moveSpeed = 0f; } else { Vector3 val8 = Vector3.ProjectOnPlane(gift.Agent.velocity, Vector3.up); moveSpeed = Mathf.Min(15f, ((Vector3)(ref val8)).magnitude); } mimicGift.MoveSpeed = moveSpeed; Vector3 val9 = ((flag && (Object)(object)val != (Object)null) ? Vector3.ProjectOnPlane(((Component)val).transform.position - position, Vector3.up) : ((flag3 && !flag4) ? Vector3.ProjectOnPlane(gift.Agent.desiredVelocity, Vector3.up) : val7)); if (((Vector3)(ref val9)).sqrMagnitude > 1E-05f) { ((Component)gift).transform.rotation = Quaternion.RotateTowards(((Component)gift).transform.rotation, Quaternion.LookRotation(val9), 300f * Time.deltaTime); } gift.ServerPosition = ((Component)gift).transform.position; gift.ServerRotation = ((Component)gift).transform.rotation; if (gift.AttackAt > 0.0 && !gift.AttackLanded && time - gift.AttackAt >= 0.3799999952316284) { gift.AttackLanded = true; PlayerControllerB val10 = Player(gift.Target); if ((Object)(object)val10 != (Object)null && MimicRules.CanBite(time, gift.RevealedAt, gift.RevealDuration, gift.AttackAt, Vector3.Distance(((Component)val10).transform.position, ((Component)gift).transform.position), val10.isInsideFactory && !val10.isPlayerDead && !val10.isInHangarShipRoom, Clear(((Component)gift).transform.position + Vector3.up * 1.3f, ((Component)val10.gameplayCamera).transform.position))) { Packet packet = new Packet { kind = 4, id = ((NetworkBehaviour)gift).NetworkObjectId, target = val10.actualClientId, damage = Mathf.Clamp(Plugin.Damage.Value, 5, 40), sequence = ++attackSequence }; if (val10.actualClientId == manager.LocalClientId) { ApplyDamage(packet); } else { Send(val10.actualClientId, packet); } } } if (gift.AttackAt > 0.0 && time - gift.AttackAt >= 0.800000011920929) { gift.NextAttack = gift.AttackAt + 1.0499999523162842; gift.AttackAt = 0.0; Broadcast(); } } } private bool Clear(Vector3 a, Vector3 b) { //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) return !Physics.Linecast(a, b, round.collidersAndRoomMaskAndDefault, (QueryTriggerInteraction)1); } private void Broadcast() { //IL_00dc: 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_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_00f0: 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) if ((Object)(object)manager == (Object)null || !manager.IsServer || !manager.IsListening) { return; } MimicGift[] array = gifts.ToArray(); foreach (MimicGift mimicGift in array) { if ((Object)(object)mimicGift == (Object)null || !((NetworkBehaviour)mimicGift).IsSpawned) { continue; } Packet packet = new Packet { kind = 3, id = ((NetworkBehaviour)mimicGift).NetworkObjectId, sequence = ++sequence, phase = mimicGift.Phase, health = mimicGift.Health, target = mimicGift.Target, position = ((mimicGift.Phase == 0) ? ((Component)mimicGift).transform.position : mimicGift.ServerPosition), rotation = ((mimicGift.Phase == 0) ? ((Component)mimicGift).transform.rotation : mimicGift.ServerRotation), revealed = mimicGift.RevealedAt, phaseAt = mimicGift.PhaseAt, attackAt = mimicGift.AttackAt, growth = mimicGift.BoxGrowth, duration = mimicGift.RevealDuration, travel = mimicGift.TravelDistance, speed = mimicGift.MoveSpeed }; foreach (ulong connectedClientsId in manager.ConnectedClientsIds) { if (connectedClientsId != 0) { Send(connectedClientsId, packet); } } } } private void ApplyDamage(Packet packet) { //IL_0075: 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) if (packet.sequence > lastAttack && packet.target == manager.LocalClientId) { lastAttack = packet.sequence; PlayerControllerB localPlayerController = round.localPlayerController; if ((Object)(object)localPlayerController != (Object)null && !localPlayerController.isPlayerDead) { localPlayerController.DamagePlayer(Mathf.Clamp(packet.damage, 5, 40), true, true, (CauseOfDeath)6, 0, false, default(Vector3)); } } } private void Receive(ulong sender, FastBufferReader reader) { //IL_0324: Unknown result type (might be due to invalid IL or missing references) //IL_0329: Unknown result type (might be due to invalid IL or missing references) //IL_0331: Unknown result type (might be due to invalid IL or missing references) //IL_0336: Unknown result type (might be due to invalid IL or missing references) //IL_02b4: Unknown result type (might be due to invalid IL or missing references) //IL_0395: Unknown result type (might be due to invalid IL or missing references) //IL_03a9: Unknown result type (might be due to invalid IL or missing references) //IL_03ae: Unknown result type (might be due to invalid IL or missing references) if (((FastBufferReader)(ref reader)).Length > 5000 || (Object)(object)round == (Object)null) { return; } try { string text = default(string); ((FastBufferReader)(ref reader)).ReadValueSafe(ref text, false); Packet packet = JsonUtility.FromJson<Packet>(text); if (packet == null || packet.version != 2) { return; } if (manager.IsServer) { if (packet.kind == 0 && (!helloTimes.TryGetValue(sender, out var value) || Time.unscaledTime - value >= 3f)) { helloTimes[sender] = Time.unscaledTime; Broadcast(); } else if (packet.kind == 1 || packet.kind == 2) { Handle(sender, packet); } } else { if (sender != 0) { return; } if (packet.kind == 4) { ApplyDamage(packet); } else { if (packet.kind != 3 || packet.phase < 0 || packet.phase > 4 || !float.IsFinite(packet.position.x) || !float.IsFinite(packet.position.y) || !float.IsFinite(packet.position.z) || !float.IsFinite(packet.travel) || packet.travel < 0f || !float.IsFinite(packet.speed) || !float.IsFinite(packet.rotation.x) || !float.IsFinite(packet.rotation.y) || !float.IsFinite(packet.rotation.z) || !float.IsFinite(packet.rotation.w) || !double.IsFinite(packet.attackAt) || !double.IsFinite(packet.revealed) || !float.IsFinite(packet.duration) || !float.IsFinite(packet.growth) || (latest.TryGetValue(packet.id, out var value2) && packet.sequence <= value2)) { return; } MimicGift mimicGift = Find(packet.id); if (!((Object)(object)mimicGift == (Object)null)) { latest[packet.id] = packet.sequence; if (mimicGift.Phase == 0 && packet.phase > 0) { mimicGift.BeginReveal(packet.position, packet.revealed, packet.growth, Mathf.Clamp(packet.duration, 0.5f, 5f)); } mimicGift.Phase = packet.phase; mimicGift.PhaseAt = packet.phaseAt; mimicGift.Health = packet.health; mimicGift.Target = packet.target; mimicGift.AttackAt = packet.attackAt; mimicGift.ServerPosition = packet.position; mimicGift.ServerRotation = packet.rotation; mimicGift.TravelDistance = packet.travel; mimicGift.MoveSpeed = Mathf.Clamp(packet.speed, 0f, 15f); mimicGift.SnapshotAt = Time.unscaledTime; if (mimicGift.Phase == 0 && !((GrabbableObject)mimicGift).isHeld) { ((Component)mimicGift).transform.position = packet.position; ((GrabbableObject)mimicGift).targetFloorPosition = ((Component)mimicGift).transform.localPosition; ((GrabbableObject)mimicGift).fallTime = 1f; } if (mimicGift.Phase == 4) { ((Collider)((Component)mimicGift).GetComponent<BoxCollider>()).enabled = false; } } } } } catch (Exception ex) { Plugin.Log.LogWarning((object)("Ignored invalid mimic message: " + ex.GetType().Name)); } } private unsafe void Send(ulong client, Packet packet) { //IL_005e: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)manager == (Object)null || !manager.IsListening || manager.ShutdownInProgress) { return; } FastBufferWriter val = default(FastBufferWriter); ((FastBufferWriter)(ref val))..ctor(6000, (Allocator)2, -1); try { ((FastBufferWriter)(ref val)).WriteValueSafe(JsonUtility.ToJson((object)packet), false); manager.CustomMessagingManager.SendNamedMessage("WyattMorse.PresentMimic.v2", client, val, (NetworkDelivery)4); } finally { ((IDisposable)(*(FastBufferWriter*)(&val))/*cast due to .constrained prefix*/).Dispose(); } } private void Disconnect() { if ((Object)(object)manager != (Object)null) { PresentCommand.ResetAmbushes(); } if ((Object)(object)manager != (Object)null && manager.CustomMessagingManager != null) { manager.CustomMessagingManager.UnregisterNamedMessageHandler("WyattMorse.PresentMimic.v2"); } manager = null; round = null; rolled = false; latest.Clear(); strikes.Clear(); helloTimes.Clear(); gifts.Clear(); sequence = (attackSequence = (lastAttack = 0u)); } private void OnDestroy() { Disconnect(); if ((Object)(object)Instance == (Object)(object)this) { Instance = null; } } } internal sealed class MimicVoice : MonoBehaviour { private AudioSource voice; private AudioSource growl; private AudioClip roar; private AudioClip bite; private double soundedBite; private int previousStep; internal void Initialize(AudioSource source) { voice = source; growl = ((Component)this).gameObject.AddComponent<AudioSource>(); growl.spatialBlend = 1f; growl.minDistance = 2f; growl.maxDistance = 24f; growl.rolloffMode = (AudioRolloffMode)1; growl.loop = true; growl.volume = 0f; voice.minDistance = 2f; voice.maxDistance = 27f; AudioSource obj = voice; float dopplerLevel = (growl.dopplerLevel = 0.15f); obj.dopplerLevel = dopplerLevel; roar = MimicAssets.Reveal; bite = MimicAssets.Bite; growl.clip = MimicAssets.Growl; EnemyType[] array = Resources.FindObjectsOfTypeAll<EnemyType>(); foreach (EnemyType val in array) { if ((Object)(object)val == (Object)null || (Object)(object)val.enemyPrefab == (Object)null) { continue; } CrawlerAI component = val.enemyPrefab.GetComponent<CrawlerAI>(); if ((Object)(object)component != (Object)null) { if (component.longRoarSFX != null && component.longRoarSFX.Length != 0 && (Object)(object)component.longRoarSFX[0] != (Object)null) { roar = component.longRoarSFX[0]; } else if ((Object)(object)component.shortRoar != (Object)null) { roar = component.shortRoar; } if ((Object)(object)component.bitePlayerSFX != (Object)null) { bite = component.bitePlayerSFX; } if ((Object)(object)((EnemyAI)component).creatureVoice != (Object)null) { voice.outputAudioMixerGroup = ((EnemyAI)component).creatureVoice.outputAudioMixerGroup; } } FlowermanAI component2 = val.enemyPrefab.GetComponent<FlowermanAI>(); if ((Object)(object)component2 != (Object)null && (Object)(object)component2.creatureAngerVoice != (Object)null && (Object)(object)component2.creatureAngerVoice.clip != (Object)null) { growl.clip = component2.creatureAngerVoice.clip; growl.outputAudioMixerGroup = component2.creatureAngerVoice.outputAudioMixerGroup; } } growl.pitch = 0.78f; voice.pitch = 0.9f; } internal void Roar(double started) { //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) double num; if (!((Object)(object)NetworkManager.Singleton != (Object)null)) { num = started; } else { NetworkTime serverTime = NetworkManager.Singleton.ServerTime; num = ((NetworkTime)(ref serverTime)).Time; } double num2 = num; if (num2 - started < 2.5) { voice.PlayOneShot(roar, 0.85f); } } internal void Animate(int phase, double attackAt, double now, float distance, float speed) { float num = ((phase != 2) ? 0f : ((attackAt > 0.0) ? 0.18f : 0.46f)); growl.volume = Mathf.MoveTowards(growl.volume, num, Time.deltaTime * 0.85f); if (growl.volume > 0.005f && !growl.isPlaying) { growl.Play(); } if (growl.volume <= 0.005f && growl.isPlaying) { growl.Stop(); } if (phase != 4 && attackAt > soundedBite && now - attackAt >= 0.3799999952316284) { soundedBite = attackAt; voice.PlayOneShot(bite, 0.9f); } int num2 = Mathf.FloorToInt(distance / 0.95f); if (num2 != previousStep && speed > 0.3f && phase == 2 && attackAt <= 0.0) { voice.PlayOneShot(MimicAssets.Footstep, Mathf.Lerp(0.16f, 0.36f, Mathf.Clamp01(speed / 8f))); } previousStep = num2; } } [BepInPlugin("WyattMorse.PresentMimic", "PresentMimic", "0.4.0")] [BepInDependency(/*Could not decode attribute arguments.*/)] public sealed class Plugin : BaseUnityPlugin { internal static ManualLogSource Log; internal static ConfigEntry<bool> EnableVisualPreview; internal static ConfigEntry<float> RevealedBoxScale; internal static ConfigEntry<float> RevealSeconds; internal static ConfigEntry<bool> Enabled; internal static ConfigEntry<float> SpawnChance; internal static ConfigEntry<float> ChaseSpeed; internal static ConfigEntry<int> Damage; internal static ConfigEntry<int> Health; private static Harmony? patches; private static GameObject? runtime; private void Awake() { //IL_006b: Unknown result type (might be due to invalid IL or missing references) //IL_0075: Expected O, but got Unknown //IL_00a8: Unknown result type (might be due to invalid IL or missing references) //IL_00b2: Expected O, but got Unknown //IL_0105: Unknown result type (might be due to invalid IL or missing references) //IL_010f: Expected O, but got Unknown //IL_0142: Unknown result type (might be due to invalid IL or missing references) //IL_014c: Expected O, but got Unknown //IL_0175: Unknown result type (might be due to invalid IL or missing references) //IL_017f: Expected O, but got Unknown //IL_01a6: Unknown result type (might be due to invalid IL or missing references) //IL_01b0: Expected O, but got Unknown //IL_0228: Unknown result type (might be due to invalid IL or missing references) //IL_0232: Expected O, but got Unknown if (patches != null) { return; } Log = ((BaseUnityPlugin)this).Logger; EnableVisualPreview = ((BaseUnityPlugin)this).Config.Bind<bool>("Development", "EnableVisualPreview", false, "Local visual preview only: F8 place a dormant mimic, F9 reveal/reset, F10 remove. Does not spawn a network enemy or change real gifts."); RevealedBoxScale = ((BaseUnityPlugin)this).Config.Bind<float>("Visuals", "RevealedBoxScale", 2.4f, new ConfigDescription("Uniform box growth after revealing; original wrapping, ribbon and mesh proportions are retained.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(1.1f, 4f), Array.Empty<object>())); RevealSeconds = ((BaseUnityPlugin)this).Config.Bind<float>("Visuals", "RevealSeconds", 1.8f, new ConfigDescription("Transformation duration; the host supplies this value for network mimics.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0.5f, 5f), Array.Empty<object>())); Enabled = ((BaseUnityPlugin)this).Config.Bind<bool>("Host", "Enabled", true, "Enable rare indoor mimic spawns; host controls gameplay."); SpawnChance = ((BaseUnityPlugin)this).Config.Bind<float>("Host", "SpawnChance", 0.1f, new ConfigDescription("Chance of one mimic per indoor round. Set to 1 for the final playtest.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 1f), Array.Empty<object>())); ChaseSpeed = ((BaseUnityPlugin)this).Config.Bind<float>("Host", "ChaseSpeed", 12f, new ConfigDescription("Maximum pursuit speed. Accelerates from 3 m/s at the native Bracken's 1.2 m/s per second.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(3f, 12f), Array.Empty<object>())); Damage = ((BaseUnityPlugin)this).Config.Bind<int>("Host", "AttackDamage", 40, new ConfigDescription("Damage on jaw contact. Default 40 matches the installed Thumper; bites repeat while the victim remains reachable.", (AcceptableValueBase)(object)new AcceptableValueRange<int>(5, 40), Array.Empty<object>())); Health = ((BaseUnityPlugin)this).Config.Bind<int>("Host", "Health", 3, new ConfigDescription("Number of validated melee hits to defeat the mimic.", (AcceptableValueBase)(object)new AcceptableValueRange<int>(1, 8), Array.Empty<object>())); ConfigEntry<int> val = ((BaseUnityPlugin)this).Config.Bind<int>("Host", "SettingsRevision", 0, "Internal migration version for requested mimic behavior."); if (val.Value < 4) { Damage.Value = 40; if (Mathf.Approximately(ChaseSpeed.Value, 3.2f)) { ChaseSpeed.Value = 12f; } val.Value = 4; } MimicAssets.Build(); patches = new Harmony("WyattMorse.PresentMimic"); patches.PatchAll(); EnsureRuntime(); Application.quitting += Shutdown; ((BaseUnityPlugin)this).Logger.LogInfo((object)"Present Mimic 0.4.0 loaded: /present retains its 50% roll; cursed gifts ambush on pickup. Bracken-style acceleration, grounded gait, repeated 40-damage bites and creature vocals enabled."); } internal static void EnsureRuntime() { //IL_0017: Unknown result type (might be due to invalid IL or missing references) //IL_0021: Expected O, but got Unknown if (!((Object)(object)runtime != (Object)null)) { runtime = new GameObject("PresentMimic.Runtime"); Object.DontDestroyOnLoad((Object)(object)runtime); runtime.AddComponent<MimicService>(); runtime.AddComponent<PresentMimicPreview>(); } } private static void Shutdown() { if ((Object)(object)runtime != (Object)null) { Object.Destroy((Object)(object)runtime); } runtime = null; Harmony? obj = patches; if (obj != null) { obj.UnpatchSelf(); } patches = null; Application.quitting -= Shutdown; } } [HarmonyPatch(typeof(StartOfRound), "Awake")] internal static class RestoreMimicRuntime { private static void Postfix() { Plugin.EnsureRuntime(); } } internal static class PresentCommand { private static readonly FieldRef<GiftBoxItem, GameObject> Contents = AccessTools.FieldRefAccess<GiftBoxItem, GameObject>("objectInPresent"); private static readonly FieldRef<GiftBoxItem, Item> ContentsItem = AccessTools.FieldRefAccess<GiftBoxItem, Item>("objectInPresentItem"); private static readonly FieldRef<GiftBoxItem, int> ContentsValue = AccessTools.FieldRefAccess<GiftBoxItem, int>("objectInPresentValue"); private static readonly FieldRef<GiftBoxItem, bool> Prepared = AccessTools.FieldRefAccess<GiftBoxItem, bool>("loadedItemFromSave"); private static readonly Random Random = new Random(); private static float nextSpawn; private static readonly HashSet<GiftBoxItem> Ambushes = new HashSet<GiftBoxItem>(); private static readonly HashSet<GiftBoxItem> Opened = new HashSet<GiftBoxItem>(); private static readonly FieldInfo RpcStage = AccessTools.Field(typeof(NetworkBehaviour), "__rpc_exec_stage"); private static float nextDiscovery; internal static void Watch(GiftBoxItem gift) { if ((Object)(object)gift != (Object)null && (Object)(object)ContentsItem.Invoke(gift) == (Object)(object)MimicAssets.Definition) { Ambushes.Add(gift); } } internal static void TickPickupAmbushes() { if ((Object)(object)NetworkManager.Singleton == (Object)null || !NetworkManager.Singleton.IsServer) { return; } if (Time.unscaledTime >= nextDiscovery) { nextDiscovery = Time.unscaledTime + 1f; GiftBoxItem[] array = Object.FindObjectsOfType<GiftBoxItem>(); foreach (GiftBoxItem val in array) { if (((NetworkBehaviour)val).IsSpawned) { Watch(val); } } Opened.RemoveWhere((GiftBoxItem g) => (Object)(object)g == (Object)null || !((NetworkBehaviour)g).IsSpawned); } GiftBoxItem[] array2 = Ambushes.ToArray(); foreach (GiftBoxItem val2 in array2) { if ((Object)(object)val2 == (Object)null || ((GrabbableObject)val2).deactivated || Opened.Contains(val2)) { Ambushes.Remove(val2); } else if (CanAmbush(val2)) { val2.OpenGiftBoxServerRpc(); } } } private static bool CanAmbush(GiftBoxItem gift) { return Plugin.Enabled.Value && ((NetworkBehaviour)gift).IsSpawned && ((GrabbableObject)gift).isHeld && (Object)(object)((GrabbableObject)gift).playerHeldBy != (Object)null && ((GrabbableObject)gift).playerHeldBy.isPlayerControlled && !((GrabbableObject)gift).playerHeldBy.isPlayerDead && ((GrabbableObject)gift).playerHeldBy.ItemSlots != null && (((GrabbableObject)gift).playerHeldBy.ItemSlots.Contains((GrabbableObject)(object)gift) || (Object)(object)((GrabbableObject)gift).playerHeldBy.ItemOnlySlot == (Object)(object)gift); } internal static bool GuardOpen(GiftBoxItem gift) { if ((Object)(object)NetworkManager.Singleton == (Object)null || !NetworkManager.Singleton.IsServer || (Object)(object)ContentsItem.Invoke(gift) != (Object)(object)MimicAssets.Definition) { return true; } if (RpcStage.GetValue(gift).ToString() != "Execute") { return true; } if (Opened.Contains(gift) || ((GrabbableObject)gift).deactivated || !CanAmbush(gift)) { return false; } Opened.Add(gift); return true; } internal static void ResetAmbushes() { Ambushes.Clear(); Opened.Clear(); nextDiscovery = 0f; } internal static bool Matches(string text) { return string.Equals(text?.Trim(), "/present", StringComparison.OrdinalIgnoreCase); } internal static bool IsMimicRoll(double roll) { return roll >= 0.0 && roll < 0.5; } internal static void Spawn() { //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_015b: 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_0164: Unknown result type (might be due to invalid IL or missing references) //IL_0169: Unknown result type (might be due to invalid IL or missing references) //IL_0171: Unknown result type (might be due to invalid IL or missing references) //IL_0176: Unknown result type (might be due to invalid IL or missing references) //IL_0180: Unknown result type (might be due to invalid IL or missing references) //IL_0185: Unknown result type (might be due to invalid IL or missing references) //IL_018a: Unknown result type (might be due to invalid IL or missing references) //IL_018c: Unknown result type (might be due to invalid IL or missing references) //IL_018e: Unknown result type (might be due to invalid IL or missing references) //IL_0195: Unknown result type (might be due to invalid IL or missing references) //IL_019a: Unknown result type (might be due to invalid IL or missing references) //IL_019f: Unknown result type (might be due to invalid IL or missing references) //IL_01a1: Unknown result type (might be due to invalid IL or missing references) //IL_01a3: 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_01d5: Unknown result type (might be due to invalid IL or missing references) //IL_01bb: Unknown result type (might be due to invalid IL or missing references) //IL_01c0: Unknown result type (might be due to invalid IL or missing references) //IL_01c7: Unknown result type (might be due to invalid IL or missing references) //IL_01cc: 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_01f5: Unknown result type (might be due to invalid IL or missing references) //IL_01fa: Unknown result type (might be due to invalid IL or missing references) //IL_0204: Unknown result type (might be due to invalid IL or missing references) //IL_0209: Unknown result type (might be due to invalid IL or missing references) //IL_020e: Unknown result type (might be due to invalid IL or missing references) //IL_0258: Unknown result type (might be due to invalid IL or missing references) //IL_025a: Unknown result type (might be due to invalid IL or missing references) NetworkManager singleton = NetworkManager.Singleton; StartOfRound instance = StartOfRound.Instance; PlayerControllerB val = (((Object)(object)instance != (Object)null) ? instance.localPlayerController : null); if ((Object)(object)singleton == (Object)null || !singleton.IsListening || !singleton.IsServer) { Tip("Only the host can spawn a present."); return; } if ((Object)(object)val == (Object)null || val.isPlayerDead || !val.isPlayerControlled || instance.shipIsLeaving || (Object)(object)RoundManager.Instance == (Object)null) { Tip("Join a round as a living player before spawning a present."); return; } if (!Plugin.Enabled.Value) { Tip("Present Mimic is disabled in the host configuration."); return; } if (Time.unscaledTime < nextSpawn) { Tip("Wait two seconds between presents."); return; } Item val2 = MimicAssets.VanillaGift(); Item[] array = instance.allItemsList.itemsList.Where((Item i) => (Object)(object)i != (Object)null && i.isScrap && (Object)(object)i.spawnPrefab != (Object)null && (Object)(object)i.spawnPrefab.GetComponent<GrabbableObject>() != (Object)null && (Object)(object)i.spawnPrefab.GetComponent<GiftBoxItem>() == (Object)null && i.maxValue > 0).ToArray(); if ((Object)(object)val2 == (Object)null || array.Length == 0) { Tip("The game's gift and loot prefabs are not ready yet."); return; } Vector3 val3 = Vector3.ProjectOnPlane(((Component)val.gameplayCamera).transform.forward, Vector3.up); Vector3 normalized = ((Vector3)(ref val3)).normalized; Vector3 val4 = ((Component)val).transform.position + Vector3.up * 0.8f; Vector3 val5 = val4 + normalized * 1.1f; RaycastHit val6 = default(RaycastHit); if (Physics.Linecast(val4, val5, ref val6, instance.collidersAndRoomMaskAndDefault, (QueryTriggerInteraction)1)) { val5 = ((RaycastHit)(ref val6)).point - normalized * 0.3f; } RaycastHit val7 = default(RaycastHit); if (Physics.Raycast(val5, Vector3.down, ref val7, 4f, instance.collidersAndRoomMaskAndDefault, (QueryTriggerInteraction)1)) { val5 = ((RaycastHit)(ref val7)).point + Vector3.up * 0.25f; bool flag = IsMimicRoll(Random.NextDouble()); Item val8 = (flag ? MimicAssets.Definition : array[Random.Next(array.Length)]); GameObject val9 = Object.Instantiate<GameObject>(val2.spawnPrefab, val5, Quaternion.identity); try { GiftBoxItem component = val9.GetComponent<GiftBoxItem>(); ContentsItem.Invoke(component) = val8; Contents.Invoke(component) = (flag ? MimicAssets.OpenedPrefab : val8.spawnPrefab); ContentsValue.Invoke(component) = ((!flag) ? Mathf.Max(1, (int)((float)Random.Next(val8.minValue + 25, Math.Max(val8.minValue + 26, val8.maxValue + 35)) * RoundManager.Instance.scrapValueMultiplier)) : 0); Prepared.Invoke(component) = true; ((GrabbableObject)component).SetScrapValue(0); ((NetworkBehaviour)component).NetworkObject.Spawn(false); if (flag) { Watch(component); } ((GrabbableObject)component).isInElevator = (((GrabbableObject)component).isInShipRoom = val.isInHangarShipRoom); nextSpawn = Time.unscaledTime + 2f; Tip("Present spawned. 50% ambush on pickup [E]. Safe gifts open normally [LMB]."); Plugin.Log.LogInfo((object)"Spawned a vanilla command gift with a single host-authoritative 50% roll."); return; } catch (Exception ex) { NetworkObject component2 = val9.GetComponent<NetworkObject>(); if ((Object)(object)component2 != (Object)null && component2.IsSpawned) { component2.Despawn(true); } else { Object.Destroy((Object)(object)val9); } Plugin.Log.LogError((object)("Could not spawn the command present: " + ex)); Tip("Could not spawn the present. See Present Mimic's log."); return; } } Tip("Stand near a clear floor before spawning a present."); } private static void Tip(string message) { HUDManager instance = HUDManager.Instance; if (instance != null) { instance.DisplayTip("Present", message, false, false, "PresentMimicCommand"); } } } [HarmonyPatch(typeof(HUDManager), "SubmitChat_performed")] internal static class PresentChatCommand { [HarmonyPriority(800)] private static void Prefix(HUDManager __instance, CallbackContext context) { PlayerControllerB val = (((Object)(object)GameNetworkManager.Instance != (Object)null) ? GameNetworkManager.Instance.localPlayerController : null); if (((CallbackContext)(ref context)).performed && !((Object)(object)val == (Object)null) && val.isTypingChat && !val.isPlayerDead && PresentCommand.Matches(__instance.chatTextField.text)) { __instance.chatTextField.text = ""; PresentCommand.Spawn(); } } } [HarmonyPatch(typeof(GiftBoxItem), "LoadItemSaveData")] internal static class RestoreSavedMimicGift { private static void Postfix(GiftBoxItem __instance, Item ___objectInPresentItem, ref GameObject ___objectInPresent) { if ((Object)(object)___objectInPresentItem == (Object)(object)MimicAssets.Definition) { ___objectInPresent = MimicAssets.OpenedPrefab; PresentCommand.Watch(__instance); } } } [HarmonyPatch(typeof(GiftBoxItem), "OpenGiftBoxServerRpc")] internal static class OnePickupAmbush { private static bool Prefix(GiftBoxItem __instance) { return PresentCommand.GuardOpen(__instance); } } internal sealed class PresentMimicPreview : MonoBehaviour { private PresentMimicVisual? preview; private StartOfRound? ownerRound; private bool revealing; private float revealStart; private void Update() { StartOfRound instance = StartOfRound.Instance; if (!Plugin.EnableVisualPreview.Value || (Object)(object)instance == (Object)null || ((Object)(object)ownerRound != (Object)null && (Object)(object)ownerRound != (Object)(object)instance)) { Clear(); return; } PlayerControllerB localPlayerController = instance.localPlayerController; if ((Object)(object)localPlayerController == (Object)null) { return; } Keyboard current = Keyboard.current; if (current != null) { if (((ButtonControl)current.f10Key).wasPressedThisFrame) { Clear(); } if (!localPlayerController.isPlayerDead && localPlayerController.isPlayerControlled && (Object)(object)localPlayerController.gameplayCamera != (Object)null) { if (((ButtonControl)current.f8Key).wasPressedThisFrame) { Place(instance); } if (((ButtonControl)current.f9Key).wasPressedThisFrame && (Object)(object)preview != (Object)null) { revealing = !revealing; revealStart = Time.time; Tip(revealing ? "Revealing the mimic." : "Reset to the original present size."); } } } if ((Object)(object)preview != (Object)null) { float num = Mathf.Max(0f, Time.time - revealStart); preview.SetPose(revealing ? Mathf.Clamp01(num / Mathf.Clamp(Plugin.RevealSeconds.Value, 0.5f, 5f)) : 0f, revealing ? num : 0f); } } private void Place(StartOfRound round) { //IL_00cf: 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_00de: Unknown result type (might be due to invalid IL or missing references) //IL_00e2: Unknown result type (might be due to invalid IL or missing references) //IL_00e7: Unknown result type (might be due to invalid IL or missing references) //IL_010e: Unknown result type (might be due to invalid IL or missing references) //IL_0113: Unknown result type (might be due to invalid IL or missing references) //IL_0119: Unknown result type (might be due to invalid IL or missing references) //IL_011e: Unknown result type (might be due to invalid IL or missing references) //IL_0123: Unknown result type (might be due to invalid IL or missing references) //IL_012d: Unknown result type (might be due to invalid IL or missing references) //IL_0132: 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_0138: Unknown result type (might be due to invalid IL or missing references) //IL_0139: Unknown result type (might be due to invalid IL or missing references) //IL_0102: Unknown result type (might be due to invalid IL or missing references) //IL_0107: Unknown result type (might be due to invalid IL or missing references) //IL_0173: Unknown result type (might be due to invalid IL or missing references) //IL_017a: Expected O, but got Unknown //IL_0184: Unknown result type (might be due to invalid IL or missing references) //IL_0189: 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_01aa: Unknown result type (might be due to invalid IL or missing references) //IL_01ab: Unknown result type (might be due to invalid IL or missing references) //IL_01b0: 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_01da: 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) if ((Object)(object)round.allItemsList == (Object)null || round.allItemsList.itemsList == null) { return; } Item val = null; foreach (Item items in round.allItemsList.itemsList) { if ((Object)(object)items != (Object)null && (Object)(object)items.spawnPrefab != (Object)null && (Object)(object)items.spawnPrefab.GetComponent<GiftBoxItem>() != (Object)null) { val = items; break; } } if ((Object)(object)val == (Object)null) { Tip("Vanilla present prefab is not available in this session."); return; } PlayerControllerB localPlayerController = round.localPlayerController; Vector3 val2 = Vector3.ProjectOnPlane(((Component)localPlayerController.gameplayCamera).transform.forward, Vector3.up); Vector3 val3 = ((Vector3)(ref val2)).normalized; if (((Vector3)(ref val3)).sqrMagnitude < 0.01f) { val3 = ((Component)localPlayerController).transform.forward; } Vector3 val4 = ((Component)localPlayerController).transform.position + val3 * 4f + Vector3.up * 2f; RaycastHit val5 = default(RaycastHit); if (!Physics.Raycast(val4, Vector3.down, ref val5, 8f, -5, (QueryTriggerInteraction)1)) { Tip("No floor ahead for a visual preview."); return; } Clear(); GameObject val6 = new GameObject("PresentMimic local visual preview (no gameplay)"); try { val6.transform.position = ((RaycastHit)(ref val5)).point + Vector3.up * 0.015f; val6.transform.rotation = Quaternion.LookRotation(-val3, Vector3.up); preview = val6.AddComponent<PresentMimicVisual>(); preview.Initialize(val.spawnPrefab, Quaternion.Euler(val.restingRotation), Plugin.RevealedBoxScale.Value); ownerRound = round; revealing = false; revealStart = Time.time; Tip("F9: grow/reveal or reset. F10: remove. This preview is visible only to you."); Plugin.Log.LogInfo((object)$"Visual preview uses vanilla '{val.itemName}' meshes/materials; dormant width {preview.DormantWidth:F3} m, growth {Plugin.RevealedBoxScale.Value:F2}x. No real gift was spawned or modified."); } catch (Exception ex) { Object.Destroy((Object)(object)val6); preview = null; Plugin.Log.LogError((object)("Could not create the present visual; no gameplay objects were changed. " + ex)); Tip("Preview could not be built. See the PresentMimic log entry."); } } private static void Tip(string text) { if ((Object)(object)HUDManager.Instance != (Object)null) { HUDManager.Instance.DisplayTip("Present Mimic visual preview", text, false, false, "PMVisualPreview"); } } private void Clear() { if ((Object)(object)preview != (Object)null) { Object.Destroy((Object)(object)((Component)preview).gameObject); } preview = null; ownerRound = null; revealing = false; } private void OnDestroy() { Clear(); } } public static class PluginInfo { public const string PLUGIN_GUID = "WyattMorse.PresentMimic"; public const string PLUGIN_NAME = "PresentMimic"; public const string PLUGIN_VERSION = "0.4.0"; } } namespace PresentMimic.Visuals { public sealed class GiftShell { public sealed class Part { public Mesh Mesh; public Material[] Materials; public Part(Mesh mesh, Material[] materials) { Mesh = mesh; Materials = materials; } } private struct Vertex { public Vector3 Position; public Vector3 Normal; public Vector4 Tangent; public Color Color; public Vector4[] UV; public static Vertex Lerp(Vertex a, Vertex b, float t) { //IL_0015: 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_0027: Unknown result type (might be due to invalid IL or missing references) //IL_002c: Unknown result type (might be due to invalid IL or missing references) //IL_0048: Unknown result type (might be due to invalid IL or missing references) //IL_004e: Unknown result type (might be due to invalid IL or missing references) //IL_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_0061: Unknown result type (might be due to invalid IL or missing references) //IL_0067: Unknown result type (might be due to invalid IL or missing references) //IL_006d: Unknown result type (might be due to invalid IL or missing references) //IL_0072: Unknown result type (might be due to invalid IL or missing references) //IL_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_0083: Unknown result type (might be due to invalid IL or missing references) //IL_0089: Unknown result type (might be due to invalid IL or missing references) //IL_008f: 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_009c: Unknown result type (might be due to invalid IL or missing references) //IL_00a2: Unknown result type (might be due to invalid IL or missing references) //IL_00a8: Unknown result type (might be due to invalid IL or missing references) //IL_00ad: Unknown result type (might be due to invalid IL or missing references) Vector4[] array = (Vector4[])(object)new Vector4[8]; for (int i = 0; i < 8; i++) { array[i] = Vector4.LerpUnclamped(a.UV[i], b.UV[i], t); } Vertex result = new Vertex { Position = Vector3.LerpUnclamped(a.Position, b.Position, t) }; Vector3 val = Vector3.LerpUnclamped(a.Normal, b.Normal, t); result.Normal = ((Vector3)(ref val)).normalized; result.Tangent = Vector4.LerpUnclamped(a.Tangent, b.Tangent, t); result.Color = Color.LerpUnclamped(a.Color, b.Color, t); result.UV = array; return result; } } public readonly List<Part> Parts = new List<Part>(); public Bounds Bounds { get; private set; } public float Width { get; private set; } public static GiftShell Capture(GameObject source, Quaternion restingRotation) { //IL_000a: Unknown result type (might be due to invalid IL or missing references) //IL_000f: Unknown result type (might be due to invalid IL or missing references) //IL_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_0026: 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_0030: Unknown result type (might be due to invalid IL or missing references) //IL_02c2: Unknown result type (might be due to invalid IL or missing references) //IL_02c7: Unknown result type (might be due to invalid IL or missing references) //IL_02cb: Unknown result type (might be due to invalid IL or missing references) //IL_0090: Unknown result type (might be due to invalid IL or missing references) //IL_0098: Unknown result type (might be due to invalid IL or missing references) //IL_009d: Unknown result type (might be due to invalid IL or missing references) //IL_00a2: Unknown result type (might be due to invalid IL or missing references) //IL_00c1: Unknown result type (might be due to invalid IL or missing references) //IL_00c6: Unknown result type (might be due to invalid IL or missing references) //IL_00ca: 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_02f2: Unknown result type (might be due to invalid IL or missing references) //IL_02f7: Unknown result type (might be due to invalid IL or missing references) //IL_02fb: Unknown result type (might be due to invalid IL or missing references) //IL_030e: Unknown result type (might be due to invalid IL or missing references) //IL_0313: Unknown result type (might be due to invalid IL or missing references) //IL_0317: Unknown result type (might be due to invalid IL or missing references) //IL_0322: Unknown result type (might be due to invalid IL or missing references) //IL_0327: Unknown result type (might be due to invalid IL or missing references) //IL_032b: Unknown result type (might be due to invalid IL or missing references) //IL_0336: Unknown result type (might be due to invalid IL or missing references) //IL_033b: Unknown result type (might be due to invalid IL or missing references) //IL_033f: 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) //IL_011c: Unknown result type (might be due to invalid IL or missing references) //IL_0121: Unknown result type (might be due to invalid IL or missing references) //IL_0129: 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_0100: 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_03eb: Unknown result type (might be due to invalid IL or missing references) //IL_03f0: Unknown result type (might be due to invalid IL or missing references) //IL_03f4: Unknown result type (might be due to invalid IL or missing references) //IL_03f9: Unknown result type (might be due to invalid IL or missing references) //IL_03fa: Unknown result type (might be due to invalid IL or missing references) //IL_0405: Unknown result type (might be due to invalid IL or missing references) //IL_040b: Unknown result type (might be due to invalid IL or missing references) //IL_0410: Unknown result type (might be due to invalid IL or missing references) //IL_0414: Unknown result type (might be due to invalid IL or missing references) //IL_041f: Unknown result type (might be due to invalid IL or missing references) //IL_0424: 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_015b: 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_0164: Unknown result type (might be due to invalid IL or missing references) //IL_0169: Unknown result type (might be due to invalid IL or missing references) //IL_0383: Unknown result type (might be due to invalid IL or missing references) //IL_0388: Unknown result type (might be due to invalid IL or missing references) //IL_0389: Unknown result type (might be due to invalid IL or missing references) //IL_0394: Unknown result type (might be due to invalid IL or missing references) //IL_0399: Unknown result type (might be due to invalid IL or missing references) //IL_0183: Unknown result type (might be due to invalid IL or missing references) //IL_0188: Unknown result type (might be due to invalid IL or missing references) //IL_018d: Unknown result type (might be due to invalid IL or missing references) //IL_0192: Unknown result type (might be due to invalid IL or missing references) //IL_0196: Unknown result type (might be due to invalid IL or missing references) //IL_019b: Unknown result type (might be due to invalid IL or missing references) //IL_01a1: 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_01af: 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) GiftShell giftShell = new GiftShell(); try { bool flag = true; Matrix4x4 val = Matrix4x4.TRS(Vector3.zero, restingRotation, source.transform.localScale) * source.transform.worldToLocalMatrix; MeshFilter[] componentsInChildren = source.GetComponentsInChildren<MeshFilter>(true); foreach (MeshFilter val2 in componentsInChildren) { MeshRenderer component = ((Component)val2).GetComponent<MeshRenderer>(); if ((Object)(object)component == (Object)null || !((Renderer)component).enabled || (Object)(object)val2.sharedMesh == (Object)null) { continue; } Mesh val3 = ReadMesh(val2.sharedMesh); Matrix4x4 val4 = val * ((Component)val2).transform.localToWorldMatrix; Vector3[] vertices = val3.vertices; Vector3[] normals = val3.normals; Vector4[] tangents = val3.tangents; Matrix4x4 inverse = ((Matrix4x4)(ref val4)).inverse; Matrix4x4 transpose = ((Matrix4x4)(ref inverse)).transpose; for (int j = 0; j < vertices.Length; j++) { vertices[j] = ((Matrix4x4)(ref val4)).MultiplyPoint3x4(vertices[j]); if (flag) { giftShell.Bounds = new Bounds(vertices[j], Vector3.zero); flag = false; } else { Bounds bounds = giftShell.Bounds; ((Bounds)(ref bounds)).Encapsulate(vertices[j]); giftShell.Bounds = bounds; } Vector3 val5; if (j < normals.Length) { int num = j; val5 = ((Matrix4x4)(ref transpose)).MultiplyVector(normals[j]); normals[num] = ((Vector3)(ref val5)).normalized; } if (j < tangents.Length) { val5 = ((Matrix4x4)(ref val4)).MultiplyVector(Vector4.op_Implicit(tangents[j])); Vector3 normalized = ((Vector3)(ref val5)).normalized; tangents[j] = new Vector4(normalized.x, normalized.y, normalized.z, tangents[j].w * Mathf.Sign(((Matrix4x4)(ref val4)).determinant)); } } val3.vertices = vertices; val3.normals = normals; val3.tangents = tangents; if (((Matrix4x4)(ref val4)).determinant < 0f) { for (int k = 0; k < val3.subMeshCount; k++) { int[] triangles = val3.GetTriangles(k); for (int l = 0; l < triangles.Length; l += 3) { int num2 = triangles[l]; triangles[l] = triangles[l + 1]; triangles[l + 1] = num2; } val3.SetTriangles(triangles, k); } } giftShell.Parts.Add(new Part(val3, ((Renderer)component).sharedMaterials)); } if (!flag) { Bounds bounds2 = giftShell.Bounds; if (!(((Bounds)(ref bounds2)).size.x < 0.001f)) { bounds2 = giftShell.Bounds; giftShell.Width = ((Bounds)(ref bounds2)).size.x; bounds2 = giftShell.Bounds; float x = ((Bounds)(ref bounds2)).center.x; bounds2 = giftShell.Bounds; float y = ((Bounds)(ref bounds2)).min.y; bounds2 = giftShell.Bounds; Vector3 val6 = default(Vector3); ((Vector3)(ref val6))..ctor(x, y, ((Bounds)(ref bounds2)).center.z); foreach (Part part in giftShell.Parts) { Vector3[] vertices2 = part.Mesh.vertices; for (int m = 0; m < vertices2.Length; m++) { vertices2[m] = (vertices2[m] - val6) / giftShell.Width; } part.Mesh.vertices = vertices2; part.Mesh.RecalculateBounds(); } bounds2 = giftShell.Bounds; Vector3 val7 = (((Bounds)(ref bounds2)).center - val6) / giftShell.Width; bounds2 = giftShell.Bounds; giftShell.Bounds = new Bounds(val7, ((Bounds)(ref bounds2)).size / giftShell.Width); return giftShell; } } throw new InvalidOperationException("Gift has no usable mesh renderers."); } catch { giftShell.Dispose(); throw; } } private static Mesh ReadMesh(Mesh source) { //IL_0017: Unknown result type (might be due to invalid IL or missing references) //IL_001c: Unknown result type (might be due to invalid IL or missing references) //IL_0033: Unknown result type (might be due to invalid IL or missing references) //IL_0035: Unknown result type (might be due to invalid IL or missing references) //IL_0041: Expected O, but got Unknown //IL_011d: Unknown result type (might be due to invalid IL or missing references) //IL_0122: Unknown result type (might be due to invalid IL or missing references) //IL_0127: Unknown result type (might be due to invalid IL or missing references) //IL_0135: Unknown result type (might be due to invalid IL or missing references) //IL_013a: Unknown result type (might be due to invalid IL or missing references) //IL_013f: Unknown result type (might be due to invalid IL or missing references) //IL_014d: Unknown result type (might be due to invalid IL or missing references) //IL_0152: 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_016a: Unknown result type (might be due to invalid IL or missing references) //IL_0191: Unknown result type (might be due to invalid IL or missing references) //IL_028b: Unknown result type (might be due to invalid IL or missing references) //IL_0290: Unknown result type (might be due to invalid IL or missing references) //IL_0294: Unknown result type (might be due to invalid IL or missing references) //IL_029a: Invalid comparison between Unknown and I4 //IL_02d2: Unknown result type (might be due to invalid IL or missing references) if (source.isReadable) { return Object.Instantiate<Mesh>(source); } Mesh val = new Mesh { name = ((Object)source).name + " (mimic copy)", indexFormat = source.indexFormat }; try { Dictionary<int, byte[]> dictionary = new Dictionary<int, byte[]>(); for (int i = 0; i < source.vertexBufferCount; i++) { GraphicsBuffer vertexBuffer = source.GetVertexBuffer(i); try { byte[] array = new byte[vertexBuffer.count * vertexBuffer.stride]; vertexBuffer.GetData((Array)array); dictionary.Add(i, array); } finally { ((IDisposable)vertexBuffer)?.Dispose(); } } Vector3[] array2 = (Vector3[])(object)new Vector3[source.vertexCount]; Vector3[] array3 = (Vector3[])(object)new Vector3[source.vertexCount]; Vector4[] array4 = (Vector4[])(object)new Vector4[source.vertexCount]; Color[] array5 = (Color[])(object)new Color[source.vertexCount]; List<Vector4>[] array6 = new List<Vector4>[8]; for (int j = 0; j < 8; j++) { array6[j] = new List<Vector4>(source.vertexCount); } for (int k = 0; k < source.vertexCount; k++) { array2[k] = Vector4.op_Implicit(ReadAttribute(source, dictionary, (VertexAttribute)0, k)); array3[k] = Vector4.op_Implicit(ReadAttribute(source, dictionary, (VertexAttribute)1, k)); array4[k] = ReadAttribute(source, dictionary, (VertexAttribute)2, k); array5[k] = Color.op_Implicit(ReadAttribute(source, dictionary, (VertexAttribute)3, k)); for (int l = 0; l < 8; l++) { if (source.HasVertexAttribute((VertexAttribute)(4 + l))) { array6[l].Add(ReadAttribute(source, dictionary, (VertexAttribute)(4 + l), k)); } } } val.vertices = array2; if (source.HasVertexAttribute((VertexAttribute)1)) { val.normals = array3; } if (source.HasVertexAttribute((VertexAttribute)2)) { val.tangents = array4; } if (source.HasVertexAttribute((VertexAttribute)3)) { val.colors = array5; } for (int m = 0; m < 8; m++) { if (array6[m].Count > 0) { val.SetUVs(m, array6[m]); } } GraphicsBuffer indexBuffer = source.GetIndexBuffer(); try { byte[] array7 = new byte[indexBuffer.count * indexBuffer.stride]; indexBuffer.GetData((Array)array7); val.subMeshCount = source.subMeshCount; for (int n = 0; n < source.subMeshCount; n++) { SubMeshDescriptor subMesh = source.GetSubMesh(n); if ((int)((SubMeshDescriptor)(ref subMesh)).topology > 0) { throw new InvalidOperationException("Gift mesh must use triangles."); } int[] array8 = new int[((SubMeshDescriptor)(ref subMesh)).indexCount]; for (int num = 0; num < array8.Length; num++) { int num2 = ((SubMeshDescriptor)(ref subMesh)).indexStart + num; array8[num] = (int)(((int)source.indexFormat == 0) ? BitConverter.ToUInt16(array7, num2 * 2) : BitConverter.ToUInt32(array7, num2 * 4)) + ((SubMeshDescriptor)(ref subMesh)).baseVertex; } val.SetTriangles(array8, n); } } finally { ((IDisposable)indexBuffer)?.Dispose(); } if (!source.HasVertexAttribute((VertexAttribute)1)) { val.RecalculateNormals(); } val.RecalculateBounds(); return val; } catch { DestroyOwned((Object)(object)val); throw; } } private unsafe static Vector4 ReadAttribute(Mesh mesh, Dictionary<int, byte[]> streams, VertexAttribute attribute, int vertex) { //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_001e: Unknown result type (might be due to invalid IL or missing references) //IL_002f: Unknown result type (might be due to invalid IL or missing references) //IL_0038: Unknown result type (might be due to invalid IL or missing references) //IL_0039: Unknown result type (might be due to invalid IL or missing references) //IL_003e: Unknown result type (might be due to invalid IL or missing references) //IL_003f: Unknown result type (might be due to invalid IL or missing references) //IL_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_0042: Unknown result type (might be due to invalid IL or missing references) //IL_0044: Invalid comparison between Unknown and I4 //IL_0195: Unknown result type (might be due to invalid IL or missing references) //IL_0056: Unknown result type (might be due to invalid IL or missing references) //IL_005b: Unknown result type (might be due to invalid IL or missing references) //IL_0046: Unknown result type (might be due to invalid IL or missing references) //IL_0048: Invalid comparison between Unknown and I4 //IL_017e: 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