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 ExponentialItemsReloaded V2 v2.0.2
ExponentialItemsReloaded.dll
Decompiled a day agousing System; using System.Diagnostics; using System.IO; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using System.Security; using System.Security.Permissions; using BepInEx; using BepInEx.Configuration; using Microsoft.CodeAnalysis; using On.RoR2; using R2API; using RoR2; 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: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("0.0.0.0")] [module: UnverifiableCode] [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 ExponentialItemsReloaded { public enum StackingMode { Off, Linear, Sqrt, Exponential } [BepInDependency(/*Could not decode attribute arguments.*/)] [BepInDependency(/*Could not decode attribute arguments.*/)] [BepInPlugin("com.cryptidlabs.exponentialitemsreloaded", "ExponentialItemsReloaded", "2.0.0")] public class ExponentialItemsReloadedPlugin : BaseUnityPlugin { public const string PluginGUID = "com.cryptidlabs.exponentialitemsreloaded"; public const string PluginName = "ExponentialItemsReloaded"; public const string PluginVersion = "2.0.0"; private static ArtifactDef exponentialArtifactDef; private static ConfigEntry<bool> requireArtifactEnabled; private static ConfigEntry<StackingMode> stackingMode; private static ConfigEntry<int> linearMultiplier; private static ConfigEntry<float> sqrtFactor; private static ConfigEntry<int> maxStack; private static ConfigEntry<int> baseSize; private static ConfigEntry<bool> affectTier1; private static ConfigEntry<bool> affectTier2; private static ConfigEntry<bool> affectTier3; private static ConfigEntry<bool> affectBoss; private static ConfigEntry<bool> affectLunar; private static ConfigEntry<bool> affectVoid; private static ConfigEntry<bool> affectTierless; private static ConfigEntry<bool> affectTemporaryItems; private static ConfigEntry<bool> affectEquipment; private static ConfigEntry<bool> debugLogging; private static ConfigEntry<bool> debugLogArtifactList; private static bool suppressExponentialHook; public void Awake() { //IL_0235: Unknown result type (might be due to invalid IL or missing references) //IL_023f: Expected O, but got Unknown //IL_0246: Unknown result type (might be due to invalid IL or missing references) //IL_0250: Expected O, but got Unknown //IL_0257: Unknown result type (might be due to invalid IL or missing references) //IL_0261: Expected O, but got Unknown //IL_0268: Unknown result type (might be due to invalid IL or missing references) //IL_0272: Expected O, but got Unknown //IL_0279: Unknown result type (might be due to invalid IL or missing references) //IL_0283: Expected O, but got Unknown requireArtifactEnabled = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "Require Artifact Enabled", true, "If true, custom stacking only applies while Artifact of Exponents is enabled. If false, the mod is always active."); stackingMode = ((BaseUnityPlugin)this).Config.Bind<StackingMode>("General", "Stacking Mode", StackingMode.Sqrt, "Stacking calculation mode: Off (Vanilla 1x), Linear (y = M*x), Sqrt (sublinear root curve, great for Huntress/Attack Speed), or Exponential (original 2^n)."); linearMultiplier = ((BaseUnityPlugin)this).Config.Bind<int>("General", "Linear Multiplier", 2, "Multiplier for Linear mode (e.g. 2 gives 2x stacks: 2, 4, 6, 8...)."); sqrtFactor = ((BaseUnityPlugin)this).Config.Bind<float>("General", "Sqrt Factor", 2.2f, "Sublinear bonus factor for Sqrt mode (e.g. 2.2 gives 3, 5, 7, 8, 10, 11, 13...)."); maxStack = ((BaseUnityPlugin)this).Config.Bind<int>("General", "Max Stack Size", 4096, "Maximum item stack count this mod will try to reach."); baseSize = ((BaseUnityPlugin)this).Config.Bind<int>("General", "Base Size", 2, "Exponential base. 2 gives 1,2,4,8... 3 gives 1,3,9,27..."); affectTier1 = ((BaseUnityPlugin)this).Config.Bind<bool>("Item Filters", "Affect White Items", true, "Allows common/white items to stack with the chosen mode."); affectTier2 = ((BaseUnityPlugin)this).Config.Bind<bool>("Item Filters", "Affect Green Items", true, "Allows uncommon/green items to stack with the chosen mode."); affectTier3 = ((BaseUnityPlugin)this).Config.Bind<bool>("Item Filters", "Affect Red Items", true, "Allows legendary/red items to stack with the chosen mode."); affectBoss = ((BaseUnityPlugin)this).Config.Bind<bool>("Item Filters", "Affect Boss Items", true, "Allows boss/yellow items to stack with the chosen mode."); affectLunar = ((BaseUnityPlugin)this).Config.Bind<bool>("Item Filters", "Affect Lunar Items", true, "Allows lunar items to stack with the chosen mode."); affectVoid = ((BaseUnityPlugin)this).Config.Bind<bool>("Item Filters", "Affect Void Items", true, "Allows void items to stack with the chosen mode."); affectTierless = ((BaseUnityPlugin)this).Config.Bind<bool>("Item Filters", "Affect Tierless Items", false, "Allows tierless/hidden/internal items to stack. Usually safer off."); affectTemporaryItems = ((BaseUnityPlugin)this).Config.Bind<bool>("Item Filters", "Affect Temporary Items", false, "Allows temporary items to stack with the chosen mode."); affectEquipment = ((BaseUnityPlugin)this).Config.Bind<bool>("Item Filters", "Affect Equipment", false, "Reserved safety option."); debugLogging = ((BaseUnityPlugin)this).Config.Bind<bool>("Debug", "Enable Debug Logging", false, "Logs item stack changes when the mod applies custom stacking."); debugLogArtifactList = ((BaseUnityPlugin)this).Config.Bind<bool>("Debug", "Log Artifact List On Load", false, "Logs every loaded artifact on game load."); RegisterArtifact(); Inventory.GiveItem_ItemIndex_int += new hook_GiveItem_ItemIndex_int(Inventory_GiveItem_ItemIndex_int); Inventory.GiveItem_ItemDef_int += new hook_GiveItem_ItemDef_int(Inventory_GiveItem_ItemDef_int); Inventory.GiveItemTemp += new hook_GiveItemTemp(Inventory_GiveItemTemp); GenericPickupController.AttemptGrant += new hook_AttemptGrant(GenericPickupController_AttemptGrant); CharacterBody.RecalculateStats += new hook_RecalculateStats(CharacterBody_RecalculateStats); ((BaseUnityPlugin)this).Logger.LogInfo((object)string.Format("{0} v{1} loaded (Mode: {2}). Artifact registered: {3}", "ExponentialItemsReloaded", "2.0.0", stackingMode.Value, (Object)(object)exponentialArtifactDef != (Object)null)); if (debugLogArtifactList.Value) { RoR2Application.onLoad = (Action)Delegate.Combine(RoR2Application.onLoad, new Action(LogLoadedArtifacts)); } } private void RegisterArtifact() { LanguageAPI.Add("ARTIFACT_EXPONENTIALITEMS_NAME", "Artifact of Exponents"); LanguageAPI.Add("ARTIFACT_EXPONENTIALITEMS_DESC", "Items stack with advanced scaling (Linear, Sqrt, or Exponential) instead of one at a time."); exponentialArtifactDef = ScriptableObject.CreateInstance<ArtifactDef>(); exponentialArtifactDef.cachedName = "ExponentialItems"; exponentialArtifactDef.nameToken = "ARTIFACT_EXPONENTIALITEMS_NAME"; exponentialArtifactDef.descriptionToken = "ARTIFACT_EXPONENTIALITEMS_DESC"; Sprite val = LoadSprite("icon_selected.png"); Sprite val2 = LoadSprite("icon_deselected.png"); if ((Object)(object)val != (Object)null) { exponentialArtifactDef.smallIconSelectedSprite = val; } if ((Object)(object)val2 != (Object)null) { exponentialArtifactDef.smallIconDeselectedSprite = val2; } ContentAddition.AddArtifactDef(exponentialArtifactDef); } private Sprite LoadSprite(string fileName) { //IL_0043: Unknown result type (might be due to invalid IL or missing references) //IL_0049: Expected O, but got Unknown //IL_0076: Unknown result type (might be due to invalid IL or missing references) //IL_0085: Unknown result type (might be due to invalid IL or missing references) string text = Path.Combine(Path.GetDirectoryName(((BaseUnityPlugin)this).Info.Location), fileName); if (!File.Exists(text)) { ((BaseUnityPlugin)this).Logger.LogWarning((object)("Icon file not found: " + text)); return null; } try { byte[] array = File.ReadAllBytes(text); Texture2D val = new Texture2D(2, 2, (TextureFormat)4, false); ImageConversion.LoadImage(val, array); ((Object)val).name = Path.GetFileNameWithoutExtension(fileName); return Sprite.Create(val, new Rect(0f, 0f, (float)((Texture)val).width, (float)((Texture)val).height), new Vector2(0.5f, 0.5f), 100f); } catch (Exception arg) { ((BaseUnityPlugin)this).Logger.LogError((object)$"Failed to load icon {fileName}: {arg}"); return null; } } private void Inventory_GiveItem_ItemIndex_int(orig_GiveItem_ItemIndex_int orig, Inventory self, ItemIndex itemIndex, int count) { //IL_00ac: Unknown result type (might be due to invalid IL or missing references) //IL_0014: Unknown result type (might be due to invalid IL or missing references) //IL_0008: Unknown result type (might be due to invalid IL or missing references) //IL_0022: Unknown result type (might be due to invalid IL or missing references) //IL_0057: Unknown result type (might be due to invalid IL or missing references) //IL_0036: Unknown result type (might be due to invalid IL or missing references) //IL_008b: Unknown result type (might be due to invalid IL or missing references) try { if (suppressExponentialHook || !ShouldApply(self, itemIndex, count)) { orig.Invoke(self, itemIndex, count); return; } int currentStackForExponential = GetCurrentStackForExponential(self, itemIndex); int nextTargetStack = GetNextTargetStack(currentStackForExponential); if (nextTargetStack <= currentStackForExponential) { orig.Invoke(self, itemIndex, count); return; } int num = Math.Max(1, nextTargetStack - currentStackForExponential); LogDebug($"GiveItem {itemIndex}: current={currentStackForExponential}, target={nextTargetStack}, adding={num}"); suppressExponentialHook = true; try { orig.Invoke(self, itemIndex, num); } finally { suppressExponentialHook = false; } } catch (Exception ex) { ((BaseUnityPlugin)this).Logger.LogError((object)ex); orig.Invoke(self, itemIndex, count); } } private void Inventory_GiveItem_ItemDef_int(orig_GiveItem_ItemDef_int orig, Inventory self, ItemDef itemDef, int count) { //IL_003f: Unknown result type (might be due to invalid IL or missing references) //IL_004b: Unknown result type (might be due to invalid IL or missing references) //IL_0057: Expected O, but got Unknown if ((Object)(object)itemDef == (Object)null) { orig.Invoke(self, itemDef, count); return; } Inventory_GiveItem_ItemIndex_int((orig_GiveItem_ItemIndex_int)delegate(Inventory inventory, ItemIndex index, int itemCount) { orig.Invoke(inventory, itemDef, itemCount); }, self, itemDef.itemIndex, count); } private void Inventory_GiveItemTemp(orig_GiveItemTemp orig, Inventory self, ItemIndex itemIndex, float countToAdd) { //IL_00c2: Unknown result type (might be due to invalid IL or missing references) //IL_001b: Unknown result type (might be due to invalid IL or missing references) //IL_0011: Unknown result type (might be due to invalid IL or missing references) //IL_0029: Unknown result type (might be due to invalid IL or missing references) //IL_0063: Unknown result type (might be due to invalid IL or missing references) //IL_003d: Unknown result type (might be due to invalid IL or missing references) //IL_00a1: Unknown result type (might be due to invalid IL or missing references) try { if (suppressExponentialHook || countToAdd <= 0f || !ShouldApplyTemporaryGrant(self, itemIndex)) { orig.Invoke(self, itemIndex, countToAdd); return; } int itemCountEffective = self.GetItemCountEffective(itemIndex); int nextTargetStack = GetNextTargetStack(itemCountEffective); if (nextTargetStack <= itemCountEffective) { orig.Invoke(self, itemIndex, countToAdd); return; } float num = Math.Max(countToAdd, nextTargetStack - itemCountEffective); LogTempGrant($"GiveItemTemp {itemIndex}: effectiveCurrent={itemCountEffective}, incoming={countToAdd}, target={nextTargetStack}, adding={num}"); suppressExponentialHook = true; try { orig.Invoke(self, itemIndex, num); } finally { suppressExponentialHook = false; } } catch (Exception ex) { ((BaseUnityPlugin)this).Logger.LogError((object)ex); orig.Invoke(self, itemIndex, countToAdd); } } private void GenericPickupController_AttemptGrant(orig_AttemptGrant orig, GenericPickupController self, CharacterBody body) { //IL_0014: Unknown result type (might be due to invalid IL or missing references) //IL_0023: Unknown result type (might be due to invalid IL or missing references) //IL_002b: Unknown result type (might be due to invalid IL or missing references) //IL_0035: Unknown result type (might be due to invalid IL or missing references) //IL_0037: Invalid comparison between Unknown and I4 //IL_003d: Unknown result type (might be due to invalid IL or missing references) //IL_0055: Unknown result type (might be due to invalid IL or missing references) //IL_0057: Invalid comparison between Unknown and I4 //IL_0061: Unknown result type (might be due to invalid IL or missing references) //IL_006f: Unknown result type (might be due to invalid IL or missing references) //IL_00a5: Unknown result type (might be due to invalid IL or missing references) //IL_00e4: Unknown result type (might be due to invalid IL or missing references) Inventory val = (((Object)(object)body != (Object)null) ? body.inventory : null); PickupDef pickupDef = PickupCatalog.GetPickupDef(self.pickupIndex); ItemIndex val2 = (ItemIndex)((pickupDef == null) ? (-1) : ((int)pickupDef.itemIndex)); int num = (((Object)(object)val != (Object)null && (int)val2 != -1) ? GetCurrentStackForExponential(val, val2) : 0); orig.Invoke(self, body); try { if ((Object)(object)val == (Object)null || (int)val2 == -1 || suppressExponentialHook || !ShouldApplyItem(val, val2)) { return; } int currentStackForExponential = GetCurrentStackForExponential(val, val2); if (currentStackForExponential <= num) { return; } int nextTargetStack = GetNextTargetStack(num); if (nextTargetStack <= currentStackForExponential) { return; } int num2 = nextTargetStack - currentStackForExponential; LogDebug($"Pickup {val2}: before={num}, after={currentStackForExponential}, target={nextTargetStack}, adding={num2}"); suppressExponentialHook = true; try { GiveExtraStacksForExponential(val, val2, num2); } finally { suppressExponentialHook = false; } } catch (Exception ex) { ((BaseUnityPlugin)this).Logger.LogError((object)ex); } } private void CharacterBody_RecalculateStats(orig_RecalculateStats orig, CharacterBody self) { orig.Invoke(self); } private static int GetCurrentStackForExponential(Inventory inventory, ItemIndex itemIndex) { //IL_0009: Unknown result type (might be due to invalid IL or missing references) //IL_000b: Invalid comparison between Unknown and I4 //IL_000f: Unknown result type (might be due to invalid IL or missing references) //IL_0025: Unknown result type (might be due to invalid IL or missing references) //IL_001d: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)inventory == (Object)null || (int)itemIndex == -1) { return 0; } if (IsTemporaryItem(ItemCatalog.GetItemDef(itemIndex))) { return inventory.GetItemCountEffective(itemIndex); } return inventory.GetItemCountPermanent(itemIndex); } private static void GiveExtraStacksForExponential(Inventory inventory, ItemIndex itemIndex, int amountToGive) { //IL_0009: Unknown result type (might be due to invalid IL or missing references) //IL_000b: Invalid comparison between Unknown and I4 //IL_0011: Unknown result type (might be due to invalid IL or missing references) //IL_0029: Unknown result type (might be due to invalid IL or missing references) //IL_001f: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)inventory != (Object)null && (int)itemIndex != -1 && amountToGive > 0) { if (IsTemporaryItem(ItemCatalog.GetItemDef(itemIndex))) { inventory.GiveItemTemp(itemIndex, (float)amountToGive); } else { inventory.GiveItemPermanent(itemIndex, amountToGive); } } } private static int GetNextTargetStack(int current) { int num = Math.Max(1, maxStack.Value); if (current < 0) { return 1; } if (current >= num) { return current; } switch (stackingMode.Value) { case StackingMode.Off: return current + 1; case StackingMode.Linear: { int num3 = Math.Max(1, linearMultiplier.Value); return Math.Min(num, current + num3); } case StackingMode.Sqrt: { float num4 = Math.Max(0.1f, sqrtFactor.Value); if (current <= 0) { return Math.Min(num, 1 + (int)Math.Round(num4)); } double num5 = ((double)(0f - num4) + Math.Sqrt((double)(num4 * num4) + 4.0 * (double)current)) / 2.0; int num6 = Math.Max(1, (int)Math.Round(num5 * num5)) + 1; int val2 = num6 + (int)Math.Round((double)num4 * Math.Sqrt(num6)); return Math.Min(num, Math.Max(current + 1, val2)); } default: { int num2 = Math.Max(2, baseSize.Value); if (current == 0) { return 1; } double y = Math.Floor(Math.Log(current, num2)) + 1.0; int val = (int)Math.Pow(num2, y); return Math.Min(num, Math.Max(current + 1, val)); } } } private static void LogTempGrant(string message) { Debug.Log((object)("[ExponentialItemsReloaded] [TempGrant] " + message)); } private static bool ShouldApplyTemporaryGrant(Inventory self, ItemIndex itemIndex) { //IL_0009: Unknown result type (might be due to invalid IL or missing references) //IL_000b: Invalid comparison between Unknown and I4 if ((Object)(object)self == (Object)null || (int)itemIndex == -1) { return false; } if ((Object)(object)exponentialArtifactDef == (Object)null) { return false; } if (requireArtifactEnabled.Value) { if ((Object)(object)RunArtifactManager.instance == (Object)null) { return false; } if (!RunArtifactManager.instance.IsArtifactEnabled(exponentialArtifactDef)) { return false; } } if (!affectTemporaryItems.Value) { return false; } return true; } private static bool ShouldApplyItem(Inventory self, ItemIndex itemIndex) { //IL_0009: Unknown result type (might be due to invalid IL or missing references) //IL_000b: Invalid comparison between Unknown and I4 //IL_004c: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)self == (Object)null || (int)itemIndex == -1) { return false; } if ((Object)(object)exponentialArtifactDef == (Object)null) { return false; } if (requireArtifactEnabled.Value) { if ((Object)(object)RunArtifactManager.instance == (Object)null) { return false; } if (!RunArtifactManager.instance.IsArtifactEnabled(exponentialArtifactDef)) { return false; } } ItemDef itemDef = ItemCatalog.GetItemDef(itemIndex); if ((Object)(object)itemDef == (Object)null) { return false; } if (IsTemporaryItem(itemDef)) { return affectTemporaryItems.Value; } if (!IsAllowedByTierConfig(itemDef)) { return false; } if (!affectTierless.Value && IsTierlessOrHidden(itemDef)) { return false; } return true; } private static bool ShouldApply(Inventory self, ItemIndex itemIndex, int count) { //IL_0007: Unknown result type (might be due to invalid IL or missing references) if (count != 1) { return false; } return ShouldApplyItem(self, itemIndex); } private static bool IsAllowedByTierConfig(ItemDef itemDef) { //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_0035: Expected I4, but got Unknown ItemTier tier = itemDef.tier; switch ((int)tier) { case 0: return affectTier1.Value; case 1: return affectTier2.Value; case 2: return affectTier3.Value; case 4: return affectBoss.Value; case 3: return affectLunar.Value; case 6: case 7: case 8: case 9: return affectVoid.Value; default: return true; } } private static bool IsTierlessOrHidden(ItemDef itemDef) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Invalid comparison between Unknown and I4 if ((int)itemDef.tier != 5) { return itemDef.hidden; } return true; } private static bool IsTemporaryItem(ItemDef itemDef) { //IL_000c: Unknown result type (might be due to invalid IL or missing references) //IL_0011: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)itemDef == (Object)null) { return false; } string text = ((object)itemDef.tier/*cast due to .constrained prefix*/).ToString(); string text2 = ((Object)itemDef).name ?? string.Empty; string obj = itemDef.nameToken ?? string.Empty; string text3 = text2.ToLowerInvariant(); string text4 = obj.ToLowerInvariant(); if (text.IndexOf("Food", StringComparison.OrdinalIgnoreCase) >= 0) { return true; } if (text.IndexOf("Temp", StringComparison.OrdinalIgnoreCase) >= 0 || text.IndexOf("Temporary", StringComparison.OrdinalIgnoreCase) >= 0) { return true; } if (text3.Contains("temp") || text3.Contains("temporary") || text4.Contains("temp") || text4.Contains("temporary")) { return true; } if (itemDef.hidden) { return true; } return false; } private static void LogLoadedArtifacts() { LogDebug($"Total Artifacts Loaded: {ArtifactCatalog.artifactCount}"); } private static void LogDebug(string message) { if (debugLogging != null && debugLogging.Value) { Debug.Log((object)("[ExponentialItemsReloaded] " + message)); } } } }