Decompiled source of PseudoDropFix v0.2.1

plugins\HungarianNotation.PseudoDrop.dll

Decompiled 2 weeks ago
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using HarmonyLib;
using Jotunn.Extensions;
using Jotunn.Utils;
using UnityEngine;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETFramework,Version=v4.8", FrameworkDisplayName = ".NET Framework 4.8")]
[assembly: AssemblyCompany("HungarianNotation.PseudoDrop")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("0.2.1.0")]
[assembly: AssemblyInformationalVersion("0.2.1+5882f9cf9679e390c1ddf32b2b03f4b3c168f986")]
[assembly: AssemblyProduct("HungarianNotation.PseudoDrop")]
[assembly: AssemblyTitle("HungarianNotation.PseudoDrop")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("0.2.1.0")]
[module: UnverifiableCode]
namespace HungarianNotation.PseudoDrop;

[HarmonyPatch]
[HarmonyWrapSafe]
public class CounterPatch
{
	public static void WriteLog(string text)
	{
		if (Plugin.IsLoggingEnabled)
		{
			Plugin.Logger.LogInfo((object)text);
		}
	}

	[HarmonyPrefix]
	[HarmonyPatch(typeof(CharacterDrop), "GenerateDropList")]
	public static void GenerateDropList_Prefix(CharacterDrop __instance)
	{
		if (!Plugin.IsEnabled)
		{
			return;
		}
		WriteLog($"Intercepted GenerateDropList for {__instance.m_character.GetHoverName()} (Level {__instance.m_character.GetLevel()})");
		int levelMultiplier = GetLevelMultiplier(__instance);
		foreach (Drop drop in __instance.m_drops)
		{
			float num = drop.m_chance;
			if (drop.m_levelMultiplier)
			{
				num *= (float)levelMultiplier;
			}
			if (!((double)num <= 0.3))
			{
				continue;
			}
			string name = ((Object)drop.m_prefab).name;
			if (!CharacterDrop.s_pseudoCounter.ContainsKey(name) || CharacterDrop.s_pseudoCounter[name].Item1 != num)
			{
				if (CharacterDrop.s_pseudoCounter.ContainsKey(name))
				{
					WriteLog("Discarding counter with mismatched drop chance: " + $"chance={CharacterDrop.s_pseudoCounter[name].Item1} counter={CharacterDrop.s_pseudoCounter[name].Item2}");
				}
				int num2 = FirstInterval(drop.m_chance);
				CharacterDrop.s_pseudoCounter[name] = new Tuple<float, int>(drop.m_chance, num2);
				WriteLog($"Setting initial drop counter: item={name} chance={num} counter={num2}");
			}
		}
	}

	[HarmonyPostfix]
	[HarmonyPatch(typeof(CharacterDrop), "GenerateDropList")]
	public static void GenerateDropList_Postfix(CharacterDrop __instance, List<KeyValuePair<GameObject, int>> __result)
	{
		if (!Plugin.IsEnabled)
		{
			return;
		}
		int levelMultiplier = GetLevelMultiplier(__instance);
		foreach (Drop drop in __instance.m_drops)
		{
			string name = ((Object)drop.m_prefab).name;
			float dropChance = GetDropChance(drop, levelMultiplier);
			if (!((double)dropChance > 0.3))
			{
				int item = CharacterDrop.s_pseudoCounter[name].Item2;
				if (!__result.Any((KeyValuePair<GameObject, int> keyValuePair) => (Object)(object)keyValuePair.Key == (Object)(object)drop.m_prefab))
				{
					WriteLog(string.Format("Item \"{0}\" will drop in {1} kill{2}; chance={3} counter={4}", name, item, (item != 1) ? "s" : "", dropChance, item));
				}
				else
				{
					int num = SubsequentInterval(dropChance);
					CharacterDrop.s_pseudoCounter[name] = new Tuple<float, int>(dropChance, num);
					WriteLog($"Confirmed drop of {name} chance={dropChance}; Counter set to {num} (was {item})");
				}
			}
		}
	}

	private static float GetDropChance(Drop drop, int levelMultiplier)
	{
		float num = drop.m_chance;
		if (drop.m_levelMultiplier)
		{
			num *= (float)levelMultiplier;
		}
		return num;
	}

	private static int GetLevelMultiplier(CharacterDrop characterDrop)
	{
		if (Object.op_Implicit((Object)(object)characterDrop.m_character))
		{
			return Mathf.Max(1, (int)Mathf.Pow(2f, (float)(characterDrop.m_character.GetLevel() - 1)));
		}
		return 1;
	}

	public static int FirstInterval(float chance)
	{
		float num = 1f / chance * 2f - 1f;
		int num2 = (int)num + ((Random.value <= num % 1f) ? 1 : 0);
		int num3 = num2 * (num2 + 1) / 2;
		int num4 = Random.Range(1, num3 + 1);
		int num5 = (int)Math.Pow(2 * num2 + 1, 2.0) - 8 * num4;
		return Mathf.CeilToInt((2f * (float)num2 + 1f - Mathf.Sqrt((float)num5)) / 2f);
	}

	public static int SubsequentInterval(float chance)
	{
		float num = 1f / chance * 2f;
		int num2 = (int)num + ((Random.value <= num % 1f) ? 1 : 0);
		return Random.Range(1, num2);
	}
}
[BepInPlugin("HungarianNotation.PseudoDrop", "PseudoDropFix", "0.2.1")]
[BepInDependency(/*Could not decode attribute arguments.*/)]
[NetworkCompatibility(/*Could not decode attribute arguments.*/)]
public class Plugin : BaseUnityPlugin
{
	public const string PluginGUID = "HungarianNotation.PseudoDrop";

	public const string PluginName = "PseudoDropFix";

	private readonly Harmony harmony = new Harmony("HungarianNotation.PseudoDrop");

	private ConfigEntry<bool> config_Enable;

	private ConfigEntry<bool> config_DoLogging;

	public const string PluginVersion = "0.2.1";

	public static Plugin Instance { get; private set; }

	public static ManualLogSource Logger { get; private set; }

	public static bool IsEnabled => Instance.config_Enable.Value;

	public static bool IsLoggingEnabled => Instance.config_DoLogging.Value;

	protected void Awake()
	{
		Instance = this;
		Logger = ((BaseUnityPlugin)this).Logger;
		CreateConfig();
		harmony.PatchAll(typeof(CounterPatch));
		Logger.LogDebug((object)"version=0.2.1");
	}

	private void CreateConfig()
	{
		config_Enable = ConfigFileExtensions.BindConfig<bool>(((BaseUnityPlugin)this).Config, "General", "Enable", true, "Enables/Disables the entire mod.", true, (int?)0, (AcceptableValueBase)null, (Action<ConfigEntryBase>)null, (ConfigurationManagerAttributes)null);
		config_DoLogging = ConfigFileExtensions.BindConfig<bool>(((BaseUnityPlugin)this).Config, "General", "DebugLogging", false, "Enables debug logging that writes drop chances and rolled intervals to the console. Not recommended for normal play.", true, (int?)1, (AcceptableValueBase)null, (Action<ConfigEntryBase>)null, (ConfigurationManagerAttributes)null);
		config_Enable.SettingChanged += Config_ConfigReloaded;
		config_DoLogging.SettingChanged += Config_ConfigReloaded;
	}

	private void Config_ConfigReloaded(object sender, EventArgs e)
	{
		((BaseUnityPlugin)this).Logger.LogInfo((object)$"config changed (enabled={config_Enable.Value}, logging={config_DoLogging.Value})");
	}
}