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 © 2025")]
[assembly: AssemblyTrademark("")]
[assembly: ComVisible(false)]
[assembly: Guid("06b0b4cd-89d7-4ff2-8dc9-3eaa535b8d99")]
[assembly: AssemblyFileVersion("1.2.0.0")]
[assembly: TargetFramework(".NETFramework,Version=v4.8", FrameworkDisplayName = ".NET Framework 4.8")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.2.0.0")]
[module: UnverifiableCode]
namespace RandomEncounters;
internal class SeaLifeMod
{
private static List<GameObject> s_whaleSpawns;
private static Type s_finWhaleAIType;
private static Type s_effectControllerType;
private static FastInvokeHandler s_triggerRandomAnimation;
private static int s_activeWhales;
private static Component s_whale0Ai;
private static AssetBundle s_assetBundle;
private static AudioClip[] s_blowholeSounds;
private static AudioClip[] s_breachSplashSounds;
private static AudioClip[] s_breachEmergeSounds;
private static AudioClip[] s_tailSplashSounds;
private static int s_soundsToLoad;
private static int s_soundsLoaded;
private static bool s_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();
s_finWhaleAIType = AccessTools.TypeByName("FinWhaleAI");
s_effectControllerType = AccessTools.TypeByName("EffectController");
MethodInfo methodInfo = AccessTools.Method(s_finWhaleAIType, "TriggerRandomAnimation", (Type[])null, (Type[])null);
s_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(s_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(s_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 && s_allSoundsLoaded));
for (int i = 0; i < 5; i++)
{
GameObject whale = Object.Instantiate<GameObject>(whalePrefab, ((Component)Refs.shiftingWorld).transform);
Component ai = whale.AddComponent(s_finWhaleAIType);
if (i == 0)
{
s_whale0Ai = ai;
}
Component effectController = whale.AddComponent(s_effectControllerType);
effectController.SetPrivateField("blowholeSounds", s_blowholeSounds);
effectController.SetPrivateField("breachSplashSounds", s_breachSplashSounds);
effectController.SetPrivateField("breachEmergeSounds", s_breachEmergeSounds);
effectController.SetPrivateField("tailSplashSounds", s_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);
s_activeWhales++;
}
internal static void TriggerEntranceAnimation()
{
s_triggerRandomAnimation.Invoke((object)s_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 (s_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);
s_activeWhales--;
}
}
}
private static IEnumerator LoadSoundsAsync()
{
s_soundsToLoad = 0;
s_soundsLoaded = 0;
s_assetBundle = RE_Plugin.SeaLifeModPluginInstance.GetPrivateField<AssetBundle>("seaLifeBundle");
((MonoBehaviour)RE_Plugin.Instance).StartCoroutine(LoadAudioClipsAsync("WhaleBlowMed", 6, delegate(AudioClip[] clips)
{
s_blowholeSounds = clips;
}));
((MonoBehaviour)RE_Plugin.Instance).StartCoroutine(LoadAudioClipsAsync("BreachSplashLarge", 5, delegate(AudioClip[] clips)
{
s_breachSplashSounds = clips;
}));
((MonoBehaviour)RE_Plugin.Instance).StartCoroutine(LoadAudioClipsAsync("BreachSplashSmall", 6, delegate(AudioClip[] clips)
{
s_breachEmergeSounds = clips;
}));
((MonoBehaviour)RE_Plugin.Instance).StartCoroutine(LoadAudioClipsAsync("TailSplash", 4, delegate(AudioClip[] clips)
{
s_tailSplashSounds = clips;
}));
while (s_soundsLoaded < s_soundsToLoad)
{
yield return null;
}
s_allSoundsLoaded = true;
}
private static IEnumerator LoadAudioClipsAsync(string baseName, int count, Action<AudioClip[]> onComplete)
{
s_soundsToLoad += count;
AudioClip[] clips = (AudioClip[])(object)new AudioClip[count];
for (int i = 0; i < count; i++)
{
string clipName = $"{baseName}{i + 1:00}";
AssetBundleRequest request = s_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);
s_soundsLoaded++;
}
while (s_soundsLoaded < s_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;
private const int ENCOUNTER_TIME_RANGE = 300;
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 IEnumerator ScheduleEncounter()
{
int maxTime = Configs.generateEncounterMinTime.Value + 300;
int timeToNextEncounter = Random.Range(Configs.generateEncounterMinTime.Value, maxTime);
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;
}
int num = Random.Range(1, 100);
RE_Plugin.LogDebug($"Roll: {num}");
int num2 = num;
int num3 = num2;
if (num3 <= 10)
{
GenerateFlotsam();
return;
}
int num4 = num3;
if (num4 > 10 && num4 <= 15)
{
GenerateFlotsam();
((MonoBehaviour)this).StartCoroutine(GenerateWhales());
return;
}
int num5 = num3;
if (num5 > 15 && num5 <= 40)
{
((MonoBehaviour)this).StartCoroutine(GenerateWhales());
return;
}
int num6 = num3;
if (num6 > 40 && num6 <= 45)
{
((MonoBehaviour)this).StartCoroutine(GenerateDenseFog());
return;
}
int num7 = num3;
if (num7 > 45 && num7 <= 55)
{
((MonoBehaviour)this).StartCoroutine(GenerateFishingBonanza());
return;
}
int num8 = num3;
if (num8 > 55 && num8 <= 60)
{
((MonoBehaviour)this).StartCoroutine(GenerateIntenseStorm());
}
}
private static void GenerateFlotsam()
{
//IL_0019: 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_002d: Unknown result type (might be due to invalid IL or missing references)
//IL_0032: 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_004b: 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_0055: 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 (Configs.enableFlotsam.Value)
{
Vector3 spawnPoint = GameState.currentBoat.position + GameState.currentBoat.right * 100f + GameState.currentBoat.forward * (float)Random.Range(-30, 30);
Flotsam.Spawn(spawnPoint);
}
}
private IEnumerator GenerateWhales()
{
if (Configs.controlSeaLifeMod.Value && !((Object)(object)RE_Plugin.SeaLifeModPluginInstance == (Object)null))
{
Vector3 boatPosition = GameState.currentBoat.position;
for (int i = 0; i < Random.Range(2, 5); i++)
{
Vector3 randomOffset = new Vector3((float)Random.Range(-200, 200), -8f, (float)Random.Range(-200, 200));
yield return (object)new WaitForSeconds(2f);
SeaLifeMod.SpawnWhale(i, boatPosition + randomOffset);
}
yield return (object)new WaitForSeconds(2f);
SeaLifeMod.TriggerEntranceAnimation();
}
}
private IEnumerator GenerateDenseFog()
{
if (!Configs.enableDenseFog.Value || DenseFog.IsRunning || WeatherStorms.instance.InvokePrivateMethod<float>("GetNormalizedDistance") < 0.75f)
{
yield break;
}
DenseFog.Spawn();
for (int i = 0; i < 4000; i++)
{
foreach (AudioSource audioSource in DenseFog.WaveAudioSources.Keys)
{
audioSource.volume = Mathf.Lerp(DenseFog.WaveAudioSources[audioSource], 0f, (float)i / 1000f);
}
DenseFog.WindAudioSource.source.volume = Mathf.Lerp(DenseFog.WindAudioSource.origVolume, 0.0001f, (float)i / 1000f);
yield return (object)new WaitForSeconds(0.001f);
}
for (int k = 0; k < 4; k++)
{
Vector3 spawnPoint = GameState.currentBoat.position + GameState.currentBoat.right * (200f + Random.Range(20f, 60f) * (float)k) + GameState.currentBoat.forward * (float)Random.Range(-200, 200);
Flotsam.SpawnItem(spawnPoint, AssetLoader.Hull, 1f, wreckage: true);
yield return (object)new WaitForSeconds(1f);
Flotsam.SpawnItem(spawnPoint, AssetLoader.Mast, 1f, wreckage: true);
yield return (object)new WaitForSeconds(1f);
Flotsam.SpawnItem(spawnPoint, AssetLoader.Bowsprit, 1f, wreckage: true);
yield return (object)new WaitForSeconds(1f);
}
yield return (object)new WaitForSeconds((float)Configs.fogDuration.Value);
DenseFog.ClearFog();
for (int j = 0; j < 1000; j++)
{
foreach (AudioSource audioSource2 in DenseFog.WaveAudioSources.Keys)
{
audioSource2.volume = Mathf.Lerp(0f, DenseFog.WaveAudioSources[audioSource2], (float)j / 1000f);
}
DenseFog.WindAudioSource.source.volume = Mathf.Lerp(0.0001f, DenseFog.WindAudioSource.origVolume, (float)j / 1000f);
yield return (object)new WaitForSeconds(0.001f);
}
}
private IEnumerator GenerateFishingBonanza()
{
if (!Configs.enableFishingBonanza.Value || (Object)(object)GameState.currentBoat == (Object)null || WeatherStorms.instance.InvokePrivateMethod<float>("GetNormalizedDistance") < 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>();
ShapeModule shape = seagullsPS.shape;
((ShapeModule)(ref shape)).radius = 100f;
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(MoveSegulls(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 MoveSegulls(Transform seagulls, Transform boat)
{
while (_moveSeagulls)
{
seagulls.position = boat.position + boat.up * 60f;
yield return null;
}
}
private IEnumerator GenerateIntenseStorm()
{
if (Configs.enableIntenseStorm.Value)
{
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)
{
s_originalFogDensity = ((s_originalFogDensity == 0f) ? palette.fogDensity : s_originalFogDensity);
s_currentFogDensity = ((s_currentFogDensity == 0f) ? palette.fogDensity : s_currentFogDensity);
if (s_clearFog && s_currentFogDensity > s_originalFogDensity)
{
s_currentFogDensity -= 1E-05f;
}
if (!s_clearFog && s_currentFogDensity < 0.06f)
{
s_currentFogDensity += 1E-05f;
}
palette.fogDensity = s_currentFogDensity;
if (s_clearFog && s_currentFogDensity <= s_originalFogDensity)
{
IsRunning = false;
s_currentFogDensity = 0f;
s_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)
{
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 = (___audio, ___audio.volume);
}
}
private static bool s_clearFog = true;
private static float s_currentFogDensity = 0f;
private static float s_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; } = (null, 0f);
public static void Spawn()
{
RE_Plugin.LogDebug("Spawning fog");
foreach (AudioSource item in WaveAudioSources.Keys.ToList())
{
WaveAudioSources[item] = item.volume;
}
WindAudioSource = (WindAudioSource.source, WindAudioSource.source.volume);
s_clearFog = false;
IsRunning = true;
}
public static void ClearFog()
{
RE_Plugin.LogDebug("Clearing fog");
s_clearFog = true;
}
}
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_0082: Unknown result type (might be due to invalid IL or missing references)
//IL_008d: 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)
//IL_0045: 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) || !((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 : 2f);
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[22]
{
1, 2, 3, 4, 5, 6, 7, 8, 9, 10,
11, 13, 14, 15, 16, 17, 18, 19, 24, 25,
26, 27
};
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_TPYES = 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)
//IL_0244: Unknown result type (might be due to invalid IL or missing references)
//IL_0256: 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.Hull, 1f, wreckage: true);
SpawnItem(spawnPoint, AssetLoader.Mast, 1f, wreckage: true);
SpawnItem(spawnPoint, AssetLoader.Bowsprit, 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)));
val.GetComponent<ShipItem>().sold = true;
val.GetComponent<SaveablePrefab>().RegisterToSave();
if (Object.op_Implicit((Object)(object)val.GetComponent<Good>()))
{
val.GetComponent<Good>().RegisterAsMissionless();
}
val.GetComponent<ShipItem>().amount = amount;
val.GetComponent<ShipItem>().health = amount;
if (wreckage)
{
((GoPointerButton)val.GetComponent<ShipItem>()).unclickable = true;
val.transform.parent = Refs.shiftingWorld;
}
RE_Plugin.LogDebug("Prefab " + ((Object)prefabGO).name + " spawned");
}
}
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.2.0")]
[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.2.0";
public const string SEALIFEMOD_GUID = "com.yourname.sailwind.sealifeplugin";
public const string IDLEFISHING_GUID = "ISA_IdleFishing";
private static ManualLogSource _logger;
internal static BaseUnityPlugin SeaLifeModPluginInstance { get; private set; }
internal static bool IdleFishingPluginDetected { 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("com.yourname.sailwind.sealifeplugin found");
SeaLifeModPluginInstance = pluginInfo.Value.Instance;
SeaLifeMod.PatchMod();
}
if (metadata.GUID.Equals("ISA_IdleFishing"))
{
LogInfo("ISA_IdleFishing found");
IdleFishingPluginDetected = true;
}
}
((Component)this).gameObject.AddComponent<EncounterGenerator>();
}
}
internal class AssetLoader
{
public static GameObject Hull { get; private set; }
public static GameObject Mast { get; private set; }
public static GameObject Bowsprit { get; private set; }
internal static IEnumerator LoadAssetBundle()
{
RE_Plugin.LogDebug("Loading bundle");
string bundlePath = Path.Combine(Path.GetDirectoryName(((BaseUnityPlugin)RE_Plugin.Instance).Info.Location), "Assets", "wreckage_bundle");
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 == "mast"));
Mast = (GameObject)(object)((obj2 is GameObject) ? obj2 : null);
Object? obj3 = ((IEnumerable<Object>)request.allAssets).FirstOrDefault((Func<Object, bool>)((Object a) => a.name == "bowsprit"));
Bowsprit = (GameObject)(object)((obj3 is GameObject) ? obj3 : null);
if ((Object)(object)Hull == (Object)null || (Object)(object)Mast == (Object)null || (Object)(object)Bowsprit == (Object)null)
{
RE_Plugin.LogError("Failed to load all assets from the bundle.");
}
}
}
internal class Configs
{
internal static ConfigEntry<int> generateEncounterMinTime;
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()
{
ConfigFile config = ((BaseUnityPlugin)RE_Plugin.Instance).Config;
generateEncounterMinTime = config.Bind<int>("Settings", "Minimum encounter generation time", 900, "Minimum time in seconds to get a chance roll for an encounter, the encounter time range max is 5 minutes added to this.");
enableFlotsam = config.Bind<bool>("Settings", "Enable flotsam encounters", true, "Enable flotsam encounters.");
controlSeaLifeMod = config.Bind<bool>("Settings", "Control SeaLifeMod spawns", true, "Use this mod to control SeaLifeMod spawns.");
enableDenseFog = config.Bind<bool>("Settings", "Enable dense fog encounters", true, "Enable dense fog encounters.");
fogDuration = config.Bind<int>("Settings", "Fog encounter duration", 300, "In seconds, the amount of time the fog encounter lasts.");
enableFishingBonanza = config.Bind<bool>("Settings", "Enable fishing bonanza encounters", true, "Enable fishing bonanza encounters.");
fishingBonanzaDuration = config.Bind<int>("Settings", "Fishing bonanza duration", 300, "In seconds, the amount of time the fishing bonanza encounter lasts.");
enableIntenseStorm = config.Bind<bool>("Settings", "Enable intense storm encounters", true, "Enable intense storm encounters.");
intenseStormDuration = config.Bind<int>("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>();
}
}