Decompiled source of SonicTheHedgehog v4.0.2

SonicTheHedgehog.dll

Decompiled 2 weeks ago
using System;
using System.Collections;
using System.Collections.Generic;
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 AncientScepter;
using BepInEx;
using BepInEx.Bootstrap;
using BepInEx.Configuration;
using BepInEx.Logging;
using EmotesAPI;
using EntityStates;
using EntityStates.Commando;
using HG;
using HG.BlendableTypes;
using HedgehogUtils;
using HedgehogUtils.Boost;
using HedgehogUtils.Boost.EntityStates;
using HedgehogUtils.Forms;
using HedgehogUtils.Forms.EntityStates;
using HedgehogUtils.Forms.SuperForm;
using HedgehogUtils.Launch;
using HedgehogUtils.Miscellaneous;
using JetBrains.Annotations;
using KinematicCharacterController;
using LoadingScreenFix;
using LookingGlass.LookingGlassLanguage;
using On.RoR2;
using On.RoR2.UI;
using R2API;
using R2API.Networking;
using R2API.Networking.Interfaces;
using R2API.Utils;
using RiskOfOptions;
using RiskOfOptions.OptionConfigs;
using RiskOfOptions.Options;
using RoR2;
using RoR2.Achievements;
using RoR2.Audio;
using RoR2.ContentManagement;
using RoR2.Projectile;
using RoR2.Skills;
using RoR2.UI;
using SonicTheHedgehog.Components;
using SonicTheHedgehog.Modules;
using SonicTheHedgehog.Modules.Achievements;
using SonicTheHedgehog.Modules.Characters;
using SonicTheHedgehog.Modules.Survivors;
using SonicTheHedgehog.SkillStates;
using SonicTheHedgehog.SkillStates.SuperUpgrades;
using UnityEngine;
using UnityEngine.AddressableAssets;
using UnityEngine.Networking;
using UnityEngine.Rendering;

