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 SpurRework v1.0.1
SpurRework.dll
Decompiled 23 minutes agousing System; using System.Collections.Generic; using System.Diagnostics; using System.IO; using System.Reflection; using System.Reflection.Emit; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using BepInEx; using BepInEx.Bootstrap; using BepInEx.Configuration; using BepInEx.Logging; using HarmonyLib; using ItemQualities; using ItemQualities.Utilities.Extensions; using KinematicCharacterController; using Microsoft.CodeAnalysis; using R2API; using R2API.Networking; using R2API.Networking.Interfaces; using RiskOfOptions; using RiskOfOptions.OptionConfigs; using RiskOfOptions.Options; using RoR2; using RoR2.Items; 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("SpurRework")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyFileVersion("1.0.1.0")] [assembly: AssemblyInformationalVersion("1.0.1")] [assembly: AssemblyProduct("SpurRework")] [assembly: AssemblyTitle("SpurRework")] [assembly: AssemblyVersion("1.0.1.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 SpurRework { internal static class QualityCompat { [MethodImpl(MethodImplOptions.NoInlining)] private static QualityTier HighestTier(CharacterBody body) { //IL_001a: 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_0022: Unknown result type (might be due to invalid IL or missing references) if (!Object.op_Implicit((Object)(object)body.inventory)) { return (QualityTier)(-1); } ItemQualityCounts itemCountsEffective = InventoryExtensions.GetItemCountsEffective(body.inventory, ItemQualityGroups.JumpDamageStrike); return ((ItemQualityCounts)(ref itemCountsEffective)).HighestQuality; } [MethodImpl(MethodImplOptions.NoInlining)] public static int AirUses(CharacterBody body) { //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_001d: Expected I4, but got Unknown QualityTier val = HighestTier(body); return (int)val switch { 0 => SpurReworkPlugin.UncommonAirUses.Value, 1 => SpurReworkPlugin.RareAirUses.Value, 2 => SpurReworkPlugin.EpicAirUses.Value, 3 => SpurReworkPlugin.LegendaryAirUses.Value, _ => 0, }; } [MethodImpl(MethodImplOptions.NoInlining)] public static void ApplyChargeCost(CharacterBody body, int chargeBefore) { //IL_0012: Unknown result type (might be due to invalid IL or missing references) //IL_0018: Invalid comparison between Unknown and I4 //IL_0033: Unknown result type (might be due to invalid IL or missing references) if (SpurReworkPlugin.OverrideRareChargeCost.Value && chargeBefore >= 25 && (int)HighestTier(body) == 1) { int num = Math.Max(0, chargeBefore - SpurReworkPlugin.RareChargeCost.Value); body.SetBuffCount(Buffs.JumpDamageStrikeCharge.buffIndex, num); } } [MethodImpl(MethodImplOptions.NoInlining)] public static void AddItemText(Dictionary<string, string> tokens) { AddTier(tokens, "UNCOMMON", 75, 150, SpurReworkPlugin.UncommonAirUses.Value); int chargeCost = (SpurReworkPlugin.OverrideRareChargeCost.Value ? SpurReworkPlugin.RareChargeCost.Value : 50); AddTier(tokens, "RARE", chargeCost, 250, SpurReworkPlugin.RareAirUses.Value); AddTier(tokens, "EPIC", 25, 350, SpurReworkPlugin.EpicAirUses.Value); AddTier(tokens, "LEGENDARY", 10, 500, SpurReworkPlugin.LegendaryAirUses.Value); } private static void AddTier(Dictionary<string, string> tokens, string tier, int chargeCost, int damagePerSpeed, int airUses) { bool flag = !SpurReworkPlugin.UsableInAir.Value; tokens["ITEM_JUMPDAMAGESTRIKE_" + tier + "_PICKUP"] = "Moving around builds up movement speed and jump height. At 25% charge or higher, press Interact while holding Jump to discharge into an electric blast that launches you upward.\n<sprite name=\"Quality\"> Increase damage based on movement speed and reduce charge used per blast." + (flag ? $" Use it {airUses} times in the air." : ""); tokens["ITEM_JUMPDAMAGESTRIKE_" + tier + "_DESC"] = SpurReworkPlugin.BonusesText + "At 25% charge or higher, pressing <style=cIsUtility>Interact</style> while holding <style=cIsUtility>Jump</style> launches you upward, " + string.Format("consumes {0} <style=cIsUtility>{1}%</style> charge and triggers an <style=cIsDamage>explosive discharge</style> for ", "<sprite name=\"Quality\">", chargeCost) + "<style=cIsDamage>400% <style=cStack>(+280% per stack)</style> damage</style>, " + string.Format("plus an additional {0} <style=cIsDamage>{1}% <style=cStack>(+{2}% per stack)</style> damage</style> for every <style=cIsUtility>100% movement speed</style>, ", "<sprite name=\"Quality\">", damagePerSpeed, damagePerSpeed) + "in a 17m-32m <style=cStack>(+7.5m per stack)</style> area." + (flag ? string.Format(" Usable on the ground, or {0} <style=cIsUtility>{1} times</style> before landing.", "<sprite name=\"Quality\">", airUses) : ""); } } internal static class RiskOfOptionsCompat { [Serializable] [CompilerGenerated] private sealed class <>c { public static readonly <>c <>9 = new <>c(); public static IsDisabledDelegate <>9__0_0; public static IsDisabledDelegate <>9__3_0; internal bool <Register>b__0_0() { return !SpurReworkPlugin.OverrideRareChargeCost.Value; } internal bool <AddKeyBind>b__3_0() { return !SpurReworkPlugin.UseCustomKeys.Value; } } [MethodImpl(MethodImplOptions.NoInlining)] public static void Register(string pluginLocation) { //IL_00d8: Unknown result type (might be due to invalid IL or missing references) //IL_00e2: Expected O, but got Unknown //IL_0105: Unknown result type (might be due to invalid IL or missing references) //IL_010f: Expected O, but got Unknown //IL_0114: Unknown result type (might be due to invalid IL or missing references) //IL_011e: Expected O, but got Unknown //IL_0175: Unknown result type (might be due to invalid IL or missing references) //IL_017f: Expected O, but got Unknown //IL_0184: Unknown result type (might be due to invalid IL or missing references) //IL_0189: Unknown result type (might be due to invalid IL or missing references) //IL_0190: 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_01c2: Expected O, but got Unknown //IL_01bd: Unknown result type (might be due to invalid IL or missing references) //IL_01c7: Expected O, but got Unknown //IL_01ad: Unknown result type (might be due to invalid IL or missing references) //IL_01b2: Unknown result type (might be due to invalid IL or missing references) //IL_01b8: Expected O, but got Unknown ModSettingsManager.SetModDescription("Reworks Faraday Spur: lower speed and jump bonuses that stack, and the blast fires from pressing Interact while holding Jump."); Sprite val = LoadIcon(pluginLocation); if (Object.op_Implicit((Object)(object)val)) { ModSettingsManager.SetModIcon(val); } AddSlider(SpurReworkPlugin.MoveSpeedBase, 0f, 200f, 5f, "{0:0}%"); AddSlider(SpurReworkPlugin.MoveSpeedPerStack, 0f, 100f, 5f, "{0:0}%"); AddSlider(SpurReworkPlugin.JumpBase, 0f, 200f, 5f, "{0:0}%"); AddSlider(SpurReworkPlugin.JumpPerStack, 0f, 100f, 5f, "{0:0}%"); AddSlider(SpurReworkPlugin.ChargeSpeed, 0.25f, 3f, 0.05f, "{0:0.00}x"); AddSlider(SpurReworkPlugin.LaunchMultiplier, 0f, 3f, 0.05f, "{0:0.00}x"); ModSettingsManager.AddOption((BaseOption)new CheckBoxOption(SpurReworkPlugin.UsableInAir)); AddSlider(SpurReworkPlugin.GroundBuffer, 0f, 1f, 0.05f, "{0:0.00}s"); ModSettingsManager.AddOption((BaseOption)new CheckBoxOption(SpurReworkPlugin.BlockWhenInteractableInView)); ModSettingsManager.AddOption((BaseOption)new CheckBoxOption(SpurReworkPlugin.UseCustomKeys)); AddKeyBind(SpurReworkPlugin.BlastKey); AddKeyBind(SpurReworkPlugin.JumpKey); if (!SpurReworkPlugin.QualityLoaded) { return; } AddIntSlider(SpurReworkPlugin.UncommonAirUses, 1, 10); AddIntSlider(SpurReworkPlugin.RareAirUses, 1, 10); AddIntSlider(SpurReworkPlugin.EpicAirUses, 1, 10); AddIntSlider(SpurReworkPlugin.LegendaryAirUses, 1, 10); ModSettingsManager.AddOption((BaseOption)new CheckBoxOption(SpurReworkPlugin.OverrideRareChargeCost)); ConfigEntry<int> rareChargeCost = SpurReworkPlugin.RareChargeCost; IntSliderConfig val2 = new IntSliderConfig { min = 5, max = 75 }; object obj = <>c.<>9__0_0; if (obj == null) { IsDisabledDelegate val3 = () => !SpurReworkPlugin.OverrideRareChargeCost.Value; <>c.<>9__0_0 = val3; obj = (object)val3; } ((BaseOptionConfig)val2).checkIfDisabled = (IsDisabledDelegate)obj; ModSettingsManager.AddOption((BaseOption)new IntSliderOption(rareChargeCost, val2)); } private static void AddSlider(ConfigEntry<float> entry, float min, float max, float increment, string format) { //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_000d: 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_0028: 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 ModSettingsManager.AddOption((BaseOption)new StepSliderOption(entry, new StepSliderConfig { min = min, max = max, increment = increment, FormatString = format })); } private static void AddIntSlider(ConfigEntry<int> entry, int min, int max) { //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_000d: Unknown result type (might be due to invalid IL or missing references) //IL_0019: Expected O, but got Unknown //IL_0014: Unknown result type (might be due to invalid IL or missing references) //IL_001e: Expected O, but got Unknown ModSettingsManager.AddOption((BaseOption)new IntSliderOption(entry, new IntSliderConfig { min = min, max = max })); } private static void AddKeyBind(ConfigEntry<KeyboardShortcut> entry) { //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_0030: Expected O, but got Unknown //IL_002b: Unknown result type (might be due to invalid IL or missing references) //IL_0035: Expected O, but got Unknown //IL_001b: Unknown result type (might be due to invalid IL or missing references) //IL_0020: Unknown result type (might be due to invalid IL or missing references) //IL_0026: Expected O, but got Unknown KeyBindConfig val = new KeyBindConfig(); object obj = <>c.<>9__3_0; if (obj == null) { IsDisabledDelegate val2 = () => !SpurReworkPlugin.UseCustomKeys.Value; <>c.<>9__3_0 = val2; obj = (object)val2; } ((BaseOptionConfig)val).checkIfDisabled = (IsDisabledDelegate)obj; ModSettingsManager.AddOption((BaseOption)new KeyBindOption(entry, val)); } private static Sprite LoadIcon(string pluginLocation) { //IL_001d: Unknown result type (might be due to invalid IL or missing references) //IL_0023: Expected O, but got Unknown //IL_004c: 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) string path = Path.Combine(Path.GetDirectoryName(pluginLocation), "icon.png"); if (!File.Exists(path)) { return null; } Texture2D val = new Texture2D(2, 2); if (!ImageConversion.LoadImage(val, File.ReadAllBytes(path))) { return null; } return Sprite.Create(val, new Rect(0f, 0f, (float)((Texture)val).width, (float)((Texture)val).height), new Vector2(0.5f, 0.5f)); } } public static class SpurPatches { private class InputState { public bool blastKeyWasDown; public InteractionDriver interactionDriver; public float airTime; public int usesSinceGrounded; public float lastUseTime = float.NegativeInfinity; } private const float LandingGraceTime = 0.1f; private static readonly ConditionalWeakTable<JumpDamageStrikeBodyBehavior, InputState> inputStates = new ConditionalWeakTable<JumpDamageStrikeBodyBehavior, InputState>(); private static bool dischargeAllowed; private static float FullChargeBonus(CharacterBody body, float baseValue, float perStack) { int num = (Object.op_Implicit((Object)(object)body.inventory) ? body.inventory.GetItemCountEffective(Items.JumpDamageStrike) : 0); if (num <= 0) { return 0f; } return (baseValue + perStack * (float)(num - 1)) / 100f; } public static float MoveSpeedPerCharge(CharacterBody body) { return FullChargeBonus(body, SpurReworkPlugin.MoveSpeedBase.Value, SpurReworkPlugin.MoveSpeedPerStack.Value) / 100f; } public static float JumpPowerPerCharge(CharacterBody body) { return FullChargeBonus(body, SpurReworkPlugin.JumpBase.Value, SpurReworkPlugin.JumpPerStack.Value) / 100f; } [HarmonyPatch(typeof(CharacterBody), "RecalculateStats")] [HarmonyTranspiler] private static IEnumerable<CodeInstruction> RecalculateStatsTranspiler(IEnumerable<CodeInstruction> instructions) { FieldInfo moveField = AccessTools.Field(typeof(JumpDamageStrikeBodyBehavior), "MoveSpeedVelocityPerCharge"); FieldInfo jumpField = AccessTools.Field(typeof(JumpDamageStrikeBodyBehavior), "JumpVelocityPerCharge"); MethodInfo moveMethod = AccessTools.Method(typeof(SpurPatches), "MoveSpeedPerCharge", (Type[])null, (Type[])null); MethodInfo jumpMethod = AccessTools.Method(typeof(SpurPatches), "JumpPowerPerCharge", (Type[])null, (Type[])null); bool movePatched = false; bool jumpPatched = false; foreach (CodeInstruction instruction in instructions) { MethodInfo replacement = null; if (CodeInstructionExtensions.LoadsField(instruction, moveField, false)) { replacement = moveMethod; movePatched = true; } else if (CodeInstructionExtensions.LoadsField(instruction, jumpField, false)) { replacement = jumpMethod; jumpPatched = true; } if (replacement == null) { yield return instruction; continue; } yield return CodeInstructionExtensions.MoveBlocksFrom(CodeInstructionExtensions.MoveLabelsFrom(new CodeInstruction(OpCodes.Ldarg_0, (object)null), instruction), instruction); yield return new CodeInstruction(OpCodes.Call, (object)replacement); } if (!movePatched || !jumpPatched) { SpurReworkPlugin.Log.LogError((object)$"RecalculateStats patch incomplete (move speed: {movePatched}, jump: {jumpPatched}). A game update probably changed the Spur code."); } } [HarmonyPatch(typeof(JumpDamageStrikeBodyBehavior), "FixedUpdate")] [HarmonyTranspiler] private static IEnumerable<CodeInstruction> FixedUpdateTranspiler(IEnumerable<CodeInstruction> instructions) { MethodInfo positionGetter = AccessTools.PropertyGetter(typeof(Transform), "position"); MethodInfo replacement = AccessTools.Method(typeof(SpurPatches), "SimulatedPosition", (Type[])null, (Type[])null); bool patched = false; foreach (CodeInstruction instruction in instructions) { if (!patched && CodeInstructionExtensions.Calls(instruction, positionGetter)) { instruction.opcode = OpCodes.Call; instruction.operand = replacement; patched = true; } yield return instruction; } if (!patched) { SpurReworkPlugin.Log.LogError((object)"Charge rate fix not applied. A game update probably changed the Spur code."); } } public static Vector3 SimulatedPosition(Transform transform) { //IL_0017: Unknown result type (might be due to invalid IL or missing references) //IL_0010: Unknown result type (might be due to invalid IL or missing references) KinematicCharacterMotor component = ((Component)transform).GetComponent<KinematicCharacterMotor>(); if (!Object.op_Implicit((Object)(object)component)) { return transform.position; } return component.TransientPosition; } [HarmonyPatch(typeof(JumpDamageStrikeBodyBehavior), "UpdateCharge")] [HarmonyTranspiler] private static IEnumerable<CodeInstruction> UpdateChargeTranspiler(IEnumerable<CodeInstruction> instructions) { MethodInfo moveSpeedGetter = AccessTools.PropertyGetter(typeof(CharacterBody), "moveSpeed"); MethodInfo scale = AccessTools.Method(typeof(SpurPatches), "ScaleChargeGain", (Type[])null, (Type[])null); bool patched = false; foreach (CodeInstruction instruction in instructions) { yield return instruction; if (!patched && CodeInstructionExtensions.Calls(instruction, moveSpeedGetter)) { yield return new CodeInstruction(OpCodes.Call, (object)scale); patched = true; } } if (!patched) { SpurReworkPlugin.Log.LogError((object)"Charge speed patch not applied. A game update probably changed the Spur code."); } } public static float ScaleChargeGain(float moveSpeed) { return moveSpeed * SpurReworkPlugin.ChargeSpeed.Value; } [HarmonyPatch(typeof(JumpDamageStrikeBodyBehavior), "DischargeEffects")] [HarmonyPrefix] private static bool DischargeEffectsPrefix() { return dischargeAllowed; } [HarmonyPatch(typeof(JumpDamageStrikeBodyBehavior), "FixedUpdate")] [HarmonyPostfix] private static void FixedUpdatePostfix(JumpDamageStrikeBodyBehavior __instance) { //IL_0059: 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_0062: Unknown result type (might be due to invalid IL or missing references) //IL_008c: 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_0095: Unknown result type (might be due to invalid IL or missing references) //IL_01c6: Unknown result type (might be due to invalid IL or missing references) CharacterBody component = ((Component)__instance).GetComponent<CharacterBody>(); if (!Object.op_Implicit((Object)(object)component) || !component.hasEffectiveAuthority || !Object.op_Implicit((Object)(object)component.inputBank)) { return; } bool value = SpurReworkPlugin.UseCustomKeys.Value; int num; int num2; if (value) { num = (LocalPlayerHasControl(component) ? 1 : 0); if (num == 0) { num2 = 0; goto IL_006f; } } else { num = 1; } KeyboardShortcut value2; if (!value) { num2 = (component.inputBank.interact.down ? 1 : 0); } else { value2 = SpurReworkPlugin.BlastKey.Value; num2 = (Input.GetKey(((KeyboardShortcut)(ref value2)).MainKey) ? 1 : 0); } goto IL_006f; IL_006f: bool flag = (byte)num2 != 0; int num3; if (num != 0) { if (!value) { num3 = (component.inputBank.jump.down ? 1 : 0); } else { value2 = SpurReworkPlugin.JumpKey.Value; num3 = (Input.GetKey(((KeyboardShortcut)(ref value2)).MainKey) ? 1 : 0); } } else { num3 = 0; } bool flag2 = (byte)num3 != 0; InputState orCreateValue = inputStates.GetOrCreateValue(__instance); bool flag3 = !Object.op_Implicit((Object)(object)component.characterMotor) || component.characterMotor.isGrounded; if (flag3) { orCreateValue.airTime = 0f; if (Time.fixedTime - orCreateValue.lastUseTime > 0.1f) { orCreateValue.usesSinceGrounded = 0; } } else { orCreateValue.airTime += Time.fixedDeltaTime; } bool num4 = flag && !orCreateValue.blastKeyWasDown; orCreateValue.blastKeyWasDown = flag; if (!num4 || !flag2 || component.GetBuffCount(Buffs.JumpDamageStrikeCharge) < 25 || (!flag3 && !CanUseInAir(component, orCreateValue))) { return; } if (!value && SpurReworkPlugin.BlockWhenInteractableInView.Value) { if (!Object.op_Implicit((Object)(object)orCreateValue.interactionDriver)) { orCreateValue.interactionDriver = ((Component)component).GetComponent<InteractionDriver>(); } if (Object.op_Implicit((Object)(object)orCreateValue.interactionDriver) && Object.op_Implicit((Object)(object)orCreateValue.interactionDriver.currentInteractable)) { return; } } orCreateValue.usesSinceGrounded++; orCreateValue.lastUseTime = Time.fixedTime; LaunchUpward(component); if (NetworkServer.active) { Discharge(__instance); } else { NetMessageExtensions.Send((INetMessage)(object)new RequestDischargeMessage(((NetworkBehaviour)component).netId), (NetworkDestination)2); } } private static bool CanUseInAir(CharacterBody body, InputState state) { if (SpurReworkPlugin.UsableInAir.Value) { return true; } int num = (SpurReworkPlugin.QualityLoaded ? QualityCompat.AirUses(body) : 0); if (num <= 0) { if (state.usesSinceGrounded == 0) { return state.airTime <= SpurReworkPlugin.GroundBuffer.Value; } return false; } return state.usesSinceGrounded < num; } private static bool LocalPlayerHasControl(CharacterBody body) { CharacterMaster master = body.master; PlayerCharacterMasterController val = (Object.op_Implicit((Object)(object)master) ? master.playerCharacterMasterController : null); NetworkUser val2 = (Object.op_Implicit((Object)(object)val) ? val.networkUser : null); LocalUser val3 = (Object.op_Implicit((Object)(object)val2) ? val2.localUser : null); if (val3 != null && !val3.isUIFocused && Object.op_Implicit((Object)(object)val2.cameraRigController)) { return val2.cameraRigController.isControlAllowed; } return false; } private static void LaunchUpward(CharacterBody body) { //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) //IL_002c: 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_004d: Unknown result type (might be due to invalid IL or missing references) CharacterMotor characterMotor = body.characterMotor; float value = SpurReworkPlugin.LaunchMultiplier.Value; if (Object.op_Implicit((Object)(object)characterMotor) && !(value <= 0f)) { Vector3 velocity = characterMotor.velocity; velocity.y = Mathf.Max(velocity.y, body.jumpPower * value * characterMotor.jumpPowerPenaltyCoefficient); characterMotor.velocity = velocity; ((BaseCharacterController)characterMotor).Motor.ForceUnground(0.1f); } } public static void Discharge(JumpDamageStrikeBodyBehavior behavior) { CharacterBody component = ((Component)behavior).GetComponent<CharacterBody>(); int buffCount = component.GetBuffCount(Buffs.JumpDamageStrikeCharge); dischargeAllowed = true; try { behavior.DischargeEffects(); if (SpurReworkPlugin.QualityLoaded) { QualityCompat.ApplyChargeCost(component, buffCount); } } finally { dischargeAllowed = false; } } } public class RequestDischargeMessage : INetMessage, ISerializableObject { private NetworkInstanceId bodyId; public RequestDischargeMessage() { } public RequestDischargeMessage(NetworkInstanceId bodyId) { //IL_0007: 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) this.bodyId = bodyId; } public void Serialize(NetworkWriter writer) { //IL_0002: Unknown result type (might be due to invalid IL or missing references) writer.Write(bodyId); } public void Deserialize(NetworkReader reader) { //IL_0002: 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) bodyId = reader.ReadNetworkId(); } public void OnReceived() { //IL_000b: Unknown result type (might be due to invalid IL or missing references) GameObject val = (NetworkServer.active ? NetworkServer.FindLocalObject(bodyId) : null); JumpDamageStrikeBodyBehavior val2 = (Object.op_Implicit((Object)(object)val) ? val.GetComponent<JumpDamageStrikeBodyBehavior>() : null); if (Object.op_Implicit((Object)(object)val2)) { SpurPatches.Discharge(val2); } } } [BepInPlugin("com.spurrework.faradayspur", "Spur Rework", "1.0.1")] [BepInDependency(/*Could not decode attribute arguments.*/)] [BepInDependency(/*Could not decode attribute arguments.*/)] [BepInDependency(/*Could not decode attribute arguments.*/)] [BepInDependency(/*Could not decode attribute arguments.*/)] public class SpurReworkPlugin : BaseUnityPlugin { public const string PluginGuid = "com.spurrework.faradayspur"; public const string PluginName = "Spur Rework"; private const string RiskOfOptionsGuid = "com.rune580.riskofoptions"; private const string QualityGuid = "com.Gorakh.ItemQualities"; public const string BasePickupText = "Moving around builds up movement speed and jump height. At 25% charge or higher, press Interact while holding Jump to discharge into an electric blast that launches you upward."; public static ManualLogSource Log; public static ConfigEntry<float> MoveSpeedBase; public static ConfigEntry<float> MoveSpeedPerStack; public static ConfigEntry<float> JumpBase; public static ConfigEntry<float> JumpPerStack; public static ConfigEntry<float> LaunchMultiplier; public static ConfigEntry<float> ChargeSpeed; public static ConfigEntry<bool> UsableInAir; public static ConfigEntry<float> GroundBuffer; public static ConfigEntry<int> UncommonAirUses; public static ConfigEntry<int> RareAirUses; public static ConfigEntry<int> EpicAirUses; public static ConfigEntry<int> LegendaryAirUses; public static ConfigEntry<bool> OverrideRareChargeCost; public static ConfigEntry<int> RareChargeCost; public static ConfigEntry<bool> BlockWhenInteractableInView; public static ConfigEntry<bool> UseCustomKeys; public static ConfigEntry<KeyboardShortcut> BlastKey; public static ConfigEntry<KeyboardShortcut> JumpKey; private LanguageOverlay descriptionOverlay; public static bool QualityLoaded { get; private set; } public static string BonusesText => "Moving around builds up <style=cIsUtility>charge</style>, granting up to " + $"<style=cIsUtility>+{MoveSpeedBase.Value:0.##}% <style=cStack>(+{MoveSpeedPerStack.Value:0.##}% per stack)</style> movement speed</style> and " + $"<style=cIsUtility>+{JumpBase.Value:0.##}% <style=cStack>(+{JumpPerStack.Value:0.##}% per stack)</style> jump height</style> at 100%. "; private void Awake() { //IL_0192: Unknown result type (might be due to invalid IL or missing references) //IL_01bd: Unknown result type (might be due to invalid IL or missing references) //IL_02a7: Unknown result type (might be due to invalid IL or missing references) Log = ((BaseUnityPlugin)this).Logger; QualityLoaded = Chainloader.PluginInfos.ContainsKey("com.Gorakh.ItemQualities"); MoveSpeedBase = ((BaseUnityPlugin)this).Config.Bind<float>("Stats", "Move Speed", 40f, "Percent move speed at 100% charge with one stack."); MoveSpeedPerStack = ((BaseUnityPlugin)this).Config.Bind<float>("Stats", "Move Speed Per Stack", 25f, "Extra percent move speed at 100% charge per additional stack."); JumpBase = ((BaseUnityPlugin)this).Config.Bind<float>("Stats", "Jump Height", 30f, "Percent jump power at 100% charge with one stack, the same stat as vanilla's +200%. Height grows with the square of power, so +30% is about +69% height."); JumpPerStack = ((BaseUnityPlugin)this).Config.Bind<float>("Stats", "Jump Height Per Stack", 15f, "Extra percent jump power at 100% charge per additional stack."); ChargeSpeed = ((BaseUnityPlugin)this).Config.Bind<float>("Stats", "Charge Speed", 1.5f, "How fast charge builds, as a multiple of vanilla. 1.5 is 50% faster."); LaunchMultiplier = ((BaseUnityPlugin)this).Config.Bind<float>("Blast", "Launch Multiplier", 1.75f, "Upward launch from the blast, as a multiple of your normal jump speed at that charge. 0 turns the launch off."); UsableInAir = ((BaseUnityPlugin)this).Config.Bind<bool>("Blast", "Usable On Ground And In Air", false, "On: the blast works any time, with no limit on uses in the air. Off: it only works on the ground or just after leaving it, plus any Quality air uses."); GroundBuffer = ((BaseUnityPlugin)this).Config.Bind<float>("Blast", "Ground Buffer", 0.3f, "Seconds after leaving the ground that the blast still counts as used from the ground, so it works right after a jump."); BlockWhenInteractableInView = ((BaseUnityPlugin)this).Config.Bind<bool>("Blast", "Block When Interactable In View", true, "Pressing Interact while looking at a chest, shrine, etc. uses that object and does not fire the blast."); UseCustomKeys = ((BaseUnityPlugin)this).Config.Bind<bool>("Keys", "Use Custom Keys", false, "Off: the blast uses the game's own Interact and Jump controls, including controllers. On: it uses the two keys below."); BlastKey = ((BaseUnityPlugin)this).Config.Bind<KeyboardShortcut>("Keys", "Blast Key", new KeyboardShortcut((KeyCode)101, Array.Empty<KeyCode>()), "Press this while holding the Hold Key to fire the blast. Only used with Use Custom Keys on."); JumpKey = ((BaseUnityPlugin)this).Config.Bind<KeyboardShortcut>("Keys", "Hold Key", new KeyboardShortcut((KeyCode)32, Array.Empty<KeyCode>()), "Hold this while pressing the Blast Key. Only used with Use Custom Keys on."); if (QualityLoaded) { UncommonAirUses = ((BaseUnityPlugin)this).Config.Bind<int>("Quality", "Uncommon Air Uses", 2, "Blasts per trip through the air with an Uncommon Spur. Each one still needs 25% charge."); RareAirUses = ((BaseUnityPlugin)this).Config.Bind<int>("Quality", "Rare Air Uses", 3, "Blasts per trip through the air with a Rare Spur. Each one still needs 25% charge, so 3 needs Override Rare Charge Cost on."); EpicAirUses = ((BaseUnityPlugin)this).Config.Bind<int>("Quality", "Epic Air Uses", 4, "Blasts per trip through the air with an Epic Spur. Each one still needs 25% charge."); LegendaryAirUses = ((BaseUnityPlugin)this).Config.Bind<int>("Quality", "Legendary Air Uses", 8, "Blasts per trip through the air with a Legendary Spur. Each one still needs 25% charge."); OverrideRareChargeCost = ((BaseUnityPlugin)this).Config.Bind<bool>("Quality", "Override Rare Charge Cost", true, "On: a Rare Spur spends Rare Charge Cost per blast. Off: it spends Quality's own 50%, which only allows 2 blasts from a full bar."); RareChargeCost = ((BaseUnityPlugin)this).Config.Bind<int>("Quality", "Rare Charge Cost", 35, "Percent charge a Rare Spur spends per blast. Only used with Override Rare Charge Cost on."); } NetworkingAPI.RegisterMessageType<RequestDischargeMessage>(); new Harmony("com.spurrework.faradayspur").PatchAll(typeof(SpurPatches)); OverrideItemText(); ((BaseUnityPlugin)this).Config.SettingChanged += delegate { ApplySettingChange(); }; if (Chainloader.PluginInfos.ContainsKey("com.rune580.riskofoptions")) { RiskOfOptionsCompat.Register(((BaseUnityPlugin)this).Info.Location); } } private void ApplySettingChange() { OverrideItemText(); foreach (CharacterBody readOnlyInstances in CharacterBody.readOnlyInstancesList) { if (readOnlyInstances.HasBuff(Buffs.JumpDamageStrikeCharge)) { readOnlyInstances.MarkAllStatsDirty(); } } } private void OverrideItemText() { LanguageOverlay obj = descriptionOverlay; if (obj != null) { obj.Remove(); } Dictionary<string, string> dictionary = new Dictionary<string, string> { ["ITEM_JUMPDAMAGESTRIKE_PICKUP"] = "Moving around builds up movement speed and jump height. At 25% charge or higher, press Interact while holding Jump to discharge into an electric blast that launches you upward.", ["ITEM_JUMPDAMAGESTRIKE_DESC"] = BonusesText + "At 25% charge or higher, pressing <style=cIsUtility>Interact</style> while holding <style=cIsUtility>Jump</style> launches you upward and triggers an <style=cIsDamage>explosive discharge</style> for <style=cIsDamage>400% <style=cStack>(+280% per stack)</style> damage</style> in a 17m-32m <style=cStack>(+7.5m per stack)</style> area." + (UsableInAir.Value ? "" : " Usable on the ground or right after leaving it.") }; if (QualityLoaded) { QualityCompat.AddItemText(dictionary); } descriptionOverlay = LanguageAPI.AddOverlay(dictionary); } } }