Beta Release

This commit is contained in:
2026-09-26 19:37:28 +02:00
parent adca4d9167
commit e77ccf2f33
29 changed files with 6819 additions and 293 deletions
+108
View File
@@ -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; }
}
}