Decompiled source of RandomEncounters v1.4.0

RandomEncounters/RandomEncounters.dll

Decompiled 2 days ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using BepInEx;
using BepInEx.Bootstrap;
using BepInEx.Configuration;
using BepInEx.Logging;
using Crest;
using HarmonyLib;
using UnityEngine;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)]
[assembly: AssemblyTitle("RandomEncounters")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("raddude")]
[assembly: AssemblyProduct("RandomEncounters")]
[assembly: AssemblyCopyright("Copyright ©  2026")]
[assembly: AssemblyTrademark("")]
[assembly: ComVisible(false)]
[assembly: Guid("06b0b4cd-89d7-4ff2-8dc9-3eaa535b8d99")]
[assembly: AssemblyFileVersion("1.4.0.0")]
[assembly: TargetFramework(".NETFramework,Version=v4.8", FrameworkDisplayName = ".NET Framework 4.8")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.4.0.0")]
[module: UnverifiableCode]
namespace RandomEncounters;

internal class SeaLifeMod
{
	private static List<GameObject> s_whaleSpawns;

	private static Type _finWhaleAIType;

	private static Type _effectControllerType;

	private static FastInvokeHandler _triggerRandomAnimation;

	private static int _activeWhales;

	private static Component _whale0Ai;

	private static AssetBundle _assetBundle;

	private static AudioClip[] _blowholeSounds;

	private static AudioClip[] _breachSplashSounds;

	private static AudioClip[] _breachEmergeSounds;

	private static AudioClip[] _tailSplashSounds;

	private static int _soundsToLoad;

	private static int _soundsLoaded;

	private static bool _allSoundsLoaded;

	private const float MAX_DISTANCE = 650f;

	public static void PatchMod()
	{
		//IL_00a9: Unknown result type (might be due to invalid IL or missing references)
		//IL_00b7: Expected O, but got Unknown
		//IL_00f7: Unknown result type (might be due to invalid IL or missing references)
		//IL_0105: Expected O, but got Unknown
		((MonoBehaviour)RE_Plugin.SeaLifeModPluginInstance).StopAllCoroutines();
		_finWhaleAIType = AccessTools.TypeByName("FinWhaleAI");
		_effectControllerType = AccessTools.TypeByName("EffectController");
		MethodInfo methodInfo = AccessTools.Method(_finWhaleAIType, "TriggerRandomAnimation", (Type[])null, (Type[])null);
		_triggerRandomAnimation = MethodInvoker.GetHandler(methodInfo, false);
		string[] array = new string[3] { "FindPlayer", "CheckDistanceToPlayer", "SetRandomScale" };
		string[] array2 = array;
		foreach (string text in array2)
		{
			MethodInfo methodInfo2 = AccessTools.Method(_finWhaleAIType, text, (Type[])null, (Type[])null);
			MethodInfo methodInfo3 = AccessTools.Method(typeof(SeaLifeModPatches), "DoNotRun", (Type[])null, (Type[])null);
			RE_Plugin.HarmonyInstance.Patch((MethodBase)methodInfo2, new HarmonyMethod(methodInfo3), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
		}
		MethodInfo methodInfo4 = AccessTools.Method(_effectControllerType, "LoadSounds", (Type[])null, (Type[])null);
		MethodInfo methodInfo5 = AccessTools.Method(typeof(SeaLifeModPatches), "DoNotRun", (Type[])null, (Type[])null);
		RE_Plugin.HarmonyInstance.Patch((MethodBase)methodInfo4, new HarmonyMethod(methodInfo5), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
		((MonoBehaviour)RE_Plugin.Instance).StartCoroutine(LoadSoundsAsync());
		((MonoBehaviour)RE_Plugin.Instance).StartCoroutine(InstantiateWhales());
	}

	private static IEnumerator InstantiateWhales()
	{
		if ((Object)(object)RE_Plugin.SeaLifeModPluginInstance == (Object)null)
		{
			yield break;
		}
		GameObject whalePrefab = RE_Plugin.SeaLifeModPluginInstance.GetPrivateField<GameObject>("animalPrefab");
		s_whaleSpawns = new List<GameObject>();
		yield return (object)new WaitUntil((Func<bool>)(() => (Object)(object)Refs.shiftingWorld != (Object)null && _allSoundsLoaded));
		for (int i = 0; i < 5; i++)
		{
			GameObject whale = Object.Instantiate<GameObject>(whalePrefab, Refs.shiftingWorld);
			Component ai = whale.AddComponent(_finWhaleAIType);
			if (i == 0)
			{
				_whale0Ai = ai;
			}
			Component effectController = whale.AddComponent(_effectControllerType);
			effectController.SetPrivateField("blowholeSounds", _blowholeSounds);
			effectController.SetPrivateField("breachSplashSounds", _breachSplashSounds);
			effectController.SetPrivateField("breachEmergeSounds", _breachEmergeSounds);
			effectController.SetPrivateField("tailSplashSounds", _tailSplashSounds);
			whale.transform.position = Vector3.zero;
			whale.gameObject.SetActive(false);
			s_whaleSpawns.Add(whale);
		}
	}

	internal static void SpawnWhale(int i, Vector3 spawnPosition)
	{
		//IL_003c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0050: Unknown result type (might be due to invalid IL or missing references)
		//IL_005f: Unknown result type (might be due to invalid IL or missing references)
		RE_Plugin.LogDebug("Spawning FinWhale");
		float num = Random.Range(0.8f, 1.4f);
		int num2 = Random.Range(0, 360);
		GameObject val = s_whaleSpawns[i];
		Transform transform = val.transform;
		transform.position = spawnPosition;
		transform.rotation = Quaternion.Euler(0f, (float)num2, 0f);
		transform.localScale = new Vector3(num, num, num);
		val.SetActive(true);
		_activeWhales++;
	}

	internal static void TriggerEntranceAnimation()
	{
		_triggerRandomAnimation.Invoke((object)_whale0Ai, Array.Empty<object>());
	}

	internal static void CheckWhaleDistance()
	{
		//IL_002f: Unknown result type (might be due to invalid IL or missing references)
		//IL_003e: Unknown result type (might be due to invalid IL or missing references)
		if (_activeWhales == 0)
		{
			return;
		}
		foreach (GameObject s_whaleSpawn in s_whaleSpawns)
		{
			float num = Vector3.Distance(s_whaleSpawn.transform.position, ((Component)Refs.observerMirror).transform.position);
			if (s_whaleSpawn.activeInHierarchy && num > 650f)
			{
				RE_Plugin.LogDebug("Removing FinWhale");
				s_whaleSpawn.SetActive(false);
				_activeWhales--;
			}
		}
	}

	private static IEnumerator LoadSoundsAsync()
	{
		_soundsToLoad = 0;
		_soundsLoaded = 0;
		_assetBundle = RE_Plugin.SeaLifeModPluginInstance.GetPrivateField<AssetBundle>("seaLifeBundle");
		((MonoBehaviour)RE_Plugin.Instance).StartCoroutine(LoadAudioClipsAsync("WhaleBlowMed", 6, delegate(AudioClip[] clips)
		{
			_blowholeSounds = clips;
		}));
		((MonoBehaviour)RE_Plugin.Instance).StartCoroutine(LoadAudioClipsAsync("BreachSplashLarge", 5, delegate(AudioClip[] clips)
		{
			_breachSplashSounds = clips;
		}));
		((MonoBehaviour)RE_Plugin.Instance).StartCoroutine(LoadAudioClipsAsync("BreachSplashSmall", 6, delegate(AudioClip[] clips)
		{
			_breachEmergeSounds = clips;
		}));
		((MonoBehaviour)RE_Plugin.Instance).StartCoroutine(LoadAudioClipsAsync("TailSplash", 4, delegate(AudioClip[] clips)
		{
			_tailSplashSounds = clips;
		}));
		while (_soundsLoaded < _soundsToLoad)
		{
			yield return null;
		}
		_allSoundsLoaded = true;
	}

	private static IEnumerator LoadAudioClipsAsync(string baseName, int count, Action<AudioClip[]> onComplete)
	{
		_soundsToLoad += count;
		AudioClip[] clips = (AudioClip[])(object)new AudioClip[count];
		for (int i = 0; i < count; i++)
		{
			string clipName = $"{baseName}{i + 1:00}";
			AssetBundleRequest request = _assetBundle.LoadAssetAsync<AudioClip>("Assets/Audio/" + clipName + ".wav");
			yield return request;
			ref AudioClip reference = ref clips[i];
			Object asset = request.asset;
			reference = (AudioClip)(object)((asset is AudioClip) ? asset : null);
			_soundsLoaded++;
		}
		while (_soundsLoaded < _soundsToLoad)
		{
			yield return null;
		}
		onComplete(clips);
	}
}
public class SeaLifeModPatches
{
	[HarmonyPrefix]
	public static bool DoNotRun()
	{
		return false;
	}
}
internal class EncounterGenerator : MonoBehaviour
{
	private bool _moveSeagulls;

	private const float MIN_DISTANCE = 1000f;

	public static EncounterGenerator Instance { get; private set; }

	public void Awake()
	{
		if ((Object)(object)Instance != (Object)null && (Object)(object)Instance != (Object)(object)this)
		{
			Object.Destroy((Object)(object)((Component)this).gameObject);
			return;
		}
		Instance = this;
		((MonoBehaviour)this).StartCoroutine(ScheduleEncounter());
	}

	public void Update()
	{
		SeaLifeMod.CheckWhaleDistance();
	}

	private List<EncounterEntry> BuildEncounterTable()
	{
		List<EncounterEntry> list = new List<EncounterEntry>();
		bool flag = Configs.controlSeaLifeMod.Value && (Object)(object)RE_Plugin.SeaLifeModPluginInstance != (Object)null;
		if (Configs.enableFlotsam.Value)
		{
			list.Add(new EncounterEntry
			{
				Name = "Flotsam",
				Weight = 15,
				Trigger = GenerateFlotsam
			});
		}
		if (Configs.enableFlotsam.Value && flag)
		{
			list.Add(new EncounterEntry
			{
				Name = "Flotsam and Whales",
				Weight = 5,
				Trigger = delegate
				{
					GenerateFlotsam();
					((MonoBehaviour)this).StartCoroutine(GenerateWhales());
				}
			});
		}
		if (flag)
		{
			list.Add(new EncounterEntry
			{
				Name = "Whales",
				Weight = 25,
				Trigger = delegate
				{
					((MonoBehaviour)this).StartCoroutine(GenerateWhales());
				}
			});
		}
		if (Configs.enableDenseFog.Value)
		{
			list.Add(new EncounterEntry
			{
				Name = "Dense Fog",
				Weight = 5,
				Trigger = delegate
				{
					((MonoBehaviour)this).StartCoroutine(GenerateDenseFog());
				}
			});
		}
		if (Configs.enableDenseFog.Value && flag)
		{
			list.Add(new EncounterEntry
			{
				Name = "Dense Fog and Whales",
				Weight = 5,
				Trigger = delegate
				{
					((MonoBehaviour)this).StartCoroutine(GenerateDenseFog());
					((MonoBehaviour)this).StartCoroutine(GenerateWhales());
				}
			});
		}
		if (Configs.enableFishingBonanza.Value)
		{
			list.Add(new EncounterEntry
			{
				Name = "Fishing Bonanza",
				Weight = 15,
				Trigger = delegate
				{
					((MonoBehaviour)this).StartCoroutine(GenerateFishingBonanza());
				}
			});
		}
		if (Configs.enableIntenseStorm.Value)
		{
			list.Add(new EncounterEntry
			{
				Name = "Intense Storm",
				Weight = 5,
				Trigger = delegate
				{
					((MonoBehaviour)this).StartCoroutine(GenerateIntenseStorm());
				}
			});
		}
		return list;
	}

	private IEnumerator ScheduleEncounter()
	{
		yield return (object)new WaitUntil((Func<bool>)(() => GameState.playing));
		int minTime = Mathf.Abs(Configs.generateEncounterMinTime.Value);
		int range = Mathf.Abs(Configs.generateEncounterTimeRange.Value);
		int timeToNextEncounter = minTime + Random.Range(0, range);
		yield return (object)new WaitForSeconds((float)timeToNextEncounter);
		if ((Object)(object)GameState.currentBoat != (Object)null)
		{
			Generate();
		}
		((MonoBehaviour)this).StartCoroutine(ScheduleEncounter());
	}

	private void Generate()
	{
		if (!GameState.playing)
		{
			return;
		}
		if (GameState.distanceToLand <= 1000f)
		{
			RE_Plugin.LogDebug($"Too close to land (distance: {GameState.distanceToLand}), skipping encounter generation.");
			return;
		}
		if (GameState.sleeping)
		{
			RE_Plugin.LogDebug("Player sleeping, skipping encounter generation.");
			return;
		}
		if (Random.value > Mathf.Abs((float)Configs.encounterRollChance.Value / 100f))
		{
			RE_Plugin.LogInfo("No encounter this time");
			return;
		}
		List<EncounterEntry> list = BuildEncounterTable();
		if (list.Count == 0)
		{
			RE_Plugin.LogDebug("No encounters enabled");
			return;
		}
		int num = list.Sum((EncounterEntry e) => e.Weight);
		int num2 = Random.Range(0, num);
		int num3 = 0;
		foreach (EncounterEntry item in list)
		{
			num3 += item.Weight;
			if (num2 < num3)
			{
				RE_Plugin.LogDebug("Encounter: " + item.Name);
				item.Trigger();
				break;
			}
		}
	}

	private static void GenerateFlotsam()
	{
		//IL_0006: Unknown result type (might be due to invalid IL or missing references)
		//IL_0010: Unknown result type (might be due to invalid IL or missing references)
		//IL_001a: Unknown result type (might be due to invalid IL or missing references)
		//IL_001f: 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_0038: Unknown result type (might be due to invalid IL or missing references)
		//IL_003d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0042: Unknown result type (might be due to invalid IL or missing references)
		//IL_0043: Unknown result type (might be due to invalid IL or missing references)
		Vector3 spawnPoint = GameState.currentBoat.position + GameState.currentBoat.right * 200f + GameState.currentBoat.forward * (float)Random.Range(-30, 30);
		Flotsam.Spawn(spawnPoint);
	}

	private IEnumerator GenerateWhales()
	{
		Vector3 boatPosition = GameState.currentBoat.position;
		int spawnCount = Random.Range(2, 5);
		WaitForSeconds spawnDelay = new WaitForSeconds(2f);
		for (int i = 0; i < spawnCount; i++)
		{
			Vector3 randomOffset = new Vector3((float)Random.Range(-200, 200), -8f, (float)Random.Range(-200, 200));
			yield return spawnDelay;
			SeaLifeMod.SpawnWhale(i, boatPosition + randomOffset);
		}
		yield return spawnDelay;
		SeaLifeMod.TriggerEntranceAnimation();
	}

	private IEnumerator GenerateDenseFog()
	{
		if (DenseFog.IsRunning || WeatherStorms.instance.InvokePrivateMethod<float>("GetNormalizedDistance") < 0.75f)
		{
			yield break;
		}
		DenseFog.Spawn();
		List<AudioSource> waveAudioSources = DenseFog.WaveAudioSources.Keys.ToList();
		AudioSource windAudioSource = DenseFog.WindAudioSource.source;
		float windOrigVolume = DenseFog.WindAudioSource.origVolume;
		for (float t = 0f; t < 4f; t += Time.deltaTime)
		{
			float lerpValue = t / 4f;
			foreach (AudioSource audioSource in waveAudioSources)
			{
				audioSource.volume = Mathf.Lerp(DenseFog.WaveAudioSources[audioSource], 0f, lerpValue);
			}
			if ((Object)(object)windAudioSource != (Object)null)
			{
				windAudioSource.volume = Mathf.Lerp(windOrigVolume, 0.0001f, lerpValue);
			}
			yield return null;
		}
		for (int i = 0; i < 4; i++)
		{
			Vector3 spawnPoint = GameState.currentBoat.position + GameState.currentBoat.right * (200f + Random.Range(20f, 60f) * (float)i) + GameState.currentBoat.forward * (float)Random.Range(-200, 200);
			Flotsam.SpawnItem(spawnPoint, (Random.Range(1, 100) > 50) ? AssetLoader.SmallWreck : AssetLoader.Hull, 1f, wreckage: true);
			yield return (object)new WaitForSeconds(1f);
		}
		yield return (object)new WaitForSeconds((float)Configs.fogDuration.Value);
		DenseFog.ClearFog();
		for (float t2 = 0f; t2 < 4f; t2 += Time.deltaTime)
		{
			float lerpValue2 = t2 / 4f;
			foreach (AudioSource audioSource2 in waveAudioSources)
			{
				audioSource2.volume = Mathf.Lerp(0f, DenseFog.WaveAudioSources[audioSource2], lerpValue2);
			}
			if ((Object)(object)windAudioSource != (Object)null)
			{
				windAudioSource.volume = Mathf.Lerp(0.0001f, windOrigVolume, lerpValue2);
			}
			yield return null;
		}
	}

	private IEnumerator GenerateFishingBonanza()
	{
		float stormDistance = WeatherStorms.instance.InvokePrivateMethod<float>("GetNormalizedDistance");
		if ((Object)(object)GameState.currentBoat == (Object)null || stormDistance < 0.75f)
		{
			RE_Plugin.LogDebug($"Storm too close for fishing bonanza {stormDistance} {stormDistance < 0.75f}");
			yield break;
		}
		Transform? obj = ((IEnumerable<Transform>)((Component)Refs.islands[3]).GetComponentsInChildren<Transform>()).FirstOrDefault((Func<Transform, bool>)((Transform t) => ((Object)t).name == "seagulls"));
		GameObject seagullsGO = ((obj != null) ? ((Component)obj).gameObject : null);
		if ((Object)(object)seagullsGO == (Object)null)
		{
			RE_Plugin.LogDebug("No seagulls found");
			yield break;
		}
		GameObject seagulls = Object.Instantiate<GameObject>(seagullsGO, Refs.shiftingWorld);
		if (!seagulls.activeInHierarchy)
		{
			seagulls.SetActive(true);
		}
		seagulls.GetComponent<AudioSource>().PlayOneShot(seagulls.GetComponent<AudioSource>().clip);
		ParticleSystem seagullsPS = seagulls.GetComponent<ParticleSystem>();
		MainModule main = seagullsPS.main;
		((MainModule)(ref main)).maxParticles = 25;
		((MainModule)(ref main)).startLifetime = MinMaxCurve.op_Implicit((float)Configs.fishingBonanzaDuration.Value);
		((MainModule)(ref main)).startRotation = MinMaxCurve.op_Implicit(0f);
		((MainModule)(ref main)).startRotation3D = false;
		RotationOverLifetimeModule rol = seagullsPS.rotationOverLifetime;
		((RotationOverLifetimeModule)(ref rol)).enabled = false;
		((RotationOverLifetimeModule)(ref rol)).x = MinMaxCurve.op_Implicit(0f);
		((RotationOverLifetimeModule)(ref rol)).y = MinMaxCurve.op_Implicit(0f);
		((RotationOverLifetimeModule)(ref rol)).z = MinMaxCurve.op_Implicit(0f);
		VelocityOverLifetimeModule vol = seagullsPS.velocityOverLifetime;
		((VelocityOverLifetimeModule)(ref vol)).enabled = true;
		((VelocityOverLifetimeModule)(ref vol)).orbitalX = MinMaxCurve.op_Implicit(0f);
		((VelocityOverLifetimeModule)(ref vol)).orbitalY = MinMaxCurve.op_Implicit(0f);
		((VelocityOverLifetimeModule)(ref vol)).orbitalZ = MinMaxCurve.op_Implicit(0f);
		((VelocityOverLifetimeModule)(ref vol)).orbitalXMultiplier = 0f;
		((VelocityOverLifetimeModule)(ref vol)).orbitalYMultiplier = 0f;
		((VelocityOverLifetimeModule)(ref vol)).orbitalZMultiplier = 0f;
		RotationBySpeedModule rbs = seagullsPS.rotationBySpeed;
		((RotationBySpeedModule)(ref rbs)).enabled = false;
		ParticleSystemRenderer seagullPSR = seagulls.GetComponent<ParticleSystemRenderer>();
		seagullPSR.alignment = (ParticleSystemRenderSpace)2;
		ShapeModule shape = seagullsPS.shape;
		((ShapeModule)(ref shape)).shapeType = (ParticleSystemShapeType)18;
		((ShapeModule)(ref shape)).scale = new Vector3(25f, 25f, 0.2f);
		EmissionModule emission = seagullsPS.emission;
		if (!((EmissionModule)(ref emission)).enabled)
		{
			((EmissionModule)(ref emission)).enabled = true;
		}
		RE_Plugin.LogDebug("Starting fishing bonanza");
		FishingBonanza.IsBonanzaActive = true;
		_moveSeagulls = true;
		((MonoBehaviour)this).StartCoroutine(MoveSeagulls(seagulls.transform, GameState.currentBoat));
		yield return (object)new WaitForSeconds((float)Configs.fishingBonanzaDuration.Value);
		RE_Plugin.LogDebug("Stopping fishing bonanza");
		FishingBonanza.IsBonanzaActive = false;
		_moveSeagulls = false;
		Object.Destroy((Object)(object)seagulls);
	}

	private IEnumerator MoveSeagulls(Transform seagulls, Transform boat)
	{
		while (_moveSeagulls)
		{
			Vector3 targetPosition = boat.position + boat.up * 40f;
			seagulls.position = Vector3.Lerp(seagulls.position, targetPosition, 0.2f * Time.deltaTime);
			Vector3 newRotation = seagulls.eulerAngles;
			newRotation.y = Mathf.LerpAngle(seagulls.eulerAngles.y, boat.eulerAngles.y - 90f, 0.2f * Time.deltaTime);
			seagulls.rotation = Quaternion.Euler(newRotation);
			yield return null;
		}
	}

	private IEnumerator GenerateIntenseStorm()
	{
		WeatherStorms weatherStorms = WeatherStorms.instance;
		WanderingStorm storm = weatherStorms.GetCurrentStorm();
		WanderingStormLightning lightning = ((Component)((Component)storm).transform.GetChild(3)).GetComponent<WanderingStormLightning>();
		Region targetRegion = RegionBlender.instance.GetPrivateField<Region>("currentTargetRegion");
		float origInertiaWindScale = IntenseStorm.oceanUpdaterCrest.inertiaWindScale;
		float origWindSpeedMult = IntenseStorm.oceanUpdaterCrest.GetPrivateField<float>("windSpeedMult");
		float origSmallWavesMult = IntenseStorm.oceanUpdaterCrest.GetPrivateField<float>("smallWavesMult");
		float origLightningInterval = lightning.GetPrivateField<float>("lightningInterval");
		float origRainDensity = targetRegion.stormWeather.particles.rainDensity;
		lightning.SetPrivateField("lightningInterval", 5f);
		targetRegion.stormWeather.particles.rainDensity = 70f;
		float stormDist = Vector3.Distance(((Component)Camera.main).transform.position, ((Component)storm).transform.position);
		Vector3 vector = ((Component)Camera.main).transform.position - ((Component)storm).transform.position;
		vector.y = 0f;
		RE_Plugin.LogDebug(((Object)storm).name + " approaching");
		while (stormDist > 1500f)
		{
			vector = ((Component)Camera.main).transform.position - ((Component)storm).transform.position;
			vector.y = 0f;
			Wind.currentBaseWind = vector * 50f;
			float translateSpeed = ((weatherStorms.InvokePrivateMethod<float>("GetNormalizedDistance") < weatherStorms.GetPrivateField<float>("rainBorder")) ? 0.005f : 0.25f);
			((Component)storm).transform.Translate(vector * translateSpeed);
			yield return (object)new WaitForSeconds(0.3f);
			stormDist = Vector3.Distance(((Component)Camera.main).transform.position, ((Component)storm).transform.position);
		}
		RE_Plugin.LogDebug(((Object)storm).name + " arrived");
		IntenseStorm.oceanUpdaterCrest.inertiaWindScale = 0.22f;
		IntenseStorm.oceanUpdaterCrest.SetPrivateField("windSpeedMult", 5f);
		IntenseStorm.oceanUpdaterCrest.SetPrivateField("smallWavesMult", 0.4f);
		for (int i = 0; i < Configs.intenseStormDuration.Value; i++)
		{
			Wind.currentBaseWind = vector * 50f;
			yield return (object)new WaitForSeconds(1f);
		}
		RE_Plugin.LogDebug(((Object)storm).name + " dying down");
		lightning.SetPrivateField("lightningInterval", origLightningInterval);
		Weather.instance.currentRegion.stormWeather.particles.rainDensity = origRainDensity;
		IntenseStorm.oceanUpdaterCrest.inertiaWindScale = origInertiaWindScale;
		IntenseStorm.oceanUpdaterCrest.SetPrivateField("windSpeedMult", origWindSpeedMult);
		IntenseStorm.oceanUpdaterCrest.SetPrivateField("smallWavesMult", origSmallWavesMult);
	}
}
internal class DenseFog
{
	[HarmonyPatch(typeof(OceanColorBlender))]
	private class OceanColorBlenderPatches
	{
		[HarmonyPrefix]
		[HarmonyPatch("ApplyPalette")]
		public static void ApplyFogDensity(ref OceanColorPalette palette)
		{
			if (IsRunning)
			{
				_originalFogDensity = ((_originalFogDensity == 0f) ? palette.fogDensity : _originalFogDensity);
				_currentFogDensity = ((_currentFogDensity == 0f) ? palette.fogDensity : _currentFogDensity);
				if (_clearFog && _currentFogDensity > _originalFogDensity)
				{
					_currentFogDensity -= 1E-05f;
				}
				if (!_clearFog && _currentFogDensity < 0.06f)
				{
					_currentFogDensity += 1E-05f;
				}
				palette.fogDensity = _currentFogDensity;
				if (_clearFog && _currentFogDensity <= _originalFogDensity)
				{
					IsRunning = false;
					_currentFogDensity = 0f;
					_originalFogDensity = 0f;
					Traverse.Create((object)GameObject.Find("wind").GetComponent<Wind>()).Field("timer").SetValue((object)0);
				}
			}
		}
	}

	[HarmonyPatch(typeof(Wind))]
	private class WindPatches
	{
		[HarmonyPrefix]
		[HarmonyPatch("SetNewGustTarget")]
		public static bool NoGust(ref Vector3 ___currentGustTarget, Vector3 ___currentWindTarget)
		{
			//IL_0012: Unknown result type (might be due to invalid IL or missing references)
			//IL_0013: Unknown result type (might be due to invalid IL or missing references)
			if (!IsRunning)
			{
				return true;
			}
			___currentGustTarget = ___currentWindTarget;
			return false;
		}

		[HarmonyPrefix]
		[HarmonyPatch("SetNewWindTarget")]
		public static bool LightWind(ref Vector3 ___currentWindTarget)
		{
			//IL_0017: Unknown result type (might be due to invalid IL or missing references)
			//IL_0021: 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)
			if (!IsRunning)
			{
				return true;
			}
			___currentWindTarget = ((Vector3)(ref Wind.currentBaseWind)).normalized * 3f;
			return false;
		}
	}

	[HarmonyPatch(typeof(WaveSound))]
	private class WaveSoundPatches
	{
		[HarmonyPrefix]
		[HarmonyPatch("UpdateIntensity")]
		public static bool SetToMinVolume()
		{
			if (!IsRunning)
			{
				return true;
			}
			return false;
		}

		[HarmonyPostfix]
		[HarmonyPatch("Start")]
		public static void GetAudioSource(AudioSource ___audio)
		{
			if (!WaveAudioSources.ContainsKey(___audio))
			{
				WaveAudioSources.Add(___audio, ___audio.volume);
			}
		}
	}

	[HarmonyPatch(typeof(WindSound))]
	private class WindSoundPatches
	{
		[HarmonyPrefix]
		[HarmonyPatch("Update")]
		public static bool SetToMinVolume()
		{
			if (!IsRunning)
			{
				return true;
			}
			return false;
		}

		[HarmonyPostfix]
		[HarmonyPatch("Start")]
		public static void GetAudioSource(AudioSource ___audio)
		{
			WindAudioSource = (source: ___audio, origVolume: ___audio.volume);
		}
	}

	private static bool _clearFog = true;

	private static float _currentFogDensity = 0f;

	private static float _originalFogDensity = 0f;

	private const float MAX_FOG_DENSITY = 0.06f;

	public static bool IsRunning { get; private set; } = false;

	public static Dictionary<AudioSource, float> WaveAudioSources { get; private set; } = new Dictionary<AudioSource, float>();

	public static (AudioSource source, float origVolume) WindAudioSource { get; private set; } = (source: null, origVolume: 0f);

	public static void Spawn()
	{
		RE_Plugin.LogDebug("Spawning fog");
		foreach (AudioSource item in WaveAudioSources.Keys.ToList())
		{
			WaveAudioSources[item] = item.volume;
		}
		if ((Object)(object)WindAudioSource.source != (Object)null)
		{
			WindAudioSource = (source: WindAudioSource.source, origVolume: WindAudioSource.source.volume);
		}
		_clearFog = false;
		IsRunning = true;
	}

	public static void ClearFog()
	{
		RE_Plugin.LogDebug("Clearing fog");
		_clearFog = true;
	}
}
internal class EncounterEntry
{
	public string Name;

	public int Weight;

	public Action Trigger;
}
internal class FishingBonanza
{
	[HarmonyPatch(typeof(FishingRodFish))]
	[HarmonyPatch("Update")]
	private class FishingRodFishPatches
	{
		[HarmonyPostfix]
		public static void IncreaseCatchChance(FishingRodFish __instance, ShipItemFishingRod ___rod, SimpleFloatingObject ___floater, ConfigurableJoint ___bobberJoint, ref float ___fishTimer)
		{
			//IL_0089: Unknown result type (might be due to invalid IL or missing references)
			//IL_0094: 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_004c: Unknown result type (might be due to invalid IL or missing references)
			if (!IsBonanzaActive || (Object)(object)__instance.currentFish != (Object)null || ((ShipItem)___rod).health <= 0f || (!Object.op_Implicit((Object)(object)((PickupableItem)___rod).held) && !RE_Plugin.IdleFishingPluginDetected && !RE_Plugin.HooksHangMorePluginDetected) || !((FloatingObjectBase)___floater).InWater)
			{
				return;
			}
			SoftJointLimit linearLimit = ___bobberJoint.linearLimit;
			if (((SoftJointLimit)(ref linearLimit)).limit <= 1f || ((Component)__instance).gameObject.layer == 16)
			{
				return;
			}
			___fishTimer -= Time.deltaTime;
			float num = Vector3.Distance(((Component)__instance).transform.position, ((Component)___rod).transform.position);
			float num2 = Mathf.InverseLerp(3f, 20f, num) * 2.5f + 0.5f;
			if (___fishTimer <= 0f)
			{
				___fishTimer = 1f;
				float num3 = (Object.op_Implicit((Object)(object)((PickupableItem)___rod).held) ? 20f : 3f);
				if (Random.Range(0f, 100f) < num2 * num3)
				{
					__instance.CatchFish();
				}
			}
		}
	}

	public static bool IsBonanzaActive { get; set; }
}
internal class Flotsam
{
	private static readonly int[] _cargos = new int[36]
	{
		1, 2, 3, 4, 5, 6, 7, 8, 9, 10,
		11, 13, 14, 15, 16, 17, 18, 19, 24, 25,
		26, 27, 201, 202, 206, 212, 213, 214, 216, 219,
		220, 222, 223, 224, 227, 228
	};

	private static readonly int[] _consumables = new int[4] { 104, 108, 131, 132 };

	private static readonly int[] _bottles = new int[5] { 55, 56, 57, 58, 59 };

	private static readonly int[] _tobaccoCrates = new int[4] { 311, 313, 315, 319 };

	private const int MAX_CARGO_TYPES = 4;

	private const int MAX_CARGOS = 3;

	private const int MAX_CONSUME_TYPES = 2;

	internal static void Spawn(Vector3 spawnPoint)
	{
		//IL_007a: Unknown result type (might be due to invalid IL or missing references)
		//IL_0127: Unknown result type (might be due to invalid IL or missing references)
		//IL_019e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0228: Unknown result type (might be due to invalid IL or missing references)
		//IL_0232: Unknown result type (might be due to invalid IL or missing references)
		for (int i = 0; i < Random.Range(1, 4); i++)
		{
			int num = Random.Range(0, _cargos.Length - 1);
			for (int j = 0; j < Random.Range(1, 3); j++)
			{
				RE_Plugin.LogDebug($"Choice: {_cargos[num]}");
				GameObject val = PrefabsDirectory.instance.directory[_cargos[num]];
				float amount = (float)Math.Round((decimal)Random.Range(0f, val.GetComponent<ShipItem>().amount));
				SpawnItem(spawnPoint, val, amount);
			}
		}
		for (int k = 0; k < Random.Range(1, 2); k++)
		{
			int num2 = Random.Range(0, _consumables.Length - 1);
			RE_Plugin.LogDebug($"Choice: {_consumables[num2]}");
			GameObject val2 = PrefabsDirectory.instance.directory[_consumables[num2]];
			float amount2 = (float)Math.Round((decimal)Random.Range(0f, val2.GetComponent<ShipItem>().amount));
			SpawnItem(spawnPoint, val2, amount2);
		}
		for (int l = 0; l < Random.Range(5, 10); l++)
		{
			int num3 = Random.Range(0, _bottles.Length - 1);
			RE_Plugin.LogDebug($"Choice: {_bottles[num3]}");
			GameObject prefabGO = PrefabsDirectory.instance.directory[_bottles[num3]];
			float amount3 = 0f;
			SpawnItem(spawnPoint, prefabGO, amount3);
		}
		int num4 = Random.Range(0, _tobaccoCrates.Length - 1);
		RE_Plugin.LogDebug($"Choice: {_tobaccoCrates[num4]}");
		GameObject val3 = PrefabsDirectory.instance.directory[_tobaccoCrates[num4]];
		float amount4 = (float)Math.Round((decimal)Random.Range(0f, val3.GetComponent<ShipItem>().amount));
		SpawnItem(spawnPoint, val3, amount4);
		SpawnItem(spawnPoint, AssetLoader.SmallWreck, 1f, wreckage: true);
	}

	internal static void SpawnItem(Vector3 spawnPoint, GameObject prefabGO, float amount, bool wreckage = false)
	{
		//IL_0002: Unknown result type (might be due to invalid IL or missing references)
		//IL_0027: Unknown result type (might be due to invalid IL or missing references)
		GameObject val = Object.Instantiate<GameObject>(prefabGO, spawnPoint, Quaternion.Euler((float)Random.Range(0, 360), (float)Random.Range(0, 360), (float)Random.Range(0, 360)));
		ShipItem component = val.GetComponent<ShipItem>();
		component.sold = true;
		component.amount = amount;
		component.health = amount;
		val.GetComponent<SaveablePrefab>().RegisterToSave();
		Good component2 = val.GetComponent<Good>();
		if ((Object)(object)component2 != (Object)null)
		{
			component2.RegisterAsMissionless();
		}
		ShipItemCrate val2 = (ShipItemCrate)(object)((component is ShipItemCrate) ? component : null);
		if (val2 != null)
		{
			((MonoBehaviour)EncounterGenerator.Instance).StartCoroutine(UnsealCrate(val2));
		}
		if (wreckage)
		{
			((GoPointerButton)val.GetComponent<ShipItem>()).unclickable = true;
			val.transform.parent = Refs.shiftingWorld;
		}
		RE_Plugin.LogDebug("Prefab " + ((Object)prefabGO).name + " spawned");
	}

	internal static IEnumerator UnsealCrate(ShipItemCrate crate)
	{
		yield return (object)new WaitForEndOfFrame();
		yield return (object)new WaitForEndOfFrame();
		CrateInventory crateInventory = ((Component)crate).GetComponent<CrateInventory>();
		int num = (int)((ShipItem)crate).amount;
		for (int i = 0; i < num; i++)
		{
			RE_Plugin.LogDebug("Inserting item " + ((ShipItem)crate).amount);
			GameObject gameObject = Object.Instantiate<GameObject>(crate.GetContainedPrefab(), ((Component)crate).transform.position + new Vector3(0f, 100.5f, 0f), ((Component)crate).transform.rotation);
			((ShipItem)crate).amount = ((ShipItem)crate).amount - 1f;
			gameObject.GetComponent<SaveablePrefab>().RegisterToSave();
			if (Object.op_Implicit((Object)(object)gameObject.GetComponent<CookableFood>()))
			{
				if (crate.smokedFood)
				{
					gameObject.GetComponent<FoodState>().smoked = 1f;
					gameObject.GetComponent<ShipItem>().amount = 1.01f;
				}
				gameObject.GetComponent<FoodState>().dried = 1f;
				gameObject.GetComponent<CookableFood>().UpdateMaterial();
			}
			((MonoBehaviour)EncounterGenerator.Instance).StartCoroutine(InsertItem(crateInventory, gameObject.GetComponent<ShipItem>()));
		}
		((ShipItem)crate).UpdateLookText();
		((ShipItem)crate).itemRigidbodyC.UpdateMass();
		RE_Plugin.LogDebug("Unsealed crate.");
	}

	private static IEnumerator InsertItem(CrateInventory crateInventory, ShipItem item)
	{
		yield return (object)new WaitForEndOfFrame();
		item.sold = true;
		crateInventory.InsertItem(item);
	}
}
internal class IntenseStorm
{
	[HarmonyPatch(typeof(OceanUpdaterCrest))]
	private static class OceanUpdaterCrestPatches
	{
		[HarmonyPostfix]
		[HarmonyPatch("Awake")]
		public static void Awake(OceanUpdaterCrest __instance)
		{
			oceanUpdaterCrest = __instance;
		}
	}

	internal static OceanUpdaterCrest oceanUpdaterCrest;
}
[BepInPlugin("com.raddude82.randomencounters", "RandomEncounters", "1.4.0")]
[BepInDependency(/*Could not decode attribute arguments.*/)]
[BepInDependency(/*Could not decode attribute arguments.*/)]
[BepInDependency(/*Could not decode attribute arguments.*/)]
public class RE_Plugin : BaseUnityPlugin
{
	public const string PLUGIN_GUID = "com.raddude82.randomencounters";

	public const string PLUGIN_NAME = "RandomEncounters";

	public const string PLUGIN_VERSION = "1.4.0";

	public const string SEALIFEMOD_GUID = "com.yourname.sailwind.sealifeplugin";

	public const string IDLEFISHING_GUID = "ISA_IdleFishing";

	public const string HOOKSHANGMORE_GUID = "com.raddude82.hookshangmore";

	private static ManualLogSource _logger;

	internal static BaseUnityPlugin SeaLifeModPluginInstance { get; private set; }

	internal static bool IdleFishingPluginDetected { get; private set; }

	internal static bool HooksHangMorePluginDetected { get; private set; }

	internal static RE_Plugin Instance { get; private set; }

	internal static Harmony HarmonyInstance { get; private set; }

	public static bool IsFlotsamEnabled => Configs.enableFlotsam.Value;

	public static bool IsSeaLifeModEnabled => (Object)(object)SeaLifeModPluginInstance != (Object)null && Configs.controlSeaLifeMod.Value;

	public static bool IsIntenseStormEnabled => Configs.enableIntenseStorm.Value;

	public static bool IsDenseFogEnabled => Configs.enableDenseFog.Value;

	public static bool IsFishingBonanzaEnabled => Configs.enableFishingBonanza.Value;

	internal static void LogDebug(string message)
	{
		_logger.LogDebug((object)message);
	}

	internal static void LogInfo(string message)
	{
		_logger.LogInfo((object)message);
	}

	internal static void LogWarning(string message)
	{
		_logger.LogWarning((object)message);
	}

	internal static void LogError(string message)
	{
		_logger.LogError((object)message);
	}

	private void Awake()
	{
		if ((Object)(object)Instance != (Object)null && (Object)(object)Instance != (Object)(object)this)
		{
			Object.Destroy((Object)(object)((Component)this).gameObject);
			return;
		}
		Instance = this;
		_logger = ((BaseUnityPlugin)this).Logger;
		Configs.InitializeConfigs();
		((MonoBehaviour)this).StartCoroutine(AssetLoader.LoadAssetBundle());
		HarmonyInstance = Harmony.CreateAndPatchAll(Assembly.GetExecutingAssembly(), "com.raddude82.randomencounters");
		foreach (KeyValuePair<string, PluginInfo> pluginInfo in Chainloader.PluginInfos)
		{
			BepInPlugin metadata = pluginInfo.Value.Metadata;
			if (Configs.controlSeaLifeMod.Value && metadata.GUID.Equals("com.yourname.sailwind.sealifeplugin"))
			{
				LogInfo("SealLifeMod mod found");
				SeaLifeModPluginInstance = pluginInfo.Value.Instance;
				SeaLifeMod.PatchMod();
			}
			if (metadata.GUID.Equals("ISA_IdleFishing"))
			{
				LogInfo("IdleFishing mod found");
				IdleFishingPluginDetected = true;
			}
			if (metadata.GUID.Equals("com.raddude82.hookshangmore"))
			{
				LogInfo("HooksHangMore mod found");
				HooksHangMorePluginDetected = true;
			}
		}
		((Component)this).gameObject.AddComponent<EncounterGenerator>();
	}
}
internal class AssetLoader
{
	private static readonly List<string> assetPaths = new List<string>
	{
		Path.Combine(Path.GetDirectoryName(((BaseUnityPlugin)RE_Plugin.Instance).Info.Location), "Assets"),
		Path.Combine(Path.GetDirectoryName(((BaseUnityPlugin)RE_Plugin.Instance).Info.Location))
	};

	public static GameObject Hull { get; private set; }

	public static GameObject SmallWreck { get; private set; }

	public static string FindAssetPath(string fileName)
	{
		foreach (string assetPath in assetPaths)
		{
			string text = Path.Combine(assetPath, fileName);
			if (File.Exists(text))
			{
				return text;
			}
		}
		return null;
	}

	internal static IEnumerator LoadAssetBundle()
	{
		RE_Plugin.LogDebug("Loading bundle");
		string bundlePath = FindAssetPath("wreckage_bundle");
		if (string.IsNullOrEmpty(bundlePath))
		{
			RE_Plugin.LogError("Asset bundle path not found");
			yield break;
		}
		AssetBundleCreateRequest assetBundleRequest = AssetBundle.LoadFromFileAsync(bundlePath);
		yield return assetBundleRequest;
		AssetBundle assetBundle = assetBundleRequest.assetBundle;
		if ((Object)(object)assetBundle == (Object)null)
		{
			RE_Plugin.LogError("Failed to load " + bundlePath);
		}
		AssetBundleRequest request = assetBundle.LoadAllAssetsAsync();
		yield return request;
		Object? obj = ((IEnumerable<Object>)request.allAssets).FirstOrDefault((Func<Object, bool>)((Object a) => a.name == "hull"));
		Hull = (GameObject)(object)((obj is GameObject) ? obj : null);
		Object? obj2 = ((IEnumerable<Object>)request.allAssets).FirstOrDefault((Func<Object, bool>)((Object a) => a.name == "small_wreck"));
		SmallWreck = (GameObject)(object)((obj2 is GameObject) ? obj2 : null);
		if ((Object)(object)Hull == (Object)null || (Object)(object)SmallWreck == (Object)null)
		{
			RE_Plugin.LogError("Failed to load all assets from the bundle");
		}
		else
		{
			RE_Plugin.LogInfo("Assets loaded");
		}
	}
}
internal class Configs
{
	internal static ConfigEntry<int> encounterRollChance;

	internal static ConfigEntry<int> generateEncounterMinTime;

	internal static ConfigEntry<int> generateEncounterTimeRange;

	internal static ConfigEntry<bool> enableFlotsam;

	internal static ConfigEntry<bool> controlSeaLifeMod;

	internal static ConfigEntry<bool> enableDenseFog;

	internal static ConfigEntry<int> fogDuration;

	internal static ConfigEntry<bool> enableFishingBonanza;

	internal static ConfigEntry<int> fishingBonanzaDuration;

	internal static ConfigEntry<bool> enableIntenseStorm;

	internal static ConfigEntry<int> intenseStormDuration;

	internal static void InitializeConfigs()
	{
		//IL_002b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0035: Expected O, but got Unknown
		ConfigFile config = ((BaseUnityPlugin)RE_Plugin.Instance).Config;
		encounterRollChance = config.Bind<int>("Encounter Generation Settings", "Chance an encounter occurs", 60, new ConfigDescription("Percent chance an encounter occurs.", (AcceptableValueBase)(object)new AcceptableValueRange<int>(0, 100), Array.Empty<object>()));
		generateEncounterMinTime = config.Bind<int>("Encounter Generation Settings", "Minimum encounter chance time", 900, "Minimum time in seconds to get a chance roll for an encounter, a random amount of time from the 'Variation in encounter chance time' setting will be added to this.");
		generateEncounterTimeRange = config.Bind<int>("Encounter Generation Settings", "Variation in encounter chance time", 300, "A random number of seconds from 0 up to the value specified will be added to the 'Minimum encounter chance time' setting.");
		enableFlotsam = config.Bind<bool>("Encounter Types", "Enable flotsam encounters", true, (ConfigDescription)null);
		controlSeaLifeMod = config.Bind<bool>("Encounter Types", "Control SeaLifeMod spawns", true, "Use this mod to control SeaLifeMod spawns.");
		enableDenseFog = config.Bind<bool>("Encounter Types", "Enable dense fog encounters", true, (ConfigDescription)null);
		enableFishingBonanza = config.Bind<bool>("Encounter Types", "Enable fishing bonanza encounters", true, (ConfigDescription)null);
		enableIntenseStorm = config.Bind<bool>("Encounter Types", "Enable intense storm encounters", true, (ConfigDescription)null);
		fogDuration = config.Bind<int>("Encounter Settings", "Fog encounter duration", 300, "In seconds, the amount of time the fog encounter lasts.");
		fishingBonanzaDuration = config.Bind<int>("Encounter Settings", "Fishing bonanza duration", 300, "In seconds, the amount of time the fishing bonanza encounter lasts.");
		intenseStormDuration = config.Bind<int>("Encounter Settings", "Intense storm duration", 300, "In seconds, the amount of time the intense storm encounter lasts.");
	}
}
internal static class Extensions
{
	public static T GetPrivateField<T>(this object obj, string field)
	{
		return (T)Traverse.Create(obj).Field(field).GetValue();
	}

	public static void SetPrivateField(this object obj, string field, object value)
	{
		Traverse.Create(obj).Field(field).SetValue(value);
	}

	public static T InvokePrivateMethod<T>(this object obj, string method)
	{
		return Traverse.Create(obj).Method(method, Array.Empty<object>()).GetValue<T>();
	}

	public static T InvokePrivateMethod<T>(this object obj, string method, params object[] parameters)
	{
		return Traverse.Create(obj).Method(method, parameters).GetValue<T>();
	}
}