using System; using System.Diagnostics; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using BepInEx; using BepInEx.Configuration; using BepInEx.Logging; using HarmonyLib; using TMPro; using Unity.Netcode; using UnityEngine; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")] [assembly: AssemblyVersion("0.0.0.0")] namespace BetterNights; internal static class ClockPatches { [HarmonyPatch(typeof(HUDManager), "SetClock")] [HarmonyPrefix] private static bool SetClock(HUDManager __instance, float timeNormalized, float numberOfHours, bool createNewLine) { if (TimeOfDayPatches.ExtraHours <= 0) { return true; } ((TMP_Text)__instance.clockNumber).text = FormatClock(timeNormalized, numberOfHours, createNewLine); return false; } [HarmonyPatch(typeof(HUDManager), "GetClockTimeFormatted")] [HarmonyPrefix] private static bool GetClockTimeFormatted(float timeNormalized, float numberOfHours, bool createNewLine, ref string __result) { if (TimeOfDayPatches.ExtraHours <= 0) { return true; } __result = FormatClock(timeNormalized, numberOfHours, createNewLine); return false; } private static string FormatClock(float timeNormalized, float numberOfHours, bool createNewLine) { int num = (int)(timeNormalized * (60f * numberOfHours)) + 360; if (num < 0) { num = 0; } int num2 = num / 60 % 24; int num3 = num % 60; int num4 = num2 % 12; if (num4 == 0) { num4 = 12; } string text = (createNewLine ? "\n" : " "); return $"{num4:00}:{num3:00}".TrimStart('0') + text + ((num2 < 12) ? "AM" : "PM"); } internal static string DescribeEndOfDay(int extraHours) { if (extraHours > 0) { return $"{extraHours}:00 AM"; } return "12:00 AM"; } } [BepInPlugin("com.tonysmoons.betternights", "BetterNights", "1.0.0")] public class Plugin : BaseUnityPlugin { public const string PluginGuid = "com.tonysmoons.betternights"; public const string PluginName = "BetterNights"; public const string PluginVersion = "1.0.0"; internal static ManualLogSource Log; internal static ConfigEntry EndOfDayHour; internal static ConfigEntry ExtendNightOnly; internal static ConfigEntry LateNightCostsADay; private static readonly string[] Banner = new string[6] { " ____ _ _ _ _ _ _ _", "| __ ) ___| |_| |_ ___ _ __| \\ | (_) __ _| |__ | |_ ___", "| _ \\ / _ \\ __| __/ _ \\ '__| \\| | |/ _` | '_ \\| __/ __|", "| |_) | __/ |_| || __/ | | |\\ | | (_| | | | | |_\\__ \\", "|____/ \\___|\\__|\\__\\___|_| |_| \\_|_|\\__, |_| |_|\\__|___/", " |___/" }; private void Awake() { //IL_0050: Unknown result type (might be due to invalid IL or missing references) //IL_005a: Expected O, but got Unknown //IL_007b: Unknown result type (might be due to invalid IL or missing references) //IL_0085: Expected O, but got Unknown //IL_00a6: Unknown result type (might be due to invalid IL or missing references) //IL_00b0: Expected O, but got Unknown //IL_00e4: Unknown result type (might be due to invalid IL or missing references) //IL_00e9: Unknown result type (might be due to invalid IL or missing references) Log = ((BaseUnityPlugin)this).Logger; Log.LogInfo((object)(Environment.NewLine + string.Join(Environment.NewLine, Banner))); EndOfDayHour = ((BaseUnityPlugin)this).Config.Bind("Night Length", "End Time", 0, new ConfigDescription("How late the night goes, in AM hours.\n0 = 12 AM (normal game), 1 = 1 AM, 2 = 2 AM, and so on up to 6 = 6 AM.\nEveryone in the lobby needs the same number.", (AcceptableValueBase)(object)new AcceptableValueRange(0, 6), Array.Empty())); ExtendNightOnly = ((BaseUnityPlugin)this).Config.Bind("Night Length", "Extend Night Only", true, new ConfigDescription("true = daytime stays its normal length and the extra hours are all night.\nfalse = the whole day gets stretched out evenly instead.\nEither way it does NOT waste a day. One landing still costs one day off the deadline,\nno matter how late you stay out, unless you turn on Late Night Costs A Day below.", (AcceptableValueBase)null, Array.Empty())); LateNightCostsADay = ((BaseUnityPlugin)this).Config.Bind("Night Length", "Late Night Costs A Day", false, new ConfigDescription("true = if the clock reaches 1 AM, that landing costs 2 days off the quota deadline instead of 1.\nfalse = staying out late is free.\nNeeds End Time set to 2 or more, otherwise the day is already over before 1 AM arrives.", (AcceptableValueBase)null, Array.Empty())); ((BaseUnityPlugin)this).Config.SettingChanged += delegate { TimeOfDayPatches.ApplyToCurrentInstance(); }; Harmony val = new Harmony("com.tonysmoons.betternights"); val.PatchAll(typeof(TimeOfDayPatches)); val.PatchAll(typeof(ClockPatches)); } } internal static class TimeOfDayPatches { private static int vanillaNumberOfHours = -1; private static bool chargedExtraDayThisRound; internal static int ExtraHours => Mathf.Clamp(Plugin.EndOfDayHour.Value, 0, 6); private static bool NightOnly { get { if (ExtraHours > 0 && vanillaNumberOfHours > 0) { return Plugin.ExtendNightOnly.Value; } return false; } } private static float DayLengthScale => (float)(vanillaNumberOfHours + ExtraHours) / (float)vanillaNumberOfHours; internal static void ApplyToCurrentInstance() { Apply(TimeOfDay.Instance); } private static void Apply(TimeOfDay timeOfDay) { if (!((Object)(object)timeOfDay == (Object)null)) { if (vanillaNumberOfHours < 0) { vanillaNumberOfHours = timeOfDay.numberOfHours; } timeOfDay.numberOfHours = vanillaNumberOfHours + ExtraHours; timeOfDay.totalTime = timeOfDay.lengthOfHours * (float)timeOfDay.numberOfHours; Plugin.Log.LogInfo((object)($"Day length set to {timeOfDay.numberOfHours} hours ({timeOfDay.totalTime}s); " + "the clock now runs to " + ClockPatches.DescribeEndOfDay(ExtraHours) + ".")); } } [HarmonyPatch(typeof(TimeOfDay), "Start")] [HarmonyPostfix] private static void ExtendDayLength(TimeOfDay __instance) { Apply(__instance); } [HarmonyPatch(typeof(TimeOfDay), "MoveTimeOfDay")] [HarmonyPostfix] private static void KeepSunOnVanillaSchedule(TimeOfDay __instance) { if (NightOnly && !((Object)(object)__instance.sunAnimator == (Object)null)) { __instance.sunAnimator.SetFloat("timeOfDay", Mathf.Clamp(__instance.normalizedTimeOfDay * DayLengthScale, 0f, 0.99f)); } } [HarmonyPatch(typeof(TimeOfDay), "TimeOfDayEvents")] [HarmonyPostfix] private static void ChargeExtraDayForLateNight(TimeOfDay __instance) { if (!Plugin.LateNightCostsADay.Value || ExtraHours <= 0 || !__instance.currentLevel.planetHasTime) { chargedExtraDayThisRound = false; } else if (__instance.normalizedTimeOfDay < 1140f / (60f * (float)__instance.numberOfHours)) { chargedExtraDayThisRound = false; } else if (!chargedExtraDayThisRound && ((NetworkBehaviour)__instance).IsServer) { chargedExtraDayThisRound = true; __instance.timeUntilDeadline = Mathf.Max(__instance.timeUntilDeadline - __instance.totalTime, 0f); __instance.UpdateProfitQuotaCurrentTime(); Plugin.Log.LogInfo((object)$"Clock reached 1 AM - charged an extra day. {__instance.daysUntilDeadline} days until deadline."); } } [HarmonyPatch(typeof(TimeOfDay), "GetDayPhase")] [HarmonyPrefix] private static void KeepDayPhaseOnVanillaSchedule(TimeOfDay __instance, ref float time) { if (NightOnly && __instance.currentDayTimeStarted) { time = Mathf.Clamp01(time * DayLengthScale); } } }