using System; using System.Collections.Generic; using System.Reflection; using System.Runtime.CompilerServices; using BepInEx; using BepInEx.Configuration; using HarmonyLib; using UnityEngine; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: AssemblyVersion("0.0.0.0")] namespace Eden.RogueWaves; [BepInPlugin("eden.valheim.roguewaves", "Rogue Waves", "1.1.0")] public class RogueWavesPlugin : BaseUnityPlugin { private sealed class RogueWave { public readonly long Id; public readonly double StartTime; public readonly Vector3 Origin; public readonly Vector3 Direction; public readonly float Height; public readonly float Duration; public readonly float Length; public readonly float Width; public readonly float Speed; private readonly Vector3 right; public RogueWave(long id, double startTime, Vector3 origin, Vector3 direction, float height, float duration, float length, float width, float speed) { //IL_0015: 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_001e: 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_0029: Unknown result type (might be due to invalid IL or missing references) //IL_002f: Unknown result type (might be due to invalid IL or missing references) //IL_0034: 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_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) Id = id; StartTime = startTime; Origin = origin; Direction = ((Vector3)(ref direction)).normalized; Vector3 val = Vector3.Cross(Vector3.up, Direction); right = ((Vector3)(ref val)).normalized; Height = height; Duration = duration; Length = length; Width = width; Speed = speed; } public bool IsExpired(double time) { return time - StartTime > (double)(Duration + 4f); } public float GetHeight(Vector3 worldPos, double time) { //IL_0021: 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) //IL_002d: Unknown result type (might be due to invalid IL or missing references) //IL_003a: 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_0047: 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) float num = (float)(time - StartTime); if (num < 0f || num > Duration) { return 0f; } Vector3 val = worldPos - Origin; val.y = 0f; float num2 = Vector3.Dot(val, Direction); float num3 = Vector3.Dot(val, right); float num4 = (0f - Speed) * Duration * 0.5f + Speed * num; float num5 = num2 - num4; float num6 = ((Mathf.Abs(num5) <= Length) ? (0.5f + 0.5f * Mathf.Cos((float)Math.PI * num5 / Length)) : 0f); float num7 = Mathf.Exp((0f - num3 * num3) / (2f * Width * Width)); float num8 = Mathf.Clamp01(num / 3f); float num9 = Mathf.Clamp01((Duration - num) / 3f); float num10 = num8 * num9; float num11 = num5 + Length * 1.15f; float num12 = ((Mathf.Abs(num11) <= Length) ? (0.5f + 0.5f * Mathf.Cos((float)Math.PI * num11 / Length)) : 0f); return (Height * num6 - Height * 0.28f * num12) * num7 * num10; } } public const string ModGuid = "eden.valheim.roguewaves"; public const string ModName = "Rogue Waves"; public const string ModVersion = "1.1.0"; private const string RpcName = "Eden_RogueWaves_StartWave"; private static ConfigEntry enabledConfig; private static ConfigEntry multiplayerSyncConfig; private static ConfigEntry waveHeightConfig; private static ConfigEntry minDelayConfig; private static ConfigEntry maxDelayConfig; private static ConfigEntry waveDurationConfig; private static ConfigEntry waveLengthConfig; private static ConfigEntry waveWidthConfig; private static ConfigEntry waveSpeedConfig; private static ConfigEntry announceConfig; private static readonly Random rng = new Random(); private static float nextWaveTime; private static ZRoutedRpc registeredRpc; private static long lastWaveId; private static RogueWave activeWave; private Harmony harmony; private void Awake() { //IL_0171: Unknown result type (might be due to invalid IL or missing references) //IL_017b: Expected O, but got Unknown enabledConfig = ((BaseUnityPlugin)this).Config.Bind("General", "Enabled", true, "Enable rogue ocean waves."); multiplayerSyncConfig = ((BaseUnityPlugin)this).Config.Bind("Multiplayer", "SyncWaves", true, "Broadcast rogue waves to everyone with the mod installed."); waveHeightConfig = ((BaseUnityPlugin)this).Config.Bind("Wave", "HeightMeters", 9f, "Peak added wave height. 9m is roughly 30 feet."); minDelayConfig = ((BaseUnityPlugin)this).Config.Bind("Timing", "MinSecondsBetweenWaves", 90f, "Minimum seconds between rogue waves while you are controlling a ship."); maxDelayConfig = ((BaseUnityPlugin)this).Config.Bind("Timing", "MaxSecondsBetweenWaves", 210f, "Maximum seconds between rogue waves while you are controlling a ship."); waveDurationConfig = ((BaseUnityPlugin)this).Config.Bind("Wave", "DurationSeconds", 22f, "How long a rogue wave takes to pass through."); waveLengthConfig = ((BaseUnityPlugin)this).Config.Bind("Wave", "CrestLengthMeters", 24f, "Front-to-back size of the crest."); waveWidthConfig = ((BaseUnityPlugin)this).Config.Bind("Wave", "CrestWidthMeters", 60f, "Side-to-side spread around your ship."); waveSpeedConfig = ((BaseUnityPlugin)this).Config.Bind("Wave", "TravelSpeedMetersPerSecond", 18f, "How fast the rogue wave travels."); announceConfig = ((BaseUnityPlugin)this).Config.Bind("General", "ChatWarning", true, "Show a small center-screen warning when a rogue wave starts."); ScheduleNextWave(35f, 75f); harmony = new Harmony("eden.valheim.roguewaves"); harmony.PatchAll(); ((BaseUnityPlugin)this).Logger.LogInfo((object)"Rogue Waves loaded."); } private void OnDestroy() { if (harmony != null) { harmony.UnpatchSelf(); } } private void Update() { TryRegisterRpc(); if (!enabledConfig.Value) { activeWave = null; return; } double networkTime = GetNetworkTime(); if (activeWave != null && activeWave.IsExpired(networkTime)) { activeWave = null; ScheduleNextWave(minDelayConfig.Value, maxDelayConfig.Value); } Ship controlledShip = GetControlledShip(); if ((Object)(object)controlledShip == (Object)null) { if (Time.time > nextWaveTime) { ScheduleNextWave(15f, 45f); } } else if (activeWave == null && Time.time >= nextWaveTime) { StartRogueWave(controlledShip); } } private static Ship GetControlledShip() { Player localPlayer = Player.m_localPlayer; if ((Object)(object)localPlayer == (Object)null) { return null; } Ship controlledShip = localPlayer.GetControlledShip(); if ((Object)(object)controlledShip == (Object)null) { return null; } if (!(Mathf.Abs(controlledShip.GetSpeed()) > 0.4f) && !controlledShip.IsSailUp()) { return null; } return controlledShip; } private static void StartRogueWave(Ship ship) { //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_000b: Unknown result type (might be due to invalid IL or missing references) //IL_0053: Unknown result type (might be due to invalid IL or missing references) //IL_0058: 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_005e: Unknown result type (might be due to invalid IL or missing references) //IL_0063: Unknown result type (might be due to invalid IL or missing references) //IL_00ad: 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) //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) Vector3 forward = ((Component)ship).transform.forward; forward.y = 0f; if (((Vector3)(ref forward)).sqrMagnitude < 0.001f) { forward = Vector3.forward; } ((Vector3)(ref forward)).Normalize(); float num = Mathf.Lerp(-35f, 35f, Next01()); Vector3 direction = Quaternion.Euler(0f, num, 0f) * -forward; direction.y = 0f; ((Vector3)(ref direction)).Normalize(); long id = DateTime.UtcNow.Ticks ^ ((long)rng.Next() << 32) ^ rng.Next(); RogueWave wave = new RogueWave(id, GetNetworkTime(), ((Component)ship).transform.position, direction, Mathf.Max(0f, waveHeightConfig.Value), Mathf.Max(5f, waveDurationConfig.Value), Mathf.Max(3f, waveLengthConfig.Value), Mathf.Max(8f, waveWidthConfig.Value), Mathf.Max(2f, waveSpeedConfig.Value)); ApplyWave(wave, showWarning: true); BroadcastWave(wave); } private static void TryRegisterRpc() { if (ZRoutedRpc.instance != null && registeredRpc != ZRoutedRpc.instance) { ZRoutedRpc.instance.Register("Eden_RogueWaves_StartWave", (Action)RPC_StartWave); registeredRpc = ZRoutedRpc.instance; } } private static void BroadcastWave(RogueWave wave) { //IL_0014: Unknown result type (might be due to invalid IL or missing references) //IL_001a: Expected O, but got Unknown //IL_0034: 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) if (multiplayerSyncConfig.Value && ZRoutedRpc.instance != null) { ZPackage val = new ZPackage(); val.Write(wave.Id); val.Write(wave.StartTime); val.Write(wave.Origin); val.Write(wave.Direction); val.Write(wave.Height); val.Write(wave.Duration); val.Write(wave.Length); val.Write(wave.Width); val.Write(wave.Speed); ZRoutedRpc.instance.InvokeRoutedRPC(ZRoutedRpc.Everybody, "Eden_RogueWaves_StartWave", new object[1] { val }); } } private static void RPC_StartWave(long sender, ZPackage package) { //IL_001d: 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) if (enabledConfig.Value && package != null) { RogueWave wave = new RogueWave(package.ReadLong(), package.ReadDouble(), package.ReadVector3(), package.ReadVector3(), package.ReadSingle(), package.ReadSingle(), package.ReadSingle(), package.ReadSingle(), package.ReadSingle()); ApplyWave(wave, showWarning: true); } } private static void ApplyWave(RogueWave wave, bool showWarning) { if (wave != null && wave.Id != lastWaveId) { lastWaveId = wave.Id; activeWave = wave; if (showWarning && announceConfig.Value && (Object)(object)MessageHud.instance != (Object)null) { MessageHud.instance.ShowMessage((MessageType)2, "ROGUE WAVE", 0, (Sprite)null, false); } } } private static void ScheduleNextWave(float minSeconds, float maxSeconds) { float num = Mathf.Max(5f, Mathf.Min(minSeconds, maxSeconds)); float num2 = Mathf.Max(num + 1f, Mathf.Max(minSeconds, maxSeconds)); nextWaveTime = Time.time + Mathf.Lerp(num, num2, Next01()); } private static float Next01() { return (float)rng.NextDouble(); } public static float ExtraWaveHeight(Vector3 worldPos) { //IL_001e: Unknown result type (might be due to invalid IL or missing references) if (!enabledConfig.Value || activeWave == null) { return 0f; } return activeWave.GetHeight(worldPos, GetNetworkTime()); } private static double GetNetworkTime() { if ((Object)(object)ZNet.instance != (Object)null) { return ZNet.instance.GetTimeSeconds(); } return Time.time; } } [HarmonyPatch] internal static class WaterVolumeCalcWavePatch { private static IEnumerable TargetMethods() { MethodInfo[] methods = typeof(WaterVolume).GetMethods(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); for (int i = 0; i < methods.Length; i++) { if (methods[i].Name == "CalcWave") { yield return methods[i]; } } } private static void Postfix(Vector3 worldPos, ref float __result) { //IL_0003: Unknown result type (might be due to invalid IL or missing references) __result += RogueWavesPlugin.ExtraWaveHeight(worldPos); } }