using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Runtime.Versioning;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using HarmonyLib;
using UnityEngine;
[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)]
[assembly: AssemblyTitle("ATLYSS_PleaseHaveASeat")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("Eleen")]
[assembly: AssemblyProduct("ATLYSS_PleaseHaveASeat")]
[assembly: AssemblyCopyright("Copyright © 2026")]
[assembly: AssemblyTrademark("")]
[assembly: ComVisible(false)]
[assembly: Guid("6a8b4633-6d6f-491c-8106-48d4fde542f8")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: TargetFramework(".NETFramework,Version=v4.7.2", FrameworkDisplayName = ".NET Framework 4.7.2")]
[assembly: AssemblyVersion("1.0.0.0")]
namespace Eleen.Atlyss.PleaseHaveASeat
{
[BepInPlugin("com.eleen.atlyss.pleasehaveaseat", "Please, Have a Seat.", "1.0.0")]
public class HaveASeatPlugin : BaseUnityPlugin
{
internal static ConfigEntry<KeyCode> ToggleKey;
private Harmony _harmony;
private void Awake()
{
//IL_0037: Unknown result type (might be due to invalid IL or missing references)
//IL_0041: Expected O, but got Unknown
ToggleKey = ((BaseUnityPlugin)this).Config.Bind<KeyCode>("General", "ToggleKey", (KeyCode)290, "Key to toggle the player selection GUI.");
SeatManager.Initialize(((BaseUnityPlugin)this).Logger);
_harmony = new Harmony("com.eleen.atlyss.pleasehaveaseat");
_harmony.PatchAll();
((Component)this).gameObject.AddComponent<SeatGui>();
((BaseUnityPlugin)this).Logger.LogInfo((object)"Have a Seat loaded.");
}
private void OnDestroy()
{
SeatManager.Shutdown();
Harmony harmony = _harmony;
if (harmony != null)
{
harmony.UnpatchSelf();
}
}
}
internal class SeatGui : MonoBehaviour
{
private static readonly KeyCode DefaultKey = (KeyCode)290;
private const float PlayerListRefreshInterval = 1f;
private bool _showWindow;
private Rect _windowRect = new Rect(20f, 20f, 360f, 400f);
private Vector2 _scrollPos;
private CursorLockMode _savedLockState;
private bool _savedVisible;
private bool _waitingForKey;
private Player[] _cachedPlayers;
private float _refreshTimer;
private void Update()
{
//IL_006a: Unknown result type (might be due to invalid IL or missing references)
if (_showWindow)
{
Cursor.lockState = (CursorLockMode)0;
Cursor.visible = true;
_refreshTimer -= Time.unscaledDeltaTime;
if (_refreshTimer <= 0f)
{
_cachedPlayers = Object.FindObjectsOfType<Player>();
_refreshTimer = 1f;
}
}
if (!_waitingForKey && Input.GetKeyDown(HaveASeatPlugin.ToggleKey.Value))
{
if (_showWindow)
{
CloseWindow();
}
else
{
OpenWindow();
}
}
}
private void OpenWindow()
{
//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)
_savedLockState = Cursor.lockState;
_savedVisible = Cursor.visible;
Cursor.lockState = (CursorLockMode)0;
Cursor.visible = true;
_cachedPlayers = Object.FindObjectsOfType<Player>();
_refreshTimer = 1f;
_showWindow = true;
}
private void CloseWindow()
{
//IL_0010: Unknown result type (might be due to invalid IL or missing references)
_waitingForKey = false;
_cachedPlayers = null;
Cursor.lockState = _savedLockState;
Cursor.visible = _savedVisible;
_showWindow = false;
}
private void OnGUI()
{
//IL_0063: Unknown result type (might be due to invalid IL or missing references)
//IL_006f: Unknown result type (might be due to invalid IL or missing references)
//IL_0083: Expected O, but got Unknown
//IL_007e: Unknown result type (might be due to invalid IL or missing references)
//IL_0083: 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_0028: Invalid comparison between Unknown and I4
//IL_002b: Unknown result type (might be due to invalid IL or missing references)
//IL_0031: Invalid comparison between Unknown and I4
//IL_0041: Unknown result type (might be due to invalid IL or missing references)
if (!_showWindow)
{
return;
}
if (_waitingForKey)
{
Event current = Event.current;
if ((int)current.type == 4 && (int)current.keyCode > 0)
{
HaveASeatPlugin.ToggleKey.Value = current.keyCode;
_waitingForKey = false;
current.Use();
}
}
_windowRect = GUILayout.Window(948201, _windowRect, new WindowFunction(DrawWindow), "Have a Seat", Array.Empty<GUILayoutOption>());
}
private void DrawWindow(int id)
{
//IL_0021: 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_0058: Unknown result type (might be due to invalid IL or missing references)
//IL_005d: Unknown result type (might be due to invalid IL or missing references)
//IL_02d9: Unknown result type (might be due to invalid IL or missing references)
//IL_02de: Unknown result type (might be due to invalid IL or missing references)
//IL_0375: Unknown result type (might be due to invalid IL or missing references)
if (GUI.Button(new Rect(((Rect)(ref _windowRect)).width - 22f, 2f, 20f, 18f), "X"))
{
CloseWindow();
return;
}
GUILayout.Space(4f);
_scrollPos = GUILayout.BeginScrollView(_scrollPos, Array.Empty<GUILayoutOption>());
bool flag = false;
if (_cachedPlayers != null)
{
Player[] cachedPlayers = _cachedPlayers;
foreach (Player val in cachedPlayers)
{
if ((Object)(object)val == (Object)null || (Object)(object)val == (Object)(object)Player._mainPlayer || string.IsNullOrEmpty(val._nickname))
{
continue;
}
flag = true;
SitMode? targetMode = SeatManager.GetTargetMode(val);
string text = (string.IsNullOrEmpty(val._globalNickname) ? val._nickname : (val._nickname + " / @" + val._globalNickname));
GUILayout.BeginHorizontal(Array.Empty<GUILayoutOption>());
GUILayout.Label(text, (GUILayoutOption[])(object)new GUILayoutOption[2]
{
GUILayout.MinWidth(100f),
GUILayout.ExpandWidth(true)
});
if (!targetMode.HasValue)
{
if (GUILayout.Button("Sit", (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(55f) }))
{
SeatManager.AddTarget(val, SitMode.Soft);
}
if (GUILayout.Button("Lock", (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(55f) }))
{
SeatManager.AddTarget(val, SitMode.Force);
}
}
else if (targetMode == SitMode.Soft)
{
if (GUILayout.Button("Unsit", (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(114f) }))
{
SeatManager.RemoveTarget(val);
}
}
else if (GUILayout.Button("Unlock", (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(114f) }))
{
SeatManager.RemoveTarget(val);
}
GUILayout.EndHorizontal();
}
}
if (!flag)
{
GUILayout.Label("No other players nearby.", Array.Empty<GUILayoutOption>());
}
GUILayout.EndScrollView();
GUILayout.Space(4f);
if (GUILayout.Button("Release All", Array.Empty<GUILayoutOption>()))
{
SeatManager.RemoveAllTargets();
}
GUILayout.Space(8f);
GUILayout.Box("", (GUILayoutOption[])(object)new GUILayoutOption[2]
{
GUILayout.ExpandWidth(true),
GUILayout.Height(1f)
});
GUILayout.Space(4f);
GUILayout.BeginHorizontal(Array.Empty<GUILayoutOption>());
object obj;
if (!_waitingForKey)
{
KeyCode value = HaveASeatPlugin.ToggleKey.Value;
obj = "Toggle Key: " + ((object)(KeyCode)(ref value)).ToString();
}
else
{
obj = "Press any key...";
}
string text2 = (string)obj;
GUILayout.Label(text2, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.ExpandWidth(true) });
if (!_waitingForKey)
{
if (GUILayout.Button("Bind", (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(50f) }))
{
_waitingForKey = true;
}
if (GUILayout.Button("Reset", (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(50f) }))
{
HaveASeatPlugin.ToggleKey.Value = DefaultKey;
}
}
else if (GUILayout.Button("Cancel", (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(50f) }))
{
_waitingForKey = false;
}
GUILayout.EndHorizontal();
GUI.DragWindow();
}
}
internal enum SitMode : byte
{
Soft,
Force
}
internal static class SeatManager
{
private class TargetInfo
{
public Player Player;
public PlayerVisual Visual;
public Animator Animator;
public PlayerMove Move;
public PlayerWater Water;
public bool IsForceSitting;
public SitMode Mode;
}
private static ManualLogSource _log;
private static FieldInfo _fi_pv_pMove;
private static FieldInfo _fi_pv_pWater;
private static readonly Dictionary<PlayerVisual, TargetInfo> _targets = new Dictionary<PlayerVisual, TargetInfo>();
internal static void Initialize(ManualLogSource log)
{
_log = log;
_fi_pv_pMove = AccessTools.Field(typeof(PlayerVisual), "_pMove");
_fi_pv_pWater = AccessTools.Field(typeof(PlayerVisual), "_pWater");
}
internal static void Shutdown()
{
RemoveAllTargets();
}
internal static void AddTarget(Player player, SitMode mode)
{
//IL_0068: Unknown result type (might be due to invalid IL or missing references)
//IL_0072: Expected O, but got Unknown
//IL_007e: Unknown result type (might be due to invalid IL or missing references)
//IL_0088: Expected O, but got Unknown
if (!((Object)(object)player == (Object)null) && !((Object)(object)player._pVisual == (Object)null))
{
PlayerVisual pVisual = player._pVisual;
if (!_targets.ContainsKey(pVisual))
{
TargetInfo value = new TargetInfo
{
Player = player,
Visual = pVisual,
Animator = pVisual._visualAnimator,
Move = (PlayerMove)_fi_pv_pMove.GetValue(pVisual),
Water = (PlayerWater)_fi_pv_pWater.GetValue(pVisual),
IsForceSitting = false,
Mode = mode
};
_targets[pVisual] = value;
_log.LogInfo((object)("Target added (" + mode.ToString() + "): " + player._nickname));
}
}
}
internal static void RemoveTarget(Player player)
{
if ((Object)(object)player == (Object)null || (Object)(object)player._pVisual == (Object)null)
{
return;
}
PlayerVisual pVisual = player._pVisual;
if (_targets.TryGetValue(pVisual, out var value))
{
if (value.IsForceSitting)
{
ReleaseSitAnimation(value);
}
_targets.Remove(pVisual);
_log.LogInfo((object)("Target removed: " + player._nickname));
}
}
internal static void RemoveAllTargets()
{
foreach (KeyValuePair<PlayerVisual, TargetInfo> target in _targets)
{
if (target.Value.IsForceSitting)
{
ReleaseSitAnimation(target.Value);
}
}
_targets.Clear();
}
internal static bool IsTarget(Player player)
{
if ((Object)(object)player == (Object)null || (Object)(object)player._pVisual == (Object)null)
{
return false;
}
return _targets.ContainsKey(player._pVisual);
}
internal static SitMode? GetTargetMode(Player player)
{
if ((Object)(object)player == (Object)null || (Object)(object)player._pVisual == (Object)null)
{
return null;
}
if (_targets.TryGetValue(player._pVisual, out var value))
{
return value.Mode;
}
return null;
}
internal static void OnFrameUpdate(PlayerVisual pv)
{
if (_targets.Count == 0 || !Object.op_Implicit((Object)(object)Player._mainPlayer) || !_targets.TryGetValue(pv, out var value))
{
return;
}
if (!ValidateTarget(value))
{
if (value.IsForceSitting)
{
ReleaseSitAnimation(value);
}
_targets.Remove(pv);
}
else if (ShouldForceSit(value))
{
ApplySitAnimation(value);
}
else if (value.IsForceSitting)
{
ReleaseSitAnimation(value);
if (value.Mode == SitMode.Soft)
{
_targets.Remove(pv);
}
}
}
internal static void OnRpcAnimReceived(PlayerVisual pv, string animName, float animFadeTime, int animLayer)
{
if (_targets.Count == 0 || !_targets.TryGetValue(pv, out var value) || !value.IsForceSitting)
{
return;
}
bool flag = false;
if (animLayer == 0 && animName != "Idle" && animName != "Idle_02")
{
flag = true;
}
else if (animLayer == 3 || animLayer == 7 || animLayer == 9 || animLayer == 10 || animLayer == 12)
{
flag = animName != "Empty" && animName != "empty";
}
else if (animLayer == 1 && animName != "Empty" && animName != "empty")
{
flag = true;
}
else if (animLayer == 8 && animName != "Empty" && animName != "empty")
{
flag = true;
}
else if (animLayer == 11)
{
flag = false;
}
if (flag)
{
ReleaseSitAnimation(value);
if (value.Mode == SitMode.Soft)
{
_targets.Remove(pv);
}
}
}
private static bool ValidateTarget(TargetInfo info)
{
return (Object)(object)info.Player != (Object)null && (Object)(object)info.Visual != (Object)null && (Object)(object)info.Animator != (Object)null && (Object)(object)info.Move != (Object)null;
}
private static bool ShouldForceSit(TargetInfo info)
{
//IL_0008: Unknown result type (might be due to invalid IL or missing references)
//IL_000e: Invalid comparison between Unknown and I4
//IL_0037: Unknown result type (might be due to invalid IL or missing references)
//IL_003d: Invalid comparison between Unknown and I4
try
{
if ((int)info.Player._currentPlayerCondition != 2)
{
return false;
}
if (info.Player._bufferingStatus)
{
return false;
}
if ((int)info.Move._currentMovementAction > 0)
{
return false;
}
if (!info.Move.RayGroundCheck())
{
return false;
}
if ((Object)(object)info.Water != (Object)null && info.Water._isInWater)
{
return false;
}
if (IsActionLayerActive(info.Animator))
{
return false;
}
return true;
}
catch
{
return false;
}
}
private static bool IsActionLayerActive(Animator anim)
{
//IL_0003: 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)
//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_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_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_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)
//IL_00ad: 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)
AnimatorStateInfo currentAnimatorStateInfo = anim.GetCurrentAnimatorStateInfo(3);
if (!((AnimatorStateInfo)(ref currentAnimatorStateInfo)).IsName("Empty"))
{
return true;
}
currentAnimatorStateInfo = anim.GetCurrentAnimatorStateInfo(7);
if (!((AnimatorStateInfo)(ref currentAnimatorStateInfo)).IsName("Empty"))
{
return true;
}
currentAnimatorStateInfo = anim.GetCurrentAnimatorStateInfo(8);
if (!((AnimatorStateInfo)(ref currentAnimatorStateInfo)).IsName("Empty"))
{
return true;
}
currentAnimatorStateInfo = anim.GetCurrentAnimatorStateInfo(9);
if (!((AnimatorStateInfo)(ref currentAnimatorStateInfo)).IsName("Empty"))
{
return true;
}
currentAnimatorStateInfo = anim.GetCurrentAnimatorStateInfo(10);
if (!((AnimatorStateInfo)(ref currentAnimatorStateInfo)).IsName("Empty"))
{
return true;
}
currentAnimatorStateInfo = anim.GetCurrentAnimatorStateInfo(12);
if (!((AnimatorStateInfo)(ref currentAnimatorStateInfo)).IsName("Empty"))
{
return true;
}
return false;
}
private static void ApplySitAnimation(TargetInfo info)
{
//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)
Animator animator = info.Animator;
if (!info.IsForceSitting)
{
animator.CrossFade("sit_Init", 0f, 11);
animator.CrossFade("Idle", 0f, 0);
info.IsForceSitting = true;
return;
}
AnimatorStateInfo currentAnimatorStateInfo = animator.GetCurrentAnimatorStateInfo(11);
if (!((AnimatorStateInfo)(ref currentAnimatorStateInfo)).IsName("sit_Init") && !((AnimatorStateInfo)(ref currentAnimatorStateInfo)).IsName("sit_Loop") && !((AnimatorStateInfo)(ref currentAnimatorStateInfo)).IsName("sit_Loop02"))
{
animator.CrossFade("sit_Init", 0f, 11);
animator.CrossFade("Idle", 0f, 0);
}
}
private static void ReleaseSitAnimation(TargetInfo info)
{
if (info.IsForceSitting)
{
if ((Object)(object)info.Animator != (Object)null)
{
info.Animator.CrossFade("Empty", 0.06f, 11);
}
info.IsForceSitting = false;
}
}
}
}
namespace Eleen.Atlyss.PleaseHaveASeat.Patches
{
[HarmonyPatch(typeof(PlayerVisual), "OnUpdate_AnimationCondition")]
internal static class AnimationUpdatePatch
{
[HarmonyPostfix]
private static void Postfix(PlayerVisual __instance)
{
SeatManager.OnFrameUpdate(__instance);
}
}
[HarmonyPatch(typeof(PlayerVisual), "UserCode_Rpc_CrossFadeAnim__String__Single__Int32")]
internal static class RpcCrossFadePatch
{
[HarmonyPrefix]
private static void Prefix(PlayerVisual __instance, string _animName, float _animFadeTime, int _animLayer)
{
SeatManager.OnRpcAnimReceived(__instance, _animName, _animFadeTime, _animLayer);
}
}
[HarmonyPatch(typeof(PlayerVisual), "UserCode_IncludeRpc_Crossfade__String__Single__Int32")]
internal static class IncludeRpcCrossFadePatch
{
[HarmonyPrefix]
private static void Prefix(PlayerVisual __instance, string _animName, float _animFadeTime, int _animLayer)
{
SeatManager.OnRpcAnimReceived(__instance, _animName, _animFadeTime, _animLayer);
}
}
}