Decompiled source of CircleSnapfreeze v1.1.3

CircleSnapfreeze.dll

Decompiled a year ago
using System;
using System.CodeDom.Compiler;
using System.Collections.Generic;
using System.ComponentModel;
using System.Diagnostics;
using System.Globalization;
using System.Reflection;
using System.Resources;
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 CircleSnapfreeze.Properties;
using CircleSnapfreeze.States;
using EntityStates;
using EntityStates.Huntress;
using EntityStates.Mage.Weapon;
using R2API;
using R2API.Utils;
using RoR2;
using RoR2.Projectile;
using RoR2.Skills;
using RoR2.UI;
using UnityEngine;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)]
[assembly: TargetFramework(".NETStandard,Version=v2.0", FrameworkDisplayName = "")]
[assembly: AssemblyCompany("CircleSnapfreeze")]
[assembly: AssemblyConfiguration("Debug")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0")]
[assembly: AssemblyProduct("CircleSnapfreeze")]
[assembly: AssemblyTitle("CircleSnapfreeze")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.0.0.0")]
[module: UnverifiableCode]
namespace CircleSnapfreeze
{
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[BepInPlugin("Borbo.CircleSnapfreeze", "CircleSnapfreeze", "1.1.2")]
	[R2APISubmoduleDependency(new string[] { "LanguageAPI", "ContentAddition" })]
	public class CircleSnapPlugin : BaseUnityPlugin
	{
		public const string PluginGUID = "Borbo.CircleSnapfreeze";

		public const string PluginAuthor = "Borbo";

		public const string PluginName = "CircleSnapfreeze";

		public const string PluginVersion = "1.1.2";

		private bool isAutosprintLoaded = Tools.isLoaded("com.johnedwa.RTAutoSprintEx");

		public static AssetBundle iconBundle = Tools.LoadAssetBundle(Resources.clapfreeze);

		public static string iconsPath = "Assets/";

		public static GameObject CircleSnapWalkerPrefab;

		internal static ConfigFile CustomConfigFile { get; set; }

		public static ConfigEntry<float> CircleMaxRadius { get; set; }

		public static ConfigEntry<float> CircleMaxDeployTime { get; set; }

		public static ConfigEntry<int> TotalRays { get; set; }

		public static ConfigEntry<int> PillarsPerRay { get; set; }

		public static ConfigEntry<int> RayRotationOffset { get; set; }

		public static ConfigEntry<bool> IsCombatSkill { get; set; }

		public static ConfigEntry<bool> CanceledFromSprinting { get; set; }

		public static ConfigEntry<int> BaseMaxStock { get; set; }

		public static ConfigEntry<int> RechargeStock { get; set; }

		public static ConfigEntry<float> BaseRechargeInterval { get; set; }

		public static ConfigEntry<bool> UseClapfreezeAssets { get; set; }

		public void Awake()
		{
			Log.Init(((BaseUnityPlugin)this).Logger);
			InitializeConfig();
			InitializeCustomWalker();
			CircleTheSnapfreeze();
			if (isAutosprintLoaded)
			{
				DoAutosprintCompat();
			}
			Log.LogInfo("Awake done.");
		}

		[MethodImpl(MethodImplOptions.NoInlining | MethodImplOptions.NoOptimization)]
		private void DoAutosprintCompat()
		{
			((Component)this).SendMessage("RT_SprintDisableMessage", (object)"CircleSnapfreeze.States.PrepCircleWall");
		}

		private void InitializeConfig()
		{
			//IL_0011: Unknown result type (might be due to invalid IL or missing references)
			//IL_001b: Expected O, but got Unknown
			CustomConfigFile = new ConfigFile(Paths.ConfigPath + "\\CircleSnap.cfg", true);
			CircleMaxRadius = CustomConfigFile.Bind<float>("Circle Snap - State", "Snapfreeze Maximum Radius", 6f, "This determines the outer radius of Circle Snapfreeze's Snapfreeze Circle. All ice pillars spawned will be WITHIN this radius. 12 behaves the same as vanilla.");
			CircleMaxDeployTime = CustomConfigFile.Bind<float>("Circle Snap - State", "Snapfreeze Deploy Time", 0.15f, "This determines the time it takes to fully deploy Snapfreeze. 0.3 behaves the same as vanilla.");
			TotalRays = CustomConfigFile.Bind<int>("Circle Snap - State", "Total Rays", 9, "This determines how many 'rays' circle snapfreeze has. 2 rays behaves the same as vanilla. Minimum of 2 rays.");
			TotalRays.Value = Mathf.Max(TotalRays.Value, 2);
			PillarsPerRay = CustomConfigFile.Bind<int>("Circle Snap - State", "Pillars Per Ray", 1, "This determines how many pillars are dropped in each of circle snapfreeze's 'rays'. 6 pillars behaves the same as vanilla. Minimum of 1 pillar per ray.");
			PillarsPerRay.Value = Mathf.Max(PillarsPerRay.Value, 1);
			RayRotationOffset = CustomConfigFile.Bind<int>("Clapfreeze", "Ray Rotation Offset", -90, "This determines the rotation offset for Snapfreeze 'rays'. This wont have a significant effect on the performance of Snapfreeze unless youre using very few rays. Every 360 degrees loops back around to 0, you know the drill. -90 fires the first ray towards you - behaving the same as ArtificerExtended's long lost Clapfreeze skill.");
			IsCombatSkill = CustomConfigFile.Bind<bool>("Circle Snap - Skill", "Is Circle Snapfreeze a Combat Skill", true, "Set whether or not casting Snapfreeze causes the player to enter combat, cancelling effects such as Red Whip. Vanilla value: True.");
			CanceledFromSprinting = CustomConfigFile.Bind<bool>("Circle Snap - Skill", "Is Circle Snapfreeze Canceled from Sprinting", true, "Set whether or not casting Snapfreeze is cancelled from sprinting. Vanilla value: True.");
			BaseMaxStock = CustomConfigFile.Bind<int>("Circle Snap - Skill", "Circle Snapfreeze Base Max Stock", 1, "Set the base value for Snapfreeze's maximum stock. Vanilla value: 1.");
			RechargeStock = CustomConfigFile.Bind<int>("Circle Snap - Skill", "Circle Snapfreeze Recharge Stock", 1, "Set the value for how much stock Snapfreeze recharges per cooldown; useful for higher values of Base Max Stock. Vanilla value: 1.");
			BaseRechargeInterval = CustomConfigFile.Bind<float>("Circle Snap - Skill", "Circle Snapfreeze Base Recharge Interval", 8f, "Set the base value for Snapfreeze's cooldown (recharge interval). Vanilla value: 12; ArtificerExtended value: 8.");
			UseClapfreezeAssets = CustomConfigFile.Bind<bool>("Clapfreeze", "Use Clapfreeze Assets", false, "Enable cosmetic changes to make the Snapfreeze skill use the Clapfreeze assets from ArtificerExtended.");
		}

		private void InitializeCustomWalker()
		{
			CircleSnapWalkerPrefab = PrefabAPI.InstantiateClone(Resources.Load<GameObject>("prefabs/projectiles/MageIcewallWalkerProjectile"), "CircleSnapWalker", true);
			float value = CircleMaxDeployTime.Value;
			float velocity = CircleMaxRadius.Value / value;
			float dropInterval = value / ((float)PillarsPerRay.Value - 0.5f) - 0.01f;
			ProjectileCharacterController component = CircleSnapWalkerPrefab.GetComponent<ProjectileCharacterController>();
			if ((Object)(object)component != (Object)null)
			{
				component.lifetime = value;
				component.velocity = velocity;
			}
			else
			{
				Log.LogError("InitializeCustomWalker tried to find the ProjectileCharacterController from the walker projectile and failed.");
			}
			ProjectileMageFirewallWalkerController component2 = CircleSnapWalkerPrefab.GetComponent<ProjectileMageFirewallWalkerController>();
			if ((Object)(object)component2 != (Object)null)
			{
				component2.dropInterval = dropInterval;
			}
			else
			{
				Log.LogError("InitializeCustomWalker tried to find the ProjectileMageFirewallWalkerController from the walker projectile and failed.");
			}
			ContentAddition.AddProjectile(CircleSnapWalkerPrefab);
		}

		private void CircleTheSnapfreeze()
		{
			//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_0032: Unknown result type (might be due to invalid IL or missing references)
			SkillDef val = Resources.Load<SkillDef>("skilldefs/magebody/magebodywall");
			if ((Object)(object)val != (Object)null)
			{
				val.activationState = new SerializableEntityStateType(typeof(PrepCircleWall));
				bool flag = default(bool);
				ContentAddition.AddEntityState<PrepCircleWall>(ref flag);
				LanguageAPI.Add(val.skillDescriptionToken = "MAGE_CIRCLESNAP_ICE_DESCRIPTION", "<style=cIsUtility>Freezing</style>. Create a barrier that hurts enemies for " + $"up to <style=cIsDamage>{PillarsPerRay.Value * TotalRays.Value}x100% damage</style>.");
				if (UseClapfreezeAssets.Value)
				{
					val.icon = iconBundle.LoadAsset<Sprite>(iconsPath + "clapfreeze.png");
					LanguageAPI.Add("MAGE_UTILITY_ICE_NAME", "Clapfreeze");
				}
				val.isCombatSkill = IsCombatSkill.Value;
				val.canceledFromSprinting = CanceledFromSprinting.Value;
				val.baseMaxStock = BaseMaxStock.Value;
				val.rechargeStock = RechargeStock.Value;
				val.baseRechargeInterval = BaseRechargeInterval.Value;
			}
			else
			{
				Log.LogError("CircleTheSnapfreeze tried to load the Snapfreeze SkillDef and failed.");
			}
		}
	}
	internal static class Log
	{
		internal static ManualLogSource _logSource;

		internal static void Init(ManualLogSource logSource)
		{
			_logSource = logSource;
		}

		internal static void LogDebug(object data)
		{
			_logSource.LogDebug(data);
		}

		internal static void LogError(object data)
		{
			_logSource.LogError(data);
		}

		internal static void LogFatal(object data)
		{
			_logSource.LogFatal(data);
		}

		internal static void LogInfo(object data)
		{
			_logSource.LogInfo(data);
		}

		internal static void LogMessage(object data)
		{
			_logSource.LogMessage(data);
		}

		internal static void LogWarning(object data)
		{
			_logSource.LogWarning(data);
		}
	}
	public static class Tools
	{
		public static string modPrefix = string.Format("@{0}+{1}", "CircleSnapfreeze", "artiskillicons");

		public static AssetBundle LoadAssetBundle(byte[] resourceBytes)
		{
			if (resourceBytes == null)
			{
				throw new ArgumentNullException("resourceBytes");
			}
			return AssetBundle.LoadFromMemory(resourceBytes);
		}

		public static string GetModPrefix(this BaseUnityPlugin plugin, string bundleName)
		{
			return $"@{plugin.Info.Metadata.Name}+{bundleName}";
		}

		public static string ConvertDecimal(float f)
		{
			return f * 100f + "%";
		}

		internal static bool isLoaded(string modguid)
		{
			foreach (KeyValuePair<string, PluginInfo> pluginInfo in Chainloader.PluginInfos)
			{
				string key = pluginInfo.Key;
				PluginInfo value = pluginInfo.Value;
				if (key == modguid)
				{
					return true;
				}
			}
			return false;
		}
	}
}
namespace CircleSnapfreeze.States
{
	internal class PrepCircleWall : BaseState
	{
		public static GameObject projectilePrefab = CircleSnapPlugin.CircleSnapWalkerPrefab;

		private bool goodPlacement;

		private GameObject areaIndicatorInstance;

		private GameObject cachedCrosshairPrefab;

		private float duration;

		private float stopwatch;

		private OverrideRequest crosshairOverrideRequest;

		public override void OnEnter()
		{
			((BaseState)this).OnEnter();
			duration = PrepWall.baseDuration / base.attackSpeedStat;
			((EntityState)this).characterBody.SetAimTimer(duration + 2f);
			((EntityState)this).PlayAnimation("Gesture, Additive", "PrepWall", "PrepWall.playbackRate", duration);
			Util.PlaySound(PrepWall.prepWallSoundString, ((EntityState)this).gameObject);
			areaIndicatorInstance = Object.Instantiate<GameObject>(ArrowRain.areaIndicatorPrefab);
			UpdateAreaIndicator();
		}

		private void UpdateAreaIndicator()
		{
			//IL_000c: Unknown result type (might be due to invalid IL or missing references)
			//IL_001b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0025: Unknown result type (might be due to invalid IL or missing references)
			//IL_006b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0070: Unknown result type (might be due to invalid IL or missing references)
			//IL_0072: Unknown result type (might be due to invalid IL or missing references)
			//IL_007c: Unknown result type (might be due to invalid IL or missing references)
			//IL_008b: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ae: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00de: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ef: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f6: Unknown result type (might be due to invalid IL or missing references)
			areaIndicatorInstance.transform.localScale = Vector3.one * CircleSnapPlugin.CircleMaxRadius.Value * 1f;
			bool flag = goodPlacement;
			goodPlacement = false;
			areaIndicatorInstance.SetActive(true);
			if (Object.op_Implicit((Object)(object)areaIndicatorInstance))
			{
				float maxDistance = PrepWall.maxDistance;
				float num = 0f;
				Ray aimRay = ((BaseState)this).GetAimRay();
				RaycastHit val = default(RaycastHit);
				if (Physics.Raycast(CameraRigController.ModifyAimRayIfApplicable(aimRay, ((EntityState)this).gameObject, ref num), ref val, maxDistance + num, LayerMask.op_Implicit(((LayerIndex)(ref LayerIndex.world)).mask)))
				{
					areaIndicatorInstance.transform.position = ((RaycastHit)(ref val)).point;
					areaIndicatorInstance.transform.up = ((RaycastHit)(ref val)).normal;
					areaIndicatorInstance.transform.forward = -((Ray)(ref aimRay)).direction;
					goodPlacement = Vector3.Angle(Vector3.up, ((RaycastHit)(ref val)).normal) < PrepWall.maxSlopeAngle;
				}
				if (flag != goodPlacement || crosshairOverrideRequest == null)
				{
					OverrideRequest val2 = crosshairOverrideRequest;
					if (val2 != null)
					{
						val2.Dispose();
					}
					GameObject val3 = (goodPlacement ? PrepWall.goodCrosshairPrefab : PrepWall.badCrosshairPrefab);
					crosshairOverrideRequest = CrosshairUtils.RequestOverrideForBody(((EntityState)this).characterBody, val3, (OverridePriority)1);
				}
			}
			areaIndicatorInstance.SetActive(goodPlacement);
		}

		public override void Update()
		{
			((EntityState)this).Update();
			UpdateAreaIndicator();
		}

		public override void FixedUpdate()
		{
			((EntityState)this).FixedUpdate();
			stopwatch += Time.fixedDeltaTime;
			if (stopwatch >= duration && !((EntityState)this).inputBank.skill3.down && ((EntityState)this).isAuthority)
			{
				((EntityState)this).outer.SetNextStateToMain();
			}
		}

		public override void OnExit()
		{
			//IL_00b5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ba: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d7: 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_0111: Unknown result type (might be due to invalid IL or missing references)
			//IL_0116: Unknown result type (might be due to invalid IL or missing references)
			//IL_011b: Unknown result type (might be due to invalid IL or missing references)
			//IL_011d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0122: Unknown result type (might be due to invalid IL or missing references)
			//IL_0139: Unknown result type (might be due to invalid IL or missing references)
			//IL_013e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0143: Unknown result type (might be due to invalid IL or missing references)
			//IL_0148: Unknown result type (might be due to invalid IL or missing references)
			//IL_014a: Unknown result type (might be due to invalid IL or missing references)
			if (!((EntityState)this).outer.destroying)
			{
				if (goodPlacement)
				{
					((EntityState)this).PlayAnimation("Gesture, Additive", "FireWall");
					Util.PlaySound(PrepWall.fireSoundString, ((EntityState)this).gameObject);
					if (Object.op_Implicit((Object)(object)areaIndicatorInstance) && ((EntityState)this).isAuthority)
					{
						EffectManager.SimpleMuzzleFlash(PrepWall.muzzleflashEffect, ((EntityState)this).gameObject, "MuzzleLeft", true);
						EffectManager.SimpleMuzzleFlash(PrepWall.muzzleflashEffect, ((EntityState)this).gameObject, "MuzzleRight", true);
						bool flag = Util.CheckRoll(base.critStat, ((EntityState)this).characterBody.master);
						Vector3 forward = areaIndicatorInstance.transform.forward;
						forward.y = 0f;
						((Vector3)(ref forward)).Normalize();
						Vector3 val = Vector3.Cross(Vector3.up, forward);
						int value = CircleSnapPlugin.TotalRays.Value;
						float num = CircleSnapPlugin.RayRotationOffset.Value;
						float num2 = 360f / (float)value;
						for (int i = 0; i < value; i++)
						{
							Vector3 val2 = Quaternion.AngleAxis(num2 * (float)i + num, Vector3.up) * val;
							ProjectileManager.instance.FireProjectile(projectilePrefab, areaIndicatorInstance.transform.position + Vector3.up, Util.QuaternionSafeLookRotation(val2), ((EntityState)this).gameObject, base.damageStat * PrepWall.damageCoefficient, 0f, flag, (DamageColorIndex)0, (GameObject)null, -1f);
						}
					}
				}
				else
				{
					((EntityState)this).skillLocator.utility.AddOneStock();
					((EntityState)this).PlayCrossfade("Gesture, Additive", "BufferEmpty", 0.2f);
				}
			}
			EntityState.Destroy((Object)(object)areaIndicatorInstance.gameObject);
			if (crosshairOverrideRequest != null)
			{
				crosshairOverrideRequest.Dispose();
			}
			((EntityState)this).OnExit();
		}

		public override InterruptPriority GetMinimumInterruptPriority()
		{
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			return (InterruptPriority)3;
		}
	}
}
namespace CircleSnapfreeze.Properties
{
	[GeneratedCode("System.Resources.Tools.StronglyTypedResourceBuilder", "16.0.0.0")]
	[DebuggerNonUserCode]
	[CompilerGenerated]
	internal class Resources
	{
		private static ResourceManager resourceMan;

		private static CultureInfo resourceCulture;

		[EditorBrowsable(EditorBrowsableState.Advanced)]
		internal static ResourceManager ResourceManager
		{
			get
			{
				if (resourceMan == null)
				{
					ResourceManager resourceManager = new ResourceManager("CircleSnapfreeze.Properties.Resources", typeof(Resources).Assembly);
					resourceMan = resourceManager;
				}
				return resourceMan;
			}
		}

		[EditorBrowsable(EditorBrowsableState.Advanced)]
		internal static CultureInfo Culture
		{
			get
			{
				return resourceCulture;
			}
			set
			{
				resourceCulture = value;
			}
		}

		internal static byte[] clapfreeze
		{
			get
			{
				object @object = ResourceManager.GetObject("clapfreeze", resourceCulture);
				return (byte[])@object;
			}
		}

		internal Resources()
		{
		}
	}
}