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 HIFUBanditTweaks v1.2.6
HIFUBanditTweaks.dll
Decompiled 2 years agousing System; using System.Collections; using System.Collections.Generic; using System.Diagnostics; using System.Linq; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using System.Security; using System.Security.Permissions; using System.Text.RegularExpressions; using BepInEx; using BepInEx.Configuration; using BepInEx.Logging; using EntityStates; using EntityStates.Bandit2; using EntityStates.Bandit2.Weapon; using HIFUBanditTweaks.Skills; using HarmonyLib; using IL.EntityStates.Bandit2; using IL.EntityStates.Bandit2.Weapon; using IL.RoR2; using KinematicCharacterController; using Microsoft.CodeAnalysis; using Mono.Cecil.Cil; using MonoMod.Cil; using MonoMod.RuntimeDetour; using On.EntityStates.Bandit2; using On.EntityStates.Bandit2.Weapon; using On.RoR2; using On.RoR2.Achievements.Bandit2; using R2API; using R2API.Networking; using R2API.Networking.Interfaces; using RoR2; using RoR2.Achievements; using RoR2.Achievements.Bandit2; using RoR2.Skills; using UnityEngine; using UnityEngine.AddressableAssets; using UnityEngine.Networking; [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("HIFUBanditTweaks")] [assembly: AssemblyConfiguration("Debug")] [assembly: AssemblyFileVersion("1.0.0.0")] [assembly: AssemblyInformationalVersion("1.0.0")] [assembly: AssemblyProduct("HIFUBanditTweaks")] [assembly: AssemblyTitle("HIFUBanditTweaks")] [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 HIFUBanditTweaks { public class ConfigManager { internal static bool ConfigChanged; internal static bool VersionChanged; public static T HandleConfig<T>(ConfigEntryBase entry, ConfigFile config, string name) { //IL_0087: Unknown result type (might be due to invalid IL or missing references) //IL_008d: Expected O, but got Unknown //IL_00a9: Unknown result type (might be due to invalid IL or missing references) //IL_00af: Expected O, but got Unknown //IL_00b8: Unknown result type (might be due to invalid IL or missing references) //IL_00be: Expected O, but got Unknown MethodInfo methodInfo = (from x in typeof(ConfigFile).GetMethods() where x.Name == "Bind" select x).First(); methodInfo = methodInfo.MakeGenericMethod(typeof(T)); object[] parameters = new object[3] { (object)new ConfigDefinition(Regex.Replace(config.ConfigFilePath, "\\W", "") + " : " + entry.Definition.Section, name), entry.DefaultValue, (object)new ConfigDescription(entry.Description.Description, (AcceptableValueBase)null, Array.Empty<object>()) }; ConfigEntryBase val = (ConfigEntryBase)methodInfo.Invoke(config, parameters); if (Main._preVersioning) { entry.BoxedValue = entry.DefaultValue; } if (!ConfigEqual(val.DefaultValue, val.BoxedValue) && VersionChanged) { entry.BoxedValue = entry.DefaultValue; val.BoxedValue = val.DefaultValue; } return default(T); } private static bool ConfigEqual(object a, object b) { if (a.Equals(b)) { return true; } if (float.TryParse(a.ToString(), out var result) && float.TryParse(b.ToString(), out var result2) && (double)Mathf.Abs(result - result2) < 0.0001) { return true; } return false; } } [BepInDependency(/*Could not decode attribute arguments.*/)] [BepInDependency(/*Could not decode attribute arguments.*/)] [BepInDependency(/*Could not decode attribute arguments.*/)] [BepInDependency(/*Could not decode attribute arguments.*/)] [BepInDependency(/*Could not decode attribute arguments.*/)] [BepInDependency(/*Could not decode attribute arguments.*/)] [BepInPlugin("HIFU.HIFUBanditTweaks", "HIFUBanditTweaks", "1.2.6")] public class Main : BaseUnityPlugin { public const string PluginGUID = "HIFU.HIFUBanditTweaks"; public const string PluginAuthor = "HIFU"; public const string PluginName = "HIFUBanditTweaks"; public const string PluginVersion = "1.2.6"; public static ConfigFile HBTConfig; public static ConfigFile HBTBackupConfig; public static ManualLogSource HBTLogger; public static bool _preVersioning; public static BodyIndex banditBodyIndex; public static ConfigEntry<bool> enableAutoConfig { get; set; } public static ConfigEntry<string> latestVersion { get; set; } public void Awake() { //IL_0027: Unknown result type (might be due to invalid IL or missing references) //IL_0031: Expected O, but got Unknown //IL_0149: Unknown result type (might be due to invalid IL or missing references) //IL_0153: Expected O, but got Unknown HBTLogger = ((BaseUnityPlugin)this).Logger; HBTConfig = ((BaseUnityPlugin)this).Config; HBTBackupConfig = new ConfigFile(Paths.ConfigPath + "\\HIFU.HIFUBanditTweaks.Backup.cfg", true); HBTBackupConfig.Bind<string>(": DO NOT MODIFY THIS FILES CONTENTS :", ": DO NOT MODIFY THIS FILES CONTENTS :", ": DO NOT MODIFY THIS FILES CONTENTS :", ": DO NOT MODIFY THIS FILES CONTENTS :"); enableAutoConfig = HBTConfig.Bind<bool>("Config", "Enable Auto Config Sync", true, "Disabling this would stop HIFUBanditTweaks from syncing config whenever a new version is found."); _preVersioning = !((Dictionary<ConfigDefinition, string>)AccessTools.DeclaredPropertyGetter(typeof(ConfigFile), "OrphanedEntries").Invoke(HBTConfig, null)).Keys.Any((ConfigDefinition x) => x.Key == "Latest Version"); latestVersion = HBTConfig.Bind<string>("Config", "Latest Version", "1.2.6", "DO NOT CHANGE THIS"); if (enableAutoConfig.Value && (_preVersioning || latestVersion.Value != "1.2.6")) { latestVersion.Value = "1.2.6"; ConfigManager.VersionChanged = true; HBTLogger.LogInfo((object)"Config Autosync Enabled."); } BodyCatalog.Init += new hook_Init(BodyCatalog_Init1); Specials.Init(); IEnumerable<Type> enumerable = from type in Assembly.GetExecutingAssembly().GetTypes() where !type.IsAbstract && type.IsSubclassOf(typeof(TweakBase)) select type; HBTLogger.LogInfo((object)"==+----------------==TWEAKS==----------------+=="); foreach (Type item in enumerable) { TweakBase tweakBase = (TweakBase)Activator.CreateInstance(item); if (ValidateTweak(tweakBase)) { tweakBase.Init(); } } IEnumerable<Type> enumerable2 = from type in Assembly.GetExecutingAssembly().GetTypes() where !type.IsAbstract && type.IsSubclassOf(typeof(MiscBase)) select type; HBTLogger.LogInfo((object)"==+----------------==MISC==----------------+=="); foreach (Type item2 in enumerable2) { MiscBase miscBase = (MiscBase)Activator.CreateInstance(item2); if (ValidateMisc(miscBase)) { miscBase.Init(); } } NetworkingAPI.RegisterMessageType<SyncCooldownReduction>(); } private IEnumerator BodyCatalog_Init1(orig_Init orig) { yield return orig.Invoke(); banditBodyIndex = BodyCatalog.FindBodyIndex("Bandit2Body(Clone)"); } public bool ValidateTweak(TweakBase tb) { if (tb.isEnabled && ((BaseUnityPlugin)this).Config.Bind<bool>(tb.Name, "Enable?", true, "Vanilla is false").Value) { return true; } return false; } public bool ValidateMisc(MiscBase mb) { if (mb.isEnabled && ((BaseUnityPlugin)this).Config.Bind<bool>(mb.Name, "Enable?", true, "Vanilla is false").Value) { return true; } return false; } private void PeripheryMyBeloved() { } } public abstract class MiscBase { public abstract string Name { get; } public virtual bool isEnabled { get; } = true; public T ConfigOption<T>(T value, string name, string description) { ConfigEntry<T> val = Main.HBTConfig.Bind<T>(Name, name, value, description); ConfigManager.HandleConfig<T>((ConfigEntryBase)(object)val, Main.HBTBackupConfig, name); return val.Value; } public abstract void Hooks(); public string d(float f) { return f * 100f + "%"; } public virtual void Init() { Hooks(); Main.HBTLogger.LogInfo((object)("Added " + Name)); } } public abstract class MiscBase<T> : MiscBase where T : MiscBase<T> { public static T instance { get; set; } public MiscBase() { if (instance != null) { throw new InvalidOperationException("Singleton class " + typeof(T).Name + " was instantiated twice"); } instance = this as T; } } public abstract class TweakBase { public abstract string Name { get; } public abstract string SkillToken { get; } public abstract string DescText { get; } public virtual bool isEnabled { get; } = true; public T ConfigOption<T>(T value, string name, string description) { ConfigEntry<T> val = Main.HBTConfig.Bind<T>(Name, name, value, description); ConfigManager.HandleConfig<T>((ConfigEntryBase)(object)val, Main.HBTBackupConfig, name); return val.Value; } public abstract void Hooks(); public string d(float f) { return f * 100f + "%"; } public virtual void Init() { Hooks(); string text = "BANDIT2_" + SkillToken.ToUpper() + "_DESCRIPTION"; LanguageAPI.Add(text, DescText); Main.HBTLogger.LogInfo((object)("Added " + Name)); } } public abstract class TweakBase<T> : TweakBase where T : TweakBase<T> { public static T instance { get; set; } public TweakBase() { if (instance != null) { throw new InvalidOperationException("Singleton class " + typeof(T).Name + " was instantiated twice"); } instance = this as T; } } } namespace HIFUBanditTweaks.Skills { public class Blast : TweakBase<Blast> { public static float Damage; public static int AmmoCount; public static float AutofireDur; public static bool VanillaSpread; public override string Name => ": Primary :: Blast"; public override string SkillToken => "primary_alt"; public override string DescText => "Fire an automatic rifle blast for <style=cIsDamage>" + d(Damage) + " damage</style>. Can hold up to " + AmmoCount + " bullets."; public override void Init() { Damage = ConfigOption(2.2f, "Damage", "Decimal. Vanilla is 3.3"); AmmoCount = ConfigOption(6, "Charges", "Vanilla is 4"); AutofireDur = ConfigOption(0.12f, "Autofire Duration per Bullet", ""); VanillaSpread = ConfigOption(value: false, "Vanilla Spread", "Uses vanilla's spread and recoil settings, making the skill much more inaccurate"); base.Init(); } public override void Hooks() { //IL_0008: Unknown result type (might be due to invalid IL or missing references) //IL_0012: Expected O, but got Unknown //IL_001a: Unknown result type (might be due to invalid IL or missing references) //IL_0024: Expected O, but got Unknown Bandit2FirePrimaryBase.OnEnter += new hook_OnEnter(Bandit2FirePrimaryBase_OnEnter); Bandit2FirePrimaryBase.GetMinimumInterruptPriority += new hook_GetMinimumInterruptPriority(Bandit2FirePrimaryBase_GetMinimumInterruptPriority); Changes(); } private InterruptPriority Bandit2FirePrimaryBase_GetMinimumInterruptPriority(orig_GetMinimumInterruptPriority orig, Bandit2FirePrimaryBase self) { //IL_002c: 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) //IL_002f: Unknown result type (might be due to invalid IL or missing references) if (((EntityState)self).fixedAge <= self.minimumDuration && ((EntityState)self).inputBank.skill1.wasDown) { return (InterruptPriority)2; } return (InterruptPriority)0; } private void Bandit2FirePrimaryBase_OnEnter(orig_OnEnter orig, Bandit2FirePrimaryBase self) { if (self is Bandit2FireRifle) { ((GenericBulletBaseState)self).damageCoefficient = Damage; if (!VanillaSpread) { ((GenericBulletBaseState)self).recoilAmplitudeX = 0.15f; ((GenericBulletBaseState)self).recoilAmplitudeY = 0.7f; ((GenericBulletBaseState)self).spreadYawScale = 0f; ((GenericBulletBaseState)self).spreadPitchScale = 0f; ((GenericBulletBaseState)self).bulletRadius = 0.4f; } self.minimumBaseDuration = AutofireDur; } orig.Invoke(self); } private void Changes() { //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_000b: 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) SkillDef val = Addressables.LoadAssetAsync<SkillDef>((object)"RoR2/Base/Bandit2/Bandit2Blast.asset").WaitForCompletion(); val.baseMaxStock = AmmoCount; val.mustKeyPress = false; val.interruptPriority = (InterruptPriority)1; } private void HaveAblastPeriphery() { } } public class Burst : TweakBase<Burst> { public static int PelletCount; public static float Damage; public static float ProcCoefficient; public static int AmmoCount; public static float AutofireDur; public override string Name => ": Primary : Burst"; public override string SkillToken => "primary"; public override string DescText => "Fire an automatic shotgun burst for <style=cIsDamage>" + PelletCount + "x" + d(Damage) + " damage</style>. Can hold up to " + AmmoCount + " shells."; public override void Init() { PelletCount = ConfigOption(5, "Pellet Count", "Vanilla is 5"); Damage = ConfigOption(0.75f, "Damage", "Decimal. Vanilla is 1"); ProcCoefficient = ConfigOption(0.7f, "Proc Coefficient", "Vanilla is 0.5"); AmmoCount = ConfigOption(4, "Charges", "Vanilla is 4"); AutofireDur = ConfigOption(0.12f, "Autofire Duration per Bullet", ""); base.Init(); } public override void Hooks() { //IL_0008: Unknown result type (might be due to invalid IL or missing references) //IL_0012: Expected O, but got Unknown Bandit2FirePrimaryBase.OnEnter += new hook_OnEnter(Bandit2FirePrimaryBase_OnEnter); Changes(); } private void Bandit2FirePrimaryBase_OnEnter(orig_OnEnter orig, Bandit2FirePrimaryBase self) { if (self is FireShotgun2) { ((GenericBulletBaseState)self).bulletCount = PelletCount; ((GenericBulletBaseState)self).damageCoefficient = Damage; ((GenericBulletBaseState)self).procCoefficient = ProcCoefficient; ((GenericBulletBaseState)self).bulletRadius = 0.3f; self.minimumBaseDuration = AutofireDur; } orig.Invoke(self); } private void Changes() { //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_000b: 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) SkillDef val = Addressables.LoadAssetAsync<SkillDef>((object)"RoR2/Base/Bandit2/FireShotgun2.asset").WaitForCompletion(); val.baseMaxStock = AmmoCount; val.mustKeyPress = false; val.interruptPriority = (InterruptPriority)1; } } public class Desperado : TweakBase<Desperado> { public static float Damage; public static float StackDamage; public static float Cooldown; public override string Name => ": Special :: Desperado"; public override string SkillToken => "special_alt"; public override string DescText => "<style=cIsDamage>Slayer</style>. Fire a revolver shot for <style=cIsDamage>" + d(Damage) + " damage</style>. Kills grant <style=cIsDamage>stacking tokens</style> for <style=cIsDamage>" + d(StackDamage * Damage) + "</style> more Desperado skill damage."; public override void Init() { Cooldown = ConfigOption(6f, "Cooldown", "Vanilla is 4"); Damage = ConfigOption(8f, "Damage", "Decimal. Vanilla is 6"); StackDamage = ConfigOption(0.055f, "Damage Per Token", "Vanilla is 0.1. Additive Damage increase per token = Damage Per Token * Damage"); base.Init(); } public override void Hooks() { //IL_0008: Unknown result type (might be due to invalid IL or missing references) //IL_0012: Expected O, but got Unknown //IL_001a: Unknown result type (might be due to invalid IL or missing references) //IL_0024: Expected O, but got Unknown BaseFireSidearmRevolverState.OnEnter += new hook_OnEnter(BaseFireSidearmRevolverState_OnEnter); FireSidearmSkullRevolver.ModifyBullet += new Manipulator(FireSidearmSkullRevolver_ModifyBullet); Changes(); } private void FireSidearmSkullRevolver_ModifyBullet(ILContext il) { //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_0008: Expected O, but got Unknown ILCursor val = new ILCursor(il); if (val.TryGotoNext((MoveType)0, new Func<Instruction, bool>[1] { (Instruction x) => ILPatternMatchingExt.MatchLdcR4(x, 0.1f) })) { val.Next.Operand = StackDamage; } else { Main.HBTLogger.LogError((object)"Failed to apply Desperado Stacking Damage hook"); } } private void BaseFireSidearmRevolverState_OnEnter(orig_OnEnter orig, BaseFireSidearmRevolverState self) { if (self is FireSidearmSkullRevolver) { self.damageCoefficient = Damage; } orig.Invoke(self); } private void Changes() { //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_000b: Unknown result type (might be due to invalid IL or missing references) SkillDef val = Addressables.LoadAssetAsync<SkillDef>((object)"RoR2/Base/Bandit2/SkullRevolver.asset").WaitForCompletion(); val.baseRechargeInterval = Cooldown; val.canceledFromSprinting = false; } } public static class Specials { [CompilerGenerated] private static class <>O { public static hook_FixedUpdate <0>__BaseSidearmState_FixedUpdate; public static hook_FixedUpdate <1>__BasePrepSidearmRevolverState_FixedUpdate; } public static void Init() { //IL_0011: Unknown result type (might be due to invalid IL or missing references) //IL_0016: Unknown result type (might be due to invalid IL or missing references) //IL_001c: Expected O, but got Unknown //IL_0032: Unknown result type (might be due to invalid IL or missing references) //IL_0037: Unknown result type (might be due to invalid IL or missing references) //IL_003d: Expected O, but got Unknown object obj = <>O.<0>__BaseSidearmState_FixedUpdate; if (obj == null) { hook_FixedUpdate val = BaseSidearmState_FixedUpdate; <>O.<0>__BaseSidearmState_FixedUpdate = val; obj = (object)val; } BaseSidearmState.FixedUpdate += (hook_FixedUpdate)obj; object obj2 = <>O.<1>__BasePrepSidearmRevolverState_FixedUpdate; if (obj2 == null) { hook_FixedUpdate val2 = BasePrepSidearmRevolverState_FixedUpdate; <>O.<1>__BasePrepSidearmRevolverState_FixedUpdate = val2; obj2 = (object)val2; } BasePrepSidearmRevolverState.FixedUpdate += (hook_FixedUpdate)obj2; } private static void BasePrepSidearmRevolverState_FixedUpdate(orig_FixedUpdate orig, BasePrepSidearmRevolverState self) { ((EntityState)self).fixedAge = ((EntityState)self).fixedAge + Time.fixedDeltaTime; if (((EntityState)self).fixedAge >= ((BaseSidearmState)self).duration && !((EntityState)self).inputBank.skill4.down) { ((EntityState)self).outer.SetNextState(self.GetNextState()); } } public static void BaseSidearmState_FixedUpdate(orig_FixedUpdate orig, BaseSidearmState self) { ((EntityState)self).fixedAge = ((EntityState)self).fixedAge + Time.fixedDeltaTime; } } public class LightsOut : TweakBase<LightsOut> { public static float Damage; public static float Cooldown; public static ModdedDamageType cooldownReset = DamageAPI.ReserveDamageType(); public static float CooldownReduction; public override string Name => ": Special : Lights Out"; public override string SkillToken => "special"; public override string DescText => "<style=cIsDamage>Slayer</style>. Fire a revolver shot for <style=cIsDamage>" + d(Damage) + " damage</style>. Kills <style=cIsUtility>reset Lights Out's cooldown</style> and <style=cIsUtility>reduce other cooldowns</style> by <style=cIsUtility>" + d(CooldownReduction) + "</style>."; public override void Init() { Cooldown = ConfigOption(6f, "Cooldown", "Vanilla is 4"); Damage = ConfigOption(8f, "Damage", "Decimal. Vanilla is 6"); CooldownReduction = ConfigOption(1f, "Non-Special Cooldown Reduction on Kill", "Decimal. Vanilla is 1"); base.Init(); } public override void Hooks() { //IL_0008: Unknown result type (might be due to invalid IL or missing references) //IL_0012: Expected O, but got Unknown //IL_001a: Unknown result type (might be due to invalid IL or missing references) //IL_0024: Expected O, but got Unknown BaseFireSidearmRevolverState.OnEnter += new hook_OnEnter(BaseFireSidearmRevolverState_OnEnter); FireSidearmResetRevolver.ModifyBullet += new hook_ModifyBullet(FireSidearmResetRevolver_ModifyBullet); GlobalEventManager.onCharacterDeathGlobal += GlobalEventManager_onCharacterDeathGlobal; Changes(); } private void GlobalEventManager_onCharacterDeathGlobal(DamageReport damageReport) { //IL_0009: 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_002a: Unknown result type (might be due to invalid IL or missing references) //IL_002c: Unknown result type (might be due to invalid IL or missing references) //IL_003d: Expected O, but got Unknown //IL_0059: Unknown result type (might be due to invalid IL or missing references) DamageInfo damageInfo = damageReport.damageInfo; if (!DamageAPI.HasModdedDamageType(damageInfo, cooldownReset)) { return; } EffectManager.SpawnEffect(LegacyResourcesAPI.Load<GameObject>("Prefabs/Effects/ImpactEffects/Bandit2ResetEffect"), new EffectData { origin = damageInfo.position }, true); GameObject attacker = damageReport.attacker; if (!Object.op_Implicit((Object)(object)attacker)) { return; } NetMessageExtensions.Send((INetMessage)(object)new SyncCooldownReduction(attacker.GetComponent<NetworkIdentity>().netId, CooldownReduction), (NetworkDestination)1); SkillLocator component = attacker.GetComponent<SkillLocator>(); if (Object.op_Implicit((Object)(object)component)) { GenericSkill primary = component.primary; GenericSkill secondary = component.secondary; GenericSkill utility = component.utility; GenericSkill special = component.special; if (Object.op_Implicit((Object)(object)primary) && primary.stock < primary.maxStock) { primary.rechargeStopwatch += primary.finalRechargeInterval * CooldownReduction; } if (Object.op_Implicit((Object)(object)secondary) && secondary.stock < secondary.maxStock) { secondary.rechargeStopwatch += secondary.finalRechargeInterval * CooldownReduction; } if (Object.op_Implicit((Object)(object)utility) && utility.stock < utility.maxStock) { utility.rechargeStopwatch += utility.finalRechargeInterval * CooldownReduction; } if (Object.op_Implicit((Object)(object)special) && special.stock < special.maxStock) { special.rechargeStopwatch += special.finalRechargeInterval * 1f; } } } private void FireSidearmResetRevolver_ModifyBullet(orig_ModifyBullet orig, FireSidearmResetRevolver self, BulletAttack bulletAttack) { //IL_000b: Unknown result type (might be due to invalid IL or missing references) //IL_0018: 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) //IL_0024: 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) orig.Invoke(self, bulletAttack); DamageAPI.AddModdedDamageType(bulletAttack, cooldownReset); bulletAttack.damageType &= DamageTypeCombo.op_Implicit((DamageType)(-5)); } private void BaseFireSidearmRevolverState_OnEnter(orig_OnEnter orig, BaseFireSidearmRevolverState self) { if (self is FireSidearmResetRevolver) { self.damageCoefficient = Damage; } orig.Invoke(self); } private void Changes() { //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_000b: Unknown result type (might be due to invalid IL or missing references) SkillDef val = Addressables.LoadAssetAsync<SkillDef>((object)"RoR2/Base/Bandit2/ResetRevolver.asset").WaitForCompletion(); val.baseRechargeInterval = Cooldown; val.canceledFromSprinting = false; } } public class SyncCooldownReduction : INetMessage, ISerializableObject { private NetworkInstanceId objID; private float cooldownReduction; public SyncCooldownReduction() { } public SyncCooldownReduction(NetworkInstanceId objID, float cooldownReduction) { //IL_0009: Unknown result type (might be due to invalid IL or missing references) //IL_000a: Unknown result type (might be due to invalid IL or missing references) this.objID = objID; this.cooldownReduction = cooldownReduction; } public void Deserialize(NetworkReader reader) { //IL_0003: 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) objID = reader.ReadNetworkId(); cooldownReduction = reader.ReadSingle(); } public void OnReceived() { //IL_0010: Unknown result type (might be due to invalid IL or missing references) if (NetworkServer.active) { return; } GameObject val = Util.FindNetworkObject(objID); if (!Object.op_Implicit((Object)(object)val)) { return; } SkillLocator component = val.GetComponent<SkillLocator>(); if (Object.op_Implicit((Object)(object)component)) { GenericSkill primary = component.primary; GenericSkill secondary = component.secondary; GenericSkill utility = component.utility; GenericSkill special = component.special; if (Object.op_Implicit((Object)(object)primary) && primary.stock < primary.maxStock) { primary.rechargeStopwatch += primary.finalRechargeInterval * cooldownReduction; } if (Object.op_Implicit((Object)(object)secondary) && secondary.stock < secondary.maxStock) { secondary.rechargeStopwatch += secondary.finalRechargeInterval * cooldownReduction; } if (Object.op_Implicit((Object)(object)utility) && utility.stock < utility.maxStock) { utility.rechargeStopwatch += utility.finalRechargeInterval * cooldownReduction; } if (Object.op_Implicit((Object)(object)special) && special.stock < special.maxStock) { special.rechargeStopwatch += special.finalRechargeInterval * 1f; } } } public void Serialize(NetworkWriter writer) { //IL_0003: Unknown result type (might be due to invalid IL or missing references) writer.Write(objID); writer.Write(cooldownReduction); } } public class SerratedDagger : TweakBase<SerratedDagger> { public static float Damage; public static float Cooldown; public static float ProcCoefficient; public static bool Lunge; public override string Name => ": Secondary : Serrated Dagger"; public override string SkillToken => "secondary"; public override string DescText => "<style=cIsUtility>Lunge</style> and slash for <style=cIsDamage>" + d(Damage) + " damage</style>. Critical Strikes also cause <style=cIsHealth>hemorrhaging</style>."; public override void Init() { Damage = ConfigOption(6f, "Damage", "Decimal. Vanilla is 3.6"); Cooldown = ConfigOption(7f, "Cooldown", "Vanilla is 4"); ProcCoefficient = ConfigOption(0f, "Proc Coefficient", "Vanilla is 1"); Lunge = ConfigOption(value: true, "Enable lunge?", "Vanilla is false"); base.Init(); } public override void Hooks() { //IL_0008: Unknown result type (might be due to invalid IL or missing references) //IL_0012: Expected O, but got Unknown SlashBlade.OnEnter += new hook_OnEnter(SlashBlade_OnEnter); Changes(); } private void SlashBlade_OnEnter(orig_OnEnter orig, SlashBlade self) { //IL_0038: 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_0041: Unknown result type (might be due to invalid IL or missing references) //IL_0046: Unknown result type (might be due to invalid IL or missing references) //IL_0049: Unknown result type (might be due to invalid IL or missing references) //IL_0053: Unknown result type (might be due to invalid IL or missing references) //IL_005e: 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_0064: 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_0073: Unknown result type (might be due to invalid IL or missing references) //IL_0074: Unknown result type (might be due to invalid IL or missing references) //IL_007f: 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) //IL_008a: Unknown result type (might be due to invalid IL or missing references) //IL_008e: Unknown result type (might be due to invalid IL or missing references) //IL_0098: Unknown result type (might be due to invalid IL or missing references) //IL_009d: Unknown result type (might be due to invalid IL or missing references) //IL_00bb: Unknown result type (might be due to invalid IL or missing references) //IL_00bc: Unknown result type (might be due to invalid IL or missing references) //IL_00bd: 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_00c4: Unknown result type (might be due to invalid IL or missing references) //IL_00c9: Unknown result type (might be due to invalid IL or missing references) ((BasicMeleeAttack)self).damageCoefficient = Damage; ((BasicMeleeAttack)self).procCoefficient = ProcCoefficient; orig.Invoke(self); if (Lunge && ((EntityState)self).isAuthority) { Ray aimRay = ((BaseState)self).GetAimRay(); Vector3 direction = ((Ray)(ref aimRay)).direction; Vector3 val = ((Vector3)(ref direction)).normalized * 2.6f * ((BaseState)self).moveSpeedStat; Vector3 val2 = Vector3.up * 2f; Vector3 val3 = new Vector3(direction.x, 0f, direction.z); Vector3 val4 = ((Vector3)(ref val3)).normalized * 2.6f; ((BaseCharacterController)((EntityState)self).characterMotor).Motor.ForceUnground(0.1f); ((EntityState)self).characterMotor.velocity = val + val2 + val4; } } private void Changes() { //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_000b: Unknown result type (might be due to invalid IL or missing references) SkillDef val = Addressables.LoadAssetAsync<SkillDef>((object)"RoR2/Base/Bandit2/SlashBlade.asset").WaitForCompletion(); val.baseRechargeInterval = Cooldown; } } public class SerratedShiv : TweakBase<SerratedShiv> { public static float Damage; public static float Cooldown; public static int Charges; public static int ChargesToRecharge; public static bool Sidestep; public override string Name => ": Secondary :: Serrated Shiv"; public override string SkillToken => "secondary_alt"; public override string DescText => (Sidestep ? "<style=cIsUtility>Sidestep</style> and throw" : "Throw") + " a hidden blade for <style=cIsDamage>" + d(Damage) + " damage</style>. Critical Strikes also cause <style=cIsHealth>hemorrhaging</style>." + ((Charges > 1) ? (" <style=cIsUtility>Can hold up to " + Charges + " shivs</style>.") : ""); public override void Init() { Damage = ConfigOption(2f, "Damage", "Decimal. Vanilla is 3.6"); Cooldown = ConfigOption(10f, "Cooldown", "Vanilla is 4"); Charges = ConfigOption(2, "Charges", "Vanilla is 1"); ChargesToRecharge = ConfigOption(2, "Charges to Recharge", "Vanilla is 1"); Sidestep = ConfigOption(value: true, "Enable sidestep?", "Vanilla is false"); base.Init(); } public override void Hooks() { //IL_0008: Unknown result type (might be due to invalid IL or missing references) //IL_0012: Expected O, but got Unknown Bandit2FireShiv.OnEnter += new hook_OnEnter(Bandit2FireShiv_OnEnter); Changes(); } private void Bandit2FireShiv_OnEnter(orig_OnEnter orig, Bandit2FireShiv self) { //IL_002f: Unknown result type (might be due to invalid IL or missing references) //IL_0034: Unknown result type (might be due to invalid IL or missing references) //IL_0052: 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: Unknown result type (might be due to invalid IL or missing references) //IL_005a: Unknown result type (might be due to invalid IL or missing references) //IL_0064: 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_0074: Unknown result type (might be due to invalid IL or missing references) //IL_0091: Unknown result type (might be due to invalid IL or missing references) //IL_0092: Unknown result type (might be due to invalid IL or missing references) self.damageCoefficient = Damage; orig.Invoke(self); if (Sidestep && ((EntityState)self).isAuthority) { Vector3 val = ((((EntityState)self).inputBank.moveVector == Vector3.zero) ? Vector3.zero : ((Vector3)(ref ((EntityState)self).inputBank.moveVector)).normalized); Vector3 velocity = ((Vector3)(ref val)).normalized * 2.5f * ((BaseState)self).moveSpeedStat; ((BaseCharacterController)((EntityState)self).characterMotor).Motor.ForceUnground(0.1f); ((EntityState)self).characterMotor.velocity = velocity; } } private void Changes() { //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_000b: Unknown result type (might be due to invalid IL or missing references) SkillDef val = Addressables.LoadAssetAsync<SkillDef>((object)"RoR2/Base/Bandit2/Bandit2SerratedShivs.asset").WaitForCompletion(); val.baseRechargeInterval = Cooldown; val.baseMaxStock = Charges; val.rechargeStock = ChargesToRecharge; } } public class SmokeBomb : TweakBase<SmokeBomb> { public static float Cooldown; public static float CloakDur; public static float Damage; public static bool Ignite; public override string Name => ": Utility : Smoke Bomb"; public override string SkillToken => "utility"; public override string DescText => "<style=cIsDamage>Stunning</style>." + (Ignite ? " <style=cIsDamage>Ignite</style>." : "") + " Deal <style=cIsDamage>" + d(Damage) + " damage</style>, become <style=cIsUtility>invisible</style> for <style=cIsUtility>" + CloakDur + "</style> seconds, then deal <style=cIsDamage>" + d(Damage) + " damage</style> again."; public override void Init() { Cooldown = ConfigOption(8f, "Cooldown", "Vanilla is 6"); CloakDur = ConfigOption(3f, "Cloak Duration", "Vanilla is 3"); Damage = ConfigOption(2f, "Damage", "Decimal. Vanilla is 2"); Ignite = ConfigOption(value: true, "Ignite?", "Vanilla is false"); base.Init(); } public override void Hooks() { //IL_0008: Unknown result type (might be due to invalid IL or missing references) //IL_0012: Expected O, but got Unknown //IL_0023: Unknown result type (might be due to invalid IL or missing references) //IL_002d: Expected O, but got Unknown StealthMode.OnEnter += new hook_OnEnter(StealthMode_OnEnter); if (Ignite) { StealthMode.FireSmokebomb += new Manipulator(StealthMode_FireSmokebomb); } Changes(); } private void StealthMode_FireSmokebomb(ILContext il) { //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_0008: Expected O, but got Unknown ILCursor val = new ILCursor(il); if (val.TryGotoNext((MoveType)0, new Func<Instruction, bool>[1] { (Instruction x) => ILPatternMatchingExt.MatchLdcI4(x, 32) })) { int index = val.Index; val.Index = index + 1; val.EmitDelegate<Func<int, int>>((Func<int, int>)((int useless) => 160)); } else { Main.HBTLogger.LogError((object)"Failed to apply Smoke Bomb Ignite hook"); } } private void StealthMode_OnEnter(orig_OnEnter orig, StealthMode self) { StealthMode.duration = CloakDur; StealthMode.blastAttackDamageCoefficient = Damage; orig.Invoke(self); } private void Changes() { //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_000b: Unknown result type (might be due to invalid IL or missing references) SkillDef val = Addressables.LoadAssetAsync<SkillDef>((object)"RoR2/Base/Bandit2/ThrowSmokebomb.asset").WaitForCompletion(); val.baseRechargeInterval = Cooldown; if (Ignite) { val.keywordTokens = new string[2] { "KEYWORD_STUNNING", "KEYWORD_IGNITE" }; } } } } namespace HIFUBanditTweaks.Misc { public class Achievements : MiscBase<Achievements> { public static Hook hook; public static int hemoRequirement; public override string Name => ": Misc : Achievements"; public override void Init() { hemoRequirement = ConfigOption(4, "Hemorrhage Required", "Vanilla is 20"); base.Init(); } public override void Hooks() { //IL_0008: Unknown result type (might be due to invalid IL or missing references) //IL_0012: Expected O, but got Unknown //IL_001a: Unknown result type (might be due to invalid IL or missing references) //IL_0024: Expected O, but got Unknown //IL_0051: Unknown result type (might be due to invalid IL or missing references) //IL_005b: Expected O, but got Unknown Bandit2StackSuperBleedAchievement.LookUpRequiredBodyIndex += new hook_LookUpRequiredBodyIndex(Bandit2StackSuperBleedAchievement_LookUpRequiredBodyIndex); Bandit2RevolverFinaleServerAchievement.DoesDamageQualify += new hook_DoesDamageQualify(Bandit2RevolverFinaleServerAchievement_DoesDamageQualify); hook = new Hook((MethodBase)typeof(Bandit2ConsecutiveResetServerAchievement).GetMethod("OnCharacterDeathGlobal", BindingFlags.Instance | BindingFlags.NonPublic), typeof(Achievements).GetMethod("OnKillDamageTypeHook", BindingFlags.Instance | BindingFlags.Static | BindingFlags.NonPublic)); Changes(); } private static void OnKillDamageTypeHook(Bandit2ConsecutiveResetServerAchievement orig, DamageReport damageReport) { //IL_0045: Unknown result type (might be due to invalid IL or missing references) //IL_0027: 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_0032: Unknown result type (might be due to invalid IL or missing references) //IL_0037: Unknown result type (might be due to invalid IL or missing references) //IL_003d: Invalid comparison between Unknown and I4 if (((Object)(object)damageReport.attackerBody == (Object)(object)orig.trackedBody && Object.op_Implicit((Object)(object)damageReport.attackerBody) && (int)DamageTypeCombo.op_Implicit(damageReport.damageInfo.damageType & DamageTypeCombo.op_Implicit((DamageType)4)) == 4) || DamageAPI.HasModdedDamageType(damageReport.damageInfo, LightsOut.cooldownReset)) { orig.waitingForKill = false; orig.progress++; if (orig.progress >= Bandit2ConsecutiveResetAchievement.requirement) { ((BaseServerAchievement)orig).Grant(); } } } private bool Bandit2RevolverFinaleServerAchievement_DoesDamageQualify(orig_DoesDamageQualify orig, BaseServerAchievement self, DamageReport damageReport) { //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_000d: 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_0017: Unknown result type (might be due to invalid IL or missing references) //IL_001d: Invalid comparison between Unknown and I4 //IL_0025: Unknown result type (might be due to invalid IL or missing references) return (int)DamageTypeCombo.op_Implicit(damageReport.damageInfo.damageType & DamageTypeCombo.op_Implicit((DamageType)4)) == 4 || DamageAPI.HasModdedDamageType(damageReport.damageInfo, LightsOut.cooldownReset); } private BodyIndex Bandit2StackSuperBleedAchievement_LookUpRequiredBodyIndex(orig_LookUpRequiredBodyIndex orig, Bandit2StackSuperBleedAchievement self) { //IL_000d: 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_0015: Unknown result type (might be due to invalid IL or missing references) Bandit2StackSuperBleedAchievement.requirement = hemoRequirement; return orig.Invoke(self); } private void Changes() { LanguageAPI.Add("ACHIEVEMENT_BANDIT2STACKSUPERBLEED_DESCRIPTION", "As Bandit, kill a monster with " + hemoRequirement + " stacks of Hemorrhage."); } } public class Hemorrhage : MiscBase<Hemorrhage> { public static float Interval; public static float DamagePerTick; public static float TotalDuration; public override string Name => ": Secondary ::: Hemorrhage"; public override void Init() { Interval = ConfigOption(0.25f, "Tick Interval", "Decimal. Vanilla is 0.25"); DamagePerTick = ConfigOption(1f, "Tick Damage", "Vanilla is 0.333"); TotalDuration = ConfigOption(4f, "Total Duration", "Vanilla is 15"); base.Init(); } public override void Hooks() { //IL_0008: Unknown result type (might be due to invalid IL or missing references) //IL_0012: Expected O, but got Unknown //IL_001a: Unknown result type (might be due to invalid IL or missing references) //IL_0024: Expected O, but got Unknown DotController.InitDotCatalog += new hook_InitDotCatalog(DotController_InitDotCatalog1); GlobalEventManager.ProcessHitEnemy += new Manipulator(GlobalEventManager_ProcessHitEnemy); GlobalEventManager.onServerDamageDealt += GlobalEventManager_onServerDamageDealt; Changes(); } private 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 ILCursor val = new ILCursor(il); if (val.TryGotoNext((MoveType)0, new Func<Instruction, bool>[2] { (Instruction x) => ILPatternMatchingExt.MatchLdcI4(x, 6), (Instruction x) => ILPatternMatchingExt.MatchLdcR4(x, 15f) })) { val.Index += 1; val.Next.Operand = TotalDuration; } else { Main.HBTLogger.LogError((object)"Failed to apply Hemorrhage Total Duration hook"); } } private void GlobalEventManager_onServerDamageDealt(DamageReport dr) { //IL_0056: Unknown result type (might be due to invalid IL or missing references) //IL_0060: Unknown result type (might be due to invalid IL or missing references) //IL_0065: Unknown result type (might be due to invalid IL or missing references) //IL_006a: Unknown result type (might be due to invalid IL or missing references) //IL_0070: Invalid comparison between Unknown and I4 DamageInfo damageInfo = dr.damageInfo; if (damageInfo == null) { return; } GameObject attacker = damageInfo.attacker; if (!((Object)(object)attacker == (Object)null)) { CharacterBody component = attacker.GetComponent<CharacterBody>(); if ((Object)(object)component != (Object)null && damageInfo.crit && damageInfo.procCoefficient == 0f && (int)DamageTypeCombo.op_Implicit(damageInfo.damageType & DamageTypeCombo.op_Implicit((DamageType)134217728)) > 0) { DotController.InflictDot(((Component)dr.victim).gameObject, damageInfo.attacker, (DotIndex)6, TotalDuration, 1f, (uint?)uint.MaxValue); } } } private void DotController_InitDotCatalog1(orig_InitDotCatalog orig) { orig.Invoke(); DotController.dotDefs[6].interval = Interval; DotController.dotDefs[6].damageCoefficient = DamagePerTick; } private void Changes() { LanguageAPI.Add("KEYWORD_SUPERBLEED", "<style=cKeywordName>Hemorrhage</style><style=cSub>Deal <style=cIsDamage>" + d(DamagePerTick / Interval * TotalDuration + TotalDuration * DamagePerTick) + "</style> base damage over " + TotalDuration + "s. <i>Hemorrhage can stack.</i></style>"); } } public class Reload : MiscBase<Reload> { public static float ReloadDur; public override string Name => ": Primary ::: Reload"; public override void Init() { ReloadDur = ConfigOption(0.3f, "Reload Duration", "Vanilla is 0.3"); base.Init(); } public override void Hooks() { //IL_0008: Unknown result type (might be due to invalid IL or missing references) //IL_0012: Expected O, but got Unknown //IL_001a: Unknown result type (might be due to invalid IL or missing references) //IL_0024: Expected O, but got Unknown EnterReload.OnEnter += new hook_OnEnter(EnterReload_OnEnter); Reload.OnEnter += new hook_OnEnter(Reload_OnEnter); } private void Reload_OnEnter(orig_OnEnter orig, Reload self) { Reload.baseDuration = ReloadDur; orig.Invoke(self); } private void EnterReload_OnEnter(orig_OnEnter orig, EnterReload self) { EnterReload.baseDuration = ReloadDur; orig.Invoke(self); } } }