Decompiled source of LuckyDynamite v3.0.0

BepInEx/plugins/LuckyDynamite/LuckyDynamite.dll

Decompiled 2 hours ago
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using BepInEx;
using BepInEx.Configuration;
using HarmonyLib;
using UnityEngine;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETFramework,Version=v4.7.2", FrameworkDisplayName = ".NET Framework 4.7.2")]
[assembly: AssemblyCompany("LuckyDynamite")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0")]
[assembly: AssemblyProduct("LuckyDynamite")]
[assembly: AssemblyTitle("LuckyDynamite")]
[assembly: AssemblyVersion("1.0.0.0")]
namespace LuckyDynamite;

[BepInPlugin("com.mod.luckydynamite", "Lucky Dynamite", "3.0.0")]
public class LuckyDynamitePlugin : BaseUnityPlugin
{
	public static ConfigEntry<string> Preset;

	public static ConfigEntry<int> CommonWeight;

	public static ConfigEntry<int> RareWeight;

	public static ConfigEntry<int> LegendaryWeight;

	public static ConfigEntry<int> CommonMaxWorth;

	public static ConfigEntry<int> LegendaryMinWorth;

	public static ConfigEntry<bool> EnableBossFish;

	public static ConfigEntry<int> BossWeight;

	public static ConfigEntry<bool> OnlyWhenBossActive;

	public static ConfigEntry<string> FishSource;

	public static ConfigEntry<int> NormalDripChance;

	public static ConfigEntry<int> MiniBossDripChance;

	public static ConfigEntry<int> BossDripChance;

	public static ConfigEntry<bool> EnableBossDrip;

	private static readonly List<Fishable> _commonPool = new List<Fishable>();

	private static readonly List<Fishable> _rarePool = new List<Fishable>();

	private static readonly List<Fishable> _legendaryPool = new List<Fishable>();

	private static readonly List<Fishable> _bossPool = new List<Fishable>();

	private static bool _poolBuilt;

	private static readonly Random _rng = new Random();

	private static FieldInfo _fishableItemField;

	private static FieldInfo _explosionWeightsField;

	private static ExplosionManager _poolIslandInstance;

	internal static bool InExplosion;

	private void Awake()
	{
		//IL_0244: Unknown result type (might be due to invalid IL or missing references)
		Preset = ((BaseUnityPlugin)this).Config.Bind<string>("General", "Preset", "Balanced", "Quick preset: Balanced / Generous / Wild / Custom.");
		CommonWeight = ((BaseUnityPlugin)this).Config.Bind<int>("Rarity", "CommonWeight", 70, "Spawn weight for Common fish (0 = disabled).");
		RareWeight = ((BaseUnityPlugin)this).Config.Bind<int>("Rarity", "RareWeight", 25, "Spawn weight for Rare fish (0 = disabled).");
		LegendaryWeight = ((BaseUnityPlugin)this).Config.Bind<int>("Rarity", "LegendaryWeight", 5, "Spawn weight for Legendary fish (0 = disabled).");
		CommonMaxWorth = ((BaseUnityPlugin)this).Config.Bind<int>("Rarity", "CommonMaxWorth", 100, "Max DefaultWorth for Common tier. Fish with worth <= this are Common.");
		LegendaryMinWorth = ((BaseUnityPlugin)this).Config.Bind<int>("Rarity", "LegendaryMinWorth", 500, "Min DefaultWorth for Legendary tier. Fish with worth >= this are Legendary.");
		EnableBossFish = ((BaseUnityPlugin)this).Config.Bind<bool>("Boss", "EnableBossFish", true, "Allow boss/mini-boss fish to spawn from dynamite.");
		BossWeight = ((BaseUnityPlugin)this).Config.Bind<int>("Boss", "BossWeight", 3, "Spawn weight for Boss fish (only used if EnableBossFish = true).");
		OnlyWhenBossActive = ((BaseUnityPlugin)this).Config.Bind<bool>("Boss", "OnlyWhenBossActive", true, "Only spawn boss fish if a boss is currently spawned.");
		FishSource = ((BaseUnityPlugin)this).Config.Bind<string>("IslandFilter", "FishSource", "CurrentIsland", "Fish source: CurrentIsland = vanilla (current island's pool) or AllIslands = full game table.");
		FishSource.SettingChanged += delegate
		{
			_poolBuilt = false;
		};
		NormalDripChance = ((BaseUnityPlugin)this).Config.Bind<int>("Drip", "NormalDripChance", 15, "Drip chance (0-100) for normal fish (BossType.None).");
		MiniBossDripChance = ((BaseUnityPlugin)this).Config.Bind<int>("Drip", "MiniBossDripChance", 10, "Drip chance (0-100) for mini-boss fish.");
		BossDripChance = ((BaseUnityPlugin)this).Config.Bind<int>("Drip", "BossDripChance", 5, "Drip chance (0-100) for boss fish.");
		EnableBossDrip = ((BaseUnityPlugin)this).Config.Bind<bool>("Drip", "EnableBossDrip", false, "Allow boss/mini-boss fish to get drip (shiny) quality.");
		ApplyPreset(Preset.Value);
		_fishableItemField = typeof(Fishable).GetField("_itemToSpawn", BindingFlags.Instance | BindingFlags.NonPublic);
		_explosionWeightsField = typeof(ExplosionManager).GetField("_explodabaleItemWeights", BindingFlags.Instance | BindingFlags.NonPublic);
		new Harmony("com.mod.luckydynamite").PatchAll();
		((BaseUnityPlugin)this).Logger.LogInfo((object)("LuckyDynamite v3 loaded! Preset: " + Preset.Value + " | " + $"Weights: C{CommonWeight.Value}/R{RareWeight.Value}/L{LegendaryWeight.Value}/B{BossWeight.Value} | " + $"Drip: {NormalDripChance.Value}/{MiniBossDripChance.Value}/{BossDripChance.Value}%"));
	}

	internal static void ApplyPreset(string name)
	{
		switch (name)
		{
		case "Generous":
			CommonWeight.Value = 50;
			RareWeight.Value = 35;
			LegendaryWeight.Value = 15;
			BossWeight.Value = 5;
			NormalDripChance.Value = 30;
			MiniBossDripChance.Value = 20;
			BossDripChance.Value = 10;
			break;
		case "Wild":
			CommonWeight.Value = 40;
			RareWeight.Value = 30;
			LegendaryWeight.Value = 30;
			BossWeight.Value = 10;
			NormalDripChance.Value = 15;
			MiniBossDripChance.Value = 10;
			BossDripChance.Value = 5;
			break;
		case "Balanced":
			CommonWeight.Value = 70;
			RareWeight.Value = 25;
			LegendaryWeight.Value = 5;
			BossWeight.Value = 3;
			NormalDripChance.Value = 15;
			MiniBossDripChance.Value = 10;
			BossDripChance.Value = 5;
			break;
		}
	}

	internal static void EnsurePoolBuilt()
	{
		ExplosionManager instance = ExplosionManager.Instance;
		bool flag = FishSource.Value == "AllIslands";
		if (_poolBuilt && (flag || (Object)(object)_poolIslandInstance == (Object)(object)instance))
		{
			return;
		}
		_poolBuilt = true;
		_poolIslandInstance = instance;
		_commonPool.Clear();
		_rarePool.Clear();
		_legendaryPool.Clear();
		_bossPool.Clear();
		int value = CommonMaxWorth.Value;
		int value2 = LegendaryMinWorth.Value;
		if (flag)
		{
			int allCreatureCount = GameInfo.AllCreatureCount;
			for (int i = 0; i < allCreatureCount; i++)
			{
				Creature creature = GameInfo.GetCreature(i);
				if (Object.op_Implicit((Object)(object)creature))
				{
					Fishable val = CreateFishable(creature);
					if (Object.op_Implicit((Object)(object)val))
					{
						CategorizeFishable(creature, val, value, value2);
					}
				}
			}
		}
		else if ((Object)(object)instance != (Object)null && _explosionWeightsField != null && _explosionWeightsField.GetValue(instance) is List<ItemInfoWeight> list)
		{
			foreach (ItemInfoWeight item in list)
			{
				Fishable fishable = item.Fishable;
				if (Object.op_Implicit((Object)(object)fishable))
				{
					Item itemToSpawn = fishable.ItemToSpawn;
					Creature val2 = (Creature)(object)((itemToSpawn is Creature) ? itemToSpawn : null);
					if (Object.op_Implicit((Object)(object)val2))
					{
						CategorizeFishable(val2, fishable, value, value2);
					}
				}
			}
		}
		Debug.Log((object)($"[LuckyDynamite] Fish pool built ({FishSource.Value}): {_commonPool.Count} common, " + $"{_rarePool.Count} rare, {_legendaryPool.Count} legendary, {_bossPool.Count} boss"));
	}

	private static void CategorizeFishable(Creature creature, Fishable fishable, int commonMax, int legendaryMin)
	{
		//IL_0001: Unknown result type (might be due to invalid IL or missing references)
		if ((int)creature.BossType != 0)
		{
			_bossPool.Add(fishable);
			return;
		}
		int defaultWorth = ((Item)creature).DefaultWorth;
		if (defaultWorth <= commonMax)
		{
			_commonPool.Add(fishable);
		}
		else if (defaultWorth >= legendaryMin)
		{
			_legendaryPool.Add(fishable);
		}
		else
		{
			_rarePool.Add(fishable);
		}
	}

	private static Fishable CreateFishable(Creature creature)
	{
		Fishable val = ScriptableObject.CreateInstance<Fishable>();
		_fishableItemField.SetValue(val, creature);
		return val;
	}

	internal static Fishable GetRandomFromPool()
	{
		EnsurePoolBuilt();
		List<Tuple<List<Fishable>, int>> list = new List<Tuple<List<Fishable>, int>>();
		if (CommonWeight.Value > 0 && _commonPool.Count > 0)
		{
			list.Add(Tuple.Create(_commonPool, CommonWeight.Value));
		}
		if (RareWeight.Value > 0 && _rarePool.Count > 0)
		{
			list.Add(Tuple.Create(_rarePool, RareWeight.Value));
		}
		if (LegendaryWeight.Value > 0 && _legendaryPool.Count > 0)
		{
			list.Add(Tuple.Create(_legendaryPool, LegendaryWeight.Value));
		}
		if (EnableBossFish.Value)
		{
			bool flag = !OnlyWhenBossActive.Value || Object.op_Implicit((Object)(object)BossManager.Boss);
			if (BossWeight.Value > 0 && _bossPool.Count > 0 && flag)
			{
				list.Add(Tuple.Create(_bossPool, BossWeight.Value));
			}
		}
		if (list.Count == 0)
		{
			return null;
		}
		int num = 0;
		foreach (Tuple<List<Fishable>, int> item2 in list)
		{
			num += item2.Item2;
		}
		int num2 = _rng.Next(num);
		int num3 = 0;
		foreach (Tuple<List<Fishable>, int> item3 in list)
		{
			num3 += item3.Item2;
			if (num2 < num3)
			{
				List<Fishable> item = item3.Item1;
				return item[_rng.Next(item.Count)];
			}
		}
		return null;
	}

	internal static int GetDripChance(BossType type)
	{
		//IL_0000: Unknown result type (might be due to invalid IL or missing references)
		//IL_0002: Invalid comparison between Unknown and I4
		//IL_0004: Unknown result type (might be due to invalid IL or missing references)
		//IL_0006: Invalid comparison between Unknown and I4
		if ((int)type != 1)
		{
			if ((int)type == 2)
			{
				return BossDripChance.Value;
			}
			return NormalDripChance.Value;
		}
		return MiniBossDripChance.Value;
	}
}
[HarmonyPatch(typeof(ExplosionManager), "ServerExplode", new Type[]
{
	typeof(Item),
	typeof(ExplosionInfo)
})]
public class ExplosionManager_ServerExplode_Patch
{
	private static void Prefix()
	{
		LuckyDynamitePlugin.InExplosion = true;
	}

	private static void Postfix()
	{
		LuckyDynamitePlugin.InExplosion = false;
	}
}
[HarmonyPatch(typeof(CreatureManager), "GetRandomItem", new Type[]
{
	typeof(Vector3),
	typeof(List<ItemInfoWeight>)
})]
public class CreatureManager_GetRandomItem_Patch
{
	private static bool Prefix(ref Fishable __result)
	{
		if (!LuckyDynamitePlugin.InExplosion)
		{
			return true;
		}
		Fishable randomFromPool = LuckyDynamitePlugin.GetRandomFromPool();
		if (Object.op_Implicit((Object)(object)randomFromPool))
		{
			__result = randomFromPool;
			return false;
		}
		return true;
	}
}
[HarmonyPatch(typeof(Creature), "ServerKillOnSpawn")]
public class Creature_ServerKillOnSpawn_Patch
{
	private static void Prefix(Creature __instance)
	{
		//IL_0001: Unknown result type (might be due to invalid IL or missing references)
		//IL_0006: Unknown result type (might be due to invalid IL or missing references)
		//IL_0007: Unknown result type (might be due to invalid IL or missing references)
		//IL_0017: Unknown result type (might be due to invalid IL or missing references)
		//IL_0033: Unknown result type (might be due to invalid IL or missing references)
		BossType bossType = __instance.BossType;
		if (((int)bossType == 0 || LuckyDynamitePlugin.EnableBossDrip.Value) && ((int)bossType == 0 || !LuckyDynamitePlugin.OnlyWhenBossActive.Value || Object.op_Implicit((Object)(object)BossManager.Boss)))
		{
			int dripChance = LuckyDynamitePlugin.GetDripChance(bossType);
			if (dripChance > 0 && Random.Range(0, 100) < dripChance)
			{
				__instance.SetDrip();
			}
		}
	}
}