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 EchoMannequin v1.1.1
BepInEx/plugins/EchoMannequin/EchoMannequin.dll
Decompiled a day agousing System; using System.Collections; using System.Collections.Generic; using System.Diagnostics; using System.Linq; using System.Reflection; using System.Runtime.CompilerServices; using BepInEx; using BepInEx.Logging; using HarmonyLib; using Microsoft.CodeAnalysis; using Photon.Pun; using REPOLib.Modules; using UnityEngine; using UnityEngine.InputSystem; using UnityEngine.InputSystem.Controls; using UnityEngine.Rendering; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: AssemblyVersion("0.0.0.0")] [module: RefSafetyRules(11)] namespace Microsoft.CodeAnalysis { [CompilerGenerated] [Embedded] internal sealed class EmbeddedAttribute : Attribute { } } namespace System.Runtime.CompilerServices { [CompilerGenerated] [Embedded] [AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)] internal sealed class RefSafetyRulesAttribute : Attribute { public readonly int Version; public RefSafetyRulesAttribute(int P_0) { Version = P_0; } } } namespace EchoMannequinMod { internal sealed class GroundedMotion { private bool sampled; private bool wasGrounded; internal bool Active { get; private set; } internal void Reset() { Active = false; sampled = false; } internal bool Step(bool held, bool floorContact, bool ownerGrounded, float upwardSpeed, int mode) { bool active = Active; if (held) { Active = false; } else if (floorContact) { Active = true; } bool result = sampled && active && Active && !held && mode != 2 && wasGrounded && !ownerGrounded && upwardSpeed > 0.5f; sampled = true; wasGrounded = ownerGrounded; return result; } } internal sealed class LiveReplica { private readonly Transform root; private readonly PlayerAvatar owner; private readonly Dictionary<Transform, Transform> transforms = new Dictionary<Transform, Transform>(); private readonly Dictionary<Renderer, Renderer> renderers = new Dictionary<Renderer, Renderer>(); private readonly MaterialPropertyBlock properties = new MaterialPropertyBlock(); private float nextScan; private float floorOffset; private bool hasPose; internal float Height { get; private set; } internal LiveReplica(Transform root, PlayerAvatar owner) { //IL_0017: Unknown result type (might be due to invalid IL or missing references) //IL_0021: Expected O, but got Unknown this.root = root; this.owner = owner; Height = 1.25f; } private Transform Map(Transform source) { //IL_00a0: Unknown result type (might be due to invalid IL or missing references) //IL_0131: Unknown result type (might be due to invalid IL or missing references) //IL_0140: Unknown result type (might be due to invalid IL or missing references) //IL_0145: Unknown result type (might be due to invalid IL or missing references) //IL_014a: Unknown result type (might be due to invalid IL or missing references) //IL_014c: Unknown result type (might be due to invalid IL or missing references) //IL_014e: 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_0163: Unknown result type (might be due to invalid IL or missing references) //IL_0168: Unknown result type (might be due to invalid IL or missing references) //IL_016d: Unknown result type (might be due to invalid IL or missing references) //IL_0178: Unknown result type (might be due to invalid IL or missing references) //IL_017d: 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_018a: 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_019b: Unknown result type (might be due to invalid IL or missing references) //IL_00c3: Unknown result type (might be due to invalid IL or missing references) //IL_00c9: Unknown result type (might be due to invalid IL or missing references) //IL_00cf: Unknown result type (might be due to invalid IL or missing references) //IL_00d5: Unknown result type (might be due to invalid IL or missing references) //IL_00da: Unknown result type (might be due to invalid IL or missing references) //IL_00df: Unknown result type (might be due to invalid IL or missing references) //IL_00e4: 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_00f6: Unknown result type (might be due to invalid IL or missing references) //IL_00fb: Unknown result type (might be due to invalid IL or missing references) //IL_0107: Unknown result type (might be due to invalid IL or missing references) //IL_010d: Unknown result type (might be due to invalid IL or missing references) //IL_0112: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)source == (Object)null) { return null; } if (transforms.TryGetValue(source, out var value)) { return value; } Transform val = (((Object)(object)source != (Object)(object)((Component)owner).transform && (Object)(object)source != (Object)(object)owner.playerTransform && (Object)(object)source.parent != (Object)null && (source.IsChildOf(((Component)owner).transform) || ((Object)(object)owner.playerTransform != (Object)null && source.IsChildOf(owner.playerTransform)))) ? Map(source.parent) : null); value = new GameObject(((Object)source).name).transform; value.SetParent(root, false); if ((Object)(object)val != (Object)null) { value.localPosition = val.localPosition + val.localRotation * Vector3.Scale(val.localScale, source.localPosition); value.localRotation = val.localRotation * source.localRotation; value.localScale = Vector3.Scale(val.localScale, source.localScale); } else { Quaternion val2 = Quaternion.Inverse(Quaternion.Euler(0f, ((Component)owner).transform.eulerAngles.y, 0f)); value.localPosition = val2 * (source.position - ((Component)owner).transform.position) + Vector3.up * floorOffset; value.localRotation = val2 * source.rotation; value.localScale = source.lossyScale; } transforms.Add(source, value); return value; } private void Scan() { //IL_02b4: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)owner.playerAvatarVisuals == (Object)null) { return; } HashSet<Renderer> hashSet = new HashSet<Renderer>(((Component)owner.playerAvatarVisuals).GetComponentsInChildren<Renderer>(true)); if ((Object)(object)owner.playerCosmetics != (Object)null && AccessTools.Field(typeof(PlayerCosmetics), "cosmeticParents").GetValue(owner.playerCosmetics) is IEnumerable enumerable) { foreach (object item2 in enumerable) { if (item2 == null) { continue; } FieldInfo fieldInfo = AccessTools.Field(item2.GetType(), "parent"); Transform val = (Transform)((fieldInfo != null) ? /*isinst with value type is only supported in some contexts*/: null); if ((Object)(object)val != (Object)null) { Renderer[] componentsInChildren = ((Component)val).GetComponentsInChildren<Renderer>(true); foreach (Renderer item in componentsInChildren) { hashSet.Add(item); } } } } Transform[] array = (Transform[])(object)new Transform[2] { ((Component)owner).transform, owner.playerTransform }; foreach (Transform val2 in array) { if ((Object)(object)val2 == (Object)null) { continue; } Renderer[] componentsInChildren = ((Component)val2).GetComponentsInChildren<Renderer>(true); foreach (Renderer val3 in componentsInChildren) { if (!((Object)(object)((Component)val3).GetComponentInParent<MannequinController>() != (Object)null) && !((Object)(object)((Component)val3).GetComponentInParent<Camera>() != (Object)null) && !((Object)(object)((Component)val3).GetComponentInParent<Canvas>() != (Object)null) && !((Object)(object)((Component)val3).GetComponentInParent<PhysGrabObject>() != (Object)null) && !((Object)(object)((Component)val3).GetComponentInParent<ItemAttributes>() != (Object)null)) { PlayerAvatar componentInParent = ((Component)val3).GetComponentInParent<PlayerAvatar>(); if (!((Object)(object)componentInParent != (Object)null) || !((Object)(object)componentInParent != (Object)(object)owner)) { hashSet.Add(val3); } } } } foreach (Renderer item3 in hashSet) { if (!renderers.ContainsKey(item3)) { SkinnedMeshRenderer val4 = (SkinnedMeshRenderer)(object)((item3 is SkinnedMeshRenderer) ? item3 : null); MeshRenderer val5 = (MeshRenderer)(object)((item3 is MeshRenderer) ? item3 : null); if ((Object)(object)val4 != (Object)null && (Object)(object)val4.sharedMesh != (Object)null) { SkinnedMeshRenderer val6 = ((Component)Map(((Component)item3).transform)).gameObject.AddComponent<SkinnedMeshRenderer>(); val6.sharedMesh = val4.sharedMesh; val6.bones = val4.bones.Select(Map).ToArray(); val6.rootBone = Map(val4.rootBone); ((Renderer)val6).localBounds = ((Renderer)val4).localBounds; val6.updateWhenOffscreen = true; renderers.Add(item3, (Renderer)(object)val6); } else if ((Object)(object)val5 != (Object)null && (Object)(object)((Component)val5).GetComponent<MeshFilter>() != (Object)null) { GameObject gameObject = ((Component)Map(((Component)item3).transform)).gameObject; (gameObject.GetComponent<MeshFilter>() ?? gameObject.AddComponent<MeshFilter>()).sharedMesh = ((Component)val5).GetComponent<MeshFilter>().sharedMesh; renderers.Add(item3, (Renderer)(object)gameObject.AddComponent<MeshRenderer>()); } } } KeyValuePair<Renderer, Renderer>[] array2 = renderers.ToArray(); for (int i = 0; i < array2.Length; i++) { KeyValuePair<Renderer, Renderer> keyValuePair = array2[i]; if ((Object)(object)keyValuePair.Key == (Object)null || !hashSet.Contains(keyValuePair.Key)) { if ((Object)(object)keyValuePair.Value != (Object)null) { Object.Destroy((Object)(object)keyValuePair.Value); } renderers.Remove(keyValuePair.Key); } } KeyValuePair<Transform, Transform>[] array3 = transforms.ToArray(); for (int i = 0; i < array3.Length; i++) { KeyValuePair<Transform, Transform> keyValuePair2 = array3[i]; if ((Object)(object)keyValuePair2.Key == (Object)null) { if ((Object)(object)keyValuePair2.Value != (Object)null) { Object.Destroy((Object)(object)((Component)keyValuePair2.Value).gameObject); } transforms.Remove(keyValuePair2.Key); } } } private bool Visible(Renderer renderer) { if (!renderer.enabled) { return false; } PlayerAvatarVisuals playerAvatarVisuals = owner.playerAvatarVisuals; Transform val = ((Component)renderer).transform; while ((Object)(object)val != (Object)null && (Object)(object)val != (Object)(object)((Component)playerAvatarVisuals).transform && (Object)(object)val != (Object)(object)((Component)owner).transform && (Object)(object)val != (Object)(object)owner.playerTransform) { if (!((Component)val).gameObject.activeSelf && (Object)(object)((Component)val).gameObject != (Object)(object)playerAvatarVisuals.meshParent) { return false; } val = val.parent; } return true; } internal void Tick(bool portable, bool freeze) { //IL_003f: Unknown result type (might be due to invalid IL or missing references) //IL_0044: Unknown result type (might be due to invalid IL or missing references) //IL_0055: Unknown result type (might be due to invalid IL or missing references) //IL_0064: Unknown result type (might be due to invalid IL or missing references) //IL_0069: Unknown result type (might be due to invalid IL or missing references) //IL_006e: Unknown result type (might be due to invalid IL or missing references) //IL_00b5: Unknown result type (might be due to invalid IL or missing references) //IL_00bd: Unknown result type (might be due to invalid IL or missing references) //IL_00c2: Unknown result type (might be due to invalid IL or missing references) //IL_00c3: Unknown result type (might be due to invalid IL or missing references) //IL_00c8: Unknown result type (might be due to invalid IL or missing references) //IL_00cd: Unknown result type (might be due to invalid IL or missing references) //IL_00d8: Unknown result type (might be due to invalid IL or missing references) //IL_00dd: Unknown result type (might be due to invalid IL or missing references) //IL_00ee: Unknown result type (might be due to invalid IL or missing references) //IL_00f6: Unknown result type (might be due to invalid IL or missing references) //IL_00fb: Unknown result type (might be due to invalid IL or missing references) //IL_0113: Unknown result type (might be due to invalid IL or missing references) //IL_044b: Unknown result type (might be due to invalid IL or missing references) //IL_045f: Unknown result type (might be due to invalid IL or missing references) //IL_0310: Unknown result type (might be due to invalid IL or missing references) //IL_0315: Unknown result type (might be due to invalid IL or missing references) //IL_0319: Unknown result type (might be due to invalid IL or missing references) //IL_0323: Unknown result type (might be due to invalid IL or missing references) //IL_0334: Unknown result type (might be due to invalid IL or missing references) //IL_0339: Unknown result type (might be due to invalid IL or missing references) //IL_033d: Unknown result type (might be due to invalid IL or missing references) //IL_0347: Unknown result type (might be due to invalid IL or missing references) //IL_03d0: Unknown result type (might be due to invalid IL or missing references) //IL_03d5: Unknown result type (might be due to invalid IL or missing references) //IL_03dc: Unknown result type (might be due to invalid IL or missing references) //IL_03e1: Unknown result type (might be due to invalid IL or missing references) if (Time.unscaledTime >= nextScan) { nextScan = Time.unscaledTime + 0.2f; Scan(); } bool flag = !freeze || !hasPose; Vector3 position = ((Component)owner).transform.position; Quaternion val = Quaternion.Inverse(Quaternion.Euler(0f, ((Component)owner).transform.eulerAngles.y, 0f)); foreach (KeyValuePair<Transform, Transform> transform in transforms) { if (flag && !((Object)(object)transform.Key == (Object)null) && !((Object)(object)transform.Value == (Object)null)) { transform.Value.localPosition = val * (transform.Key.position - position) + Vector3.up * floorOffset; transform.Value.localRotation = val * transform.Key.rotation; transform.Value.localScale = transform.Key.lossyScale; } } float num = float.PositiveInfinity; float num2 = float.NegativeInfinity; foreach (KeyValuePair<Renderer, Renderer> renderer in renderers) { if ((Object)(object)renderer.Key == (Object)null || (Object)(object)renderer.Value == (Object)null) { continue; } Renderer key = renderer.Key; Renderer value = renderer.Value; value.enabled = Visible(key); value.sharedMaterials = key.sharedMaterials; value.shadowCastingMode = (ShadowCastingMode)1; value.receiveShadows = key.receiveShadows; key.GetPropertyBlock(properties); value.SetPropertyBlock(properties); for (int i = 0; i < key.sharedMaterials.Length; i++) { key.GetPropertyBlock(properties, i); value.SetPropertyBlock(properties, i); } SkinnedMeshRenderer val2 = (SkinnedMeshRenderer)(object)((key is SkinnedMeshRenderer) ? key : null); SkinnedMeshRenderer val3 = (SkinnedMeshRenderer)(object)((value is SkinnedMeshRenderer) ? value : null); if (key is MeshRenderer) { ((Component)value).GetComponent<MeshFilter>().sharedMesh = ((Component)key).GetComponent<MeshFilter>().sharedMesh; } if ((Object)(object)val2 != (Object)null && (Object)(object)val3 != (Object)null && (Object)(object)val2.sharedMesh != (Object)null) { if ((Object)(object)val3.sharedMesh != (Object)(object)val2.sharedMesh) { val3.sharedMesh = val2.sharedMesh; val3.bones = val2.bones.Select(Map).ToArray(); val3.rootBone = Map(val2.rootBone); } if (flag) { for (int j = 0; j < val2.sharedMesh.blendShapeCount; j++) { val3.SetBlendShapeWeight(j, val2.GetBlendShapeWeight(j)); } } } if (value.enabled) { float num3 = num; Bounds bounds = key.bounds; num = Mathf.Min(num3, ((Bounds)(ref bounds)).min.y - position.y); float num4 = num2; bounds = key.bounds; num2 = Mathf.Max(num4, ((Bounds)(ref bounds)).max.y - position.y); } } if (flag && !float.IsInfinity(num) && !float.IsInfinity(num2)) { float num5 = 0f - num - floorOffset; floorOffset = 0f - num; foreach (KeyValuePair<Transform, Transform> transform2 in transforms) { if ((Object)(object)transform2.Value != (Object)null) { Transform value2 = transform2.Value; value2.localPosition += Vector3.up * num5; } } Height = Mathf.Clamp(num2 + floorOffset, 0.5f, 2.5f); } hasPose = transforms.Count > 0; root.localScale = new Vector3(-1f, 1f, 1f) * (portable ? 0.3f : 1f); } } [DefaultExecutionOrder(10000)] public sealed class MannequinController : MonoBehaviour, IPunObservable { private static readonly FieldInfo OwnerId = AccessTools.Field(typeof(ItemEquippable), "ownerPlayerId"); private static readonly FieldInfo LastGrabber = AccessTools.Field(typeof(PhysGrabObject), "lastPlayerGrabbing"); private static readonly FieldInfo IsGrabbed = AccessTools.Field(typeof(PhysGrabObject), "grabbed"); private ItemEquippable item; private PhysGrabObject physics; private Rigidbody body; private CapsuleCollider shape; private Transform model; private LiveReplica replica; private PlayerAvatar owner; private int ownerViewId; private Vector3 previousOwnerPosition; private RigidbodyConstraints originalConstraints; private bool moving; private readonly GroundedMotion motion = new GroundedMotion(); private bool active; private float lastFloorContact = float.NegativeInfinity; private Vector3 floorPoint; private static readonly FieldInfo Grounded = AccessTools.Field(typeof(PlayerAvatar), "isGrounded"); private static readonly FieldInfo OwnerVelocity = AccessTools.Field(typeof(PlayerAvatar), "rbVelocityRaw"); private float nextOwnerSearch; private int mode; private float mirrorYaw; private bool wasDeployed; private float nextModeChange; private static readonly FieldInfo Grabbers = AccessTools.Field(typeof(PhysGrabObject), "playerGrabbing"); private static readonly FieldInfo HeldObject = AccessTools.Field(typeof(PhysGrabber), "grabbedPhysGrabObject"); private static readonly FieldInfo InputDisabled = AccessTools.Field(typeof(PlayerController), "InputDisableTimer"); private static readonly string[] ModeNames = new string[3] { "1 — Обычный", "2 — Ходить на месте", "3 — Замереть" }; private bool HeldLocally { get { if (!item.IsEquipped() && (Object)(object)PhysGrabber.instance != (Object)null && PhysGrabber.instance.grabbed) { object? value = HeldObject.GetValue(PhysGrabber.instance); return (Object)((value is PhysGrabObject) ? value : null) == (Object)(object)physics; } return false; } } private bool Authority { get { if (SemiFunc.IsMultiplayer()) { return PhotonNetwork.IsMasterClient; } return true; } } private bool Grabbed { get { if ((Object)(object)physics != (Object)null) { return (bool)IsGrabbed.GetValue(physics); } return false; } } private void Awake() { //IL_0046: Unknown result type (might be due to invalid IL or missing references) //IL_004b: Unknown result type (might be due to invalid IL or missing references) item = ((Component)this).GetComponent<ItemEquippable>(); physics = ((Component)this).GetComponent<PhysGrabObject>(); body = ((Component)this).GetComponent<Rigidbody>(); shape = ((Component)((Component)this).transform.Find("Echo Body Collider")).GetComponent<CapsuleCollider>(); originalConstraints = body.constraints; } private void Start() { MannequinFactory.ApplyRuntimeIcon(((Component)this).GetComponent<ItemAttributes>()); } private PlayerAvatar EquippedOwner() { if (!SemiFunc.IsMultiplayer()) { return PlayerAvatar.instance; } PhotonView val = PhotonView.Find((int)OwnerId.GetValue(item)); if ((Object)(object)val == (Object)null) { return null; } PlayerAvatar component = ((Component)val).GetComponent<PlayerAvatar>(); PhysGrabber component2 = ((Component)val).GetComponent<PhysGrabber>(); if (!((Object)(object)component != (Object)null)) { if (!((Object)(object)component2 != (Object)null)) { return null; } return component2.playerAvatar; } return component; } private void Bind(PlayerAvatar avatar) { //IL_004d: Unknown result type (might be due to invalid IL or missing references) //IL_0052: Unknown result type (might be due to invalid IL or missing references) //IL_007b: Unknown result type (might be due to invalid IL or missing references) if (!((Object)(object)avatar == (Object)null) && !((Object)(object)owner == (Object)(object)avatar)) { owner = avatar; ownerViewId = (((Object)(object)avatar.photonView != (Object)null) ? avatar.photonView.ViewID : 0); previousOwnerPosition = ((Component)owner).transform.position; if ((Object)(object)model != (Object)null) { Object.Destroy((Object)(object)((Component)model).gameObject); } model = new GameObject("Echo Live Replica").transform; model.SetParent(((Component)this).transform, false); replica = new LiveReplica(model, owner); if (Authority) { motion.Reset(); active = false; wasDeployed = false; } } } private void Update() { //IL_0029: Unknown result type (might be due to invalid IL or missing references) //IL_002f: Invalid comparison between Unknown and I4 if (HeldLocally && Keyboard.current != null && ((ButtonControl)Keyboard.current.eKey).wasPressedThisFrame && (int)Cursor.lockState == 1 && Time.timeScale > 0f && (Object)(object)PlayerController.instance != (Object)null && (float)InputDisabled.GetValue(PlayerController.instance) <= 0f && Time.unscaledTime >= nextModeChange) { nextModeChange = Time.unscaledTime + 0.25f; if (SemiFunc.IsMultiplayer()) { ((Component)this).GetComponent<PhotonView>().RPC("EchoModeRequest", (RpcTarget)2, new object[1] { mode }); } else { SetMode(MirrorRules.NextMode(mode)); } } if (Authority) { if (item.IsEquipped()) { Bind(EquippedOwner()); } else if (Grabbed) { object? value = LastGrabber.GetValue(physics); Bind((PlayerAvatar)((value is PlayerAvatar) ? value : null)); } if ((Object)(object)owner == (Object)null && Time.time >= nextOwnerSearch) { nextOwnerSearch = Time.time + 1f; Bind((from p in Object.FindObjectsOfType<PlayerAvatar>() where (Object)(object)p.playerAvatarVisuals != (Object)null select p).OrderBy(delegate(PlayerAvatar p) { //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_0011: Unknown result type (might be due to invalid IL or missing references) //IL_0016: Unknown result type (might be due to invalid IL or missing references) //IL_001b: Unknown result type (might be due to invalid IL or missing references) Vector3 val2 = ((Component)p).transform.position - ((Component)this).transform.position; return ((Vector3)(ref val2)).sqrMagnitude; }).FirstOrDefault()); } } else if (((Object)(object)owner == (Object)null || owner.photonView.ViewID != ownerViewId) && ownerViewId != 0) { PhotonView val = PhotonView.Find(ownerViewId); if ((Object)(object)val != (Object)null) { Bind(((Component)val).GetComponent<PlayerAvatar>()); } } if ((Object)(object)owner == (Object)null) { if ((Object)(object)model != (Object)null) { ((Component)model).gameObject.SetActive(false); } } else if (item.IsEquipped() || Grabbed) { lastFloorContact = float.NegativeInfinity; if (Authority) { motion.Reset(); active = false; } } } private void OnCollisionEnter(Collision collision) { RecordFloor(collision); } private void OnCollisionStay(Collision collision) { RecordFloor(collision); } private bool FloorBelow() { //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_000b: Unknown result type (might be due to invalid IL or missing references) //IL_000e: Unknown result type (might be due to invalid IL or missing references) //IL_0013: Unknown result type (might be due to invalid IL or missing references) //IL_001a: Unknown result type (might be due to invalid IL or missing references) //IL_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_0040: Unknown result type (might be due to invalid IL or missing references) Bounds bounds = ((Collider)shape).bounds; RaycastHit[] array = Physics.RaycastAll(((Bounds)(ref bounds)).center, Vector3.down, ((Bounds)(ref bounds)).extents.y + 0.08f, -1, (QueryTriggerInteraction)1); for (int i = 0; i < array.Length; i++) { RaycastHit val = array[i]; if (((RaycastHit)(ref val)).normal.y >= 0.55f && (Object)(object)((RaycastHit)(ref val)).collider.attachedRigidbody != (Object)(object)body && (Object)(object)((Component)((RaycastHit)(ref val)).collider).GetComponentInParent<PlayerAvatar>() == (Object)null && (Object)(object)((Component)((RaycastHit)(ref val)).collider).GetComponentInParent<PlayerController>() == (Object)null && (Object)(object)((Component)((RaycastHit)(ref val)).collider).GetComponentInParent<PhysGrabObject>() == (Object)null) { return true; } } return false; } private void RecordFloor(Collision collision) { //IL_0064: Unknown result type (might be due to invalid IL or missing references) //IL_0069: Unknown result type (might be due to invalid IL or missing references) //IL_006c: Unknown result type (might be due to invalid IL or missing references) //IL_008b: Unknown result type (might be due to invalid IL or missing references) //IL_0090: Unknown result type (might be due to invalid IL or missing references) if (!Authority || (Object)(object)item == (Object)null || item.IsEquipped() || Grabbed) { return; } Collider collider = collision.collider; if ((Object)(object)((Component)collider).GetComponentInParent<PlayerAvatar>() != (Object)null || (Object)(object)((Component)collider).GetComponentInParent<PlayerController>() != (Object)null || (Object)(object)((Component)collider).GetComponentInParent<PhysGrabObject>() != (Object)null) { return; } for (int i = 0; i < collision.contactCount; i++) { ContactPoint contact = collision.GetContact(i); if (!(((ContactPoint)(ref contact)).normal.y < 0.55f)) { lastFloorContact = Time.fixedTime; floorPoint = ((ContactPoint)(ref contact)).point; break; } } } private void FixedUpdate() { //IL_0030: 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_0036: Unknown result type (might be due to invalid IL or missing references) //IL_0038: Unknown result type (might be due to invalid IL or missing references) //IL_003d: Unknown result type (might be due to invalid IL or missing references) //IL_0042: Unknown result type (might be due to invalid IL or missing references) //IL_0044: 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_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_00b2: Unknown result type (might be due to invalid IL or missing references) //IL_00fb: Unknown result type (might be due to invalid IL or missing references) //IL_01cd: Unknown result type (might be due to invalid IL or missing references) //IL_01d4: 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_014d: Unknown result type (might be due to invalid IL or missing references) //IL_016e: Unknown result type (might be due to invalid IL or missing references) //IL_0178: 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_01ae: Unknown result type (might be due to invalid IL or missing references) //IL_01f6: Unknown result type (might be due to invalid IL or missing references) //IL_01fc: Unknown result type (might be due to invalid IL or missing references) //IL_0201: Unknown result type (might be due to invalid IL or missing references) //IL_0203: Unknown result type (might be due to invalid IL or missing references) //IL_020a: 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_01f0: Unknown result type (might be due to invalid IL or missing references) //IL_0259: Unknown result type (might be due to invalid IL or missing references) //IL_0260: Unknown result type (might be due to invalid IL or missing references) //IL_0265: Unknown result type (might be due to invalid IL or missing references) //IL_026f: Unknown result type (might be due to invalid IL or missing references) //IL_0252: Unknown result type (might be due to invalid IL or missing references) //IL_0257: Unknown result type (might be due to invalid IL or missing references) //IL_02af: Unknown result type (might be due to invalid IL or missing references) //IL_02db: Unknown result type (might be due to invalid IL or missing references) //IL_02ef: Unknown result type (might be due to invalid IL or missing references) //IL_029d: Unknown result type (might be due to invalid IL or missing references) if (!Authority || (Object)(object)body == (Object)null || (Object)(object)owner == (Object)null) { return; } Vector3 position = ((Component)owner).transform.position; Vector3 val = position - previousOwnerPosition; previousOwnerPosition = position; bool flag = item.IsEquipped() || Grabbed; bool flag2 = Time.fixedTime - lastFloorContact <= Time.fixedDeltaTime * 2.1f; Vector3 val2 = (Vector3)OwnerVelocity.GetValue(owner); bool flag3 = motion.Step(flag, flag2, (bool)Grounded.GetValue(owner), val2.y, mode); active = motion.Active; if (flag || !active) { wasDeployed = false; if (moving) { body.constraints = originalConstraints; moving = false; } } else if (!body.isKinematic) { if (!wasDeployed) { mirrorYaw = ((Component)owner).transform.eulerAngles.y; body.position = new Vector3(body.position.x, floorPoint.y + 0.03f, body.position.z); body.velocity = Vector3.zero; body.MoveRotation(Quaternion.Euler(0f, mirrorYaw + 180f, 0f)); wasDeployed = true; } moving = true; body.constraints = (RigidbodyConstraints)(originalConstraints | 0x70); if (mode != 0) { Rigidbody obj = body; obj.constraints = (RigidbodyConstraints)(obj.constraints | 0xA); } Vector3 val3 = val / Time.fixedDeltaTime; MirrorRules.Movement(val3.x, val3.z, mirrorYaw, mode, out var resultX, out var resultZ); val3.x = resultX; val3.z = resultZ; val3.y = 0f; if (((Vector3)(ref val)).sqrMagnitude > 4f) { val3 = Vector3.zero; } val3 = Vector3.ClampMagnitude(val3, 12f); val3.y = body.velocity.y; if (flag3 && (flag2 || FloorBelow()) && ((Vector3)(ref val)).sqrMagnitude <= 4f) { val3.y = val2.y; } body.velocity = val3; if (mode != 2) { body.MoveRotation(Quaternion.Euler(0f, MirrorRules.Facing(mirrorYaw, ((Component)owner).transform.eulerAngles.y), 0f)); } } } private void LateUpdate() { //IL_00c5: Unknown result type (might be due to invalid IL or missing references) //IL_00cb: Unknown result type (might be due to invalid IL or missing references) //IL_00d5: Unknown result type (might be due to invalid IL or missing references) //IL_00eb: Unknown result type (might be due to invalid IL or missing references) if (!((Object)(object)owner == (Object)null) && replica != null && !((Object)(object)model == (Object)null)) { bool flag = item.IsEquipped(); ((Component)model).gameObject.SetActive(!flag); if (!flag) { bool flag2 = Grabbed || !active; replica.Tick(flag2, mode == 2); float num = Mathf.Max(0.5f, replica.Height * (flag2 ? 0.3f : 1f)); shape.height = num; shape.radius = (flag2 ? 0.15f : 0.25f); shape.center = Vector3.up * num * 0.5f; body.centerOfMass = shape.center; } } } public void OnPhotonSerializeView(PhotonStream stream, PhotonMessageInfo info) { //IL_007d: Unknown result type (might be due to invalid IL or missing references) if (stream.IsWriting) { stream.SendNext((object)ownerViewId); stream.SendNext((object)mode); stream.SendNext((object)mirrorYaw); stream.SendNext((object)active); return; } int num = (int)stream.ReceiveNext(); int num2 = (int)stream.ReceiveNext(); float num3 = (float)stream.ReceiveNext(); bool flag = (bool)stream.ReceiveNext(); if (info.Sender == PhotonNetwork.MasterClient) { ownerViewId = num; SetMode(num2); mirrorYaw = num3; active = flag; } } private void SetMode(int value) { if (value >= 0 && value <= 2) { mode = value; } } [PunRPC] private void EchoModeRequest(int expected, PhotonMessageInfo info) { //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_0008: Unknown result type (might be due to invalid IL or missing references) if (PhotonNetwork.IsMasterClient && Grabbed && !item.IsEquipped() && expected == mode && Grabbers.GetValue(physics) is List<PhysGrabber> source && source.Any((PhysGrabber g) => (Object)(object)g != (Object)null && (Object)(object)g.playerAvatar != (Object)null && g.playerAvatar.photonView.Owner == info.Sender)) { ((Component)this).GetComponent<PhotonView>().RPC("EchoModeCommit", (RpcTarget)0, new object[1] { MirrorRules.NextMode(mode) }); } } [PunRPC] private void EchoModeCommit(int value, PhotonMessageInfo info) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) if (info.Sender == PhotonNetwork.MasterClient) { SetMode(value); } } private void OnGUI() { //IL_002d: Unknown result type (might be due to invalid IL or missing references) if (HeldLocally) { GUI.Box(new Rect((float)((Screen.width - 360) / 2), (float)(Screen.height - 135), 360f, 62f), "Echo Mannequin • Зеркало\nE — сменить режим: " + ModeNames[mode]); } } private void OnDisable() { //IL_001d: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)body != (Object)null && moving) { body.constraints = originalConstraints; } moving = false; wasDeployed = false; motion.Reset(); active = false; lastFloorContact = float.NegativeInfinity; } } internal static class MannequinFactory { internal const string ItemName = "Item Echo Mannequin"; private const string PrefabName = "Item Echo Mannequin"; private static bool _loggedMissingSource; private static bool _registrationComplete; private static Sprite _inventoryIcon; private static Sprite CreateIcon() { //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_000c: Expected O, but got Unknown //IL_011e: 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_00da: Unknown result type (might be due to invalid IL or missing references) //IL_00df: Unknown result type (might be due to invalid IL or missing references) //IL_00d3: Unknown result type (might be due to invalid IL or missing references) //IL_00bd: Unknown result type (might be due to invalid IL or missing references) Texture2D val = new Texture2D(64, 64, (TextureFormat)4, false); Color[] array = (Color[])(object)new Color[4096]; for (int i = 0; i < 64; i++) { for (int j = 0; j < 64; j++) { bool flag = j >= 18 && j < 46 && i >= 34 && i < 56; bool flag2 = j >= 22 && j < 42 && i >= 16 && i < 34; bool flag3 = i >= 8 && i < 16 && ((j >= 20 && j < 29) || (j >= 35 && j < 44)); bool flag4 = i >= 42 && i < 49 && ((j >= 23 && j < 28) || (j >= 36 && j < 41)); array[i * 64 + j] = (Color)(flag4 ? Color.black : ((flag || flag2 || flag3) ? new Color(0.35f, 0.95f, 0.85f) : Color.clear)); } } val.SetPixels(array); val.Apply(); return Sprite.Create(val, new Rect(0f, 0f, 64f, 64f), new Vector2(0.5f, 0.5f), 64f); } private static void ConfigurePhysics(GameObject prefab) { //IL_0072: Unknown result type (might be due to invalid IL or missing references) //IL_0077: Unknown result type (might be due to invalid IL or missing references) //IL_0089: Unknown result type (might be due to invalid IL or missing references) //IL_0099: Unknown result type (might be due to invalid IL or missing references) //IL_00a4: 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) Collider[] componentsInChildren = prefab.GetComponentsInChildren<Collider>(true); foreach (Collider val in componentsInChildren) { if (!val.isTrigger) { val.enabled = false; } } Renderer[] componentsInChildren2 = prefab.GetComponentsInChildren<Renderer>(true); for (int i = 0; i < componentsInChildren2.Length; i++) { componentsInChildren2[i].enabled = false; } Light[] componentsInChildren3 = prefab.GetComponentsInChildren<Light>(true); for (int i = 0; i < componentsInChildren3.Length; i++) { ((Behaviour)componentsInChildren3[i]).enabled = false; } GameObject val2 = new GameObject("Echo Body Collider"); val2.transform.SetParent(prefab.transform, false); val2.layer = LayerMask.NameToLayer("PhysGrabObject"); val2.tag = "Phys Grab Object"; CapsuleCollider obj = val2.AddComponent<CapsuleCollider>(); obj.radius = 0.25f; obj.height = 1.25f; obj.center = new Vector3(0f, 0.625f, 0f); val2.AddComponent<PhysGrabObjectCollider>(); Rigidbody component = prefab.GetComponent<Rigidbody>(); if ((Object)(object)component != (Object)null) { component.mass = 5f; } } internal static void ApplyRuntimeIcon(ItemAttributes attributes) { if (!((Object)(object)attributes == (Object)null)) { if ((Object)(object)_inventoryIcon == (Object)null) { _inventoryIcon = CreateIcon(); } Sprite itemIcon = (attributes.icon = Object.Instantiate<Sprite>(_inventoryIcon)); AccessTools.Field(typeof(ItemAttributes), "hasIcon").SetValue(attributes, true); ItemEquippable component = ((Component)attributes).GetComponent<ItemEquippable>(); if ((Object)(object)component != (Object)null) { component.ItemIcon = itemIcon; } } } internal static bool TryRegister() { if (_registrationComplete) { return true; } List<Item> list = new List<Item>(); list.AddRange(Items.AllItems.Where((Item val4) => (Object)(object)val4 != (Object)null)); list.AddRange(from val4 in Resources.LoadAll<Item>("ScriptableObjects") where (Object)(object)val4 != (Object)null select val4); list.AddRange(from val4 in Resources.FindObjectsOfTypeAll<Item>() where (Object)(object)val4 != (Object)null select val4); if ((Object)(object)StatsManager.instance != (Object)null && StatsManager.instance.itemDictionary != null) { list.AddRange(StatsManager.instance.itemDictionary.Values.Where((Item val4) => (Object)(object)val4 != (Object)null)); } if ((Object)(object)ShopManager.instance != (Object)null) { list.AddRange(ShopManager.instance.potentialItems.Where((Item val4) => (Object)(object)val4 != (Object)null)); list.AddRange(ShopManager.instance.potentialItemConsumables.Where((Item val4) => (Object)(object)val4 != (Object)null)); list.AddRange(ShopManager.instance.potentialItemUpgrades.Where((Item val4) => (Object)(object)val4 != (Object)null)); list.AddRange(ShopManager.instance.potentialItemHealthPacks.Where((Item val4) => (Object)(object)val4 != (Object)null)); } list = list.Distinct().ToList(); if (Items.AllItems.Any((Item item2) => IsNamed(item2, "Item Echo Mannequin"))) { return true; } Item val = Resources.Load<Item>("Items/Item Drone Indestructible") ?? ((IEnumerable<Item>)list).FirstOrDefault((Func<Item, bool>)((Item item2) => IsNamed(item2, "Item Drone Indestructible"))); if ((Object)(object)val == (Object)null || val.prefab == null || (Object)(object)((PrefabRef<GameObject>)(object)val.prefab).Prefab == (Object)null) { if (!_loggedMissingSource) { _loggedMissingSource = true; string text = string.Join(", ", (from val4 in list where ContainsDrone(((Object)val4).name) || ContainsDrone(val4.itemName) select "[" + ((Object)val4).name + " | " + val4.itemName + "]").Distinct().Take(20).ToArray()); MannequinPlugin.Log.LogWarning((object)("Waiting for the built-in Item Drone Indestructible prefab. Loaded item candidates: " + list.Count + ". Drone candidates: " + text)); } return false; } GameObject obj = Object.Instantiate<GameObject>(((PrefabRef<GameObject>)(object)val.prefab).Prefab); ((Object)obj).name = "Item Echo Mannequin"; obj.SetActive(false); Object.DontDestroyOnLoad((Object)(object)obj); RemoveDroneBehaviour(obj); ConfigurePhysics(obj); Item val2 = ScriptableObject.CreateInstance<Item>(); CopyItem(val, val2); ((Object)val2).name = "Item Echo Mannequin"; val2.itemName = "Item Echo Mannequin"; val2.description = "A live replica of its owner. Grab, store and drop; it mirrors walking, crouching and tumbling."; val2.maxAmountInShop = 1; Value val3 = ScriptableObject.CreateInstance<Value>(); ((Object)val3).name = "Value - Echo Mannequin"; val3.valueMin = 30000f; val3.valueMax = 40000f; val2.value = val3; ItemAttributes component = obj.GetComponent<ItemAttributes>(); if ((Object)(object)component == (Object)null) { throw new InvalidOperationException("The source item has no ItemAttributes component."); } component.item = val2; Sprite itemIcon = (component.icon = CreateIcon()); ItemEquippable component2 = obj.GetComponent<ItemEquippable>(); if ((Object)(object)component2 == (Object)null) { throw new InvalidOperationException("The source item has no ItemEquippable component."); } component2.ItemIcon = itemIcon; MannequinController item = obj.AddComponent<MannequinController>(); obj.GetComponent<PhotonView>().ObservedComponents.Add((Component)(object)item); if (Items.RegisterItem(component) == null) { throw new InvalidOperationException("REPOLib rejected the mannequin prefab."); } _registrationComplete = true; MannequinPlugin.Log.LogInfo((object)"Registered Item Echo Mannequin with shop price 30000-40000 and maximum one per visit."); return true; } private static bool IsNamed(Item item, string expected) { if ((Object)(object)item != (Object)null) { if (!string.Equals(((Object)item).name, expected, StringComparison.Ordinal)) { return string.Equals(item.itemName, expected, StringComparison.Ordinal); } return true; } return false; } private static bool ContainsDrone(string value) { if (!string.IsNullOrEmpty(value)) { return value.IndexOf("Drone", StringComparison.OrdinalIgnoreCase) >= 0; } return false; } private static void RemoveDroneBehaviour(GameObject prefab) { List<Component> removed = new List<Component>(); MonoBehaviour[] componentsInChildren = prefab.GetComponentsInChildren<MonoBehaviour>(true); foreach (MonoBehaviour val in componentsInChildren) { if (!((Object)(object)val == (Object)null)) { Type type = ((object)val).GetType(); if (val is ItemBattery || val is ItemToggle || type.Name.StartsWith("ItemDrone", StringComparison.Ordinal)) { removed.Add((Component)(object)val); Object.DestroyImmediate((Object)(object)val); } } } PhotonView[] componentsInChildren2 = prefab.GetComponentsInChildren<PhotonView>(true); foreach (PhotonView val2 in componentsInChildren2) { if (!((Object)(object)val2 == (Object)null) && val2.ObservedComponents != null) { val2.ObservedComponents.RemoveAll((Component component) => (Object)(object)component == (Object)null || removed.Contains(component)); } } } private static void CopyItem(Item source, Item destination) { //IL_0010: Unknown result type (might be due to invalid IL or missing references) //IL_0015: Unknown result type (might be due to invalid IL or missing references) //IL_001c: Unknown result type (might be due to invalid IL or missing references) //IL_0021: Unknown result type (might be due to invalid IL or missing references) //IL_0028: Unknown result type (might be due to invalid IL or missing references) //IL_002d: Unknown result type (might be due to invalid IL or missing references) //IL_0034: Unknown result type (might be due to invalid IL or missing references) //IL_0039: Unknown result type (might be due to invalid IL or missing references) //IL_0089: Unknown result type (might be due to invalid IL or missing references) //IL_008e: Unknown result type (might be due to invalid IL or missing references) destination.disabled = false; destination.itemNameLocalized = null; destination.itemType = source.itemType; destination.emojiIcon = source.emojiIcon; destination.itemVolume = source.itemVolume; destination.itemSecretShopType = source.itemSecretShopType; destination.colorPreset = source.colorPreset; destination.maxAmount = Math.Max(1, source.maxAmount); destination.maxAmountInShop = 1; destination.minPlayerCount = source.minPlayerCount; destination.maxPurchase = source.maxPurchase; destination.maxPurchaseAmount = source.maxPurchaseAmount; destination.spawnRotationOffset = source.spawnRotationOffset; destination.physicalItem = true; } } [BepInPlugin("uz.cherdak.repo.echomannequin", "Echo Mannequin", "1.1.1")] [BepInDependency(/*Could not decode attribute arguments.*/)] public sealed class MannequinPlugin : BaseUnityPlugin { internal static ManualLogSource Log; private float nextAttempt; private bool ready; private void Awake() { //IL_0010: Unknown result type (might be due to invalid IL or missing references) Log = ((BaseUnityPlugin)this).Logger; new Harmony("uz.cherdak.repo.echomannequin").PatchAll(); ((BaseUnityPlugin)this).Logger.LogInfo((object)"Echo Mannequin 1.1.1 loaded"); } private void Update() { if (ready || Time.unscaledTime < nextAttempt) { return; } nextAttempt = Time.unscaledTime + 3f; try { ready = MannequinFactory.TryRegister(); } catch (Exception ex) { ((BaseUnityPlugin)this).Logger.LogError((object)ex); } } } [HarmonyPatch(typeof(StatsManager), "LoadItemsFromFolder")] internal static class RegisterPatch { [HarmonyPostfix] [HarmonyPriority(0)] private static void Postfix() { try { MannequinFactory.TryRegister(); } catch (Exception ex) { MannequinPlugin.Log.LogError((object)ex); } } } internal static class MirrorRules { internal static int NextMode(int mode) { return (mode + 1) % 3; } internal static float Facing(float planeYaw, float ownerYaw) { return 2f * planeYaw + 180f - ownerYaw; } internal static void Movement(float x, float z, float planeYaw, int mode, out float resultX, out float resultZ) { if (mode != 0) { resultX = (resultZ = 0f); return; } double num = (double)planeYaw * Math.PI / 180.0; float num2 = (float)Math.Sin(num); float num3 = (float)Math.Cos(num); float num4 = x * num2 + z * num3; resultX = x - 2f * num4 * num2; resultZ = z - 2f * num4 * num3; } } }