-
-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathAISomniumFiles2Fix.cs
199 lines (182 loc) · 8.91 KB
/
AISomniumFiles2Fix.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
using MelonLoader;
using HarmonyLib;
using UnityEngine;
using UnityEngine.UI;
[assembly: MelonInfo(typeof(AISomniumFiles2Mod.AISomniumFiles2Fix), "AI: Somnium Files 2", "1.0.6", "Lyall")]
[assembly: MelonGame("SpikeChunsoft", "AI_TheSomniumFiles2")]
namespace AISomniumFiles2Mod
{
public class AISomniumFiles2Fix : MelonMod
{
public static MelonPreferences_Category Fixes;
public static MelonPreferences_Entry<int> DesiredResolutionX;
public static MelonPreferences_Entry<int> DesiredResolutionY;
public static MelonPreferences_Entry<bool> Fullscreen;
public static MelonPreferences_Entry<bool> UIFix;
public static MelonPreferences_Entry<bool> IncreaseQuality;
public static MelonPreferences_Entry<bool> bDisableMouseCursor;
public override void OnApplicationStart()
{
LoggerInstance.Msg("Application started.");
Fixes = MelonPreferences.CreateCategory("AISomnium2Fix");
Fixes.SetFilePath("Mods/AISomnium2Fix.cfg");
DesiredResolutionX = Fixes.CreateEntry("Resolution_Width", Display.main.systemWidth, "", "Custom resolution width"); // Set default to something safe
DesiredResolutionY = Fixes.CreateEntry("Resolution_Height", Display.main.systemHeight, "", "Custom resolution height"); // Set default to something safe
Fullscreen = Fixes.CreateEntry("Fullscreen", true, "", "Set to true for fullscreen or false for windowed");
UIFix = Fixes.CreateEntry("UI_Fixes", true, "", "Fixes UI issues at ultrawide/wider");
IncreaseQuality = Fixes.CreateEntry("IncreaseQuality", true, "", "Increase graphical quality."); //
bDisableMouseCursor = Fixes.CreateEntry("DIsableMouseCursor", true, "", "Set to true to force the mouse cursor to be invisible.");
}
[HarmonyPatch]
public class CustomResolution
{
[HarmonyPatch(typeof(Game.LauncherArgs), nameof(Game.LauncherArgs.OnRuntimeMethodLoad))]
[HarmonyPostfix]
public static void SetResolution()
{
if (!Fullscreen.Value)
{
Screen.SetResolution(DesiredResolutionX.Value, DesiredResolutionY.Value, FullScreenMode.Windowed);
}
else
{
Screen.SetResolution(DesiredResolutionX.Value, DesiredResolutionY.Value, FullScreenMode.FullScreenWindow);
}
MelonLogger.Msg($"Screen resolution set to {DesiredResolutionX.Value}x{DesiredResolutionY.Value}, Fullscreen = {Fullscreen.Value}");
}
}
[HarmonyPatch]
public class UIFixes
{
public static float NativeAspectRatio = (float)16 / 9;
public static float NewAspectRatio = (float)DesiredResolutionX.Value / DesiredResolutionY.Value;
public static float AspectMultiplier = NewAspectRatio / NativeAspectRatio;
// Set screen match mode when object has CanvasScaler enabled
[HarmonyPatch(typeof(CanvasScaler), "OnEnable")]
[HarmonyPostfix]
public static void SetScreenMatchMode(CanvasScaler __instance)
{
if (NewAspectRatio > NativeAspectRatio && UIFix.Value)
{
__instance.m_ScreenMatchMode = CanvasScaler.ScreenMatchMode.Expand;
}
}
// Fix letterboxing to span screen
[HarmonyPatch(typeof(Game.CinemaScope), "Show")]
[HarmonyPostfix]
public static void LetterboxFix()
{
if (NewAspectRatio > NativeAspectRatio && UIFix.Value)
{
var GameObjects = GameObject.FindObjectsOfType<Game.CinemaScope>();
foreach (var GameObject in GameObjects)
{
GameObject.transform.localScale = new Vector3(1 * AspectMultiplier, 1f, 1f);
}
MelonLogger.Msg("Letterboxing spanned.");
}
}
// Fix filters to span screen
// This is jank but I can't think of a better solution right now.
[HarmonyPatch(typeof(Game.FilterController), "Black")]
[HarmonyPatch(typeof(Game.FilterController), "FadeIn")]
[HarmonyPatch(typeof(Game.FilterController), "FadeInWait")]
[HarmonyPatch(typeof(Game.FilterController), "FadeOut")]
[HarmonyPatch(typeof(Game.FilterController), "FadeOutWait")]
[HarmonyPatch(typeof(Game.FilterController), "Flash")]
[HarmonyPatch(typeof(Game.FilterController), "Set")]
[HarmonyPatch(typeof(Game.FilterController), "SetValue")]
[HarmonyPostfix]
public static void FilterFix()
{
if (NewAspectRatio > NativeAspectRatio && UIFix.Value)
{
var GameObjects = GameObject.FindObjectsOfType<Game.FilterController>();
foreach (var GameObject in GameObjects)
{
GameObject.transform.localScale = new Vector3(1 * AspectMultiplier, 1f, 1f);
}
// Log spam
//MelonLogger.Msg("Filter spanned.");
}
}
// Fix eye fade filter
[HarmonyPatch(typeof(Game.EyeFadeFilter), "FadeIn")]
[HarmonyPatch(typeof(Game.EyeFadeFilter), "FadeInWait")]
[HarmonyPatch(typeof(Game.EyeFadeFilter), "FadeOut")]
[HarmonyPatch(typeof(Game.EyeFadeFilter), "FadeOutWait")]
[HarmonyPostfix]
public static void EyeFadeFilterFix()
{
if (NewAspectRatio > NativeAspectRatio && UIFix.Value)
{
var GameObjects = GameObject.FindObjectsOfType<Game.EyeFadeFilter>();
foreach (var GameObject in GameObjects)
{
GameObject.transform.localScale = new Vector3(1 * AspectMultiplier, 1f, 1f);
}
// Log spam
//MelonLogger.Msg("EyeFade filter spanned.");
}
}
// Scale cutscene viewport when video plays
[HarmonyPatch(typeof(Game.VideoController), nameof(Game.VideoController.Prepare))]
[HarmonyPostfix]
public static void FixCutsceneViewport(Game.VideoController __instance)
{
if (NewAspectRatio > NativeAspectRatio)
{
var cutsceneImage = __instance.world.Image;
cutsceneImage.transform.localScale = new Vector3(1 / AspectMultiplier, 1f, 1f);
MelonLogger.Msg("Cutscene viewport scaled horizontally.");
}
}
// Reset cutscene viewport after video ends
[HarmonyPatch(typeof(Game.VideoController), nameof(Game.VideoController.Stop))]
[HarmonyPostfix]
public static void ResetCutsceneViewport(Game.VideoController __instance)
{
if (NewAspectRatio > NativeAspectRatio)
{
var cutsceneImage = __instance.world.Image;
cutsceneImage.transform.localScale = new Vector3(1f, 1f, 1f);
MelonLogger.Msg("Cutscene viewport scale reset to default.");
}
}
}
[HarmonyPatch]
public class QualityPatches
{
// Enable high-quality SMAA for all cameras
[HarmonyPatch(typeof(Game.CameraController), "OnEnable")]
[HarmonyPostfix]
public static void CameraQualityFix(Game.CameraController __instance)
{
if (IncreaseQuality.Value)
{
var UACD = __instance._camera.GetComponent<UnityEngine.Rendering.Universal.UniversalAdditionalCameraData>();
UACD.antialiasing = UnityEngine.Rendering.Universal.AntialiasingMode.SubpixelMorphologicalAntiAliasing;
UACD.antialiasingQuality = UnityEngine.Rendering.Universal.AntialiasingQuality.High;
MelonLogger.Msg("Camera set to SMAA High.");
}
}
}
[HarmonyPatch]
public class CursorPatches
{
// Mouse cursor visibility
[HarmonyPatch(typeof(UnityEngine.Cursor), nameof(UnityEngine.Cursor.visible), MethodType.Setter)]
[HarmonyPrefix]
public static void CameraQualityFix(UnityEngine.Cursor __instance, ref bool __0)
{
if (bDisableMouseCursor.Value)
{
__0 = false;
// Log Spam
// Seems to set cursor visibility a lot, :|
//MelonLogger.Msg("Forced mouse cursor to be invisible.");
}
}
}
}
}