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<float>(val.x);
writer.Write<float>(val.y);
writer.Write<float>(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<PlayerMovement>();
if ((Object)(object)component != (Object)null)
{
val = ((Component)component).transform;
break;
}
}
}
}
catch
{
}
if ((Object)(object)val == (Object)null)
{
PlayerMovement[] array = Object.FindObjectsOfType<PlayerMovement>();
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<ParticleSystem>();
ParticleSystemRenderer component2 = psObj.GetComponent<ParticleSystemRenderer>();
Material val4 = null;
ParticleSystem[] array3 = Object.FindObjectsOfType<ParticleSystem>();
for (int i = 0; i < array3.Length; i++)
{
ParticleSystemRenderer component3 = ((Component)array3[i]).GetComponent<ParticleSystemRenderer>();
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<AudioSource>();
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<PlayerMovement>();
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<PlayerMovement>();
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."));
}
}