using System; using System.Collections; using System.Collections.Generic; using System.Diagnostics; using System.IO; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using BepInEx; using BlackMagicAPI.Managers; using BlackMagicAPI.Modules.Spells; using BlackMagicAPI.Network; using FishNet; using FishNet.Connection; using FishNet.Object; using UnityEngine; using UnityEngine.Networking; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: TargetFramework(".NETFramework,Version=v4.8", FrameworkDisplayName = ".NET Framework 4.8")] [assembly: AssemblyCompany("SpeedSpell")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyFileVersion("1.0.0.0")] [assembly: AssemblyInformationalVersion("1.0.0")] [assembly: AssemblyProduct("SpeedSpell")] [assembly: AssemblyTitle("SpeedSpell")] [assembly: AssemblyVersion("1.0.0.0")] namespace SpeedSpell; [BepInPlugin("com.thewargod_ares.speedspell", "SpeedSpell", "1.0.0")] [BepInDependency(/*Could not decode attribute arguments.*/)] [BepInDependency(/*Could not decode attribute arguments.*/)] public class Plugin : BaseUnityPlugin { public const string GUID = "com.thewargod_ares.speedspell"; public const string NAME = "SpeedSpell"; public const string VERSION = "1.0.0"; public static string modsync = "all"; private void Awake() { BlackMagicManager.RegisterSpell((BaseUnityPlugin)(object)this, typeof(SpeedData), typeof(SpeedLogic)); ((BaseUnityPlugin)this).Logger.LogInfo((object)"Speed spell loaded."); } } public class SpeedData : SpellData { public override string Name => "Speed"; public override float Cooldown => 30f; public override Color GlowColor => new Color(1f, 0.85f, 0f); public override string[] SubNames => new string[6] { "Speed Up", "Swiftness", "Haste", "Sprint", "Swift", "Go Fast" }; public override bool CanSpawnInTeamChest => false; public override bool DebugForceSpawn => false; } public class SpeedLogic : SpellLogic { private const float BOOST_MULTIPLIER = 2.5f; private const float DURATION = 15f; private static readonly string[] SPEED_FIELD_NAMES = new string[8] { "walkingSpeed", "runningSpeed", "movespeed", "moveSpeed", "MoveSpeed", "speed", "baseSpeed", "currentSpeed" }; private static readonly string[] BONUS_FIELD_NAMES = new string[3] { "stewspeedboost", "pixiedustspeedmult", "currentSpeedMultiplier" }; private const float BONUS_VALUE = 15f; public override bool CastSpell(PlayerMovement caster, PageController page, Vector3 spawnPos, Vector3 viewDirectionVector, int castingLevel) { Debug.Log((object)"[SpeedSpell] CastSpell fired — boost will apply via SyncData."); return true; } public override void WriteData(DataWriter writer, PageController page, PlayerMovement caster, Vector3 spawnPos, Vector3 viewDirectionVector, int level) { //IL_0013: Unknown result type (might be due to invalid IL or missing references) //IL_0009: 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_001a: Unknown result type (might be due to invalid IL or missing references) //IL_0026: 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) Vector3 val = (((Object)(object)caster != (Object)null) ? ((Component)caster).transform.position : spawnPos); writer.Write(val.x); writer.Write(val.y); writer.Write(val.z); } public override void SyncData(object[] values) { //IL_0034: Unknown result type (might be due to invalid IL or missing references) //IL_004f: Unknown result type (might be due to invalid IL or missing references) if (((SpellLogic)this).IsPrefab) { return; } Debug.Log((object)"[SpeedSpell] SyncData received on client."); try { Vector3 castPos = default(Vector3); ((Vector3)(ref castPos))..ctor(Convert.ToSingle(values[0]), Convert.ToSingle(values[1]), Convert.ToSingle(values[2])); ((MonoBehaviour)this).StartCoroutine(BoostLocalPlayer(castPos)); ((MonoBehaviour)this).StartCoroutine(PlayCastSound()); ((MonoBehaviour)this).StartCoroutine(SpawnSpeedParticles(castPos)); } catch (Exception ex) { Debug.LogError((object)("[SpeedSpell] SyncData error: " + ex.Message)); } } private IEnumerator SpawnSpeedParticles(Vector3 castPos) { //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) yield return null; Transform val = null; try { NetworkConnection val2 = InstanceFinder.ClientManager?.Connection; if (val2 != (NetworkConnection)null) { foreach (NetworkObject @object in val2.Objects) { PlayerMovement component = ((Component)@object).GetComponent(); if ((Object)(object)component != (Object)null) { val = ((Component)component).transform; break; } } } } catch { } if ((Object)(object)val == (Object)null) { PlayerMovement[] array = Object.FindObjectsOfType(); float num = float.MaxValue; PlayerMovement[] array2 = array; foreach (PlayerMovement val3 in array2) { float num2 = Vector3.Distance(((Component)val3).transform.position, castPos); if (num2 < num) { num = num2; val = ((Component)val3).transform; } } } if ((Object)(object)val == (Object)null) { yield break; } GameObject psObj = new GameObject("SpeedAura"); psObj.transform.SetParent(val); psObj.transform.localPosition = new Vector3(0f, 0.9f, 0f); ParticleSystem ps = psObj.AddComponent(); ParticleSystemRenderer component2 = psObj.GetComponent(); Material val4 = null; ParticleSystem[] array3 = Object.FindObjectsOfType(); for (int i = 0; i < array3.Length; i++) { ParticleSystemRenderer component3 = ((Component)array3[i]).GetComponent(); if ((Object)(object)component3 != (Object)null && (Object)(object)((Renderer)component3).sharedMaterial != (Object)null) { val4 = new Material(((Renderer)component3).sharedMaterial); val4.color = Color.white; break; } } if ((Object)(object)val4 == (Object)null) { string[] array4 = new string[5] { "Particles/Standard Unlit", "Particles/Alpha Blended", "Legacy Shaders/Particles/Alpha Blended", "Particles/Additive", "Legacy Shaders/Particles/Additive" }; for (int i = 0; i < array4.Length; i++) { Shader val5 = Shader.Find(array4[i]); if ((Object)(object)val5 != (Object)null) { val4 = new Material(val5); val4.color = Color.white; break; } } } if ((Object)(object)val4 != (Object)null) { ((Renderer)component2).material = val4; } MainModule main = ps.main; ((MainModule)(ref main)).loop = true; ((MainModule)(ref main)).duration = 15f; ((MainModule)(ref main)).simulationSpace = (ParticleSystemSimulationSpace)1; ((MainModule)(ref main)).maxParticles = 300; ((MainModule)(ref main)).startLifetime = new MinMaxCurve(0.3f, 0.6f); ((MainModule)(ref main)).startSpeed = new MinMaxCurve(2.5f, 5f); ((MainModule)(ref main)).startSize = new MinMaxCurve(0.04f, 0.12f); ((MainModule)(ref main)).startColor = new MinMaxGradient(new Color(1f, 0.95f, 0.2f, 0.9f), new Color(1f, 0.55f, 0f, 0.7f)); ((MainModule)(ref main)).gravityModifier = MinMaxCurve.op_Implicit(-0.3f); EmissionModule emission = ps.emission; ((EmissionModule)(ref emission)).rateOverTime = MinMaxCurve.op_Implicit(40f); ((EmissionModule)(ref emission)).SetBursts((Burst[])(object)new Burst[1] { new Burst(0f, (short)60) }); ShapeModule shape = ps.shape; ((ShapeModule)(ref shape)).enabled = true; ((ShapeModule)(ref shape)).shapeType = (ParticleSystemShapeType)0; ((ShapeModule)(ref shape)).radius = 0.35f; ColorOverLifetimeModule colorOverLifetime = ps.colorOverLifetime; ((ColorOverLifetimeModule)(ref colorOverLifetime)).enabled = true; Gradient val6 = new Gradient(); val6.SetKeys((GradientColorKey[])(object)new GradientColorKey[2] { new GradientColorKey(new Color(1f, 1f, 0.4f), 0f), new GradientColorKey(new Color(1f, 0.5f, 0f), 1f) }, (GradientAlphaKey[])(object)new GradientAlphaKey[3] { new GradientAlphaKey(1f, 0f), new GradientAlphaKey(0.6f, 0.4f), new GradientAlphaKey(0f, 1f) }); ((ColorOverLifetimeModule)(ref colorOverLifetime)).color = new MinMaxGradient(val6); SizeOverLifetimeModule sizeOverLifetime = ps.sizeOverLifetime; ((SizeOverLifetimeModule)(ref sizeOverLifetime)).enabled = true; AnimationCurve val7 = new AnimationCurve((Keyframe[])(object)new Keyframe[2] { new Keyframe(0f, 1f), new Keyframe(1f, 0f) }); ((SizeOverLifetimeModule)(ref sizeOverLifetime)).size = new MinMaxCurve(1f, val7); ps.Play(); yield return (object)new WaitForSeconds(15f); ps.Stop(true, (ParticleSystemStopBehavior)1); Object.Destroy((Object)(object)psObj, 1.5f); } private IEnumerator PlayCastSound() { string directoryName = Path.GetDirectoryName(((object)this).GetType().Assembly.Location); string wavPath = Path.Combine(directoryName, "Sounds", "SpeedSpell.wav"); string text = "file:///" + wavPath.Replace('\\', '/'); AudioClip clip = null; UnityWebRequest req = UnityWebRequestMultimedia.GetAudioClip(text, (AudioType)20); yield return req.SendWebRequest(); if ((int)req.result == 1) { clip = DownloadHandlerAudioClip.GetContent(req); } else { Debug.LogWarning((object)("[SpeedSpell] Audio load failed: " + req.error + " | path: " + wavPath)); } req.Dispose(); if (!((Object)(object)clip == (Object)null)) { GameObject val = new GameObject("SpeedSpellAudio"); AudioSource obj = val.AddComponent(); obj.spatialBlend = 0f; obj.volume = 1f; obj.clip = clip; obj.Play(); Object.Destroy((Object)val, clip.length + 0.1f); } } private IEnumerator BoostLocalPlayer(Vector3 castPos) { //IL_000e: Unknown result type (might be due to invalid IL or missing references) //IL_000f: Unknown result type (might be due to invalid IL or missing references) yield return null; PlayerMovement val = null; try { NetworkConnection val2 = InstanceFinder.ClientManager?.Connection; if (val2 != (NetworkConnection)null) { foreach (NetworkObject @object in val2.Objects) { PlayerMovement component = ((Component)@object).GetComponent(); if ((Object)(object)component != (Object)null) { val = component; Debug.Log((object)"[SpeedSpell] Found local player via InstanceFinder."); break; } } } } catch (Exception ex) { Debug.LogWarning((object)("[SpeedSpell] InstanceFinder path failed: " + ex.Message)); } if ((Object)(object)val == (Object)null) { Debug.Log((object)"[SpeedSpell] Falling back to proximity search."); PlayerMovement[] array = Object.FindObjectsOfType(); float num = float.MaxValue; PlayerMovement[] array2 = array; foreach (PlayerMovement val3 in array2) { float num2 = Vector3.Distance(((Component)val3).transform.position, castPos); if (num2 < num) { num = num2; val = val3; } } } if ((Object)(object)val == (Object)null) { Debug.LogWarning((object)"[SpeedSpell] Could not find local PlayerMovement."); } else { ((MonoBehaviour)this).StartCoroutine(ApplyBoost(val, "CLIENT")); } } private IEnumerator ApplyBoost(PlayerMovement target, string context) { if ((Object)(object)target == (Object)null) { yield break; } Type type = ((object)target).GetType(); Debug.Log((object)("[SpeedSpell][" + context + "] Float fields on " + type.Name + ":")); FieldInfo[] fields = type.GetFields(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); foreach (FieldInfo fieldInfo in fields) { if (fieldInfo.FieldType == typeof(float)) { Debug.Log((object)$" {fieldInfo.Name} = {fieldInfo.GetValue(target)}"); } } List<(FieldInfo fi, float orig, bool isBonus)> boosted = new List<(FieldInfo, float, bool)>(); string[] sPEED_FIELD_NAMES = SPEED_FIELD_NAMES; foreach (string text in sPEED_FIELD_NAMES) { FieldInfo field = type.GetField(text, BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); if (!(field == null) && !(field.FieldType != typeof(float))) { float num = (float)field.GetValue(target); field.SetValue(target, num * 2.5f); boosted.Add((field, num, false)); Debug.Log((object)$"[SpeedSpell][{context}] {text}: {num:F2} -> {num * 2.5f:F2}"); } } sPEED_FIELD_NAMES = BONUS_FIELD_NAMES; foreach (string text2 in sPEED_FIELD_NAMES) { FieldInfo field2 = type.GetField(text2, BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); if (!(field2 == null) && !(field2.FieldType != typeof(float))) { float num2 = (float)field2.GetValue(target); field2.SetValue(target, num2 + 15f); boosted.Add((field2, num2, true)); Debug.Log((object)$"[SpeedSpell][{context}] bonus {text2}: {num2:F2} -> {num2 + 15f:F2}"); } } if (boosted.Count == 0) { Debug.LogWarning((object)("[SpeedSpell][" + context + "] No speed fields found — check the field dump above.")); yield break; } Debug.Log((object)("[SpeedSpell][" + context + "] Boost active for " + 15f + "s.")); yield return (object)new WaitForSeconds(15f); if ((Object)(object)target == (Object)null) { yield break; } foreach (var (fieldInfo2, num3, _) in boosted) { fieldInfo2.SetValue(target, num3); } Debug.Log((object)("[SpeedSpell][" + context + "] Boost expired, values restored.")); } }