using 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 transforms = new Dictionary(); private readonly Dictionary renderers = new Dictionary(); 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 hashSet = new HashSet(((Component)owner.playerAvatarVisuals).GetComponentsInChildren(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(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(true); foreach (Renderer val3 in componentsInChildren) { if (!((Object)(object)((Component)val3).GetComponentInParent() != (Object)null) && !((Object)(object)((Component)val3).GetComponentInParent() != (Object)null) && !((Object)(object)((Component)val3).GetComponentInParent() != (Object)null) && !((Object)(object)((Component)val3).GetComponentInParent() != (Object)null) && !((Object)(object)((Component)val3).GetComponentInParent() != (Object)null)) { PlayerAvatar componentInParent = ((Component)val3).GetComponentInParent(); 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(); 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() != (Object)null) { GameObject gameObject = ((Component)Map(((Component)item3).transform)).gameObject; (gameObject.GetComponent() ?? gameObject.AddComponent()).sharedMesh = ((Component)val5).GetComponent().sharedMesh; renderers.Add(item3, (Renderer)(object)gameObject.AddComponent()); } } } KeyValuePair[] array2 = renderers.ToArray(); for (int i = 0; i < array2.Length; i++) { KeyValuePair 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[] array3 = transforms.ToArray(); for (int i = 0; i < array3.Length; i++) { KeyValuePair 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 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 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().sharedMesh = ((Component)key).GetComponent().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 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(); physics = ((Component)this).GetComponent(); body = ((Component)this).GetComponent(); shape = ((Component)((Component)this).transform.Find("Echo Body Collider")).GetComponent(); originalConstraints = body.constraints; } private void Start() { MannequinFactory.ApplyRuntimeIcon(((Component)this).GetComponent()); } 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(); PhysGrabber component2 = ((Component)val).GetComponent(); 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().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() 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()); } } 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() == (Object)null && (Object)(object)((Component)((RaycastHit)(ref val)).collider).GetComponentInParent() == (Object)null && (Object)(object)((Component)((RaycastHit)(ref val)).collider).GetComponentInParent() == (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() != (Object)null || (Object)(object)((Component)collider).GetComponentInParent() != (Object)null || (Object)(object)((Component)collider).GetComponentInParent() != (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 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().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(true); foreach (Collider val in componentsInChildren) { if (!val.isTrigger) { val.enabled = false; } } Renderer[] componentsInChildren2 = prefab.GetComponentsInChildren(true); for (int i = 0; i < componentsInChildren2.Length; i++) { componentsInChildren2[i].enabled = false; } Light[] componentsInChildren3 = prefab.GetComponentsInChildren(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(); obj.radius = 0.25f; obj.height = 1.25f; obj.center = new Vector3(0f, 0.625f, 0f); val2.AddComponent(); Rigidbody component = prefab.GetComponent(); 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(_inventoryIcon)); AccessTools.Field(typeof(ItemAttributes), "hasIcon").SetValue(attributes, true); ItemEquippable component = ((Component)attributes).GetComponent(); if ((Object)(object)component != (Object)null) { component.ItemIcon = itemIcon; } } } internal static bool TryRegister() { if (_registrationComplete) { return true; } List list = new List(); list.AddRange(Items.AllItems.Where((Item val4) => (Object)(object)val4 != (Object)null)); list.AddRange(from val4 in Resources.LoadAll("ScriptableObjects") where (Object)(object)val4 != (Object)null select val4); list.AddRange(from val4 in Resources.FindObjectsOfTypeAll() 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("Items/Item Drone Indestructible") ?? ((IEnumerable)list).FirstOrDefault((Func)((Item item2) => IsNamed(item2, "Item Drone Indestructible"))); if ((Object)(object)val == (Object)null || val.prefab == null || (Object)(object)((PrefabRef)(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(((PrefabRef)(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(); 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(); ((Object)val3).name = "Value - Echo Mannequin"; val3.valueMin = 30000f; val3.valueMax = 40000f; val2.value = val3; ItemAttributes component = obj.GetComponent(); 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(); if ((Object)(object)component2 == (Object)null) { throw new InvalidOperationException("The source item has no ItemEquippable component."); } component2.ItemIcon = itemIcon; MannequinController item = obj.AddComponent(); obj.GetComponent().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 removed = new List(); MonoBehaviour[] componentsInChildren = prefab.GetComponentsInChildren(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(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; } } }