diff --git a/Nuclei/Events/ServerEvents.cs b/Nuclei/Events/ServerEvents.cs index 7ff1cd1..bc7d6fb 100644 --- a/Nuclei/Events/ServerEvents.cs +++ b/Nuclei/Events/ServerEvents.cs @@ -1,4 +1,5 @@ using System; +using Nuclei.Features; namespace Nuclei.Events; @@ -15,6 +16,7 @@ public static class ServerEvents internal static void OnServerStarted() { ServerStarted?.Invoke(); + TimeService.Initialize(); } /// @@ -26,4 +28,4 @@ internal static void OnServerStopped() { ServerStopped?.Invoke(); } -} \ No newline at end of file +} diff --git a/Nuclei/Features/MissionService.cs b/Nuclei/Features/MissionService.cs index 49ea733..336d2e6 100644 --- a/Nuclei/Features/MissionService.cs +++ b/Nuclei/Features/MissionService.cs @@ -47,7 +47,7 @@ public static class MissionService /// /// The current mission time. /// - public static float CurrentMissionTime => Globals.MissionManagerInstance.missionTime; + public static float CurrentMissionTime => Globals.MissionManagerInstance.MissionTime; /// /// Gets all Mission Keys as an IEnumerable. diff --git a/Nuclei/Features/NucleiConfig.cs b/Nuclei/Features/NucleiConfig.cs index 6acfb49..ebc8dbb 100644 --- a/Nuclei/Features/NucleiConfig.cs +++ b/Nuclei/Features/NucleiConfig.cs @@ -1,5 +1,8 @@ +using System; using System.Collections.Generic; +using System.IO; using System.Linq; +using System.Text.Json.Nodes; using BepInEx.Configuration; using Nuclei.Enums; using Nuclei.Helpers; @@ -62,6 +65,9 @@ public static class NucleiConfig internal static ConfigEntry? RefreshServerNamePeriodically; internal const bool DefaultRefreshServerNamePeriodically = true; + + internal static ConfigEntry? RandomizeWeather; + internal const bool DefaultRandomizeWeather = false; internal static ConfigEntry? TargetFrameRate; internal const short DefaultTargetFrameRate = 120; @@ -164,6 +170,12 @@ internal static void InitSettings(ConfigFile config) CommandPrefix = config.Bind(GeneralSection, "CommandPrefix", DefaultCommandPrefix, "What to use as the command prefix (the character at the start of a command)."); Nuclei.Logger?.LogDebug($"CommandPrefix: {CommandPrefix.Value}"); + + RandomizeWeather = config.Bind(GeneralSection, "RandomizeWeather", DefaultRandomizeWeather, + "Randomize weather by modifying the .json mission file directly. This requires the missions to be in " + + "the mission folder you assigned in DedicatedServerConfig.json, meaning all missions' MissionGroup must be User, not BuiltIn"); + + Nuclei.Logger?.LogDebug($"CommandPrefix: {CommandPrefix.Value}"); Nuclei.Logger?.LogDebug("Loaded settings!"); } diff --git a/Nuclei/Features/TimeService.cs b/Nuclei/Features/TimeService.cs index 885c8f3..d0e3c42 100644 --- a/Nuclei/Features/TimeService.cs +++ b/Nuclei/Features/TimeService.cs @@ -54,6 +54,15 @@ private void FixedUpdate() _lastTime = currentTime; TimeEvents.OnEverySecond(); + + + // MoTD + var motdFreq = NucleiConfig.MotDFrequency!.Value; + if (currentTime % motdFreq == 0) + { + ChatService.SendMotD(); + } + if (currentTime % 3600 == 0) { TimeEvents.OnEveryHour(); @@ -85,4 +94,4 @@ private void FixedUpdate() TimeEvents.OnEvery30Seconds(); } } -} \ No newline at end of file +} diff --git a/Nuclei/Features/WeatherRandomizerService.cs b/Nuclei/Features/WeatherRandomizerService.cs new file mode 100644 index 0000000..2299cbc --- /dev/null +++ b/Nuclei/Features/WeatherRandomizerService.cs @@ -0,0 +1,38 @@ +using System; +using System.IO; +using System.Linq; +using System.Text.Json; + + namespace Nuclei.Features; + + public class WeatherRandomizerService + { + internal static string MissionDir = null!; + public static void RandomizeWeather(string missionName) + { + var currentMissionDir = Directory.GetDirectories(MissionDir).First(x => x.Contains(missionName)); + Nuclei.Logger?.LogInfo($"currentMissionDir: {currentMissionDir} "); + var currentMissionFile = $"{currentMissionDir}/{missionName}.json"; + Nuclei.Logger?.LogInfo($"currentMissionFile: {currentMissionFile} "); + + string json = File.ReadAllText(currentMissionFile); + var parsedJson = System.Text.Json.Nodes.JsonNode.Parse(json)!; + + var writerOptions = new JsonSerializerOptions() + { + WriteIndented = true + }; + + Random rnd = new Random(); + parsedJson["environment"]!["timeOfDay"] = rnd.Next(3,13); + parsedJson["environment"]!["timeFactor"] = 2.0; + parsedJson["environment"]!["weatherIntensity"] = rnd.NextDouble() * 0.9; + parsedJson["environment"]!["cloudAltitude"] = 500 + rnd.NextDouble() * 1000; + parsedJson["environment"]!["cloudAltitude"] = 500 + rnd.NextDouble() * 1000; + parsedJson["environment"]!["windSpeed"] = rnd.NextDouble() * 4; + parsedJson["environment"]!["windTurbulence"] = rnd.NextDouble() * 1; + parsedJson["environment"]!["windHeading"] = rnd.Next(0, 360); + parsedJson["environment"]!["windRandomHeading"] = rnd.Next(0, 91); + File.WriteAllText(currentMissionFile, parsedJson.ToJsonString(writerOptions)); + } + } \ No newline at end of file diff --git a/Nuclei/Nuclei.csproj b/Nuclei/Nuclei.csproj index 7b3033f..4f71a60 100644 --- a/Nuclei/Nuclei.csproj +++ b/Nuclei/Nuclei.csproj @@ -52,6 +52,7 @@ + diff --git a/Nuclei/Patches/MissionSaveLoadPatches.cs b/Nuclei/Patches/MissionSaveLoadPatches.cs new file mode 100644 index 0000000..4d6eb68 --- /dev/null +++ b/Nuclei/Patches/MissionSaveLoadPatches.cs @@ -0,0 +1,48 @@ +using System; +using HarmonyLib; +using NuclearOption.SavedMission; +using Nuclei.Features; + +[HarmonyPriority(Priority.First)] +[HarmonyWrapSafe] +[HarmonyPatch(typeof(MissionSaveLoad))] +public class MissionSaveLoadPatches +{ + [HarmonyPostfix] + [HarmonyPatch(nameof(MissionSaveLoad.TryLoad))] + private static void Postfix( + MissionKey item, + ref Mission mission, + ref string error, + ref bool __result) + { + if (!__result || mission == null) return; + + RandomizeWeather(ref mission); + ModifyDifficulty(ref mission); + } + + private static void ModifyDifficulty(ref Mission mission) + { + // This is set to scale for larger player counts better + foreach (var f in mission.factions) + { + f.addAIPerEnemyPlayer = 0.80f; + f.AIAircraftLimit = 8; + } + } + + private static void RandomizeWeather(ref Mission mission) + { + if (!NucleiConfig.RandomizeWeather!.Value) return; + + var rnd = new Random(); + mission.environment.timeOfDay = rnd.Next(3, 18); + mission.environment.timeFactor = 8f; + mission.environment.weatherIntensity = (float)(rnd.NextDouble() * 0.9); + mission.environment.cloudAltitude = (float)(500 + rnd.NextDouble() * 1000); + mission.environment.windSpeed = (float)(rnd.NextDouble() * 4); + mission.environment.windTurbulence = (float)rnd.NextDouble(); + mission.environment.windHeading = rnd.Next(0, 360); + } +} \ No newline at end of file