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 Item Stand Rotation v0.5.1
BepInEx/plugins/StandTurn/StandTurn.dll
Decompiled 2 weeks agousing System; using System.Collections.Generic; using System.Diagnostics; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using BepInEx; using BepInEx.Configuration; using HarmonyLib; using Microsoft.CodeAnalysis; using UnityEngine; using UnityEngine.InputSystem; using UnityEngine.InputSystem.Controls; using UnityEngine.InputSystem.Utilities; using UnityEngine.Rendering; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: TargetFramework(".NETFramework,Version=v4.7.2", FrameworkDisplayName = "")] [assembly: AssemblyCompany("StandTurn")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyFileVersion("0.5.1.0")] [assembly: AssemblyInformationalVersion("0.5.1")] [assembly: AssemblyProduct("StandTurn")] [assembly: AssemblyTitle("StandTurn")] [assembly: AssemblyVersion("0.5.1.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 StandTurn { internal static class AngleMath { internal static float Normalize(float value) { if (float.IsNaN(value) || float.IsInfinity(value)) { return 0f; } return (value % 360f + 360f) % 360f; } internal static float Scroll(float angle, float wheel, float step) { if (float.IsNaN(wheel) || float.IsInfinity(wheel) || wheel == 0f) { return Normalize(angle); } return Normalize(angle + (float)Math.Sign(wheel) * step); } } internal struct FacingRotation { internal float X; internal float Y; internal float Z; internal float W; internal static FacingRotation Identity => new FacingRotation(0f, 0f, 0f, 1f); internal FacingRotation(float x, float y, float z, float w) { X = x; Y = y; Z = z; W = w; } internal FacingRotation Normalized() { double num = Math.Sqrt((double)X * (double)X + (double)Y * (double)Y + (double)Z * (double)Z + (double)W * (double)W); if (double.IsNaN(num) || double.IsInfinity(num) || num < 1E-06) { return Identity; } return new FacingRotation((float)((double)X / num), (float)((double)Y / num), (float)((double)Z / num), (float)((double)W / num)); } internal FacingRotation Turn(int axis, float degrees) { return Rotate(axis, degrees, fixedAxis: false); } internal FacingRotation TurnFixed(int axis, float degrees) { return Rotate(axis, degrees, fixedAxis: true); } private FacingRotation Rotate(int axis, float degrees, bool fixedAxis) { double num = (double)AngleMath.Normalize(degrees) * Math.PI / 360.0; float num2 = (float)Math.Sin(num); float w = (float)Math.Cos(num); FacingRotation facingRotation = new FacingRotation((axis == 0) ? num2 : 0f, (axis == 1) ? num2 : 0f, (axis == 2) ? num2 : 0f, w); FacingRotation facingRotation2 = Normalized(); if (fixedAxis) { FacingRotation facingRotation3 = facingRotation2; facingRotation2 = facingRotation; facingRotation = facingRotation3; } return new FacingRotation(facingRotation2.W * facingRotation.X + facingRotation2.X * facingRotation.W + facingRotation2.Y * facingRotation.Z - facingRotation2.Z * facingRotation.Y, facingRotation2.W * facingRotation.Y - facingRotation2.X * facingRotation.Z + facingRotation2.Y * facingRotation.W + facingRotation2.Z * facingRotation.X, facingRotation2.W * facingRotation.Z + facingRotation2.X * facingRotation.Y - facingRotation2.Y * facingRotation.X + facingRotation2.Z * facingRotation.W, facingRotation2.W * facingRotation.W - facingRotation2.X * facingRotation.X - facingRotation2.Y * facingRotation.Y - facingRotation2.Z * facingRotation.Z).Normalized(); } internal bool SameOrientation(FacingRotation other) { FacingRotation facingRotation = Normalized(); FacingRotation facingRotation2 = other.Normalized(); return Math.Abs((double)facingRotation.X * (double)facingRotation2.X + (double)facingRotation.Y * (double)facingRotation2.Y + (double)facingRotation.Z * (double)facingRotation2.Z + (double)facingRotation.W * (double)facingRotation2.W) > 0.9999999; } } internal static class GameAccess { internal static readonly FieldRef<ItemStand, ZNetView> View = AccessTools.FieldRefAccess<ItemStand, ZNetView>("m_nview"); internal static readonly FieldRef<ItemStand, GameObject> Visual = AccessTools.FieldRefAccess<ItemStand, GameObject>("m_visualItem"); internal static readonly FieldRef<ItemStand, ItemData> QueuedItem = AccessTools.FieldRefAccess<ItemStand, ItemData>("m_queuedItem"); internal static readonly Func<ItemStand, ItemData, bool> CanAttach = AccessTools.MethodDelegate<Func<ItemStand, ItemData, bool>>(AccessTools.Method(typeof(ItemStand), "CanAttach", (Type[])null, (Type[])null), (object)null, true); internal static readonly Func<ItemStand, int> Orientation = AccessTools.MethodDelegate<Func<ItemStand, int>>(AccessTools.Method(typeof(ItemStand), "GetOrientation", (Type[])null, (Type[])null), (object)null, true); internal static readonly Action<ItemStand> UpdateAttach = AccessTools.MethodDelegate<Action<ItemStand>>(AccessTools.Method(typeof(ItemStand), "UpdateAttach", (Type[])null, (Type[])null), (object)null, true); internal static readonly Func<Player, bool> TakeInput = AccessTools.MethodDelegate<Func<Player, bool>>(AccessTools.Method(typeof(Player), "TakeInput", (Type[])null, (Type[])null), (object)null, true); internal static readonly FieldRef<Player, float> MaxDistance = AccessTools.FieldRefAccess<Player, float>("m_maxInteractDistance"); private static readonly Type EquipmentVisualType = typeof(ItemStand).Assembly.GetType("IEquipmentVisual", throwOnError: true); internal static void SetupEquipment(GameObject model, int variant) { Component componentInChildren = model.GetComponentInChildren(EquipmentVisualType, true); if (Object.op_Implicit((Object)(object)componentInChildren)) { EquipmentVisualType.GetMethod("Setup").Invoke(componentInChildren, new object[1] { variant }); } } internal static bool Valid(ItemStand stand) { if (Object.op_Implicit((Object)(object)stand) && Object.op_Implicit((Object)(object)View.Invoke(stand))) { return View.Invoke(stand).IsValid(); } return false; } internal static bool Supported(ItemStand stand) { if (!Valid(stand) || Object.op_Implicit((Object)(object)stand.m_guardianPower) || !stand.m_canBeRemoved) { return false; } string text = ((Object)((Component)stand).gameObject).name.Replace("(Clone)", "").Trim(); if (!(text == "itemstand")) { return text == "itemstandh"; } return true; } internal static float ReadAngle(ItemStand stand) { return AngleMath.Normalize(View.Invoke(stand).GetZDO().GetFloat("StandTurn.Angle.v1", 0f)); } internal static FacingRotation ReadFacing(ItemStand stand) { return ReadQuaternion(stand, "StandTurn.Facing.v1"); } internal static FacingRotation ReadRotation(ItemStand stand) { return ReadQuaternion(stand, "StandTurn.Rotation.v1"); } internal static Vector3 ReadOffset(ItemStand stand) { //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) //IL_0021: 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_0037: 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) Vector3 vec = View.Invoke(stand).GetZDO().GetVec3("StandTurn.Offset.v1", Vector3.zero); return new Vector3(PositionMath.Clean(vec.x), PositionMath.Clean(vec.y), PositionMath.Clean(vec.z)); } private static FacingRotation ReadQuaternion(ItemStand stand, string key) { //IL_0012: 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_0023: 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_002f: Unknown result type (might be due to invalid IL or missing references) Quaternion quaternion = View.Invoke(stand).GetZDO().GetQuaternion(key, Quaternion.identity); return new FacingRotation(quaternion.x, quaternion.y, quaternion.z, quaternion.w).Normalized(); } internal static Quaternion ToQuaternion(FacingRotation facing) { //IL_0020: Unknown result type (might be due to invalid IL or missing references) FacingRotation facingRotation = facing.Normalized(); return new Quaternion(facingRotation.X, facingRotation.Y, facingRotation.Z, facingRotation.W); } internal static Vector3 Axis(ItemStand stand, Transform parent) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Invalid comparison between Unknown and I4 //IL_0024: 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_0029: Unknown result type (might be due to invalid IL or missing references) //IL_0047: Unknown result type (might be due to invalid IL or missing references) //IL_004c: Unknown result type (might be due to invalid IL or missing references) //IL_0051: Unknown result type (might be due to invalid IL or missing references) //IL_0056: 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_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) Vector3 val = (((int)stand.m_orientationType == 2) ? Plugin.Instance.HorizontalAxis.Value : Plugin.Instance.VerticalAxis.Value); if (((Vector3)(ref val)).sqrMagnitude < 0.001f) { val = Vector3.up; } Vector3 val2 = parent.InverseTransformDirection(((Component)stand).transform.TransformDirection(((Vector3)(ref val)).normalized)); return ((Vector3)(ref val2)).normalized; } internal static Quaternion RotationFrame(ItemStand stand, Transform parent) { //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_0009: Unknown result type (might be due to invalid IL or missing references) //IL_000f: Invalid comparison between Unknown and I4 //IL_0018: 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_001d: Unknown result type (might be due to invalid IL or missing references) //IL_0025: Unknown result type (might be due to invalid IL or missing references) //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_0031: 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_0033: 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_004e: Unknown result type (might be due to invalid IL or missing references) //IL_0053: Unknown result type (might be due to invalid IL or missing references) //IL_0058: Unknown result type (might be due to invalid IL or missing references) //IL_0059: Unknown result type (might be due to invalid IL or missing references) //IL_005e: Unknown result type (might be due to invalid IL or missing references) //IL_0085: Unknown result type (might be due to invalid IL or missing references) //IL_0088: Unknown result type (might be due to invalid IL or missing references) //IL_008d: Unknown result type (might be due to invalid IL or missing references) //IL_0094: 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_0074: Unknown result type (might be due to invalid IL or missing references) //IL_0079: Unknown result type (might be due to invalid IL or missing references) //IL_007e: Unknown result type (might be due to invalid IL or missing references) //IL_007f: Unknown result type (might be due to invalid IL or missing references) //IL_0084: Unknown result type (might be due to invalid IL or missing references) Vector3 val = Axis(stand, parent); Vector3 val2 = (((int)stand.m_orientationType == 2) ? Vector3.forward : Vector3.up); Vector3 val3 = parent.InverseTransformDirection(((Component)stand).transform.TransformDirection(val2)); val3 = Vector3.ProjectOnPlane(val3, val); if (((Vector3)(ref val3)).sqrMagnitude < 0.001f) { val3 = Vector3.ProjectOnPlane(parent.InverseTransformDirection(((Component)stand).transform.right), val); } if (((Vector3)(ref val3)).sqrMagnitude < 0.001f) { val3 = Vector3.ProjectOnPlane(parent.InverseTransformDirection(((Component)stand).transform.forward), val); } return Quaternion.LookRotation(Vector3.Cross(val, ((Vector3)(ref val3)).normalized), ((Vector3)(ref val3)).normalized); } internal static Vector3 DisplayAngles(ItemStand stand, Transform parent, Quaternion mounting, float angle, FacingRotation facing, FacingRotation standRotation) { //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_000c: Unknown result type (might be due to invalid IL or missing references) //IL_000d: Unknown result type (might be due to invalid IL or missing references) //IL_0012: Unknown result type (might be due to invalid IL or missing references) //IL_0015: 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) //IL_0025: Unknown result type (might be due to invalid IL or missing references) //IL_002a: Unknown result type (might be due to invalid IL or missing references) //IL_002b: 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_0037: Unknown result type (might be due to invalid IL or missing references) //IL_003c: Unknown result type (might be due to invalid IL or missing references) //IL_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_0047: 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) Quaternion val = Quaternion.Inverse(RotationFrame(stand, parent)) * mounting; Quaternion val2 = ToQuaternion(standRotation) * Quaternion.AngleAxis(angle, Vector3.right) * val * ToQuaternion(facing) * Quaternion.Inverse(val); return ((Quaternion)(ref val2)).eulerAngles; } internal static void Apply(Transform target, Vector3 position, Quaternion rotation, ItemStand stand, float angle, FacingRotation facing, FacingRotation standRotation, Vector3 offset) { //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_000c: Unknown result type (might be due to invalid IL or missing references) //IL_0014: 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_001a: Unknown result type (might be due to invalid IL or missing references) //IL_0022: Unknown result type (might be due to invalid IL or missing references) //IL_0027: 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_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_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_003b: Unknown result type (might be due to invalid IL or missing references) //IL_0040: Unknown result type (might be due to invalid IL or missing references) //IL_0042: Unknown result type (might be due to invalid IL or missing references) //IL_0043: Unknown result type (might be due to invalid IL or missing references) //IL_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_004a: 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_0061: Unknown result type (might be due to invalid IL or missing references) //IL_0062: 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_0079: Unknown result type (might be due to invalid IL or missing references) //IL_007a: Unknown result type (might be due to invalid IL or missing references) //IL_007b: Unknown result type (might be due to invalid IL or missing references) //IL_0080: Unknown result type (might be due to invalid IL or missing references) //IL_0081: Unknown result type (might be due to invalid IL or missing references) //IL_0088: Unknown result type (might be due to invalid IL or missing references) //IL_008d: Unknown result type (might be due to invalid IL or missing references) Vector3 val = Axis(stand, target.parent); Quaternion val2 = Quaternion.AngleAxis(AngleMath.Normalize(angle), val); Quaternion val3 = RotationFrame(stand, target.parent); Quaternion val4 = val3 * ToQuaternion(standRotation) * Quaternion.Inverse(val3); target.localPosition = val4 * (val2 * position); target.position += target.parent.TransformDirection(val3 * offset); target.localRotation = val4 * val2 * rotation * ToQuaternion(facing); } } internal static class InputCapture { internal struct Snapshot { internal bool Edit; internal bool Cancel; internal bool Confirm; internal bool Reset; internal bool Turn; internal bool CycleAxis; internal bool ToggleMode; internal bool Fine; internal bool OtherHeld; internal float Wheel; } [ThreadStatic] private static int ownReadDepth; private static readonly HashSet<InputControl> locomotion = new HashSet<InputControl>(); internal static bool Blocking { get { if (ownReadDepth == 0) { return Plugin.BlockActions; } return false; } } internal static void RefreshBindings() { //IL_0071: Unknown result type (might be due to invalid IL or missing references) //IL_0076: Unknown result type (might be due to invalid IL or missing references) //IL_007a: Unknown result type (might be due to invalid IL or missing references) //IL_007f: Unknown result type (might be due to invalid IL or missing references) locomotion.Clear(); if (ZInput.instance == null) { return; } string[] array = new string[6] { "Forward", "Backward", "Left", "Right", "Jump", "JoyJump" }; foreach (string text in array) { ButtonDef buttonDef = ZInput.instance.GetButtonDef(text); if (((buttonDef != null) ? buttonDef.ButtonAction : null) == null) { continue; } Enumerator<InputControl> enumerator = buttonDef.ButtonAction.controls.GetEnumerator(); try { while (enumerator.MoveNext()) { InputControl current = enumerator.Current; locomotion.Add(current); } } finally { ((IDisposable)enumerator/*cast due to .constrained prefix*/).Dispose(); } } } internal static bool AllowsControl(InputControl control) { if (locomotion.Contains(control)) { return true; } for (InputControl parent = control.parent; parent != null; parent = parent.parent) { if (parent is StickControl) { return true; } } return false; } internal static Snapshot Read(Key edit, Key turn, Key axis, Key mode) { //IL_0026: 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_00b3: Unknown result type (might be due to invalid IL or missing references) //IL_00cc: Unknown result type (might be due to invalid IL or missing references) //IL_0112: Unknown result type (might be due to invalid IL or missing references) //IL_012a: Unknown result type (might be due to invalid IL or missing references) //IL_012f: Unknown result type (might be due to invalid IL or missing references) //IL_0133: 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_0162: Unknown result type (might be due to invalid IL or missing references) //IL_0167: Unknown result type (might be due to invalid IL or missing references) //IL_016b: 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) ownReadDepth++; try { Keyboard current = Keyboard.current; Mouse current2 = Mouse.current; Snapshot result = new Snapshot { Edit = (current != null && ((ButtonControl)current[edit]).wasPressedThisFrame), Cancel = ((current != null && ((ButtonControl)current.escapeKey).wasPressedThisFrame) || (current2 != null && current2.rightButton.wasPressedThisFrame)), Confirm = (current2 != null && current2.leftButton.wasPressedThisFrame), Reset = (current != null && ((ButtonControl)current.rKey).wasPressedThisFrame), Turn = (current != null && ((ButtonControl)current[turn]).wasPressedThisFrame), CycleAxis = (current != null && ((ButtonControl)current[axis]).wasPressedThisFrame), ToggleMode = (current != null && ((ButtonControl)current[mode]).wasPressedThisFrame), Fine = (current != null && (((ButtonControl)current.leftShiftKey).isPressed || ((ButtonControl)current.rightShiftKey).isPressed)), Wheel = ((current2 == null) ? 0f : ((InputControl<Vector2>)(object)current2.scroll).ReadValue().y) }; Enumerator<InputDevice> enumerator = InputSystem.devices.GetEnumerator(); try { while (enumerator.MoveNext()) { InputDevice current3 = enumerator.Current; if (!(current3 is Keyboard) && !(current3 is Mouse) && !(current3 is Gamepad)) { continue; } Enumerator<InputControl> enumerator2 = current3.allControls.GetEnumerator(); try { while (enumerator2.MoveNext()) { InputControl current4 = enumerator2.Current; ButtonControl val = (ButtonControl)(object)((current4 is ButtonControl) ? current4 : null); if (val != null && !AllowsControl((InputControl)(object)val) && val.isPressed) { result.OtherHeld = true; } } } finally { ((IDisposable)enumerator2/*cast due to .constrained prefix*/).Dispose(); } } } finally { ((IDisposable)enumerator/*cast due to .constrained prefix*/).Dispose(); } return result; } finally { ownReadDepth--; } } } [HarmonyPatch] internal static class RawButtonPatch { private static IEnumerable<MethodBase> TargetMethods() { string[] array = new string[3] { "isPressed", "wasPressedThisFrame", "wasReleasedThisFrame" }; foreach (string text in array) { yield return AccessTools.PropertyGetter(typeof(ButtonControl), text); } } [HarmonyPriority(0)] private static void Postfix(ButtonControl __instance, ref bool __result) { if (InputCapture.Blocking && !InputCapture.AllowsControl((InputControl)(object)__instance)) { __result = false; } } } [HarmonyPatch] internal static class ShortcutInputPatch { internal static IEnumerable<MethodBase> Targets() { string[] array = new string[3] { "IsDown", "IsPressed", "IsUp" }; foreach (string text in array) { yield return AccessTools.Method(typeof(KeyboardShortcut), text, (Type[])null, (Type[])null); } List<Type> list = new List<Type> { typeof(ZInput), typeof(Input) }; Type[] types = typeof(BaseUnityPlugin).Assembly.GetTypes(); foreach (Type type in types) { if (!type.IsInterface && !type.IsAbstract && typeof(IInputSystem).IsAssignableFrom(type)) { list.Add(type); } } foreach (Type type2 in list) { MethodInfo[] methods = type2.GetMethods(BindingFlags.DeclaredOnly | BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public); foreach (MethodInfo methodInfo in methods) { if (methodInfo.ReturnType == typeof(bool) && methodInfo.GetMethodBody() != null && (methodInfo.Name == "GetKey" || methodInfo.Name == "GetKeyDown" || methodInfo.Name == "GetKeyUp" || methodInfo.Name == "GetMouseButton" || methodInfo.Name == "GetMouseButtonDown" || methodInfo.Name == "GetMouseButtonUp" || (type2 == typeof(Input) && (methodInfo.Name == "GetButton" || methodInfo.Name == "GetButtonDown" || methodInfo.Name == "GetButtonUp")))) { yield return methodInfo; } } } } private static IEnumerable<MethodBase> TargetMethods() { return Targets(); } [HarmonyPriority(800)] private static bool Prefix(ref bool __result) { if (!InputCapture.Blocking) { return true; } __result = false; return false; } [HarmonyPriority(0)] private static void Postfix(ref bool __result) { if (InputCapture.Blocking) { __result = false; } } } [HarmonyPatch] internal static class ButtonDefinitionPatch { private static IEnumerable<MethodBase> TargetMethods() { string[] array = new string[3] { "Held", "Pressed", "Released" }; foreach (string text in array) { yield return AccessTools.PropertyGetter(typeof(ButtonDef), text); } } [HarmonyPriority(0)] private static void Postfix(ButtonDef __instance, ref bool __result) { if (Plugin.BlockActions && !InputPolicy.AllowsAction(__instance.Name)) { __result = false; } } } [HarmonyPatch] internal static class ActionTimerPatch { private static IEnumerable<MethodBase> TargetMethods() { yield return AccessTools.Method(typeof(ZInput), "GetButtonPressedTimer", (Type[])null, (Type[])null); yield return AccessTools.Method(typeof(ZInput), "GetButtonLastPressedTimer", (Type[])null, (Type[])null); } [HarmonyPriority(0)] private static void Postfix(string name, MethodBase __originalMethod, ref float __result) { if (Plugin.BlockActions && !InputPolicy.AllowsAction(name)) { __result = ((__originalMethod.Name == "GetButtonLastPressedTimer") ? float.MaxValue : 0f); } } } [HarmonyPatch] internal static class LegacyAxisPatch { private static IEnumerable<MethodBase> TargetMethods() { yield return AccessTools.Method(typeof(Input), "GetAxis", (Type[])null, (Type[])null); yield return AccessTools.Method(typeof(Input), "GetAxisRaw", (Type[])null, (Type[])null); } [HarmonyPriority(800)] private static bool Prefix(string __0, ref float __result) { if (!Plugin.BlockActions || InputPolicy.AllowsLegacyAxis(__0)) { return true; } __result = 0f; return false; } [HarmonyPriority(0)] private static void Postfix(string __0, ref float __result) { if (Plugin.BlockActions && !InputPolicy.AllowsLegacyAxis(__0)) { __result = 0f; } } } internal static class InputPolicy { internal static bool AllowsAction(string name) { switch (name) { case "Forward": case "Backward": case "Left": case "Right": case "Jump": case "JoyJump": return true; default: return false; } } internal static bool AllowsLegacyAxis(string name) { switch (name) { default: return name == "Mouse Y"; case "Horizontal": case "Vertical": case "Mouse X": return true; } } } internal sealed class InputReleaseGate { private bool waiting; private int throughFrame = -1; internal bool Blocks(int frame) { if (!waiting) { return frame <= throughFrame; } return true; } internal void Finish(int frame) { waiting = true; throughFrame = frame + 1; } internal void Poll(bool held, int frame) { if (waiting && !held) { waiting = false; throughFrame = frame + 1; } } } [BepInPlugin("com.keeton.standturn", "Item Stand Rotation", "0.5.1")] [DefaultExecutionOrder(-10000)] public sealed class Plugin : BaseUnityPlugin { private sealed class Session { internal ItemStand Stand; internal ItemData Item; internal PreviewVisual Ghost; internal StandVisual Existing; internal int ItemHash; internal int Variant; internal int Quality; internal int Orientation; internal float Angle; internal float SavedAngle; internal float Deadline; internal FacingRotation Facing = FacingRotation.Identity; internal FacingRotation SavedFacing; internal FacingRotation Rotation = FacingRotation.Identity; internal FacingRotation SavedRotation; internal int Axis; internal Vector3 Offset; internal Vector3 SavedOffset; internal bool Editing; internal bool Waiting; internal bool Moving; } public const string Id = "com.keeton.standturn"; public const string ModVersion = "0.5.1"; internal const string AngleKey = "StandTurn.Angle.v1"; internal const string FacingKey = "StandTurn.Facing.v1"; internal const string RotationKey = "StandTurn.Rotation.v1"; internal const string OffsetKey = "StandTurn.Offset.v1"; internal static Plugin Instance; internal static bool AllowVanillaAttach; private Harmony harmony; private Session session; private readonly InputReleaseGate releaseGate = new InputReleaseGate(); private ConfigEntry<float> step; private ConfigEntry<float> fineStep; private ConfigEntry<float> moveStep; private ConfigEntry<float> fineMoveStep; private ConfigEntry<Key> editKey; private ConfigEntry<Key> facingKey; private ConfigEntry<Key> axisKey; private ConfigEntry<Key> modeKey; internal ConfigEntry<Vector3> VerticalAxis; internal ConfigEntry<Vector3> HorizontalAxis; internal static bool Busy { get { if (Object.op_Implicit((Object)(object)Instance)) { return Instance.session != null; } return false; } } internal static bool BlockActions { get { if (Object.op_Implicit((Object)(object)Instance)) { if (!Busy) { return Instance.releaseGate.Blocks(Time.frameCount); } return true; } return false; } } private void Awake() { //IL_0035: Unknown result type (might be due to invalid IL or missing references) //IL_003f: Expected O, but got Unknown //IL_0073: Unknown result type (might be due to invalid IL or missing references) //IL_007d: Expected O, but got Unknown //IL_0139: Unknown result type (might be due to invalid IL or missing references) //IL_0143: Expected O, but got Unknown //IL_0177: Unknown result type (might be due to invalid IL or missing references) //IL_0181: Expected O, but got Unknown //IL_0197: Unknown result type (might be due to invalid IL or missing references) //IL_01bc: Unknown result type (might be due to invalid IL or missing references) //IL_01d6: Unknown result type (might be due to invalid IL or missing references) //IL_01e0: Expected O, but got Unknown Instance = this; step = ((BaseUnityPlugin)this).Config.Bind<float>("Controls", "RotationStep", 15f, new ConfigDescription("Degrees per wheel event.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(1f, 90f), Array.Empty<object>())); fineStep = ((BaseUnityPlugin)this).Config.Bind<float>("Controls", "FineRotationStep", 1f, new ConfigDescription("Degrees per wheel event while holding Shift.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0.1f, 15f), Array.Empty<object>())); editKey = ((BaseUnityPlugin)this).Config.Bind<Key>("Controls", "EditKey", (Key)101, "Start editing the mounted item on the stand you are looking at."); facingKey = ((BaseUnityPlugin)this).Config.Bind<Key>("Controls", "FacingKey", (Key)20, "Turn 90 degrees around the selected stand axis during preview/edit. Press twice for 180 degrees."); axisKey = ((BaseUnityPlugin)this).Config.Bind<Key>("Controls", "FacingAxisKey", (Key)34, "Cycle stand-relative rotation axes X (wall rotation), Y (surface-up), Z (across surface). Starts on X."); modeKey = ((BaseUnityPlugin)this).Config.Bind<Key>("Controls", "MoveModeKey", (Key)21, "Toggle rotate/move mode during preview/edit."); moveStep = ((BaseUnityPlugin)this).Config.Bind<float>("Controls", "MoveStep", 0.05f, new ConfigDescription("Meters per wheel event in move mode.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0.001f, 1f), Array.Empty<object>())); fineMoveStep = ((BaseUnityPlugin)this).Config.Bind<float>("Controls", "FineMoveStep", 0.01f, new ConfigDescription("Meters per wheel event with Shift in move mode.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0.001f, 0.1f), Array.Empty<object>())); VerticalAxis = ((BaseUnityPlugin)this).Config.Bind<Vector3>("Axes", "VerticalStandNormal", Vector3.forward, "Surface normal in vertical stand ROOT local coordinates. Restart after changes. Default: 0,0,1."); HorizontalAxis = ((BaseUnityPlugin)this).Config.Bind<Vector3>("Axes", "HorizontalStandNormal", Vector3.up, "Surface normal in horizontal stand ROOT local coordinates. Restart after changes. Default: 0,1,0."); try { harmony = new Harmony("com.keeton.standturn"); harmony.PatchAll(typeof(Plugin).Assembly); ((BaseUnityPlugin)this).Logger.LogInfo((object)("Item Stand Rotation 0.5.1 loaded. Game: " + Version.GetVersionString(false))); } catch (Exception ex) { Harmony obj = harmony; if (obj != null) { obj.UnpatchSelf(); } ((Behaviour)this).enabled = false; ((BaseUnityPlugin)this).Logger.LogError((object)("StandTurn could not bind to this game version; disabled. " + ex)); } } private void Update() { try { Tick(); } catch (Exception ex) { ((BaseUnityPlugin)this).Logger.LogError((object)("StandTurn canceled an interaction: " + ex)); Finish(); Notify("StandTurn canceled. See BepInEx LogOutput.log."); } } private void Tick() { //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_001c: 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_017e: 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_0336: Unknown result type (might be due to invalid IL or missing references) //IL_03c6: Unknown result type (might be due to invalid IL or missing references) InputCapture.Snapshot snapshot = InputCapture.Read(editKey.Value, facingKey.Value, axisKey.Value, modeKey.Value); releaseGate.Poll(snapshot.OtherHeld, Time.frameCount); Player localPlayer = Player.m_localPlayer; if (!Object.op_Implicit((Object)(object)localPlayer) || Keyboard.current == null || !GameAccess.TakeInput(localPlayer)) { if (Busy) { Finish(); } return; } if (session == null) { if (!BlockActions && snapshot.Edit) { GameObject hoverObject = ((Humanoid)localPlayer).GetHoverObject(); ItemStand val = (Object.op_Implicit((Object)(object)hoverObject) ? hoverObject.GetComponentInParent<ItemStand>() : null); if (GameAccess.Supported(val) && val.HaveAttachment()) { BeginEdit(val); } } return; } if (!Validate(session, localPlayer)) { Finish(); Notify("StandTurn canceled: stand, item, or access changed."); return; } if (snapshot.Cancel) { Finish(); return; } if (session.Waiting) { if (Time.unscaledTime > session.Deadline) { Finish(); Notify("StandTurn: ownership request timed out; nothing placed."); } else if (GameAccess.View.Invoke(session.Stand).IsOwner()) { Commit(); } return; } if (snapshot.ToggleMode) { session.Moving = !session.Moving; } if (snapshot.Reset) { if (session.Moving) { session.Offset = Vector3.zero; } else { session.Angle = 0f; session.Facing = FacingRotation.Identity; session.Rotation = FacingRotation.Identity; } } if (snapshot.CycleAxis) { session.Axis = (session.Axis + 1) % 3; } if (snapshot.Turn && !session.Moving) { session.Rotation = session.Rotation.TurnFixed(session.Axis, 90f); } float wheel = snapshot.Wheel; float num = (snapshot.Fine ? fineStep.Value : step.Value); if (session.Moving) { ((Vector3)(ref session.Offset))[session.Axis] = PositionMath.Scroll(((Vector3)(ref session.Offset))[session.Axis], wheel, snapshot.Fine ? fineMoveStep.Value : moveStep.Value); } else if (!float.IsNaN(wheel) && !float.IsInfinity(wheel) && wheel != 0f) { session.Rotation = session.Rotation.TurnFixed(session.Axis, (float)Math.Sign(wheel) * num); } session.Ghost?.SetPose(session.Angle, session.Facing, session.Rotation, session.Offset); if (Object.op_Implicit((Object)(object)session.Existing)) { session.Existing.PreviewAngle = session.Angle; session.Existing.PreviewFacing = session.Facing; session.Existing.PreviewRotation = session.Rotation; session.Existing.PreviewOffset = session.Offset; session.Existing.Refresh(); } if (snapshot.Confirm) { session.Waiting = true; session.Deadline = Time.unscaledTime + 5f; ZNetView val2 = GameAccess.View.Invoke(session.Stand); if (val2.IsOwner()) { Commit(); } else { val2.InvokeRPC("RPC_RequestOwn", Array.Empty<object>()); } } } internal bool BeginAttach(ItemStand stand, ItemData item) { Finish(); Player localPlayer = Player.m_localPlayer; if (!Object.op_Implicit((Object)(object)localPlayer) || !GameAccess.TakeInput(localPlayer) || !CanReach(stand, localPlayer) || !GameAccess.CanAttach(stand, item)) { return false; } if (GameAccess.QueuedItem.Invoke(stand) != null) { Notify("This stand is already attaching an item."); return false; } Session session = Snapshot(stand); session.Item = item; session.ItemHash = StringExtensionMethods.GetStableHashCode(((Object)item.m_dropPrefab).name); session.Ghost = new PreviewVisual(stand, item, session.Orientation); InputCapture.RefreshBindings(); this.session = session; return true; } private void BeginEdit(ItemStand stand) { //IL_0055: 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_00ce: Unknown result type (might be due to invalid IL or missing references) if (CanReach(stand, Player.m_localPlayer) && Object.op_Implicit((Object)(object)GameAccess.Visual.Invoke(stand))) { Session session = Snapshot(stand); session.Editing = true; session.Angle = session.SavedAngle; session.Facing = session.SavedFacing; session.Rotation = session.SavedRotation; session.Offset = session.SavedOffset; session.Existing = ((Component)stand).GetComponent<StandVisual>() ?? ((Component)stand).gameObject.AddComponent<StandVisual>(); session.Existing.Capture(); session.Existing.PreviewAngle = session.Angle; session.Existing.PreviewFacing = session.Facing; session.Existing.PreviewRotation = session.Rotation; session.Existing.PreviewOffset = session.Offset; InputCapture.RefreshBindings(); this.session = session; } } private static Session Snapshot(ItemStand stand) { //IL_005c: Unknown result type (might be due to invalid IL or missing references) //IL_0061: Unknown result type (might be due to invalid IL or missing references) ZDO zDO = GameAccess.View.Invoke(stand).GetZDO(); return new Session { Stand = stand, SavedAngle = GameAccess.ReadAngle(stand), Orientation = GameAccess.Orientation(stand), SavedFacing = GameAccess.ReadFacing(stand), SavedRotation = GameAccess.ReadRotation(stand), Axis = 0, SavedOffset = GameAccess.ReadOffset(stand), ItemHash = stand.GetAttachedItem(), Variant = zDO.GetInt(ZDOVars.s_variant, 0), Quality = zDO.GetInt(ZDOVars.s_quality, 1) }; } private static bool CanReach(ItemStand stand, Player player) { //IL_0011: 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_003a: Unknown result type (might be due to invalid IL or missing references) if (GameAccess.Valid(stand) && Object.op_Implicit((Object)(object)player) && Vector3.Distance(((Character)player).GetEyePoint(), ((Component)stand).transform.position) <= GameAccess.MaxDistance.Invoke(player)) { return PrivateArea.CheckAccess(((Component)stand).transform.position, 0f, false, false); } return false; } private static bool Validate(Session s, Player player) { //IL_0085: Unknown result type (might be due to invalid IL or missing references) //IL_008a: Unknown result type (might be due to invalid IL or missing references) //IL_008e: Unknown result type (might be due to invalid IL or missing references) if (CanReach(s.Stand, player) && GameAccess.TakeInput(player) && GameAccess.Orientation(s.Stand) == s.Orientation && GameAccess.ReadAngle(s.Stand) == s.SavedAngle && GameAccess.ReadFacing(s.Stand).SameOrientation(s.SavedFacing) && GameAccess.ReadRotation(s.Stand).SameOrientation(s.SavedRotation)) { Vector3 val = GameAccess.ReadOffset(s.Stand); if (((Vector3)(ref val)).Equals(s.SavedOffset)) { if (!s.Editing) { if (!s.Stand.HaveAttachment() && ((Humanoid)player).GetInventory().ContainsItem(s.Item)) { return GameAccess.CanAttach(s.Stand, s.Item); } return false; } ZDO zDO = GameAccess.View.Invoke(s.Stand).GetZDO(); if (s.Stand.HaveAttachment() && s.Stand.GetAttachedItem() == s.ItemHash && zDO.GetInt(ZDOVars.s_variant, 0) == s.Variant) { return zDO.GetInt(ZDOVars.s_quality, 1) == s.Quality; } return false; } } return false; } private void Commit() { //IL_0070: Unknown result type (might be due to invalid IL or missing references) //IL_0086: Unknown result type (might be due to invalid IL or missing references) //IL_0097: 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_0164: Unknown result type (might be due to invalid IL or missing references) //IL_0175: Unknown result type (might be due to invalid IL or missing references) Session session = this.session; Player localPlayer = Player.m_localPlayer; if (!Validate(session, localPlayer) || !GameAccess.View.Invoke(session.Stand).IsOwner()) { Finish(); return; } ZDO zDO = GameAccess.View.Invoke(session.Stand).GetZDO(); bool flag = false; try { zDO.Set("StandTurn.Angle.v1", AngleMath.Normalize(session.Angle)); zDO.Set("StandTurn.Facing.v1", GameAccess.ToQuaternion(session.Facing)); zDO.Set("StandTurn.Rotation.v1", GameAccess.ToQuaternion(session.Rotation)); zDO.Set("StandTurn.Offset.v1", session.Offset); if (session.Editing) { flag = true; } else { AllowVanillaAttach = true; if (session.Stand.UseItem((Humanoid)(object)localPlayer, session.Item)) { GameAccess.UpdateAttach(session.Stand); } flag = session.Stand.HaveAttachment() && session.Stand.GetAttachedItem() == session.ItemHash; } } finally { AllowVanillaAttach = false; if (!flag && GameAccess.Valid(session.Stand) && GameAccess.View.Invoke(session.Stand).IsOwner()) { zDO.Set("StandTurn.Angle.v1", session.SavedAngle); zDO.Set("StandTurn.Facing.v1", GameAccess.ToQuaternion(session.SavedFacing)); zDO.Set("StandTurn.Rotation.v1", GameAccess.ToQuaternion(session.SavedRotation)); zDO.Set("StandTurn.Offset.v1", session.SavedOffset); } if (!session.Editing && GameAccess.Valid(session.Stand) && GameAccess.QueuedItem.Invoke(session.Stand) == session.Item) { ((MonoBehaviour)session.Stand).CancelInvoke("UpdateAttach"); GameAccess.QueuedItem.Invoke(session.Stand) = null; } Finish(); } Notify(flag ? "Item Stand Rotation: placement saved." : "Item Stand Rotation: item could not be attached."); } private void Finish() { Session session = this.session; this.session = null; if (session != null) { session.Ghost?.Dispose(); if (Object.op_Implicit((Object)(object)session.Existing)) { session.Existing.PreviewAngle = null; session.Existing.PreviewFacing = null; session.Existing.PreviewRotation = null; session.Existing.PreviewOffset = null; session.Existing.Refresh(); } releaseGate.Finish(Time.frameCount); } } internal void ReportPreviewError(Exception error) { Finish(); ((BaseUnityPlugin)this).Logger.LogError((object)("Could not create item preview: " + error)); Notify("StandTurn: preview unavailable; item was not placed."); } private static void Notify(string text) { if (Object.op_Implicit((Object)(object)Player.m_localPlayer)) { ((Character)Player.m_localPlayer).Message((MessageType)2, text, 0, (Sprite)null, false); } } private void OnGUI() { //IL_0013: Unknown result type (might be due to invalid IL or missing references) //IL_0018: Unknown result type (might be due to invalid IL or missing references) //IL_0044: Unknown result type (might be due to invalid IL or missing references) //IL_004b: Unknown result type (might be due to invalid IL or missing references) //IL_0052: Unknown result type (might be due to invalid IL or missing references) //IL_005a: Expected O, but got Unknown //IL_00d6: Unknown result type (might be due to invalid IL or missing references) //IL_00db: Unknown result type (might be due to invalid IL or missing references) //IL_00e6: Unknown result type (might be due to invalid IL or missing references) //IL_00fe: Unknown result type (might be due to invalid IL or missing references) //IL_0116: Unknown result type (might be due to invalid IL or missing references) //IL_0181: Unknown result type (might be due to invalid IL or missing references) //IL_0187: Invalid comparison between Unknown and I4 //IL_00a3: 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_02ea: Unknown result type (might be due to invalid IL or missing references) //IL_02f6: Expected O, but got Unknown //IL_0320: Unknown result type (might be due to invalid IL or missing references) //IL_023c: Unknown result type (might be due to invalid IL or missing references) //IL_024f: Unknown result type (might be due to invalid IL or missing references) //IL_0296: Unknown result type (might be due to invalid IL or missing references) if (session != null) { GUIStyle val = new GUIStyle(GUI.skin.box) { fontSize = Mathf.RoundToInt(17f * Mathf.Clamp((float)Screen.height / 1080f, 0.8f, 1.5f)), alignment = (TextAnchor)4, wordWrap = true, richText = true }; Vector3 val2 = (Object.op_Implicit((Object)(object)session.Existing) ? session.Existing.DisplayAngles(session.Angle, session.Facing, session.Rotation) : (session.Ghost?.DisplayAngles(session.Angle, session.Facing, session.Rotation) ?? Vector3.zero)); string text = AxisCounter(0, val2.x) + " " + AxisCounter(1, val2.y) + " " + AxisCounter(2, val2.z); text = "Rotation: " + text + "\nPosition: " + PositionCounter(0) + " " + PositionCounter(1) + " " + PositionCounter(2); bool flag = (int)session.Stand.m_orientationType == 2; string text2 = ((!session.Moving) ? "X: wall rotation Y: surface-up Z: across surface" : (flag ? "X: up/down Y: forward/back Z: sideways" : "X: into/out of wall Y: up/down Z: sideways")); string text3 = (session.Waiting ? ("Item Stand Rotation • Waiting for stand ownership…\n" + text + "\nRight-click / Esc: cancel") : ("Item Stand Rotation • " + (session.Editing ? "Edit" : "Preview") + " • " + (session.Moving ? "MOVE" : "ROTATE") + "\n" + text + "\n" + string.Format("{0}\n{1}: rotate/move {2}: X → Y → Z Scroll: {3} selected axis Shift: fine\n", text2, modeKey.Value, axisKey.Value, session.Moving ? "move" : "rotate") + (session.Moving ? "R: reset position" : $"{facingKey.Value}: +90° on selected axis R: reset rotation") + "\nLeft-click: confirm Right-click / Esc: cancel\nMovement, jump and look remain available; other controls are captured.")); float num = Mathf.Min(800f, (float)Screen.width - 24f); float num2 = val.CalcHeight(new GUIContent(text3), num) + 12f; GUI.Box(new Rect(((float)Screen.width - num) / 2f, (float)Screen.height - 130f - num2, num, num2), text3, val); } } private string AxisCounter(int axis, float degrees) { float num = AngleMath.Normalize((float)Math.Round(degrees, 1)); string text = string.Format("{0}: {1:0.#}°", "XYZ"[axis], num); if (axis != session.Axis || session.Moving) { return text; } return "<color=#FFFF00><b>" + text + "</b></color>"; } private string PositionCounter(int axis) { float num = (float)Math.Round(((Vector3)(ref session.Offset))[axis], 3); string text = string.Format("{0}: {1:0.###} m", "XYZ"[axis], num); if (axis != session.Axis || !session.Moving) { return text; } return "<color=#FFFF00><b>" + text + "</b></color>"; } private void OnDestroy() { Finish(); Harmony obj = harmony; if (obj != null) { obj.UnpatchSelf(); } StandVisual[] array = Object.FindObjectsByType<StandVisual>((FindObjectsSortMode)0); for (int i = 0; i < array.Length; i++) { Object.Destroy((Object)(object)array[i]); } Instance = null; } private void OnApplicationFocus(bool focused) { if (!focused) { Finish(); } } } [HarmonyPatch(typeof(ItemStand), "Awake")] internal static class StandAwakePatch { private static void Postfix(ItemStand __instance) { if (GameAccess.Supported(__instance) && !Object.op_Implicit((Object)(object)((Component)__instance).GetComponent<StandVisual>())) { ((Component)__instance).gameObject.AddComponent<StandVisual>(); } } } [HarmonyPatch(typeof(ItemStand), "SetVisualItem")] internal static class StandVisualPatch { private static void Postfix(ItemStand __instance) { //IL_0062: Unknown result type (might be due to invalid IL or missing references) //IL_0082: 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) if (GameAccess.Supported(__instance) && !__instance.HaveAttachment() && GameAccess.View.Invoke(__instance).IsOwner()) { GameAccess.View.Invoke(__instance).GetZDO().Set("StandTurn.Angle.v1", 0f); GameAccess.View.Invoke(__instance).GetZDO().Set("StandTurn.Facing.v1", Quaternion.identity); GameAccess.View.Invoke(__instance).GetZDO().Set("StandTurn.Rotation.v1", Quaternion.identity); GameAccess.View.Invoke(__instance).GetZDO().Set("StandTurn.Offset.v1", Vector3.zero); } StandVisual component = ((Component)__instance).GetComponent<StandVisual>(); if (Object.op_Implicit((Object)(object)component)) { component.Refresh(); } } } [HarmonyPatch(typeof(ItemStand), "UseItem")] internal static class StandUsePatch { private static bool Prefix(ItemStand __instance, Humanoid user, ItemData item, ref bool __result) { if (Plugin.AllowVanillaAttach || !Object.op_Implicit((Object)(object)Plugin.Instance) || !((Behaviour)Plugin.Instance).enabled || (Object)(object)user != (Object)(object)Player.m_localPlayer || !GameAccess.Supported(__instance) || __instance.HaveAttachment()) { return true; } __result = true; try { Plugin.Instance.BeginAttach(__instance, item); } catch (Exception error) { Plugin.Instance.ReportPreviewError(error); } return false; } } [HarmonyPatch(typeof(ItemStand), "Interact")] internal static class StandInteractPatch { private static bool Prefix(ref bool __result) { if (!Plugin.Busy) { return true; } __result = false; return false; } } [HarmonyPatch(typeof(ItemStand), "GetHoverText")] internal static class StandHoverPatch { private static void Postfix(ItemStand __instance, ref string __result) { if (GameAccess.Supported(__instance) && !Plugin.Busy) { __result += (__instance.HaveAttachment() ? "\n[Item Stand Rotation] Edit: configured EditKey (F8 default)" : "\n[Item Stand Rotation] Use an item hotbar key to preview"); } } } [HarmonyPatch(typeof(ZInput), "GetMouseScrollWheel")] internal static class ScrollPatch { private static void Postfix(ref float __result) { if (Plugin.BlockActions) { __result = 0f; } } } [HarmonyPatch(typeof(Player), "UseHotbarItem")] internal static class HotbarPatch { private static bool Prefix(Player __instance) { if (!((Object)(object)__instance != (Object)(object)Player.m_localPlayer)) { return !Plugin.BlockActions; } return true; } } [HarmonyPatch(typeof(Player), "SetControls")] internal static class ControlsPatch { private static void Prefix(Player __instance, ref bool attack, ref bool attackHold, ref bool secondaryAttack, ref bool secondaryAttackHold, ref bool block, ref bool blockHold, ref bool dodge, ref bool crouch, ref bool run, ref bool autoRun) { if (!((Object)(object)__instance != (Object)(object)Player.m_localPlayer) && Plugin.BlockActions) { attack = (attackHold = (secondaryAttack = (secondaryAttackHold = (block = (blockHold = (dodge = (crouch = (run = (autoRun = false))))))))); __instance.m_autoRun = false; } } } [HarmonyPatch] internal static class ActionButtonPatch { private static IEnumerable<MethodBase> TargetMethods() { yield return AccessTools.Method(typeof(ZInput), "GetButton", (Type[])null, (Type[])null); yield return AccessTools.Method(typeof(ZInput), "GetButtonDown", (Type[])null, (Type[])null); yield return AccessTools.Method(typeof(ZInput), "GetButtonUp", (Type[])null, (Type[])null); } [HarmonyPriority(0)] private static void Postfix(string name, ref bool __result) { if (Plugin.BlockActions && !InputPolicy.AllowsAction(name)) { __result = false; } } } internal static class PositionMath { internal static float Clean(float value) { if (!float.IsNaN(value) && !float.IsInfinity(value)) { return value; } return 0f; } internal static float Scroll(float current, float wheel, float step) { current = Clean(current); if (float.IsNaN(wheel) || float.IsInfinity(wheel) || wheel == 0f || step <= 0f || Clean(step) == 0f) { return current; } return Clean((float)Math.Round(current + (float)Math.Sign(wheel) * step, 4)); } } internal sealed class PreviewVisual : IDisposable { private readonly GameObject staging; private GameObject model; private Material ghostMaterial; private Vector3 position; private Quaternion rotation; private readonly ItemStand stand; internal PreviewVisual(ItemStand target, ItemData item, int orientation) { //IL_0013: Unknown result type (might be due to invalid IL or missing references) //IL_001d: Expected O, but got Unknown //IL_0282: Unknown result type (might be due to invalid IL or missing references) //IL_0288: Unknown result type (might be due to invalid IL or missing references) //IL_028d: Unknown result type (might be due to invalid IL or missing references) //IL_0292: Unknown result type (might be due to invalid IL or missing references) //IL_029e: Unknown result type (might be due to invalid IL or missing references) //IL_02a4: Unknown result type (might be due to invalid IL or missing references) //IL_02a9: Unknown result type (might be due to invalid IL or missing references) //IL_02ae: Unknown result type (might be due to invalid IL or missing references) //IL_02b3: Unknown result type (might be due to invalid IL or missing references) //IL_02e6: Unknown result type (might be due to invalid IL or missing references) //IL_02f3: Unknown result type (might be due to invalid IL or missing references) //IL_02f8: Unknown result type (might be due to invalid IL or missing references) //IL_02fe: Unknown result type (might be due to invalid IL or missing references) //IL_0303: Unknown result type (might be due to invalid IL or missing references) //IL_0452: Unknown result type (might be due to invalid IL or missing references) //IL_0328: 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_0342: Unknown result type (might be due to invalid IL or missing references) //IL_0351: Expected O, but got Unknown stand = target; staging = new GameObject("StandTurn inactive preview staging"); staging.SetActive(false); try { GameObject attachPrefab = ItemStand.GetAttachPrefab(item.m_dropPrefab); if (!Object.op_Implicit((Object)(object)attachPrefab)) { throw new InvalidOperationException("This item has no vanilla attachment visual."); } model = Object.Instantiate<GameObject>(ItemStand.GetAttachGameObject(attachPrefab), staging.transform, false); model.SetActive(false); GameAccess.SetupEquipment(model, item.m_variant); MonoBehaviour[] componentsInChildren = model.GetComponentsInChildren<MonoBehaviour>(true); for (int i = 0; i < componentsInChildren.Length; i++) { Object.DestroyImmediate((Object)(object)componentsInChildren[i]); } if (model.GetComponentsInChildren<MonoBehaviour>(true).Length != 0) { throw new InvalidOperationException("Could not remove all gameplay scripts from the preview."); } Collider[] componentsInChildren2 = model.GetComponentsInChildren<Collider>(true); for (int i = 0; i < componentsInChildren2.Length; i++) { Object.DestroyImmediate((Object)(object)componentsInChildren2[i]); } Rigidbody[] componentsInChildren3 = model.GetComponentsInChildren<Rigidbody>(true); for (int i = 0; i < componentsInChildren3.Length; i++) { Object.DestroyImmediate((Object)(object)componentsInChildren3[i]); } AudioSource[] componentsInChildren4 = model.GetComponentsInChildren<AudioSource>(true); for (int i = 0; i < componentsInChildren4.Length; i++) { Object.DestroyImmediate((Object)(object)componentsInChildren4[i]); } Light[] componentsInChildren5 = model.GetComponentsInChildren<Light>(true); for (int i = 0; i < componentsInChildren5.Length; i++) { ((Behaviour)componentsInChildren5[i]).enabled = false; } ParticleSystem[] componentsInChildren6 = model.GetComponentsInChildren<ParticleSystem>(true); for (int i = 0; i < componentsInChildren6.Length; i++) { componentsInChildren6[i].Stop(true, (ParticleSystemStopBehavior)0); } Animator[] componentsInChildren7 = model.GetComponentsInChildren<Animator>(true); for (int i = 0; i < componentsInChildren7.Length; i++) { ((Behaviour)componentsInChildren7[i]).enabled = false; } Transform[] componentsInChildren8 = model.GetComponentsInChildren<Transform>(true); for (int i = 0; i < componentsInChildren8.Length; i++) { ((Component)componentsInChildren8[i]).gameObject.layer = 2; } Renderer[] componentsInChildren9 = model.GetComponentsInChildren<Renderer>(true); foreach (Renderer val in componentsInChildren9) { if (!(val is MeshRenderer) && !(val is SkinnedMeshRenderer)) { val.enabled = false; } } List<OrientationSettings> list = new List<OrientationSettings>(); ItemData itemData = item.m_dropPrefab.GetComponent<ItemDrop>().m_itemData; stand.GetOrientationSettings(itemData, ref list); OrientationSettings val2 = list[Mathf.Clamp(orientation, 0, list.Count - 1)]; position = attachPrefab.transform.localPosition + val2.m_position; rotation = attachPrefab.transform.localRotation * Quaternion.Euler(val2.m_rotation); model.transform.SetParent(stand.GetAttach(itemData), false); model.transform.localScale = Vector3.Scale(Vector3.Scale(attachPrefab.transform.localScale, itemData.GetScale((float)item.m_quality)), val2.m_scale); Shader val3 = Shader.Find("Standard"); if (Object.op_Implicit((Object)(object)val3)) { ghostMaterial = new Material(val3) { color = new Color(0.3f, 0.9f, 1f, 0.55f) }; ghostMaterial.SetFloat("_Mode", 2f); ghostMaterial.SetInt("_SrcBlend", 5); ghostMaterial.SetInt("_DstBlend", 10); ghostMaterial.SetInt("_ZWrite", 0); ghostMaterial.EnableKeyword("_ALPHABLEND_ON"); ghostMaterial.renderQueue = 3000; componentsInChildren9 = model.GetComponentsInChildren<Renderer>(true); foreach (Renderer val4 in componentsInChildren9) { if (!(val4 is MeshRenderer) && !(val4 is SkinnedMeshRenderer)) { val4.enabled = false; continue; } Material[] sharedMaterials = val4.sharedMaterials; for (int j = 0; j < sharedMaterials.Length; j++) { sharedMaterials[j] = ghostMaterial; } val4.sharedMaterials = sharedMaterials; val4.shadowCastingMode = (ShadowCastingMode)0; } } model.SetActive(true); SetPose(0f, FacingRotation.Identity, FacingRotation.Identity, Vector3.zero); } catch { Dispose(); throw; } } internal void SetPose(float angle, FacingRotation facing, FacingRotation standRotation, Vector3 offset) { //IL_0019: Unknown result type (might be due to invalid IL or missing references) //IL_001f: Unknown result type (might be due to invalid IL or missing references) //IL_002d: Unknown result type (might be due to invalid IL or missing references) if (Object.op_Implicit((Object)(object)model)) { GameAccess.Apply(model.transform, position, rotation, stand, angle, facing, standRotation, offset); } } internal Vector3 DisplayAngles(float angle, FacingRotation facing, FacingRotation standRotation) { //IL_002a: 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_000d: Unknown result type (might be due to invalid IL or missing references) if (!Object.op_Implicit((Object)(object)model)) { return Vector3.zero; } return GameAccess.DisplayAngles(stand, model.transform.parent, rotation, angle, facing, standRotation); } public void Dispose() { if (Object.op_Implicit((Object)(object)model)) { model.SetActive(false); Object.Destroy((Object)(object)model); } if (Object.op_Implicit((Object)(object)staging)) { Object.Destroy((Object)(object)staging); } if (Object.op_Implicit((Object)(object)ghostMaterial)) { Object.Destroy((Object)(object)ghostMaterial); } } } public sealed class StandVisual : MonoBehaviour { private ItemStand stand; private GameObject visual; private Vector3 originalPosition; private Quaternion originalRotation; internal float? PreviewAngle; internal FacingRotation? PreviewFacing; internal FacingRotation? PreviewRotation; internal Vector3? PreviewOffset; private void Awake() { stand = ((Component)this).GetComponent<ItemStand>(); } internal void Capture() { //IL_0050: Unknown result type (might be due to invalid IL or missing references) //IL_0055: Unknown result type (might be due to invalid IL or missing references) //IL_0066: Unknown result type (might be due to invalid IL or missing references) //IL_006b: Unknown result type (might be due to invalid IL or missing references) if (!GameAccess.Valid(stand)) { return; } GameObject val = GameAccess.Visual.Invoke(stand); if (!((Object)(object)val == (Object)(object)visual)) { visual = val; if (Object.op_Implicit((Object)(object)visual)) { originalPosition = visual.transform.localPosition; originalRotation = visual.transform.localRotation; } } } private void LateUpdate() { Refresh(); } internal Vector3 DisplayAngles(float angle, FacingRotation facing, FacingRotation rotation) { //IL_002a: Unknown result type (might be due to invalid IL or missing references) //IL_0047: Unknown result type (might be due to invalid IL or missing references) //IL_004f: Unknown result type (might be due to invalid IL or missing references) Capture(); if (!Object.op_Implicit((Object)(object)visual) || !Object.op_Implicit((Object)(object)visual.transform.parent)) { return Vector3.zero; } return GameAccess.DisplayAngles(stand, visual.transform.parent, originalRotation, angle, facing, rotation); } internal void Refresh() { //IL_0044: 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_00e0: Unknown result type (might be due to invalid IL or missing references) //IL_00d7: Unknown result type (might be due to invalid IL or missing references) Capture(); if (Object.op_Implicit((Object)(object)visual) && Object.op_Implicit((Object)(object)visual.transform.parent) && GameAccess.Valid(stand)) { GameAccess.Apply(visual.transform, originalPosition, originalRotation, stand, PreviewAngle ?? GameAccess.ReadAngle(stand), PreviewFacing ?? GameAccess.ReadFacing(stand), PreviewRotation ?? GameAccess.ReadRotation(stand), (Vector3)(((??)PreviewOffset) ?? GameAccess.ReadOffset(stand))); } } private void OnDestroy() { //IL_001a: 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 (Object.op_Implicit((Object)(object)visual)) { visual.transform.localPosition = originalPosition; visual.transform.localRotation = originalRotation; } } } }