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<float> SpeedMultiplier;
internal static ConfigEntry<float> CooldownMultiplier;
internal static ConfigEntry<bool> LocalPlayersOnly;
internal static readonly HashSet<Character> Boosted = new HashSet<Character>();
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<float>("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<float>("General", "CooldownMultiplier", 0f, "Multiplier applied to rune skill cooldowns. 0 = no cooldown at all; 0.5 = half; 1 = vanilla.");
LocalPlayersOnly = ((BaseUnityPlugin)this).Config.Bind<bool>("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<Character> list = new List<Character>();
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);
}
}
}