using System; using System.Collections.Generic; using System.Reflection; using System.Runtime.CompilerServices; using BepInEx; using BepInEx.Configuration; using BepInEx.Logging; using HarmonyLib; using UnityEngine; [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: AssemblyVersion("0.0.0.0")] namespace SwiftScribe; [BepInPlugin("com.spencer4792.swiftscribe", "SwiftScribe", "1.0.0")] public class SwiftScribePlugin : BaseUnityPlugin { public const string GUID = "com.spencer4792.swiftscribe"; public const string NAME = "SwiftScribe"; public const string VERSION = "1.0.0"; internal static ManualLogSource Log; internal static ConfigEntry SpeedMultiplier; internal static ConfigEntry CooldownMultiplier; internal static ConfigEntry LocalPlayersOnly; internal static readonly HashSet Boosted = new HashSet(); private static readonly PropertyInfo s_animatorProp = typeof(Character).GetProperty("Animator"); private static PropertyInfo s_speedProp; internal static void SetSpeed(Character c, float speed) { try { object obj = ((!(s_animatorProp != null)) ? null : s_animatorProp.GetValue(c, null)); if (obj != null) { if (s_speedProp == null) { s_speedProp = obj.GetType().GetProperty("speed"); } if (s_speedProp != null) { s_speedProp.SetValue(obj, speed, null); } } } catch (Exception ex) { Log.LogWarning((object)("SetSpeed: " + ex.Message)); } } private void Awake() { //IL_0078: Unknown result type (might be due to invalid IL or missing references) Log = ((BaseUnityPlugin)this).Logger; SpeedMultiplier = ((BaseUnityPlugin)this).Config.Bind("General", "SpeedMultiplier", 2f, "Animator speed while writing a rune. 1 = vanilla look; 2 = snappy but natural (default); 30 = instant flick."); CooldownMultiplier = ((BaseUnityPlugin)this).Config.Bind("General", "CooldownMultiplier", 0f, "Multiplier applied to rune skill cooldowns. 0 = no cooldown at all; 0.5 = half; 1 = vanilla."); LocalPlayersOnly = ((BaseUnityPlugin)this).Config.Bind("General", "LocalPlayersOnly", true, "Only accelerate local player characters (recommended)."); new Harmony("com.spencer4792.swiftscribe").PatchAll(); Log.LogMessage((object)("SwiftScribe 1.0.0 ready. Rune cast speed x" + SpeedMultiplier.Value + ".")); } private void Update() { if (Boosted.Count == 0) { return; } List list = new List(); foreach (Character item in Boosted) { if ((Object)(object)item == (Object)null || !item.IsCasting) { list.Add(item); } else { SetSpeed(item, Mathf.Max(1f, SpeedMultiplier.Value)); } } foreach (Character item2 in list) { RestoreSpeed(item2); } } internal static void BoostSpeed(Character c) { SetSpeed(c, Mathf.Max(1f, SpeedMultiplier.Value)); Boosted.Add(c); } internal static void RestoreSpeed(Character c) { if ((Object)(object)c != (Object)null) { SetSpeed(c, 1f); } Boosted.Remove(c); } } [HarmonyPatch(typeof(Character), "SpellCastAnim")] internal static class SpellCastAnimPatch { private static void Postfix(Character __instance, SpellCastType __0) { //IL_001f: Unknown result type (might be due to invalid IL or missing references) //IL_0022: Invalid comparison between Unknown and I4 try { if ((!SwiftScribePlugin.LocalPlayersOnly.Value || __instance.IsLocalPlayer) && (int)__0 == 44) { SwiftScribePlugin.Log.LogMessage((object)("Boosting rune cast for '" + __instance.Name + "' (x" + SwiftScribePlugin.SpeedMultiplier.Value + ").")); SwiftScribePlugin.BoostSpeed(__instance); } } catch (Exception ex) { SwiftScribePlugin.Log.LogWarning((object)("SpellCastAnim patch: " + ex.Message)); } } } [HarmonyPatch(typeof(Character), "CastDone")] internal static class CastDonePatch { private static void Postfix(Character __instance) { if (SwiftScribePlugin.Boosted.Contains(__instance)) { SwiftScribePlugin.RestoreSpeed(__instance); } } } [HarmonyPatch(typeof(Skill), "StartCooldown")] internal static class StartCooldownPatch { private static readonly FieldInfo s_animTypeField = typeof(Item).GetField("m_activateEffectAnimType", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); private static readonly FieldInfo s_remainingField = typeof(Skill).GetField("m_remainingCooldownTime", BindingFlags.Instance | BindingFlags.NonPublic); private static void Postfix(Skill __instance) { try { if ((SwiftScribePlugin.LocalPlayersOnly.Value && ((Object)(object)((EffectSynchronizer)__instance).OwnerCharacter == (Object)null || !((EffectSynchronizer)__instance).OwnerCharacter.IsLocalPlayer)) || s_animTypeField == null) { return; } object value = s_animTypeField.GetValue(__instance); if (value != null && Convert.ToInt32(value) == 44) { float num = Mathf.Clamp(SwiftScribePlugin.CooldownMultiplier.Value, 0f, 1f); if (num <= 0f) { __instance.ResetCoolDown(); } else if (s_remainingField != null) { float num2 = (float)s_remainingField.GetValue(__instance); s_remainingField.SetValue(__instance, num2 * num); } } } catch (Exception ex) { SwiftScribePlugin.Log.LogWarning((object)("StartCooldown patch: " + ex.Message)); } } } [HarmonyPatch(typeof(Character), "InterruptCast")] internal static class InterruptCastPatch { private static void Postfix(Character __instance) { if (SwiftScribePlugin.Boosted.Contains(__instance)) { SwiftScribePlugin.RestoreSpeed(__instance); } } }