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 PartialCommand v0.1.0
PartialCommand.dll
Decompiled a day agousing System; using System.Collections.Generic; using System.Diagnostics; using System.Globalization; using System.IO; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using BepInEx; using BepInEx.Configuration; using BepInEx.Logging; using HarmonyLib; using Microsoft.CodeAnalysis; using R2API; using RoR2; using UnityEngine; using UnityEngine.Networking; [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("PartialCommand")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyFileVersion("0.1.0.0")] [assembly: AssemblyInformationalVersion("0.1.0")] [assembly: AssemblyProduct("PartialCommand")] [assembly: AssemblyTitle("PartialCommand")] [assembly: AssemblyVersion("0.1.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 PartialCommand { [HarmonyPatch] internal static class CommandChancePatch { private static readonly List<PartialArtifact> Enabled = new List<PartialArtifact>(3); private static Xoroshiro128Plus rng; private static string lastDescription; internal static void Init() { Run.onRunStartGlobal += OnRunStart; } internal static void Dispose() { Run.onRunStartGlobal -= OnRunStart; rng = null; lastDescription = null; Enabled.Clear(); } private static void OnRunStart(Run run) { //IL_0010: Unknown result type (might be due to invalid IL or missing references) //IL_001a: Expected O, but got Unknown rng = new Xoroshiro128Plus(run.seed ^ 0x9E3779B97F4A7C15uL); lastDescription = null; } [HarmonyPrefix] [HarmonyPatch(typeof(PickupDropletController), "CreatePickupDroplet", new Type[] { typeof(CreatePickupInfo), typeof(Vector3), typeof(Vector3) })] private static void MaybeMakeChoosable(ref CreatePickupInfo pickupInfo) { //IL_0009: Unknown result type (might be due to invalid IL or missing references) //IL_000e: Unknown result type (might be due to invalid IL or missing references) //IL_000f: 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) if (!NetworkServer.active) { return; } PickupArtifactFlag artifactFlag = pickupInfo.artifactFlag; if (((Enum)artifactFlag).HasFlag((Enum)(object)(PickupArtifactFlag)1) || ((Enum)artifactFlag).HasFlag((Enum)(object)(PickupArtifactFlag)2)) { return; } RunArtifactManager instance = RunArtifactManager.instance; if (!Object.op_Implicit((Object)(object)instance)) { return; } if (instance.IsArtifactEnabled(Artifacts.commandArtifactDef)) { Describe("Artifact of Command is enabled, so every drop is already choosable. PartialCommand is standing down for this run."); return; } float num = ChanceForCurrentRun(instance); if (Enabled.Count != 0) { Describe(Summarise(num)); if (!(num <= 0f) && (!(num < 100f) || !(NextPercent() >= num))) { ref PickupArtifactFlag artifactFlag2 = ref pickupInfo.artifactFlag; artifactFlag2 = (PickupArtifactFlag)((uint)artifactFlag2 | 1u); } } } private static float ChanceForCurrentRun(RunArtifactManager artifacts) { Enabled.Clear(); float num = 0f; float num2 = 1f; foreach (PartialArtifact item in PartialArtifacts.All) { if (!((Object)(object)item.Def == (Object)null) && artifacts.IsArtifactEnabled(item.Def)) { float num3 = ModConfig.Percent(item.Chance); Enabled.Add(item); if (num3 > num) { num = num3; } num2 *= 1f - num3 / 100f; } } if (Enabled.Count == 0) { return 0f; } return Mathf.Clamp((ModConfig.MultipleArtifacts.Value == ModConfig.StackMode.Independent) ? ((1f - num2) * 100f) : num, 0f, ModConfig.Percent(ModConfig.MaximumChance)); } private static string Summarise(float chance) { List<string> list = new List<string>(Enabled.Count); foreach (PartialArtifact item in Enabled) { list.Add(item.DisplayName + " " + Format(ModConfig.Percent(item.Chance)) + "%"); } string text = string.Join(" + ", list.ToArray()); if (Enabled.Count > 1) { text = text + " [" + ModConfig.MultipleArtifacts.Value.ToString() + "]"; } text = text + " -> " + Format(chance) + "% of drops choosable this run."; float num = ModConfig.Percent(ModConfig.MaximumChance); if (num < 100f) { text = text + " (MaximumChance ceiling: " + Format(num) + "%)"; } if (chance <= 0f) { text += " That is zero, so nothing will be choosable - check the Chances values and MaximumChance in the config."; } return text; } private static string Format(float value) { return value.ToString("0.##", CultureInfo.InvariantCulture); } private static void Describe(string message) { if (!(message == lastDescription)) { lastDescription = message; Plugin.Log.LogInfo((object)message); } } private static float NextPercent() { //IL_0014: Unknown result type (might be due to invalid IL or missing references) //IL_001e: Expected O, but got Unknown if (rng == null) { rng = new Xoroshiro128Plus((ulong)DateTime.UtcNow.Ticks); } return rng.nextNormalizedFloat * 100f; } } internal static class IconFactory { private const int Size = 128; private const int Supersample = 3; internal static string IconDirectory; internal static Sprite Build(string key, float fraction, bool selected) { Sprite val = TryLoadFromDisk(key, selected); if (!((Object)(object)val != (Object)null)) { return Generate(key, fraction, selected); } return val; } private static Sprite TryLoadFromDisk(string key, bool selected) { if (string.IsNullOrEmpty(IconDirectory)) { return null; } string text = Path.Combine(IconDirectory, key.ToLowerInvariant() + (selected ? "_on.png" : "_off.png")); if (!File.Exists(text)) { return null; } Texture2D val = NewTexture(key + (selected ? "_on" : "_off")); if (!ImageConversion.LoadImage(val, File.ReadAllBytes(text), false)) { Object.Destroy((Object)(object)val); Plugin.Log.LogWarning((object)("Could not decode icon at " + text + "; falling back to the generated one.")); return null; } return MakeSprite(val); } private static Sprite Generate(string key, float fraction, bool selected) { //IL_0028: Unknown result type (might be due to invalid IL or missing references) //IL_0012: Unknown result type (might be due to invalid IL or missing references) //IL_002d: Unknown result type (might be due to invalid IL or missing references) //IL_0056: Unknown result type (might be due to invalid IL or missing references) //IL_0040: Unknown result type (might be due to invalid IL or missing references) //IL_005b: Unknown result type (might be due to invalid IL or missing references) //IL_0084: Unknown result type (might be due to invalid IL or missing references) //IL_006e: Unknown result type (might be due to invalid IL or missing references) //IL_0089: Unknown result type (might be due to invalid IL or missing references) //IL_0204: Unknown result type (might be due to invalid IL or missing references) //IL_01e9: Unknown result type (might be due to invalid IL or missing references) //IL_0209: Unknown result type (might be due to invalid IL or missing references) //IL_0152: Unknown result type (might be due to invalid IL or missing references) //IL_0153: Unknown result type (might be due to invalid IL or missing references) //IL_018b: Unknown result type (might be due to invalid IL or missing references) //IL_0197: Unknown result type (might be due to invalid IL or missing references) //IL_01a3: Unknown result type (might be due to invalid IL or missing references) //IL_0186: Unknown result type (might be due to invalid IL or missing references) //IL_0183: Unknown result type (might be due to invalid IL or missing references) //IL_0187: Unknown result type (might be due to invalid IL or missing references) Color val = (selected ? new Color(1f, 0.8f, 0.38f) : new Color(0.4f, 0.41f, 0.45f)); Color val2 = (selected ? new Color(1f, 0.56f, 0.2f) : new Color(0.29f, 0.3f, 0.33f)); Color val3 = (selected ? new Color(0.26f, 0.2f, 0.13f) : new Color(0.16f, 0.16f, 0.18f)); float num = Mathf.Clamp01(fraction) * MathF.PI * 2f; float num2 = 1f / 9f; Color[] array = (Color[])(object)new Color[16384]; for (int i = 0; i < 128; i++) { for (int j = 0; j < 128; j++) { float num3 = 0f; float num4 = 0f; float num5 = 0f; float num6 = 0f; for (int k = 0; k < 3; k++) { for (int l = 0; l < 3; l++) { float num7 = (float)j + ((float)l + 0.5f) / 3f - 0.5f - 63.5f; float num8 = (float)i + ((float)k + 0.5f) / 3f - 0.5f - 63.5f; float num9 = Mathf.Sqrt(num7 * num7 + num8 * num8); Color val4; if (num9 >= 50.56f && num9 <= 60.16f) { val4 = val; } else { if (!(num9 <= 42.24f)) { continue; } float num10 = Mathf.Atan2(num7, num8); if (num10 < 0f) { num10 += MathF.PI * 2f; } val4 = ((num10 < num) ? val2 : val3); } num3 += val4.r; num4 += val4.g; num5 += val4.b; num6 += 1f; } } array[i * 128 + j] = (Color)((num6 > 0f) ? new Color(num3 / num6, num4 / num6, num5 / num6, num6 * num2) : Color.clear); } } Texture2D obj = NewTexture(key + (selected ? "_on" : "_off")); obj.SetPixels(array); obj.Apply(false, false); return MakeSprite(obj); } private static Texture2D NewTexture(string name) { //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) //IL_0022: 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_0030: Unknown result type (might be due to invalid IL or missing references) //IL_0039: Expected O, but got Unknown return new Texture2D(128, 128, (TextureFormat)4, false) { name = "PartialCommand_" + name, wrapMode = (TextureWrapMode)1, filterMode = (FilterMode)1, hideFlags = (HideFlags)32 }; } private static Sprite MakeSprite(Texture2D texture) { //IL_0019: Unknown result type (might be due to invalid IL or missing references) //IL_0028: Unknown result type (might be due to invalid IL or missing references) Sprite obj = Sprite.Create(texture, new Rect(0f, 0f, (float)((Texture)texture).width, (float)((Texture)texture).height), new Vector2(0.5f, 0.5f), 100f); ((Object)obj).name = ((Object)texture).name; ((Object)obj).hideFlags = (HideFlags)32; return obj; } } internal static class ModConfig { internal enum StackMode { Highest, Independent } internal static ConfigEntry<float> DirectChance; internal static ConfigEntry<float> SuggestChance; internal static ConfigEntry<float> AskChance; internal static ConfigEntry<StackMode> MultipleArtifacts; internal static ConfigEntry<float> MaximumChance; internal static void Init(ConfigFile file) { //IL_0029: Unknown result type (might be due to invalid IL or missing references) //IL_0033: Expected O, but got Unknown //IL_0061: Unknown result type (might be due to invalid IL or missing references) //IL_006b: Expected O, but got Unknown //IL_0099: Unknown result type (might be due to invalid IL or missing references) //IL_00a3: Expected O, but got Unknown //IL_00ec: Unknown result type (might be due to invalid IL or missing references) //IL_00f6: Expected O, but got Unknown DirectChance = file.Bind<float>("Chances", "Direct", 75f, new ConfigDescription("Percent of dropped items that become choosable under Artifact of Direct.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 100f), Array.Empty<object>())); SuggestChance = file.Bind<float>("Chances", "Suggest", 50f, new ConfigDescription("Percent of dropped items that become choosable under Artifact of Suggest.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 100f), Array.Empty<object>())); AskChance = file.Bind<float>("Chances", "Ask", 25f, new ConfigDescription("Percent of dropped items that become choosable under Artifact of Ask.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 100f), Array.Empty<object>())); MultipleArtifacts = file.Bind<StackMode>("Behaviour", "MultipleArtifacts", StackMode.Highest, "What happens when several of these artifacts are enabled at once. Highest: only the biggest chance applies. Independent: each one rolls on its own, so 75 + 50 lands at 87.5%."); MaximumChance = file.Bind<float>("Behaviour", "MaximumChance", 100f, new ConfigDescription("Hard ceiling on the combined chance, applied after the artifacts and the stacking mode are worked out. A safety valve for odd combinations; 100 disables it.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 100f), Array.Empty<object>())); } internal static float Percent(ConfigEntry<float> entry) { float value = entry.Value; if (float.IsNaN(value)) { return 0f; } return Mathf.Clamp(value, 0f, 100f); } } internal sealed class PartialArtifact { internal string Key { get; } internal string DisplayName { get; } internal ConfigEntry<float> Chance { get; } internal ArtifactDef Def { get; set; } internal PartialArtifact(string key, string displayName, ConfigEntry<float> chance) { Key = key; DisplayName = displayName; Chance = chance; } } internal static class PartialArtifacts { internal static readonly List<PartialArtifact> All = new List<PartialArtifact>(); internal static void Register() { All.Clear(); Add(new PartialArtifact("Direct", "Artifact of Direct", ModConfig.DirectChance)); Add(new PartialArtifact("Suggest", "Artifact of Suggest", ModConfig.SuggestChance)); Add(new PartialArtifact("Ask", "Artifact of Ask", ModConfig.AskChance)); } private static void Add(PartialArtifact artifact) { string text = "PARTIALCOMMAND_" + artifact.Key.ToUpperInvariant(); string text2 = text + "_NAME"; string text3 = text + "_DESCRIPTION"; float num = ModConfig.Percent(artifact.Chance); LanguageAPI.Add(text2, artifact.DisplayName); LanguageAPI.Add(text3, "<style=cIsUtility>" + num.ToString("0.##", CultureInfo.InvariantCulture) + "%</style> of dropped items let you pick what they become. The rest drop as normal."); ArtifactDef val = ScriptableObject.CreateInstance<ArtifactDef>(); val.cachedName = "PARTIALCOMMAND_" + artifact.Key; val.nameToken = text2; val.descriptionToken = text3; val.unlockableDef = null; val.requiredExpansion = null; val.smallIconSelectedSprite = IconFactory.Build(artifact.Key, num / 100f, selected: true); val.smallIconDeselectedSprite = IconFactory.Build(artifact.Key, num / 100f, selected: false); if (!ContentAddition.AddArtifactDef(val)) { Plugin.Log.LogError((object)("R2API rejected " + artifact.DisplayName + "; it will not appear in the lobby.")); return; } artifact.Def = val; All.Add(artifact); Plugin.Log.LogInfo((object)("Registered " + artifact.DisplayName + " at " + num + "%.")); } } [BepInPlugin("com.zackman.partialcommand", "PartialCommand", "0.1.0")] [BepInDependency(/*Could not decode attribute arguments.*/)] [BepInDependency(/*Could not decode attribute arguments.*/)] [BepInDependency(/*Could not decode attribute arguments.*/)] [BepInProcess("Risk of Rain 2.exe")] public sealed class Plugin : BaseUnityPlugin { public const string Guid = "com.zackman.partialcommand"; public const string Name = "PartialCommand"; public const string Version = "0.1.0"; private Harmony harmony; internal static ManualLogSource Log { get; private set; } private void Awake() { //IL_004e: Unknown result type (might be due to invalid IL or missing references) //IL_0058: Expected O, but got Unknown Log = ((BaseUnityPlugin)this).Logger; ModConfig.Init(((BaseUnityPlugin)this).Config); IconFactory.IconDirectory = Path.Combine(Path.GetDirectoryName(((BaseUnityPlugin)this).Info.Location) ?? string.Empty, "icons"); PartialArtifacts.Register(); CommandChancePatch.Init(); harmony = new Harmony("com.zackman.partialcommand"); harmony.PatchAll(typeof(CommandChancePatch)); } private void OnDestroy() { Harmony obj = harmony; if (obj != null) { obj.UnpatchSelf(); } CommandChancePatch.Dispose(); } } }