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()
{
}
}
}