Beta Release
This commit is contained in:
+108
@@ -0,0 +1,108 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Reflection;
|
||||
using Harmony;
|
||||
using MSCLoader;
|
||||
using UnityEngine;
|
||||
|
||||
namespace MSCO
|
||||
{
|
||||
/// <summary>
|
||||
/// Solange ein Eingabefenster offen ist (F8-Konsole, Chat, Admin-Menü): Spieler bewegt sich nicht,
|
||||
/// Kamera dreht nicht mit, Mauszeiger ist frei. Danach wird genau das wieder eingeschaltet,
|
||||
/// was hier ausgeschaltet wurde.
|
||||
/// </summary>
|
||||
public static class InputLock
|
||||
{
|
||||
static readonly string[] ControlScripts =
|
||||
{
|
||||
"CharacterMotor", "FPSInputController", "MouseLook", "SimpleSmoothMouseLook", "SmoothMouseLook", "MouseLook2", "MouseLook3"
|
||||
};
|
||||
|
||||
static readonly List<Behaviour> disabled = new List<Behaviour>();
|
||||
static bool locked;
|
||||
static bool previousVisible;
|
||||
static CursorLockMode previousLock;
|
||||
static bool patched;
|
||||
|
||||
public static bool Locked { get { return locked; } }
|
||||
|
||||
public static void Set(bool on)
|
||||
{
|
||||
if (on) KeepCursorFree();
|
||||
if (on == locked) return;
|
||||
locked = on;
|
||||
|
||||
if (on)
|
||||
{
|
||||
PatchCursorActions();
|
||||
previousVisible = Cursor.visible;
|
||||
previousLock = Cursor.lockState;
|
||||
GameObject player = GameObject.Find("PLAYER");
|
||||
if (player != null)
|
||||
{
|
||||
foreach (MonoBehaviour mb in player.GetComponentsInChildren<MonoBehaviour>())
|
||||
{
|
||||
if (mb == null || !mb.enabled || Array.IndexOf(ControlScripts, mb.GetType().Name) < 0) continue;
|
||||
mb.enabled = false;
|
||||
disabled.Add(mb);
|
||||
}
|
||||
}
|
||||
KeepCursorFree();
|
||||
}
|
||||
else
|
||||
{
|
||||
foreach (Behaviour b in disabled) if (b != null) b.enabled = true;
|
||||
disabled.Clear();
|
||||
PlayMakerGUI.LockCursor = previousLock != CursorLockMode.None;
|
||||
PlayMakerGUI.HideCursor = !previousVisible;
|
||||
Cursor.visible = previousVisible;
|
||||
Cursor.lockState = previousLock;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Das Spiel sperrt den Zeiger jeden Frame wieder (PlayMakerGUI.LockCursor + "SetMouseCursor"-Aktionen),
|
||||
/// dadurch springt er in die Mitte. Solange offen: überall freigeben - auch aus OnGUI/LateUpdate aufrufen.
|
||||
/// </summary>
|
||||
public static void KeepCursorFree()
|
||||
{
|
||||
if (!locked) return;
|
||||
PlayMakerGUI.LockCursor = false;
|
||||
PlayMakerGUI.HideCursor = false;
|
||||
Cursor.visible = true;
|
||||
Cursor.lockState = CursorLockMode.None;
|
||||
}
|
||||
|
||||
/// <summary>PlayMaker-Aktionen, die den Mauszeiger setzen, überspringen, solange ein Fenster offen ist.</summary>
|
||||
static void PatchCursorActions()
|
||||
{
|
||||
if (patched) return;
|
||||
patched = true;
|
||||
try
|
||||
{
|
||||
Type action = null;
|
||||
foreach (Assembly asm in AppDomain.CurrentDomain.GetAssemblies())
|
||||
{
|
||||
action = asm.GetType("HutongGames.PlayMaker.Actions.SetMouseCursor");
|
||||
if (action != null) break;
|
||||
}
|
||||
if (action == null) return;
|
||||
|
||||
HarmonyInstance harmony = HarmonyInstance.Create("mbm.msco.inputlock");
|
||||
var prefix = new HarmonyMethod(typeof(InputLock).GetMethod("SkipWhileLocked", BindingFlags.Static | BindingFlags.NonPublic));
|
||||
foreach (string name in new[] { "OnEnter", "OnUpdate", "DoSetMouseCursor" })
|
||||
{
|
||||
MethodInfo m = action.GetMethod(name, BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
|
||||
if (m != null && m.DeclaringType == action) harmony.Patch(m, prefix, null);
|
||||
}
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
ModConsole.Warning("[MSCO] Could not patch cursor actions: " + e.Message);
|
||||
}
|
||||
}
|
||||
|
||||
static bool SkipWhileLocked() { return !locked; }
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user