diff --git a/MuzikaGromche/MuzikaGromche.csproj b/MuzikaGromche/MuzikaGromche.csproj index 0f73454..f6a91f1 100644 --- a/MuzikaGromche/MuzikaGromche.csproj +++ b/MuzikaGromche/MuzikaGromche.csproj @@ -7,6 +7,7 @@ 13.37.1337 true latest + enable $(NoWarn);CS0436 diff --git a/MuzikaGromche/Plugin.cs b/MuzikaGromche/Plugin.cs index 9ca7814..10743a2 100644 --- a/MuzikaGromche/Plugin.cs +++ b/MuzikaGromche/Plugin.cs @@ -27,7 +27,7 @@ namespace MuzikaGromche [LobbyCompatibility(CompatibilityLevel.Everyone, VersionStrictness.Patch)] public class Plugin : BaseUnityPlugin { - internal new static Config Config { get; private set; } = null; + internal new static Config Config { get; private set; } = null!; private static readonly string[] PwnLyricsVariants = [ "", "", "", // make sure the array has enough items to index it without checking @@ -480,8 +480,8 @@ namespace MuzikaGromche return tracks[trackId]; } - public static Track CurrentTrack; - public static BeatTimeState BeatTimeState; + public static Track? CurrentTrack; + public static BeatTimeState? BeatTimeState; public static void SetLightColor(Color color) { @@ -624,16 +624,16 @@ namespace MuzikaGromche public class Track { - public string Name; + public required string Name; // Language of the track's lyrics. - public Language Language; + public required Language Language; // Whether this track has NSFW/explicit lyrics. public bool IsExplicit = false; // Wind-up time can and should be shorter than the Start audio track, // so that the "pop" effect can be baked into the Start audio and kept away // from the looped part. This also means that the light show starts before // the looped track does, so we need to sync them up as soon as we enter the Loop. - public float WindUpTimer; + public required float WindUpTimer; // Estimated number of beats per minute. Not used for light show, but might come in handy. public float Bpm => 60f / (LoadedLoop.length / Beats); @@ -655,11 +655,11 @@ namespace MuzikaGromche // WAV is OK, but takes a lot of space. Try OGGVORBIS instead. public AudioType AudioType = AudioType.MPEG; - public AudioClip LoadedStart; - public AudioClip LoadedLoop; + public AudioClip LoadedStart = null!; + public AudioClip LoadedLoop = null!; // How often this track should be chosen, relative to the sum of weights of all tracks. - public SyncedEntry Weight; + public SyncedEntry Weight = null!; public string FileNameStart => $"{Name}Start.{Ext}"; public string FileNameLoop => $"{Name}Loop.{Ext}"; @@ -743,7 +743,7 @@ namespace MuzikaGromche // In such case, a random number chosen and updated once per loop // is used to select an alternative. // If the chosen alternative is an empty string, lyrics event shall be skipped. - public string[] LyricsLines { get; private set; } + public string[] LyricsLines { get; private set; } = []; public (float, string)[] Lyrics { set @@ -989,7 +989,7 @@ namespace MuzikaGromche private float loopOffsetBeat = float.NegativeInfinity; - private static System.Random lyricsRandom = null; + private static System.Random lyricsRandom = null!; private int lyricsRandomPerLoop; @@ -1140,7 +1140,7 @@ namespace MuzikaGromche return events; } - private SetLightsColorEvent GetColorEvent(BeatTimeSpan loopOffsetSpan, BeatTimestamp windUpOffsetTimestamp) + private SetLightsColorEvent? GetColorEvent(BeatTimeSpan loopOffsetSpan, BeatTimestamp windUpOffsetTimestamp) { if (FadeOut(loopOffsetSpan) is Color c1) { @@ -1403,26 +1403,26 @@ namespace MuzikaGromche public class Config : SyncedConfig2 { - public static ConfigEntry EnableColorAnimations { get; private set; } + public static ConfigEntry EnableColorAnimations { get; private set; } = null!; - public static ConfigEntry DisplayLyrics { get; private set; } + public static ConfigEntry DisplayLyrics { get; private set; } = null!; - public static ConfigEntry AudioOffset { get; private set; } + public static ConfigEntry AudioOffset { get; private set; } = null!; - public static ConfigEntry SkipExplicitTracks { get; private set; } + public static ConfigEntry SkipExplicitTracks { get; private set; } = null!; public static bool ShouldSkipWindingPhase { get; private set; } = false; - public static Palette PaletteOverride { get; private set; } = null; + public static Palette? PaletteOverride { get; private set; } = null; public static float? FadeOutBeatOverride { get; private set; } = null; public static float? FadeOutDurationOverride { get; private set; } = null; - public static float[] FlickerLightsTimeSeriesOverride { get; private set; } = null; - public static float[] LyricsTimeSeriesOverride { get; private set; } = null; + public static float[]? FlickerLightsTimeSeriesOverride { get; private set; } = null; + public static float[]? LyricsTimeSeriesOverride { get; private set; } = null; public static float? BeatsOffsetOverride { get; private set; } = null; public static float? ColorTransitionInOverride { get; private set; } = null; public static float? ColorTransitionOutOverride { get; private set; } = null; - public static string ColorTransitionEasingOverride { get; private set; } = null; + public static string? ColorTransitionEasingOverride { get; private set; } = null; public Config(ConfigFile configFile) : base(PluginInfo.PLUGIN_GUID) { @@ -1559,7 +1559,7 @@ namespace MuzikaGromche const string section = "Palette"; const int maxCustomPaletteSize = 8; // Declare and initialize early to avoid "Use of unassigned local variable" - SyncedEntry customPaletteSizeSyncedEntry = null; + SyncedEntry customPaletteSizeSyncedEntry = null!; var customPaletteSyncedEntries = new SyncedEntry[maxCustomPaletteSize]; var loadButton = new GenericButtonConfigItem(section, "Load Palette from the Current Track", @@ -1623,16 +1623,16 @@ namespace MuzikaGromche const string section = "Timings"; var colorTransitionRange = new AcceptableValueRange(0f, 1f); // Declare and initialize early to avoid "Use of unassigned local variable" - List<(Action Load, Action Apply)> entries = []; - SyncedEntry overrideTimingsSyncedEntry = null; - SyncedEntry fadeOutBeatSyncedEntry = null; - SyncedEntry fadeOutDurationSyncedEntry = null; - SyncedEntry flickerLightsTimeSeriesSyncedEntry = null; - SyncedEntry lyricsTimeSeriesSyncedEntry = null; - SyncedEntry beatsOffsetSyncedEntry = null; - SyncedEntry colorTransitionInSyncedEntry = null; - SyncedEntry colorTransitionOutSyncedEntry = null; - SyncedEntry colorTransitionEasingSyncedEntry = null; + List<(Action Load, Action Apply)> entries = []; + SyncedEntry overrideTimingsSyncedEntry = null!; + SyncedEntry fadeOutBeatSyncedEntry = null!; + SyncedEntry fadeOutDurationSyncedEntry = null!; + SyncedEntry flickerLightsTimeSeriesSyncedEntry = null!; + SyncedEntry lyricsTimeSeriesSyncedEntry = null!; + SyncedEntry beatsOffsetSyncedEntry = null!; + SyncedEntry colorTransitionInSyncedEntry = null!; + SyncedEntry colorTransitionOutSyncedEntry = null!; + SyncedEntry colorTransitionEasingSyncedEntry = null!; var loadButton = new GenericButtonConfigItem(section, "Load Timings from the Current Track", "Override custom timings with the built-in timings of the current track.", "Load", load); @@ -1687,7 +1687,7 @@ namespace MuzikaGromche CSyncHackAddSyncedEntry(syncedEntry); syncedEntry.SyncHostToLocal(); syncedEntry.Changed += (sender, args) => applier(); - void loader(Track track) + void loader(Track? track) { // if track is null, set everything to defaults syncedEntry.LocalValue = track == null ? (T)syncedEntry.Entry.DefaultValue : getter(track); @@ -1697,9 +1697,9 @@ namespace MuzikaGromche void registerStruct(SyncedEntry syncedEntry, Func getter, Action setter) where T : struct => register(syncedEntry, getter, () => setter.Invoke(overrideTimingsSyncedEntry.Value ? syncedEntry.Value : null)); - void registerClass(SyncedEntry syncedEntry, Func getter, Action setter) where T : class => + void registerClass(SyncedEntry syncedEntry, Func getter, Action setter) where T : class => register(syncedEntry, getter, () => setter.Invoke(overrideTimingsSyncedEntry.Value ? syncedEntry.Value : null)); - void registerArray(SyncedEntry syncedEntry, Func getter, Action setter, Func parser, bool sort = false) where T : struct => + void registerArray(SyncedEntry syncedEntry, Func getter, Action setter, Func parser, bool sort = false) where T : struct => register(syncedEntry, (track) => string.Join(", ", getter(track)), () => @@ -1713,7 +1713,7 @@ namespace MuzikaGromche setter.Invoke(overrideTimingsSyncedEntry.Value ? values : null); }); - T[] parseStringArray(string str, Func parser, bool sort = false) where T : struct + T[]? parseStringArray(string str, Func parser, bool sort = false) where T : struct { try { @@ -1838,7 +1838,7 @@ namespace MuzikaGromche __instance.farAudio = __state.farAudio; var time = __instance.farAudio.time; - var delay = Plugin.CurrentTrack.LoadedStart.length - time; + var delay = Plugin.CurrentTrack!.LoadedStart.length - time; // Override screamingSFX with Loop, delayed by the remaining time of the Start audio __instance.creatureVoice.Stop(); @@ -1853,7 +1853,7 @@ namespace MuzikaGromche // Manage the timeline: switch color of the lights according to the current playback/beat position. if (__instance.previousState == 1 || __instance.previousState == 2) { - var events = Plugin.BeatTimeState.Update(start: __instance.farAudio, loop: __instance.creatureVoice); + var events = Plugin.BeatTimeState!.Update(start: __instance.farAudio, loop: __instance.creatureVoice); foreach (var ev in events) { switch (ev) @@ -1906,7 +1906,7 @@ namespace MuzikaGromche internal class State { - public AudioSource farAudio; - public int previousState; + public required AudioSource farAudio; + public required int previousState; } }