using System;
using System.Collections.Generic;
using System.Reflection;
using System.Runtime.CompilerServices;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using HarmonyLib;
using LazyBearTechnology;
using UnityEngine;
using UnityEngine.SceneManagement;
[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: AssemblyVersion("0.0.0.0")]
namespace Empress.FirstPerson;
[DefaultExecutionOrder(32000)]
internal sealed class FirstPersonService : MonoBehaviour
{
private ViewSettings settings;
private ManualLogSource log;
private NativeMovementBridge movement;
private NativeVisibilityBridge visibility;
private SpriteWorld world;
private FirstPersonView view;
private PlayerController player;
private Camera camera;
private bool running;
private bool enabledView;
private bool lookEnabled;
private bool ownsCursor;
private CursorLockMode originalCursorLock;
private bool originalCursorVisible;
private float yaw;
private float pitch;
internal bool IsActive
{
get
{
if (view != null)
{
return running;
}
return false;
}
}
internal float Yaw => yaw;
internal float Pitch => pitch;
internal int ConvertedCount
{
get
{
if (world != null)
{
return world.ConvertedCount;
}
return 0;
}
}
public void Initialize(ViewSettings configuration, ManualLogSource logger)
{
try
{
settings = configuration;
log = logger;
enabledView = settings.Enabled.Value;
lookEnabled = settings.MouseLook.Value;
world = new SpriteWorld();
movement = new NativeMovementBridge(() => IsActive, () => yaw);
visibility = new NativeVisibilityBridge(() => IsActive && GameBridge.IsGameplayReady(player), PrepareVisibility);
SceneManager.sceneLoaded += OnSceneLoaded;
running = true;
}
catch
{
Shutdown();
throw;
}
}
private void Update()
{
//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_00cb: Unknown result type (might be due to invalid IL or missing references)
//IL_00d0: Unknown result type (might be due to invalid IL or missing references)
if (!running)
{
return;
}
try
{
PlayerController val;
Camera source;
bool flag = GameBridge.TryGetPlayer(out val, out source) && GameBridge.IsGameplayReady(val);
if (flag && Application.isFocused)
{
KeyboardShortcut value = settings.ToggleViewKey.Value;
if (((KeyboardShortcut)(ref value)).IsDown())
{
enabledView = !enabledView;
}
}
if (flag && Application.isFocused && Input.GetKeyDown((KeyCode)288))
{
lookEnabled = !lookEnabled;
}
if (!flag || !enabledView)
{
ReleaseView();
return;
}
if ((Object)(object)player != (Object)(object)val || view == null || !view.Matches(source))
{
ReleaseView();
player = val;
camera = source;
Vector2 animationDirection = val.View.GetAnimationDirection();
yaw = ((((Vector2)(ref animationDirection)).sqrMagnitude > 0.001f) ? (Mathf.Atan2(animationDirection.x, animationDirection.y) * 57.29578f) : 0f);
pitch = 0f;
view = new FirstPersonView(camera);
}
bool flag2 = lookEnabled && Application.isFocused && GameBridge.CanLook(player);
SetCursorCapture(flag2);
if (flag2)
{
yaw = Mathf.Repeat(yaw + Input.GetAxisRaw("Mouse X") * settings.MouseSensitivity.Value, 360f);
pitch = Mathf.Clamp(pitch - Input.GetAxisRaw("Mouse Y") * settings.MouseSensitivity.Value, -70f, 70f);
}
}
catch (Exception error)
{
Fail(error);
}
}
private void LateUpdate()
{
if (!running || view == null)
{
return;
}
try
{
if (!GameBridge.IsGameplayReady(player))
{
ReleaseView();
return;
}
view.Apply(player, yaw, pitch, settings);
world.Synchronize(camera, player);
SetCursorCapture(lookEnabled && Application.isFocused && GameBridge.CanLook(player));
}
catch (Exception error)
{
Fail(error);
}
}
private void OnGUI()
{
//IL_0044: Unknown result type (might be due to invalid IL or missing references)
if (IsActive && GameBridge.CanLook(player))
{
GUI.Label(new Rect((float)Screen.width * 0.5f - 4f, (float)Screen.height * 0.5f - 10f, 20f, 20f), "+");
}
}
private void PrepareVisibility()
{
try
{
if (view != null)
{
view.PrepareCamera(player, yaw, pitch, settings);
}
}
catch (Exception error)
{
Fail(error);
}
}
private void OnSceneLoaded(Scene scene, LoadSceneMode mode)
{
ReleaseView();
if (world != null)
{
world.Refresh();
}
}
private void SetCursorCapture(bool capture)
{
//IL_000c: 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_0041: Unknown result type (might be due to invalid IL or missing references)
if (capture)
{
if (!ownsCursor)
{
originalCursorLock = Cursor.lockState;
originalCursorVisible = Cursor.visible;
ownsCursor = true;
}
Cursor.lockState = (CursorLockMode)1;
Cursor.visible = false;
}
else if (!capture && ownsCursor)
{
Cursor.lockState = originalCursorLock;
Cursor.visible = originalCursorVisible;
ownsCursor = false;
}
}
private void ReleaseView()
{
SetCursorCapture(capture: false);
if (view != null)
{
view.Dispose();
view = null;
}
if (world != null)
{
world.Refresh();
}
player = null;
camera = null;
}
private void Fail(Exception error)
{
ReleaseView();
running = false;
if (visibility != null)
{
visibility.Dispose();
visibility = null;
}
if (movement != null)
{
movement.Dispose();
movement = null;
}
log.LogError((object)("First-person rendering stopped and the native view was restored: " + error));
}
public void Shutdown()
{
running = false;
SceneManager.sceneLoaded -= OnSceneLoaded;
ReleaseView();
if (visibility != null)
{
visibility.Dispose();
visibility = null;
}
if (movement != null)
{
movement.Dispose();
movement = null;
}
if (world != null)
{
world.Dispose();
world = null;
}
}
private void OnDestroy()
{
Shutdown();
}
}
internal sealed class FirstPersonView : IDisposable
{
private readonly Camera camera;
private readonly Vector3 localPosition;
private readonly Quaternion localRotation;
private readonly bool orthographic;
private readonly float fieldOfView;
private readonly float nearClip;
private readonly float farClip;
private readonly CameraClearFlags clearFlags;
private readonly Color backgroundColor;
private readonly Dictionary<Renderer, bool> playerVisibility = new Dictionary<Renderer, bool>();
private bool disposed;
public FirstPersonView(Camera source)
{
//IL_001f: Unknown result type (might be due to invalid IL or missing references)
//IL_0024: 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_006c: Unknown result type (might be due to invalid IL or missing references)
//IL_0071: Unknown result type (might be due to invalid IL or missing references)
//IL_0078: Unknown result type (might be due to invalid IL or missing references)
//IL_007d: Unknown result type (might be due to invalid IL or missing references)
camera = source;
localPosition = ((Component)source).transform.localPosition;
localRotation = ((Component)source).transform.localRotation;
orthographic = source.orthographic;
fieldOfView = source.fieldOfView;
nearClip = source.nearClipPlane;
farClip = source.farClipPlane;
clearFlags = source.clearFlags;
backgroundColor = source.backgroundColor;
}
public bool Matches(Camera source)
{
if (!disposed)
{
return (Object)(object)camera == (Object)(object)source;
}
return false;
}
public void PrepareCamera(PlayerController player, float yaw, float pitch, ViewSettings settings)
{
//IL_00b3: Unknown result type (might be due to invalid IL or missing references)
//IL_00c5: Unknown result type (might be due to invalid IL or missing references)
//IL_00ca: 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_00e0: Unknown result type (might be due to invalid IL or missing references)
//IL_00ec: 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_009c: Unknown result type (might be due to invalid IL or missing references)
if (!disposed && !((Object)(object)camera == (Object)null))
{
camera.orthographic = false;
camera.ResetProjectionMatrix();
camera.fieldOfView = settings.FieldOfView.Value;
camera.nearClipPlane = 0.035f;
camera.farClipPlane = settings.ViewDistance.Value;
Color val = default(Color);
if (!ColorUtility.TryParseHtmlString(settings.HorizonColor.Value, ref val))
{
val = new Color(18f / 85f, 0.2627451f, 0.3372549f, 1f);
}
camera.clearFlags = (CameraClearFlags)2;
camera.backgroundColor = val;
((Component)camera).transform.SetPositionAndRotation(GameBridge.Position(player) + Vector3.up * settings.EyeHeight.Value, Quaternion.Euler(pitch, yaw, 0f));
}
}
public void Apply(PlayerController player, float yaw, float pitch, ViewSettings settings)
{
PrepareCamera(player, yaw, pitch, settings);
if (disposed || (Object)(object)camera == (Object)null || (Object)(object)player.View == (Object)null)
{
return;
}
Renderer[] componentsInChildren = ((Component)player.View).GetComponentsInChildren<Renderer>(true);
foreach (Renderer val in componentsInChildren)
{
if (!((Object)(object)val == (Object)null))
{
if (!playerVisibility.ContainsKey(val))
{
playerVisibility.Add(val, val.forceRenderingOff);
}
val.forceRenderingOff = true;
}
}
}
public void Dispose()
{
//IL_00d1: Unknown result type (might be due to invalid IL or missing references)
//IL_00e2: Unknown result type (might be due to invalid IL or missing references)
//IL_00f8: Unknown result type (might be due to invalid IL or missing references)
//IL_010e: Unknown result type (might be due to invalid IL or missing references)
if (disposed)
{
return;
}
disposed = true;
foreach (KeyValuePair<Renderer, bool> item in playerVisibility)
{
if ((Object)(object)item.Key != (Object)null)
{
item.Key.forceRenderingOff = item.Value;
}
}
playerVisibility.Clear();
if (!((Object)(object)camera == (Object)null))
{
camera.orthographic = orthographic;
camera.ResetProjectionMatrix();
camera.fieldOfView = fieldOfView;
camera.nearClipPlane = nearClip;
camera.farClipPlane = farClip;
camera.clearFlags = clearFlags;
camera.backgroundColor = backgroundColor;
((Component)camera).transform.localPosition = localPosition;
((Component)camera).transform.localRotation = localRotation;
}
}
}
internal static class GameBridge
{
public static bool TryGetPlayer(out PlayerController player, out Camera camera)
{
player = CurrentPlayer();
camera = null;
if (!IsGameplayReady(player))
{
return false;
}
CameraSystem instance = CameraSystem.Instance;
if ((Object)(object)instance == (Object)null || (Object)(object)instance.MainCamera == (Object)null)
{
return false;
}
camera = instance.WorldCamera;
if ((Object)(object)camera != (Object)null)
{
return ((Component)camera).gameObject.activeInHierarchy;
}
return false;
}
public static Vector3 Position(PlayerController player)
{
//IL_0017: 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)
if (!((Object)(object)player != (Object)null) || !((Object)(object)player.PhysicalBody != (Object)null))
{
return Vector3.zero;
}
return ((Component)player.PhysicalBody).transform.position;
}
public static bool IsGameplayReady(PlayerController player)
{
//IL_0028: Unknown result type (might be due to invalid IL or missing references)
//IL_002e: Invalid comparison between Unknown and I4
if ((Object)(object)MainGame.Instance != (Object)null && (Object)(object)player != (Object)null && (Object)(object)player == (Object)(object)MainGame.PlayerController && (int)MainGame.Instance.gameState == 1 && !MainGame.IsGamePaused && Time.timeScale > 0f && player.IsControlsEnabled && (Object)(object)player.PhysicalBody != (Object)null && (Object)(object)player.View != (Object)null && ((Component)player.PhysicalBody).gameObject.activeInHierarchy)
{
return ((Component)player.View).gameObject.activeInHierarchy;
}
return false;
}
public static bool CanLook(PlayerController player)
{
if (IsGameplayReady(player) && Application.isFocused && player.IsControlsEnabled)
{
return !MouseAimHelper.IsPointerOverUI();
}
return false;
}
public static bool CanMove(PlayerController player)
{
if (IsGameplayReady(player) && Application.isFocused && player.IsControlsEnabled && player.Ssm != null)
{
return player.Ssm.CurState is FreePlayerState;
}
return false;
}
internal static PlayerController CurrentPlayer()
{
if (!((Object)(object)MainGame.Instance == (Object)null))
{
return MainGame.PlayerController;
}
return null;
}
}
internal sealed class NativeMovementBridge : IDisposable
{
private const string PatchIdentifier = "empress.graveyardkeeper2.firstperson.input";
private static NativeMovementBridge active;
private readonly Func<bool> enabled;
private readonly Func<float> yaw;
private readonly Harmony harmony;
private int scope;
private bool disposed;
public NativeMovementBridge(Func<bool> isEnabled, Func<float> currentYaw)
{
//IL_003d: Unknown result type (might be due to invalid IL or missing references)
//IL_0047: Expected O, but got Unknown
//IL_0073: 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_0095: Expected O, but got Unknown
//IL_0095: Expected O, but got Unknown
//IL_00c3: Unknown result type (might be due to invalid IL or missing references)
//IL_00d0: Expected O, but got Unknown
//IL_00fd: Unknown result type (might be due to invalid IL or missing references)
//IL_010b: Expected O, but got Unknown
if (isEnabled == null || currentYaw == null)
{
throw new ArgumentNullException("First-person input requires view state and yaw providers.");
}
if (active != null)
{
throw new InvalidOperationException("First-person input is already attached.");
}
enabled = isEnabled;
yaw = currentYaw;
harmony = new Harmony("empress.graveyardkeeper2.firstperson.input");
try
{
harmony.Patch((MethodBase)AccessTools.Method(typeof(FreePlayerState), "FixedUpdate", (Type[])null, (Type[])null), new HarmonyMethod(typeof(NativeMovementBridge), "BeginMovement", (Type[])null), (HarmonyMethod)null, (HarmonyMethod)null, new HarmonyMethod(typeof(NativeMovementBridge), "EndMovement", (Type[])null), (HarmonyMethod)null);
harmony.Patch((MethodBase)AccessTools.Method(typeof(LazyInput), "GetDirection", (Type[])null, (Type[])null), (HarmonyMethod)null, new HarmonyMethod(typeof(NativeMovementBridge), "RotateMovement", (Type[])null), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
harmony.Patch((MethodBase)AccessTools.Method(typeof(MouseAimHelper), "TryGetAimDirection", (Type[])null, (Type[])null), new HarmonyMethod(typeof(NativeMovementBridge), "ReadAim", (Type[])null), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
active = this;
}
catch
{
harmony.UnpatchSelf();
throw;
}
}
public void Dispose()
{
if (!disposed)
{
disposed = true;
scope = 0;
if (active == this)
{
active = null;
}
harmony.UnpatchSelf();
}
}
private static void BeginMovement(FreePlayerState __instance, out NativeMovementBridge __state)
{
__state = null;
NativeMovementBridge nativeMovementBridge = active;
PlayerController val = GameBridge.CurrentPlayer();
if (nativeMovementBridge != null && !nativeMovementBridge.disposed && nativeMovementBridge.enabled() && GameBridge.CanMove(val) && object.ReferenceEquals(val.Ssm.CurState, __instance))
{
nativeMovementBridge.scope++;
__state = nativeMovementBridge;
}
}
private static Exception EndMovement(Exception __exception, NativeMovementBridge __state)
{
if (__state != null)
{
__state.scope = Math.Max(0, __state.scope - 1);
}
return __exception;
}
private static void RotateMovement(ref Vector2 __result)
{
//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)
NativeMovementBridge nativeMovementBridge = active;
if (nativeMovementBridge != null && !nativeMovementBridge.disposed && nativeMovementBridge.scope != 0 && nativeMovementBridge.enabled() && GameBridge.CanMove(GameBridge.CurrentPlayer()))
{
float num = nativeMovementBridge.yaw() * ((float)Math.PI / 180f);
if (!float.IsNaN(num) && !float.IsInfinity(num))
{
float num2 = Mathf.Sin(num);
float num3 = Mathf.Cos(num);
__result = new Vector2(num3 * __result.x + num2 * __result.y, (0f - num2) * __result.x + num3 * __result.y);
}
}
}
private static bool ReadAim(Vector3 __0, ref Vector2 __1, ref bool __result)
{
//IL_002c: Unknown result type (might be due to invalid IL or missing references)
//IL_002e: 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_0080: 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_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)
NativeMovementBridge nativeMovementBridge = active;
PlayerController player = GameBridge.CurrentPlayer();
if (nativeMovementBridge != null && !nativeMovementBridge.disposed && nativeMovementBridge.enabled() && GameBridge.CanLook(player))
{
Vector3 val = __0 - GameBridge.Position(player);
if (!(((Vector3)(ref val)).sqrMagnitude > 0.0001f))
{
float num = nativeMovementBridge.yaw() * ((float)Math.PI / 180f);
if (float.IsNaN(num) || float.IsInfinity(num))
{
return true;
}
Vector2 val2 = new Vector2(Mathf.Sin(num), Mathf.Cos(num) * 1.25f);
__1 = ((Vector2)(ref val2)).normalized;
__result = true;
return false;
}
}
return true;
}
}
internal sealed class NativeVisibilityBridge : IDisposable
{
private const string PatchIdentifier = "empress.graveyardkeeper2.firstperson.visibility";
private static NativeVisibilityBridge active;
private readonly Func<bool> enabled;
private readonly Action applyCamera;
private readonly Harmony harmony;
private bool preparing;
private bool disposed;
public NativeVisibilityBridge(Func<bool> isEnabled, Action prepareCamera)
{
//IL_003d: Unknown result type (might be due to invalid IL or missing references)
//IL_0047: Expected O, but got Unknown
//IL_009c: Unknown result type (might be due to invalid IL or missing references)
//IL_00aa: Expected O, but got Unknown
if (isEnabled == null || prepareCamera == null)
{
throw new ArgumentNullException("First-person visibility requires view state and camera providers.");
}
if (active != null)
{
throw new InvalidOperationException("First-person visibility is already attached.");
}
enabled = isEnabled;
applyCamera = prepareCamera;
harmony = new Harmony("empress.graveyardkeeper2.firstperson.visibility");
try
{
MethodInfo methodInfo = AccessTools.Method(typeof(ChunkManager), "TryProcessChunkVisibility", Type.EmptyTypes, (Type[])null);
if (methodInfo == null)
{
throw new MissingMethodException(typeof(ChunkManager).FullName, "TryProcessChunkVisibility");
}
harmony.Patch((MethodBase)methodInfo, new HarmonyMethod(typeof(NativeVisibilityBridge), "PrepareCamera", (Type[])null), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
active = this;
}
catch
{
harmony.UnpatchSelf();
throw;
}
}
public void Dispose()
{
if (!disposed)
{
disposed = true;
if (active == this)
{
active = null;
}
harmony.UnpatchSelf();
}
}
[HarmonyPriority(800)]
private static void PrepareCamera()
{
NativeVisibilityBridge nativeVisibilityBridge = active;
if (nativeVisibilityBridge == null || nativeVisibilityBridge.disposed || nativeVisibilityBridge.preparing || !nativeVisibilityBridge.enabled())
{
return;
}
nativeVisibilityBridge.preparing = true;
try
{
nativeVisibilityBridge.applyCamera();
}
finally
{
nativeVisibilityBridge.preparing = false;
}
}
}
[BepInPlugin("empress.graveyardkeeper2.firstperson", "Empress First Person", "0.1.1")]
public sealed class Plugin : BaseUnityPlugin
{
public const string Identifier = "empress.graveyardkeeper2.firstperson";
private FirstPersonService service;
private GameObject serviceHost;
private void Awake()
{
//IL_0012: Unknown result type (might be due to invalid IL or missing references)
//IL_001c: Expected O, but got Unknown
try
{
ViewSettings configuration = new ViewSettings(((BaseUnityPlugin)this).Config);
serviceHost = new GameObject("Empress First Person");
Object.DontDestroyOnLoad((Object)(object)serviceHost);
service = serviceHost.AddComponent<FirstPersonService>();
service.Initialize(configuration, ((BaseUnityPlugin)this).Logger);
}
catch
{
if ((Object)(object)serviceHost != (Object)null)
{
Object.Destroy((Object)(object)serviceHost);
}
service = null;
serviceHost = null;
throw;
}
}
private void OnDestroy()
{
if ((Object)(object)service != (Object)null)
{
service.Shutdown();
}
if ((Object)(object)serviceHost != (Object)null)
{
Object.Destroy((Object)(object)serviceHost);
}
}
}
internal sealed class ViewSettings
{
public readonly ConfigEntry<bool> Enabled;
public readonly ConfigEntry<float> FieldOfView;
public readonly ConfigEntry<float> EyeHeight;
public readonly ConfigEntry<float> MouseSensitivity;
public readonly ConfigEntry<bool> MouseLook;
public readonly ConfigEntry<string> HorizonColor;
public readonly ConfigEntry<KeyboardShortcut> ToggleViewKey;
public readonly ConfigEntry<float> ViewDistance;
public ViewSettings(ConfigFile config)
{
//IL_004d: Unknown result type (might be due to invalid IL or missing references)
//IL_0057: Expected O, but got Unknown
//IL_0087: Unknown result type (might be due to invalid IL or missing references)
//IL_0091: Expected O, but got Unknown
//IL_00c1: Unknown result type (might be due to invalid IL or missing references)
//IL_00cb: Expected O, but got Unknown
//IL_011b: Unknown result type (might be due to invalid IL or missing references)
//IL_0125: Expected O, but got Unknown
//IL_015d: Unknown result type (might be due to invalid IL or missing references)
Enabled = config.Bind<bool>("General", "Enabled", true, "Enable the first-person view on startup during free gameplay.");
FieldOfView = config.Bind<float>("View", "FieldOfView", 70f, new ConfigDescription("Vertical field of view.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(45f, 100f), new object[0]));
ViewDistance = config.Bind<float>("View", "ViewDistance", 50f, new ConfigDescription("First-person draw distance in world units.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(15f, 120f), new object[0]));
EyeHeight = config.Bind<float>("View", "EyeHeight", 0.8f, new ConfigDescription("Camera height above the physical player position.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0.2f, 2.5f), new object[0]));
HorizonColor = config.Bind<string>("View", "HorizonColor", "#364356", "Solid horizon color in hexadecimal RGB notation.");
MouseSensitivity = config.Bind<float>("Controls", "MouseSensitivity", 2f, new ConfigDescription("Mouse look sensitivity.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0.1f, 8f), new object[0]));
MouseLook = config.Bind<bool>("Controls", "MouseLook", true, "Capture the mouse during free gameplay. F7 releases or captures it.");
ToggleViewKey = config.Bind<KeyboardShortcut>("Controls", "ToggleViewKey", new KeyboardShortcut((KeyCode)277, (KeyCode[])(object)new KeyCode[0]), "Toggle first-person and the original view. Default: Insert.");
}
}
internal sealed class SpriteWorld : IDisposable
{
private sealed class Surface : IDisposable
{
private readonly SpriteRenderer renderer;
private Material original;
private Material owned;
public Surface(SpriteRenderer source)
{
renderer = source;
Synchronize();
}
public void Synchronize()
{
//IL_00c2: Unknown result type (might be due to invalid IL or missing references)
//IL_00cc: Expected O, but got Unknown
if ((Object)(object)renderer == (Object)null)
{
return;
}
Material sharedMaterial = ((Renderer)renderer).sharedMaterial;
if ((Object)(object)sharedMaterial == (Object)(object)owned)
{
if ((Object)(object)owned != (Object)null)
{
owned.SetFloat("_ForceVertical", 1f);
owned.EnableKeyword("FORCE_VERTICAL");
}
return;
}
if ((Object)(object)owned != (Object)null)
{
Object.Destroy((Object)(object)owned);
}
owned = null;
original = sharedMaterial;
if (!((Object)(object)sharedMaterial == (Object)null) && !((Object)(object)sharedMaterial.shader == (Object)null) && !(((Object)sharedMaterial.shader).name != "Custom/3D Sprite") && sharedMaterial.HasProperty("_ForceVertical"))
{
owned = new Material(sharedMaterial);
((Object)owned).name = "Empress First Person Sprite";
((Object)owned).hideFlags = (HideFlags)52;
owned.SetFloat("_ForceVertical", 1f);
owned.EnableKeyword("FORCE_VERTICAL");
((Renderer)renderer).sharedMaterial = owned;
}
}
public void Dispose()
{
if ((Object)(object)renderer != (Object)null && (Object)(object)((Renderer)renderer).sharedMaterial == (Object)(object)owned)
{
((Renderer)renderer).sharedMaterial = original;
}
if ((Object)(object)owned != (Object)null)
{
Object.Destroy((Object)(object)owned);
}
owned = null;
original = null;
}
}
private readonly Dictionary<SpriteRenderer, Surface> surfaces = new Dictionary<SpriteRenderer, Surface>();
private float nextDiscovery;
private float nextVisibility;
private bool disposed;
public int ConvertedCount => surfaces.Count;
public void Synchronize(Camera view, PlayerController player)
{
if (disposed || (Object)(object)view == (Object)null || (Object)(object)player == (Object)null)
{
return;
}
if (Time.unscaledTime >= nextVisibility)
{
ChunkManager instance = LazySingleton<ChunkManager>.Instance;
if ((Object)(object)instance != (Object)null && instance.IsActive)
{
instance.ForceProcessVisibility();
}
nextVisibility = Time.unscaledTime + 0.2f;
}
if (Time.unscaledTime >= nextDiscovery)
{
Discover(view, player);
nextDiscovery = Time.unscaledTime + 2f;
}
foreach (Surface value in surfaces.Values)
{
value.Synchronize();
}
}
public void Refresh()
{
foreach (Surface value in surfaces.Values)
{
value.Dispose();
}
surfaces.Clear();
nextDiscovery = 0f;
nextVisibility = 0f;
}
public void Dispose()
{
if (!disposed)
{
disposed = true;
Refresh();
}
}
private void Discover(Camera view, PlayerController player)
{
//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_008d: Unknown result type (might be due to invalid IL or missing references)
//IL_0092: Unknown result type (might be due to invalid IL or missing references)
//IL_0103: Unknown result type (might be due to invalid IL or missing references)
//IL_010e: 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_0118: Unknown result type (might be due to invalid IL or missing references)
//IL_0174: Unknown result type (might be due to invalid IL or missing references)
//IL_0179: Unknown result type (might be due to invalid IL or missing references)
float num = Mathf.Min(150f, Mathf.Max(40f, view.farClipPlane));
float num2 = num * num;
Transform val = (((Object)(object)player.View == (Object)null) ? null : ((Component)player.View).transform);
SpriteRenderer[] array = Resources.FindObjectsOfTypeAll<SpriteRenderer>();
foreach (SpriteRenderer val2 in array)
{
if ((Object)(object)val2 == (Object)null || surfaces.ContainsKey(val2))
{
continue;
}
Scene scene = ((Component)val2).gameObject.scene;
if (!((Scene)(ref scene)).IsValid())
{
continue;
}
Scene scene2 = ((Component)val2).gameObject.scene;
if (!((Scene)(ref scene2)).isLoaded || !((Component)val2).gameObject.activeInHierarchy || ((Component)val2).gameObject.layer == 5 || (Object)(object)val2.sprite == (Object)null || ((Object)(object)val != (Object)null && ((Component)val2).transform.IsChildOf(val)) || (Object)(object)((Component)val2).GetComponentInParent<Canvas>() != (Object)null)
{
continue;
}
Vector3 val3 = ((Component)val2).transform.position - ((Component)view).transform.position;
if (!(((Vector3)(ref val3)).sqrMagnitude > num2))
{
Material sharedMaterial = ((Renderer)val2).sharedMaterial;
if (!((Object)(object)sharedMaterial == (Object)null) && !((Object)(object)sharedMaterial.shader == (Object)null) && !(((Object)sharedMaterial.shader).name != "Custom/3D Sprite") && sharedMaterial.HasProperty("_ForceVertical") && !(Mathf.Abs(Vector3.Dot(((Component)val2).transform.forward, Vector3.up)) > 0.75f) && !IsGround(((Object)val2.sprite).name))
{
surfaces.Add(val2, new Surface(val2));
}
}
}
}
private static bool IsGround(string name)
{
string text = name.ToLowerInvariant();
if (!text.Contains("floor") && !text.Contains("ground") && !text.Contains("shadow") && !text.Contains("decal") && !text.Contains("terrain") && !text.Contains("road"))
{
return text.Contains("water");
}
return true;
}
}