using System; using System.Collections.Generic; using System.Diagnostics; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using System.Security; using System.Security.Permissions; using BepInEx; using BepInEx.Bootstrap; using BepInEx.Configuration; using Microsoft.CodeAnalysis; using On.RoR2; using RiskOfOptions; using RiskOfOptions.OptionConfigs; using RiskOfOptions.Options; using RoR2; using UnityEngine; 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("OneShotOneKill")] [assembly: AssemblyConfiguration("Debug")] [assembly: AssemblyFileVersion("1.0.0.0")] [assembly: AssemblyInformationalVersion("1.0.0")] [assembly: AssemblyProduct("OneShotOneKill")] [assembly: AssemblyTitle("OneShotOneKill")] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("1.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 OneShotOneKill { [BepInPlugin("com.yourname.oneshotonekill", "One Shot, One Kill", "1.0.0")] [BepInDependency(/*Could not decode attribute arguments.*/)] public class OneShotOneKillPlugin : BaseUnityPlugin { public const string PluginGUID = "com.yourname.oneshotonekill"; public const string PluginName = "One Shot, One Kill"; public const string PluginVersion = "1.0.0"; public static ConfigEntry ModEnabled; public static ConfigEntry GracePeriodSeconds; public static ConfigEntry NoKillCooldownSeconds; public static ConfigEntry AttributionWindowSeconds; private static readonly Dictionary lockStartTime = new Dictionary(); private static readonly List scratchKeys = new List(); private void Awake() { //IL_00b0: Unknown result type (might be due to invalid IL or missing references) //IL_00ba: Expected O, but got Unknown //IL_00c2: Unknown result type (might be due to invalid IL or missing references) //IL_00cc: Expected O, but got Unknown //IL_00d4: Unknown result type (might be due to invalid IL or missing references) //IL_00de: Expected O, but got Unknown //IL_00e6: Unknown result type (might be due to invalid IL or missing references) //IL_00f0: Expected O, but got Unknown ModEnabled = ((BaseUnityPlugin)this).Config.Bind("General", "Enabled", true, "Master on/off switch for One Shot, One Kill."); GracePeriodSeconds = ((BaseUnityPlugin)this).Config.Bind("General", "Initial Grace Period (seconds)", 300f, "How many seconds after the run/stage timer starts before the kill-to-reset rule kicks in. Default 300 = 5 minutes."); NoKillCooldownSeconds = ((BaseUnityPlugin)this).Config.Bind("General", "No-Kill Cooldown (seconds)", 99f, "If a locked skill does NOT get a kill, this is how long it takes to come back on its own."); AttributionWindowSeconds = ((BaseUnityPlugin)this).Config.Bind("General", "Kill Attribution Window (seconds)", 3f, "How many seconds after firing a skill a kill can still be credited to it. Increase this for slow projectiles/DoTs, decrease it if kills feel like they're crediting the wrong skill."); if (Chainloader.PluginInfos.ContainsKey("com.rune580.riskofoptions")) { SetupRiskOfOptions(); } GenericSkill.CanExecute += new hook_CanExecute(GenericSkill_CanExecute); GenericSkill.OnExecute += new hook_OnExecute(GenericSkill_OnExecute); GlobalEventManager.OnCharacterDeath += new hook_OnCharacterDeath(GlobalEventManager_OnCharacterDeath); Run.OnDestroy += new hook_OnDestroy(Run_OnDestroy); ((BaseUnityPlugin)this).Logger.LogInfo((object)"One Shot, One Kill loaded."); } private void OnDestroy() { //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_002c: Unknown result type (might be due to invalid IL or missing references) //IL_0036: Expected O, but got Unknown //IL_003e: Unknown result type (might be due to invalid IL or missing references) //IL_0048: Expected O, but got Unknown GenericSkill.CanExecute -= new hook_CanExecute(GenericSkill_CanExecute); GenericSkill.OnExecute -= new hook_OnExecute(GenericSkill_OnExecute); GlobalEventManager.OnCharacterDeath -= new hook_OnCharacterDeath(GlobalEventManager_OnCharacterDeath); Run.OnDestroy -= new hook_OnDestroy(Run_OnDestroy); lockStartTime.Clear(); } private void SetupRiskOfOptions() { //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_0016: Unknown result type (might be due to invalid IL or missing references) //IL_0021: Unknown result type (might be due to invalid IL or missing references) //IL_0031: Expected O, but got Unknown //IL_002c: Unknown result type (might be due to invalid IL or missing references) //IL_0036: Expected O, but got Unknown //IL_003c: 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_004c: 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_0067: Expected O, but got Unknown //IL_0062: Unknown result type (might be due to invalid IL or missing references) //IL_006c: Expected O, but got Unknown //IL_0072: Unknown result type (might be due to invalid IL or missing references) //IL_0077: Unknown result type (might be due to invalid IL or missing references) //IL_0082: Unknown result type (might be due to invalid IL or missing references) //IL_008d: Unknown result type (might be due to invalid IL or missing references) //IL_009d: Expected O, but got Unknown //IL_0098: Unknown result type (might be due to invalid IL or missing references) //IL_00a2: Expected O, but got Unknown ModSettingsManager.AddOption((BaseOption)new StepSliderOption(GracePeriodSeconds, new StepSliderConfig { min = 0f, max = 900f, increment = 15f })); ModSettingsManager.AddOption((BaseOption)new StepSliderOption(NoKillCooldownSeconds, new StepSliderConfig { min = 5f, max = 300f, increment = 1f })); ModSettingsManager.AddOption((BaseOption)new StepSliderOption(AttributionWindowSeconds, new StepSliderConfig { min = 0.5f, max = 10f, increment = 0.5f })); } private bool GenericSkill_CanExecute(orig_CanExecute orig, GenericSkill self) { if (!orig.Invoke(self)) { return false; } if (!ModEnabled.Value || (Object)(object)self == (Object)null) { return true; } if (lockStartTime.TryGetValue(self, out var value) && Time.time - value < NoKillCooldownSeconds.Value) { return false; } return true; } private void GenericSkill_OnExecute(orig_OnExecute orig, GenericSkill self) { orig.Invoke(self); if (!NetworkServer.active || !ModEnabled.Value || (Object)(object)self == (Object)null) { return; } CharacterBody characterBody = self.characterBody; if (!((Object)(object)characterBody == (Object)null) && characterBody.isPlayerControlled && !((Object)(object)Run.instance == (Object)null) && !(Run.instance.GetRunStopwatch() < GracePeriodSeconds.Value)) { SkillLocator skillLocator = characterBody.skillLocator; if (!((Object)(object)skillLocator == (Object)null) && !((Object)(object)self == (Object)(object)skillLocator.utility) && ((Object)(object)self == (Object)(object)skillLocator.primary || (Object)(object)self == (Object)(object)skillLocator.secondary || (Object)(object)self == (Object)(object)skillLocator.special)) { lockStartTime[self] = Time.time; } } } private void GlobalEventManager_OnCharacterDeath(orig_OnCharacterDeath orig, GlobalEventManager self, DamageReport damageReport) { orig.Invoke(self, damageReport); if (!NetworkServer.active || !ModEnabled.Value) { return; } CharacterBody attackerBody = damageReport.attackerBody; if ((Object)(object)attackerBody == (Object)null || !attackerBody.isPlayerControlled) { return; } SkillLocator skillLocator = attackerBody.skillLocator; if (!((Object)(object)skillLocator == (Object)null)) { GenericSkill best = null; float bestTime = float.NegativeInfinity; TryConsiderForCredit(skillLocator.primary, ref best, ref bestTime); TryConsiderForCredit(skillLocator.secondary, ref best, ref bestTime); TryConsiderForCredit(skillLocator.special, ref best, ref bestTime); if ((Object)(object)best != (Object)null) { UnlockAndRestock(best); } } } private static void TryConsiderForCredit(GenericSkill skill, ref GenericSkill best, ref float bestTime) { if (!((Object)(object)skill == (Object)null) && lockStartTime.TryGetValue(skill, out var value) && Time.time - value <= AttributionWindowSeconds.Value && value > bestTime) { best = skill; bestTime = value; } } private static void UnlockAndRestock(GenericSkill skill) { lockStartTime.Remove(skill); skill.stock = skill.maxStock; skill.rechargeStopwatch = 0f; } private void Run_OnDestroy(orig_OnDestroy orig, Run self) { orig.Invoke(self); lockStartTime.Clear(); } private void FixedUpdate() { if (!NetworkServer.active || !ModEnabled.Value || lockStartTime.Count == 0) { return; } scratchKeys.Clear(); scratchKeys.AddRange(lockStartTime.Keys); for (int i = 0; i < scratchKeys.Count; i++) { GenericSkill val = scratchKeys[i]; if ((Object)(object)val == (Object)null) { lockStartTime.Remove(val); continue; } float num = lockStartTime[val]; float num2 = Time.time - num; if (num2 >= NoKillCooldownSeconds.Value) { UnlockAndRestock(val); continue; } val.stock = 0; val.rechargeStopwatch = 0f; } } } }