Decompiled source of WagerSpell v2.0.0

BepInEx\plugins\WagerSpell\WagerSpell.dll

Decompiled a week ago
using System;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using BepInEx;
using BepInEx.Bootstrap;
using BepInEx.Configuration;
using BepInEx.Logging;
using BlackMagicAPI.Enums;
using BlackMagicAPI.Helpers;
using BlackMagicAPI.Managers;
using BlackMagicAPI.Modules.Spells;
using BlackMagicAPI.Network;
using FishNet.Object;
using Microsoft.CodeAnalysis;
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("WagerSpell")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("2.0.0.0")]
[assembly: AssemblyInformationalVersion("2.0.0+615e37e965e7a7e1ceb9b3f3395c63bb257b3243")]
[assembly: AssemblyProduct("One-shot spell with a 50/50 chance to hit you instead of your target")]
[assembly: AssemblyTitle("WagerSpell")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("2.0.0.0")]
[module: UnverifiableCode]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.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 WagerSpell
{
	internal class PluginInfo
	{
		public const string PLUGIN_GUID = "com.YeahThatsMJ.WagerSpell";

		public const string PLUGIN_NAME = "Wager Spell";

		public const string PLUGIN_VERSION = "2.0.0";
	}
	internal static class Utils
	{
		public static readonly string PluginDir = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location);

		public static bool HasLineOfSight(Vector3 origin, Vector3 target)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_000b: 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)
			//IL_0015: Unknown result type (might be due to invalid IL or missing references)
			//IL_0016: Unknown result type (might be due to invalid IL or missing references)
			//IL_0017: Unknown result type (might be due to invalid IL or missing references)
			//IL_0021: 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_002b: 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_002d: Unknown result type (might be due to invalid IL or missing references)
			//IL_002e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0033: Unknown result type (might be due to invalid IL or missing references)
			//IL_0037: Unknown result type (might be due to invalid IL or missing references)
			//IL_003c: Unknown result type (might be due to invalid IL or missing references)
			//IL_003d: Unknown result type (might be due to invalid IL or missing references)
			//IL_003e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0087: 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_008d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0092: Unknown result type (might be due to invalid IL or missing references)
			//IL_0094: 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)
			Vector3 val = origin + Vector3.up * 1.5f;
			Vector3 val2 = target + Vector3.up * 1.5f;
			Vector3 val3 = val2 - val;
			Vector3 normalized = ((Vector3)(ref val3)).normalized;
			float num = Vector3.Distance(val, val2);
			int num2 = ~(1 << LayerMask.NameToLayer("Player"));
			float[] array = new float[3] { -5f, 0f, 5f };
			foreach (float num3 in array)
			{
				Vector3 val4 = Quaternion.Euler(0f, num3, 0f) * normalized;
				if (!Physics.Raycast(val, val4, num, num2))
				{
					return true;
				}
			}
			return false;
		}

		public static AudioClip LoadSound(string soundFileName, AudioType soundFileType)
		{
			//IL_005f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0076: Unknown result type (might be due to invalid IL or missing references)
			//IL_007c: Invalid comparison between Unknown and I4
			WagerSpell.Logger.LogInfo((object)("Loading sound file: " + soundFileName));
			string text = Path.Combine(PluginDir, "Sounds", soundFileName);
			if (!File.Exists(text))
			{
				WagerSpell.Logger.LogError((object)("Could not find sound file: " + text));
				return null;
			}
			UnityWebRequest audioClip = UnityWebRequestMultimedia.GetAudioClip("file://" + text.Replace("\\", "/"), soundFileType);
			try
			{
				audioClip.SendWebRequest();
				while (!audioClip.isDone)
				{
				}
				if ((int)audioClip.result != 1)
				{
					WagerSpell.Logger.LogError((object)("Failed to load " + text + ": " + audioClip.error));
					return null;
				}
				WagerSpell.Logger.LogInfo((object)("Successfully loaded " + text));
				return DownloadHandlerAudioClip.GetContent(audioClip);
			}
			finally
			{
				((IDisposable)audioClip)?.Dispose();
			}
		}

		public static void PlaySpatialSoundAtPosition(Vector3 position, AudioClip clip)
		{
			//IL_000f: 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_001a: 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_0076: Expected O, but got Unknown
			if (!((Object)(object)clip == (Object)null))
			{
				GameObject val = new GameObject("WagerSpellAudio");
				val.transform.position = position;
				AudioSource obj = val.AddComponent<AudioSource>();
				obj.clip = clip;
				obj.volume = 1f;
				obj.spatialBlend = 1f;
				obj.rolloffMode = (AudioRolloffMode)1;
				obj.minDistance = 5f;
				obj.maxDistance = 350f;
				obj.Play();
				Object.Destroy((Object)val, clip.length + 0.1f);
			}
		}
	}
	[BepInPlugin("com.YeahThatsMJ.WagerSpell", "Wager Spell", "2.0.0")]
	[BepInProcess("MageArena.exe")]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	public class WagerSpell : BaseUnityPlugin
	{
		public static readonly string modsync = "all";

		public static WagerSpell Instance { get; private set; }

		internal static AudioClip ExplodeSound { get; private set; }

		internal static AudioClip JackpotSound { get; private set; }

		internal static GameObject ExplosionPrefab { get; private set; }

		internal static ManualLogSource Logger { get; private set; }

		private void Awake()
		{
			Instance = this;
			Logger = ((BaseUnityPlugin)this).Logger;
			Logger.LogInfo((object)"Initializing com.YeahThatsMJ.WagerSpell...");
			WagerSpellConfig.LoadConfig((BaseUnityPlugin)(object)this);
			LoadAssets();
			BlackMagicManager.RegisterSpell((BaseUnityPlugin)(object)this, typeof(WagerSpellData), typeof(WagerSpellLogic));
			BlackMagicManager.RegisterDeathIcon((BaseUnityPlugin)(object)this, "Wager", "Wager_Death");
			Logger.LogInfo((object)"Plugin com.YeahThatsMJ.WagerSpell is loaded!");
		}

		private void Update()
		{
		}

		private void LoadAssets()
		{
			Logger.LogInfo((object)"Loading sounds");
			ExplodeSound = Utils.LoadSound("Explode.wav", (AudioType)20);
			JackpotSound = Utils.LoadSound("Jackpot.wav", (AudioType)20);
			Logger.LogInfo((object)"Loading assets from bundle");
			AssetBundle obj = Utils.LoadAssetBundleFromDisk(Path.Combine(Utils.PluginDir, "AssetBundles", "explosion_prefab"));
			string text = "assets/gabrielaguiarproductions/freequickeffectsvol1/prefabs/vfx_impact_01.prefab";
			ExplosionPrefab = obj.LoadAsset<GameObject>(text);
			Object.DontDestroyOnLoad((Object)(object)ExplosionPrefab);
			obj.UnloadAsync(false);
		}
	}
	internal static class WagerSpellConfig
	{
		private static bool _mageConfigApiExists;

		private static BaseUnityPlugin _plugin;

		internal static ConfigEntry<float> CooldownConfig { get; private set; }

		internal static ConfigEntry<float> RangeConfig { get; private set; }

		internal static ConfigEntry<float> DamageConfig { get; private set; }

		internal static ConfigEntry<float> ChanceConfig { get; private set; }

		internal static ConfigEntry<bool> TeamChestConfig { get; private set; }

		public static void LoadConfig(BaseUnityPlugin plugin)
		{
			_plugin = plugin;
			_mageConfigApiExists = Chainloader.PluginInfos.ContainsKey("com.d1gq.mage.configuration.api");
			if (!_mageConfigApiExists)
			{
				WagerSpell.Logger.LogInfo((object)"MageConfigurationAPI not present. Continuing to bind from config, but will not add to in-game menu.");
			}
			CooldownConfig = BindConfig("Cooldown", 60f, "Time until spell can be used again (> 0)", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, float.MaxValue));
			RangeConfig = BindConfig("Range", 20f, "Maximum distance a target can be from the caster (> 0)", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, float.MaxValue));
			DamageConfig = BindConfig("Damage", 1000f, "Damage that will be dealt to target", (AcceptableValueBase)(object)new AcceptableValueRange<float>(float.MinValue, float.MaxValue));
			ChanceConfig = BindConfig("Chance", 0.5f, "Chance that caster will be the target of the spell (0 - 1)", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 1f));
			TeamChestConfig = BindConfig("Team Chest", defaultValue: true, "Whether the page can spawn in the team chest");
		}

		private static ConfigEntry<T> BindConfig<T>(string key, T defaultValue, string description, AcceptableValueBase acceptableValues = null)
		{
			//IL_0018: Unknown result type (might be due to invalid IL or missing references)
			//IL_0022: Expected O, but got Unknown
			ConfigEntry<T> val = _plugin.Config.Bind<T>("Wager Spell", key, defaultValue, new ConfigDescription(description, acceptableValues, Array.Empty<object>()));
			if (_mageConfigApiExists)
			{
				TryRegisterWithMageConfig(val);
			}
			return val;
		}

		private static void TryRegisterWithMageConfig(object configEntry)
		{
			try
			{
				Assembly assembly = AppDomain.CurrentDomain.GetAssemblies().FirstOrDefault((Assembly a) => a.GetName().Name.Equals("MageConfigurationAPI", StringComparison.OrdinalIgnoreCase));
				if (assembly == null && Chainloader.PluginInfos.TryGetValue("com.d1gq.mage.configuration.api", out var value))
				{
					assembly = ((object)value.Instance)?.GetType().Assembly;
				}
				if (assembly == null)
				{
					WagerSpell.Logger.LogInfo((object)"MageConfigurationAPI present in PluginInfos, but assembly not found. Skipping menu registration.");
					return;
				}
				Type settingsFlagType = assembly.GetType("MageConfigurationAPI.Enums.SettingsFlag", throwOnError: false);
				Type type = assembly.GetType("MageConfigurationAPI.Data.ModConfig", throwOnError: false);
				if (settingsFlagType == null || type == null)
				{
					WagerSpell.Logger.LogWarning((object)"MageConfigurationAPI types not found. Skipping menu registration.");
					return;
				}
				object obj = Enum.Parse(settingsFlagType, "ShowInLobbyMenu");
				ConstructorInfo constructorInfo = type.GetConstructors(BindingFlags.Instance | BindingFlags.Public).FirstOrDefault(delegate(ConstructorInfo ci)
				{
					ParameterInfo[] parameters = ci.GetParameters();
					return parameters.Length == 3 && typeof(BaseUnityPlugin).IsAssignableFrom(parameters[0].ParameterType) && parameters[2].ParameterType == settingsFlagType;
				});
				if (constructorInfo == null)
				{
					WagerSpell.Logger.LogWarning((object)"MageConfigurationAPI ModConfig constructor signature changed. Skipping menu registration.");
					return;
				}
				constructorInfo.Invoke(new object[3] { _plugin, configEntry, obj });
			}
			catch (Exception ex)
			{
				WagerSpell.Logger.LogWarning((object)("MageConfigurationAPI present but reflection failed: " + ex.GetType().Name + ": " + ex.Message));
			}
		}
	}
	internal class WagerSpellData : SpellData
	{
		public override SpellType SpellType => (SpellType)0;

		public override string Name => "Wager";

		public override float Cooldown => WagerSpellConfig.CooldownConfig.Value;

		public override Color GlowColor => new Color(2f, 1.886f, 1.427f);

		public override bool CanSpawnInTeamChest => WagerSpellConfig.TeamChestConfig.Value;
	}
	internal class WagerSpellLogic : SpellLogic
	{
		private const float MaxAngle = 45f;

		private int _casterNetworkId;

		private int _targetNetworkId;

		private static float SelfHitChance => WagerSpellConfig.ChanceConfig.Value;

		private static float Damage => WagerSpellConfig.DamageConfig.Value;

		private static float Range => WagerSpellConfig.RangeConfig.Value;

		public override void WriteData(DataWriter dataWriter, PageController page, PlayerMovement casterPlayerMovement, Vector3 spawnPos, Vector3 viewDirectionVector, int spellLevel)
		{
			//IL_005c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0061: Unknown result type (might be due to invalid IL or missing references)
			//IL_0069: Unknown result type (might be due to invalid IL or missing references)
			//IL_006e: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bc: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00dc: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fe: Unknown result type (might be due to invalid IL or missing references)
			NetworkObject component = ((Component)casterPlayerMovement).GetComponent<NetworkObject>();
			if (component == null)
			{
				WagerSpell.Logger.LogError((object)"Spell network object couldn't be found!");
				return;
			}
			int objectId = component.ObjectId;
			int num = -1;
			float num2 = Random.Range(0f, 1f);
			if (((Component)casterPlayerMovement).GetComponent<PlayerMovement>() == null)
			{
				WagerSpell.Logger.LogError((object)"Caster's PlayerMovement could not be found!");
				return;
			}
			if (num2 > SelfHitChance)
			{
				Vector3 position = ((Component)casterPlayerMovement).transform.position;
				Vector3 forward = ((Component)casterPlayerMovement).transform.forward;
				float num3 = float.MaxValue;
				GameObject[] array = GameObject.FindGameObjectsWithTag("Player");
				foreach (GameObject val in array)
				{
					NetworkObject component2 = val.GetComponent<NetworkObject>();
					if (component2 == null || component2.ObjectId == objectId || val.GetComponent<PlayerMovement>() == null)
					{
						continue;
					}
					Vector3 val2 = val.transform.position - position;
					float magnitude = ((Vector3)(ref val2)).magnitude;
					if (magnitude > Range)
					{
						continue;
					}
					float num4 = Vector3.Angle(forward, ((Vector3)(ref val2)).normalized);
					if (!(num4 > 45f) && Utils.HasLineOfSight(position, val.transform.position))
					{
						float num5 = num4 * 2f + magnitude;
						if (num5 < num3)
						{
							num3 = num5;
							num = component2.ObjectId;
						}
					}
				}
			}
			else
			{
				num = component.ObjectId;
			}
			dataWriter.Write<int>(objectId);
			dataWriter.Write<int>(num);
		}

		public override void SyncData(object[] values)
		{
			if (values.Length != 2 || (values[0].GetType() != typeof(int) && values[1].GetType() != typeof(int)))
			{
				WagerSpell.Logger.LogError((object)"SyncData values does not contain 2 int entries!");
				return;
			}
			_casterNetworkId = (int)values[0];
			_targetNetworkId = (int)values[1];
		}

		public override bool CastSpell(PlayerMovement caster, PageController page, Vector3 spawnPos, Vector3 viewDirection, int castingLevel)
		{
			//IL_0123: Unknown result type (might be due to invalid IL or missing references)
			//IL_0128: Unknown result type (might be due to invalid IL or missing references)
			//IL_0132: Unknown result type (might be due to invalid IL or missing references)
			//IL_0137: Unknown result type (might be due to invalid IL or missing references)
			//IL_013c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0149: Unknown result type (might be due to invalid IL or missing references)
			//IL_014e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0158: Unknown result type (might be due to invalid IL or missing references)
			//IL_015d: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fb: Unknown result type (might be due to invalid IL or missing references)
			//IL_0100: Unknown result type (might be due to invalid IL or missing references)
			//IL_010a: Unknown result type (might be due to invalid IL or missing references)
			//IL_010f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0114: Unknown result type (might be due to invalid IL or missing references)
			//IL_0171: Unknown result type (might be due to invalid IL or missing references)
			//IL_0173: Unknown result type (might be due to invalid IL or missing references)
			//IL_0187: Unknown result type (might be due to invalid IL or missing references)
			//IL_018c: Unknown result type (might be due to invalid IL or missing references)
			//IL_019e: Unknown result type (might be due to invalid IL or missing references)
			PlayerMovement val = null;
			PlayerMovement val2 = null;
			GameObject[] array = GameObject.FindGameObjectsWithTag("Player");
			foreach (GameObject val3 in array)
			{
				NetworkObject component = val3.GetComponent<NetworkObject>();
				if (component == null)
				{
					continue;
				}
				if (component.ObjectId == _casterNetworkId)
				{
					PlayerMovement component2 = val3.GetComponent<PlayerMovement>();
					if (component2 == null)
					{
						WagerSpell.Logger.LogError((object)"Caster's PlayerMovement could not be found!");
						return false;
					}
					val = component2;
				}
				if (component.ObjectId == _targetNetworkId)
				{
					PlayerMovement component3 = val3.GetComponent<PlayerMovement>();
					if (component3 == null)
					{
						WagerSpell.Logger.LogError((object)"Caster's PlayerMovement could not be found!");
						return false;
					}
					val2 = component3;
				}
			}
			if (val == null)
			{
				WagerSpell.Logger.LogError((object)"Caster's PlayerMovement could not be found!");
				return false;
			}
			if (_targetNetworkId != 0)
			{
				if (val2 == null)
				{
					WagerSpell.Logger.LogError((object)"Targets's PlayerMovement could not be found!");
					return false;
				}
				WagerSpell.Logger.LogInfo((object)(val.playername + " wagered and is targeting " + val2.playername + "!"));
				Vector3 val4;
				if ((Object)(object)val2 == (Object)(object)val)
				{
					val4 = ((Component)val).gameObject.transform.position + Vector3.up * 1.75f;
				}
				else
				{
					val4 = ((Component)val2).gameObject.transform.position + Vector3.up * 1.75f;
					Utils.PlaySpatialSoundAtPosition(((Component)val).gameObject.transform.position + Vector3.up * 1.75f, WagerSpell.JackpotSound);
				}
				GameObject obj = Object.Instantiate<GameObject>(WagerSpell.ExplosionPrefab, val4, Quaternion.identity);
				MainModule main = WagerSpell.ExplosionPrefab.GetComponent<ParticleSystem>().main;
				float duration = ((MainModule)(ref main)).duration;
				Object.Destroy((Object)(object)obj, duration);
				Utils.PlaySpatialSoundAtPosition(val4, WagerSpell.ExplodeSound);
				val2.DamagePlayer(Damage, ((Component)val).gameObject, "Wager");
				return true;
			}
			WagerSpell.Logger.LogInfo((object)(val.playername + " wagered but found no valid targets!"));
			return false;
		}
	}
	public static class MyPluginInfo
	{
		public const string PLUGIN_GUID = "WagerSpell";

		public const string PLUGIN_NAME = "One-shot spell with a 50/50 chance to hit you instead of your target";

		public const string PLUGIN_VERSION = "2.0.0";
	}
}