[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.1", FrameworkDisplayName = ".NET Standard 2.1")]
[assembly: AssemblyCompany("SonicTheHedgehog")]
[assembly: AssemblyConfiguration("Debug")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0+24c167ce642e33091e5ddf3bbe927d81be90042e")]
[assembly: AssemblyProduct("SonicTheHedgehog")]
[assembly: AssemblyTitle("SonicTheHedgehog")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.0.0.0")]
[module: UnverifiableCode]
[module: UnverifiableCode]
namespace SonicTheHedgehog
{
	internal static class Log
	{
		internal static ManualLogSource _logSource;

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

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

		internal static void Error(object data)
		{
			if (Config.EnableLogs().Value)
			{
				_logSource.LogError(data);
			}
		}

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

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

		internal static void Message(object data)
		{
			if (Config.EnableLogs().Value)
			{
				_logSource.LogMessage(data);
			}
		}

		internal static void Warning(object data)
		{
			if (Config.EnableLogs().Value)
			{
				_logSource.LogWarning(data);
			}
		}
	}
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[NetworkCompatibility(/*Could not decode attribute arguments.*/)]
	[BepInPlugin("com.ds_gaming.SonicTheHedgehog", "SonicTheHedgehog", "4.0.1")]
	public class SonicTheHedgehogPlugin : BaseUnityPlugin
	{
		[Serializable]
		[CompilerGenerated]
		private sealed class <>c
		{
			public static readonly <>c <>9 = new <>c();

			public static hook_Init <>9__12_0;

			internal void <EmoteSkeleton>b__12_0(orig_Init orig)
			{
				orig.Invoke();
				foreach (SurvivorDef allSurvivorDef in SurvivorCatalog.allSurvivorDefs)
				{
					if (((Object)allSurvivorDef.bodyPrefab).name == "SonicTheHedgehog")
					{
						GameObject val = Assets.mainAssetBundle.LoadAsset<GameObject>("SonicEmoteSupport.prefab");
						CustomEmotesAPI.ImportArmature(allSurvivorDef.bodyPrefab, val, 0, true);
						val.GetComponentInChildren<BoneMapper>().scale = 1f;
					}
				}
			}
		}

		public const string MODUID = "com.ds_gaming.SonicTheHedgehog";

		public const string MODNAME = "SonicTheHedgehog";

		public const string MODVERSION = "4.0.1";

		public const string DEVELOPER_PREFIX = "DS_GAMING";

		public static SonicTheHedgehogPlugin instance;

		public static bool emoteAPILoaded;

		public static bool lookingGlassLoaded;

		public static bool riskOfOptionsLoaded;

		public static bool ancientScepterLoaded;

		public static bool loadingScreenFixLoaded;

		private void Awake()
		{
			instance = this;
			Log.Init(((BaseUnityPlugin)this).Logger);
			emoteAPILoaded = Chainloader.PluginInfos.ContainsKey("com.weliveinasociety.CustomEmotesAPI");
			Log.Message("Emote API exists? " + emoteAPILoaded);
			lookingGlassLoaded = Chainloader.PluginInfos.ContainsKey("droppod.lookingglass");
			Log.Message("Looking Glass exists? " + lookingGlassLoaded);
			riskOfOptionsLoaded = Chainloader.PluginInfos.ContainsKey("com.rune580.riskofoptions");
			Log.Message("Risk of Options exists? " + riskOfOptionsLoaded);
			ancientScepterLoaded = Chainloader.PluginInfos.ContainsKey("com.DestroyedClone.AncientScepter");
			Log.Message("Ancient Scepter exists? " + ancientScepterLoaded);
			loadingScreenFixLoaded = Chainloader.PluginInfos.ContainsKey("Nebby1999.LoadingScreenFix");
			Log.Message("Loading Screen Fix exists? " + loadingScreenFixLoaded);
			Assets.Initialize();
			if (loadingScreenFixLoaded)
			{
				SonicLoadingScreenSprite();
			}
			Config.ReadConfig();
			States.RegisterStates();
			Buffs.RegisterBuffs();
			Projectiles.RegisterProjectiles();
			Tokens.AddTokens();
			ItemDisplays.PopulateDisplays();
			SuperFormSupport.Initialize();
			DamageTypes.Initialize();
			NetworkingAPI.RegisterMessageType<SonicParryHit>();
			new SonicTheHedgehogCharacter().Initialize();
			new ContentPacks().Initialize();
			if (riskOfOptionsLoaded)
			{
				RiskOfOptionsSetup();
			}
			Hook();
		}

		private void Hook()
		{
			//IL_0008: Unknown result type (might be due to invalid IL or missing references)
			//IL_0012: Expected O, but got Unknown
			//IL_001a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0024: Expected O, but got Unknown
			//IL_002c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0036: Expected O, but got Unknown
			//IL_003e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0048: Expected O, but got Unknown
			HealthComponent.TakeDamage += new hook_TakeDamage(TakeDamage);
			CharacterBody.OnBuffFirstStackGained += new hook_OnBuffFirstStackGained(AddGrandSlamJuggleFloat);
			RecalculateStatsAPI.GetStatCoefficients += new StatHookEventHandler(SonicRecalculateStats);
			UserProfile.OnLogin += new hook_OnLogin(ConfigUnlocks);
			if (emoteAPILoaded)
			{
				EmoteSkeleton();
			}
			if (lookingGlassLoaded)
			{
				RoR2Application.onLoad = (Action)Delegate.Combine(RoR2Application.onLoad, new Action(LookingGlassSetup));
			}
		}

		private void EmoteSkeleton()
		{
			//IL_0015: 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: Expected O, but got Unknown
			object obj = <>c.<>9__12_0;
			if (obj == null)
			{
				hook_Init val = delegate(orig_Init orig)
				{
					orig.Invoke();
					foreach (SurvivorDef allSurvivorDef in SurvivorCatalog.allSurvivorDefs)
					{
						if (((Object)allSurvivorDef.bodyPrefab).name == "SonicTheHedgehog")
						{
							GameObject val2 = Assets.mainAssetBundle.LoadAsset<GameObject>("SonicEmoteSupport.prefab");
							CustomEmotesAPI.ImportArmature(allSurvivorDef.bodyPrefab, val2, 0, true);
							val2.GetComponentInChildren<BoneMapper>().scale = 1f;
						}
					}
				};
				<>c.<>9__12_0 = val;
				obj = (object)val;
			}
			SurvivorCatalog.Init += (hook_Init)obj;
		}

		private static void SonicLoadingScreenSprite()
		{
			Sprite[] array = Assets.mainAssetBundle.LoadAssetWithSubAssets<Sprite>("SonicLoadingScreen");
			int[] array2 = new int[4] { 1, 1, 1, 1 };
			SimpleSpriteAnimation val = SimpleSpriteAnimationGenerator.CreateSpriteAnimation((IEnumerable<Sprite>)array, (IEnumerable<int>)array2, 8f);
			LoadingScreenFix.AddSpriteAnimation(val);
			Log.Message("Added Sonic loading screen sprite");
		}

		public static void LookingGlassSetup()
		{
			if (Language.languagesByName.TryGetValue("en", out var value))
			{
				RegisterLookingGlassBuff(value, Buffs.boostBuff, "Sonic Boost", $"Gain <style=cIsUtility>+{50f} armor</style>. If <style=cIsDamage>health</style> is above <style=cIsDamage>90%</style>, gain <style=cIsUtility>+{65f}% movement speed</style>. Otherwise, gain <style=cIsUtility>+{35f}% movement speed</style>.");
				RegisterLookingGlassBuff(value, Buffs.superBoostBuff, "Super Sonic Boost", $"Gain <style=cIsUtility>+{100f}% movement speed</style>.");
				RegisterLookingGlassBuff(value, Buffs.ballBuff, "Sonic Ball", $"Gain <style=cIsUtility>+{100f} armor</style>.");
				RegisterLookingGlassBuff(value, Buffs.parryBuff, "Sonic Parry", $"Gain <style=cIsUtility>+{25f}% attack speed</style> and <style=cIsUtility>+{25f}% movement speed</style>.");
				RegisterLookingGlassBuff(value, Buffs.superParryDebuff, "Super Sonic Parry Debuff", $"Reduces <style=cIsUtility>armor</style> by {50f}, reduces <style=cIsUtility>attack speed and movement speed</style> by {50f}%.");
				RegisterLookingGlassBuff(value, Buffs.sonicBoomDebuff, "Sonic Boom Debuff", $"Reduces <style=cIsUtility>armor</style> by {5f}.");
				RegisterLookingGlassBuff(value, Buffs.crossSlashDebuff, "Sonic Cross Slash Debuff", $"Reduces <style=cIsUtility>armor</style> by {10f}.");
			}
		}

		private static void RegisterLookingGlassBuff(Language language, BuffDef buff, string name, string description)
		{
			LookingGlassLanguageAPI.SetupToken(language, "NAME_" + ((Object)buff).name, name);
			LookingGlassLanguageAPI.SetupToken(language, "DESCRIPTION_" + ((Object)buff).name, description);
		}

		private static void RiskOfOptionsSetup()
		{
			//IL_0029: 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_0035: 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_004c: Expected O, but got Unknown
			//IL_0047: Unknown result type (might be due to invalid IL or missing references)
			//IL_0051: Expected O, but got Unknown
			//IL_0057: Unknown result type (might be due to invalid IL or missing references)
			//IL_005c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0063: Unknown result type (might be due to invalid IL or missing references)
			//IL_006a: Unknown result type (might be due to invalid IL or missing references)
			//IL_007a: Expected O, but got Unknown
			//IL_0075: Unknown result type (might be due to invalid IL or missing references)
			//IL_007f: Expected O, but got Unknown
			//IL_0085: Unknown result type (might be due to invalid IL or missing references)
			//IL_008f: Expected O, but got Unknown
			//IL_0095: Unknown result type (might be due to invalid IL or missing references)
			//IL_009f: Expected O, but got Unknown
			//IL_00bc: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c6: Expected O, but got Unknown
			//IL_00e3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ed: Expected O, but got Unknown
			Sprite modIcon = Assets.mainAssetBundle.LoadAsset<Sprite>("texSonicIcon");
			ModSettingsManager.SetModIcon(modIcon);
			float min = -500f;
			float max = 500f;
			ModSettingsManager.AddOption((BaseOption)new SliderOption(Config.BoostMeterLocationX(), new SliderConfig
			{
				min = min,
				max = max,
				formatString = "{0:0}"
			}));
			ModSettingsManager.AddOption((BaseOption)new SliderOption(Config.BoostMeterLocationY(), new SliderConfig
			{
				min = min,
				max = max,
				formatString = "{0:0}"
			}));
			ModSettingsManager.AddOption((BaseOption)new CheckBoxOption(Config.KeyPressHomingAttack()));
			ModSettingsManager.AddOption((BaseOption)new CheckBoxOption(Config.ForceUnlockParry()));
			Config.ForceUnlockParry().SettingChanged += SonicTheHedgehogCharacter.UnlockParryConfig;
			ModSettingsManager.AddOption((BaseOption)new CheckBoxOption(Config.ForceUnlockMastery()));
			Config.ForceUnlockMastery().SettingChanged += SonicTheHedgehogCharacter.UnlockMasteryConfig;
			ModSettingsManager.AddOption((BaseOption)new CheckBoxOption(Config.EnableLogs()));
		}

		private void SonicRecalculateStats(CharacterBody self, StatHookEventArgs stats)
		{
			if (Object.op_Implicit((Object)(object)self))
			{
				if (self.HasBuff(Buffs.boostBuff))
				{
					BoostLogic.BoostStats(self, stats, PowerBoostLogic.ShouldPowerBoost(self) ? 0.65f : 0.35f);
					stats.armorAdd += 50f;
				}
				if (self.HasBuff(Buffs.superBoostBuff))
				{
					stats.baseMoveSpeedAdd += 4.25f;
					stats.moveSpeedMultAdd += 0.33f;
				}
				if (self.HasBuff(Buffs.ballBuff))
				{
					stats.armorAdd += 100f;
				}
				if (self.HasBuff(Buffs.parryBuff))
				{
					stats.attackSpeedMultAdd += 0.25f;
					stats.moveSpeedMultAdd += 0.25f;
				}
				PowerBoostLogic component = ((Component)self).GetComponent<PowerBoostLogic>();
				if (Object.op_Implicit((Object)(object)component))
				{
					((BoostLogic)component).CalculateBoostVariables();
				}
				if (self.HasBuff(Buffs.superParryDebuff))
				{
					stats.baseMoveSpeedAdd -= self.baseMoveSpeed / 2f;
					stats.armorAdd -= 50f;
					stats.baseAttackSpeedAdd -= self.baseAttackSpeed / 2f;
				}
				if (self.HasBuff(Buffs.grandSlamJuggleDebuff))
				{
					stats.moveSpeedReductionMultAdd += 1f;
				}
				if (self.HasBuff(Buffs.sonicBoomDebuff))
				{
					stats.armorAdd -= 5f * (float)self.GetBuffCount(Buffs.sonicBoomDebuff);
				}
				if (self.HasBuff(Buffs.crossSlashDebuff))
				{
					stats.armorAdd -= 10f * (float)self.GetBuffCount(Buffs.crossSlashDebuff);
				}
			}
		}

		private void TakeDamage(orig_TakeDamage orig, HealthComponent self, DamageInfo damage)
		{
			//IL_00af: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d6: 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)
			if (!NetworkServer.active)
			{
				return;
			}
			if (Object.op_Implicit((Object)(object)self))
			{
				EntityStateMachine val = EntityStateMachine.FindByCustomName(((Component)self).gameObject, "Body");
				if (Object.op_Implicit((Object)(object)val))
				{
					EntityState state = val.state;
					NetworkIdentity component = ((Component)self).gameObject.GetComponent<NetworkIdentity>();
					if (typeof(Parry).IsAssignableFrom(((object)state).GetType()) && Object.op_Implicit((Object)(object)component))
					{
						((Parry)(object)state).OnTakeDamage(damage);
						NetMessageExtensions.Send((INetMessage)(object)new SonicParryHit(component.netId, damage), (NetworkDestination)1);
					}
				}
			}
			orig.Invoke(self, damage);
			if (DamageAPI.HasModdedDamageType(ref damage.damageType, DamageTypes.grandSlamJuggle) && Object.op_Implicit((Object)(object)self) && Object.op_Implicit((Object)(object)self.body) && !((Enum)self.body.bodyFlags).HasFlag((Enum)(object)(BodyFlags)16384))
			{
				self.body.AddTimedBuff(Buffs.grandSlamJuggleDebuff, 1f, 1);
			}
		}

		private void AddGrandSlamJuggleFloat(orig_OnBuffFirstStackGained orig, CharacterBody self, BuffDef buff)
		{
			orig.Invoke(self, buff);
			if (Object.op_Implicit((Object)(object)self) && Object.op_Implicit((Object)(object)buff) && (Object)(object)buff == (Object)(object)Buffs.grandSlamJuggleDebuff)
			{
				GrandSlamJuggleFloat component = ((Component)self).GetComponent<GrandSlamJuggleFloat>();
				if (!Object.op_Implicit((Object)(object)component))
				{
					((Component)self).gameObject.AddComponent<GrandSlamJuggleFloat>();
				}
			}
		}

		private void ConfigUnlocks(orig_OnLogin orig, UserProfile self)
		{
			orig.Invoke(self);
			if (!self.HasAchievement("DS_GAMINGSONICPARRYUNLOCKABLE") && Config.ForceUnlockParry().Value)
			{
				self.AddAchievement("DS_GAMINGSONICPARRYUNLOCKABLE", true);
			}
			if (!self.HasAchievement("DS_GAMINGSONICMASTERYUNLOCKABLE") && Config.ForceUnlockMastery().Value)
			{
				self.AddAchievement("DS_GAMINGSONICMASTERYUNLOCKABLE", true);
			}
		}
	}
}
namespace SonicTheHedgehog.SkillStates
{
	public class Death : GenericCharacterDeath
	{
		protected string soundString = "Play_sonicthehedgehog_death";

		private const float destroyTime = 1.6f;

		public override void OnEnter()
		{
			((GenericCharacterDeath)this).OnEnter();
			Util.PlaySound(soundString, ((EntityState)this).gameObject);
			((EntityState)this).cameraTargetParams.cameraPivotTransform = ((EntityState)this).gameObject.transform;
		}

		public override void FixedUpdate()
		{
			//IL_001e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0023: Unknown result type (might be due to invalid IL or missing references)
			((GenericCharacterDeath)this).FixedUpdate();
			if (Object.op_Implicit((Object)(object)((EntityState)this).characterMotor))
			{
				((EntityState)this).characterMotor.velocity = Vector3.zero;
			}
			if (((EntityState)this).fixedAge >= 1.6f && NetworkServer.active)
			{
				((GenericCharacterDeath)this).DestroyBodyAsapServer();
			}
		}

		public override void OnExit()
		{
			((GenericCharacterDeath)this).DestroyModel();
			((GenericCharacterDeath)this).OnExit();
		}
	}
	public class FollowUp : BaseSkillState
	{
		protected string hitboxName = "FollowUp";

		protected DamageType damageType = (DamageType)0;

		protected float hitStopDuration;

		protected float attackRecoil;

		protected string swingSoundString = "";

		protected string hitSoundString = "";

		protected string muzzleString = "SwingCenter";

		protected GameObject swingEffectPrefab;

		protected GameObject hitEffectPrefab = Assets.meleeImpactEffect;

		protected NetworkSoundEventIndex impactSound = Assets.meleeFinalHitSoundEvent.index;

		public float duration;

		private bool hasFired;

		private float hitPauseTimer;

		private OverlapAttack attack;

		protected bool inHitPause;

		protected float stopwatch;

		protected Animator animator;

		private HitStopCachedState hitStopCachedState;

		private Vector3 storedVelocity;

		private ICharacterFlightParameterProvider flight;

		private bool effectPlayed = false;

		protected ParryFollowUpTracker followUp;

		protected virtual float launchPushForce => 400f;

		public override void OnEnter()
		{
			((BaseState)this).OnEnter();
			flight = ((Component)((EntityState)this).characterBody).GetComponent<ICharacterFlightParameterProvider>();
			followUp = ((EntityState)this).GetComponent<ParryFollowUpTracker>();
			RemoveFollowUpAttack();
			hasFired = false;
			swingSoundString = "Play_sonicthehedgehog_swing_strong";
			hitStopDuration = 0.2f;
			attackRecoil = 3f;
			duration = 1.4f / ((EntityState)this).characterBody.attackSpeed;
			((BaseState)this).StartAimMode(2f, false);
			PlayAttackAnimation();
			animator = ((EntityState)this).GetModelAnimator();
			((EntityState)this).characterBody.outOfCombatStopwatch = 0f;
			animator.SetBool("attacking", true);
			if (!Helpers.Flying(flight) && !((EntityState)this).characterMotor.isGrounded && ((EntityState)this).isAuthority)
			{
				((BaseState)this).SmallHop(((EntityState)this).characterMotor, 12f);
			}
			PrepareOverlapAttack();
			if (NetworkServer.active)
			{
				((EntityState)this).characterBody.AddBuff(Buffs.SmallArmorBoost);
			}
		}

		protected virtual void PlayAttackAnimation()
		{
			((EntityState)this).PlayAnimation("Body", "ParryFollowUp", "Slash.playbackRate", duration * 0.8f, 0f);
		}

		public override void OnExit()
		{
			if (!hasFired)
			{
				FireAttack();
			}
			if (NetworkServer.active)
			{
				((EntityState)this).characterBody.RemoveBuff(Buffs.SmallArmorBoost);
			}
			((EntityState)this).OnExit();
			animator.SetBool("attacking", false);
		}

		protected virtual void OnHitEnemyAuthority()
		{
			//IL_003b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0040: Unknown result type (might be due to invalid IL or missing references)
			//IL_0058: Unknown result type (might be due to invalid IL or missing references)
			//IL_005d: Unknown result type (might be due to invalid IL or missing references)
			if (!effectPlayed)
			{
				effectPlayed = true;
			}
			if (!inHitPause && hitStopDuration > 0f)
			{
				storedVelocity = ((EntityState)this).characterMotor.velocity;
				hitStopCachedState = ((BaseState)this).CreateHitStopCachedState(((EntityState)this).characterMotor, animator, "Slash.playbackRate");
				hitPauseTimer = hitStopDuration / ((BaseState)this).attackSpeedStat;
				inHitPause = true;
			}
		}

		private void FireAttack()
		{
			if (!hasFired)
			{
				hasFired = true;
				Util.PlayAttackSpeedSound(swingSoundString, ((EntityState)this).gameObject, ((BaseState)this).attackSpeedStat);
				if (((EntityState)this).isAuthority)
				{
					((BaseState)this).AddRecoil(-0.4f * attackRecoil, -0.3f * attackRecoil, -1f * attackRecoil, 1f * attackRecoil);
					OnFireAuthority();
				}
			}
			if (((EntityState)this).isAuthority && attack.Fire((List<HurtBox>)null))
			{
				OnHitEnemyAuthority();
			}
		}

		public override void FixedUpdate()
		{
			//IL_0037: Unknown result type (might be due to invalid IL or missing references)
			//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_00a0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a5: Unknown result type (might be due to invalid IL or missing references)
			//IL_014c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0157: Unknown result type (might be due to invalid IL or missing references)
			//IL_015c: Unknown result type (might be due to invalid IL or missing references)
			((EntityState)this).FixedUpdate();
			hitPauseTimer -= Time.fixedDeltaTime;
			if (hitPauseTimer <= 0f && inHitPause)
			{
				((BaseState)this).ConsumeHitStopCachedState(hitStopCachedState, ((EntityState)this).characterMotor, animator);
				inHitPause = false;
				((EntityState)this).characterMotor.velocity = storedVelocity;
			}
			if (!inHitPause)
			{
				stopwatch += Time.fixedDeltaTime;
			}
			else
			{
				if (Object.op_Implicit((Object)(object)((EntityState)this).characterMotor))
				{
					((EntityState)this).characterMotor.velocity = Vector3.zero;
				}
				if (Object.op_Implicit((Object)(object)animator))
				{
					animator.SetFloat("Slash.playbackRate", 0f);
				}
			}
			if (((EntityState)this).isAuthority)
			{
				((EntityState)this).characterMotor.velocity.y = Mathf.Max(((EntityState)this).characterMotor.velocity.y, -3f);
			}
			if (stopwatch >= duration * 0.4f && stopwatch <= duration * 0.6f)
			{
				attack.forceVector = ((EntityState)this).characterDirection.forward * launchPushForce;
				if (!hasFired)
				{
					Util.PlayAttackSpeedSound(swingSoundString, ((EntityState)this).gameObject, ((BaseState)this).attackSpeedStat);
					EffectManager.SimpleMuzzleFlash(Assets.followUpKickEffect, ((EntityState)this).gameObject, muzzleString, true);
				}
				if (((EntityState)this).isAuthority)
				{
					FireAttack();
				}
				hasFired = true;
			}
			if (stopwatch >= duration && ((EntityState)this).isAuthority)
			{
				((EntityState)this).outer.SetNextStateToMain();
			}
		}

		protected virtual void RemoveFollowUpAttack()
		{
			if (Object.op_Implicit((Object)(object)followUp))
			{
				followUp.RemoveFollowUpAttack();
			}
		}

		protected virtual void OnFireAuthority()
		{
		}

		public virtual void PrepareOverlapAttack()
		{
			//IL_002f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0039: Expected O, but got Unknown
			//IL_0040: Unknown result type (might be due to invalid IL or missing references)
			//IL_0045: Unknown result type (might be due to invalid IL or missing references)
			//IL_004a: Unknown result type (might be due to invalid IL or missing references)
			//IL_005b: 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_009f: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a4: Unknown result type (might be due to invalid IL or missing references)
			//IL_0105: 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)
			HitBoxGroup hitBoxGroup = null;
			Transform modelTransform = ((EntityState)this).GetModelTransform();
			if (Object.op_Implicit((Object)(object)modelTransform))
			{
				hitBoxGroup = Array.Find(((Component)modelTransform).GetComponents<HitBoxGroup>(), (HitBoxGroup element) => element.groupName == hitboxName);
			}
			attack = new OverlapAttack();
			attack.damageType = DamageTypeCombo.op_Implicit(damageType);
			attack.damageType.damageSource = (DamageSource)2;
			DamageAPI.AddModdedDamageType(ref attack.damageType, DamageTypes.launch);
			attack.attacker = ((EntityState)this).gameObject;
			attack.inflictor = ((EntityState)this).gameObject;
			attack.teamIndex = ((BaseState)this).GetTeam();
			attack.damage = 7f * ((BaseState)this).damageStat;
			attack.procCoefficient = 1f;
			attack.hitEffectPrefab = hitEffectPrefab;
			attack.hitBoxGroup = hitBoxGroup;
			attack.isCrit = ((BaseState)this).RollCrit();
			attack.impactSound = impactSound;
		}

		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)2;
		}
	}
	public class GrandSlamDash : BaseSkillState
	{
		protected string hitboxName = "Ball";

		protected DamageType damageType = (DamageType)33;

		protected float damageCoefficient = 1.4f;

		protected float procCoefficient = 0.5f;

		protected float pushForce = 0f;

		protected Vector3 bonusForce = Vector3.zero;

		protected float baseAttackStartTime = 0.5f;

		protected float attackStartTime;

		protected float attackRecoil = 3f;

		protected float hitHopVelocity = 6f;

		protected bool cancelled = false;

		protected float noTargetDistancePercentage = 0.7f;

		protected float dashSpeed;

		protected float estimatedDashTime;

		protected float dashOvershoot;

		protected HurtBox target = null;

		private Vector3 targetDirection;

		protected string chargeSoundString = "Play_sonicthehedgehog_spindash_charge";

		protected string launchSoundString = "Play_sonicthehedgehog_spindash_release";

		protected string hitSoundString = "Play_sonicthehedgehog_homing_impact";

		protected string muzzleString = "SwingCenter";

		protected GameObject swingEffectPrefab;

		protected GameObject hitEffectPrefab = Assets.meleeImpactEffect;

		protected NetworkSoundEventIndex impactSound = Assets.homingHitSoundEvent.index;

		public float duration;

		private bool hasFired;

		private OverlapAttack attack;

		protected bool inHitPause;

		protected float stopwatch;

		protected Animator animator;

		private bool hasHit = false;

		private HomingTracker homingTracker;

		public override void OnEnter()
		{
			//IL_0077: Unknown result type (might be due to invalid IL or missing references)
			//IL_007d: Unknown result type (might be due to invalid IL or missing references)
			//IL_007e: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ad: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b8: 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_00d3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d8: Unknown result type (might be due to invalid IL or missing references)
			//IL_015f: Unknown result type (might be due to invalid IL or missing references)
			//IL_016a: Unknown result type (might be due to invalid IL or missing references)
			//IL_016f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0174: Unknown result type (might be due to invalid IL or missing references)
			((BaseState)this).OnEnter();
			homingTracker = ((Component)((EntityState)this).characterBody).GetComponent<HomingTracker>();
			if (NetworkServer.active)
			{
				((EntityState)this).characterBody.AddBuff(Buffs.ballBuff);
			}
			dashSpeed = homingTracker.Speed();
			hasFired = false;
			attackStartTime = baseAttackStartTime / ((EntityState)this).characterBody.attackSpeed;
			dashOvershoot = 1.75f;
			CharacterBody characterBody = ((EntityState)this).characterBody;
			characterBody.bodyFlags = (BodyFlags)(characterBody.bodyFlags | 1);
			if (Object.op_Implicit((Object)(object)homingTracker))
			{
				target = homingTracker.GetTrackingTarget(allowTargetingLaunched: true);
			}
			Ray aimRay = ((BaseState)this).GetAimRay();
			Vector3 direction = ((Ray)(ref aimRay)).direction;
			targetDirection = ((Vector3)(ref direction)).normalized * homingTracker.MaxRange() * noTargetDistancePercentage;
			if ((Object)(object)target != (Object)null)
			{
				if (Object.op_Implicit((Object)(object)target.healthComponent) && Object.op_Implicit((Object)(object)target.healthComponent.body) && target.healthComponent.body.HasBuff(Buffs.launchedBuff))
				{
					dashOvershoot *= 2.5f;
				}
				targetDirection = ((Component)target).transform.position - ((EntityState)this).transform.position;
			}
			if (dashSpeed > 0f)
			{
				estimatedDashTime = ((Vector3)(ref targetDirection)).magnitude / dashSpeed * dashOvershoot;
			}
			else
			{
				attackStartTime *= 2f;
				estimatedDashTime = 0f;
			}
			if (((EntityState)this).isAuthority)
			{
				((BaseCharacterController)((EntityState)this).characterMotor).Motor.ForceUnground(0.1f);
			}
			if (attackStartTime >= 0.2f)
			{
				Util.PlayAttackSpeedSound(chargeSoundString, ((EntityState)this).gameObject, ((BaseState)this).attackSpeedStat);
			}
			EndChrysalis();
			hitboxName = "Ball";
			((EntityState)this).PlayAnimation("FullBody, Override", "Ball");
			animator = ((EntityState)this).GetModelAnimator();
			((EntityState)this).characterBody.outOfCombatStopwatch = 0f;
			animator.SetBool("attacking", true);
			((EntityState)this).characterMotor.disableAirControlUntilCollision = false;
			PrepareOverlapAttack();
		}

		public override void OnExit()
		{
			//IL_0008: 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)
			//IL_0010: Unknown result type (might be due to invalid IL or missing references)
			CharacterBody characterBody = ((EntityState)this).characterBody;
			characterBody.bodyFlags = (BodyFlags)(characterBody.bodyFlags & -2);
			((EntityState)this).PlayAnimation("FullBody, Override", "BufferEmpty");
			if (NetworkServer.active)
			{
				((EntityState)this).characterBody.RemoveBuff(Buffs.ballBuff);
			}
			((EntityState)this).OnExit();
			animator.SetBool("attacking", false);
		}

		protected virtual void OnHitEnemyAuthority()
		{
			//IL_0026: 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_0031: Unknown result type (might be due to invalid IL or missing references)
			if (!hasHit)
			{
				hasHit = true;
				EffectManager.SimpleEffect(Assets.homingAttackHitEffect, ((EntityState)this).gameObject.transform.position, Util.QuaternionSafeLookRotation(targetDirection), true);
			}
			SetNextState();
		}

		private void FireAttack()
		{
			//IL_0081: Unknown result type (might be due to invalid IL or missing references)
			//IL_0086: Unknown result type (might be due to invalid IL or missing references)
			if (!((EntityState)this).isAuthority)
			{
				return;
			}
			List<HurtBox> list = new List<HurtBox>();
			if (attack.Fire(list))
			{
				((BaseState)this).AddRecoil(-1f * attackRecoil, -2f * attackRecoil, -0.5f * attackRecoil, 0.5f * attackRecoil);
				if ((Object)(object)target == (Object)null)
				{
					target = list.FirstOrDefault();
				}
				((EntityState)this).characterMotor.velocity = Vector3.zero;
				OnHitEnemyAuthority();
			}
		}

		protected virtual void SetNextState()
		{
			((EntityState)this).outer.SetNextState((EntityState)(object)new GrandSlamSpin
			{
				target = target
			});
		}

		public override void FixedUpdate()
		{
			//IL_0039: 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_0056: Unknown result type (might be due to invalid IL or missing references)
			//IL_005b: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b1: 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_00c6: Unknown result type (might be due to invalid IL or missing references)
			//IL_0263: Unknown result type (might be due to invalid IL or missing references)
			//IL_0268: 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_0110: 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_0204: Unknown result type (might be due to invalid IL or missing references)
			//IL_021b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0226: Unknown result type (might be due to invalid IL or missing references)
			//IL_022b: Unknown result type (might be due to invalid IL or missing references)
			((EntityState)this).FixedUpdate();
			stopwatch += Time.fixedDeltaTime;
			if (((EntityState)this).fixedAge < attackStartTime)
			{
				((EntityState)this).characterMotor.velocity = Vector3.Lerp(((EntityState)this).characterMotor.velocity, Vector3.zero, ((EntityState)this).fixedAge / (attackStartTime * 0.6f));
			}
			else if (((EntityState)this).fixedAge < estimatedDashTime + attackStartTime && ((EntityState)this).fixedAge > attackStartTime)
			{
				if ((Object)(object)target != (Object)null)
				{
					targetDirection = ((Component)target).transform.position - ((EntityState)this).transform.position;
				}
				if (!hasFired)
				{
					hasFired = true;
					Util.PlaySound(launchSoundString, ((EntityState)this).gameObject);
					if (((EntityState)this).isAuthority)
					{
						EffectManager.SimpleEffect(Assets.homingAttackLaunchEffect, ((EntityState)this).gameObject.transform.position, Util.QuaternionSafeLookRotation(targetDirection), true);
					}
					OnLaunch();
				}
				((EntityState)this).characterDirection.forward = ((Vector3)(ref targetDirection)).normalized;
				if (((EntityState)this).fixedAge >= attackStartTime + estimatedDashTime * 0.75f)
				{
					dashSpeed = Mathf.Lerp(homingTracker.Speed(), 0f, (((EntityState)this).fixedAge - attackStartTime + estimatedDashTime * 0.75f) / (attackStartTime + estimatedDashTime));
				}
				if (dashSpeed * Time.fixedDeltaTime > ((Vector3)(ref targetDirection)).magnitude * 3f)
				{
					dashSpeed = Mathf.Max(((Vector3)(ref targetDirection)).magnitude * 3f, 15f);
				}
				((EntityState)this).characterDirection.forward = ((Vector3)(ref targetDirection)).normalized;
				((EntityState)this).characterMotor.velocity = ((Vector3)(ref targetDirection)).normalized * dashSpeed;
				FireAttack();
			}
			if (((EntityState)this).fixedAge > estimatedDashTime + attackStartTime && ((EntityState)this).isAuthority)
			{
				((EntityState)this).characterMotor.velocity = Vector3.zero;
				((EntityState)this).outer.SetNextStateToMain();
			}
		}

		protected virtual void OnLaunch()
		{
		}

		private void EndChrysalis()
		{
			JetpackController val = JetpackController.FindJetpackController(((EntityState)this).gameObject);
			if (Object.op_Implicit((Object)(object)val) && val.stopwatch >= val.duration && NetworkServer.active)
			{
				Object.Destroy((Object)(object)((Component)val).gameObject);
			}
		}

		public virtual void PrepareOverlapAttack()
		{
			//IL_002f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0039: Expected O, but got Unknown
			//IL_0040: Unknown result type (might be due to invalid IL or missing references)
			//IL_0045: Unknown result type (might be due to invalid IL or missing references)
			//IL_004a: Unknown result type (might be due to invalid IL or missing references)
			//IL_005a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0071: Unknown result type (might be due to invalid IL or missing references)
			//IL_009f: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ea: 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_0129: Unknown result type (might be due to invalid IL or missing references)
			//IL_012e: Unknown result type (might be due to invalid IL or missing references)
			HitBoxGroup hitBoxGroup = null;
			Transform modelTransform = ((EntityState)this).GetModelTransform();
			if (Object.op_Implicit((Object)(object)modelTransform))
			{
				hitBoxGroup = Array.Find(((Component)modelTransform).GetComponents<HitBoxGroup>(), (HitBoxGroup element) => element.groupName == hitboxName);
			}
			attack = new OverlapAttack();
			attack.damageType = DamageTypeCombo.op_Implicit(damageType);
			DamageAPI.AddModdedDamageType(ref attack.damageType, DamageTypes.grandSlamJuggle);
			attack.damageType.damageSource = (DamageSource)8;
			attack.attacker = ((EntityState)this).gameObject;
			attack.inflictor = ((EntityState)this).gameObject;
			attack.teamIndex = ((BaseState)this).GetTeam();
			attack.damage = damageCoefficient * ((BaseState)this).damageStat;
			attack.procCoefficient = procCoefficient;
			attack.hitEffectPrefab = hitEffectPrefab;
			attack.forceVector = bonusForce;
			attack.pushAwayForce = pushForce;
			attack.hitBoxGroup = hitBoxGroup;
			attack.isCrit = ((BaseState)this).RollCrit();
			attack.impactSound = impactSound;
		}

		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)2;
		}
	}
	public class GrandSlamFinal : BaseSkillState
	{
		protected string hitboxName = "Stomp";

		protected DamageType damageType = (DamageType)0;

		protected float damageCoefficient = 22f;

		protected float procCoefficient = 1.5f;

		protected float attackRecoil = 11f;

		protected float startUpTime = 0.5f;

		private float baseMaxAttackTime = 1f;

		protected float maxAttackTime = 0.75f;

		protected float hitStopDuration = 0.2f;

		protected float endTime = 0.5f;

		protected float baseSpeedMultiplier = 200f;

		public HurtBox target;

		protected Vector3 targetDirection;

		protected string swingSoundString = "";

		protected string hitSoundString = "Play_sonicthehedgehog_strong_impact";

		protected string muzzleString = "SwingBottom";

		protected GameObject swingEffectPrefab;

		protected GameObject hitEffectPrefab = Assets.meleeImpactEffect;

		protected NetworkSoundEventIndex impactSound = Assets.grandSlamHitSoundEvent.index;

		private float earlyExitTime;

		public float duration;

		protected bool hasFired;

		private bool hasHit;

		private float hitPauseTimer;

		private OverlapAttack attack;

		protected bool inHitPause;

		private bool hasHopped;

		protected float stopwatch;

		protected Animator animator;

		private HitStopCachedState hitStopCachedState;

		private Vector3 storedVelocity;

		private float speedMultiplier;

		private bool animationEnded = false;

		private bool effectFired = false;

		protected float startUpVelocityMax = 60f;

		protected float startUpVelocityMin = 3f;

		protected virtual float basePushForce => 1000f;

		public override void OnEnter()
		{
			//IL_002b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0031: 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)
			((BaseState)this).OnEnter();
			if (NetworkServer.active)
			{
				((EntityState)this).characterBody.AddBuff(Buffs.HiddenInvincibility);
			}
			CharacterBody characterBody = ((EntityState)this).characterBody;
			characterBody.bodyFlags = (BodyFlags)(characterBody.bodyFlags | 1);
			maxAttackTime = baseMaxAttackTime;
			hasFired = false;
			hasHit = false;
			hitboxName = "Stomp";
			((EntityState)this).PlayAnimation("FullBody, Override", "GrandSlam", "Roll.playbackRate", startUpTime * 1.15f, 0f);
			Util.PlaySound("Play_sonicthehedgehog_swing_low", ((EntityState)this).gameObject);
			animator = ((EntityState)this).GetModelAnimator();
			((EntityState)this).characterBody.outOfCombatStopwatch = 0f;
			animator.SetBool("attacking", true);
			PrepareOverlapAttack();
		}

		public override void OnExit()
		{
			//IL_0008: 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)
			//IL_0010: Unknown result type (might be due to invalid IL or missing references)
			CharacterBody characterBody = ((EntityState)this).characterBody;
			characterBody.bodyFlags = (BodyFlags)(characterBody.bodyFlags & -2);
			if (!animationEnded)
			{
				((EntityState)this).PlayAnimation("FullBody, Override", "BufferEmpty");
				((EntityState)this).PlayAnimation("Body", "Backflip");
			}
			if (NetworkServer.active)
			{
				((EntityState)this).characterBody.RemoveBuff(Buffs.HiddenInvincibility);
			}
			((EntityState)this).OnExit();
			animator.SetBool("attacking", false);
		}

		protected virtual void OnHitEnemyAuthority()
		{
			//IL_004b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0055: Unknown result type (might be due to invalid IL or missing references)
			//IL_005a: 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)
			//IL_009a: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b7: Unknown result type (might be due to invalid IL or missing references)
			if (!effectFired)
			{
				EffectManager.SimpleMuzzleFlash(Assets.grandSlamHitEffect, ((EntityState)this).gameObject, muzzleString, true);
				effectFired = true;
			}
			((BaseCharacterController)((EntityState)this).characterMotor).Motor.ForceUnground(0.1f);
			((EntityState)this).characterMotor.velocity = Vector3.up * 9f;
			hasHit = true;
			stopwatch = 0f;
			if (!inHitPause && hitStopDuration > 0f)
			{
				storedVelocity = ((EntityState)this).characterMotor.velocity;
				hitStopCachedState = ((BaseState)this).CreateHitStopCachedState(((EntityState)this).characterMotor, animator, "Slash.playbackRate");
				hitPauseTimer = hitStopDuration / ((BaseState)this).attackSpeedStat;
				inHitPause = true;
			}
		}

		private void FireAttack()
		{
			if (((EntityState)this).isAuthority && attack.Fire((List<HurtBox>)null))
			{
				((BaseState)this).AddRecoil(-2f * attackRecoil, -0.5f * attackRecoil, -0.5f * attackRecoil, 0.5f * attackRecoil);
				OnHitEnemyAuthority();
			}
		}

		public override void FixedUpdate()
		{
			//IL_0037: Unknown result type (might be due to invalid IL or missing references)
			//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_00c9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ce: Unknown result type (might be due to invalid IL or missing references)
			//IL_013b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0140: Unknown result type (might be due to invalid IL or missing references)
			//IL_0293: Unknown result type (might be due to invalid IL or missing references)
			//IL_0298: Unknown result type (might be due to invalid IL or missing references)
			//IL_0231: Unknown result type (might be due to invalid IL or missing references)
			//IL_0236: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ae: Unknown result type (might be due to invalid IL or missing references)
			//IL_01be: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c3: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c8: Unknown result type (might be due to invalid IL or missing references)
			//IL_01cc: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d1: Unknown result type (might be due to invalid IL or missing references)
			//IL_01e2: Unknown result type (might be due to invalid IL or missing references)
			//IL_01f2: Unknown result type (might be due to invalid IL or missing references)
			//IL_01f7: Unknown result type (might be due to invalid IL or missing references)
			//IL_01fc: Unknown result type (might be due to invalid IL or missing references)
			//IL_023d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0242: Unknown result type (might be due to invalid IL or missing references)
			//IL_02d6: Unknown result type (might be due to invalid IL or missing references)
			//IL_02db: Unknown result type (might be due to invalid IL or missing references)
			//IL_026d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0278: Unknown result type (might be due to invalid IL or missing references)
			//IL_027d: Unknown result type (might be due to invalid IL or missing references)
			//IL_025b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0260: Unknown result type (might be due to invalid IL or missing references)
			((EntityState)this).FixedUpdate();
			hitPauseTimer -= Time.fixedDeltaTime;
			if (hitPauseTimer <= 0f && inHitPause)
			{
				((BaseState)this).ConsumeHitStopCachedState(hitStopCachedState, ((EntityState)this).characterMotor, animator);
				inHitPause = false;
				((EntityState)this).characterMotor.velocity = storedVelocity;
				animationEnded = true;
				((EntityState)this).PlayAnimation("FullBody, Override", "BufferEmpty");
				((EntityState)this).PlayAnimation("Body", "Backflip");
			}
			if (!inHitPause)
			{
				stopwatch += Time.fixedDeltaTime;
			}
			else
			{
				if (Object.op_Implicit((Object)(object)((EntityState)this).characterMotor))
				{
					((EntityState)this).characterMotor.velocity = Vector3.zero;
				}
				if (Object.op_Implicit((Object)(object)animator))
				{
					animator.SetFloat("Swing.playbackRate", 0f);
				}
			}
			if (!((EntityState)this).isAuthority)
			{
				return;
			}
			if (!hasHit)
			{
				if (((EntityState)this).fixedAge <= startUpTime)
				{
					((EntityState)this).characterMotor.velocity = GetStartUpVelocity();
				}
				else
				{
					if (!(((EntityState)this).fixedAge <= startUpTime + maxAttackTime))
					{
						((EntityState)this).characterMotor.velocity = Vector3.zero;
						((EntityState)this).outer.SetNextStateToMain();
						return;
					}
					if (!hasFired)
					{
						hasFired = true;
						EndChrysalis();
					}
					if ((Object)(object)target != (Object)null)
					{
						Vector3 val = ((Component)target).transform.position - ((Component)((EntityState)this).characterMotor).transform.position;
						targetDirection = ((Vector3)(ref val)).normalized;
						val = ((Component)target).transform.position - ((Component)((EntityState)this).characterMotor).transform.position;
						speedMultiplier = Mathf.Clamp(((Vector3)(ref val)).magnitude * 10f, 25f, baseSpeedMultiplier);
					}
					else
					{
						speedMultiplier = baseSpeedMultiplier;
						targetDirection = Vector3.down;
					}
					if (Vector3.Dot(targetDirection, Vector3.down) < 0.3f)
					{
						targetDirection = Vector3.down;
					}
					((EntityState)this).characterMotor.velocity = targetDirection * speedMultiplier;
					FireAttack();
				}
				if (((EntityState)this).characterMotor.isGrounded && startUpTime < ((EntityState)this).fixedAge)
				{
					((EntityState)this).characterMotor.velocity = Vector3.zero;
					((EntityState)this).outer.SetNextStateToMain();
				}
			}
			else if (stopwatch >= endTime)
			{
				((EntityState)this).outer.SetNextStateToMain();
			}
		}

		protected virtual Vector3 GetStartUpVelocity()
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0024: Unknown result type (might be due to invalid IL or missing references)
			//IL_0029: 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)
			return Vector3.up * Mathf.Lerp(startUpVelocityMax, startUpVelocityMin, ((EntityState)this).fixedAge / startUpTime);
		}

		public virtual void PrepareOverlapAttack()
		{
			//IL_002f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0039: Expected O, but got Unknown
			//IL_0040: Unknown result type (might be due to invalid IL or missing references)
			//IL_0045: Unknown result type (might be due to invalid IL or missing references)
			//IL_004a: Unknown result type (might be due to invalid IL or missing references)
			//IL_005b: 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_009f: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a4: 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_00f4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f9: 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_0127: Unknown result type (might be due to invalid IL or missing references)
			HitBoxGroup hitBoxGroup = null;
			Transform modelTransform = ((EntityState)this).GetModelTransform();
			if (Object.op_Implicit((Object)(object)modelTransform))
			{
				hitBoxGroup = Array.Find(((Component)modelTransform).GetComponents<HitBoxGroup>(), (HitBoxGroup element) => element.groupName == hitboxName);
			}
			attack = new OverlapAttack();
			attack.damageType = DamageTypeCombo.op_Implicit(damageType);
			attack.damageType.damageSource = (DamageSource)8;
			DamageAPI.AddModdedDamageType(ref attack.damageType, DamageTypes.launch);
			attack.attacker = ((EntityState)this).gameObject;
			attack.inflictor = ((EntityState)this).gameObject;
			attack.teamIndex = ((BaseState)this).GetTeam();
			attack.damage = damageCoefficient * ((BaseState)this).damageStat;
			attack.procCoefficient = procCoefficient;
			attack.hitEffectPrefab = hitEffectPrefab;
			attack.forceVector = basePushForce * Vector3.down;
			attack.hitBoxGroup = hitBoxGroup;
			attack.isCrit = ((BaseState)this).RollCrit();
			attack.impactSound = impactSound;
		}

		private void EndChrysalis()
		{
			JetpackController val = JetpackController.FindJetpackController(((EntityState)this).gameObject);
			if (Object.op_Implicit((Object)(object)val) && val.stopwatch >= val.duration && NetworkServer.active)
			{
				Object.Destroy((Object)(object)((Component)val).gameObject);
			}
		}

		public override InterruptPriority GetMinimumInterruptPriority()
		{
			//IL_000d: 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)
			return (InterruptPriority)(hasHit ? 1 : 5);
		}
	}
	public class GrandSlamSpin : BaseSkillState
	{
		protected string hitboxName = "Ball";

		protected DamageType damageType = (DamageType)33;

		protected float damageCoefficient = 1.4f;

		protected float procCoefficient = 0.5f;

		protected float pushForce = 0f;

		protected Vector3 bonusForce = Vector3.up * 5f;

		protected int baseAttackCount = 4;

		protected int maxAttackCount;

		protected int attackCount;

		protected float attackRecoil = 3f;

		protected float attackDuration = 0.75f;

		public HurtBox target;

		protected string swingSoundString = "";

		protected string hitSoundString = "Play_sonicthehedgehog_melee_hit";

		protected string muzzleString = "SwingCenter";

		protected GameObject swingEffectPrefab;

		protected GameObject hitEffectPrefab = Assets.meleeImpactEffect;

		protected NetworkSoundEventIndex impactSound = Assets.meleeHitSoundEvent.index;

		private float earlyExitTime;

		public float duration;

		private bool hasFired;

		private float hitPauseTimer;

		private OverlapAttack attack;

		protected bool inHitPause;

		private bool hasHopped;

		protected float stopwatch;

		protected Animator animator;

		private HitStopCachedState hitStopCachedState;

		private Vector3 storedVelocity;

		private bool effectFired;

		public override void OnEnter()
		{
			((BaseState)this).OnEnter();
			hasFired = false;
			if (NetworkServer.active)
			{
				((EntityState)this).characterBody.AddBuff(Buffs.HiddenInvincibility);
			}
			maxAttackCount = (int)Math.Ceiling(((EntityState)this).characterBody.attackSpeed * (float)baseAttackCount);
			hitboxName = "LargeBall";
			((EntityState)this).PlayAnimation("FullBody, Override", "Ball", "Slash.playbackRate", attackDuration / (float)maxAttackCount, 0f);
			animator = ((EntityState)this).GetModelAnimator();
			((EntityState)this).characterBody.outOfCombatStopwatch = 0f;
			animator.SetBool("attacking", true);
		}

		public override void OnExit()
		{
			((EntityState)this).OnExit();
			animator.SetBool("attacking", false);
			if (NetworkServer.active)
			{
				((EntityState)this).characterBody.RemoveBuff(Buffs.HiddenInvincibility);
			}
			((EntityState)this).PlayAnimation("FullBody, Override", "BufferEmpty");
		}

		protected virtual void OnHitEnemyAuthority()
		{
			//IL_0015: 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_001f: Unknown result type (might be due to invalid IL or missing references)
			//IL_002a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0034: Unknown result type (might be due to invalid IL or missing references)
			//IL_0039: Unknown result type (might be due to invalid IL or missing references)
			//IL_0043: Unknown result type (might be due to invalid IL or missing references)
			//IL_0048: Unknown result type (might be due to invalid IL or missing references)
			//IL_0059: Unknown result type (might be due to invalid IL or missing references)
			//IL_005e: Unknown result type (might be due to invalid IL or missing references)
			if (!effectFired)
			{
				Quaternion val = Quaternion.Lerp(Util.QuaternionSafeLookRotation(((EntityState)this).characterDirection.forward), Util.QuaternionSafeLookRotation(Vector3.up, ((EntityState)this).characterDirection.forward * -1f), 0.6f);
				EffectManager.SimpleEffect(Assets.homingAttackHitEffect, ((EntityState)this).gameObject.transform.position, val, true);
				effectFired = true;
			}
		}

		private void FireAttack()
		{
			if (((EntityState)this).isAuthority)
			{
				attackCount++;
				if (attack.Fire((List<HurtBox>)null))
				{
					((BaseState)this).AddRecoil(-1f * attackRecoil, -2f * attackRecoil, -0.5f * attackRecoil, 0.5f * attackRecoil);
					OnHitEnemyAuthority();
				}
			}
		}

		protected virtual void SetNextState()
		{
			((EntityState)this).outer.SetNextState((EntityState)(object)new GrandSlamFinal
			{
				target = target
			});
		}

		public override void FixedUpdate()
		{
			//IL_004f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0054: Unknown result type (might be due to invalid IL or missing references)
			((EntityState)this).FixedUpdate();
			stopwatch += Time.fixedDeltaTime;
			if (!((EntityState)this).isAuthority)
			{
				return;
			}
			if (((EntityState)this).fixedAge <= attackDuration || attackCount < maxAttackCount)
			{
				((EntityState)this).characterMotor.velocity = Vector3.zero;
				if (((EntityState)this).fixedAge >= attackDuration / (float)maxAttackCount * (float)(attackCount + 1))
				{
					PrepareOverlapAttack();
					FireAttack();
				}
			}
			else
			{
				SetNextState();
			}
		}

		public virtual void PrepareOverlapAttack()
		{
			//IL_0036: Unknown result type (might be due to invalid IL or missing references)
			//IL_0040: Expected O, but got Unknown
			//IL_0047: Unknown result type (might be due to invalid IL or missing references)
			//IL_004c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0051: 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_0078: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ab: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f1: 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)
			//IL_0130: Unknown result type (might be due to invalid IL or missing references)
			//IL_0135: Unknown result type (might be due to invalid IL or missing references)
			effectFired = false;
			HitBoxGroup hitBoxGroup = null;
			Transform modelTransform = ((EntityState)this).GetModelTransform();
			if (Object.op_Implicit((Object)(object)modelTransform))
			{
				hitBoxGroup = Array.Find(((Component)modelTransform).GetComponents<HitBoxGroup>(), (HitBoxGroup element) => element.groupName == hitboxName);
			}
			attack = new OverlapAttack();
			attack.damageType = DamageTypeCombo.op_Implicit(damageType);
			DamageAPI.AddModdedDamageType(ref attack.damageType, DamageTypes.grandSlamJuggle);
			attack.damageType.damageSource = (DamageSource)8;
			attack.attacker = ((EntityState)this).gameObject;
			attack.inflictor = ((EntityState)this).gameObject;
			attack.teamIndex = ((BaseState)this).GetTeam();
			attack.damage = damageCoefficient * ((BaseState)this).damageStat;
			attack.procCoefficient = procCoefficient;
			attack.hitEffectPrefab = hitEffectPrefab;
			attack.forceVector = bonusForce;
			attack.pushAwayForce = pushForce;
			attack.hitBoxGroup = hitBoxGroup;
			attack.isCrit = ((BaseState)this).RollCrit();
			attack.impactSound = impactSound;
		}

		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)5;
		}
	}
	public class HomingAttack : BaseSkillState
	{
		protected string hitboxName;

		protected DamageType damageType = (DamageType)0;

		protected float damageCoefficient;

		protected float procCoefficient;

		protected float attackStartTime;

		protected float attackEndTime;

		protected float hitStopDuration;

		protected float attackRecoil;

		protected float hitHopVelocity;

		protected bool cancelled = false;

		protected float maxHomingAttackRange;

		protected float homingAttackSpeed;

		protected float estimatedHomingAttackTime;

		protected float homingAttackOvershoot;

		protected float homingAttackEndLag;

		protected float homingAttackHitHopVelocity = 12f;

		public HurtBox target;

		private Vector3 targetDirection;

		protected bool homingAttackHit;

		protected string swingSoundString = "";

		protected string hitSoundString = "";

		protected string homingAttackSoundString = "Play_sonicthehedgehog_homing_attack";

		protected string muzzleString;

		protected GameObject swingEffectPrefab;

		protected GameObject hitEffectPrefab = Assets.meleeImpactEffect;

		protected NetworkSoundEventIndex impactSound = Assets.meleeHitSoundEvent.index;

		protected GameObject homingAttackEffect;

		public float duration;

		private bool hasFired;

		private float hitPauseTimer;

		private OverlapAttack attack;

		protected bool inHitPause;

		private bool hasHopped;

		protected float stopwatch;

		protected Animator animator;

		private HitStopCachedState hitStopCachedState;

		private Vector3 storedVelocity;

		private bool animationEnded = false;

		private ICharacterFlightParameterProvider flight;

		private HomingTracker homingTracker;

		private bool effectPlayed = false;

		protected virtual float launchPushForce => 250f;

		protected virtual float baseHomingAttackEndLag => 0.3f;

		public static event Action<HomingAttack, HurtBox> onAuthorityHitEnemy;

		public override void OnEnter()
		{
			//IL_00ad: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b4: 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_00bf: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ec: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f1: 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)
			//IL_01b7: Unknown result type (might be due to invalid IL or missing references)
			//IL_01bc: Unknown result type (might be due to invalid IL or missing references)
			//IL_0130: Unknown result type (might be due to invalid IL or missing references)
			//IL_0135: Unknown result type (might be due to invalid IL or missing references)
			//IL_0154: Unknown result type (might be due to invalid IL or missing references)
			//IL_015a: Unknown result type (might be due to invalid IL or missing references)
			//IL_015f: Unknown result type (might be due to invalid IL or missing references)
			((BaseState)this).OnEnter();
			flight = ((Component)((EntityState)this).characterBody).GetComponent<ICharacterFlightParameterProvider>();
			homingTracker = ((Component)((EntityState)this).characterBody).GetComponent<HomingTracker>();
			hasFired = false;
			maxHomingAttackRange = homingTracker.MaxRange();
			homingAttackSpeed = homingTracker.Speed();
			homingAttackOvershoot = 1.4f;
			if (NetworkServer.active)
			{
				((EntityState)this).characterBody.AddBuff(Buffs.ballBuff);
			}
			damageCoefficient = 6f;
			procCoefficient = 1f;
			attackRecoil = 3f;
			hitStopDuration = 0.1f;
			CharacterBody characterBody = ((EntityState)this).characterBody;
			characterBody.bodyFlags = (BodyFlags)(characterBody.bodyFlags | 1);
			targetDirection = Vector3.zero;
			if ((Object)(object)target != (Object)null)
			{
				targetDirection = ((Component)target).transform.position - ((EntityState)this).transform.position;
			}
			Util.PlaySound(homingAttackSoundString, ((EntityState)this).gameObject);
			if (((EntityState)this).isAuthority)
			{
				((BaseCharacterController)((EntityState)this).characterMotor).Motor.ForceUnground(0.1f);
				if (targetDirection != Vector3.zero)
				{
					EffectManager.SimpleEffect(Assets.homingAttackLaunchEffect, ((EntityState)this).gameObject.transform.position, Util.QuaternionSafeLookRotation(targetDirection), true);
				}
			}
			EndChrysalis();
			estimatedHomingAttackTime = ((Vector3)(ref targetDirection)).magnitude / homingAttackSpeed * homingAttackOvershoot;
			homingAttackEndLag = baseHomingAttackEndLag / ((BaseState)this).attackSpeedStat;
			hitboxName = "Ball";
			impactSound = Assets.homingHitSoundEvent.index;
			((EntityState)this).PlayAnimation("FullBody, Override", "Ball");
			((EntityState)this).characterMotor.disableAirControlUntilCollision = false;
			animator = ((EntityState)this).GetModelAnimator();
			((EntityState)this).characterBody.outOfCombatStopwatch = 0f;
			animator.SetBool("attacking", true);
			PrepareOverlapAttack();
		}

		public override void OnExit()
		{
			//IL_0080: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00aa: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ab: Unknown result type (might be due to invalid IL or missing references)
			if (!hasFired && !cancelled)
			{
				FireAttack();
			}
			if (!animationEnded || cancelled)
			{
				((EntityState)this).PlayAnimation("FullBody, Override", "BufferEmpty");
			}
			if (((EntityState)this).characterBody.HasBuff(Buffs.ballBuff) && NetworkServer.active)
			{
				((EntityState)this).characterBody.RemoveBuff(Buffs.ballBuff);
			}
			if (((Enum)((EntityState)this).characterBody.bodyFlags).HasFlag((Enum)(object)(BodyFlags)1))
			{
				CharacterBody characterBody = ((EntityState)this).characterBody;
				characterBody.bodyFlags = (BodyFlags)(characterBody.bodyFlags & -2);
			}
			if (Object.op_Implicit((Object)(object)homingAttackEffect))
			{
				EntityState.Destroy((Object)(object)homingAttackEffect);
			}
			((EntityState)this).OnExit();
			animator.SetBool("attacking", false);
		}

		protected virtual void PlayHomingAttackHitEffect()
		{
			//IL_0011: 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_001c: Unknown result type (might be due to invalid IL or missing references)
			EffectManager.SimpleEffect(Assets.homingAttackHitEffect, ((EntityState)this).gameObject.transform.position, Util.QuaternionSafeLookRotation(targetDirection), true);
			if (Object.op_Implicit((Object)(object)homingAttackEffect))
			{
				homingAttackEffect.transform.parent = null;
			}
		}

		protected virtual void OnHitEnemyAuthority()
		{
			//IL_0034: Unknown result type (might be due to invalid IL or missing references)
			//IL_0039: 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_00d9: 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)
			if (!effectPlayed)
			{
				PlayHomingAttackHitEffect();
				effectPlayed = true;
			}
			if (Object.op_Implicit((Object)(object)((EntityState)this).characterMotor))
			{
				((EntityState)this).characterMotor.velocity = Vector3.zero;
				if (!Flying())
				{
					((BaseState)this).SmallHop(((EntityState)this).characterMotor, homingAttackHitHopVelocity);
				}
			}
			if (NetworkServer.active)
			{
				((EntityState)this).characterBody.RemoveBuff(Buffs.ballBuff);
			}
			stopwatch = 0f;
			hasFired = true;
			hasHopped = true;
			if (!inHitPause && hitStopDuration > 0f)
			{
				storedVelocity = ((EntityState)this).characterMotor.velocity;
				hitStopCachedState = ((BaseState)this).CreateHitStopCachedState(((EntityState)this).characterMotor, animator, "Slash.playbackRate");
				hitPauseTimer = hitStopDuration / ((BaseState)this).attackSpeedStat;
				inHitPause = true;
			}
		}

		private void FireAttack()
		{
			if (!((EntityState)this).isAuthority)
			{
				return;
			}
			List<HurtBox> list = new List<HurtBox>();
			if (!attack.Fire(list))
			{
				return;
			}
			((BaseState)this).AddRecoil(-1f * attackRecoil, -2f * attackRecoil, -0.5f * attackRecoil, 0.5f * attackRecoil);
			foreach (HurtBox item in list)
			{
				if (HomingAttack.onAuthorityHitEnemy != null)
				{
					HomingAttack.onAuthorityHitEnemy(this, item);
				}
			}
			OnHitEnemyAuthority();
		}

		public override void FixedUpdate()
		{
			//IL_0037: Unknown result type (might be due to invalid IL or missing references)
			//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_00df: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e4: Unknown result type (might be due to invalid IL or missing references)
			//IL_02c1: Unknown result type (might be due to invalid IL or missing references)
			//IL_02c6: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a4: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b4: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b9: Unknown result type (might be due to invalid IL or missing references)
			//IL_01be: Unknown result type (might be due to invalid IL or missing references)
			//IL_0218: Unknown result type (might be due to invalid IL or missing references)
			//IL_0223: Unknown result type (might be due to invalid IL or missing references)
			//IL_0228: Unknown result type (might be due to invalid IL or missing references)
			//IL_0239: Unknown result type (might be due to invalid IL or missing references)
			//IL_029a: Unknown result type (might be due to invalid IL or missing references)
			//IL_02a5: Unknown result type (might be due to invalid IL or missing references)
			//IL_02aa: Unknown result type (might be due to invalid IL or missing references)
			((EntityState)this).FixedUpdate();
			hitPauseTimer -= Time.fixedDeltaTime;
			if (hitPauseTimer <= 0f && inHitPause)
			{
				((BaseState)this).ConsumeHitStopCachedState(hitStopCachedState, ((EntityState)this).characterMotor, animator);
				inHitPause = false;
				((EntityState)this).characterMotor.velocity = storedVelocity;
				animationEnded = true;
				((EntityState)this).PlayAnimation("FullBody, Override", "BufferEmpty");
				((EntityState)this).PlayAnimation("Body", "Backflip", "Slash.playbackRate", homingAttackEndLag * 2f, 0f);
			}
			if (!inHitPause)
			{
				stopwatch += Time.fixedDeltaTime;
			}
			else
			{
				if (Object.op_Implicit((Object)(object)((EntityState)this).characterMotor))
				{
					((EntityState)this).characterMotor.velocity = Vector3.zero;
				}
				if (Object.op_Implicit((Object)(object)animator))
				{
					animator.SetFloat("Swing.playbackRate", 0f);
				}
			}
			if (!((EntityState)this).isAuthority)
			{
				return;
			}
			if (hasFired)
			{
				if (stopwatch >= homingAttackEndLag)
				{
					((EntityState)this).outer.SetNextStateToMain();
				}
			}
			else if (((EntityState)this).fixedAge < estimatedHomingAttackTime)
			{
				homingAttackSpeed = homingTracker.Speed();
				if ((Object)(object)target != (Object)null)
				{
					targetDirection = ((Component)target).transform.position - ((Component)((EntityState)this).characterMotor).transform.position;
				}
				if (homingAttackSpeed * Time.fixedDeltaTime > ((Vector3)(ref targetDirection)).magnitude * 3f)
				{
					homingAttackSpeed = Mathf.Max(((Vector3)(ref targetDirection)).magnitude * 3f, 15f);
				}
				((EntityState)this).characterMotor.velocity = ((Vector3)(ref targetDirection)).normalized * homingAttackSpeed;
				((EntityState)this).characterDirection.forward = ((Vector3)(ref targetDirection)).normalized;
				if (((EntityState)this).isAuthority && ((BaseState)this).isGrounded)
				{
					((BaseCharacterController)((EntityState)this).characterMotor).Motor.ForceUnground(0.1f);
				}
				if (((EntityState)this).fixedAge > estimatedHomingAttackTime / 2.5f)
				{
					attack.forceVector = ((Vector3)(ref targetDirection)).normalized * launchPushForce;
					FireAttack();
				}
			}
			else
			{
				((EntityState)this).characterMotor.velocity = Vector3.zero;
				((EntityState)this).outer.SetNextStateToMain();
			}
		}

		private void EndChrysalis()
		{
			JetpackController val = JetpackController.FindJetpackController(((EntityState)this).gameObject);
			if (Object.op_Implicit((Object)(object)val) && val.stopwatch >= val.duration && NetworkServer.active)
			{
				Object.Destroy((Object)(object)((Component)val).gameObject);
			}
		}

		private bool Flying()
		{
			return flight != null && flight.isFlying;
		}

		public virtual void PrepareOverlapAttack()
		{
			//IL_002f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0039: Expected O, but got Unknown
			//IL_0040: Unknown result type (might be due to invalid IL or missing references)
			//IL_0045: Unknown result type (might be due to invalid IL or missing references)
			//IL_004a: Unknown result type (might be due to invalid IL or missing references)
			//IL_005b: 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_009f: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a4: Unknown result type (might be due to invalid IL or missing references)
			//IL_0107: Unknown result type (might be due to invalid IL or missing references)
			//IL_010c: Unknown result type (might be due to invalid IL or missing references)
			HitBoxGroup hitBoxGroup = null;
			Transform modelTransform = ((EntityState)this).GetModelTransform();
			if (Object.op_Implicit((Object)(object)modelTransform))
			{
				hitBoxGroup = Array.Find(((Component)modelTransform).GetComponents<HitBoxGroup>(), (HitBoxGroup element) => element.groupName == hitboxName);
			}
			attack = new OverlapAttack();
			attack.damageType = DamageTypeCombo.op_Implicit(damageType);
			attack.damageType.damageSource = (DamageSource)1;
			DamageAPI.AddModdedDamageType(ref attack.damageType, DamageTypes.launchOnKill);
			attack.attacker = ((EntityState)this).gameObject;
			attack.inflictor = ((EntityState)this).gameObject;
			attack.teamIndex = ((BaseState)this).GetTeam();
			attack.damage = damageCoefficient * ((BaseState)this).damageStat;
			attack.procCoefficient = procCoefficient;
			attack.hitEffectPrefab = hitEffectPrefab;
			attack.hitBoxGroup = hitBoxGroup;
			attack.isCrit = ((BaseState)this).RollCrit();
			attack.impactSound = impactSound;
		}

		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)2;
		}
	}
	public class IDWAttack : BaseSkillState
	{
		protected static DamageType damageType = (DamageType)131104;

		protected static float damageCoefficient = 8f;

		protected static float procCoefficient = 0.7f;

		protected static float baseAttackDuration = 1.6f;

		protected static float increasePerAdditionalStock = 0.2f;

		protected static float range = 25f;

		protected static int baseAttackCount = 8;

		protected static float pushForce = 400f;

		protected static float baseEndLag = 1.6f;

		protected float endLag;

		public HurtBox target = null;

		protected Vector3 targetPosition = Vector3.zero;

		public float attackDuration;

		public float duration;

		private bool hasFired;

		protected bool inHitPause;

		protected float stopwatch;

		protected Animator animator;

		private int maxAttackCount;

		private int attackCount;

		private bool invisible;

		private Transform modelTransform;

		private CharacterModel characterModel;

		private GameObject idwAttackEffect;

		protected BlastAttack blastAttack;

		private HitPoint[] hit;

		public override void OnEnter()
		{
			((BaseState)this).OnEnter();
			modelTransform = ((EntityState)this).GetModelTransform();
			if (Object.op_Implicit((Object)(object)modelTransform))
			{
				characterModel = ((Component)modelTransform).GetComponent<CharacterModel>();
			}
			hasFired = false;
			endLag = baseEndLag;
			if (((EntityState)this).isAuthority)
			{
				((BaseCharacterController)((EntityState)this).characterMotor).Motor.ForceUnground(0.1f);
			}
			attackDuration = baseAttackDuration * (1f + increasePerAdditionalStock * (float)(((EntityState)this).skillLocator.secondary.maxStock - 1));
			animator = ((EntityState)this).GetModelAnimator();
			((EntityState)this).characterBody.outOfCombatStopwatch = 0f;
			animator.SetBool("attacking", true);
			((EntityState)this).characterMotor.disableAirControlUntilCollision = false;
			Util.PlaySound("Play_sonicthehedgehog_idw", ((EntityState)this).gameObject);
			idwAttackEffect = Object.Instantiate<GameObject>(Assets.idwAttackEffect);
			EffectManager.SimpleMuzzleFlash(Assets.superSonicBlurEffect, ((EntityState)this).gameObject, "BlurForward", true);
			hasFired = true;
			if (Object.op_Implicit((Object)(object)characterModel))
			{
				CharacterModel obj = characterModel;
				int invisibilityCount = obj.invisibilityCount;
				obj.invisibilityCount = invisibilityCount + 1;
			}
			invisible = true;
			maxAttackCount = (int)Math.Ceiling(((EntityState)this).characterBody.attackSpeed * (float)baseAttackCount * (1f + increasePerAdditionalStock * (float)(((EntityState)this).skillLocator.secondary.maxStock - 1)));
			if (NetworkServer.active)
			{
				((EntityState)this).characterBody.AddBuff(Buffs.Intangible);
			}
			((EntityState)this).skillLocator.secondary.onSkillChanged += OnSkillChanged;
		}

		public override void OnExit()
		{
			((EntityState)this).PlayAnimation("FullBody, Override", "BufferEmpty");
			if (invisible)
			{
				if (Object.op_Implicit((Object)(object)characterModel))
				{
					CharacterModel obj = characterModel;
					int invisibilityCount = obj.invisibilityCount;
					obj.invisibilityCount = invisibilityCount - 1;
				}
				if (NetworkServer.active)
				{
					((EntityState)this).characterBody.RemoveBuff(Buffs.Intangible);
				}
			}
			if (Object.op_Implicit((Object)(object)idwAttackEffect))
			{
				Object.Destroy((Object)(object)idwAttackEffect);
			}
			((EntityState)this).OnExit();
			animator.SetBool("attacking", false);
			((EntityState)this).skillLocator.secondary.onSkillChanged -= OnSkillChanged;
		}

		public override void FixedUpdate()
		{
			//IL_008c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0075: Unknown result type (might be due to invalid IL or missing references)
			//IL_007a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0230: Unknown result type (might be due to invalid IL or missing references)
			//IL_0235: Unknown result type (might be due to invalid IL or missing references)
			//IL_01cb: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d5: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ec: Unknown result type (might be due to invalid IL or missing references)
			//IL_01f6: Unknown result type (might be due to invalid IL or missing references)
			//IL_01fb: Unknown result type (might be due to invalid IL or missing references)
			((EntityState)this).FixedUpdate();
			stopwatch += Time.fixedDeltaTime;
			if (((EntityState)this).fixedAge <= attackDuration && ((EntityState)this).fixedAge > attackDuration / (float)maxAttackCount * (float)(attackCount + 1))
			{
				if ((Object)(object)target != (Object)null)
				{
					targetPosition = ((Component)target).transform.position;
				}
				idwAttackEffect.transform.position = targetPosition;
				Util.PlaySound("Play_sonicthehedgehog_idw_hit", ((EntityState)this).gameObject);
				if (((EntityState)this).isAuthority)
				{
					PrepareBlastAttack();
					FireBlastAttack();
				}
				attackCount++;
			}
			else if (((EntityState)this).fixedAge > attackDuration && invisible)
			{
				EffectManager.SimpleMuzzleFlash(Assets.superSonicBlurEffect, ((EntityState)this).gameObject, "BlurSide", true);
				idwAttackEffect.GetComponentInChildren<ParticleSystem>().Stop();
				if (Object.op_Implicit((Object)(object)characterModel))
				{
					CharacterModel obj = characterModel;
					int invisibilityCount = obj.invisibilityCount;
					obj.invisibilityCount = invisibilityCount - 1;
				}
				invisible = false;
				if (NetworkServer.active)
				{
					((EntityState)this).characterBody.RemoveBuff(Buffs.Intangible);
				}
				Util.PlaySound("Play_sonicthehedgehog_idw_end", ((EntityState)this).gameObject);
				endLag = baseEndLag / ((EntityState)this).characterBody.attackSpeed;
				((EntityState)this).PlayAnimation("FullBody, Override", "IDWEnd", "Slash.playbackRate", endLag, 0f);
				((EntityState)this).characterDirection.forward = ((EntityState)this).characterDirection.forward * -1f;
				((EntityState)this).characterDirection.moveVector = ((EntityState)this).characterDirection.moveVector * -1f;
			}
			else if (((EntityState)this).isAuthority && ((EntityState)this).fixedAge > attackDuration + endLag)
			{
				((EntityState)this).characterMotor.velocity = Vector3.zero;
				((EntityState)this).outer.SetNextStateToMain();
			}
		}

		public virtual void PrepareBlastAttack()
		{
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			//IL_000c: Expected O, but got Unknown
			//IL_0033: Unknown result type (might be due to invalid IL or missing references)
			//IL_0038: Unknown result type (might be due to invalid IL or missing references)
			//IL_0097: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ac: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bd: Unknown result type (might be due to invalid IL or missing references)
			//IL_00df: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f0: Unknown result type (might be due to invalid IL or missing references)
			blastAttack = new BlastAttack();
			blastAttack.radius = range;
			blastAttack.procCoefficient = procCoefficient;
			blastAttack.position = targetPosition;
			blastAttack.attacker = ((EntityState)this).gameObject;
			blastAttack.crit = Util.CheckRoll(((EntityState)this).characterBody.crit, ((EntityState)this).characterBody.master);
			blastAttack.baseDamage = ((EntityState)this).characterBody.damage * damageCoefficient;
			blastAttack.falloffModel = (FalloffModel)0;
			blastAttack.damageType = DamageTypeCombo.op_Implicit(damageType);
			blastAttack.damageType.damageSource = (DamageSource)2;
			blastAttack.baseForce = 0f - pushForce;
			blastAttack.teamIndex = ((EntityState)this).teamComponent.teamIndex;
			blastAttack.attackerFiltering = (AttackerFiltering)2;
		}

		protected virtual void FireBlastAttack()
		{
			//IL_0008: Unknown result type (might be due to invalid IL or missing references)
			hit = blastAttack.Fire().hitPoints;
		}

		public virtual void OnSkillChanged(GenericSkill skill)
		{
			//IL_000c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0011: Unknown result type (might be due to invalid IL or missing references)
			Type typeFromHandle = typeof(IDWAttackSearch);
			SerializableEntityStateType activationState = skill.activationState;
			if (!typeFromHandle.IsAssignableFrom(((SerializableEntityStateType)(ref activationState)).stateType) && (Object)(object)skill.skillDef != (Object)(object)SuperSkillReplacer.afterIDWAttack)
			{
				((EntityState)this).outer.SetNextStateToMain();
			}
		}

		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)5;
		}

		public override void OnSerialize(NetworkWriter writer)
		{
			//IL_0010: Unknown result type (might be due to invalid IL or missing references)
			((BaseSkillState)this).OnSerialize(writer);
			NetworkExtensions.Write(writer, HurtBoxReference.FromHurtBox(target));
		}

		public override void OnDeserialize(NetworkReader reader)
		{
			//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)
			((BaseSkillState)this).OnDeserialize(reader);
			HurtBoxReference val = NetworkExtensions.ReadHurtBoxReference(reader);
			target = ((HurtBoxReference)(ref val)).ResolveHurtBox();
		}
	}
	public class IDWAttackSearch : BaseSkillState
	{
		protected static float baseSearchTime = 1f;

		protected float searchTime;

		protected HurtBox target = null;

		protected bool targetLocked = false;

		protected Vector3 targetPosition = Vector3.zero;

		protected string chargeSoundString = "Play_sonicthehedgehog_spindash_charge";

		protected string launchSoundString = "Play_sonicthehedgehog_spindash_release";

		protected string hitSoundString = "Play_sonicthehedgehog_homing_impact";

		protected string muzzleString = "SwingCenter";

		public float duration;

		protected bool inHitPause;

		protected float stopwatch;

		protected Animator animator;

		private HomingTracker homingTracker;

		public override void OnEnter()
		{
			((BaseState)this).OnEnter();
			homingTracker = ((Component)((EntityState)this).characterBody).GetComponent<HomingTracker>();
			searchTime = baseSearchTime / ((EntityState)this).characterBody.attackSpeed;
			SearchForTarget();
			if (((EntityState)this).isAuthority)
			{
				((BaseCharacterController)((EntityState)this).characterMotor).Motor.ForceUnground(0.1f);
			}
			((EntityState)this).PlayAnimation("FullBody, Override", "IDWStart", "Slash.playbackRate", searchTime, 0f);
			animator = ((EntityState)this).GetModelAnimator();
			((EntityState)this).characterBody.outOfCombatStopwatch = 0f;
			animator.SetBool("attacking", true);
			((EntityState)this).characterMotor.disableAirControlUntilCollision = false;
			Util.PlaySound("Play_sonicthehedgehog_swing", ((EntityState)this).gameObject);
			((BaseState)this).StartAimMode(searchTime, false);
		}

		public override void OnExit()
		{
			((EntityState)this).PlayAnimation("FullBody, Override", "BufferEmpty");
			((EntityState)this).OnExit();
			animator.SetBool("attacking", false);
		}

		public override void FixedUpdate()
		{
			//IL_0065: Unknown result type (might be due to invalid IL or missing references)
			//IL_006a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0082: 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_0114: Unknown result type (might be due to invalid IL or missing references)
			//IL_0119: Unknown result type (might be due to invalid IL or missing references)
			((EntityState)this).FixedUpdate();
			stopwatch += Time.fixedDeltaTime;
			if (!Forms.GetIsInForm(((EntityState)this).characterBody, SuperFormDef.superFormDef))
			{
				((EntityState)this).outer.SetNextStateToMain();
			}
			else if (((EntityState)this).fixedAge <= searchTime)
			{
				((EntityState)this).characterMotor.velocity = Vector3.Lerp(((EntityState)this).characterMotor.velocity, Vector3.zero, ((EntityState)this).fixedAge / (searchTime * 0.8f));
				if ((Object)(object)target == (Object)null && !targetLocked)
				{
					SearchForTarget();
				}
			}
			else if (targetLocked && HasValidSkill())
			{
				((EntityState)this).outer.SetNextState((EntityState)(object)new IDWAttack
				{
					target = target
				});
			}
			else if (((EntityState)this).isAuthority && ((EntityState)this).fixedAge > searchTime)
			{
				((EntityState)this).characterMotor.velocity = Vector3.zero;
				((EntityState)this).outer.SetNextStateToMain();
			}
		}

		protected virtual bool HasValidSkill()
		{
			//IL_000c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0011: Unknown result type (might be due to invalid IL or missing references)
			SerializableEntityStateType activationState = ((EntityState)this).skillLocator.secondary.activationState;
			return ((SerializableEntityStateType)(ref activationState)).stateType == ((object)this).GetType() || (Object)(object)((EntityState)this).skillLocator.secondary.skillDef == (Object)(object)SuperSkillReplacer.afterIDWAttack;
		}

		private void TargetLocked()
		{
			targetLocked = true;
			SuperSkillReplacer superSkillReplacer = default(SuperSkillReplacer);
			if (((EntityState)this).isAuthority && ((EntityState)this).gameObject.TryGetComponent<SuperSkillReplacer>(ref superSkillReplacer))
			{
				superSkillReplacer.IDWAttackActivated();
			}
		}

		private void SearchForTarget()
		{
			if (Object.op_Implicit((Object)(object)homingTracker))
			{
				target = homingTracker.GetTrackingTarget(allowTargetingLaunched: true);
				if ((Object)(object)target != (Object)null)
				{
					TargetLocked();
				}
			}
		}

		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)5;
		}
	}
	public class NewBoost : Boost
	{
		private string jumpSoundString = "Play_sonicthehedgehog_jump";

		private const float boostChangeCooldown = 0.4f;

		private float boostChangeCooldownTimer;

		private bool boostChangeEffect;

		protected override BuffDef buff => Buffs.boostBuff;

		public override void OnEnter()
		{
			//IL_000e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0018: Expected O, but got Unknown
			((EntityState)this).characterMotor.onHitGroundAuthority += new HitGroundDelegate(OnHitGround);
			((Boost)this).OnEnter();
			if (Object.op_Implicit((Object)(object)((EntityState)this).modelLocator))
			{
				((EntityState)this).modelLocator.normalizeToFloor = true;
			}
			if (base.airBoosting)
			{
				((EntityState)this).characterMotor.disableAirControlUntilCollision = false;
			}
		}

		public override void FixedUpdate()
		{
			((Boost)this).FixedUpdate();
			if (boostChangeCooldownTimer > 0f)
			{
				boostChangeCooldownTimer -= Time.fixedDeltaTime;
			}
			if (boostChangeCooldownTimer <= 0f && (((PowerBoostLogic)(object)base.boostLogic).powerBoosting ^ PowerBoostLogic.ShouldPowerBoost(((EntityState)this).healthComponent)))
			{
				((Boost)this).RemoveBoostVFX();
				boostChangeEffect = true;
				((Boost)this).CreateBoostVFX();
			}
		}

		public override void OnExit()
		{
			//IL_002b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0035: Expected O, but got Unknown
			if (Object.op_Implicit((Object)(object)((EntityState)this).modelLocator))
			{
				((EntityState)this).modelLocator.normalizeToFloor = false;
			}
			((EntityState)this).characterMotor.onHitGroundAuthority -= new HitGroundDelegate(OnHitGround);
			((Boost)this).OnExit();
		}

		public override void ProcessJump()
		{
			if (((EntityState)this).isAuthority && ((BaseCharacterMain)this).hasCharacterMotor && ((GenericCharacterMain)this).jumpInputReceived && Object.op_Implicit((Object)(object)((EntityState)this).characterBody) && ((EntityState)this).characterMotor.jumpCount < ((EntityState)this).characterBody.maxJumpCount)
			{
				Util.PlaySound(jumpSoundString, ((EntityState)this).gameObject);
				((BaseCharacterMain)this).modelAnimator.SetBool("isBall", true);
			}
			((GenericCharacterMain)this).ProcessJump();
		}

		private void OnHitGround(ref HitGroundInfo hitGroundInfo)
		{
			if (((BaseCharacterMain)this).modelAnimator.GetBool("isBall"))
			{
				((BaseCharacterMain)this).modelAnimator.SetBool("isBall", false);
			}
		}

		protected override void CreateBoostVFX()
		{
			((PowerBoostLogic)(object)base.boostLogic).UpdatePowerBoosting();
			((Boost)this).CreateBoostVFX();
			boostChangeCooldownTimer = 0.4f;
			boostChangeEffect = false;
		}

		public override Material GetOverlayMaterial()
		{
			if (((PowerBoostLogic)(object)base.boostLogic).powerBoosting)
			{
				return ((Boost)this).GetOverlayMaterial();
			}
			return null;
		}

		public override GameObject GetAuraPrefab()
		{
			if (((PowerBoostLogic)(object)base.boostLogic).powerBoosting)
			{
				return ((Boost)this).GetAuraPrefab();
			}
			return null;
		}

		public override GameObject GetFlashPrefab()
		{
			if (((PowerBoostLogic)(object)base.boostLogic).powerBoosting)
			{
				return ((Boost)this).GetFlashPrefab();
			}
			return Assets.boostFlashEffect;
		}

		public override string GetSoundString()
		{
			if (boostChangeEffect)
			{
				return "Play_sonicthehedgehog_boost_change";
			}
			return "Play_hedgehogutils_boost";
		}
	}
	public class BoostIdle : BoostIdle
	{
		public override void OnEnter()
		{
			((BoostIdle)this).OnEnter();
			if (Object.op_Implicit((Object)(object)((EntityState)this).modelLocator))
			{
				((EntityState)this).modelLocator.normalizeToFloor = true;
			}
		}

		public override void OnExit()
		{
			if (Object.op_Implicit((Object)(object)((EntityState)this).modelLocator))
			{
				((EntityState)this).modelLocator.normalizeToFloor = false;
			}
			((BoostIdle)this).OnExit();
		}
	}
	public class SonicBrake : Brake
	{
		public override void OnEnter()
		{
			((Brake)this).OnEnter();
			if (Object.op_Implicit((Object)(object)((EntityState)this).modelLocator))
			{
				((EntityState)this).modelLocator.normalizeToFloor = true;
			}
			if (((EntityState)this).GetModelAnimator().GetFloat("isSuperFloat") == 0f)
			{
				Util.PlaySound("Play_sonicthehedgehog_brake", ((EntityState)this).gameObject);
			}
			else
			{
				Util.PlaySound("Play_sonicthehedgehog_swing_low", ((EntityState)this).gameObject);
			}
		}

		public override void OnExit()
		{
			if (Object.op_Implicit((Object)(object)((EntityState)this).modelLocator))
			{
				((EntityState)this).modelLocator.normalizeToFloor = false;
			}
			((EntityState)this).OnExit();
		}
	}
	public class NewScepterBoost : ScepterBoostBase
	{
		private const float boostChangeCooldown = 0.4f;

		private float boostChangeCooldownTimer;

		private bool boostChangeEffect;

		protected override BuffDef buff => Buffs.boostBuff;

		public override void FixedUpdate()
		{
			base.FixedUpdate();
			if (boostChangeCooldownTimer > 0f)
			{
				boostChangeCooldownTimer -= Time.fixedDeltaTime;
			}
			if (boostChangeCooldownTimer <= 0f && (((PowerBoostLogic)(object)((Boost)this).boostLogic).powerBoosting ^ PowerBoostLogic.ShouldPowerBoost(((EntityState)this).healthComponent)))
			{
				((Boost)this).RemoveBoostVFX();
				boostChangeEffect = true;
				((Boost)this).CreateBoostVFX();
			}
		}

		protected override void CreateBoostVFX()
		{
			((PowerBoostLogic)(object)((Boost)this).boostLogic).UpdatePowerBoosting();
			((Boost)this).CreateBoostVFX();
			boostChangeCooldownTimer = 0.4f;
			boostChangeEffect = false;
		}

		public override Material GetOverlayMaterial()
		{
			if (((PowerBoostLogic)(object)((Boost)this).boostLogic).powerBoosting)
			{
				return ((Boost)this).GetOverlayMaterial();
			}
			return null;
		}

		public override GameObject GetAuraPrefab()
		{
			if (((PowerBoostLogic)(object)((Boost)this).boostLogic).powerBoosting)
			{
				return Assets.scepterPowerBoostAuraEffect;
			}
			return null;
		}

		public override GameObject GetFlashPrefab()
		{
			if (((PowerBoostLogic)(object)((Boost)this).boostLogic).powerBoosting)
			{
				return Assets.scepterPowerBoostFlashEffect;
			}
			return Assets.scepterBoostFlashEffect;
		}

		public override string GetSoundString()
		{
			if (boostChangeEffect)
			{
				return "Play_sonicthehedgehog_boost_change";
			}
			return "Play_hedgehogutils_strong_boost";
		}
	}
	public class ScepterBoostBase : Boost
	{
		private string jumpSoundString = "Play_sonicthehedgehog_jump";

		protected OverlapAttack attack;

		protected float attackTimer;

		protected static float attacksPerSecond = 15f;

		protected virtual string hitBoxName => "Ball";

		protected virtual float launchForce => 400f;

		public override void OnEnter()
		{
			//IL_001c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0026: Expected O, but got Unknown
			((Boost)this).OnEnter();
			PrepareOverlapAttack();
			((EntityState)this).characterMotor.onHitGroundAuthority += new HitGroundDelegate(OnHitGround);
			if (Object.op_Implicit((Object)(object)((EntityState)this).modelLocator))
			{
				((EntityState)this).modelLocator.normalizeToFloor = true;
			}
			if (base.airBoosting)
			{
				((EntityState)this).characterMotor.disableAirControlUntilCollision = false;
			}
		}

		public override void FixedUpdate()
		{
			//IL_0067: Unknown result type (might be due to invalid IL or missing references)
			//IL_0078: Unknown result type (might be due to invalid IL or missing references)
			//IL_007d: Unknown result type (might be due to invalid IL or missing references)
			((Boost)this).FixedUpdate();
			if (((EntityState)this).isAuthority)
			{
				attackTimer += Time.fixedDeltaTime;
				if (attackTimer > 1f / attacksPerSecond)
				{
					attackTimer %= 1f / attacksPerSecond;
					attack.forceVector = ((EntityState)this).characterDirection.forward * (launchForce * 0.8f);
					attack.isCrit = ((BaseState)this).RollCrit();
					attack.damage = 9f * ((EntityState)this).characterBody.moveSpeed / 24f * ((EntityState)this).characterBody.damage;
					attack.Fire((List<HurtBox>)null);
				}
			}
		}

		public override void OnExit()
		{
			//IL_002b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0035: Expected O, but got Unknown
			if (Object.op_Implicit((Object)(object)((EntityState)this).modelLocator))
			{
				((EntityState)this).modelLocator.normalizeToFloor = false;
			}
			((EntityState)this).characterMotor.onHitGroundAuthority -= new HitGroundDelegate(OnHitGround);
			((Boost)this).OnExit();
		}

		public override void ProcessJump()
		{
			if (((EntityState)this).isAuthority && ((BaseCharacterMain)this).hasCharacterMotor && ((GenericCharacterMain)this).jumpInputReceived && Object.op_Implicit((Object)(object)((EntityState)this).characterBody) && ((EntityState)this).characterMotor.jumpCount < ((EntityState)this).characterBody.maxJumpCount)
			{
				Util.PlaySound(jumpSoundString, ((EntityState)this).gameObject);
				((BaseCharacterMain)this).modelAnimator.SetBool("isBall", true);
			}
			((GenericCharacterMain)this).ProcessJump();
		}

		private void OnHitGround(ref HitGroundInfo hitGroundInfo)
		{
			if (((BaseCharacterMain)this).modelAnimator.GetBool("isBall"))
			{
				((BaseCharacterMain)this).modelAnimator.SetBool("isBall", false);
			}
		}

		public override GameObject GetAuraPrefab()
		{
			return Assets.scepterPowerBoostAuraEffect;
		}

		public override GameObject GetFlashPrefab()
		{
			return Assets.scepterPowerBoostFlashEffect;
		}

		public override string GetSoundString()
		{
			return "Play_hedgehogutils_strong_boost";
		}

		public virtual void PrepareOverlapAttack()
		{
			//IL_002f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0039: Expected O, but got Unknown
			//IL_0040: Unknown result type (might be due to invalid IL or missing references)
			//IL_0045: Unknown result type (might be due to invalid IL or missing references)
			//IL_0056: Unknown result type (might be due to invalid IL or missing references)
			//IL_0066: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b1: Unknown result type (might be due to invalid IL or missing references)
			//IL_0