Please disclose if any significant portion of your mod was created using AI tools by adding the 'AI Generated' category. Failing to do so may result in the mod being removed from Thunderstore.
Decompiled source of CreatureTrophyDropRate ExcludeBoss v1.0.0
BepInEx/plugins/CreatureTrophyDropRate_ExcludeBoss/CreatureTrophyDropRate_ExcludeBoss.dll
Decompiled 2 weeks agousing 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 Microsoft.CodeAnalysis; using UnityEngine; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")] [assembly: AssemblyCompany("CreatureTrophyDropRate_ExcludeBoss")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyFileVersion("1.0.0.0")] [assembly: AssemblyInformationalVersion("1.0.0")] [assembly: AssemblyProduct("CreatureTrophyDropRate_ExcludeBoss")] [assembly: AssemblyTitle("CreatureTrophyDropRate_ExcludeBoss")] [assembly: AssemblyVersion("1.0.0.0")] [module: RefSafetyRules(11)] namespace Microsoft.CodeAnalysis { [CompilerGenerated] [Embedded] internal sealed class EmbeddedAttribute : Attribute { } } namespace System.Runtime.CompilerServices { [CompilerGenerated] [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 CreatureTrophyDropRate_ExcludeBoss { public enum TrophyChanceMode { Fixed, Multiplier } internal sealed class ChanceSettings { internal readonly TrophyChanceMode Mode; internal readonly float FixedChance; internal readonly float Multiplier; internal ChanceSettings(string mode, float fixedChance, float multiplier, Action<string> warn) { if (string.Equals(mode?.Trim(), "Fixed", StringComparison.OrdinalIgnoreCase)) { Mode = TrophyChanceMode.Fixed; } else { Mode = TrophyChanceMode.Multiplier; if (!string.Equals(mode?.Trim(), "Multiplier", StringComparison.OrdinalIgnoreCase)) { warn("Invalid Mode; falling back to Multiplier."); } } FixedChance = Validate(fixedChance, 0.5f, 1f, "FixedChance", warn); Multiplier = Validate(multiplier, 2f, float.MaxValue, "Multiplier", warn); } private static float Validate(float value, float fallback, float max, string key, Action<string> warn) { if (float.IsNaN(value) || float.IsInfinity(value)) { warn(key + " must be finite; using " + fallback + "."); return fallback; } float num = Math.Max(0f, Math.Min(max, value)); if (num != value) { warn(key + " is outside its allowed range; clamped to " + num + "."); } return num; } internal float Apply(float original) { if (Mode != TrophyChanceMode.Fixed) { return (float)Math.Max(0.0, Math.Min(1.0, (double)original * (double)Multiplier)); } return FixedChance; } } internal sealed class DropProcessor { private sealed class Baseline { internal readonly float Chance; internal Baseline(float chance) { Chance = chance; } } private readonly ConditionalWeakTable<Drop, Baseline> originals = new ConditionalWeakTable<Drop, Baseline>(); private static readonly MethodInfo Clone = typeof(object).GetMethod("MemberwiseClone", BindingFlags.Instance | BindingFlags.NonPublic); internal void Process(IEnumerable<GameObject> prefabs, ChanceSettings settings, Action<string> info, Action<string> debug) { //IL_0113: Unknown result type (might be due to invalid IL or missing references) //IL_011a: Invalid comparison between Unknown and I4 //IL_01da: Unknown result type (might be due to invalid IL or missing references) //IL_01e1: Expected O, but got Unknown int num = 0; int num2 = 0; int num3 = 0; HashSet<GameObject> hashSet = new HashSet<GameObject>(); foreach (GameObject prefab in prefabs) { if (!Object.op_Implicit((Object)(object)prefab) || !hashSet.Add(prefab)) { continue; } Character component = prefab.GetComponent<Character>(); CharacterDrop component2 = prefab.GetComponent<CharacterDrop>(); if (!Object.op_Implicit((Object)(object)component) || !Object.op_Implicit((Object)(object)component2)) { continue; } if (component.m_boss) { num3++; debug?.Invoke("Boss skipped: " + ((Object)prefab).name); } else { if (component2.m_drops == null) { continue; } List<Drop> list = null; for (int i = 0; i < component2.m_drops.Count; i++) { Drop val = component2.m_drops[i]; if (val == null || !Object.op_Implicit((Object)(object)val.m_prefab)) { continue; } ItemDrop component3 = val.m_prefab.GetComponent<ItemDrop>(); if (!Object.op_Implicit((Object)(object)component3) || component3.m_itemData?.m_shared == null || (int)component3.m_itemData.m_shared.m_itemType != 13) { continue; } Baseline value = originals.GetValue(val, (Drop d) => new Baseline(d.m_chance)); if (float.IsNaN(value.Chance) || float.IsInfinity(value.Chance)) { debug?.Invoke("Invalid original chance skipped: " + ((Object)prefab).name + " -> " + ((Object)val.m_prefab).name); continue; } float num4 = settings.Apply(value.Chance); if (num4 != val.m_chance) { if (list == null) { list = new List<Drop>(component2.m_drops); } Drop val2 = (Drop)Clone.Invoke(val, null); val2.m_chance = num4; originals.Add(val2, value); list[i] = val2; num++; debug?.Invoke($"{((Object)prefab).name} -> {((Object)val.m_prefab).name}: {value.Chance:G6} -> {num4:G6}"); } } if (list != null) { component2.m_drops = list; num2++; } } } info($"Modified {num} trophy drop entries across {num2} non-boss creatures."); info($"Skipped {num3} bosses."); } } [BepInPlugin("com.weizhexu.nonbosstrophies", "CreatureTrophyDropRate_ExcludeBoss", "1.0.0")] public sealed class Plugin : BaseUnityPlugin { [HarmonyPatch(typeof(ZNetScene), "Awake")] private static class SceneAwakePatch { [HarmonyPostfix] [HarmonyPriority(0)] private static void Postfix(ZNetScene __instance) { if ((Object)(object)instance != (Object)null) { instance.Apply(__instance); } } } public const string Guid = "com.weizhexu.nonbosstrophies"; private static Plugin instance; private Harmony harmony; private ChanceSettings settings; private bool debugLogging; private readonly DropProcessor processor = new DropProcessor(); private readonly ConditionalWeakTable<ZNetScene, object> scenes = new ConditionalWeakTable<ZNetScene, object>(); private void Awake() { //IL_00bb: Unknown result type (might be due to invalid IL or missing references) //IL_00c5: Expected O, but got Unknown instance = this; ConfigEntry<string> val = ((BaseUnityPlugin)this).Config.Bind<string>("General", "Mode", "Fixed", "Fixed or Multiplier (case-insensitive). Invalid values use Multiplier. Restart after editing."); ConfigEntry<float> val2 = ((BaseUnityPlugin)this).Config.Bind<float>("General", "FixedChance", 0.5f, "Used in Fixed mode. 0 = 0%, 0.5 = 50%, 1 = 100%. Clamped to [0,1]."); ConfigEntry<float> val3 = ((BaseUnityPlugin)this).Config.Bind<float>("General", "Multiplier", 2f, "Used in Multiplier mode. 2 doubles the existing base trophy chance, capped at 100%. Negative values clamp to zero."); debugLogging = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "DebugLogging", false, "Log individual changes and skipped bosses.").Value; settings = new ChanceSettings(val.Value, val2.Value, val3.Value, delegate(string s) { ((BaseUnityPlugin)this).Logger.LogWarning((object)s); }); harmony = new Harmony("com.weizhexu.nonbosstrophies"); harmony.PatchAll(typeof(Plugin).Assembly); ((BaseUnityPlugin)this).Logger.LogInfo((object)"Initialized."); ((BaseUnityPlugin)this).Logger.LogInfo((object)$"Mode: {settings.Mode}, FixedChance: {settings.FixedChance}, Multiplier: {settings.Multiplier}"); } private void Apply(ZNetScene scene) { if (!scenes.TryGetValue(scene, out var _)) { List<GameObject> list = new List<GameObject>(scene.m_prefabs); list.AddRange(scene.m_nonNetViewPrefabs); processor.Process(list, settings, delegate(string s) { ((BaseUnityPlugin)this).Logger.LogInfo((object)s); }, debugLogging ? ((Action<string>)delegate(string s) { ((BaseUnityPlugin)this).Logger.LogInfo((object)s); }) : null); scenes.Add(scene, new object()); } } private void OnDestroy() { Harmony obj = harmony; if (obj != null) { obj.UnpatchSelf(); } if ((Object)(object)instance == (Object)(object)this) { instance = null; } } } }