Decompiled source of RandomEncounters v2.0.0

RandomEncounters/RandomEncounters.dll

Decompiled 6 days ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.Globalization;
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 RandomEncounters.API;
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("https://github.com/bryon82/SailwindRandomEncounters")]
[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("2.0.0.0")]
[assembly: TargetFramework(".NETFramework,Version=v4.8", FrameworkDisplayName = ".NET Framework 4.8")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("2.0.0.0")]
[module: UnverifiableCode]
namespace RandomEncounters
{
	internal class SeaLifeMod
	{
		private static List<GameObject> _whaleSpawns;

		private static Type _finWhaleAIType;

		private static Type _effectControllerType;

		private static FastInvokeHandler _triggerRandomAnimation;

		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 bool _allSoundsLoaded;

		private static int _groupsCompleted;

		private const int TOTAL_GROUPS = 4;

		private const float MAX_DISTANCE = 650f;

		internal static int ActiveWhales { get; set; }

		internal static bool WhalesReady { get; set; }

		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");
			_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);
				_whaleSpawns.Add(whale);
			}
			WhalesReady = true;
		}

		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 = _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 whaleSpawn in _whaleSpawns)
			{
				float num = Vector3.Distance(whaleSpawn.transform.position, ((Component)Refs.observerMirror).transform.position);
				if (whaleSpawn.activeInHierarchy && num > 650f)
				{
					RE_Plugin.LogDebug("Removing FinWhale");
					whaleSpawn.SetActive(false);
					ActiveWhales--;
				}
			}
		}

		private static IEnumerator LoadSoundsAsync()
		{
			_groupsCompleted = 0;
			_allSoundsLoaded = false;
			_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 (_groupsCompleted < 4)
			{
				yield return null;
			}
			_allSoundsLoaded = true;
		}

		private static IEnumerator LoadAudioClipsAsync(string baseName, int count, Action<AudioClip[]> onComplete)
		{
			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);
			}
			onComplete(clips);
			_groupsCompleted++;
		}
	}
	public class SeaLifeModPatches
	{
		[HarmonyPrefix]
		public static bool DoNotRun()
		{
			return false;
		}
	}
	internal class EncounterGenerator : MonoBehaviour
	{
		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;
			EncounterRegistry.RegisterEncounter(new FlotsamEncounter());
			EncounterRegistry.RegisterEncounter(new WhalesEncounter());
			EncounterRegistry.RegisterEncounter(new DenseFogEncounter());
			EncounterRegistry.RegisterEncounter(new FishingBonanzaEncounter());
			EncounterRegistry.RegisterEncounter(new IntenseStormEncounter());
			EncounterRegistry.RegisterEncounter(new FogAndWhalesEncounter());
			EncounterRegistry.RegisterEncounter(new FlotsamAndWhalesEncounter());
			((MonoBehaviour)this).StartCoroutine(ScheduleEncounter());
		}

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

		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");
				EncounterEvents.RaiseEncounterSkipped();
				return;
			}
			List<Encounter> list = EncounterRegistry.GetAvailable().ToList();
			if (list.Count == 0)
			{
				RE_Plugin.LogInfo("No encounters enabled");
				return;
			}
			int num = list.Sum((Encounter e) => e.Weight);
			int num2 = Random.Range(0, num);
			int num3 = 0;
			foreach (Encounter item in list)
			{
				num3 += item.Weight;
				if (num2 < num3)
				{
					RE_Plugin.LogInfo("Encounter: " + item.Name);
					EncounterEvents.RaiseEncounterTriggered(item);
					item.Trigger();
					break;
				}
			}
		}

		internal void LoadEncounter()
		{
			((MonoBehaviour)this).StartCoroutine(EncounterLoader());
		}

		private IEnumerator EncounterLoader()
		{
			string encounterName = ModData.GetEntry<string>("RandomEncounters.EncounterName");
			float timeRemaining = ModData.GetEntry<float>("RandomEncounters.EncounterTimeRemaining");
			int whaleCount = ModData.GetEntry<int>("RandomEncounters.WhaleCount");
			RE_Plugin.LogDebug($"Loaded encounter data: Name={encounterName}, TimeRemaining={timeRemaining}, WhaleCount={whaleCount}");
			yield return (object)new WaitUntil((Func<bool>)(() => GameState.playing && !GameState.currentlyLoading));
			if (!string.IsNullOrEmpty(encounterName) && timeRemaining > 0f)
			{
				Encounter enc = EncounterRegistry.GetByName(encounterName);
				if (enc?.IsAvailable ?? false)
				{
					RE_Plugin.LogInfo($"Restoring encounter: {encounterName} with {timeRemaining} seconds remaining.");
					enc.TimeRemaining = timeRemaining;
					enc.Trigger();
				}
			}
			if (whaleCount > 0)
			{
				WhalesEncounter whalesEncounter = (WhalesEncounter)EncounterRegistry.GetByName("Whales");
				if (whalesEncounter?.IsAvailable ?? false)
				{
					whalesEncounter.TriggerWasActive(whaleCount);
				}
			}
		}

		internal void SaveEncounter()
		{
			Encounter active = EncounterRegistry.GetActive();
			if (active != null)
			{
				RE_Plugin.LogDebug($"Saving encounter data: Name={active.Name}, TimeRemaining={active.TimeRemaining}");
				ModData.AddEntry("RandomEncounters.EncounterName", active.Name);
				ModData.AddEntry("RandomEncounters.EncounterTimeRemaining", active.TimeRemaining);
			}
			else
			{
				ModData.AddEntry("RandomEncounters.EncounterName", string.Empty);
				ModData.AddEntry("RandomEncounters.EncounterTimeRemaining", 0f);
			}
			ModData.AddEntry("RandomEncounters.WhaleCount", SeaLifeMod.ActiveWhales);
		}
	}
	internal class DenseFogEncounter : Encounter
	{
		[HarmonyPatch(typeof(OceanColorBlender))]
		private class OceanColorBlenderPatches
		{
			[HarmonyPrefix]
			[HarmonyPatch("ApplyPalette")]
			public static void ApplyFogDensity(ref OceanColorPalette palette)
			{
				if (!_fogCleared)
				{
					_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)
					{
						_fogCleared = true;
						_currentFogDensity = 0f;
						_originalFogDensity = 0f;
						GameObject.Find("wind").GetComponent<Wind>().SetPrivateField("timer", 0);
						RE_Plugin.LogDebug("Fog cleared");
					}
				}
			}
		}

		[HarmonyPatch(typeof(Wind))]
		private class WindPatches
		{
			[HarmonyPrefix]
			[HarmonyPatch("SetNewGustTarget")]
			public static bool NoGust(ref Vector3 ___currentGustTarget, Vector3 ___currentWindTarget)
			{
				//IL_0019: 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)
				if (_fogCleared || _clearFog)
				{
					return true;
				}
				___currentGustTarget = ___currentWindTarget;
				return false;
			}

			[HarmonyPrefix]
			[HarmonyPatch("SetNewWindTarget")]
			public static bool LightWind(ref Vector3 ___currentWindTarget)
			{
				//IL_001e: 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)
				if (_fogCleared || _clearFog)
				{
					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 (_fogCleared || _clearFog)
				{
					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 (_fogCleared || _clearFog)
				{
					return true;
				}
				return false;
			}

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

		private static readonly Dictionary<AudioSource, float> _waveAudioSources = new Dictionary<AudioSource, float>();

		private static (AudioSource source, float origVolume) _windAudioSource;

		private static bool _clearFog = false;

		private static bool _fogCleared = true;

		private static float _currentFogDensity = 0f;

		private static float _originalFogDensity = 0f;

		private const float MAX_FOG_DENSITY = 0.06f;

		public override string Name => "Dense Fog";

		public override int Weight => 5;

		public override bool IsAvailable => Configs.enableDenseFog.Value && !base.IsActive && WeatherStorms.instance.InvokePrivateMethod<float>("GetNormalizedDistance") >= 0.75f;

		public override void Trigger()
		{
			Runner(Run());
		}

		private IEnumerator Run()
		{
			base.IsActive = true;
			Spawn();
			List<AudioSource> waveAudioSources = _waveAudioSources.Keys.ToList();
			AudioSource windAudioSource = _windAudioSource.source;
			float windOrigVolume = _windAudioSource.origVolume;
			for (float t = 0f; t < 4f; t += Time.deltaTime)
			{
				float lerpValue = t / 4f;
				foreach (AudioSource audioSource in waveAudioSources)
				{
					audioSource.volume = Mathf.Lerp(_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);
			}
			float duration = ((base.TimeRemaining > 0f) ? base.TimeRemaining : ((float)Configs.fogDuration.Value));
			float elapsed = 0f;
			while (elapsed < duration)
			{
				elapsed += Time.deltaTime;
				base.TimeRemaining = duration - elapsed;
				yield return null;
			}
			ClearFog();
			for (float t2 = 0f; t2 < 4f; t2 += Time.deltaTime)
			{
				float lerpValue2 = t2 / 4f;
				foreach (AudioSource audioSource2 in waveAudioSources)
				{
					audioSource2.volume = Mathf.Lerp(0f, _waveAudioSources[audioSource2], lerpValue2);
				}
				if ((Object)(object)windAudioSource != (Object)null)
				{
					windAudioSource.volume = Mathf.Lerp(0.0001f, windOrigVolume, lerpValue2);
				}
				yield return null;
			}
			base.IsActive = false;
			EncounterEvents.RaiseEncounterCompleted(this);
		}

		private 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;
			_fogCleared = false;
		}

		private static void ClearFog()
		{
			RE_Plugin.LogDebug("Clearing fog");
			_clearFog = true;
		}
	}
	public abstract class Encounter
	{
		public abstract string Name { get; }

		public abstract int Weight { get; }

		public float TimeRemaining { get; set; }

		public bool IsActive { get; internal set; }

		public abstract bool IsAvailable { get; }

		public Coroutine Runner(IEnumerator enumerator)
		{
			return ((MonoBehaviour)EncounterGenerator.Instance).StartCoroutine(enumerator);
		}

		public abstract void Trigger();
	}
	internal class FishingBonanzaEncounter : Encounter
	{
		[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_0096: Unknown result type (might be due to invalid IL or missing references)
				//IL_00a1: Unknown result type (might be due to invalid IL or missing references)
				//IL_0051: Unknown result type (might be due to invalid IL or missing references)
				//IL_0056: Unknown result type (might be due to invalid IL or missing references)
				if (!EncounterRegistry.GetByName("Fishing Bonanza").IsActive || (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();
					}
				}
			}
		}

		private static Seagulls _seagulls;

		public override string Name => "Fishing Bonanza";

		public override int Weight => 15;

		public override bool IsAvailable => Configs.enableFishingBonanza.Value && GameState.playing && Object.op_Implicit((Object)(object)GameState.currentBoat) && !base.IsActive && WeatherStorms.instance.InvokePrivateMethod<float>("GetNormalizedDistance") >= 0.75f;

		public override void Trigger()
		{
			Runner(Run());
		}

		private IEnumerator Run()
		{
			if ((Object)(object)_seagulls == (Object)null)
			{
				_seagulls = ((Component)Refs.shiftingWorld).GetComponentInChildren<Seagulls>(true);
			}
			if ((Object)(object)_seagulls == (Object)null)
			{
				RE_Plugin.LogDebug("No seagulls found");
				yield break;
			}
			GameObject seagulls = Object.Instantiate<GameObject>(((Component)_seagulls).gameObject, 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(base.TimeRemaining);
			((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");
			base.IsActive = true;
			float duration = ((base.TimeRemaining > 0f) ? base.TimeRemaining : ((float)Configs.fishingBonanzaDuration.Value));
			float elapsed = 0f;
			while (elapsed < duration)
			{
				elapsed += Time.deltaTime;
				base.TimeRemaining = duration - elapsed;
				Vector3 targetPosition = GameState.currentBoat.position + GameState.currentBoat.up * 40f;
				seagulls.transform.position = Vector3.Lerp(seagulls.transform.position, targetPosition, 0.2f * Time.deltaTime);
				Vector3 euler = seagulls.transform.eulerAngles;
				euler.y = Mathf.LerpAngle(euler.y, GameState.currentBoat.eulerAngles.y - 90f, 0.2f * Time.deltaTime);
				seagulls.transform.rotation = Quaternion.Euler(euler);
				yield return null;
			}
			RE_Plugin.LogDebug("Stopping fishing bonanza");
			base.IsActive = false;
			Object.Destroy((Object)(object)seagulls);
			base.TimeRemaining = 0f;
			EncounterEvents.RaiseEncounterCompleted(this);
		}
	}
	internal class FlotsamAndWhalesEncounter : Encounter
	{
		public override string Name => "Flotsam and Whales";

		public override int Weight => 10;

		public override bool IsAvailable => Configs.controlSeaLifeMod.Value && (Object)(object)RE_Plugin.SeaLifeModPluginInstance != (Object)null && Configs.enableFlotsam.Value;

		public override void Trigger()
		{
			EncounterRegistry.GetByName("Flotsam")?.Trigger();
			EncounterRegistry.GetByName("Whales")?.Trigger();
		}
	}
	internal class FlotsamEncounter : Encounter
	{
		private static readonly int[] _cargos = new int[40]
		{
			1, 2, 3, 4, 5, 6, 7, 8, 9, 10,
			11, 13, 14, 15, 16, 17, 18, 19, 24, 26,
			27, 201, 202, 206, 213, 214, 216, 219, 220, 222,
			223, 224, 227, 228, 229, 230, 231, 232, 233, 234
		};

		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 static readonly int[] _teaAndCoffeeBoxes = new int[4] { 387, 388, 389, 373 };

		private const int MAX_CARGO_TYPES = 4;

		private const int MAX_CARGOS = 3;

		private const int MAX_CONSUME_TYPES = 2;

		public override string Name => "Flotsam";

		public override int Weight => 15;

		public override bool IsAvailable => Configs.enableFlotsam.Value;

		public override void Trigger()
		{
			Run();
		}

		private void Run()
		{
			//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);
			Spawn(spawnPoint);
			EncounterEvents.RaiseEncounterCompleted(this);
		}

		internal static void Spawn(Vector3 spawnPoint)
		{
			//IL_006a: Unknown result type (might be due to invalid IL or missing references)
			//IL_010a: Unknown result type (might be due to invalid IL or missing references)
			//IL_017f: Unknown result type (might be due to invalid IL or missing references)
			//IL_01f8: Unknown result type (might be due to invalid IL or missing references)
			//IL_025a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0267: 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($"Cargo choice: {_cargos[num]}");
					GameObject val = PrefabsDirectory.instance.directory[_cargos[num]];
					int num2 = Random.Range(1, (int)val.GetComponent<ShipItem>().amount + 1);
					Flotsam.SpawnItem(spawnPoint, val, num2);
				}
			}
			for (int k = 0; k < Random.Range(1, 2); k++)
			{
				int num3 = Random.Range(0, _consumables.Length - 1);
				RE_Plugin.LogDebug($"Consumable choice: {_consumables[num3]}");
				GameObject val2 = PrefabsDirectory.instance.directory[_consumables[num3]];
				int num4 = Random.Range(1, (int)val2.GetComponent<ShipItem>().amount + 1);
				Flotsam.SpawnItem(spawnPoint, val2, num4);
			}
			for (int l = 0; l < Random.Range(5, 10); l++)
			{
				int num5 = Random.Range(0, _bottles.Length - 1);
				RE_Plugin.LogDebug($"Bottle choice: {_bottles[num5]}");
				GameObject prefabGO = PrefabsDirectory.instance.directory[_bottles[num5]];
				float amount = 0f;
				Flotsam.SpawnItem(spawnPoint, prefabGO, amount);
			}
			int num6 = Random.Range(0, _tobaccoCrates.Length - 1);
			RE_Plugin.LogDebug($"Tobacco choice: {_tobaccoCrates[num6]}");
			GameObject val3 = PrefabsDirectory.instance.directory[_tobaccoCrates[num6]];
			int num7 = Random.Range(1, (int)val3.GetComponent<ShipItem>().amount + 1);
			Flotsam.SpawnItem(spawnPoint, val3, num7);
			int num8 = Random.Range(0, _teaAndCoffeeBoxes.Length - 1);
			RE_Plugin.LogDebug($"Tea/Coffee choice: {_teaAndCoffeeBoxes[num8]}");
			GameObject val4 = PrefabsDirectory.instance.directory[_teaAndCoffeeBoxes[num8]];
			int num9 = Random.Range(1, (int)val4.GetComponent<ShipItem>().amount + 1);
			Flotsam.SpawnItem(spawnPoint, val4, num9);
			Flotsam.SpawnItem(spawnPoint, AssetLoader.SmallWreck, 1f, wreckage: true);
		}
	}
	internal class FogAndWhalesEncounter : Encounter
	{
		private readonly Encounter denseFogEncounter = EncounterRegistry.GetByName("Dense Fog");

		public override string Name => "Dense Fog and Whales";

		public override int Weight => 5;

		public override bool IsAvailable => Configs.controlSeaLifeMod.Value && (Object)(object)RE_Plugin.SeaLifeModPluginInstance != (Object)null && Configs.enableDenseFog.Value && !denseFogEncounter.IsActive && WeatherStorms.instance.InvokePrivateMethod<float>("GetNormalizedDistance") >= 0.75f;

		public override void Trigger()
		{
			denseFogEncounter.Trigger();
			Encounter byName = EncounterRegistry.GetByName("Whales");
			byName.Trigger();
		}
	}
	internal class Flotsam
	{
		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 IntenseStormEncounter : Encounter
	{
		[HarmonyPatch(typeof(OceanUpdaterCrest))]
		private static class OceanUpdaterCrestPatches
		{
			[HarmonyPostfix]
			[HarmonyPatch("Awake")]
			public static void Awake(OceanUpdaterCrest __instance)
			{
				_oceanUpdaterCrest = __instance;
			}
		}

		private static OceanUpdaterCrest _oceanUpdaterCrest;

		public override string Name => "Intense Storm";

		public override int Weight => 5;

		public override bool IsAvailable => Configs.enableIntenseStorm.Value && !base.IsActive;

		public override void Trigger()
		{
			Runner(Run());
		}

		private IEnumerator Run()
		{
			base.IsActive = true;
			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 = _oceanUpdaterCrest.inertiaWindScale;
			float origWindSpeedMult = _oceanUpdaterCrest.GetPrivateField<float>("windSpeedMult");
			float origSmallWavesMult = _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 = (((double)weatherStorms.InvokePrivateMethod<float>("GetNormalizedDistance") < 0.66) ? 0.0025f : 0.125f);
				((Component)storm).transform.Translate(vector * translateSpeed);
				yield return (object)new WaitForSeconds(0.05f);
				stormDist = Vector3.Distance(((Component)Camera.main).transform.position, ((Component)storm).transform.position);
			}
			RE_Plugin.LogDebug(((Object)storm).name + " arrived");
			_oceanUpdaterCrest.inertiaWindScale = 0.22f;
			_oceanUpdaterCrest.SetPrivateField("windSpeedMult", 5f);
			_oceanUpdaterCrest.SetPrivateField("smallWavesMult", 0.4f);
			float duration = ((base.TimeRemaining > 0f) ? base.TimeRemaining : ((float)Configs.intenseStormDuration.Value));
			float elapsed = 0f;
			while (elapsed < duration)
			{
				elapsed += Time.deltaTime;
				base.TimeRemaining = duration - elapsed;
				Wind.currentBaseWind = vector * 50f;
				yield return null;
			}
			RE_Plugin.LogDebug(((Object)storm).name + " dying down");
			lightning.SetPrivateField("lightningInterval", origLightningInterval);
			Weather.instance.currentRegion.stormWeather.particles.rainDensity = origRainDensity;
			_oceanUpdaterCrest.inertiaWindScale = origInertiaWindScale;
			_oceanUpdaterCrest.SetPrivateField("windSpeedMult", origWindSpeedMult);
			_oceanUpdaterCrest.SetPrivateField("smallWavesMult", origSmallWavesMult);
			base.IsActive = false;
			base.TimeRemaining = 0f;
			EncounterEvents.RaiseEncounterCompleted(this);
		}
	}
	internal class WhalesEncounter : Encounter
	{
		public override string Name => "Whales";

		public override int Weight => 25;

		public override bool IsAvailable => Configs.controlSeaLifeMod.Value && (Object)(object)RE_Plugin.SeaLifeModPluginInstance != (Object)null;

		public override void Trigger()
		{
			Runner(Run());
		}

		internal void TriggerWasActive(int whaleCount)
		{
			Runner(Run(whaleCount));
		}

		private IEnumerator Run(int whaleCount = -1)
		{
			Vector3 boatPosition = GameState.currentBoat.position;
			int spawnCount = Random.Range(2, 5);
			if (whaleCount > 0)
			{
				spawnCount = whaleCount;
			}
			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();
			if (whaleCount == -1)
			{
				EncounterEvents.RaiseEncounterCompleted(this);
			}
		}
	}
	[BepInPlugin("com.raddude.randomencounters", "RandomEncounters", "2.0.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.raddude.randomencounters";

		public const string PLUGIN_NAME = "RandomEncounters";

		public const string PLUGIN_VERSION = "2.0.0";

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

		public const string IDLEFISHING_GUID = "ISA_IdleFishing";

		public const string HOOKSHANGMORE_GUID = "com.raddude.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.raddude.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.raddude.hookshangmore"))
				{
					LogInfo("HooksHangMore mod found");
					HooksHangMorePluginDetected = true;
				}
				if ((Object)(object)SeaLifeModPluginInstance != (Object)null && IdleFishingPluginDetected && HooksHangMorePluginDetected)
				{
					break;
				}
			}
			((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. <b>Requires restart to take effect.</b>");
			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>();
		}
	}
	internal class ModData
	{
		[HarmonyPatch(typeof(SaveLoadManager))]
		private class SaveLoadManagerPatches
		{
			[HarmonyPrefix]
			[HarmonyPatch("SaveModData")]
			public static void SaveModData()
			{
				EncounterGenerator.Instance.SaveEncounter();
			}

			[HarmonyPrefix]
			[HarmonyPatch("LoadModData")]
			public static void LoadModData()
			{
				EncounterGenerator.Instance.LoadEncounter();
			}
		}

		public static void AddEntry<T>(string dataName, T data)
		{
			string value = ((!(typeof(T) == typeof(float))) ? data.ToString() : ((float)(object)data).ToString(CultureInfo.InvariantCulture));
			if (GameState.modData.ContainsKey(dataName))
			{
				GameState.modData[dataName] = value;
			}
			else
			{
				GameState.modData.Add(dataName, value);
			}
		}

		public static T GetEntry<T>(string dataName)
		{
			if (!GameState.modData.ContainsKey(dataName))
			{
				RE_Plugin.LogWarning("GetEntry: " + dataName + " not found in modData");
				return default(T);
			}
			string text = GameState.modData[dataName];
			if (typeof(T) == typeof(float))
			{
				return (T)(object)float.Parse(text, CultureInfo.InvariantCulture);
			}
			return (T)Convert.ChangeType(text, typeof(T));
		}
	}
}
namespace RandomEncounters.API
{
	public class EncounterEvents
	{
		public static event Action<Encounter> EncounterTriggered;

		public static event Action<Encounter> EncounterCompleted;

		public static event Action EncounterSkipped;

		internal static void RaiseEncounterTriggered(Encounter enc)
		{
			EncounterEvents.EncounterTriggered?.Invoke(enc);
		}

		public static void RaiseEncounterCompleted(Encounter enc)
		{
			EncounterEvents.EncounterCompleted?.Invoke(enc);
		}

		internal static void RaiseEncounterSkipped()
		{
			EncounterEvents.EncounterSkipped?.Invoke();
		}
	}
	public static class EncounterRegistry
	{
		internal static readonly List<Encounter> RegisteredEncounters = new List<Encounter>();

		public static void RegisterEncounter(Encounter enc)
		{
			RegisteredEncounters.Add(enc);
		}

		internal static IEnumerable<Encounter> GetAvailable()
		{
			return RegisteredEncounters.Where((Encounter e) => e.IsAvailable);
		}

		internal static Encounter GetByName(string name)
		{
			return RegisteredEncounters.FirstOrDefault((Encounter e) => e.Name == name);
		}

		internal static Encounter GetActive()
		{
			return RegisteredEncounters.FirstOrDefault((Encounter e) => e.IsActive);
		}
	}
}