using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using BepInEx;
using BepInEx.Bootstrap;
using BepInEx.Configuration;
using BepInEx.Logging;
using HarmonyLib;
using Microsoft.CodeAnalysis;
using TrinketFortune.Patches;
using UnityEngine;
using Wish;
[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)]
[assembly: TargetFramework(".NETFramework,Version=v4.8", FrameworkDisplayName = ".NET Framework 4.8")]
[assembly: AssemblyCompany("TrinketFortune")]
[assembly: AssemblyConfiguration("Debug")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0+445c94b8877770510e89901862d3520955e229c2")]
[assembly: AssemblyProduct("TrinketFortune")]
[assembly: AssemblyTitle("TrinketFortune")]
[assembly: AssemblyVersion("1.0.0.0")]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
[CompilerGenerated]
[Microsoft.CodeAnalysis.Embedded]
internal sealed class EmbeddedAttribute : Attribute
{
}
}
namespace System.Runtime.CompilerServices
{
[CompilerGenerated]
[Microsoft.CodeAnalysis.Embedded]
[AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)]
internal sealed class RefSafetyRulesAttribute : Attribute
{
public readonly int Version;
public RefSafetyRulesAttribute(int P_0)
{
Version = P_0;
}
}
}
namespace TrinketFortune
{
public static class Config
{
public static ConfigEntry<bool> Enabled;
public static ConfigEntry<float> MuseumProgressBonusPercent;
public static ConfigEntry<float> MinimumMuseumProgress;
public static void Bind(ConfigFile config)
{
//IL_0064: Unknown result type (might be due to invalid IL or missing references)
//IL_006e: Expected O, but got Unknown
Enabled = config.Bind<bool>("General", "Enabled", true, "Enable Trinket Fortune. When enabled, odds of unowned fishing trinkets increase as you complete the aquarium.");
MuseumProgressBonusPercent = config.Bind<float>("General", "MuseumProgressBonusPercent", 5f, "Bonus to unowned trinket odds per 10% aquarium completion (e.g. 5 = +5% per 10%). Applied on top of base drop chance.");
MinimumMuseumProgress = config.Bind<float>("General", "MinimumMuseumProgress", 0.2f, new ConfigDescription("Museum progress below this has no bonus (0.2 = 20% donated). Prevents bonus at very low completion.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 1f), Array.Empty<object>()));
}
}
public static class DonationHelper
{
private const string SmutGuid = "com.azraelgodking.sunhavenmuseumutilitytracker";
private static object _donationManager;
private static MethodInfo _hasDonatedByGameId;
public static bool IsAvailable => _donationManager != null && _hasDonatedByGameId != null;
static DonationHelper()
{
if (Chainloader.PluginInfos == null || !Chainloader.PluginInfos.TryGetValue("com.azraelgodking.sunhavenmuseumutilitytracker", out var _))
{
return;
}
try
{
Type type = Type.GetType("SunHavenMuseumUtilityTracker.Plugin, SunHavenMuseumUtilityTracker");
if (type == null)
{
return;
}
MethodInfo method = type.GetMethod("GetDonationManager", BindingFlags.Static | BindingFlags.Public);
if (!(method == null))
{
_donationManager = method.Invoke(null, null);
if (_donationManager != null)
{
_hasDonatedByGameId = _donationManager.GetType().GetMethod("HasDonatedByGameId", BindingFlags.Instance | BindingFlags.Public, null, new Type[1] { typeof(int) }, null);
}
}
}
catch (Exception ex)
{
ManualLogSource log = Plugin.Log;
if (log != null)
{
log.LogDebug((object)("DonationHelper: SMUT not available: " + ex.Message));
}
}
}
public static bool HasDonatedByGameId(int gameItemId)
{
if (_donationManager == null || _hasDonatedByGameId == null)
{
return false;
}
try
{
return (bool)_hasDonatedByGameId.Invoke(_donationManager, new object[1] { gameItemId });
}
catch
{
return false;
}
}
public static int PickBiasedFishingMuseumItem()
{
if (!Config.Enabled.Value)
{
return 0;
}
List<int> fishingMuseumItems = FishingRod.fishingMuseumItems;
if (fishingMuseumItems == null || fishingMuseumItems.Count == 0)
{
return 0;
}
if (!IsAvailable)
{
return 0;
}
List<int> list = fishingMuseumItems.Where((int id) => !HasDonatedByGameId(id)).ToList();
if (list.Count == 0)
{
return fishingMuseumItems[Random.Range(0, fishingMuseumItems.Count)];
}
float aquariumProgress = GetAquariumProgress();
if (aquariumProgress < Config.MinimumMuseumProgress.Value * 100f)
{
return fishingMuseumItems[Random.Range(0, fishingMuseumItems.Count)];
}
float num = Config.MuseumProgressBonusPercent.Value * (aquariumProgress / 10f);
float num2 = Random.Range(0f, 100f);
if (num2 < num)
{
return list[Random.Range(0, list.Count)];
}
return fishingMuseumItems[Random.Range(0, fishingMuseumItems.Count)];
}
private static float GetAquariumProgress()
{
try
{
int num = 0;
int num2 = 0;
Type type = Type.GetType("Wish.GameSave, SunHaven.Core");
if (type == null)
{
return 0f;
}
PropertyInfo property = type.GetProperty("Instance", BindingFlags.Static | BindingFlags.Public);
if (property == null)
{
return 0f;
}
object value = property.GetValue(null);
if (value == null)
{
return 0f;
}
MethodInfo method = type.GetMethod("GetProgressIntWorld", new Type[1] { typeof(string) });
if (method == null)
{
return 0f;
}
foreach (var item2 in MuseumCurator.aquaticMuseumProgress)
{
string text = item2.Item1 + "complete";
int item = item2.Item2;
int num3 = (int)method.Invoke(value, new object[1] { text });
num += item;
num2 += num3;
}
return (num > 0) ? ((float)num2 / (float)num * 100f) : 0f;
}
catch
{
return 0f;
}
}
public static FishData PickBiasedFish(RandomFishArray array, float level)
{
if (!Config.Enabled.Value || array == null || array.Length == 0)
{
return null;
}
if (!IsAvailable)
{
return null;
}
List<FishData> list = new List<FishData>();
for (int i = 0; i < array.Length; i++)
{
FishLoot val = array.drops[i];
if (!((Object)(object)val?.fish == (Object)null))
{
int id = ((ItemData)val.fish).id;
if (!HasDonatedByGameId(id))
{
list.Add(val.fish);
}
}
}
if (list.Count == 0)
{
return null;
}
float aquariumProgress = GetAquariumProgress();
if (aquariumProgress < Config.MinimumMuseumProgress.Value * 100f)
{
return null;
}
float num = Config.MuseumProgressBonusPercent.Value * (aquariumProgress / 10f);
if (Random.Range(0f, 100f) >= num)
{
return null;
}
return list[Random.Range(0, list.Count)];
}
}
[BepInPlugin("com.azraelgodking.trinketfortune", "Trinket Fortune", "1.0.3")]
public class Plugin : BaseUnityPlugin
{
public static class PluginInfo
{
public const string PLUGIN_GUID = "com.azraelgodking.trinketfortune";
public const string PLUGIN_NAME = "Trinket Fortune";
public const string PLUGIN_VERSION = "1.0.3";
}
private Harmony _harmony;
public static ManualLogSource Log { get; private set; }
private void Awake()
{
//IL_001e: Unknown result type (might be due to invalid IL or missing references)
//IL_0028: Expected O, but got Unknown
Log = ((BaseUnityPlugin)this).Logger;
Config.Bind(CreateNamedConfig());
_harmony = new Harmony("com.azraelgodking.trinketfortune");
FishingTrinketPatches.ApplyPatches(_harmony);
if (Chainloader.PluginInfos != null && Chainloader.PluginInfos.ContainsKey("com.azraelgodking.havendevtools"))
{
Log.LogInfo((object)"HavenDevTools detected. Trinket Fortune runs in standalone-safe mode (no hard API dependency).");
}
Log.LogInfo((object)"Trinket Fortune v1.0.3 loaded. Fishing loot bias active when S.M.U.T. is installed.");
}
private static ConfigFile CreateNamedConfig()
{
//IL_006a: Unknown result type (might be due to invalid IL or missing references)
//IL_0071: Expected O, but got Unknown
string text = Path.Combine(Paths.ConfigPath, "TrinketFortune.cfg");
string text2 = Path.Combine(Paths.ConfigPath, "com.azraelgodking.trinketfortune.cfg");
try
{
if (!File.Exists(text) && File.Exists(text2))
{
File.Copy(text2, text);
}
}
catch (Exception ex)
{
ManualLogSource log = Log;
if (log != null)
{
log.LogWarning((object)("[Config] Migration to TrinketFortune.cfg failed: " + ex.Message));
}
}
return new ConfigFile(text, true);
}
}
}
namespace TrinketFortune.Patches
{
public static class FishingTrinketPatches
{
public static void ApplyPatches(Harmony harmony)
{
//IL_0046: Unknown result type (might be due to invalid IL or missing references)
//IL_004c: Expected O, but got Unknown
//IL_00cb: Unknown result type (might be due to invalid IL or missing references)
//IL_00d8: Expected O, but got Unknown
MethodInfo methodInfo = AccessTools.Method(typeof(Utilities), "RandomItem", new Type[1] { typeof(IList<int>) }, (Type[])null);
if (methodInfo != null)
{
HarmonyMethod val = new HarmonyMethod(typeof(FishingTrinketPatches), "RandomItem_Prefix", (Type[])null);
harmony.Patch((MethodBase)methodInfo, val, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
Plugin.Log.LogInfo((object)"Patched Utilities.RandomItem<int> for fishing museum items");
}
else
{
Plugin.Log.LogWarning((object)"Could not find Utilities.RandomItem for museum item bias");
}
MethodInfo method = typeof(RandomFishArray).GetMethod("RandomItem", BindingFlags.Instance | BindingFlags.Public, null, new Type[1] { typeof(float) }, null);
if (method != null)
{
harmony.Patch((MethodBase)method, (HarmonyMethod)null, new HarmonyMethod(typeof(FishingTrinketPatches), "RandomFishArray_RandomItem_Postfix", (Type[])null), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
Plugin.Log.LogInfo((object)"Patched RandomFishArray.RandomItem for fish bias");
}
else
{
Plugin.Log.LogWarning((object)"Could not find RandomFishArray.RandomItem");
}
}
private static bool RandomItem_Prefix<T>(IList<T> list, ref T __result)
{
if (!Config.Enabled.Value)
{
return true;
}
if (typeof(T) != typeof(int))
{
return true;
}
if (list == null || list != FishingRod.fishingMuseumItems)
{
return true;
}
int num = DonationHelper.PickBiasedFishingMuseumItem();
if (num == 0)
{
return true;
}
__result = (T)(object)num;
return false;
}
private static void RandomFishArray_RandomItem_Postfix(RandomFishArray __instance, float level, ref FishData __result)
{
FishData val = DonationHelper.PickBiasedFish(__instance, level);
if ((Object)(object)val != (Object)null)
{
__result = val;
}
}
}
}