using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using Cinemachine;
using HarmonyLib;
using HorizonBasedAmbientOcclusion;
using LazyBearTechnology;
using Microsoft.CodeAnalysis;
using PI.NGSS;
using TMPro;
using UnityEngine;
using UnityEngine.SceneManagement;
using UnityEngine.UI;
[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETFramework,Version=v4.7.2", FrameworkDisplayName = ".NET Framework 4.7.2")]
[assembly: AssemblyCompany("GK2Perf")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0")]
[assembly: AssemblyProduct("GK2Perf")]
[assembly: AssemblyTitle("GK2Perf")]
[assembly: AssemblyVersion("1.0.0.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 GK2Perf
{
internal static class FpsCounter
{
private const float Window = 0.5f;
private static int frames;
private static float elapsed;
private static float worst;
private static string text = "";
private static GUIStyle style;
private static GUIStyle shadow;
private static int styledFor;
public static void Tick()
{
if (!PerfSettings.FpsCounter.Value)
{
frames = 0;
elapsed = 0f;
worst = 0f;
return;
}
float unscaledDeltaTime = Time.unscaledDeltaTime;
frames++;
elapsed += unscaledDeltaTime;
worst = Mathf.Max(worst, unscaledDeltaTime);
if (elapsed >= 0.5f)
{
text = $"{(float)frames / elapsed:0} fps {elapsed * 1000f / (float)frames:0.0} ms worst {worst * 1000f:0.0} ms";
frames = 0;
elapsed = 0f;
worst = 0f;
}
}
public static void Draw()
{
//IL_001d: Unknown result type (might be due to invalid IL or missing references)
//IL_0023: Invalid comparison between Unknown and I4
//IL_0060: Unknown result type (might be due to invalid IL or missing references)
//IL_0065: 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_0073: 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_0086: Expected O, but got Unknown
//IL_0090: Unknown result type (might be due to invalid IL or missing references)
//IL_009f: Unknown result type (might be due to invalid IL or missing references)
//IL_00a9: Expected O, but got Unknown
//IL_00c7: Unknown result type (might be due to invalid IL or missing references)
//IL_0127: Unknown result type (might be due to invalid IL or missing references)
//IL_013b: Unknown result type (might be due to invalid IL or missing references)
if (PerfSettings.FpsCounter.Value && text.Length != 0 && (int)Event.current.type == 7)
{
if (style == null || styledFor != Screen.height)
{
styledFor = Screen.height;
int fontSize = Mathf.Max(12, Screen.height / 50);
style = new GUIStyle(GUI.skin.label)
{
fontSize = fontSize,
fontStyle = (FontStyle)1,
wordWrap = false,
alignment = (TextAnchor)2
};
style.normal.textColor = Color.white;
shadow = new GUIStyle(style);
shadow.normal.textColor = new Color(0f, 0f, 0f, 0.8f);
}
Rect val = default(Rect);
((Rect)(ref val))..ctor(10f, 6f, (float)Screen.width - 20f, (float)style.fontSize * 2f);
GUI.Label(new Rect(((Rect)(ref val)).x + 2f, ((Rect)(ref val)).y + 2f, ((Rect)(ref val)).width, ((Rect)(ref val)).height), text, shadow);
GUI.Label(val, text, style);
}
}
}
internal static class MotionCheck
{
[CompilerGenerated]
private static class <>O
{
public static CameraCallback <0>__OnPreCull;
}
private const float SampleSeconds = 4f;
private const float PauseSeconds = 60f;
private const int MaxLogs = 10;
private const float WalkingSpeed = 0.5f;
private static int physicsSteps;
private static int lastFrame = -1;
private static bool hasLast;
private static Vector3 lastBody;
private static Vector3 lastCamera;
private static float nextSample;
private static int logs;
private static Camera worldCamera;
private static float nextLookup;
private static int measuredPacing = int.MinValue;
private static float walked;
private static int frames;
private static int bodyStill;
private static int cameraStill;
private static int noStep;
private static int manySteps;
private static double cameraSum;
private static double cameraSquares;
private static float cameraMax;
public static void Start()
{
//IL_0025: Unknown result type (might be due to invalid IL or missing references)
//IL_002f: Expected O, but got Unknown
//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_0020: Expected O, but got Unknown
CameraCallback onPreCull = Camera.onPreCull;
object obj = <>O.<0>__OnPreCull;
if (obj == null)
{
CameraCallback val = OnPreCull;
<>O.<0>__OnPreCull = val;
obj = (object)val;
}
Camera.onPreCull = (CameraCallback)Delegate.Combine((Delegate?)(object)onPreCull, (Delegate?)obj);
}
public static void CountStep()
{
physicsSteps++;
}
public static string Describe()
{
//IL_002e: Unknown result type (might be due to invalid IL or missing references)
//IL_009e: Unknown result type (might be due to invalid IL or missing references)
//IL_00aa: Unknown result type (might be due to invalid IL or missing references)
string text = "no player";
PlayerPhysicalBody val = PlayerBody();
if ((Object)(object)val != (Object)null && (Object)(object)val.Rb != (Object)null)
{
text = string.Format("player body {0}{1}", val.Rb.interpolation, val.Rb.isKinematic ? " (kinematic)" : "");
}
string text2 = "no camera brain";
CameraSystem instance = CameraSystem.Instance;
MainCamera val2 = (((Object)(object)instance != (Object)null) ? instance.MainCamera : null);
CinemachineBrain val3 = (((Object)(object)val2 != (Object)null) ? ((Component)val2).GetComponent<CinemachineBrain>() : null);
if ((Object)(object)val3 != (Object)null)
{
text2 = $"camera brain {val3.m_UpdateMethod} (blends {val3.m_BlendUpdateMethod})";
}
CameraController val4 = (((Object)(object)instance != (Object)null) ? instance.ActiveCameraController : null);
CinemachineVirtualCamera val5 = (((Object)(object)val4 != (Object)null) ? val4.VirtualCamera : null);
string text3 = (((Object)(object)val5 != (Object)null && (Object)(object)((CinemachineVirtualCameraBase)val5).Follow != (Object)null) ? (", camera follows '" + ((Object)((CinemachineVirtualCameraBase)val5).Follow).name + "'") : "");
return $"physics {1f / Time.fixedDeltaTime:0} Hz, {text}, {text2}{text3}";
}
private static PlayerPhysicalBody PlayerBody()
{
if ((Object)(object)MainGame.Instance == (Object)null)
{
return null;
}
PlayerController playerController = MainGame.PlayerController;
if (!((Object)(object)playerController != (Object)null))
{
return null;
}
return playerController.PhysicalBody;
}
private static void OnPreCull(Camera camera)
{
//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_00cd: Unknown result type (might be due to invalid IL or missing references)
//IL_00d2: Unknown result type (might be due to invalid IL or missing references)
//IL_00da: Unknown result type (might be due to invalid IL or missing references)
//IL_00df: Unknown result type (might be due to invalid IL or missing references)
//IL_01e4: Unknown result type (might be due to invalid IL or missing references)
//IL_01e6: Unknown result type (might be due to invalid IL or missing references)
//IL_01eb: Unknown result type (might be due to invalid IL or missing references)
//IL_01ed: 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_0115: Unknown result type (might be due to invalid IL or missing references)
//IL_011a: 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_012c: Unknown result type (might be due to invalid IL or missing references)
//IL_0131: Unknown result type (might be due to invalid IL or missing references)
int num = Application.targetFrameRate * 10 + QualitySettings.vSyncCount;
if (num != measuredPacing)
{
measuredPacing = num;
Restart();
nextSample = 0f;
}
if (Time.frameCount == lastFrame || logs >= 10 || Time.unscaledTime < nextSample || Time.timeScale <= 0f)
{
return;
}
try
{
if ((Object)(object)camera != (Object)(object)WorldCamera())
{
return;
}
lastFrame = Time.frameCount;
int num2 = physicsSteps;
physicsSteps = 0;
PlayerPhysicalBody val = PlayerBody();
if ((Object)(object)val == (Object)null || (Object)(object)val.Rb == (Object)null || val.Rb.isKinematic)
{
hasLast = false;
return;
}
Transform transform = ((Component)camera).transform;
Vector3 position = ((Component)val).transform.position;
Vector3 position2 = transform.position;
Vector3 linearVelocity = val.Rb.linearVelocity;
bool flag = ((Vector3)(ref linearVelocity)).magnitude > 0.5f;
if (hasLast && flag)
{
float num3 = (float)Screen.height / (2f * camera.orthographicSize);
float num4 = OnScreen(position - lastBody, transform) * num3;
float num5 = OnScreen(position2 - lastCamera, transform) * num3;
frames++;
walked += Time.unscaledDeltaTime;
bodyStill += ((num4 < 0.01f) ? 1 : 0);
cameraStill += ((num5 < 0.01f) ? 1 : 0);
noStep += ((num2 == 0) ? 1 : 0);
manySteps += ((num2 > 1) ? 1 : 0);
cameraSum += num5;
cameraSquares += num5 * num5;
cameraMax = Mathf.Max(cameraMax, num5);
if (walked >= 4f)
{
Log();
}
}
lastBody = position;
lastCamera = position2;
hasLast = true;
}
catch (Exception ex)
{
Plugin.Log.LogDebug((object)("Measuring movement failed: " + ex.Message));
logs = 10;
}
}
private static Camera WorldCamera()
{
if ((Object)(object)worldCamera == (Object)null && Time.unscaledTime >= nextLookup)
{
nextLookup = Time.unscaledTime + 2f;
CameraSystem val = (((Object)(object)MainGame.Instance != (Object)null) ? CameraSystem.Instance : null);
MainCamera val2 = (((Object)(object)val != (Object)null) ? val.MainCamera : null);
worldCamera = (((Object)(object)val2 != (Object)null) ? val2.Camera : null);
}
return worldCamera;
}
private static float OnScreen(Vector3 delta, Transform view)
{
//IL_0000: Unknown result type (might be due to invalid IL or missing references)
//IL_0002: 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_000e: Unknown result type (might be due to invalid IL or missing references)
float num = Vector3.Dot(delta, view.right);
float num2 = Vector3.Dot(delta, view.up);
return Mathf.Sqrt(num * num + num2 * num2);
}
private static void Log()
{
double num = cameraSum / (double)frames;
double num2 = Math.Sqrt(Math.Max(0.0, cameraSquares / (double)frames - num * num));
logs++;
Plugin.Log.LogInfo((object)($"Movement while walking ({frames} frames, {(float)frames / walked:0} fps): the character didn't move on {Percent(bodyStill)} of frames, " + "the camera on " + Percent(cameraStill) + "; frames with no physics step " + Percent(noStep) + ", with two or more " + Percent(manySteps) + "; " + $"camera step {num:0.0} px on average (spread {num2:0.0}, largest {cameraMax:0.0}); " + $"FPS limit {Application.targetFrameRate}, vsync {QualitySettings.vSyncCount}. {Describe()}."));
Restart();
nextSample = Time.unscaledTime + 60f;
}
private static void Restart()
{
walked = 0f;
frames = (bodyStill = (cameraStill = (noStep = (manySteps = 0))));
cameraSum = (cameraSquares = 0.0);
cameraMax = 0f;
hasLast = false;
}
private static string Percent(int count)
{
return $"{100f * (float)count / (float)frames:0}%";
}
}
internal sealed class PerfRunner : MonoBehaviour
{
private bool applyPending;
private bool appliedOnLoad;
private float lastLoadReport = -1000f;
public static PerfRunner Instance { get; private set; }
private void Awake()
{
Instance = this;
PerfSettings.Changed += delegate
{
applyPending = true;
};
SceneManager.sceneLoaded += OnSceneLoaded;
MotionCheck.Start();
}
private void FixedUpdate()
{
MotionCheck.CountStep();
}
private void OnDestroy()
{
SceneManager.sceneLoaded -= OnSceneLoaded;
}
private void OnSceneLoaded(Scene scene, LoadSceneMode mode)
{
if (!appliedOnLoad && PerfSettings.AnyOverride)
{
appliedOnLoad = true;
applyPending = true;
}
else if (Time.unscaledTime - lastLoadReport > 30f)
{
lastLoadReport = Time.unscaledTime;
Report.Soon();
}
}
private void Update()
{
if (applyPending)
{
applyPending = false;
Tuning.Reapply();
}
ShadowFit.Tick();
FpsCounter.Tick();
Report.Tick();
}
private void OnGUI()
{
FpsCounter.Draw();
}
}
internal enum ShadowChoice
{
Game,
Fitted,
Console,
Hard,
Off
}
internal enum RenderChoice
{
Game,
Full,
PixelArt
}
internal enum SnapChoice
{
Game,
Off
}
internal enum ShadingChoice
{
Game,
HalfResolution,
Low,
Off
}
internal enum LampChoice
{
Game,
Real,
RealNoShadows,
Faked
}
internal sealed class MenuOption
{
public string Key;
public string Header;
public string[] Labels;
public Func<int> Get;
public Action<int> Set;
}
internal static class PerfSettings
{
public static ConfigEntry<ShadowChoice> Shadows;
public static ConfigEntry<RenderChoice> WorldResolution;
public static ConfigEntry<SnapChoice> PixelSnapping;
public static ConfigEntry<ShadingChoice> AmbientShading;
public static ConfigEntry<LampChoice> Lamps;
public static ConfigEntry<bool> FpsCounter;
public static ConfigEntry<bool> InSettingsMenu;
public static ConfigEntry<float> ShadowMargin;
public static MenuOption[] Menu;
public static bool AnyOverride
{
get
{
if (Shadows.Value == ShadowChoice.Game && WorldResolution.Value == RenderChoice.Game && AmbientShading.Value == ShadingChoice.Game)
{
return Lamps.Value != LampChoice.Game;
}
return true;
}
}
public static event Action Changed;
public static void Bind(ConfigFile config)
{
Shadows = config.Bind<ShadowChoice>("Graphics", "Shadows", ShadowChoice.Game, "Game: the Graphics preset's shadows (on PC: soft shadows reaching 3000 units in 4 layers, though the camera shows about 20). Fitted: the same soft shadows, reaching only as far as the camera shows, in one layer. Console: the shadows PS5 and Xbox Series use (simpler soft shadows, no lamp shadows). Hard: hard-edged shadows. Off: no shadows.");
WorldResolution = config.Bind<RenderChoice>("Graphics", "WorldResolution", RenderChoice.Game, "Game: what the Graphics preset uses (Full on High to Low, Pixel art on Lowest). Full: the world at full screen resolution. Pixel art: the world at the game's pixel size (half resolution at 1080p, a quarter at 4K), scaled up. In Pixel art the camera follows the player rigidly and the water is the simpler kind, as on Lowest.");
PixelSnapping = config.Bind<SnapChoice>("Graphics", "PixelSnapping", SnapChoice.Game, "Game: the camera and your character snap to whole screen pixels, so while walking the world moves in uneven pixel steps. Off: they move smoothly between pixels, so the world scrolls evenly; pixel-art edges may shimmer a little while moving. Only with the world at full resolution (Pixel art draws on the pixel grid anyway).");
AmbientShading = config.Bind<ShadingChoice>("Graphics", "AmbientShading", ShadingChoice.Game, "Ambient shading (HBAO, the soft darkening in corners and under objects). Game: the preset's. HalfResolution: the preset's quality, worked out at half resolution. Low: the lowest quality at half resolution. Off: none.");
Lamps = config.Bind<LampChoice>("Graphics", "Lamps", LampChoice.Game, "Lamps, torches and other point lights. Game: the preset's (real on High and Medium, faked on Low and Lowest). Real: real lights. RealNoShadows: real lights that cast no shadows. Faked: lights painted into a texture (cheaper).");
FpsCounter = config.Bind<bool>("Display", "FpsCounter", false, "Show the frame rate and frame time in the top-right corner (to compare the options).");
InSettingsMenu = config.Bind<bool>("Display", "InSettingsMenu", true, "Add these options to the game's Settings menu, under Graphics. Off: change them here only.");
ShadowMargin = config.Bind<float>("Advanced", "FittedShadowMargin", 15f, "With Fitted, Console or Hard shadows: how far past the farthest ground the camera shows the shadows still reach (in game units). Raise it if shadows vanish at the top of the screen.");
ConfigEntryBase[] graphics = (ConfigEntryBase[])(object)new ConfigEntryBase[4]
{
(ConfigEntryBase)Shadows,
(ConfigEntryBase)WorldResolution,
(ConfigEntryBase)AmbientShading,
(ConfigEntryBase)Lamps
};
PixelSnapping.SettingChanged += delegate
{
Plugin.Log.LogInfo((object)$"Pixel snapping: {PixelSnapping.Value}.");
};
config.SettingChanged += delegate(object sender, SettingChangedEventArgs args)
{
if (Array.IndexOf(graphics, args.ChangedSetting) >= 0)
{
PerfSettings.Changed?.Invoke();
}
};
Menu = new MenuOption[6]
{
Choice<ShadowChoice>("Shadows", "Shadows", Shadows, new string[5] { "Game", "Fitted", "Console", "Hard", "Off" }),
Choice<RenderChoice>("WorldResolution", "World resolution", WorldResolution, new string[3] { "Game", "Full", "Pixel art" }),
Choice<SnapChoice>("PixelSnapping", "Pixel snapping", PixelSnapping, new string[2] { "Game", "Off" }),
Choice<ShadingChoice>("AmbientShading", "Ambient shading", AmbientShading, new string[4] { "Game", "Half res", "Low", "Off" }),
Choice<LampChoice>("Lamps", "Lamps", Lamps, new string[4] { "Game", "Real", "No shadows", "Faked" }),
new MenuOption
{
Key = "FpsCounter",
Header = "FPS counter",
Labels = new string[2] { "Off", "On" },
Get = () => FpsCounter.Value ? 1 : 0,
Set = delegate(int i)
{
FpsCounter.Value = i == 1;
}
}
};
}
public static string Describe()
{
return $"Shadows {Shadows.Value}, world resolution {WorldResolution.Value}, pixel snapping {PixelSnapping.Value}, ambient shading {AmbientShading.Value}, lamps {Lamps.Value}.";
}
private static MenuOption Choice<T>(string key, string header, ConfigEntry<T> entry, params string[] labels) where T : struct, Enum
{
return new MenuOption
{
Key = key,
Header = header,
Labels = labels,
Get = () => Convert.ToInt32(entry.Value),
Set = delegate(int i)
{
entry.Value = (T)Enum.ToObject(typeof(T), i);
}
};
}
}
[BepInPlugin("com.gk2perf.performance", "GK2 Performance", "0.1.4")]
public class Plugin : BaseUnityPlugin
{
public const string Guid = "com.gk2perf.performance";
public const string Name = "GK2 Performance";
public const string Version = "0.1.4";
internal static ManualLogSource Log;
private void Awake()
{
//IL_001b: Unknown result type (might be due to invalid IL or missing references)
//IL_0039: Unknown result type (might be due to invalid IL or missing references)
//IL_003e: Unknown result type (might be due to invalid IL or missing references)
//IL_0046: Unknown result type (might be due to invalid IL or missing references)
//IL_004c: Expected O, but got Unknown
Log = ((BaseUnityPlugin)this).Logger;
PerfSettings.Bind(((BaseUnityPlugin)this).Config);
new Harmony("com.gk2perf.performance").PatchAll(typeof(Plugin).Assembly);
GameObject val = new GameObject("GK2Perf")
{
hideFlags = (HideFlags)61
};
Object.DontDestroyOnLoad((Object)val);
val.AddComponent<PerfRunner>();
Log.LogInfo((object)("GK2 Performance 0.1.4 loaded. " + PerfSettings.Describe()));
}
}
internal static class Report
{
private static float dueAt = -1f;
public static void Soon()
{
dueAt = Time.unscaledTime + 1f;
}
public static void Tick()
{
if (dueAt < 0f || Time.unscaledTime < dueAt)
{
return;
}
dueAt = -1f;
try
{
Plugin.Log.LogInfo((object)Describe());
}
catch (Exception ex)
{
Plugin.Log.LogDebug((object)("Describing the graphics failed: " + ex.Message));
}
}
private static string Describe()
{
//IL_0028: 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_004a: 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)
//IL_008a: Unknown result type (might be due to invalid IL or missing references)
//IL_01c1: Unknown result type (might be due to invalid IL or missing references)
//IL_00f2: Unknown result type (might be due to invalid IL or missing references)
//IL_0332: Unknown result type (might be due to invalid IL or missing references)
//IL_0338: Invalid comparison between Unknown and I4
//IL_03c2: Unknown result type (might be due to invalid IL or missing references)
//IL_040c: Unknown result type (might be due to invalid IL or missing references)
//IL_044d: Unknown result type (might be due to invalid IL or missing references)
//IL_0163: Unknown result type (might be due to invalid IL or missing references)
//IL_034b: Unknown result type (might be due to invalid IL or missing references)
//IL_02f2: 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)
PlatformFeatureEntry current = PlatformFeatures.Current;
GameSettings instance = GameSettings.Instance;
string text = ((instance != null) ? ((object)Unsafe.As<GraphicsTier, GraphicsTier>(ref instance.graphicsTier)/*cast due to .constrained prefix*/).ToString() : "?");
string text2;
if ((int)QualitySettings.shadows == 0)
{
text2 = "off";
}
else
{
text2 = $"{current.shadowMode} ({PlatformFeatures.GetActiveUnityShadowPreset()}): distance {QualitySettings.shadowDistance:0}, " + $"cascades {QualitySettings.shadowCascades}, {QualitySettings.shadows}, resolution {QualitySettings.shadowResolution}, pixel lights {QualitySettings.pixelLightCount}";
LightsSystem instance2 = LightsSystem.Instance;
Light val = (((Object)(object)instance2 != (Object)null) ? instance2.SunLight : null);
NGSS_Directional val2 = (((Object)(object)val != (Object)null) ? ((Component)val).GetComponent<NGSS_Directional>() : null);
if ((Object)(object)val != (Object)null)
{
text2 += $"; sun {val.shadows}, custom map {val.shadowCustomResolution}";
}
if ((Object)(object)val2 != (Object)null && ((Behaviour)val2).enabled)
{
text2 += $"; NGSS samples {val2.NGSS_SAMPLING_TEST}/{val2.NGSS_SAMPLING_FILTER}, PCSS {val2.NGSS_PCSS_ENABLED}, map {val2.NGSS_SHADOWS_RESOLUTION}";
}
}
string text3 = "?";
string text4 = "?";
CameraSystem instance3 = CameraSystem.Instance;
MainCamera val3 = (((Object)(object)instance3 != (Object)null) ? instance3.MainCamera : null);
if ((Object)(object)val3 != (Object)null)
{
Camera camera = val3.Camera;
text3 = $"{val3.GetRenderType()}";
if ((Object)(object)val3.RenderTexture != (Object)null)
{
text3 += $" {((Texture)val3.RenderTexture).width}x{((Texture)val3.RenderTexture).height}";
}
text3 += $" on {Screen.width}x{Screen.height} (pixel size {ResolutionConfig.PixelSize}";
if ((Object)(object)camera != (Object)null)
{
text3 += $", view {camera.orthographicSize * 2f * camera.aspect:0.0}x{camera.orthographicSize * 2f:0.0}, clip {camera.nearClipPlane:0.##}-{camera.farClipPlane:0}";
}
text3 += ")";
HBAO component = ((Component)val3).GetComponent<HBAO>();
text4 = (((Object)(object)component == (Object)null) ? "none" : (((Behaviour)component).enabled ? $"{component.GetQuality()} at {component.GetResolution()} resolution" : "off"));
}
int num = 0;
int num2 = 0;
Light[] array = Object.FindObjectsByType<Light>((FindObjectsSortMode)0);
foreach (Light val4 in array)
{
if ((int)val4.type != 1 && ((Behaviour)val4).isActiveAndEnabled)
{
num++;
if ((int)val4.shadows != 0)
{
num2++;
}
}
}
return "In effect (Graphics preset " + text + "; ours: " + PerfSettings.Describe() + ")\n Shadows: " + text2 + "\n World: " + text3 + "\n Ambient shading: " + text4 + "\n" + $" Lamps: {current.pointLightMode}, {num} lit, {num2} with shadows\n" + " Motion: " + MotionCheck.Describe() + "\n" + $" Water {current.waterTier}, post-processing {current.postProcessing}, frame cap {Application.targetFrameRate}, vsync {QualitySettings.vSyncCount}, " + $"graphics {SystemInfo.graphicsDeviceType} on {SystemInfo.graphicsDeviceName}";
}
}
internal static class SettingsMenu
{
private const string RowPrefix = "GK2Perf ";
private const float ScreenShare = 0.94f;
private static readonly FieldRef<UIGameSettingsWindow, UISwitchButton> GraphicsButton = AccessTools.FieldRefAccess<UIGameSettingsWindow, UISwitchButton>("graphicsTierButton");
private static readonly FieldRef<UIGameSettingsWindow, UISwitchButton> FpsButton = AccessTools.FieldRefAccess<UIGameSettingsWindow, UISwitchButton>("fpsLockButton");
private static readonly FieldRef<UISwitchButton, TextMeshProUGUI> HeaderLabel = AccessTools.FieldRefAccess<UISwitchButton, TextMeshProUGUI>("headerLabel");
private static readonly FieldRef<UISwitchButton, TextMeshProUGUI> AmountLabel = AccessTools.FieldRefAccess<UISwitchButton, TextMeshProUGUI>("amountLabel");
private static readonly FieldRef<UISwitchButton, GamepadNavigationItem> NavigationItem = AccessTools.FieldRefAccess<UISwitchButton, GamepadNavigationItem>("gamepadNavigationItem");
private static readonly Dictionary<int, Vector3> ownScales = new Dictionary<int, Vector3>();
public static void Build(UIGameSettingsWindow window)
{
if (!PerfSettings.InSettingsMenu.Value)
{
return;
}
UISwitchButton val = GraphicsButton.Invoke(window) ?? FpsButton.Invoke(window);
if ((Object)(object)val == (Object)null)
{
Plugin.Log.LogWarning((object)"The Settings window has no Graphics switch to copy: the options are in the config file only.");
return;
}
Transform val2 = RowOf(val, ((Component)window).transform);
Transform parent = val2.parent;
int num = val2.GetSiblingIndex();
(GameKey[], GameKey[]) tuple = (Traverse.Create(typeof(UIGameSettingsWindow)).Field("decreaseKeys").GetValue<GameKey[]>(), Traverse.Create(typeof(UIGameSettingsWindow)).Field("increaseKeys").GetValue<GameKey[]>());
MenuOption[] menu = PerfSettings.Menu;
foreach (MenuOption menuOption in menu)
{
Transform val3 = parent.Find("GK2Perf " + menuOption.Key);
GameObject val4 = (((Object)(object)val3 != (Object)null) ? ((Component)val3).gameObject : Object.Instantiate<GameObject>(((Component)val2).gameObject, parent, false));
((Object)val4).name = "GK2Perf " + menuOption.Key;
val4.transform.SetSiblingIndex(++num);
val4.SetActive(true);
LocalizedLabel[] componentsInChildren = val4.GetComponentsInChildren<LocalizedLabel>(true);
for (int j = 0; j < componentsInChildren.Length; j++)
{
componentsInChildren[j].IgnoreLocalize = true;
}
UISwitchButton button = val4.GetComponentInChildren<UISwitchButton>(true);
GamepadNavigationItem val5 = NavigationItem.Invoke(button);
if ((Object)(object)val5 != (Object)null)
{
val5.ResetCustomDirections();
}
MenuOption chosen = menuOption;
button.Initialize((Action<int>)delegate(int obj)
{
chosen.Set(obj);
}, chosen.Labels, chosen.Get(), chosen.Header, tuple.Item1, tuple.Item2, false);
TextMeshProUGUI val6 = HeaderLabel.Invoke(button) ?? ((IEnumerable<TextMeshProUGUI>)val4.GetComponentsInChildren<TextMeshProUGUI>(true)).FirstOrDefault((Func<TextMeshProUGUI, bool>)((TextMeshProUGUI t) => (Object)(object)t != (Object)(object)AmountLabel.Invoke(button)));
if ((Object)(object)val6 != (Object)null)
{
((TMP_Text)val6).text = chosen.Header;
}
}
Plugin.Log.LogInfo((object)$"Added {PerfSettings.Menu.Length} options to the Settings window (copies of '{Path(val2, ((Component)window).transform)}', {((Component)val2).GetComponentsInChildren<Selectable>(true).Length} controls each).");
}
public static void Opened(UIGameSettingsWindow window)
{
if (!PerfSettings.InSettingsMenu.Value)
{
return;
}
UISwitchButton val = GraphicsButton.Invoke(window) ?? FpsButton.Invoke(window);
if ((Object)(object)val == (Object)null)
{
return;
}
Transform parent = RowOf(val, ((Component)window).transform).parent;
MenuOption[] menu = PerfSettings.Menu;
foreach (MenuOption menuOption in menu)
{
Transform val2 = parent.Find("GK2Perf " + menuOption.Key);
UISwitchButton val3 = (((Object)(object)val2 != (Object)null) ? ((Component)val2).GetComponentInChildren<UISwitchButton>(true) : null);
if ((Object)(object)val3 != (Object)null && val3.CurrentFieldIndex != menuOption.Get())
{
val3.UpdateField(menuOption.Get(), false);
}
}
PerfRunner instance = PerfRunner.Instance;
if (instance != null)
{
((MonoBehaviour)instance).StartCoroutine(FitOnScreen(window, parent));
}
}
private static IEnumerator FitOnScreen(UIGameSettingsWindow window, Transform rows)
{
yield return null;
if ((Object)(object)window == (Object)null || !((Behaviour)window).isActiveAndEnabled || (Object)(object)rows == (Object)null)
{
yield break;
}
Canvas componentInParent = ((Component)window).GetComponentInParent<Canvas>();
RectTransform val = (RectTransform)(((Object)(object)componentInParent != (Object)null) ? /*isinst with value type is only supported in some contexts*/: null);
if ((Object)(object)val == (Object)null)
{
yield break;
}
Rect rect = val.rect;
float height = ((Rect)(ref rect)).height;
LayoutRebuilder.ForceRebuildLayoutImmediate((RectTransform)((Component)window).transform);
RectTransform val2 = null;
Transform val3 = rows;
while ((Object)(object)val3 != (Object)null && (Object)(object)val3 != (Object)(object)((Component)window).transform)
{
RectTransform val4 = (RectTransform)(object)((val3 is RectTransform) ? val3 : null);
if (val4 != null && HeightOnScreen(val4, val) < height * 0.99f)
{
val2 = val4;
}
val3 = val3.parent;
}
if (!((Object)(object)val2 == (Object)null))
{
int instanceID = ((Object)val2).GetInstanceID();
if (!ownScales.TryGetValue(instanceID, out var value))
{
value = ((Transform)val2).localScale;
ownScales[instanceID] = value;
}
((Transform)val2).localScale = value;
float num = HeightOnScreen(val2, val);
float num2 = height * 0.94f;
if (num > num2)
{
float num3 = num2 / num;
((Transform)val2).localScale = value * num3;
Plugin.Log.LogInfo((object)$"The Settings panel ({num:0} of {height:0} high) shrunk to {num3:0.00} to fit the screen.");
}
}
}
private static float HeightOnScreen(RectTransform rect, RectTransform canvasRect)
{
//IL_0011: Unknown result type (might be due to invalid IL or missing references)
//IL_0016: 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_0028: Unknown result type (might be due to invalid IL or missing references)
Vector3[] array = (Vector3[])(object)new Vector3[4];
rect.GetWorldCorners(array);
return ((Transform)canvasRect).InverseTransformPoint(array[1]).y - ((Transform)canvasRect).InverseTransformPoint(array[0]).y;
}
private static Transform RowOf(UISwitchButton button, Transform window)
{
TextMeshProUGUI val = HeaderLabel.Invoke(button);
Transform val2 = ((Component)button).transform;
if ((Object)(object)val == (Object)null || ((TMP_Text)val).transform.IsChildOf(val2))
{
return val2;
}
while ((Object)(object)val2.parent != (Object)null && (Object)(object)val2.parent != (Object)(object)window && !((TMP_Text)val).transform.IsChildOf(val2))
{
val2 = val2.parent;
}
if (!((TMP_Text)val).transform.IsChildOf(val2) || ((Component)val2).GetComponentsInChildren<UISwitchButton>(true).Length != 1)
{
Plugin.Log.LogWarning((object)"The Graphics switch's header isn't in its row: copying the switch alone.");
return ((Component)button).transform;
}
return val2;
}
private static string Path(Transform t, Transform root)
{
string text = ((Object)t).name;
Transform parent = t.parent;
while ((Object)(object)parent != (Object)null && (Object)(object)parent != (Object)(object)root)
{
text = ((Object)parent).name + "/" + text;
parent = parent.parent;
}
return text;
}
}
[HarmonyPatch(typeof(UIGameSettingsWindow), "Init")]
internal static class AddSettingsRows
{
private static void Postfix(UIGameSettingsWindow __instance)
{
try
{
SettingsMenu.Build(__instance);
}
catch (Exception arg)
{
Plugin.Log.LogError((object)$"Adding the options to the Settings window failed: {arg}");
}
}
}
[HarmonyPatch(typeof(UIGameSettingsWindow), "Open", new Type[] { typeof(LazyWidgetDataBase) })]
internal static class ShowSettingsRows
{
private static void Postfix(UIGameSettingsWindow __instance)
{
try
{
SettingsMenu.Opened(__instance);
}
catch (Exception arg)
{
Plugin.Log.LogError((object)$"Showing the options in the Settings window failed: {arg}");
}
}
}
internal static class ShadowFit
{
private const float CheckSeconds = 0.25f;
private const float MinDistance = 30f;
private const float MaxDistance = 600f;
private const float LowerGround = 6f;
private static readonly Vector3[] Corners = (Vector3[])(object)new Vector3[4]
{
new Vector3(0f, 0f, 0f),
new Vector3(1f, 0f, 0f),
new Vector3(0f, 1f, 0f),
new Vector3(1f, 1f, 0f)
};
private static float nextCheck;
private static float nextLookup;
private static CameraSystem cameras;
private static int logged;
public static float Distance { get; private set; } = 150f;
public static void Tick()
{
//IL_00f2: Unknown result type (might be due to invalid IL or missing references)
if (!Tuning.FitsShadows || Time.unscaledTime < nextCheck)
{
return;
}
nextCheck = Time.unscaledTime + 0.25f;
float? num;
try
{
num = Measure();
}
catch (Exception ex)
{
Plugin.Log.LogDebug((object)("Measuring the camera's view failed: " + ex.Message));
cameras = null;
return;
}
if (num.HasValue)
{
float num2 = Mathf.Clamp(Mathf.Ceil((num.Value + PerfSettings.ShadowMargin.Value) / 10f) * 10f, 30f, 600f);
if (num2 > Distance || num2 < Distance - 30f)
{
if (logged < 20)
{
logged++;
Plugin.Log.LogInfo((object)$"Shadow range fitted to the camera: {Distance:0} -> {num2:0} (farthest ground {num.Value:0.0}).");
}
Distance = num2;
}
}
if ((int)QualitySettings.shadows != 0 && (Mathf.Abs(QualitySettings.shadowDistance - Distance) > 0.5f || QualitySettings.shadowCascades > 1))
{
Tuning.AfterShadowsApplied();
}
}
private static float? Measure()
{
//IL_002e: 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)
//IL_0051: Unknown result type (might be due to invalid IL or missing references)
//IL_0072: Unknown result type (might be due to invalid IL or missing references)
//IL_0077: 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_007c: 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_0085: Unknown result type (might be due to invalid IL or missing references)
//IL_00a1: Unknown result type (might be due to invalid IL or missing references)
//IL_00a7: Unknown result type (might be due to invalid IL or missing references)
//IL_00ac: 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)
Camera val = WorldCamera();
if ((Object)(object)val == (Object)null || !((Behaviour)val).isActiveAndEnabled)
{
return null;
}
Transform transform = ((Component)val).transform;
float num = cameras.CameraGroundPos.y - 6f;
Plane val2 = default(Plane);
((Plane)(ref val2))..ctor(Vector3.up, new Vector3(0f, num, 0f));
float num2 = 0f;
Vector3[] corners = Corners;
float num3 = default(float);
foreach (Vector3 val3 in corners)
{
Ray val4 = val.ViewportPointToRay(val3);
if (!((Plane)(ref val2)).Raycast(val4, ref num3))
{
return 600f;
}
num2 = Mathf.Max(num2, Vector3.Dot(((Ray)(ref val4)).GetPoint(num3) - transform.position, transform.forward));
}
return num2;
}
private static Camera WorldCamera()
{
if ((Object)(object)cameras == (Object)null)
{
if (Time.unscaledTime < nextLookup)
{
return null;
}
nextLookup = Time.unscaledTime + 2f;
cameras = CameraSystem.Instance;
if ((Object)(object)cameras == (Object)null)
{
return null;
}
}
MainCamera mainCamera = cameras.MainCamera;
if (!((Object)(object)mainCamera != (Object)null))
{
return null;
}
return mainCamera.Camera;
}
}
internal static class Snapping
{
public static bool Off => PerfSettings.PixelSnapping.Value == SnapChoice.Off;
}
[HarmonyPatch(typeof(CameraController), "GetRoundedCameraPosition")]
internal static class SmoothCamera
{
private static readonly FieldRef<bool> CanMoveBySubpixel = AccessTools.StaticFieldRefAccess<bool>(AccessTools.Field(typeof(CameraController), "canMoveBySubpixel"));
private static readonly FieldRef<bool> SubpixelPosition = AccessTools.StaticFieldRefAccess<bool>(AccessTools.Field(typeof(CameraController), "subpixelPosition"));
private static readonly int SubOffset = Shader.PropertyToID("_CameraSubOffset");
private static readonly int Offset = Shader.PropertyToID("_CameraOffset");
private static bool Prefix(Vector3 position, bool writeOffsetToShader, ref Vector3 __result)
{
//IL_0016: Unknown result type (might be due to invalid IL or missing references)
//IL_0019: Unknown result type (might be due to invalid IL or missing references)
//IL_001e: 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_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_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_003c: 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)
//IL_005b: Unknown result type (might be due to invalid IL or missing references)
//IL_0054: Unknown result type (might be due to invalid IL or missing references)
//IL_005c: 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_006e: 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)
if (!Snapping.Off || !CanMoveBySubpixel.Invoke())
{
return true;
}
Vector3 roundedPosXYZ = VisualConsts.GetRoundedPosXYZ(position, 2, 1);
Vector3 val = Vector3.Scale(position - roundedPosXYZ, VisualConsts.XYZ_STEP_INV) * ((float)ResolutionConfig.PixelSize / 2f);
Shader.SetGlobalVector(SubOffset, Vector4.op_Implicit(SubpixelPosition.Invoke() ? val : Vector3.zero));
if (writeOffsetToShader)
{
Shader.SetGlobalVector(Offset, Vector4.op_Implicit(val));
}
__result = position;
return false;
}
}
[HarmonyPatch(typeof(PlayerView), "LateUpdate")]
internal static class SmoothPlayer
{
private static readonly FieldRef<PlayerView, int> RoundingSize = AccessTools.FieldRefAccess<PlayerView, int>("pixelSizeForPosRounding");
private static bool Prefix(PlayerView __instance)
{
//IL_0036: Unknown result type (might be due to invalid IL or missing references)
if (!Snapping.Off || RoundingSize.Invoke(__instance) != 1)
{
return true;
}
Transform parent = ((Component)__instance).transform.parent;
if ((Object)(object)parent == (Object)null)
{
return true;
}
((Component)__instance).transform.position = parent.position;
return false;
}
}
internal static class Tuning
{
private static readonly Dictionary<int, Resolution> hbaoResolutions = new Dictionary<int, Resolution>();
public static bool FitsShadows
{
get
{
ShadowChoice value = PerfSettings.Shadows.Value;
if (value != ShadowChoice.Fitted && value != ShadowChoice.Console)
{
return value == ShadowChoice.Hard;
}
return true;
}
}
public static PlatformFeatureEntry Override(PlatformFeatureEntry entry, PlatformFeatureEntry baseEntry)
{
//IL_0004: Unknown result type (might be due to invalid IL or missing references)
//IL_0049: 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_0059: 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_0069: Unknown result type (might be due to invalid IL or missing references)
//IL_0072: 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)
//IL_0097: Unknown result type (might be due to invalid IL or missing references)
//IL_009e: Unknown result type (might be due to invalid IL or missing references)
//IL_00ba: Unknown result type (might be due to invalid IL or missing references)
//IL_00c3: Unknown result type (might be due to invalid IL or missing references)
//IL_00e4: Unknown result type (might be due to invalid IL or missing references)
//IL_00ed: Unknown result type (might be due to invalid IL or missing references)
if (entry == null || (int)entry.platform != 0 || !PerfSettings.AnyOverride)
{
return entry;
}
PlatformFeatureEntry val = ((entry == baseEntry) ? entry.Clone() : entry);
switch (PerfSettings.Shadows.Value)
{
case ShadowChoice.Fitted:
val.shadowMode = (PlatformShadowMode)1;
break;
case ShadowChoice.Console:
val.shadowMode = (PlatformShadowMode)2;
val.unityShadowPreset = (PlatformUnityShadowPreset)6;
break;
case ShadowChoice.Hard:
val.shadowMode = (PlatformShadowMode)2;
val.unityShadowPreset = (PlatformUnityShadowPreset)1;
break;
case ShadowChoice.Off:
val.shadowMode = (PlatformShadowMode)0;
break;
}
switch (PerfSettings.WorldResolution.Value)
{
case RenderChoice.Full:
val.renderMode = (PlatformRenderMode)0;
break;
case RenderChoice.PixelArt:
val.renderMode = (PlatformRenderMode)1;
val.waterTier = (PlatformWaterTier)2;
break;
}
switch (PerfSettings.AmbientShading.Value)
{
case ShadingChoice.Low:
val.hbaoQuality = (PlatformHBAOQuality)1;
break;
case ShadingChoice.Off:
val.hbaoQuality = (PlatformHBAOQuality)0;
break;
}
switch (PerfSettings.Lamps.Value)
{
case LampChoice.Real:
case LampChoice.RealNoShadows:
val.pointLightMode = (PlatformPointLightMode)0;
break;
case LampChoice.Faked:
val.pointLightMode = (PlatformPointLightMode)1;
break;
}
return val;
}
public static void AfterShadowsApplied()
{
//IL_0007: Unknown result type (might be due to invalid IL or missing references)
if (FitsShadows && (int)QualitySettings.shadows != 0)
{
QualitySettings.shadowCascades = 0;
QualitySettings.shadowDistance = ShadowFit.Distance;
RefreshNgss();
}
}
public static void RefreshNgss()
{
LightsSystem instance = LightsSystem.Instance;
Light val = (((Object)(object)instance != (Object)null) ? instance.SunLight : null);
NGSS_Directional val2 = (((Object)(object)val != (Object)null) ? ((Component)val).GetComponent<NGSS_Directional>() : null);
if ((Object)(object)val2 == (Object)null || !((Behaviour)val2).isActiveAndEnabled || !val2.NGSS_NO_UPDATE_ON_PLAY)
{
return;
}
try
{
val2.UpdateParameters();
}
catch (Exception ex)
{
Plugin.Log.LogDebug((object)("Refreshing NGSS failed: " + ex.Message));
}
}
public static void AfterHbaoApplied()
{
//IL_004d: 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: Unknown result type (might be due to invalid IL or missing references)
//IL_007c: 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)
//IL_0077: 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)
CameraSystem instance = CameraSystem.Instance;
MainCamera val = (((Object)(object)instance != (Object)null) ? instance.MainCamera : null);
HBAO val2 = (((Object)(object)val != (Object)null) ? ((Component)val).GetComponent<HBAO>() : null);
if (!((Object)(object)val2 == (Object)null))
{
int instanceID = ((Object)val2).GetInstanceID();
if (!hbaoResolutions.TryGetValue(instanceID, out var value))
{
value = val2.GetResolution();
hbaoResolutions[instanceID] = value;
}
ShadingChoice value2 = PerfSettings.AmbientShading.Value;
Resolution val3 = (Resolution)((value2 == ShadingChoice.HalfResolution || value2 == ShadingChoice.Low) ? 1 : ((int)value));
if (val2.GetResolution() != val3)
{
val2.SetResolution(val3);
}
}
}
public static void Reapply()
{
if (GameSettings.Instance == null)
{
return;
}
try
{
PlatformFeatures.ReapplyAll();
Plugin.Log.LogInfo((object)("Applied: " + PerfSettings.Describe()));
Report.Soon();
}
catch (Exception arg)
{
Plugin.Log.LogError((object)$"Applying the graphics options failed: {arg}");
}
}
}
[HarmonyPatch(typeof(GraphicsTierConfig), "ApplyTier")]
internal static class TierOverrides
{
private static void Postfix(PlatformFeatureEntry baseEntry, ref PlatformFeatureEntry __result)
{
try
{
__result = Tuning.Override(__result, baseEntry);
}
catch (Exception arg)
{
Plugin.Log.LogError((object)$"Overriding the graphics preset failed: {arg}");
}
}
}
[HarmonyPatch(typeof(PlatformFeatures), "ApplyShadowSettings")]
internal static class FittedShadows
{
private static void Postfix()
{
try
{
Tuning.AfterShadowsApplied();
}
catch (Exception arg)
{
Plugin.Log.LogError((object)$"Fitting the shadows failed: {arg}");
}
}
}
[HarmonyPatch(typeof(PlatformFeatures), "ApplyHBAO")]
internal static class HbaoResolution
{
private static void Postfix()
{
try
{
Tuning.AfterHbaoApplied();
}
catch (Exception arg)
{
Plugin.Log.LogError((object)$"Setting the ambient shading resolution failed: {arg}");
}
}
}
[HarmonyPatch(typeof(SwitchLightPolicy), "ApplyLocalLightShadowPolicy")]
internal static class LampShadows
{
private static bool Prefix(Light light)
{
//IL_0017: Unknown result type (might be due to invalid IL or missing references)
//IL_001d: Invalid comparison between Unknown and I4
//IL_0022: Unknown result type (might be due to invalid IL or missing references)
if (PerfSettings.Lamps.Value != LampChoice.RealNoShadows || (Object)(object)light == (Object)null || (int)light.type == 1)
{
return true;
}
if ((int)light.shadows != 0)
{
light.shadows = (LightShadows)0;
}
return false;
}
}
}