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 Sticky Tweaks v1.0.3
StickyTweaks.dll
Decompiled a month ago#define DEBUG using 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 BepInEx.Logging; using IL.RoR2; using Microsoft.CodeAnalysis; using Mono.Cecil.Cil; using MonoMod.Cil; using On.RoR2; using R2API; using R2API.Utils; using RiskOfOptions; using RiskOfOptions.OptionConfigs; using RiskOfOptions.Options; using RoR2; using RoR2.Projectile; using UnityEngine; using UnityEngine.AddressableAssets; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)] [assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")] [assembly: AssemblyCompany("StickyTweaks")] [assembly: AssemblyConfiguration("Debug")] [assembly: AssemblyFileVersion("1.0.0.0")] [assembly: AssemblyInformationalVersion("1.0.0+81a73fd425895e8c1d8b3242524a824932503ebe")] [assembly: AssemblyProduct("StickyTweaks")] [assembly: AssemblyTitle("StickyTweaks")] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("1.0.0.0")] [module: UnverifiableCode] [module: RefSafetyRules(11)] namespace Microsoft.CodeAnalysis { [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] internal sealed class EmbeddedAttribute : Attribute { } } namespace System.Runtime.CompilerServices { [CompilerGenerated] [Microsoft.CodeAnalysis.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 StickyTweaks { internal static class Log { private static ManualLogSource _logSource; internal static void Init(ManualLogSource logSource) { _logSource = logSource; } [Conditional("DEBUG")] internal static void Debug(object data) { _logSource.LogDebug(data); } internal static void Error(object data) { _logSource.LogError(data); } internal static void Fatal(object data) { _logSource.LogFatal(data); } internal static void Info(object data) { _logSource.LogInfo(data); } internal static void Message(object data) { _logSource.LogMessage(data); } internal static void Warning(object data) { _logSource.LogWarning(data); } } [BepInDependency(/*Could not decode attribute arguments.*/)] [BepInPlugin("Braquen.Sticky_Tweaks", "Sticky_Tweaks", "1.0.1")] [NetworkCompatibility(/*Could not decode attribute arguments.*/)] public class Main : BaseUnityPlugin { [CompilerGenerated] private static class <>O { public static Manipulator <0>__GlobalEventManager_ProcessHitEnemy; public static Action<ProjectileManager, GameObject, Vector3, Quaternion, GameObject, float, float, bool, DamageColorIndex, GameObject, float, DamageInfo> <1>__FireModifiedStickyBomb; public static Func<DamageInfo, bool> <2>__CheckHitEnemyProc; public static Func<float, float> <3>__InjectProcChance; } public const string PluginGUID = "Braquen.Sticky_Tweaks"; public const string PluginAuthor = "Braquen"; public const string PluginName = "Sticky_Tweaks"; public const string PluginVersion = "1.0.1"; public static PluginInfo pluginInfo; public static AssetBundle AssetBundle; public static ConfigEntry<float> Damage; public static ConfigEntry<float> ProcChance; public static ConfigEntry<float> ProcCoefficient; public static ConfigEntry<bool> OnHitAll; private static float DamageCoefficient; private GameObject StickyBombPrefab; private static ProjectileImpactExplosion StickyExplosion; public static ModdedProcType StickyProc = ProcTypeAPI.ReserveProcType(); public void Awake() { //IL_0028: Unknown result type (might be due to invalid IL or missing references) //IL_002e: Expected O, but got Unknown //IL_0052: 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_0062: Unknown result type (might be due to invalid IL or missing references) //IL_006d: Unknown result type (might be due to invalid IL or missing references) //IL_007d: Expected O, but got Unknown //IL_0078: Unknown result type (might be due to invalid IL or missing references) //IL_0082: Expected O, but got Unknown //IL_00a7: Unknown result type (might be due to invalid IL or missing references) //IL_00ac: Unknown result type (might be due to invalid IL or missing references) //IL_00b7: Unknown result type (might be due to invalid IL or missing references) //IL_00c2: Unknown result type (might be due to invalid IL or missing references) //IL_00d2: Expected O, but got Unknown //IL_00cd: Unknown result type (might be due to invalid IL or missing references) //IL_00d7: Expected O, but got Unknown //IL_00fc: Unknown result type (might be due to invalid IL or missing references) //IL_0101: Unknown result type (might be due to invalid IL or missing references) //IL_010c: Unknown result type (might be due to invalid IL or missing references) //IL_0117: Unknown result type (might be due to invalid IL or missing references) //IL_0127: 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_014d: Unknown result type (might be due to invalid IL or missing references) //IL_0157: Expected O, but got Unknown //IL_0168: Unknown result type (might be due to invalid IL or missing references) //IL_016d: 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_0188: Unknown result type (might be due to invalid IL or missing references) //IL_02c5: Unknown result type (might be due to invalid IL or missing references) //IL_02cf: Expected O, but got Unknown //IL_02ad: Unknown result type (might be due to invalid IL or missing references) //IL_02b2: Unknown result type (might be due to invalid IL or missing references) //IL_02b8: Expected O, but got Unknown Log.Init(((BaseUnityPlugin)this).Logger); pluginInfo = ((BaseUnityPlugin)this).Info; ConfigFile val = new ConfigFile(Path.Combine(Paths.ConfigPath, "braquen-stickytweaks.cfg"), true); Damage = val.Bind<float>("Stats", "Damage", 1.8f, "Sticky Bomb's damage multiplier."); ModSettingsManager.AddOption((BaseOption)new StepSliderOption(Damage, new StepSliderConfig { min = 0.1f, max = 18f, increment = 0.05f })); ProcChance = val.Bind<float>("Stats", "Proc Chance", 5f, "Sticky Bomb's chance to proc on hit."); ModSettingsManager.AddOption((BaseOption)new StepSliderOption(ProcChance, new StepSliderConfig { min = 1f, max = 300f, increment = 0.5f })); ProcCoefficient = val.Bind<float>("Extra Functionality", "Proc Coefficient", 0.5f, "Sticky Bomb's proc coefficient. Set 0 to restore base game functionality."); ModSettingsManager.AddOption((BaseOption)new StepSliderOption(ProcCoefficient, new StepSliderConfig { min = 0f, max = 10f, increment = 0.1f })); OnHitAll = val.Bind<bool>("Extra Functionality", "Stick Anything", false, "Allows Sticky Bomb to proc when hitting anything, similar to Behemoth or Overloading Elite bombs."); ModSettingsManager.AddOption((BaseOption)new CheckBoxOption(OnHitAll)); ModSettingsManager.SetModDescription("Tweaks sticky bomb to give it more potential for synergy."); Sprite modIcon = Addressables.LoadAssetAsync<Sprite>((object)"RoR2/Base/StickyBomb/texStickyBombIcon.png").WaitForCompletion(); ModSettingsManager.SetModIcon(modIcon); StickyBombPrefab = Addressables.LoadAssetAsync<GameObject>((object)"RoR2/Base/StickyBomb/StickyBomb.prefab").WaitForCompletion(); ProjectileController component = StickyBombPrefab.GetComponent<ProjectileController>(); component.procCoefficient = 1f; StickyExplosion = StickyBombPrefab.GetComponent<ProjectileImpactExplosion>(); ((ProjectileExplosion)StickyExplosion).blastProcCoefficient = ProcCoefficient.Value; ProcCoefficient.SettingChanged += delegate { ((ProjectileExplosion)StickyExplosion).blastProcCoefficient = ProcCoefficient.Value; }; DamageCoefficient = Damage.Value / 1.8f; Damage.SettingChanged += delegate { DamageCoefficient = Damage.Value / 1.8f; }; Damage.SettingChanged += delegate { UpdateText(); }; ProcChance.SettingChanged += delegate { UpdateText(); }; ProcCoefficient.SettingChanged += delegate { UpdateText(); }; OnHitAll.SettingChanged += delegate { UpdateText(); }; UpdateText(); object obj = <>O.<0>__GlobalEventManager_ProcessHitEnemy; if (obj == null) { Manipulator val2 = GlobalEventManager_ProcessHitEnemy; <>O.<0>__GlobalEventManager_ProcessHitEnemy = val2; obj = (object)val2; } GlobalEventManager.ProcessHitEnemy += (Manipulator)obj; GlobalEventManager.OnHitAllProcess += new hook_OnHitAllProcess(GlobalEventManager_OnHitAllProcess); } private static void GlobalEventManager_ProcessHitEnemy(ILContext il) { //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_0008: Expected O, but got Unknown //IL_0085: Unknown result type (might be due to invalid IL or missing references) //IL_0195: Unknown result type (might be due to invalid IL or missing references) //IL_01c3: Unknown result type (might be due to invalid IL or missing references) ILCursor val = new ILCursor(il); Log.Debug("Changing proc chain mask"); try { val.GotoNext((MoveType)0, new Func<Instruction, bool>[1] { (Instruction x) => ILPatternMatchingExt.MatchLdstr(x, "Prefabs/Projectiles/StickyBomb") }); val.GotoNext((MoveType)0, new Func<Instruction, bool>[1] { (Instruction x) => ILPatternMatchingExt.MatchCallOrCallvirt<ProjectileManager>(x, "FireProjectileWithoutDamageType") }); Log.Debug("Replacing fire projectile call"); val.Next.OpCode = OpCodes.Ldarg_1; int index = val.Index; val.Index = index + 1; val.EmitDelegate<Action<ProjectileManager, GameObject, Vector3, Quaternion, GameObject, float, float, bool, DamageColorIndex, GameObject, float, DamageInfo>>((Action<ProjectileManager, GameObject, Vector3, Quaternion, GameObject, float, float, bool, DamageColorIndex, GameObject, float, DamageInfo>)FireModifiedStickyBomb); index = val.Index; val.Index = index - 1; val.MarkLabel(); } catch (Exception e) { ErrorHookFailed("Add Sticky to mask", e); return; } Log.Debug("Adding Procchain conditional"); try { ILLabel stickyConditional = null; Log.Debug("Locating sticky bomb if-block"); val.GotoPrev((MoveType)0, new Func<Instruction, bool>[1] { (Instruction x) => ILPatternMatchingExt.MatchCallOrCallvirt<Inventory>(x, "GetItemCountEffective") }); Log.Debug("GetItemCount call found"); val.GotoNext((MoveType)2, new Func<Instruction, bool>[1] { (Instruction x) => ILPatternMatchingExt.MatchBle(x, ref stickyConditional) }); Log.Debug("Sticky bomb condition block end found"); Log.Debug("Adding procchain max condition"); Log.Debug(stickyConditional.Target); val.Emit(OpCodes.Ldarg_1); val.EmitDelegate<Func<DamageInfo, bool>>((Func<DamageInfo, bool>)CheckHitEnemyProc); val.Emit(OpCodes.Brtrue, (object)stickyConditional); Log.Debug("Proc condition added, now adding new proc chance"); val.GotoNext((MoveType)2, new Func<Instruction, bool>[1] { (Instruction x) => ILPatternMatchingExt.MatchLdcR4(x, 5f) }); Log.Debug("Old proc chance found"); val.EmitDelegate<Func<float, float>>((Func<float, float>)InjectProcChance); Log.Debug("Added new proc chance"); } catch (Exception e2) { ErrorHookFailed("Check for sticky proc", e2); } } private static bool CheckHitEnemyProc(DamageInfo info) { //IL_000e: Unknown result type (might be due to invalid IL or missing references) //IL_0013: Unknown result type (might be due to invalid IL or missing references) return OnHitAll.Value || ProcTypeAPI.HasModdedProc(info.procChainMask, StickyProc); } private static float InjectProcChance(float ogChance) { return ProcChance.Value; } private static void FireModifiedStickyBomb(ProjectileManager instance, GameObject prefab, Vector3 pos, Quaternion rot, GameObject owner, float damage, float force, bool crit, DamageColorIndex col, GameObject target, float speedOverride, DamageInfo info) { //IL_0003: Unknown result type (might be due to invalid IL or missing references) //IL_0013: 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_001b: Unknown result type (might be due to invalid IL or missing references) //IL_001c: Unknown result type (might be due to invalid IL or missing references) //IL_004d: Unknown result type (might be due to invalid IL or missing references) //IL_004f: Unknown result type (might be due to invalid IL or missing references) //IL_0078: Unknown result type (might be due to invalid IL or missing references) //IL_007d: 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_0095: Unknown result type (might be due to invalid IL or missing references) FireProjectileInfo val = default(FireProjectileInfo); val.projectilePrefab = prefab; val.position = pos; val.rotation = rot; val.owner = owner; val.damage = damage * DamageCoefficient; val.force = force; val.crit = crit; val.damageColorIndex = col; val.target = target; ((FireProjectileInfo)(ref val)).speedOverride = speedOverride; ((FireProjectileInfo)(ref val)).fuseOverride = -1f; val.procChainMask = info.procChainMask; ProcTypeAPI.AddModdedProc(ref val.procChainMask, StickyProc); instance.FireProjectile(val); } internal static void ErrorHookFailed(string name, Exception e) { Log.Error(name + " hook failed: " + e.Message); } private void GlobalEventManager_OnHitAllProcess(orig_OnHitAllProcess orig, GlobalEventManager self, DamageInfo damageInfo, GameObject hitObject) { //IL_00bb: Unknown result type (might be due to invalid IL or missing references) //IL_00c0: Unknown result type (might be due to invalid IL or missing references) //IL_0112: Unknown result type (might be due to invalid IL or missing references) //IL_011c: Unknown result type (might be due to invalid IL or missing references) //IL_0121: Unknown result type (might be due to invalid IL or missing references) //IL_0126: Unknown result type (might be due to invalid IL or missing references) //IL_012b: Unknown result type (might be due to invalid IL or missing references) //IL_013d: Unknown result type (might be due to invalid IL or missing references) //IL_0142: Unknown result type (might be due to invalid IL or missing references) //IL_0144: Unknown result type (might be due to invalid IL or missing references) //IL_0135: Unknown result type (might be due to invalid IL or missing references) //IL_0149: Unknown result type (might be due to invalid IL or missing references) //IL_0164: Unknown result type (might be due to invalid IL or missing references) //IL_0166: Unknown result type (might be due to invalid IL or missing references) //IL_015d: Unknown result type (might be due to invalid IL or missing references) //IL_016b: Unknown result type (might be due to invalid IL or missing references) //IL_0198: Unknown result type (might be due to invalid IL or missing references) //IL_019a: Unknown result type (might be due to invalid IL or missing references) orig.Invoke(self, damageInfo, hitObject); if (!OnHitAll.Value || damageInfo.procCoefficient == 0f || damageInfo.rejected || !Object.op_Implicit((Object)(object)damageInfo.attacker)) { return; } CharacterBody component = damageInfo.attacker.GetComponent<CharacterBody>(); if (!Object.op_Implicit((Object)(object)component)) { return; } CharacterMaster master = component.master; if (!Object.op_Implicit((Object)(object)master)) { return; } Inventory inventory = master.inventory; if (!Object.op_Implicit((Object)(object)master.inventory)) { return; } CharacterBody component2 = hitObject.GetComponent<CharacterBody>(); if (!ProcTypeAPI.HasModdedProc(damageInfo.procChainMask, StickyProc)) { int itemCountEffective = inventory.GetItemCountEffective(Items.StickyBomb); if (itemCountEffective > 0 && Util.CheckRoll(ProcChance.Value * (float)itemCountEffective * damageInfo.procCoefficient, master)) { Vector3 val = damageInfo.position + 0.1f * Vector3.upVector; Vector3 val2 = (Object.op_Implicit((Object)(object)component2) ? (component2.corePosition - val) : Vector3.zero); float magnitude = ((Vector3)(ref val2)).magnitude; Quaternion rot = ((magnitude != 0f) ? Util.QuaternionSafeLookRotation(val2) : Random.rotationUniform); float num = 1.8f; float damage = Util.OnHitProcDamage(damageInfo.damage, component.damage, num); FireModifiedStickyBomb(ProjectileManager.instance, LegacyResourcesAPI.Load<GameObject>("Prefabs/Projectiles/StickyBomb"), val, rot, damageInfo.attacker, damage, 100f, damageInfo.crit, (DamageColorIndex)3, null, -1f, damageInfo); } } } private void UpdateText() { string token = "ITEM_STICKYBOMB_DESC"; string newtext = "<style=cIsDamage>" + ProcChance.Value + "%</style> <style=cStack>(+" + ProcChance.Value + "% per stack)</style> chance on hit to attach a <style=cIsDamage>bomb</style>" + (OnHitAll.Value ? "" : " to an enemy") + ", detonating for <style=cIsDamage>" + Damage.Value * 100f + "%</style> TOTAL damage."; string token2 = "ITEM_STICKYBOMB_PICKUP"; string text = "Chance on hit to attach a bomb to enemies"; text += (OnHitAll.Value ? " and terrain." : "."); ReplaceString(token, newtext); ReplaceString(token2, text); } private void ReplaceString(string token, string newtext) { LanguageAPI.Add(token, newtext); } } }