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 WisplightUpgrades v1.0.2
WisplightUpgrades.dll
Decompiled a day 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 BepInEx.Logging; using HarmonyLib; using Jotunn.Utils; using Microsoft.CodeAnalysis; using UnityEngine; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: TargetFramework(".NETFramework,Version=v4.6.2", FrameworkDisplayName = ".NET Framework 4.6.2")] [assembly: AssemblyCompany("WisplightUpgrades")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyFileVersion("1.0.0.0")] [assembly: AssemblyInformationalVersion("1.0.0")] [assembly: AssemblyProduct("WisplightUpgrades")] [assembly: AssemblyTitle("WisplightUpgrades")] [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 WisplightUpgrades { [BepInPlugin("com.wisplightupgrades", "WisplightUpgrades", "1.0.2")] [BepInDependency(/*Could not decode attribute arguments.*/)] [NetworkCompatibility(/*Could not decode attribute arguments.*/)] public class Plugin : BaseUnityPlugin { internal enum MistModes { Vanilla, SkipWastedWork, ThinnedEdge, NoEdgeMist } public const string PluginGUID = "com.wisplightupgrades"; public const string PluginName = "WisplightUpgrades"; public const string PluginVersion = "1.0.2"; internal static ConfigEntry<int> RangeLevel2; internal static ConfigEntry<int> RangeLevel3; internal static ConfigEntry<int> RangeLevel4; internal static ConfigEntry<int> CostPercent; internal static ConfigEntry<bool> RequireStationLevel; internal static ConfigEntry<MistModes> MistMode; internal static ManualLogSource Log; private void Awake() { //IL_002b: Unknown result type (might be due to invalid IL or missing references) //IL_0030: Unknown result type (might be due to invalid IL or missing references) //IL_0038: Expected O, but got Unknown //IL_0068: Unknown result type (might be due to invalid IL or missing references) //IL_0072: Expected O, but got Unknown //IL_00a7: Unknown result type (might be due to invalid IL or missing references) //IL_00b1: Expected O, but got Unknown //IL_00e6: Unknown result type (might be due to invalid IL or missing references) //IL_00f0: Expected O, but got Unknown //IL_0122: Unknown result type (might be due to invalid IL or missing references) //IL_012c: Expected O, but got Unknown //IL_0152: Unknown result type (might be due to invalid IL or missing references) //IL_015c: Expected O, but got Unknown //IL_0166: Unknown result type (might be due to invalid IL or missing references) Log = ((BaseUnityPlugin)this).Logger; MistMode = ((BaseUnityPlugin)this).Config.Bind<MistModes>("Performance", "MistMode", MistModes.SkipWastedWork, "Mist drawing at the edge of your cleared area. Only affects your screen.\nVanilla: game default. Slowest at high levels.\nSkipWastedWork: same look, a bit faster.\nThinnedEdge: faster, thinner mist at the edge.\nNoEdgeMist: fastest, emptier surroundings."); ConfigurationManagerAttributes val = new ConfigurationManagerAttributes { IsAdminOnly = true }; RangeLevel2 = ((BaseUnityPlugin)this).Config.Bind<int>("Range", "Level2Range", 200, new ConfigDescription("Size of the cleared area at level 2, in percent of the normal Wisplight. (Level 1 is 100.)", (AcceptableValueBase)(object)new AcceptableValueRange<int>(100, 1000), new object[1] { val })); RangeLevel3 = ((BaseUnityPlugin)this).Config.Bind<int>("Range", "Level3Range", 300, new ConfigDescription("Size of the cleared area at level 3, in percent of the normal Wisplight.", (AcceptableValueBase)(object)new AcceptableValueRange<int>(100, 1000), new object[1] { val })); RangeLevel4 = ((BaseUnityPlugin)this).Config.Bind<int>("Range", "Level4Range", 400, new ConfigDescription("Size of the cleared area at level 4, in percent of the normal Wisplight.", (AcceptableValueBase)(object)new AcceptableValueRange<int>(100, 1000), new object[1] { val })); CostPercent = ((BaseUnityPlugin)this).Config.Bind<int>("Upgrades", "UpgradeCostPercent", 100, new ConfigDescription("Scales how many materials each upgrade costs. 100 = the default amounts.", (AcceptableValueBase)(object)new AcceptableValueRange<int>(10, 500), new object[1] { val })); RequireStationLevel = ((BaseUnityPlugin)this).Config.Bind<bool>("Upgrades", "RequireStationUpgrades", false, new ConfigDescription("Off (default): upgrades only need the crafting station the Wisplight is made at. On: each upgrade level also needs the station to have one more upgrade (the game's usual rule).", (AcceptableValueBase)null, new object[1] { val })); new Harmony("com.wisplightupgrades").PatchAll(); ((BaseUnityPlugin)this).Logger.LogInfo((object)"WisplightUpgrades 1.0.2 loaded"); } private void Update() { Upgrades.TickRange(); } } internal static class Upgrades { private class Cost { public string[] Names; public int[] PerLevel; public Cost(int[] perLevel, params string[] names) { PerLevel = perLevel; Names = names; } } [HarmonyPatch(typeof(ObjectDB), "Awake")] private static class ObjectDB_Awake_Patch { private static void Postfix() { Apply(); } } [HarmonyPatch(typeof(ZNetScene), "Awake")] private static class ZNetScene_Awake_Patch { private static void Postfix() { Apply(); } } [HarmonyPatch(typeof(Requirement), "GetAmount")] private static class Requirement_GetAmount_Patch { private static void Postfix(Requirement __instance, int qualityLevel, ref int __result) { if (Schedules.TryGetValue(__instance, out var value)) { int num = value[Mathf.Clamp(qualityLevel - 1, 0, value.Length - 1)]; if (qualityLevel > 1 && num > 0) { num = Mathf.Max(1, Mathf.RoundToInt((float)(num * Plugin.CostPercent.Value) / 100f)); } __result = num; } } } [HarmonyPatch(typeof(Recipe), "GetRequiredStationLevel")] private static class Recipe_GetRequiredStationLevel_Patch { private static void Postfix(Recipe __instance, ref int __result) { if (!Plugin.RequireStationLevel.Value && Recipes.Contains(__instance)) { __result = Mathf.Max(1, __instance.m_minStationLevel); } } } [HarmonyPatch(typeof(ParticleMist), "Emit")] private static class ParticleMist_Emit_Patch { private static bool Prefix(ParticleMist __instance, Vector3 center, float radius, float thickness) { //IL_0014: Unknown result type (might be due to invalid IL or missing references) //IL_0019: Unknown result type (might be due to invalid IL or missing references) if (Plugin.MistMode.Value == Plugin.MistModes.Vanilla) { return true; } return !(Vector3.Distance(((Component)__instance).transform.position, center) - (radius + thickness) > __instance.m_maxDistance); } } private const string ItemPrefab = "Demister"; private const string ItemSharedName = "$item_demister"; private const int MaxLevel = 4; private static readonly Cost[] Costs = new Cost[4] { new Cost(new int[4] { 0, 5, 10, 15 }, "Wisp"), new Cost(new int[4] { 0, 2, 4, 8 }, "ScaleHide"), new Cost(new int[4] { 0, 0, 2, 4 }, "Carapace"), new Cost(new int[4] { 0, 0, 0, 4 }, "YggdrasilWood") }; private static readonly Dictionary<Requirement, int[]> Schedules = new Dictionary<Requirement, int[]>(); private static readonly HashSet<Recipe> Recipes = new HashSet<Recipe>(); private static readonly FieldRef<Humanoid, ItemData> UtilityItem = AccessTools.FieldRefAccess<Humanoid, ItemData>("m_utilityItem"); private static readonly FieldRef<SE_Demister, GameObject> BallField = AccessTools.FieldRefAccess<SE_Demister, GameObject>("m_ballInstance"); private static readonly Dictionary<Demister, float> NormalRange = new Dictionary<Demister, float>(); private static float _nextTick; private static int _loggedLevel = -1; private static float _normalEmission = -1f; private static float _normalPerUnit; internal static void Apply() { //IL_0178: Unknown result type (might be due to invalid IL or missing references) //IL_017d: Unknown result type (might be due to invalid IL or missing references) //IL_018a: Unknown result type (might be due to invalid IL or missing references) //IL_0191: Unknown result type (might be due to invalid IL or missing references) //IL_019a: Expected O, but got Unknown ObjectDB instance = ObjectDB.instance; if ((Object)(object)instance == (Object)null || instance.m_items.Count == 0) { return; } foreach (Recipe recipe in instance.m_recipes) { if ((Object)(object)recipe == (Object)null || (Object)(object)recipe.m_item == (Object)null || ((Object)recipe.m_item).name != "Demister" || Recipes.Contains(recipe)) { continue; } Recipes.Add(recipe); recipe.m_item.m_itemData.m_shared.m_maxQuality = 4; List<Requirement> list = new List<Requirement>(recipe.m_resources); Cost[] costs = Costs; foreach (Cost cost in costs) { ItemDrop item = null; string[] names = cost.Names; foreach (string text in names) { GameObject itemPrefab = instance.GetItemPrefab(text); item = (Object.op_Implicit((Object)(object)itemPrefab) ? itemPrefab.GetComponent<ItemDrop>() : null); if ((Object)(object)item != (Object)null) { break; } } if ((Object)(object)item == (Object)null) { Plugin.Log.LogWarning((object)("Material not found, skipped: " + cost.Names[0])); continue; } int[] array = new int[4]; Requirement val = list.Find((Requirement r) => (Object)(object)r.m_resItem != (Object)null && ((Object)r.m_resItem).name == ((Object)item).name); if (val == null) { val = new Requirement { m_resItem = item, m_amount = 0, m_recover = true }; list.Add(val); } else { array[0] = val.m_amount; } for (int num = 1; num < 4; num++) { array[num] = cost.PerLevel[num]; } val.m_amountPerLevel = 1; Schedules[val] = array; } recipe.m_resources = list.ToArray(); Plugin.Log.LogInfo((object)$"Wisplight can now be upgraded to level {4}"); } } private static GameObject BallInstance(StatusEffect effect) { //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_0010: Expected O, but got Unknown return BallField.Invoke((SE_Demister)effect); } private static float RangeMultiplier(int level) { return level switch { 2 => (float)Plugin.RangeLevel2.Value / 100f, 3 => (float)Plugin.RangeLevel3.Value / 100f, 4 => (float)Plugin.RangeLevel4.Value / 100f, _ => 1f, }; } internal static void TickRange() { //IL_0256: Unknown result type (might be due to invalid IL or missing references) if (Time.unscaledTime < _nextTick) { return; } _nextTick = Time.unscaledTime + 0.5f; Player localPlayer = Player.m_localPlayer; if ((Object)(object)localPlayer == (Object)null) { return; } ItemData val = null; foreach (ItemData equippedItem in ((Humanoid)localPlayer).GetInventory().GetEquippedItems()) { if (equippedItem.m_shared.m_name == "$item_demister") { val = equippedItem; break; } } int num = val?.m_quality ?? 0; float num2 = RangeMultiplier(num); ParticleMist instance = ParticleMist.instance; if ((Object)(object)instance != (Object)null) { if (_normalEmission < 0f) { _normalEmission = instance.m_emissionMax; _normalPerUnit = instance.m_emissionPerUnit; } Plugin.MistModes value = Plugin.MistMode.Value; float num3 = value switch { Plugin.MistModes.NoEdgeMist => 0f, Plugin.MistModes.ThinnedEdge => 1f / Mathf.Max(1f, num2), _ => 1f, }; instance.m_emissionMax = _normalEmission * num3; instance.m_emissionPerUnit = _normalPerUnit * ((value == Plugin.MistModes.NoEdgeMist) ? 0f : 1f); } foreach (StatusEffect statusEffect in ((Character)localPlayer).GetSEMan().GetStatusEffects()) { if (!(statusEffect is SE_Demister)) { continue; } GameObject val2 = BallInstance(statusEffect); Demister val3 = (((Object)(object)val2 != (Object)null) ? val2.GetComponentInChildren<Demister>() : null); if (!((Object)(object)val3 == (Object)null) && !((Object)(object)val3.m_forceField == (Object)null)) { if (!NormalRange.TryGetValue(val3, out var value2)) { value2 = (NormalRange[val3] = val3.m_forceField.endRange); Plugin.Log.LogInfo((object)$"Wisplight normal clearing radius: {value2} m"); } val3.m_forceField.endRange = value2 * num2; if (num != _loggedLevel) { _loggedLevel = num; Plugin.Log.LogInfo((object)string.Format("Wisplight level {0}: x{1} -> clearing radius {2} m (start {3}, scale {4}, item {5})", num, num2, val3.m_forceField.endRange, val3.m_forceField.startRange, ((Component)val3).transform.lossyScale, (val != null) ? val.m_shared.m_name : "none")); } } } if (NormalRange.Count <= 20) { return; } List<Demister> list = new List<Demister>(); foreach (Demister key in NormalRange.Keys) { if ((Object)(object)key == (Object)null) { list.Add(key); } } foreach (Demister item in list) { NormalRange.Remove(item); } } } }