Decompiled source of BossMakerAPI v0.10.3

BepInEx/plugins/BossMakerAPI/BossMakerAPI.Contracts.dll

Decompiled a day ago
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Diagnostics;
using System.Globalization;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Security.Cryptography;
using System.Text;
using System.Text.RegularExpressions;
using Microsoft.CodeAnalysis;
using UnityEngine;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: InternalsVisibleTo("BossMakerAPI")]
[assembly: InternalsVisibleTo("BossMakerAPI.Tests")]
[assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")]
[assembly: AssemblyCompany("BossMakerAPI contributors")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("0.10.3.0")]
[assembly: AssemblyInformationalVersion("0.10.3")]
[assembly: AssemblyProduct("BossMakerAPI")]
[assembly: AssemblyTitle("BossMakerAPI.Contracts")]
[assembly: AssemblyVersion("0.2.0.0")]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[Embedded]
	[AttributeUsage(AttributeTargets.Class | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Parameter | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter, AllowMultiple = false, Inherited = false)]
	internal sealed class NullableAttribute : Attribute
	{
		public readonly byte[] NullableFlags;

		public NullableAttribute(byte P_0)
		{
			NullableFlags = new byte[1] { P_0 };
		}

		public NullableAttribute(byte[] P_0)
		{
			NullableFlags = P_0;
		}
	}
	[CompilerGenerated]
	[Embedded]
	[AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Method | AttributeTargets.Interface | AttributeTargets.Delegate, AllowMultiple = false, Inherited = false)]
	internal sealed class NullableContextAttribute : Attribute
	{
		public readonly byte Flag;

		public NullableContextAttribute(byte P_0)
		{
			Flag = P_0;
		}
	}
	[CompilerGenerated]
	[Embedded]
	[AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)]
	internal sealed class RefSafetyRulesAttribute : Attribute
	{
		public readonly int Version;

		public RefSafetyRulesAttribute(int P_0)
		{
			Version = P_0;
		}
	}
}
namespace HowToFish.BossMaker
{
	public enum BossActionKind
	{
		StatMultiplier,
		SpawnMinions,
		ToggleVisualNode,
		SetVisualScale,
		PlayAudio,
		SpawnVisualEffect,
		AreaDamage,
		Force,
		Dash
	}
	public abstract class BossActionDefinition
	{
		public abstract BossActionKind Kind { get; }

		public string Id { get; set; } = string.Empty;
	}
	public sealed class StatMultiplierAction : BossActionDefinition
	{
		public override BossActionKind Kind => BossActionKind.StatMultiplier;

		public float? DamageMultiplier { get; set; }

		public float? MovementSpeedMultiplier { get; set; }

		public float? AttackCooldownMultiplier { get; set; }

		public float? DashForceMultiplier { get; set; }

		public float? DashIntervalMultiplier { get; set; }

		public string ModifierId { get; set; } = string.Empty;

		public BossModifierLifetime Lifetime { get; set; }

		public float DurationSeconds { get; set; }
	}
	public sealed class SpawnMinionsAction : BossActionDefinition
	{
		public override BossActionKind Kind => BossActionKind.SpawnMinions;

		public string? TemplateName { get; set; }

		public string? RegisteredBossId { get; set; }

		public int Count { get; set; } = 1;

		public float SpawnRadius { get; set; } = 4f;

		public int MaxAliveFromThisAction { get; set; } = 1;

		public string GroupId { get; set; } = "default";

		public MinionCleanupPolicy CleanupPolicy { get; set; } = MinionCleanupPolicy.Persist;

		public float LifetimeSeconds { get; set; }

		public BossPlacementDefinition? Placement { get; set; }

		public BossFormationDefinition? Formation { get; set; }
	}
	public sealed class ToggleVisualNodeAction : BossActionDefinition
	{
		public override BossActionKind Kind => BossActionKind.ToggleVisualNode;

		public string RelativeTransformPath { get; set; } = string.Empty;

		public bool Enabled { get; set; } = true;

		public bool Persistent { get; set; } = true;
	}
	public sealed class SetVisualScaleAction : BossActionDefinition
	{
		public override BossActionKind Kind => BossActionKind.SetVisualScale;

		public float ScaleMultiplier { get; set; } = 1f;

		public bool Persistent { get; set; } = true;
	}
	public sealed class PlayAudioAction : BossActionDefinition
	{
		public override BossActionKind Kind => BossActionKind.PlayAudio;

		public AudioClip? Clip { get; set; }

		public float Volume { get; set; } = 1f;

		public float SpatialBlend { get; set; } = 1f;
	}
	public enum BossVisualEffectAnchor
	{
		Boss,
		AbilityOrigin,
		TargetPosition,
		AbilityEndpoint
	}
	public sealed class SpawnVisualEffectAction : BossActionDefinition
	{
		public override BossActionKind Kind => BossActionKind.SpawnVisualEffect;

		public GameObject? Prefab { get; set; }

		public BossVisualEffectAnchor Anchor { get; set; }

		public bool ParentToBoss { get; set; } = true;

		public bool AlignToAbilityDirection { get; set; }

		public Vector3 LocalOffset { get; set; } = Vector3.zero;

		public Vector3 LocalEulerAngles { get; set; } = Vector3.zero;

		public Vector3 LocalScale { get; set; } = Vector3.one;

		public float Lifetime { get; set; } = 5f;
	}
	public enum MinionCleanupPolicy
	{
		DespawnOnBossDefeat,
		DespawnOnOwnerDespawn,
		DespawnOnPhaseExit,
		Persist
	}
	public sealed class AreaDamageAction : BossActionDefinition
	{
		public override BossActionKind Kind => BossActionKind.AreaDamage;

		public int Damage { get; set; } = 1;

		public float DurationSeconds { get; set; }

		public float TickIntervalSeconds { get; set; }

		public int MaxHitsPerTarget { get; set; } = 1;

		public float VerticalTolerance { get; set; } = 4f;
	}
	public enum BossForceMode
	{
		Push,
		Pull,
		Directional
	}
	public sealed class ForceAction : BossActionDefinition
	{
		public override BossActionKind Kind => BossActionKind.Force;

		public BossForceMode Mode { get; set; }

		public float Magnitude { get; set; } = 5f;

		public float DurationSeconds { get; set; }

		public float VerticalTolerance { get; set; } = 4f;

		public float VerticalMultiplier { get; set; } = 1f;

		public float MaximumVelocityChange { get; set; } = 20f;
	}
	public sealed class DashAction : BossActionDefinition
	{
		public override BossActionKind Kind => BossActionKind.Dash;

		public float Impulse { get; set; } = 16f;

		public float VerticalImpulse { get; set; }

		public float RetainedVelocityFraction { get; set; } = 0.15f;

		public float MaximumSpeed { get; set; } = 40f;

		public float MaximumTravelDistance { get; set; }

		public float StoppingDistance { get; set; }

		public float BrakeDurationSeconds { get; set; }

		public float ExitVelocityFraction { get; set; } = 1f;
	}
	public enum BossActionExecutionStatus
	{
		Applied,
		Skipped,
		Failed
	}
	public enum BossActionResultCode
	{
		Succeeded,
		IdempotentReplay,
		NoEligibleTargets,
		BudgetExceeded,
		CapabilityUnavailable,
		PlacementUnavailable,
		AuthorityRequired,
		InvalidContext,
		Cancelled,
		ExecutionFailed
	}
	public sealed class BossActionResultSnapshot
	{
		public string EncounterId { get; }

		public string BossId { get; }

		public string ActionId { get; }

		public BossActionKind ActionKind { get; }

		public int ActionOrdinal { get; }

		public long Sequence { get; }

		public long ServerTick { get; }

		public double ServerTime { get; }

		public BossActionExecutionStatus Status { get; }

		public BossActionResultCode Code { get; }

		public int AttemptedTargets { get; }

		public int AffectedTargets { get; }

		public int SpawnedEntities { get; }

		public string? PhaseId { get; }

		public string? AbilityId { get; }

		public string Message { get; }

		public bool Succeeded => Status == BossActionExecutionStatus.Applied;

		public BossActionResultSnapshot(string encounterId, string bossId, string actionId, BossActionKind actionKind, int actionOrdinal, long sequence, long serverTick, double serverTime, BossActionExecutionStatus status, BossActionResultCode code, int attemptedTargets = 0, int affectedTargets = 0, int spawnedEntities = 0, string? phaseId = null, string? abilityId = null, string? message = null)
		{
			EncounterIdValidationResult encounterIdValidationResult = EncounterIdValidator.Validate(encounterId);
			if (!encounterIdValidationResult.IsValid)
			{
				throw new ArgumentException(encounterIdValidationResult.Message, "encounterId");
			}
			if (!BossDefinitionValidator.IsValidBossId(bossId))
			{
				throw new ArgumentException("BossId must be a normalized namespaced boss ID.", "bossId");
			}
			EncounterContractValidation.RequireSafeToken(actionId, "actionId", 128);
			if (!Enum.IsDefined(typeof(BossActionKind), actionKind))
			{
				throw new ArgumentOutOfRangeException("actionKind");
			}
			if (actionOrdinal < 0 || actionOrdinal >= 32)
			{
				throw new ArgumentOutOfRangeException("actionOrdinal");
			}
			if (sequence < 0)
			{
				throw new ArgumentOutOfRangeException("sequence");
			}
			if (serverTick < 0)
			{
				throw new ArgumentOutOfRangeException("serverTick");
			}
			if (!EncounterContractValidation.IsFinite(serverTime) || serverTime < 0.0)
			{
				throw new ArgumentOutOfRangeException("serverTime");
			}
			if (!Enum.IsDefined(typeof(BossActionExecutionStatus), status))
			{
				throw new ArgumentOutOfRangeException("status");
			}
			if (!Enum.IsDefined(typeof(BossActionResultCode), code))
			{
				throw new ArgumentOutOfRangeException("code");
			}
			if (attemptedTargets < 0 || attemptedTargets > 1024 || affectedTargets < 0 || affectedTargets > attemptedTargets || spawnedEntities < 0 || spawnedEntities > 1024)
			{
				throw new ArgumentOutOfRangeException("attemptedTargets", "Action result counts are inconsistent or exceed their bound.");
			}
			if (phaseId != null)
			{
				EncounterContractValidation.RequireSafeToken(phaseId, "phaseId", 128);
			}
			if (abilityId != null)
			{
				EncounterContractValidation.RequireSafeToken(abilityId, "abilityId", 128);
			}
			if (message != null && message.Length > 1024)
			{
				throw new ArgumentOutOfRangeException("message");
			}
			EncounterId = encounterId;
			BossId = bossId;
			ActionId = actionId;
			ActionKind = actionKind;
			ActionOrdinal = actionOrdinal;
			Sequence = sequence;
			ServerTick = serverTick;
			ServerTime = serverTime;
			Status = status;
			Code = code;
			AttemptedTargets = attemptedTargets;
			AffectedTargets = affectedTargets;
			SpawnedEntities = spawnedEntities;
			PhaseId = phaseId;
			AbilityId = abilityId;
			Message = message ?? string.Empty;
		}
	}
	public enum BossModifierLifetime
	{
		Permanent,
		UntilPhaseExit,
		UntilAbilityEnd,
		Timed
	}
	public sealed class BossActiveModifierSnapshot
	{
		public string ModifierId { get; }

		public string SourceActionId { get; }

		public long SourceSequence { get; }

		public BossModifierLifetime Lifetime { get; }

		public float? DamageMultiplier { get; }

		public float? MovementSpeedMultiplier { get; }

		public float? AttackCooldownMultiplier { get; }

		public float? DashForceMultiplier { get; }

		public float? DashIntervalMultiplier { get; }

		public string? PhaseId { get; }

		public string? AbilityId { get; }

		public double? ExpiresAtServerTime { get; }

		public BossActiveModifierSnapshot(string modifierId, string sourceActionId, long sourceSequence, BossModifierLifetime lifetime, float? damageMultiplier, float? movementSpeedMultiplier, float? attackCooldownMultiplier, string? phaseId = null, string? abilityId = null, double? expiresAtServerTime = null)
			: this(modifierId, sourceActionId, sourceSequence, lifetime, damageMultiplier, movementSpeedMultiplier, attackCooldownMultiplier, null, null, phaseId, abilityId, expiresAtServerTime)
		{
		}

		public BossActiveModifierSnapshot(string modifierId, string sourceActionId, long sourceSequence, BossModifierLifetime lifetime, float? damageMultiplier, float? movementSpeedMultiplier, float? attackCooldownMultiplier, float? dashForceMultiplier, float? dashIntervalMultiplier, string? phaseId = null, string? abilityId = null, double? expiresAtServerTime = null)
		{
			EncounterContractValidation.RequireSafeToken(modifierId, "modifierId", 128);
			EncounterContractValidation.RequireSafeToken(sourceActionId, "sourceActionId", 128);
			if (!Enum.IsDefined(typeof(BossModifierLifetime), lifetime))
			{
				throw new ArgumentOutOfRangeException("lifetime");
			}
			if (lifetime == BossModifierLifetime.Permanent)
			{
				throw new ArgumentException("Active modifier snapshots represent reversible layers and cannot use Permanent lifetime.", "lifetime");
			}
			if (sourceSequence < 0)
			{
				throw new ArgumentOutOfRangeException("sourceSequence");
			}
			ValidateMultiplier(damageMultiplier, "damageMultiplier");
			ValidateMultiplier(movementSpeedMultiplier, "movementSpeedMultiplier");
			ValidateMultiplier(attackCooldownMultiplier, "attackCooldownMultiplier");
			ValidateMultiplier(dashForceMultiplier, "dashForceMultiplier");
			ValidateMultiplier(dashIntervalMultiplier, "dashIntervalMultiplier");
			if (!damageMultiplier.HasValue && !movementSpeedMultiplier.HasValue && !attackCooldownMultiplier.HasValue && !dashForceMultiplier.HasValue && !dashIntervalMultiplier.HasValue)
			{
				throw new ArgumentException("An active modifier must change at least one supported multiplier.", "damageMultiplier");
			}
			if (phaseId != null)
			{
				EncounterContractValidation.RequireSafeToken(phaseId, "phaseId", 128);
			}
			if (abilityId != null)
			{
				EncounterContractValidation.RequireSafeToken(abilityId, "abilityId", 128);
			}
			if (expiresAtServerTime.HasValue && (!EncounterContractValidation.IsFinite(expiresAtServerTime.Value) || expiresAtServerTime.Value < 0.0))
			{
				throw new ArgumentOutOfRangeException("expiresAtServerTime");
			}
			if (lifetime == BossModifierLifetime.Timed != expiresAtServerTime.HasValue)
			{
				throw new ArgumentException("Timed modifiers require an expiry; other lifetimes cannot carry one.", "expiresAtServerTime");
			}
			if (lifetime == BossModifierLifetime.UntilPhaseExit && phaseId == null)
			{
				throw new ArgumentException("UntilPhaseExit modifiers require an owning PhaseId.", "phaseId");
			}
			if (lifetime == BossModifierLifetime.UntilAbilityEnd && (abilityId == null || sourceSequence <= 0))
			{
				throw new ArgumentException("UntilAbilityEnd modifiers require an owning AbilityId and positive source sequence.", "abilityId");
			}
			ModifierId = modifierId;
			SourceActionId = sourceActionId;
			SourceSequence = sourceSequence;
			Lifetime = lifetime;
			DamageMultiplier = damageMultiplier;
			MovementSpeedMultiplier = movementSpeedMultiplier;
			AttackCooldownMultiplier = attackCooldownMultiplier;
			DashForceMultiplier = dashForceMultiplier;
			DashIntervalMultiplier = dashIntervalMultiplier;
			PhaseId = phaseId;
			AbilityId = abilityId;
			ExpiresAtServerTime = expiresAtServerTime;
		}

		private static void ValidateMultiplier(float? value, string parameterName)
		{
			if (value.HasValue && (float.IsNaN(value.Value) || float.IsInfinity(value.Value) || value.Value < 0.01f || value.Value > 100f))
			{
				throw new ArgumentOutOfRangeException(parameterName);
			}
		}
	}
	internal static class PhaseActionIdentity
	{
		internal const int MaximumEncounterIdLength = 256;

		private const int OrdinalBits = 5;

		private const uint OrdinalMask = 31u;

		internal static int CreateActionSeed(int parentSeed, string phaseId, int actionOrdinal)
		{
			ValidatePhaseId(phaseId);
			ValidateActionOrdinal(actionOrdinal);
			return (int)(CreateScope(parentSeed, phaseId) & 0x7FFFFFE0) | actionOrdinal;
		}

		internal static int CreateMinionSeed(int parentSeed, string phaseId, int actionOrdinal, int minionIndex)
		{
			ValidatePhaseId(phaseId);
			ValidateActionOrdinal(actionOrdinal);
			ValidateMinionIndex(minionIndex);
			uint num = CreateScope(parentSeed, phaseId);
			uint num2 = (uint)((actionOrdinal << 5) | minionIndex);
			return (int)((num & 0x7FFFFC00) | num2);
		}

		internal static string CreateMinionEncounterId(string parentEncounterId, string bossId, string phaseId, int actionOrdinal, int minionIndex)
		{
			if (parentEncounterId == null)
			{
				throw new ArgumentNullException("parentEncounterId");
			}
			if (bossId == null)
			{
				throw new ArgumentNullException("bossId");
			}
			ValidatePhaseId(phaseId);
			ValidateActionOrdinal(actionOrdinal);
			ValidateMinionIndex(minionIndex);
			string text = actionOrdinal.ToString(CultureInfo.InvariantCulture);
			string text2 = minionIndex.ToString(CultureInfo.InvariantCulture);
			string text3 = parentEncounterId + ":" + phaseId + ":minion:a" + text + ":i" + text2;
			if (text3.Length <= 256)
			{
				return text3;
			}
			string text4 = DeterministicIdentityAllocator.Fnv1A(text3).ToString("x8", CultureInfo.InvariantCulture);
			string text5 = ":minion:" + text4 + ":a" + text + ":i" + text2;
			return bossId[..Math.Min(bossId.Length, 256 - text5.Length)] + text5;
		}

		private static uint CreateScope(int parentSeed, string phaseId)
		{
			uint num = ((uint)parentSeed ^ DeterministicIdentityAllocator.Fnv1A(phaseId) ^ 0x9E3779B9u) * 16777619;
			return num ^ (num >> 16);
		}

		private static void ValidatePhaseId(string phaseId)
		{
			if (string.IsNullOrEmpty(phaseId))
			{
				throw new ArgumentException("A phase ID is required.", "phaseId");
			}
		}

		private static void ValidateActionOrdinal(int actionOrdinal)
		{
			if (actionOrdinal < 0 || actionOrdinal >= 32 || (uint)actionOrdinal > 31u)
			{
				throw new ArgumentOutOfRangeException("actionOrdinal");
			}
		}

		private static void ValidateMinionIndex(int minionIndex)
		{
			if (minionIndex < 0 || minionIndex >= 32 || (uint)minionIndex > 31u)
			{
				throw new ArgumentOutOfRangeException("minionIndex");
			}
		}
	}
	public static class BossMakerMetadata
	{
		public const string ProductName = "BossMakerAPI";

		public const string AssemblyName = "BossMakerAPI";

		public const string PublicNamespace = "HowToFish.BossMaker";

		public const string PluginGuid = "com.skylin3.howtofish.bossmakerapi";

		public const string Version = "0.10.3";

		public const string TargetFramework = "netstandard2.1";
	}
	public enum BossAbilityTrigger
	{
		PhaseEnter,
		OnSpawn,
		AfterDelay,
		Interval,
		Reactive
	}
	public enum BossReactiveRearmPolicy
	{
		AfterFalse,
		AfterCooldownWhileTrue
	}
	public enum BossTargetSelectorKind
	{
		BossPosition,
		NearestPlayer,
		FarthestPlayer,
		RandomPlayer
	}
	public enum BossAbilityGeometryKind
	{
		Circle,
		Ring,
		Line,
		Cone
	}
	public sealed class BossAbilityTimelineDefinition
	{
		public float TelegraphDurationSeconds { get; set; } = 1f;

		public float ResolveDurationSeconds { get; set; }

		public float RecoveryDurationSeconds { get; set; }
	}
	public sealed class BossTelegraphDefinition
	{
		public bool Enabled { get; set; } = true;

		public Color Color { get; set; } = new Color(1f, 0.15f, 0.05f, 0.65f);

		public Color BorderColor { get; set; } = new Color(1f, 0.8f, 0.2f, 1f);

		public float BorderWidth { get; set; } = 0.08f;

		public float PulseFrequency { get; set; } = 1f;

		public bool UseColorBlindPattern { get; set; }

		public AudioClip? AudioClip { get; set; }

		public float AudioVolume { get; set; } = 1f;
	}
	public sealed class BossTargetSelectorDefinition
	{
		public BossTargetSelectorKind Kind { get; set; }

		public float MaximumRange { get; set; }

		public bool LockPositionAtTelegraph { get; set; } = true;

		public float LockBeforeResolveSeconds { get; set; }
	}
	public abstract class BossAbilityGeometryDefinition
	{
		public abstract BossAbilityGeometryKind Kind { get; }

		public Vector3 LocalOffset { get; set; } = Vector3.zero;
	}
	public sealed class CircleGeometryDefinition : BossAbilityGeometryDefinition
	{
		public override BossAbilityGeometryKind Kind => BossAbilityGeometryKind.Circle;

		public float Radius { get; set; } = 4f;
	}
	public sealed class RingGeometryDefinition : BossAbilityGeometryDefinition
	{
		public override BossAbilityGeometryKind Kind => BossAbilityGeometryKind.Ring;

		public float InnerRadius { get; set; } = 2f;

		public float OuterRadius { get; set; } = 5f;
	}
	public sealed class LineGeometryDefinition : BossAbilityGeometryDefinition
	{
		public override BossAbilityGeometryKind Kind => BossAbilityGeometryKind.Line;

		public float Length { get; set; } = 8f;

		public float Width { get; set; } = 1f;
	}
	public sealed class ConeGeometryDefinition : BossAbilityGeometryDefinition
	{
		public override BossAbilityGeometryKind Kind => BossAbilityGeometryKind.Cone;

		public float Radius { get; set; } = 7f;

		public float AngleDegrees { get; set; } = 60f;
	}
	public sealed class BossAbilityDefinition
	{
		public string Id { get; set; } = string.Empty;

		public BossAbilityTrigger Trigger { get; set; }

		public float InitialDelaySeconds { get; set; }

		public float CooldownSeconds { get; set; }

		public int MaxRepeats { get; set; }

		public float Probability { get; set; } = 1f;

		public BossConditionDefinition? Condition { get; set; }

		public BossReactiveRearmPolicy ReactiveRearmPolicy { get; set; }

		public BossAbilityTimelineDefinition Timeline { get; set; } = new BossAbilityTimelineDefinition();

		public BossTargetSelectorDefinition TargetSelector { get; set; } = new BossTargetSelectorDefinition();

		public BossAbilityGeometryDefinition Geometry { get; set; } = new CircleGeometryDefinition();

		public BossTelegraphDefinition Telegraph { get; set; } = new BossTelegraphDefinition();

		public IReadOnlyList<BossActionDefinition> Actions { get; set; } = Array.Empty<BossActionDefinition>();
	}
	public enum BossConditionKind
	{
		Health,
		DamageTaken,
		PlayerDistance,
		MinionCount,
		MinionDefeated,
		AbilityCompleted,
		TimeInPhase,
		BossHooked,
		All,
		Any,
		Not
	}
	public enum BossNumericComparison
	{
		LessThan,
		LessThanOrEqual,
		Equal,
		GreaterThanOrEqual,
		GreaterThan,
		NotEqual
	}
	public enum BossConditionScope
	{
		Encounter,
		ActivePhase,
		RollingWindow
	}
	public abstract class BossConditionDefinition
	{
		public abstract BossConditionKind Kind { get; }
	}
	public sealed class BossHealthConditionDefinition : BossConditionDefinition
	{
		public override BossConditionKind Kind => BossConditionKind.Health;

		public BossNumericComparison Comparison { get; set; } = BossNumericComparison.LessThanOrEqual;

		public float HealthFraction { get; set; } = 0.5f;
	}
	public sealed class BossDamageTakenConditionDefinition : BossConditionDefinition
	{
		public override BossConditionKind Kind => BossConditionKind.DamageTaken;

		public BossNumericComparison Comparison { get; set; } = BossNumericComparison.GreaterThanOrEqual;

		public int Damage { get; set; } = 1;

		public BossConditionScope Scope { get; set; } = BossConditionScope.ActivePhase;

		public float WindowSeconds { get; set; }
	}
	public sealed class BossPlayerDistanceConditionDefinition : BossConditionDefinition
	{
		public override BossConditionKind Kind => BossConditionKind.PlayerDistance;

		public BossNumericComparison Comparison { get; set; } = BossNumericComparison.LessThanOrEqual;

		public float Distance { get; set; } = 10f;

		public int RequiredPlayerCount { get; set; } = 1;
	}
	public sealed class BossMinionCountConditionDefinition : BossConditionDefinition
	{
		public override BossConditionKind Kind => BossConditionKind.MinionCount;

		public string? GroupId { get; set; }

		public BossNumericComparison Comparison { get; set; } = BossNumericComparison.LessThanOrEqual;

		public int Count { get; set; }
	}
	public sealed class BossMinionDefeatedConditionDefinition : BossConditionDefinition
	{
		public override BossConditionKind Kind => BossConditionKind.MinionDefeated;

		public string? GroupId { get; set; }

		public BossNumericComparison Comparison { get; set; } = BossNumericComparison.GreaterThanOrEqual;

		public int Count { get; set; } = 1;

		public BossConditionScope Scope { get; set; } = BossConditionScope.ActivePhase;

		public float WindowSeconds { get; set; }
	}
	public sealed class BossAbilityCompletedConditionDefinition : BossConditionDefinition
	{
		public override BossConditionKind Kind => BossConditionKind.AbilityCompleted;

		public string AbilityId { get; set; } = string.Empty;

		public BossNumericComparison Comparison { get; set; } = BossNumericComparison.GreaterThanOrEqual;

		public int Count { get; set; } = 1;

		public BossConditionScope Scope { get; set; } = BossConditionScope.ActivePhase;

		public float WindowSeconds { get; set; }
	}
	public sealed class BossTimeInPhaseConditionDefinition : BossConditionDefinition
	{
		public override BossConditionKind Kind => BossConditionKind.TimeInPhase;

		public BossNumericComparison Comparison { get; set; } = BossNumericComparison.GreaterThanOrEqual;

		public float Seconds { get; set; } = 1f;
	}
	public sealed class BossHookedConditionDefinition : BossConditionDefinition
	{
		public override BossConditionKind Kind => BossConditionKind.BossHooked;

		public BossHookLifecycleState? RequiredState { get; set; } = BossHookLifecycleState.Hooked;

		public float MinimumContinuousSeconds { get; set; }
	}
	public sealed class BossAllConditionDefinition : BossConditionDefinition
	{
		public override BossConditionKind Kind => BossConditionKind.All;

		public IReadOnlyList<BossConditionDefinition> Conditions { get; set; } = Array.Empty<BossConditionDefinition>();
	}
	public sealed class BossAnyConditionDefinition : BossConditionDefinition
	{
		public override BossConditionKind Kind => BossConditionKind.Any;

		public IReadOnlyList<BossConditionDefinition> Conditions { get; set; } = Array.Empty<BossConditionDefinition>();
	}
	public sealed class BossNotConditionDefinition : BossConditionDefinition
	{
		public override BossConditionKind Kind => BossConditionKind.Not;

		public BossConditionDefinition? Condition { get; set; }
	}
	public sealed class BossDefinition
	{
		public string Id { get; set; } = string.Empty;

		public string ContentVersion { get; set; } = "1.0.0";

		public string DisplayName { get; set; } = string.Empty;

		public string Template { get; set; } = string.Empty;

		public BossVisualDefinition Visual { get; set; } = new BossVisualDefinition();

		public BossStatOverrides Stats { get; set; } = new BossStatOverrides();

		public IReadOnlyList<BossAbilityDefinition> Abilities { get; set; } = Array.Empty<BossAbilityDefinition>();

		public IReadOnlyList<BossPhaseDefinition> Phases { get; set; } = Array.Empty<BossPhaseDefinition>();

		public IReadOnlyList<BossRewardDefinition> Rewards { get; set; } = Array.Empty<BossRewardDefinition>();

		public RewardPolicy RewardPolicy { get; set; }

		public BossEncounterDefinition Encounter { get; set; } = new BossEncounterDefinition();

		public BossPersistenceDefinition Persistence { get; set; } = new BossPersistenceDefinition();

		public BossVanillaIntegrationDefinition VanillaIntegration { get; set; } = new BossVanillaIntegrationDefinition();

		public bool ShowBossBar { get; set; } = true;

		public bool Live { get; internal set; }

		public string FailureMessage { get; internal set; } = string.Empty;
	}
	public sealed class BossVisualDefinition
	{
		public GameObject? Prefab { get; set; }

		public Vector3 LocalPosition { get; set; } = Vector3.zero;

		public Vector3 LocalEulerAngles { get; set; } = Vector3.zero;

		public Vector3 LocalScale { get; set; } = Vector3.one;

		public bool DisableTemplateRenderers { get; set; }

		public bool RemoveVisualColliders { get; set; } = true;

		public string AssetIdentity { get; set; } = string.Empty;

		public string DeclaredAssetDigest { get; set; } = string.Empty;
	}
	public sealed class BossStatOverrides
	{
		public int? MaxHealth { get; set; }

		public float? DamageMultiplier { get; set; }

		public float? MovementSpeedMultiplier { get; set; }

		public float? AttackCooldownMultiplier { get; set; }

		public float? DashForceMultiplier { get; set; }

		public float? DashIntervalMultiplier { get; set; }

		public float? KnockbackResistanceMultiplier { get; set; }

		public float? MassMultiplier { get; set; }

		public float? ScaleMultiplier { get; set; }

		public float? VanillaCorpseValueMultiplier { get; set; }
	}
	public sealed class BossPhaseDefinition
	{
		public string Id { get; set; } = string.Empty;

		public string? DisplayName { get; set; }

		public float TriggerHealthFraction { get; set; }

		public IReadOnlyList<BossActionDefinition> Actions { get; set; } = Array.Empty<BossActionDefinition>();

		public IReadOnlyList<BossActionDefinition> ExitActions { get; set; } = Array.Empty<BossActionDefinition>();

		public IReadOnlyList<BossAbilityDefinition> Abilities { get; set; } = Array.Empty<BossAbilityDefinition>();

		public BossPhaseGateDefinition Gate { get; set; } = new BossPhaseGateDefinition();
	}
	public sealed class BossPhaseGateDefinition
	{
		public bool Enabled { get; set; }

		public float MinimumDurationSeconds { get; set; }

		public float MaximumDurationSeconds { get; set; } = 30f;

		public string RequiredAbilityId { get; set; } = string.Empty;

		public bool ProtectFromDefeat { get; set; }
	}
	internal static class BossDefinitionSnapshot
	{
		private sealed class ConditionReferenceComparer : IEqualityComparer<BossConditionDefinition>
		{
			internal static readonly ConditionReferenceComparer Instance = new ConditionReferenceComparer();

			public bool Equals(BossConditionDefinition? left, BossConditionDefinition? right)
			{
				return left == right;
			}

			public int GetHashCode(BossConditionDefinition value)
			{
				return RuntimeHelpers.GetHashCode(value);
			}
		}

		internal static BossDefinition Clone(BossDefinition source)
		{
			if (source == null)
			{
				throw new ArgumentNullException("source");
			}
			return new BossDefinition
			{
				Id = source.Id,
				ContentVersion = source.ContentVersion,
				DisplayName = source.DisplayName,
				Template = source.Template,
				Visual = Clone(source.Visual),
				Stats = Clone(source.Stats),
				Abilities = CloneAbilities(source.Abilities),
				Phases = ClonePhases(source.Phases),
				Rewards = CloneRewards(source.Rewards, 0),
				RewardPolicy = source.RewardPolicy,
				Encounter = Clone(source.Encounter),
				Persistence = Clone(source.Persistence),
				VanillaIntegration = Clone(source.VanillaIntegration),
				ShowBossBar = source.ShowBossBar,
				Live = source.Live,
				FailureMessage = source.FailureMessage
			};
		}

		private static BossPersistenceDefinition Clone(BossPersistenceDefinition source)
		{
			if (source == null)
			{
				return null;
			}
			return new BossPersistenceDefinition
			{
				Mode = source.Mode
			};
		}

		private static BossVanillaIntegrationDefinition Clone(BossVanillaIntegrationDefinition source)
		{
			if (source == null)
			{
				return null;
			}
			return new BossVanillaIntegrationDefinition
			{
				Mode = source.Mode,
				DurationSeconds = source.DurationSeconds
			};
		}

		internal static BossPhaseDefinition Clone(BossPhaseDefinition source)
		{
			if (source == null)
			{
				return null;
			}
			return new BossPhaseDefinition
			{
				Id = source.Id,
				DisplayName = source.DisplayName,
				TriggerHealthFraction = source.TriggerHealthFraction,
				Actions = CloneActions(source.Actions),
				ExitActions = CloneActions(source.ExitActions),
				Abilities = CloneAbilities(source.Abilities),
				Gate = Clone(source.Gate)
			};
		}

		private static BossPhaseGateDefinition Clone(BossPhaseGateDefinition source)
		{
			if (source == null)
			{
				return null;
			}
			return new BossPhaseGateDefinition
			{
				Enabled = source.Enabled,
				MinimumDurationSeconds = source.MinimumDurationSeconds,
				MaximumDurationSeconds = source.MaximumDurationSeconds,
				RequiredAbilityId = source.RequiredAbilityId,
				ProtectFromDefeat = source.ProtectFromDefeat
			};
		}

		private static BossEncounterDefinition Clone(BossEncounterDefinition source)
		{
			if (source == null)
			{
				return null;
			}
			BossCatchTriggerDefinition[] array = ((source.CatchTriggers == null) ? null : new BossCatchTriggerDefinition[source.CatchTriggers.Count]);
			if (source.CatchTriggers != null)
			{
				for (int i = 0; i < source.CatchTriggers.Count; i++)
				{
					BossCatchTriggerDefinition bossCatchTriggerDefinition = source.CatchTriggers[i];
					array[i] = ((bossCatchTriggerDefinition == null) ? null : new BossCatchTriggerDefinition
					{
						Id = bossCatchTriggerDefinition.Id,
						CaughtTemplate = bossCatchTriggerDefinition.CaughtTemplate,
						Probability = bossCatchTriggerDefinition.Probability,
						CooldownSeconds = bossCatchTriggerDefinition.CooldownSeconds,
						MaxActivations = bossCatchTriggerDefinition.MaxActivations,
						RequiredRod = bossCatchTriggerDefinition.RequiredRod,
						RequiredBait = bossCatchTriggerDefinition.RequiredBait,
						ReplaceCatch = bossCatchTriggerDefinition.ReplaceCatch,
						ResetRodAfterReplacement = bossCatchTriggerDefinition.ResetRodAfterReplacement,
						IntroductionGraceSeconds = bossCatchTriggerDefinition.IntroductionGraceSeconds,
						MinimumSpawnDistance = bossCatchTriggerDefinition.MinimumSpawnDistance,
						MaximumSpawnDistance = bossCatchTriggerDefinition.MaximumSpawnDistance,
						RequireWater = bossCatchTriggerDefinition.RequireWater,
						Placement = Clone(bossCatchTriggerDefinition.Placement)
					});
				}
			}
			return new BossEncounterDefinition
			{
				CatchTriggers = array,
				MaximumOwnedMinions = source.MaximumOwnedMinions,
				MaximumOwnedHazards = source.MaximumOwnedHazards,
				MaximumConcurrentAbilities = source.MaximumConcurrentAbilities,
				HookStagger = Clone(source.HookStagger),
				Engagement = Clone(source.Engagement),
				AquaticRecovery = Clone(source.AquaticRecovery)
			};
		}

		private static BossEngagementDefinition Clone(BossEngagementDefinition source)
		{
			if (source == null)
			{
				return null;
			}
			return new BossEngagementDefinition
			{
				Enabled = source.Enabled,
				MaximumTargetDistance = source.MaximumTargetDistance,
				ReengageSpeed = source.ReengageSpeed,
				MaximumSpeed = source.MaximumSpeed,
				PollIntervalSeconds = source.PollIntervalSeconds
			};
		}

		private static BossAquaticRecoveryDefinition Clone(BossAquaticRecoveryDefinition source)
		{
			if (source == null)
			{
				return null;
			}
			return new BossAquaticRecoveryDefinition
			{
				Enabled = source.Enabled,
				MinimumDepth = source.MinimumDepth,
				IgnoreHorizontalProgress = source.IgnoreHorizontalProgress,
				MinimumTargetHeightDifference = source.MinimumTargetHeightDifference,
				StallDurationSeconds = source.StallDurationSeconds,
				MinimumProgressDistance = source.MinimumProgressDistance,
				SurfaceClearance = source.SurfaceClearance,
				MaximumSpeed = source.MaximumSpeed,
				Acceleration = source.Acceleration,
				MaximumDurationSeconds = source.MaximumDurationSeconds,
				RetryCooldownSeconds = source.RetryCooldownSeconds,
				MaximumLateralDistance = source.MaximumLateralDistance,
				ProbeIntervalSeconds = source.ProbeIntervalSeconds
			};
		}

		private static BossVisualDefinition Clone(BossVisualDefinition source)
		{
			//IL_0018: 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_0030: Unknown result type (might be due to invalid IL or missing references)
			if (source == null)
			{
				return null;
			}
			return new BossVisualDefinition
			{
				Prefab = source.Prefab,
				LocalPosition = source.LocalPosition,
				LocalEulerAngles = source.LocalEulerAngles,
				LocalScale = source.LocalScale,
				DisableTemplateRenderers = source.DisableTemplateRenderers,
				RemoveVisualColliders = source.RemoveVisualColliders,
				AssetIdentity = source.AssetIdentity,
				DeclaredAssetDigest = source.DeclaredAssetDigest
			};
		}

		private static BossStatOverrides Clone(BossStatOverrides source)
		{
			if (source == null)
			{
				return null;
			}
			return new BossStatOverrides
			{
				MaxHealth = source.MaxHealth,
				DamageMultiplier = source.DamageMultiplier,
				MovementSpeedMultiplier = source.MovementSpeedMultiplier,
				AttackCooldownMultiplier = source.AttackCooldownMultiplier,
				DashForceMultiplier = source.DashForceMultiplier,
				DashIntervalMultiplier = source.DashIntervalMultiplier,
				KnockbackResistanceMultiplier = source.KnockbackResistanceMultiplier,
				MassMultiplier = source.MassMultiplier,
				ScaleMultiplier = source.ScaleMultiplier,
				VanillaCorpseValueMultiplier = source.VanillaCorpseValueMultiplier
			};
		}

		private static BossPhaseDefinition[] ClonePhases(IReadOnlyList<BossPhaseDefinition> source)
		{
			if (source == null)
			{
				return null;
			}
			BossPhaseDefinition[] array = new BossPhaseDefinition[source.Count];
			for (int i = 0; i < source.Count; i++)
			{
				array[i] = Clone(source[i]);
			}
			return array;
		}

		private static BossActionDefinition[] CloneActions(IReadOnlyList<BossActionDefinition> source)
		{
			if (source == null)
			{
				return null;
			}
			BossActionDefinition[] array = new BossActionDefinition[source.Count];
			for (int i = 0; i < source.Count; i++)
			{
				array[i] = CloneAction(source[i]);
			}
			return array;
		}

		private static BossAbilityDefinition[] CloneAbilities(IReadOnlyList<BossAbilityDefinition> source)
		{
			if (source == null)
			{
				return null;
			}
			BossAbilityDefinition[] array = new BossAbilityDefinition[source.Count];
			for (int i = 0; i < source.Count; i++)
			{
				BossAbilityDefinition bossAbilityDefinition = source[i];
				array[i] = ((bossAbilityDefinition == null) ? null : new BossAbilityDefinition
				{
					Id = bossAbilityDefinition.Id,
					Trigger = bossAbilityDefinition.Trigger,
					InitialDelaySeconds = bossAbilityDefinition.InitialDelaySeconds,
					CooldownSeconds = bossAbilityDefinition.CooldownSeconds,
					MaxRepeats = bossAbilityDefinition.MaxRepeats,
					Probability = bossAbilityDefinition.Probability,
					Condition = CloneCondition(bossAbilityDefinition.Condition),
					ReactiveRearmPolicy = bossAbilityDefinition.ReactiveRearmPolicy,
					Timeline = Clone(bossAbilityDefinition.Timeline),
					TargetSelector = Clone(bossAbilityDefinition.TargetSelector),
					Geometry = CloneGeometry(bossAbilityDefinition.Geometry),
					Telegraph = Clone(bossAbilityDefinition.Telegraph),
					Actions = CloneActions(bossAbilityDefinition.Actions)
				});
			}
			return array;
		}

		private static BossAbilityTimelineDefinition Clone(BossAbilityTimelineDefinition source)
		{
			if (source == null)
			{
				return null;
			}
			return new BossAbilityTimelineDefinition
			{
				TelegraphDurationSeconds = source.TelegraphDurationSeconds,
				ResolveDurationSeconds = source.ResolveDurationSeconds,
				RecoveryDurationSeconds = source.RecoveryDurationSeconds
			};
		}

		private static BossTargetSelectorDefinition Clone(BossTargetSelectorDefinition source)
		{
			if (source == null)
			{
				return null;
			}
			return new BossTargetSelectorDefinition
			{
				Kind = source.Kind,
				MaximumRange = source.MaximumRange,
				LockPositionAtTelegraph = source.LockPositionAtTelegraph,
				LockBeforeResolveSeconds = source.LockBeforeResolveSeconds
			};
		}

		private static BossTelegraphDefinition Clone(BossTelegraphDefinition source)
		{
			//IL_0018: 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)
			if (source == null)
			{
				return null;
			}
			return new BossTelegraphDefinition
			{
				Enabled = source.Enabled,
				Color = source.Color,
				BorderColor = source.BorderColor,
				BorderWidth = source.BorderWidth,
				PulseFrequency = source.PulseFrequency,
				UseColorBlindPattern = source.UseColorBlindPattern,
				AudioClip = source.AudioClip,
				AudioVolume = source.AudioVolume
			};
		}

		private static BossAbilityGeometryDefinition CloneGeometry(BossAbilityGeometryDefinition source)
		{
			//IL_0039: Unknown result type (might be due to invalid IL or missing references)
			//IL_0057: Unknown result type (might be due to invalid IL or missing references)
			//IL_0081: 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 (source == null)
			{
				return null;
			}
			if (!(source is CircleGeometryDefinition circleGeometryDefinition))
			{
				if (!(source is RingGeometryDefinition ringGeometryDefinition))
				{
					if (!(source is LineGeometryDefinition lineGeometryDefinition))
					{
						if (source is ConeGeometryDefinition coneGeometryDefinition)
						{
							return new ConeGeometryDefinition
							{
								LocalOffset = coneGeometryDefinition.LocalOffset,
								Radius = coneGeometryDefinition.Radius,
								AngleDegrees = coneGeometryDefinition.AngleDegrees
							};
						}
						return source;
					}
					return new LineGeometryDefinition
					{
						LocalOffset = lineGeometryDefinition.LocalOffset,
						Length = lineGeometryDefinition.Length,
						Width = lineGeometryDefinition.Width
					};
				}
				return new RingGeometryDefinition
				{
					LocalOffset = ringGeometryDefinition.LocalOffset,
					InnerRadius = ringGeometryDefinition.InnerRadius,
					OuterRadius = ringGeometryDefinition.OuterRadius
				};
			}
			return new CircleGeometryDefinition
			{
				LocalOffset = circleGeometryDefinition.LocalOffset,
				Radius = circleGeometryDefinition.Radius
			};
		}

		private static BossActionDefinition CloneAction(BossActionDefinition source)
		{
			//IL_026f: Unknown result type (might be due to invalid IL or missing references)
			//IL_027c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0289: Unknown result type (might be due to invalid IL or missing references)
			if (source == null)
			{
				return null;
			}
			if (!(source is StatMultiplierAction statMultiplierAction))
			{
				if (!(source is SpawnMinionsAction spawnMinionsAction))
				{
					if (!(source is ToggleVisualNodeAction toggleVisualNodeAction))
					{
						if (!(source is SetVisualScaleAction setVisualScaleAction))
						{
							if (!(source is PlayAudioAction playAudioAction))
							{
								if (!(source is SpawnVisualEffectAction spawnVisualEffectAction))
								{
									if (!(source is AreaDamageAction areaDamageAction))
									{
										if (!(source is ForceAction forceAction))
										{
											if (source is DashAction dashAction)
											{
												return new DashAction
												{
													Id = dashAction.Id,
													Impulse = dashAction.Impulse,
													VerticalImpulse = dashAction.VerticalImpulse,
													RetainedVelocityFraction = dashAction.RetainedVelocityFraction,
													MaximumSpeed = dashAction.MaximumSpeed,
													MaximumTravelDistance = dashAction.MaximumTravelDistance,
													StoppingDistance = dashAction.StoppingDistance,
													BrakeDurationSeconds = dashAction.BrakeDurationSeconds,
													ExitVelocityFraction = dashAction.ExitVelocityFraction
												};
											}
											return source;
										}
										return new ForceAction
										{
											Id = forceAction.Id,
											Mode = forceAction.Mode,
											Magnitude = forceAction.Magnitude,
											DurationSeconds = forceAction.DurationSeconds,
											VerticalTolerance = forceAction.VerticalTolerance,
											VerticalMultiplier = forceAction.VerticalMultiplier,
											MaximumVelocityChange = forceAction.MaximumVelocityChange
										};
									}
									return new AreaDamageAction
									{
										Id = areaDamageAction.Id,
										Damage = areaDamageAction.Damage,
										DurationSeconds = areaDamageAction.DurationSeconds,
										TickIntervalSeconds = areaDamageAction.TickIntervalSeconds,
										MaxHitsPerTarget = areaDamageAction.MaxHitsPerTarget,
										VerticalTolerance = areaDamageAction.VerticalTolerance
									};
								}
								return new SpawnVisualEffectAction
								{
									Id = spawnVisualEffectAction.Id,
									Prefab = spawnVisualEffectAction.Prefab,
									Anchor = spawnVisualEffectAction.Anchor,
									ParentToBoss = spawnVisualEffectAction.ParentToBoss,
									AlignToAbilityDirection = spawnVisualEffectAction.AlignToAbilityDirection,
									LocalOffset = spawnVisualEffectAction.LocalOffset,
									LocalEulerAngles = spawnVisualEffectAction.LocalEulerAngles,
									LocalScale = spawnVisualEffectAction.LocalScale,
									Lifetime = spawnVisualEffectAction.Lifetime
								};
							}
							return new PlayAudioAction
							{
								Id = playAudioAction.Id,
								Clip = playAudioAction.Clip,
								Volume = playAudioAction.Volume,
								SpatialBlend = playAudioAction.SpatialBlend
							};
						}
						return new SetVisualScaleAction
						{
							Id = setVisualScaleAction.Id,
							ScaleMultiplier = setVisualScaleAction.ScaleMultiplier,
							Persistent = setVisualScaleAction.Persistent
						};
					}
					return new ToggleVisualNodeAction
					{
						Id = toggleVisualNodeAction.Id,
						RelativeTransformPath = toggleVisualNodeAction.RelativeTransformPath,
						Enabled = toggleVisualNodeAction.Enabled,
						Persistent = toggleVisualNodeAction.Persistent
					};
				}
				return new SpawnMinionsAction
				{
					Id = spawnMinionsAction.Id,
					TemplateName = spawnMinionsAction.TemplateName,
					RegisteredBossId = spawnMinionsAction.RegisteredBossId,
					Count = spawnMinionsAction.Count,
					SpawnRadius = spawnMinionsAction.SpawnRadius,
					MaxAliveFromThisAction = spawnMinionsAction.MaxAliveFromThisAction,
					GroupId = spawnMinionsAction.GroupId,
					CleanupPolicy = spawnMinionsAction.CleanupPolicy,
					LifetimeSeconds = spawnMinionsAction.LifetimeSeconds,
					Placement = Clone(spawnMinionsAction.Placement),
					Formation = Clone(spawnMinionsAction.Formation)
				};
			}
			return new StatMultiplierAction
			{
				Id = statMultiplierAction.Id,
				DamageMultiplier = statMultiplierAction.DamageMultiplier,
				MovementSpeedMultiplier = statMultiplierAction.MovementSpeedMultiplier,
				AttackCooldownMultiplier = statMultiplierAction.AttackCooldownMultiplier,
				DashForceMultiplier = statMultiplierAction.DashForceMultiplier,
				DashIntervalMultiplier = statMultiplierAction.DashIntervalMultiplier,
				ModifierId = statMultiplierAction.ModifierId,
				Lifetime = statMultiplierAction.Lifetime,
				DurationSeconds = statMultiplierAction.DurationSeconds
			};
		}

		private static BossPlacementDefinition? Clone(BossPlacementDefinition? source)
		{
			//IL_0018: Unknown result type (might be due to invalid IL or missing references)
			if (source == null)
			{
				return null;
			}
			return new BossPlacementDefinition
			{
				Mode = source.Mode,
				LocalOffset = source.LocalOffset,
				SearchRadius = source.SearchRadius,
				VerticalSearchDistance = source.VerticalSearchDistance,
				ClearanceRadius = source.ClearanceRadius,
				UseBossBodyClearance = source.UseBossBodyClearance,
				MaximumAttempts = source.MaximumAttempts,
				SocketPath = source.SocketPath,
				FailurePolicy = source.FailurePolicy
			};
		}

		private static BossFormationDefinition? Clone(BossFormationDefinition? source)
		{
			if (source == null)
			{
				return null;
			}
			string[] array;
			if (source.SocketPaths == null)
			{
				array = null;
			}
			else
			{
				array = new string[source.SocketPaths.Count];
				for (int i = 0; i < array.Length; i++)
				{
					array[i] = source.SocketPaths[i];
				}
			}
			return new BossFormationDefinition
			{
				Kind = source.Kind,
				Radius = source.Radius,
				Spacing = source.Spacing,
				AngleDegrees = source.AngleDegrees,
				YawOffsetDegrees = source.YawOffsetDegrees,
				FaceCenter = source.FaceCenter,
				SocketPaths = array
			};
		}

		private static BossHookStaggerDefinition Clone(BossHookStaggerDefinition source)
		{
			if (source == null)
			{
				return null;
			}
			return new BossHookStaggerDefinition
			{
				Enabled = source.Enabled,
				MinimumSafeTension = source.MinimumSafeTension,
				MaximumSafeTension = source.MaximumSafeTension,
				ProgressPerSecond = source.ProgressPerSecond,
				DecayPerSecond = source.DecayPerSecond,
				StaggerThreshold = source.StaggerThreshold,
				StaggerDurationSeconds = source.StaggerDurationSeconds,
				RecoveryDurationSeconds = source.RecoveryDurationSeconds,
				MaximumSimultaneousHooks = source.MaximumSimultaneousHooks,
				InterruptActiveAbilityOnStagger = source.InterruptActiveAbilityOnStagger
			};
		}

		private static BossConditionDefinition? CloneCondition(BossConditionDefinition? source)
		{
			if (source == null)
			{
				return null;
			}
			return CloneCondition(source, 0, new HashSet<BossConditionDefinition>(ConditionReferenceComparer.Instance));
		}

		private static BossConditionDefinition CloneCondition(BossConditionDefinition source, int depth, ISet<BossConditionDefinition> recursionStack)
		{
			if (depth > 8 || !recursionStack.Add(source))
			{
				throw new ArgumentException("Condition graph is cyclic or exceeds the supported nesting depth.", "source");
			}
			try
			{
				if (!(source is BossHealthConditionDefinition bossHealthConditionDefinition))
				{
					if (!(source is BossDamageTakenConditionDefinition bossDamageTakenConditionDefinition))
					{
						if (!(source is BossPlayerDistanceConditionDefinition bossPlayerDistanceConditionDefinition))
						{
							if (!(source is BossMinionCountConditionDefinition bossMinionCountConditionDefinition))
							{
								if (!(source is BossMinionDefeatedConditionDefinition bossMinionDefeatedConditionDefinition))
								{
									if (!(source is BossAbilityCompletedConditionDefinition bossAbilityCompletedConditionDefinition))
									{
										if (!(source is BossTimeInPhaseConditionDefinition bossTimeInPhaseConditionDefinition))
										{
											if (!(source is BossHookedConditionDefinition bossHookedConditionDefinition))
											{
												if (!(source is BossAllConditionDefinition bossAllConditionDefinition))
												{
													if (!(source is BossAnyConditionDefinition bossAnyConditionDefinition))
													{
														if (source is BossNotConditionDefinition bossNotConditionDefinition)
														{
															return new BossNotConditionDefinition
															{
																Condition = ((bossNotConditionDefinition.Condition == null) ? null : CloneCondition(bossNotConditionDefinition.Condition, depth + 1, recursionStack))
															};
														}
														return source;
													}
													return new BossAnyConditionDefinition
													{
														Conditions = CloneConditions(bossAnyConditionDefinition.Conditions, depth + 1, recursionStack)
													};
												}
												return new BossAllConditionDefinition
												{
													Conditions = CloneConditions(bossAllConditionDefinition.Conditions, depth + 1, recursionStack)
												};
											}
											return new BossHookedConditionDefinition
											{
												RequiredState = bossHookedConditionDefinition.RequiredState,
												MinimumContinuousSeconds = bossHookedConditionDefinition.MinimumContinuousSeconds
											};
										}
										return new BossTimeInPhaseConditionDefinition
										{
											Comparison = bossTimeInPhaseConditionDefinition.Comparison,
											Seconds = bossTimeInPhaseConditionDefinition.Seconds
										};
									}
									return new BossAbilityCompletedConditionDefinition
									{
										AbilityId = bossAbilityCompletedConditionDefinition.AbilityId,
										Comparison = bossAbilityCompletedConditionDefinition.Comparison,
										Count = bossAbilityCompletedConditionDefinition.Count,
										Scope = bossAbilityCompletedConditionDefinition.Scope,
										WindowSeconds = bossAbilityCompletedConditionDefinition.WindowSeconds
									};
								}
								return new BossMinionDefeatedConditionDefinition
								{
									GroupId = bossMinionDefeatedConditionDefinition.GroupId,
									Comparison = bossMinionDefeatedConditionDefinition.Comparison,
									Count = bossMinionDefeatedConditionDefinition.Count,
									Scope = bossMinionDefeatedConditionDefinition.Scope,
									WindowSeconds = bossMinionDefeatedConditionDefinition.WindowSeconds
								};
							}
							return new BossMinionCountConditionDefinition
							{
								GroupId = bossMinionCountConditionDefinition.GroupId,
								Comparison = bossMinionCountConditionDefinition.Comparison,
								Count = bossMinionCountConditionDefinition.Count
							};
						}
						return new BossPlayerDistanceConditionDefinition
						{
							Comparison = bossPlayerDistanceConditionDefinition.Comparison,
							Distance = bossPlayerDistanceConditionDefinition.Distance,
							RequiredPlayerCount = bossPlayerDistanceConditionDefinition.RequiredPlayerCount
						};
					}
					return new BossDamageTakenConditionDefinition
					{
						Comparison = bossDamageTakenConditionDefinition.Comparison,
						Damage = bossDamageTakenConditionDefinition.Damage,
						Scope = bossDamageTakenConditionDefinition.Scope,
						WindowSeconds = bossDamageTakenConditionDefinition.WindowSeconds
					};
				}
				return new BossHealthConditionDefinition
				{
					Comparison = bossHealthConditionDefinition.Comparison,
					HealthFraction = bossHealthConditionDefinition.HealthFraction
				};
			}
			finally
			{
				recursionStack.Remove(source);
			}
		}

		private static BossConditionDefinition[] CloneConditions(IReadOnlyList<BossConditionDefinition> source, int depth, ISet<BossConditionDefinition> recursionStack)
		{
			if (source == null)
			{
				return null;
			}
			BossConditionDefinition[] array = new BossConditionDefinition[source.Count];
			for (int i = 0; i < array.Length; i++)
			{
				array[i] = ((source[i] == null) ? null : CloneCondition(source[i], depth, recursionStack));
			}
			return array;
		}

		private static BossRewardDefinition[] CloneRewards(IReadOnlyList<BossRewardDefinition> source, int depth)
		{
			if (source == null)
			{
				return null;
			}
			BossRewardDefinition[] array = new BossRewardDefinition[source.Count];
			for (int i = 0; i < source.Count; i++)
			{
				array[i] = CloneReward(source[i], depth);
			}
			return array;
		}

		private static BossRewardDefinition CloneReward(BossRewardDefinition source, int depth)
		{
			if (source == null)
			{
				return null;
			}
			if (depth > 8)
			{
				return source;
			}
			if (!(source is VanillaItemReward vanillaItemReward))
			{
				if (!(source is MoneyReward moneyReward))
				{
					if (!(source is MultipleReward multipleReward))
					{
						if (!(source is WeightedReward weightedReward))
						{
							if (source is CustomItemReward customItemReward)
							{
								return new CustomItemReward
								{
									ProviderId = customItemReward.ProviderId,
									ItemId = customItemReward.ItemId,
									Count = customItemReward.Count
								};
							}
							return source;
						}
						WeightedRewardEntry[] array = ((weightedReward.Entries == null) ? null : new WeightedRewardEntry[weightedReward.Entries.Count]);
						if (weightedReward.Entries != null)
						{
							for (int i = 0; i < weightedReward.Entries.Count; i++)
							{
								WeightedRewardEntry weightedRewardEntry = weightedReward.Entries[i];
								array[i] = ((weightedRewardEntry == null) ? null : new WeightedRewardEntry
								{
									Weight = weightedRewardEntry.Weight,
									Reward = ((weightedRewardEntry.Reward == null) ? null : CloneReward(weightedRewardEntry.Reward, depth + 1))
								});
							}
						}
						return new WeightedReward
						{
							Rolls = weightedReward.Rolls,
							Entries = array
						};
					}
					return new MultipleReward
					{
						Rewards = CloneRewards(multipleReward.Rewards, depth + 1)
					};
				}
				return new MoneyReward
				{
					Amount = moneyReward.Amount
				};
			}
			return new VanillaItemReward
			{
				ItemName = vanillaItemReward.ItemName,
				Count = vanillaItemReward.Count,
				SpawnRadius = vanillaItemReward.SpawnRadius
			};
		}
	}
	public static class BossDefinitionValidator
	{
		private sealed class ConditionReferenceComparer : IEqualityComparer<BossConditionDefinition>
		{
			internal static readonly ConditionReferenceComparer Instance = new ConditionReferenceComparer();

			public bool Equals(BossConditionDefinition? left, BossConditionDefinition? right)
			{
				return left == right;
			}

			public int GetHashCode(BossConditionDefinition value)
			{
				return RuntimeHelpers.GetHashCode(value);
			}
		}

		public const int MaximumPhases = 32;

		public const int MaximumActionsPerPhase = 32;

		public const int MaximumAbilitiesPerPhase = 32;

		public const int MaximumAbilitiesPerDefinition = 128;

		public const int MaximumActionsPerAbility = 32;

		public const int MaximumAbilityRepeats = 1024;

		public const int MaximumCatchTriggers = 32;

		public const float MaximumCatchIntroductionGraceSeconds = 30f;

		public const int MaximumCatchActivations = 100000;

		public const int MaximumMinionsPerAction = 32;

		public const int MaximumConditionNodesPerAbility = 32;

		public const int MaximumConditionNodesPerDefinition = 256;

		public const int MaximumConditionNestingDepth = 8;

		public const int MaximumConditionChildren = 16;

		public const int MaximumConditionCounter = 1000000;

		public const int MaximumConditionPlayerCount = 64;

		public const int MaximumFormationSockets = 32;

		public const int MaximumPlacementAttempts = 32;

		public const int MaximumSimultaneousHooks = 8;

		public const int MaximumActiveModifiers = 64;

		public const int MaximumActionResultCount = 1024;

		public const int MaximumValidationIssues = 512;

		public const int MaximumDeclaredActiveMinions = 128;

		public const int MaximumTopLevelRewards = 64;

		public const int MaximumRewardChildren = 64;

		public const int MaximumRewardRolls = 64;

		public const int MaximumRewardNodes = 256;

		public const int MaximumRewardItems = 256;

		public const int MaximumRewardNestingDepth = 8;

		public const int MaximumHealth = 10000000;

		public const float MinimumMultiplier = 0.01f;

		public const float MaximumMultiplier = 100f;

		public const float MaximumSpawnRadius = 1000f;

		public const float MaximumAudioVolume = 4f;

		public const float MaximumVisualEffectLifetime = 300f;

		public const float MaximumVisualOffset = 100000f;

		public const float MaximumVisualScale = 1000f;

		public const float MaximumAbilityDuration = 3600f;

		public const float MaximumAbilityCooldown = 86400f;

		public const float MinimumVanillaBossDuration = 1f;

		public const float MaximumVanillaBossDuration = 86400f;

		public const float MaximumAbilityRange = 10000f;

		public const float MaximumGeometryExtent = 1000f;

		public const float MaximumForceMagnitude = 1000f;

		public const float MaximumVelocityChange = 1000f;

		public const float MaximumDashBrakeDuration = 10f;

		public const float MaximumEngagementPollInterval = 10f;

		public const float MinimumAquaticRecoveryDepth = 0.5f;

		public const float MaximumAquaticRecoveryDepth = 50f;

		public const float MinimumAquaticRecoveryTargetHeightDifference = 0.25f;

		public const float MaximumAquaticRecoveryTargetHeightDifference = 50f;

		public const float MinimumAquaticRecoveryStallDuration = 0.25f;

		public const float MaximumAquaticRecoveryStallDuration = 30f;

		public const float MinimumAquaticRecoveryProgressDistance = 0.05f;

		public const float MaximumAquaticRecoveryProgressDistance = 10f;

		public const float MinimumAquaticRecoverySurfaceClearance = 0.25f;

		public const float MaximumAquaticRecoverySurfaceClearance = 10f;

		public const float MinimumAquaticRecoverySpeed = 0.5f;

		public const float MaximumAquaticRecoverySpeed = 12f;

		public const float MinimumAquaticRecoveryAcceleration = 0.5f;

		public const float MaximumAquaticRecoveryAcceleration = 30f;

		public const float MinimumAquaticRecoveryDuration = 0.25f;

		public const float MaximumAquaticRecoveryDuration = 30f;

		public const float MinimumAquaticRecoveryRetryCooldown = 0.5f;

		public const float MaximumAquaticRecoveryRetryCooldown = 120f;

		public const float MinimumAquaticRecoveryLateralDistance = 0.5f;

		public const float MaximumAquaticRecoveryLateralDistance = 30f;

		public const float MinimumAquaticRecoveryProbeInterval = 0.1f;

		public const float MaximumAquaticRecoveryProbeInterval = 1f;

		public const float MaximumHookRate = 100f;

		public const int MaximumAreaDamage = 10000000;

		public const int MaximumHitsPerTarget = 1024;

		public const int MaximumOwnedMinionBudget = 256;

		public const int MaximumOwnedHazardBudget = 256;

		public const int MaximumConcurrentAbilityBudget = 1;

		public const int MaximumEncounterExecutionClaims = 4096;

		public const int MaximumDisplayNameLength = 256;

		public const int MaximumTemplateNameLength = 256;

		public const int MaximumPhaseIdLength = 128;

		public const int MaximumAssetIdentityLength = 1024;

		public const int MaximumRelativePathLength = 1024;

		public const int MaximumRewardIdentifierLength = 256;

		public const int MaximumAbilityIdLength = 128;

		public const int MaximumCatchTriggerIdLength = 128;

		public const int MaximumCatchFilterLength = 256;

		public const int MaximumMinionGroupIdLength = 128;

		public const int MaximumActionIdLength = 128;

		public const int MaximumModifierIdLength = 128;

		public const int MaximumResultMessageLength = 1024;

		private static readonly Regex NamespacedId = new Regex("^[a-z0-9][a-z0-9_-]*(?:\\.[a-z0-9][a-z0-9_-]*)+$", RegexOptions.CultureInvariant);

		private static readonly Regex SemanticVersion = new Regex("^(0|[1-9][0-9]*)\\.(0|[1-9][0-9]*)\\.(0|[1-9][0-9]*)(?:-[0-9A-Za-z-]+(?:\\.[0-9A-Za-z-]+)*)?(?:\\+[0-9A-Za-z-]+(?:\\.[0-9A-Za-z-]+)*)?$", RegexOptions.CultureInvariant);

		public static bool IsValidBossId(string? id)
		{
			if (!string.IsNullOrEmpty(id) && id.Length <= 128)
			{
				return NamespacedId.IsMatch(id);
			}
			return false;
		}

		public static BossValidationReport Analyze(BossDefinition definition)
		{
			if (definition == null)
			{
				throw new ArgumentNullException("definition");
			}
			IReadOnlyList<string> readOnlyList = ValidateLegacyMessages(definition);
			List<BossValidationIssue> list = new List<BossValidationIssue>();
			for (int i = 0; i < readOnlyList.Count; i++)
			{
				if (list.Count >= 512)
				{
					break;
				}
				AddIssue(list, "legacy.definition_invalid", "$", readOnlyList[i]);
			}
			ValidateVersion4(definition, list);
			if (list.Count == 0)
			{
				try
				{
					if (!BossManifestBuilder.TryValidateDefinitionWireBudget(definition, out string error))
					{
						AddIssue(list, "manifest.wire_budget_exceeded", "$", error);
					}
				}
				catch (Exception ex)
				{
					AddIssue(list, "manifest.encoding_failed", "$", "Definition could not be encoded safely: " + ex.GetType().Name + ": " + ex.Message);
				}
			}
			TrimIssueBudget(list);
			return new BossValidationReport(list);
		}

		public static IReadOnlyList<string> Validate(BossDefinition definition)
		{
			return Analyze(definition).Errors.Select((BossValidationIssue issue) => issue.Message).ToArray();
		}

		private static IReadOnlyList<string> ValidateLegacyMessages(BossDefinition definition)
		{
			//IL_01c1: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d3: Unknown result type (might be due to invalid IL or missing references)
			//IL_01e5: 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_0235: Unknown result type (might be due to invalid IL or missing references)
			if (definition == null)
			{
				throw new ArgumentNullException("definition");
			}
			List<string> list = new List<string>();
			if (!IsValidBossId(definition.Id))
			{
				list.Add("Id must be a lowercase namespaced identifier using letters, digits, '.', '-' or '_'.");
			}
			if (string.IsNullOrWhiteSpace(definition.ContentVersion) || definition.ContentVersion.Length > 128 || !SemanticVersion.IsMatch(definition.ContentVersion))
			{
				list.Add("ContentVersion must be a semantic version such as 1.0.0 or 1.0.0-beta.1.");
			}
			if (string.IsNullOrWhiteSpace(definition.DisplayName) || definition.DisplayName.Length > 256)
			{
				list.Add($"DisplayName is required and cannot exceed {256} characters.");
			}
			if (string.IsNullOrWhiteSpace(definition.Template) || definition.Template.Length > 256)
			{
				list.Add($"Template is required and cannot exceed {256} characters.");
			}
			if (definition.Visual == null)
			{
				list.Add("Visual cannot be null.");
			}
			if (definition.Stats == null)
			{
				list.Add("Stats cannot be null.");
			}
			if (definition.Persistence == null)
			{
				list.Add("Persistence cannot be null.");
			}
			else if (!Enum.IsDefined(typeof(BossPersistenceMode), definition.Persistence.Mode))
			{
				list.Add("Persistence Mode is not a supported value.");
			}
			if (definition.Visual != null)
			{
				if (definition.Visual.AssetIdentity != null && definition.Visual.AssetIdentity.Length > 1024)
				{
					list.Add($"Visual AssetIdentity cannot exceed {1024} characters.");
				}
				if (!string.IsNullOrEmpty(definition.Visual.DeclaredAssetDigest) && !BossManifestDigest.TryNormalizeSha256(definition.Visual.DeclaredAssetDigest, out string _))
				{
					list.Add("Visual DeclaredAssetDigest must be a 64-character SHA-256 hexadecimal digest, optionally prefixed with 'sha256:'.");
				}
				if (!IsFinite(definition.Visual.LocalPosition) || !IsFinite(definition.Visual.LocalEulerAngles) || !IsFinite(definition.Visual.LocalScale))
				{
					list.Add("Visual position, rotation and scale must contain only finite values.");
				}
				else
				{
					if (!IsWithinMagnitude(definition.Visual.LocalPosition, 100000f))
					{
						list.Add($"Visual local position components cannot exceed {100000f} in magnitude.");
					}
					if (!IsWithinMagnitude(definition.Visual.LocalScale, 1000f))
					{
						list.Add($"Visual local scale components cannot exceed {1000f} in magnitude.");
					}
				}
			}
			ValidateStats(definition.Stats, list);
			if (!Enum.IsDefined(typeof(RewardPolicy), definition.RewardPolicy))
			{
				list.Add("RewardPolicy is not a supported value.");
			}
			ValidateVanillaIntegration(definition.VanillaIntegration, list);
			ValidateEncounter(definition.Encounter, list);
			HashSet<string> abilityIds = new HashSet<string>(StringComparer.Ordinal);
			long declaredActiveMinions = 0L;
			long declaredExecutionClaims = 1L;
			long num = 0L;
			if (definition.Abilities == null)
			{
				list.Add("Abilities cannot be null; use an empty collection.");
			}
			else if (definition.Abilities.Count > 32)
			{
				list.Add($"A boss may declare at most {32} global abilities.");
			}
			IReadOnlyList<BossAbilityDefinition> readOnlyList = definition.Abilities ?? Array.Empty<BossAbilityDefinition>();
			num += readOnlyList.Count;
			for (int i = 0; i < Math.Min(readOnlyList.Count, 32); i++)
			{
				ValidateAbility(readOnlyList[i], "global", abilityIds, list, ref declaredActiveMinions, ref declaredExecutionClaims, isGlobal: true);
			}
			HashSet<float> hashSet = new HashSet<float>();
			HashSet<string> hashSet2 = new HashSet<string>(StringComparer.Ordinal);
			if (definition.Phases == null)
			{
				list.Add("Phases cannot be null; use an empty collection.");
			}
			else if (definition.Phases.Count > 32)
			{
				list.Add($"A boss may declare at most {32} phases.");
			}
			IReadOnlyList<BossPhaseDefinition> readOnlyList2 = definition.Phases ?? Array.Empty<BossPhaseDefinition>();
			for (int j = 0; j < Math.Min(readOnlyList2.Count, 32); j++)
			{
				BossPhaseDefinition phase = readOnlyList2[j];
				if (phase == null)
				{
					list.Add("Phases cannot contain null entries.");
					continue;
				}
				if (!EncounterContractValidation.IsSafeToken(phase.Id, 128))
				{
					list.Add($"Every phase requires a normalized, control-free Id no longer than {128} characters.");
				}
				else if (!hashSet2.Add(phase.Id))
				{
					list.Add("Duplicate phase Id '" + phase.Id + "'.");
				}
				if (!IsFinite(phase.TriggerHealthFraction) || phase.TriggerHealthFraction < 0f || phase.TriggerHealthFraction > 1f)
				{
					list.Add("Phase '" + phase.Id + "' threshold must be between 0 and 1.");
				}
				else if (!hashSet.Add(phase.TriggerHealthFraction))
				{
					list.Add($"Duplicate phase threshold {phase.TriggerHealthFraction}.");
				}
				if (phase.Actions == null)
				{
					list.Add("Phase '" + phase.Id + "' Actions cannot be null; use an empty collection.");
				}
				else if (phase.Actions.Count > 32)
				{
					list.Add($"Phase '{phase.Id}' may declare at most {32} actions.");
				}
				IReadOnlyList<BossActionDefinition> readOnlyList3 = phase.Actions ?? Array.Empty<BossActionDefinition>();
				int num2 = Math.Min(readOnlyList3.Count, 32);
				declaredExecutionClaims += num2;
				for (int k = 0; k < num2; k++)
				{
					ValidateAction(readOnlyList3[k], phase.Id, list, ref declaredActiveMinions, isAbilityAction: false);
				}
				IReadOnlyList<BossActionDefinition> readOnlyList4 = phase.ExitActions ?? Array.Empty<BossActionDefinition>();
				int num3 = Math.Min(readOnlyList4.Count, 32);
				declaredExecutionClaims += num3;
				for (int l = 0; l < num3; l++)
				{
					if (readOnlyList4[l] is SpawnMinionsAction { MaxAliveFromThisAction: >0 } spawnMinionsAction)
					{
						declaredActiveMinions = SaturatingAdd(declaredActiveMinions, spawnMinionsAction.MaxAliveFromThisAction);
					}
				}
				if (phase.Abilities == null)
				{
					list.Add("Phase '" + phase.Id + "' Abilities cannot be null; use an empty collection.");
				}
				else if (phase.Abilities.Count > 32)
				{
					list.Add($"Phase '{phase.Id}' may declare at most {32} abilities.");
				}
				IReadOnlyList<BossAbilityDefinition> readOnlyList5 = phase.Abilities ?? Array.Empty<BossAbilityDefinition>();
				num += readOnlyList5.Count;
				for (int m = 0; m < Math.Min(readOnlyList5.Count, 32); m++)
				{
					ValidateAbility(readOnlyList5[m], phase.Id, abilityIds, list, ref declaredActiveMinions, ref declaredExecutionClaims, isGlobal: false);
				}
				ValidatePhaseGate(phase, readOnlyList5, !readOnlyList2.Any((BossPhaseDefinition candidate) => candidate != null && IsFinite(candidate.TriggerHealthFraction) && candidate.TriggerHealthFraction < phase.TriggerHealthFraction), list);
			}
			if (num > 128)
			{
				list.Add($"A boss may declare at most {128} abilities across its global and phase collections.");
			}
			if (declaredActiveMinions > 128)
			{
				list.Add($"A boss may declare at most {128} simultaneously active minions across all phase actions.");
			}
			if (definition.Encounter != null && definition.Encounter.MaximumOwnedMinions >= 0 && declaredActiveMinions > definition.Encounter.MaximumOwnedMinions)
			{
				list.Add($"Declared active minions ({declaredActiveMinions}) exceed the encounter MaximumOwnedMinions budget ({definition.Encounter.MaximumOwnedMinions}).");
			}
			if (definition.Rewards == null)
			{
				list.Add("Rewards cannot be null; use an empty collection.");
			}
			else if (definition.Rewards.Count > 64)
			{
				list.Add($"A boss may declare at most {64} top-level rewards.");
			}
			IReadOnlyList<BossRewardDefinition> readOnlyList6 = definition.Rewards ?? Array.Empty<BossRewardDefinition>();
			declaredExecutionClaims += Math.Min(readOnlyList6.Count, 64);
			if (definition.RewardPolicy == RewardPolicy.PreserveVanilla && readOnlyList6.Count != 0)
			{
				list.Add("RewardPolicy PreserveVanilla requires Rewards to be empty so configured rewards are not silently ignored.");
			}
			int nodes = 0;
			long num4 = 0L;
			for (int num5 = 0; num5 < Math.Min(readOnlyList6.Count, 64); num5++)
			{
				num4 = SaturatingAdd(num4, ValidateReward(readOnlyList6[num5], list, 0, ref nodes));
			}
			if (nodes > 256)
			{
				list.Add($"A boss reward graph may contain at most {256} nodes.");
			}
			if (num4 > 256)
			{
				list.Add($"A boss may spawn at most {256} reward items in the worst case.");
			}
			if (declaredExecutionClaims > 4096)
			{
				list.Add($"A boss may require at most {4096} exactly-once execution claims across ability actions, rewards and cleanup; " + $"this definition can require {declaredExecutionClaims} in the worst case.");
			}
			return list;
		}

		internal static IReadOnlyList<BossPhaseDefinition> OrderPhases(IEnumerable<BossPhaseDefinition>? phases)
		{
			return (phases ?? Array.Empty<BossPhaseDefinition>()).OrderByDescending((BossPhaseDefinition x) => x.TriggerHealthFraction).ThenBy<BossPhaseDefinition, string>((BossPhaseDefinition x) => x.Id, StringComparer.Ordinal).ToArray();
		}

		private static void ValidateStats(BossStatOverrides? stats, ICollection<string> errors)
		{
			if (stats != null)
			{
				if (stats.MaxHealth.HasValue && (stats.MaxHealth <= 0 || stats.MaxHealth > 10000000))
				{
					errors.Add($"MaxHealth must be between 1 and {10000000}.");
				}
				ValidateMultiplier(stats.DamageMultiplier, "DamageMultiplier", errors);
				ValidateMultiplier(stats.MovementSpeedMultiplier, "MovementSpeedMultiplier", errors);
				ValidateMultiplier(stats.AttackCooldownMultiplier, "AttackCooldownMultiplier", errors);
				ValidateMultiplier(stats.DashForceMultiplier, "DashForceMultiplier", errors);
				ValidateMultiplier(stats.DashIntervalMultiplier, "DashIntervalMultiplier", errors);
				ValidateMultiplier(stats.KnockbackResistanceMultiplier, "KnockbackResistanceMultiplier", errors);
				ValidateMultiplier(stats.MassMultiplier, "MassMultiplier", errors);
				ValidateMultiplier(stats.ScaleMultiplier, "ScaleMultiplier", errors);
				ValidateMultiplier(stats.VanillaCorpseValueMultiplier, "VanillaCorpseValueMultiplier", errors);
			}
		}

		private static void ValidateVanillaIntegration(BossVanillaIntegrationDefinition? integration, ICollection<string> errors)
		{
			if (integration == null)
			{
				errors.Add("VanillaIntegration cannot be null.");
			}
			else if (!Enum.IsDefined(typeof(BossVanillaMode), integration.Mode))
			{
				errors.Add("VanillaIntegration Mode is not a supported value.");
			}
			else if (integration.Mode == BossVanillaMode.TemplateDefault)
			{
				if (integration.DurationSeconds.HasValue)
				{
					errors.Add("VanillaIntegration DurationSeconds must be null when Mode is TemplateDefault.");
				}
			}
			else if (!integration.DurationSeconds.HasValue)
			{
				errors.Add("VanillaIntegration DurationSeconds is required for VanillaMiniBoss and VanillaBoss modes.");
			}
			else if (!IsFinite(integration.DurationSeconds.Value) || integration.DurationSeconds.Value < 1f || integration.DurationSeconds.Value > 86400f)
			{
				errors.Add($"VanillaIntegration DurationSeconds must be a finite value between {1f} and {86400f}.");
			}
		}

		private static void ValidateEncounter(BossEncounterDefinition? encounter, ICollection<string> errors)
		{
			if (encounter == null)
			{
				errors.Add("Encounter cannot be null.");
				return;
			}
			if (encounter.MaximumOwnedMinions < 0 || encounter.MaximumOwnedMinions > 256)
			{
				errors.Add($"Encounter MaximumOwnedMinions must be between 0 and {256}.");
			}
			if (encounter.MaximumOwnedHazards < 0 || encounter.MaximumOwnedHazards > 256)
			{
				errors.Add($"Encounter MaximumOwnedHazards must be between 0 and {256}.");
			}
			if (encounter.MaximumConcurrentAbilities != 1)
			{
				errors.Add("Encounter MaximumConcurrentAbilities must be 1 because snapshots expose one active ability.");
			}
			ValidateEngagement(encounter.Engagement, errors);
			ValidateAquaticRecovery(encounter.AquaticRecovery, errors);
			if (encounter.CatchTriggers == null)
			{
				errors.Add("Encounter CatchTriggers cannot be null; use an empty collection.");
				return;
			}
			if (encounter.CatchTriggers.Count > 32)
			{
				errors.Add($"An encounter may declare at most {32} catch triggers.");
			}
			HashSet<string> hashSet = new HashSet<string>(StringComparer.Ordinal);
			for (int i = 0; i < Math.Min(encounter.CatchTriggers.Count, 32); i++)
			{
				BossCatchTriggerDefinition bossCatchTriggerDefinition = encounter.CatchTriggers[i];
				if (bossCatchTriggerDefinition == null)
				{
					errors.Add("Encounter CatchTriggers cannot contain null entries.");
					continue;
				}
				if (!EncounterContractValidation.IsSafeToken(bossCatchTriggerDefinition.Id, 128))
				{
					errors.Add($"Every catch trigger requires a normalized, control-free Id no longer than {128} characters.");
				}
				else if (!hashSet.Add(bossCatchTriggerDefinition.Id))
				{
					errors.Add("Duplicate catch trigger Id '" + bossCatchTriggerDefinition.Id + "'.");
				}
				if (string.IsNullOrWhiteSpace(bossCatchTriggerDefinition.CaughtTemplate) || bossCatchTriggerDefinition.CaughtTemplate.Length > 256)
				{
					errors.Add($"Catch trigger '{bossCatchTriggerDefinition.Id}' requires a caught template no longer than {256} characters.");
				}
				if (!IsFinite(bossCatchTriggerDefinition.Probability) || bossCatchTriggerDefinition.Probability < 0f || bossCatchTriggerDefinition.Probability > 1f)
				{
					errors.Add("Catch trigger '" + bossCatchTriggerDefinition.Id + "' Probability must be between 0 and 1.");
				}
				if (!IsFinite(bossCatchTriggerDefinition.CooldownSeconds) || bossCatchTriggerDefinition.CooldownSeconds < 0f || bossCatchTriggerDefinition.CooldownSeconds > 86400f)
				{
					errors.Add($"Catch trigger '{bossCatchTriggerDefinition.Id}' CooldownSeconds must be between 0 and {86400f}.");
				}
				if (bossCatchTriggerDefinition.MaxActivations < 0 || bossCatchTriggerDefinition.MaxActivations > 100000)
				{
					errors.Add($"Catch trigger '{bossCatchTriggerDefinition.Id}' MaxActivations must be between 0 and {100000}.");
				}
				ValidateOptionalFilter(bossCatchTriggerDefinition.RequiredRod, "RequiredRod", bossCatchTriggerDefinition.Id, errors);
				ValidateOptionalFilter(bossCatchTriggerDefinition.RequiredBait, "RequiredBait", bossCatchTriggerDefinition.Id, errors);
				if (bossCatchTriggerDefinition.ResetRodAfterReplacement && !bossCatchTriggerDefinition.ReplaceCatch)
				{
					errors.Add("Catch trigger '" + bossCatchTriggerDefinition.Id + "' ResetRodAfterReplacement requires ReplaceCatch.");
				}
				BossPlacementDefinition? placement = bossCatchTriggerDefinition.Placement;
				if (placement != null && placement.UseBossBodyClearance && (!bossCatchTriggerDefinition.ReplaceCatch || !bossCatchTriggerDefinition.RequireWater))
				{
					errors.Add("Catch trigger '" + bossCatchTriggerDefinition.Id + "' body-clearance placement requires ReplaceCatch and RequireWater.");
				}
				if (!IsFinite(bossCatchTriggerDefinition.IntroductionGraceSeconds) || bossCatchTriggerDefinition.IntroductionGraceSeconds < 0f || bossCatchTriggerDefinition.IntroductionGraceSeconds > 30f)
				{
					errors.Add("Catch trigger '" + bossCatchTriggerDefinition.Id + "' IntroductionGraceSeconds must be between 0 and " + $"{30f}.");
				}
				if (!IsFinite(bossCatchTriggerDefinition.MinimumSpawnDistance) || !IsFinite(bossCatchTriggerDefinition.MaximumSpawnDistance) || bossCatchTriggerDefinition.MinimumSpawnDistance < 0f || bossCatchTriggerDefinition.MaximumSpawnDistance < bossCatchTriggerDefinition.MinimumSpawnDistance || bossCatchTriggerDefinition.MaximumSpawnDistance > 1000f)
				{
					errors.Add($"Catch trigger '{bossCatchTriggerDefinition.Id}' spawn distances must be finite, ordered, non-negative and at most {1000f}.");
				}
			}
		}

		private static void ValidateEngagement(BossEngagementDefinition? engagement, ICollection<string> errors)
		{
			if (engagement == null)
			{
				errors.Add("Encounter Engagement cannot be null.");
				return;
			}
			if (!IsFinite(engagement.MaximumTargetDistance) || engagement.MaximumTargetDistance <= 0f || engagement.MaximumTargetDistance > 10000f)
			{
				errors.Add($"Engagement MaximumTargetDistance must be greater than zero and at most {10000f}.");
			}
			if (!IsFinite(engagement.ReengageSpeed) || engagement.ReengageSpeed <= 0f || engagement.ReengageSpeed > 1000f)
			{
				errors.Add($"Engagement ReengageSpeed must be greater than zero and at most {1000f}.");
			}
			if (!IsFinite(engagement.MaximumSpeed) || engagement.MaximumSpeed <= 0f || engagement.MaximumSpeed > 1000f)
			{
				errors.Add($"Engagement MaximumSpeed must be greater than zero and at most {1000f}.");
			}
			else if (IsFinite(engagement.ReengageSpeed) && engagement.ReengageSpeed > engagement.MaximumSpeed)
			{
				errors.Add("Engagement ReengageSpeed cannot exceed MaximumSpeed.");
			}
			if (!IsFinite(engagement.PollIntervalSeconds) || engagement.PollIntervalSeconds <= 0f || engagement.PollIntervalSeconds > 10f)
			{
				errors.Add($"Engagement PollIntervalSeconds must be greater than zero and at most {10f}.");
			}
		}

		private static void ValidateAquaticRecovery(BossAquaticRecoveryDefinition? recovery, ICollection<string> errors)
		{
			if (recovery == null)
			{
				errors.Add("Encounter AquaticRecovery cannot be null.");
				return;
			}
			ValidateAquaticRecoveryRange(recovery.MinimumDepth, 0.5f, 50f, "MinimumDepth", errors);
			ValidateAquaticRecoveryRange(recovery.MinimumTargetHeightDifference, 0.25f, 50f, "MinimumTargetHeightDifference", errors);
			ValidateAquaticRecoveryRange(recovery.StallDurationSeconds, 0.25f, 30f, "StallDurationSeconds", errors);
			ValidateAquaticRecoveryRange(recovery.MinimumProgressDistance, 0.05f, 10f, "MinimumProgressDistance", errors);
			ValidateAquaticRecoveryRange(recovery.SurfaceClearance, 0.25f, 10f, "SurfaceClearance", errors);
			ValidateAquaticRecoveryRange(recovery.MaximumSpeed, 0.5f, 12f, "MaximumSpeed", errors);
			ValidateAquaticRecoveryRange(recovery.Acceleration, 0.5f, 30f, "Acceleration", errors);
			ValidateAquaticRecoveryRange(recovery.MaximumDurationSeconds, 0.25f, 30f, "MaximumDurationSeconds", errors);
			ValidateAquaticRecoveryRange(recovery.RetryCooldownSeconds, 0.5f, 120f, "RetryCooldownSeconds", errors);
			ValidateAquaticRecoveryRange(recovery.MaximumLateralDistance, 0.5f, 30f, "MaximumLateralDistance", errors);
			ValidateAquaticRecoveryRange(recovery.ProbeIntervalSeconds, 0.1f, 1f, "ProbeIntervalSeconds", errors);
			if (IsFinite(recovery.MinimumDepth) && IsFinite(recovery.SurfaceClearance) && recovery.MinimumDepth <= recovery.SurfaceClearance)
			{
				errors.Add("AquaticRecovery MinimumDepth must be greater than SurfaceClearance.");
			}
			if (IsFinite(recovery.StallDurationSeconds) && IsFinite(recovery.ProbeIntervalSeconds) && recovery.StallDurationSeconds < recovery.ProbeIntervalSeconds)
			{
				errors.Add("AquaticRecovery StallDurationSeconds must be at least ProbeIntervalSeconds.");
			}
			if (IsFinite(recovery.MaximumDurationSeconds) && IsFinite(recovery.ProbeIntervalSeconds) && recovery.MaximumDurationSeconds < recovery.ProbeIntervalSeconds)
			{
				errors.Add("AquaticRecovery MaximumDurationSeconds must be at least ProbeIntervalSeconds.");
			}
		}

		private static void ValidateAquaticRecoveryRange(float value, float minimum, float maximum, string property, ICollection<string> errors)
		{
			if (!IsFinite(value) || value < minimum || value > maximum)
			{
				errors.Add($"AquaticRecovery {property} must be finite and between {minimum} and {maximum}.");
			}
		}

		private static void ValidatePhaseGate(BossPhaseDefinition phase, IReadOnlyList<BossAbilityDefinition> abilities, bool isFinalPhase, ICollection<string> errors)
		{
			BossPhaseGateDefinition gate = phase.Gate;
			if (gate == null)
			{
				errors.Add("Phase '" + phase.Id + "' Gate cannot be null.");
				return;
			}
			if (!IsDuration(gate.MinimumDurationSeconds))
			{
				errors.Add($"Phase '{phase.Id}' gate MinimumDurationSeconds must be between 0 and {3600f}.");
			}
			if (!IsFinite(gate.MaximumDurationSeconds) || gate.MaximumDurationSeconds <= 0f || gate.MaximumDurationSeconds > 3600f || gate.MaximumDurationSeconds < gate.MinimumDurationSeconds)
			{
				errors.Add($"Phase '{phase.Id}' gate MaximumDurationSeconds must be positive, no greater than {3600f}, and not shorter than its minimum.");
			}
			if (!string.IsNullOrEmpty(gate.RequiredAbilityId))
			{
				if (!EncounterContractValidation.IsSafeToken(gate.RequiredAbilityId, 128))
				{
					errors.Add("Phase '" + phase.Id + "' gate RequiredAbilityId must be a normalized, control-free ability ID.");
				}
				else if (!abilities.Any((BossAbilityDefinition ability) => ability != null && string.Equals(ability.Id, gate.RequiredAbilityId, StringComparison.Ordinal)))
				{
					errors.Add("Phase '" + phase.Id + "' gate RequiredAbilityId must reference an ability owned by that phase.");
				}
			}
			if (gate.ProtectFromDefeat && !gate.Enabled)
			{
				errors.Add("Phase '" + phase.Id + "' gate ProtectFromDefeat requires Enabled=true.");
			}
			if (gate.ProtectFromDefeat && !isFinalPhase)
			{
				errors.Add("Phase '" + phase.Id + "' gate ProtectFromDefeat may only be used on the final phase.");
			}
			if (gate.Enabled && phase.TriggerHealthFraction <= 0f)
			{
				errors.Add("Phase '" + phase.Id + "' must have a positive health threshold when its progression gate is enabled.");
			}
		}

		private static void ValidateOptionalFilter(string? value, string name, string triggerId, ICollection<string> errors)
		{
			if (value != null && !EncounterContractValidation.IsSafeToken(value, 256))
			{
				errors.Add($"Catch trigger '{triggerId}' {name} must be null or a normalized, control-free value no longer than {256} characters.");
			}
		}

		private static void ValidateHookStagger(BossHookStaggerDefinition? value, string path, ICollection<BossValidationIssue> issues)
		{
			if (value == null)
			{
				AddIssue(issues, "hook.missing_definition", path, "Encounter HookStagger cannot be null.");
				return;
			}
			if (!IsFinite(value.MinimumSafeTension) || !IsFinite(value.MaximumSafeTension) || value.MinimumSafeTension < 0f || value.MaximumSafeTension > 1f || value.MaximumSafeTension < value.MinimumSafeTension)
			{
				AddIssue(issues, "hook.invalid_tension_bounds", path, "HookStagger safe tension bounds must be finite, ordered and between 0 and 1.");
			}
			if (!IsFinite(value.ProgressPerSecond) || value.ProgressPerSecond < 0f || value.ProgressPerSecond > 100f || !IsFinite(value.DecayPerSecond) || value.DecayPerSecond < 0f || value.DecayPerSecond > 100f)
			{
				AddIssue(issues, "hook.invalid_rate", path, $"HookStagger progress and decay rates must be finite values between 0 and {100f}.");
			}
			if (!IsFinite(value.StaggerThreshold) || value.StaggerThreshold <= 0f || value.StaggerThreshold > 1f)
			{
				AddIssue(issues, "hook.invalid_threshold", path + ".staggerThreshold", "HookStagger StaggerThreshold must be between 0 (exclusive) and 1.");
			}
			if (!IsDuration(value.StaggerDurationSeconds) || !IsDuration(value.RecoveryDurationSeconds))
			{
				AddIssue(issues, "hook.invalid_duration", path, $"HookStagger durations must be finite values between 0 and {3600f}.");
			}
			if (value.MaximumSimultaneousHooks <= 0 || value.MaximumSimultaneousHooks > 8)
			{
				AddIssue(issues, "hook.invalid_limit", path + ".maximumSimultaneousHooks", $"HookStagger MaximumSimultaneousHooks must be between 1 and {8}.");
			}
		}

		private static void ValidatePlacement(BossPlacementDefinition? value, string path, ICollection<BossValidationIssue> issues, bool allowBossRelative, bool allowBossBodyClearance = false)
		{
			//IL_0112: Unknown result type (might be due to invalid IL or missing references)
			//IL_011f: 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_003c: Unknown result type (might be due to invalid IL or missing references)
			//IL_004e: Unknown result type (might be due to invalid IL or missing references)
			if (value == null)
			{
				return;
			}
			if (value.UseBossBodyClearance && (!allowBossBodyClearance || value.Mode != BossPlacementMode.Surface || value.FailurePolicy != BossPlacementFailurePolicy.SkipAction || value.SocketPath != null || value.LocalOffset.x != 0f || value.LocalOffset.z != 0f || value.LocalOffset.y > 0f))
			{
				AddIssue(issues, "placement.invalid_body_clearance_context", path + ".useBossBodyClearance", "Body clearance is supported only for Surface replacement catches with SkipAction, no socket, and a non-positive vertical-only LocalOffset.");
			}
			if (!Enum.IsDefined(typeof(BossPlacementMode), value.Mode))
			{
				AddIssue(issues, "placement.unsupported_mode", path + ".mode", "Placement Mode is not supported.");
			}
			else if (!allowBossRelative && value.Mode == BossPlacementMode.BossRelative)
			{
				AddIssue(issues, "placement.invalid_context", path + ".mode", "BossRelative placement cannot be used before the boss exists.");
			}
			if (!Enum.IsDefined(typeof(BossPlacementFailurePolicy), value.FailurePolicy))
			{
				AddIssue(issues, "placement.unsupported_failure_policy", path + ".failurePolicy", "Placement FailurePolicy is not supported.");
			}
			if (!IsFinite(value.LocalOffset) || !IsWithinMagnitude(value.LocalOffset, 1000f))
			{
				AddIssue(issues, "placement.invalid_offset", path + ".localOffset", $"Placement LocalOffset must be finite and bounded by {1000f}.");
			}
			if (!IsFinite(value.SearchRadius) || value.SearchRadius < 0f || value.SearchRadius > 1000f)
			{
				AddIssue(issues, "placement.invalid_search_radius", path + ".searchRadius", $"Placement SearchRadius must be between 0 and {1000f}.");
			}
			if (!IsFinite(value.VerticalSearchDistance) || value.VerticalSearchDistance < 0f || value.VerticalSearchDistance > 1000f)
			{
				AddIssue(issues, "placement.invalid_vertical_search", path + ".verticalSearchDistance", $"Placement VerticalSearchDistance must be between 0 and {1000f}.");
			}
			if (!IsFinite(value.ClearanceRadius) || value.ClearanceRadius < 0f || value.ClearanceRadius > 1000f)
			{
				AddIssue(issues, "placement.invalid_clearance", path + ".clearanceRadius", $"Placement ClearanceRadius must be between 0 and {1000f}.");
			}
			if (value.MaximumAttempts <= 0 || value.MaximumAttempts > 32)
			{
				AddIssue(issues, "placement.invalid_attempt_limit", path + ".maximumAttempts", $"Placement MaximumAttempts must be between 1 and {32}.");
			}
			if (value.Mode == BossPlacementMode.TransformSocket)
			{
				if (!IsSafeRelativePath(value.SocketPath))
				{
					AddIssue(issues, "placement.invalid_socket", path + ".socketPath", "TransformSocket placement requires a safe relative SocketPath.");
				}
			}
			else if (value.SocketPath != null)
			{
				AddIssue(issues, "placement.unused_socket", path + ".socketPath", "SocketPath may only be supplied for TransformSocket mode.");
			}
		}

		private static void ValidateFormation(BossFormationDefinition? value, int count, string path, ICollection<BossValidationIssue> issues)
		{
			if (value == null)
			{
				return;
			}
			if (!Enum.IsDefined(typeof(BossFormationKind), value.Kind))
			{
				AddIssue(issues, "formation.unsupported_kind", path + ".kind", "Formation Kind is not supported.");
			}
			if (!IsFinite(value.Radius) || value.Radius < 0f || value.Radius > 1000f)
			{
				AddIssue(issues, "formation.invalid_radius", path + ".radius", $"Formation Radius must be between 0 and {1000f}.");
			}
			if (!IsFinite(value.Spacing) || value.Spacing <= 0f || value.Spacing > 1000f)
			{
				AddIssue(issues, "formation.invalid_spacing", path + ".spacing", $"Formation Spacing must be between 0 (exclusive) and {1000f}.");
			}
			if (!IsFinite(value.AngleDegrees) || value.AngleDegrees <= 0f || value.AngleDegrees > 360f)
			{
				AddIssue(issues, "formation.invalid_angle", path + ".angleDegrees", "Formation AngleDegrees must be between 0 (exclusive) and 360.");
			}
			if (!IsFinite(value.YawOffsetDegrees) || Math.Abs(value.YawOffsetDegrees) > 36000f)
			{
				AddIssue(issues, "formation.invalid_yaw", path + ".yawOffsetDegrees", "Formation YawOffsetDegrees must be finite and bounded by 36000 degrees.");
			}
			if (value.SocketPaths == null)
			{
				AddIssue(issues, "formation.missing_sockets", path + ".socketPaths", "Formation SocketPaths cannot be null; use an empty collection.");
				return;
			}
			if (value.SocketPaths.Count > 32)
			{
				AddIssue(issues, "formation.socket_budget_exceeded", path + ".socketPaths", $"Formation may contain at most {32} socket paths.");
			}
			if (value.Kind == BossFormationKind.Sockets && value.SocketPaths.Count != count)
			{
				AddIssue(issues, "formation.socket_count_mismatch", path + ".socketPaths", "Sockets formation requires exactly one SocketPath per requested minion.");
			}
			if (value.Kind != BossFormationKind.Sockets && value.SocketPaths.Count != 0)
			{
				AddIssue(issues, "formation.unused_sockets", path + ".socketPaths", "SocketPaths may only be supplied for a Sockets formation.");
			}
			HashSet<string> hashSet = new HashSet<string>(StringComparer.Ordinal);
			for (int i = 0; i < Math.Min(value.SocketPaths.Count, 32); i++)
			{
				string text = value.SocketPaths[i];
				if (!IsSafeRelativePath(text))
				{
					AddIssue(issues, "formation.invalid_socket", path + ".socketPaths[" + i + "]", "Every formation SocketPath must be a safe relative transform path.");
				}
				else if (!hashSet.Add(text))
				{
					AddIssue(issues, "formation.duplicate_socket", path + ".socketPaths[" + i + "]", "Duplicate formation SocketPath '" + text + "'.");
				}
			}
			if ((value.Kind == BossFormationKind.Ring || value.Kind == BossFormationKind.Cone) && value.Radius <= 0f)
			{
				AddIssue(issues, "formation.invalid_radius", path + ".radius", "Ring and Cone formations require a positive Radius.");
			}
		}

		private static bool IsSafeRelativePath(string? value)
		{
			if (!string.IsNullOrWhiteSpace(value) && value.Length <= 1024 && string.Equals(value, value.Trim(), StringComparison.Ordinal) && !value.StartsWith("/", StringComparison.Ordinal) && !value.StartsWith("\\", StringComparison.Ordinal) && !value.Contains(".."))
			{
				return EncounterContractValidation.IsSafeToken(value, 1024);
			}
			return false;
		}

		private static void ValidateAbility(BossAbilityDefinition? ability, string phaseId, ISet<string> abilityIds, ICollection<string> errors, ref long declaredActiveMinions, ref long declaredExecutionClaims, bool isGlobal)
		{
			if (ability == null)
			{
				errors.Add("Phase '" + phaseId + "' contains a null ability.");
				return;
			}
			if (!EncounterContractValidation.IsSafeToken(ability.Id, 128))
			{
				errors.Add($"Every ability requires a normalized, control-free Id no longer than {128} characters.");
			}
			else if (!abilityIds.Add(ability.Id))
			{
				errors.Add("Duplicate ability Id '" + ability.Id + "'.");
			}
			if (!Enum.IsDefined(typeof(BossAbilityTrigger), ability.Trigger))
			{
				errors.Add("Ability '" + ability.Id + "' Trigger is not supported.");
			}
			else if (isGlobal && ability.Trigger == BossAbilityTrigger.PhaseEnter)
			{
				errors.Add("Global ability '" + ability.Id + "' cannot use PhaseEnter; place it on a phase.");
			}
			else if (!isGlobal && ability.Trigger == BossAbilityTrigger.OnSpawn)
			{
				errors.Add("Phase ability '" + ability.Id + "' cannot use OnSpawn; place it in BossDefinition.Abilities.");
			}
			if (!IsFinite(ability.InitialDelaySeconds) || ability.InitialDelaySeconds < 0f || ability.InitialDelaySeconds > 3600f)
			{
				errors.Add($"Ability '{ability.Id}' InitialDelaySeconds must be between 0 and {3600f}.");
			}
			if (!IsFinite(ability.CooldownSeconds) || ability.CooldownSeconds < 0f || ability.CooldownSeconds > 86400f)
			{
				errors.Add($"Ability '{ability.Id}' CooldownSeconds must be between 0 and {86400f}.");
			}
			if (ability.MaxRepeats < 0 || ability.MaxRepeats > 1024)
			{
				errors.Add($"Ability '{ability.Id}' MaxRepeats must be between 0 and {1024}.");
			}
			if (ability.MaxRepeats > 0 && (!IsFinite(ability.CooldownSeconds) || ability.CooldownSeconds <= 0f))
			{
				errors.Add("Ability '" + ability.Id + "' requires a positive CooldownSeconds when MaxRepeats is positive.");
			}
			if (!IsFinite(ability.Probability) || ability.Probability < 0f || ability.Probability > 1f)
			{
				errors.Add("Ability '" + ability.Id + "' Probability must be between 0 and 1.");
			}
			ValidateTimeline(ability.Id, ability.Timeline, errors);
			ValidateTargetSelector(ability.Id, ability.TargetSelector, errors);
			ValidateGeometry(ability.Id, ability.Geometry, errors);
			ValidateTelegraph(ability.Id, ability.Telegraph, errors);
			if (ability.Actions == null)
			{
				errors.Add("Ability '" + ability.Id + "' Actions cannot be null; use an empty collection.");
			}
			else if (ability.Actions.Count > 32)
			{
				errors.Add($"Ability '{ability.Id}' may declare at most {32} actions.");
			}
			IReadOnlyList<BossActionDefinition> readOnlyList = ability.Actions ?? Array.Empty<BossActionDefinition>();
			if (ability.Probability > 0f)
			{
				int num = Math.Min(Math.Max(ability.MaxRepeats, 0), 1024);
				declaredExecutionClaims += ((long)num + 1L) * Math.Min(readOnlyList.Count, 32);
			}
			for (int i = 0; i < Math.Min(readOnlyList.Count, 32); i++)
			{
				ValidateAction(readOnlyList[i], phaseId + "/" + ability.Id, errors, ref declaredActiveMinions, isAbilityAction: true);
				if (ability.Timeline != null)
				{
					ValidateAbilityActionTimeline(ability.Id, readOnlyList[i], ability.Timeline, errors);
				}
			}
		}

		private static void ValidateVersion4(BossDefinition definition, ICollection<BossValidationIssue> issues)
		{
			ValidateVersion4VanillaIntegration(definition.VanillaIntegration, issues);
			HashSet<string> hashSet = new HashSet<string>(StringComparer.Ordinal);
			IReadOnlyList<BossAbilityDefinition> readOnlyList = definition.Abilities ?? Array.Empty<BossAbilityDefinition>();
			for (int i = 0; i < Math.Min(readOnlyList.Count, 32); i++)
			{
				BossAbilityDefinition bossAbilityDefinition = readOnlyList[i];
				if (bossAbilityDefinition != null && EncounterContractValidation.IsSafeToken(bossAbilityDefinition.Id, 128))
				{
					hashSet.Add(bossAbilityDefinition.Id);
				}
			}
			IReadOnlyList<BossPhaseDefinition> readOnlyList2 = definition.Phases ?? Array.Empty<BossPhaseDefinition>();
			for (int j = 0; j < Math.Min(readOnlyList2.Count, 32); j++)
			{
				BossPhaseDefinition bossPhaseDefinition = readOnlyList2[j];
				if (bossPhaseDefinition == null)
				{
					continue;
				}
				IReadOnlyList<BossAbilityDefinition> readOnlyList3 = bossPhaseDefinition.Abilities ?? Array.Empty<BossAbilityDefinition>();
				for (int k = 0; k < Math.Min(readOnlyList3.Count, 32); k++)
				{
					BossAbilityDefinition bossAbilityDefinition2 = readOnlyList3[k];
					if (bossAbilityDefinition2 != null && EncounterContractValidation.IsSafeToken(bossAbilityDefinition2.Id, 128))
					{
						hashSet.Add(bossAbilityDefinition2.Id);
					}
				}
			}
			HashSet<string> actionIds = new HashSet<string>(StringComparer.Ordinal);
			HashSet<string> modifierIds = new HashSet<string>(StringComparer.Ordinal);
			int totalConditionNodes = 0;
			int reversibleModifiers = 0;
			if (definition.Encounter != null)
			{
				ValidateHookStagger(definition.Encounter.HookStagger, "encounter.hookStagger", issues);
				IReadOnlyList<BossCatchTriggerDefinition> readOnlyList4 = definition.Encounter.CatchTriggers ?? Array.Empty<BossCatchTriggerDefinition>();
				for (int l = 0; l < Math.Min(readOnlyList4.Count, 32); l++)
				{
					if (readOnlyList4[l] != null)
					{
						ValidatePlacement(readOnlyList4[l].Placement, "encounter.catchTriggers[" + l + "].placement", issues, allowBossRelative: false, allowBossBodyClearance: true);
					}
				}
			}
			IReadOnlyList<BossAbilityDefinition> readOnlyList5 = definition.Abilities ?? Array.Empty<BossAbilityDefinition>();
			for (int m = 0; m < Math.Min(readOnlyList5.Count, 32); m++)
			{
				ValidateVersion4Ability(readOnlyList5[m], "abilities[" + m + "]", null, hashSet, actionIds, modifierIds, issues, ref totalConditionNodes, ref reversibleModifiers);
			}
			IReadOnlyList<BossPhaseDefinition> readOnlyList6 = definition.Phases ?? Array.Empty<BossPhaseDefinition>();
			for (int n = 0; n < Math.Min(readOnlyList6.Count, 32); n++)
			{
				BossPhaseDefinition bossPhaseDefinition2 = readOnlyList6[n];
				if (bossPhaseDefinition2 != null)
				{
					string text = "phases[" + n + "]";
					if (bossPhaseDefinition2.ExitActions == null)
					{
						AddIssue(issues, "phase.missing_exit_actions", text + ".exitActions", "ExitActions cannot be null; use an empty collection.");
					}
					else if (bossPhaseDefinition2.ExitActions.Count > 32)
					{
						AddIssue(issues, "phase.exit_action_budget_exceeded", text + ".exitActions", $"A phase may declare at most {32} exit actions.");
					}
					ValidateVersion4Actions(bossPhaseDefinition2.Actions, text + ".actions", bossPhaseDefinition2.Id, null, isExit: false, actionIds, modifierIds, issues, ref reversibleModifiers);
					ValidateVersion4Actions(bossPhaseDefinition2.ExitActions, text + ".exitActions", bossPhaseDefinition2.Id, null, isExit: true, actionIds, modifierIds, issues, ref reversibleModifiers);
					IReadOnlyList<BossAbilityDefinition> readOnlyList7 = bossPhaseDefinition2.Abilities ?? Array.Empty<BossAbilityDefinition>();
					for (int num = 0; num < Math.Min(readOnlyList7.Count, 32); num++)
					{
						ValidateVersion4Ability(readOnlyList7[num], text + ".abilities[" + num + "]", bossPhaseDefinition2.Id, hashSet, actionIds, modifierIds, issues, ref totalConditionNodes, ref reversibleModifiers);
					}
				}
			}
			if (reversibleModifiers > 64)
			{
				AddIssue(issues

BepInEx/plugins/BossMakerAPI/BossMakerAPI.dll

Decompiled a day ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Diagnostics;
using System.Globalization;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Reflection.Emit;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Security.Cryptography;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading;
using BepInEx;
using BepInEx.Bootstrap;
using BepInEx.Configuration;
using BepInEx.Logging;
using FishNet;
using FishNet.Broadcast;
using FishNet.Connection;
using FishNet.Managing;
using FishNet.Managing.Logging;
using FishNet.Managing.Object;
using FishNet.Managing.Observing;
using FishNet.Managing.Server;
using FishNet.Object;
using FishNet.Observing;
using FishNet.Serializing;
using FishNet.Transporting;
using HarmonyLib;
using Microsoft.CodeAnalysis;
using TMPro;
using UnityEngine;
using UnityEngine.Rendering;
using UnityEngine.SceneManagement;
using UnityEngine.UI;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: InternalsVisibleTo("BossMakerAPI.Tests")]
[assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")]
[assembly: AssemblyCompany("BossMakerAPI contributors")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyDescription("Framework only. Configure each boss in its own tab. Startup and developer settings use com.skylin3.howtofish.bossmakerapi.advanced.cfg and require a restart.")]
[assembly: AssemblyFileVersion("0.10.3.0")]
[assembly: AssemblyInformationalVersion("0.10.3")]
[assembly: AssemblyProduct("BossMakerAPI")]
[assembly: AssemblyTitle("BossMakerAPI")]
[assembly: AssemblyVersion("0.2.0.0")]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[Embedded]
	[AttributeUsage(AttributeTargets.Class | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Parameter | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter, AllowMultiple = false, Inherited = false)]
	internal sealed class NullableAttribute : Attribute
	{
		public readonly byte[] NullableFlags;

		public NullableAttribute(byte P_0)
		{
			NullableFlags = new byte[1] { P_0 };
		}

		public NullableAttribute(byte[] P_0)
		{
			NullableFlags = P_0;
		}
	}
	[CompilerGenerated]
	[Embedded]
	[AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Method | AttributeTargets.Interface | AttributeTargets.Delegate, AllowMultiple = false, Inherited = false)]
	internal sealed class NullableContextAttribute : Attribute
	{
		public readonly byte Flag;

		public NullableContextAttribute(byte P_0)
		{
			Flag = P_0;
		}
	}
	[CompilerGenerated]
	[Embedded]
	[AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)]
	internal sealed class RefSafetyRulesAttribute : Attribute
	{
		public readonly int Version;

		public RefSafetyRulesAttribute(int P_0)
		{
			Version = P_0;
		}
	}
}
namespace HowToFish.BossMaker.Runtime
{
	internal sealed class AbilityTargetCandidate
	{
		internal string EntityId { get; }

		internal int? NetworkObjectId { get; }

		internal Vector3 Position { get; }

		internal object? RuntimeEntity { get; }

		internal AbilityTargetCandidate(string entityId, int? networkObjectId, Vector3 position, object? runtimeEntity = null)
		{
			//IL_002d: Unknown result type (might be due to invalid IL or missing references)
			//IL_002e: Unknown result type (might be due to invalid IL or missing references)
			if (string.IsNullOrWhiteSpace(entityId))
			{
				throw new ArgumentException("Entity ID is required.", "entityId");
			}
			EntityId = entityId;
			NetworkObjectId = networkObjectId;
			Position = position;
			RuntimeEntity = runtimeEntity;
		}

		internal EncounterEntityReference ToReference()
		{
			//IL_000c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0012: Expected O, but got Unknown
			return new EncounterEntityReference(EntityId, NetworkObjectId);
		}
	}
	internal sealed class AbilityTargetSelection
	{
		internal AbilityTargetCandidate Candidate { get; }

		internal Vector3 LockedPosition { get; }

		internal AbilityTargetSelection(AbilityTargetCandidate candidate, Vector3 lockedPosition)
		{
			//IL_001d: Unknown result type (might be due to invalid IL or missing references)
			//IL_001e: Unknown result type (might be due to invalid IL or missing references)
			Candidate = candidate ?? throw new ArgumentNullException("candidate");
			LockedPosition = lockedPosition;
		}
	}
	internal enum AbilityPlayerIneligibilityReason
	{
		MissingVitals,
		NonPositiveHealth,
		ServerNotInitialized,
		MissingOwner,
		OwnerInvalid,
		OwnerInactive,
		OwnerDisconnecting,
		NonFinitePosition
	}
	internal sealed class AbilityPlayerCapture
	{
		internal IReadOnlyList<AbilityTargetCandidate> EligibleCandidates { get; }

		internal int ObservedPlayerCount { get; }

		internal IReadOnlyDictionary<AbilityPlayerIneligibilityReason, int> IneligibilityReasons { get; }

		internal bool CaptureFailed { get; }

		internal AbilityPlayerCapture(IReadOnlyList<AbilityTargetCandidate> eligibleCandidates, int observedPlayerCount, IReadOnlyDictionary<AbilityPlayerIneligibilityReason, int>? ineligibilityReasons = null, bool captureFailed = false)
		{
			if (eligibleCandidates == null)
			{
				throw new ArgumentNullException("eligibleCandidates");
			}
			if (observedPlayerCount < 0)
			{
				throw new ArgumentOutOfRangeException("observedPlayerCount");
			}
			EligibleCandidates = eligibleCandidates.Where((AbilityTargetCandidate value) => value != null).OrderBy<AbilityTargetCandidate, string>((AbilityTargetCandidate value) => value.EntityId, StringComparer.Ordinal).ThenBy((AbilityTargetCandidate value) => value.NetworkObjectId ?? int.MaxValue)
				.ToArray();
			ObservedPlayerCount = observedPlayerCount;
			CaptureFailed = captureFailed;
			Dictionary<AbilityPlayerIneligibilityReason, int> dictionary = new Dictionary<AbilityPlayerIneligibilityReason, int>();
			if (ineligibilityReasons != null)
			{
				foreach (KeyValuePair<AbilityPlayerIneligibilityReason, int> ineligibilityReason in ineligibilityReasons)
				{
					if (ineligibilityReason.Value > 0)
					{
						dictionary[ineligibilityReason.Key] = ineligibilityReason.Value;
					}
				}
			}
			IneligibilityReasons = dictionary;
		}
	}
	internal enum AbilityTargetFailureKind
	{
		None,
		PlayerCaptureFailed,
		NoPlayersFound,
		PlayersIneligible,
		EligiblePlayersOutsideMaximumRange,
		Unclassified
	}
	internal readonly struct AbilityTargetFailureDiagnostic
	{
		internal AbilityTargetFailureKind Kind { get; }

		internal string Message { get; }

		internal AbilityTargetFailureDiagnostic(AbilityTargetFailureKind kind, string message)
		{
			Kind = kind;
			Message = message ?? string.Empty;
		}
	}
	internal static class DeterministicAbilityTargetResolver
	{
		private readonly struct RankedCandidate
		{
			internal AbilityTargetCandidate Candidate { get; }

			internal double DistanceSquared { get; }

			internal RankedCandidate(AbilityTargetCandidate candidate, double distanceSquared)
			{
				Candidate = candidate;
				DistanceSquared = distanceSquared;
			}
		}

		private const int MaximumReportedIneligibilityReasons = 5;

		internal static bool TrySelect(BossTargetSelectorDefinition selector, AbilityTargetCandidate boss, IReadOnlyList<AbilityTargetCandidate> candidates, int encounterSeed, string phaseId, string abilityId, int attemptOrdinal, out AbilityTargetSelection selection)
		{
			//IL_003d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0052: Unknown result type (might be due to invalid IL or missing references)
			//IL_0131: Unknown result type (might be due to invalid IL or missing references)
			//IL_0136: Unknown result type (might be due to invalid IL or missing references)
			//IL_0138: 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_014d: Expected I4, but got Unknown
			//IL_024f: Unknown result type (might be due to invalid IL or missing references)
			if (selector == null)
			{
				throw new ArgumentNullException("selector");
			}
			if (boss == null)
			{
				throw new ArgumentNullException("boss");
			}
			if (candidates == null)
			{
				throw new ArgumentNullException("candidates");
			}
			if ((int)selector.Kind == 0)
			{
				selection = new AbilityTargetSelection(boss, boss.Position);
				return true;
			}
			double maximumSquared = ((selector.MaximumRange <= 0f) ? double.PositiveInfinity : ((double)selector.MaximumRange * (double)selector.MaximumRange));
			RankedCandidate[] array = (from value in candidates
				where value != null && IsFinite(value.Position)
				select new RankedCandidate(value, PlanarSquared(value.Position - boss.Position)) into value
				where value.DistanceSquared <= maximumSquared
				select value).OrderBy<RankedCandidate, string>((RankedCandidate value) => value.Candidate.EntityId, StringComparer.Ordinal).ThenBy((RankedCandidate value) => value.Candidate.NetworkObjectId ?? int.MaxValue).ToArray();
			if (array.Length == 0)
			{
				selection = null;
				return false;
			}
			BossTargetSelectorKind kind = selector.Kind;
			RankedCandidate rankedCandidate;
			switch (kind - 1)
			{
			case 0:
				rankedCandidate = array.OrderBy((RankedCandidate value) => value.DistanceSquared).ThenBy<RankedCandidate, string>((RankedCandidate value) => value.Candidate.EntityId, StringComparer.Ordinal).First();
				break;
			case 1:
				rankedCandidate = array.OrderByDescending((RankedCandidate value) => value.DistanceSquared).ThenBy<RankedCandidate, string>((RankedCandidate value) => value.Candidate.EntityId, StringComparer.Ordinal).First();
				break;
			case 2:
			{
				double num = DeterministicAbilityScheduler.DeterministicProbabilitySample(encounterSeed, phaseId, abilityId + ":target", 0L, attemptOrdinal);
				rankedCandidate = array[Math.Min(array.Length - 1, (int)(num * (double)array.Length))];
				break;
			}
			default:
				throw new ArgumentOutOfRangeException("Kind");
			}
			selection = new AbilityTargetSelection(rankedCandidate.Candidate, rankedCandidate.Candidate.Position);
			return true;
		}

		internal static AbilityTargetFailureDiagnostic DiagnoseFailure(BossTargetSelectorDefinition selector, AbilityTargetCandidate boss, AbilityPlayerCapture capture)
		{
			//IL_002b: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e2: 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)
			//IL_00f6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fb: Unknown result type (might be due to invalid IL or missing references)
			//IL_0100: Unknown result type (might be due to invalid IL or missing references)
			//IL_0103: 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)
			if (selector == null)
			{
				throw new ArgumentNullException("selector");
			}
			if (boss == null)
			{
				throw new ArgumentNullException("boss");
			}
			if (capture == null)
			{
				throw new ArgumentNullException("capture");
			}
			if ((int)selector.Kind == 0)
			{
				return new AbilityTargetFailureDiagnostic(AbilityTargetFailureKind.None, string.Empty);
			}
			if (capture.CaptureFailed)
			{
				return new AbilityTargetFailureDiagnostic(AbilityTargetFailureKind.PlayerCaptureFailed, "the authoritative Player snapshot could not be inspected completely; selection failed closed");
			}
			if (capture.ObservedPlayerCount == 0)
			{
				return new AbilityTargetFailureDiagnostic(AbilityTargetFailureKind.NoPlayersFound, "no Player objects were found in the authoritative scene snapshot");
			}
			if (capture.EligibleCandidates.Count == 0)
			{
				return new AbilityTargetFailureDiagnostic(AbilityTargetFailureKind.PlayersIneligible, capture.ObservedPlayerCount.ToString(CultureInfo.InvariantCulture) + " Player object(s) were found, but none was server-eligible" + FormatIneligibilityReasons(capture.IneligibilityReasons));
			}
			if (selector.MaximumRange > 0f)
			{
				double num = double.PositiveInfinity;
				double num2 = double.PositiveInfinity;
				foreach (AbilityTargetCandidate eligibleCandidate in capture.EligibleCandidates)
				{
					if (eligibleCandidate != null && IsFinite(eligibleCandidate.Position))
					{
						Vector3 val = eligibleCandidate.Position - boss.Position;
						num = Math.Min(num, Math.Sqrt(PlanarSquared(val)));
						num2 = Math.Min(num2, Math.Abs((double)val.y));
					}
				}
				if (!double.IsInfinity(num) && !double.IsInfinity(num2))
				{
					return new AbilityTargetFailureDiagnostic(AbilityTargetFailureKind.EligiblePlayersOutsideMaximumRange, capture.EligibleCandidates.Count.ToString(CultureInfo.InvariantCulture) + " server-eligible Player object(s) were all outside planar MaximumRange=" + FormatDistance(selector.MaximumRange) + "m (minimum horizontal distance=" + FormatDistance(num) + "m; minimum absolute vertical separation=" + FormatDistance(num2) + "m; vertical separation does not affect range selection)");
				}
			}
			return new AbilityTargetFailureDiagnostic(AbilityTargetFailureKind.Unclassified, "target selection failed closed for a bounded, unclassified reason (observed=" + capture.ObservedPlayerCount.ToString(CultureInfo.InvariantCulture) + ", eligible=" + capture.EligibleCandidates.Count.ToString(CultureInfo.InvariantCulture) + ")");
		}

		private static string FormatIneligibilityReasons(IReadOnlyDictionary<AbilityPlayerIneligibilityReason, int> reasons)
		{
			KeyValuePair<AbilityPlayerIneligibilityReason, int>[] array = (from pair in reasons
				where pair.Value > 0
				orderby (int)pair.Key
				select pair).ToArray();
			if (array.Length == 0)
			{
				return " (reason unavailable)";
			}
			List<string> list = (from pair in array.Take(5)
				select ReasonLabel(pair.Key) + "=" + pair.Value.ToString(CultureInfo.InvariantCulture)).ToList();
			if (array.Length > 5)
			{
				list.Add("other=" + array.Skip(5).Sum((KeyValuePair<AbilityPlayerIneligibilityReason, int> pair) => pair.Value).ToString(CultureInfo.InvariantCulture));
			}
			return " (" + string.Join("; ", list) + ")";
		}

		private static string ReasonLabel(AbilityPlayerIneligibilityReason reason)
		{
			return reason switch
			{
				AbilityPlayerIneligibilityReason.MissingVitals => "missing vitals", 
				AbilityPlayerIneligibilityReason.NonPositiveHealth => "non-positive health", 
				AbilityPlayerIneligibilityReason.ServerNotInitialized => "server not initialized", 
				AbilityPlayerIneligibilityReason.MissingOwner => "missing owner", 
				AbilityPlayerIneligibilityReason.OwnerInvalid => "invalid owner", 
				AbilityPlayerIneligibilityReason.OwnerInactive => "inactive owner", 
				AbilityPlayerIneligibilityReason.OwnerDisconnecting => "disconnecting owner", 
				AbilityPlayerIneligibilityReason.NonFinitePosition => "non-finite position", 
				_ => "unknown", 
			};
		}

		private static string FormatDistance(double value)
		{
			return value.ToString("0.###", CultureInfo.InvariantCulture);
		}

		private static double PlanarSquared(Vector3 value)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0007: 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_0016: Unknown result type (might be due to invalid IL or missing references)
			return (double)value.x * (double)value.x + (double)value.z * (double)value.z;
		}

		internal static bool IsFinitePosition(Vector3 value)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			return IsFinite(value);
		}

		private static bool IsFinite(Vector3 value)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_000d: 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_0027: 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_0041: Unknown result type (might be due to invalid IL or missing references)
			if (!float.IsNaN(value.x) && !float.IsInfinity(value.x) && !float.IsNaN(value.y) && !float.IsInfinity(value.y) && !float.IsNaN(value.z))
			{
				return !float.IsInfinity(value.z);
			}
			return false;
		}
	}
	internal static class GameAbilityTargetSource
	{
		internal static IReadOnlyList<AbilityTargetCandidate> CaptureAlivePlayers(Action<string> warning)
		{
			return CapturePlayers(warning).EligibleCandidates;
		}

		internal static AbilityPlayerCapture CapturePlayers(Action<string> warning)
		{
			//IL_010e: Unknown result type (might be due to invalid IL or missing references)
			List<AbilityTargetCandidate> list = new List<AbilityTargetCandidate>();
			Dictionary<AbilityPlayerIneligibilityReason, int> dictionary = new Dictionary<AbilityPlayerIneligibilityReason, int>();
			int num = 0;
			bool captureFailed = false;
			try
			{
				List<Player> alivePlayers = PlayerManager.AlivePlayers;
				Player[] array = ((alivePlayers != null && alivePlayers.Count != 0) ? alivePlayers.ToArray() : Object.FindObjectsByType<Player>((FindObjectsInactive)0));
				foreach (Player val in array)
				{
					if (!((Object)(object)val == (Object)null))
					{
						num++;
						Vector3 position;
						AbilityPlayerIneligibilityReason? ineligibilityReason = GetIneligibilityReason(val, out position);
						if (ineligibilityReason.HasValue)
						{
							dictionary.TryGetValue(ineligibilityReason.Value, out var value);
							dictionary[ineligibilityReason.Value] = value + 1;
						}
						else
						{
							int? networkObjectId = (((Object)(object)((NetworkBehaviour)val).NetworkObject == (Object)null) ? ((int?)null) : new int?(((NetworkBehaviour)val).NetworkObject.ObjectId));
							string entityId = (networkObjectId.HasValue ? ("player:" + networkObjectId.Value.ToString(CultureInfo.InvariantCulture)) : ("player-owner:" + ((NetworkBehaviour)val).Owner.ClientId.ToString(CultureInfo.InvariantCulture)));
							list.Add(new AbilityTargetCandidate(entityId, networkObjectId, position, val));
						}
					}
				}
			}
			catch (Exception ex)
			{
				captureFailed = true;
				warning("Could not enumerate alive players for an ability: " + ex.Message);
			}
			return new AbilityPlayerCapture(list, num, dictionary, captureFailed);
		}

		internal static Player? ResolvePlayer(EncounterEntityReference reference, bool requireServerEligibility = true)
		{
			if (reference == null)
			{
				return null;
			}
			Player[] array;
			try
			{
				array = Object.FindObjectsByType<Player>((FindObjectsInactive)0);
			}
			catch
			{
				return null;
			}
			Player[] array2 = array;
			foreach (Player val in array2)
			{
				if (!((Object)(object)val == (Object)null) && (!requireServerEligibility || IsEligible(val)))
				{
					int? num = (((Object)(object)((NetworkBehaviour)val).NetworkObject == (Object)null) ? ((int?)null) : new int?(((NetworkBehaviour)val).NetworkObject.ObjectId));
					if (string.Equals(num.HasValue ? ("player:" + num.Value.ToString(CultureInfo.InvariantCulture)) : ((((NetworkBehaviour)val).Owner == (NetworkConnection)null) ? string.Empty : ("player-owner:" + ((NetworkBehaviour)val).Owner.ClientId.ToString(CultureInfo.InvariantCulture))), reference.EntityId, StringComparison.Ordinal) || (reference.NetworkObjectId.HasValue && num == reference.NetworkObjectId))
					{
						return val;
					}
				}
			}
			return null;
		}

		internal static bool IsEligible(Player? player)
		{
			if ((Object)(object)player == (Object)null || (Object)(object)player.Vitals == (Object)null || player.Vitals.Health <= 0 || !((NetworkBehaviour)player).IsServerInitialized)
			{
				return false;
			}
			NetworkConnection owner = ((NetworkBehaviour)player).Owner;
			if (owner != (NetworkConnection)null && owner.IsValid && owner.IsActive)
			{
				return !owner.Disconnecting;
			}
			return false;
		}

		private static AbilityPlayerIneligibilityReason? GetIneligibilityReason(Player player, out Vector3 position)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			position = default(Vector3);
			if ((Object)(object)player.Vitals == (Object)null)
			{
				return AbilityPlayerIneligibilityReason.MissingVitals;
			}
			if (player.Vitals.Health <= 0)
			{
				return AbilityPlayerIneligibilityReason.NonPositiveHealth;
			}
			if (!((NetworkBehaviour)player).IsServerInitialized)
			{
				return AbilityPlayerIneligibilityReason.ServerNotInitialized;
			}
			NetworkConnection owner = ((NetworkBehaviour)player).Owner;
			if (owner == (NetworkConnection)null)
			{
				return AbilityPlayerIneligibilityReason.MissingOwner;
			}
			if (!owner.IsValid)
			{
				return AbilityPlayerIneligibilityReason.OwnerInvalid;
			}
			if (!owner.IsActive)
			{
				return AbilityPlayerIneligibilityReason.OwnerInactive;
			}
			if (owner.Disconnecting)
			{
				return AbilityPlayerIneligibilityReason.OwnerDisconnecting;
			}
			if (!PlayerCombatAnchorAdapter.TryGetPosition(player, out position))
			{
				return AbilityPlayerIneligibilityReason.NonFinitePosition;
			}
			return null;
		}
	}
	internal sealed class AbilityTelegraphPresenter : IDisposable
	{
		private const int CurvedSegments = 64;

		private const int SweepSegments = 32;

		private const float FillHeight = 0.006f;

		private const float ProgressHeight = 0.012f;

		private const float LineHeight = 0.018f;

		private const float AfterglowHeight = 0.024f;

		private const double AfterglowDurationSeconds = 0.32;

		private static bool _shaderWarmupSucceeded;

		private readonly Transform _owner;

		private readonly double _minimumLeadTime;

		private readonly List<Vector3> _scratchVertices = new List<Vector3>(132);

		private readonly List<int> _scratchTriangles = new List<int>(384);

		private readonly List<Color> _scratchColors = new List<Color>(132);

		private GameObject? _root;

		private GameObject? _afterglowRoot;

		private LineRenderer? _primary;

		private LineRenderer? _secondary;

		private LineRenderer? _pattern;

		private LineRenderer? _sweep;

		private LineRenderer? _impact;

		private Mesh? _fillMesh;

		private Mesh? _progressMesh;

		private Mesh? _afterglowMesh;

		private MeshRenderer? _fillRenderer;

		private MeshRenderer? _progressRenderer;

		private MeshRenderer? _afterglowRenderer;

		private MaterialPropertyBlock? _propertyBlock;

		private Material? _material;

		private GameObject? _audioObject;

		private BossTelegraphDefinition? _definition;

		private ResolvedAbilityGeometry _geometry;

		private ResolvedAbilityGeometry _afterglowGeometry;

		private double _telegraphTime;

		private double _resolveTime;

		private double _afterglowStartTime;

		private double _afterglowEndTime;

		private Color _afterglowColor;

		private Color _afterglowBorderColor;

		private float _afterglowBorderWidth;

		private float _progress;

		private bool _visible;

		private bool _afterglowVisible;

		internal bool IsVisible => _visible;

		internal AbilityTelegraphPresenter(Transform owner, double minimumLeadTime)
		{
			_owner = owner ?? throw new ArgumentNullException("owner");
			if (double.IsNaN(minimumLeadTime) || double.IsInfinity(minimumLeadTime) || minimumLeadTime < 0.0)
			{
				throw new ArgumentOutOfRangeException("minimumLeadTime");
			}
			_minimumLeadTime = minimumLeadTime;
		}

		internal bool TryPrepare(out string diagnostic)
		{
			//IL_0022: Unknown result type (might be due to invalid IL or missing references)
			//IL_002c: Expected O, but got Unknown
			Stopwatch stopwatch = Stopwatch.StartNew();
			try
			{
				bool flag = (Object)(object)_root != (Object)null;
				EnsureRig();
				if (_propertyBlock == null)
				{
					_propertyBlock = new MaterialPropertyBlock();
				}
				diagnostic = FormattableString.Invariant(FormattableStringFactory.Create("Telegraph presentation {0}: 10 objects, 3 meshes, 5 lines; {1:0.###} ms CPU.", flag ? "already prepared" : "prepared invisibly", stopwatch.Elapsed.TotalMilliseconds));
				return true;
			}
			catch (Exception ex)
			{
				try
				{
					Dispose();
				}
				catch
				{
				}
				diagnostic = FormattableString.Invariant($"Telegraph preparation failed after {stopwatch.Elapsed.TotalMilliseconds:0.###} ms CPU: {ex.GetType().Name}: {ex.Message}");
				return false;
			}
		}

		internal static bool TryWarmUpShader(out string diagnostic)
		{
			//IL_000f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0015: Invalid comparison between Unknown and I4
			//IL_0050: 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_0060: Unknown result type (might be due to invalid IL or missing references)
			//IL_0069: Expected O, but got Unknown
			//IL_0071: Unknown result type (might be due to invalid IL or missing references)
			Stopwatch stopwatch = Stopwatch.StartNew();
			ShaderVariantCollection val = null;
			try
			{
				if (_shaderWarmupSucceeded || (int)SystemInfo.graphicsDeviceType == 4)
				{
					diagnostic = (_shaderWarmupSucceeded ? "Telegraph shader was already warmed." : "Telegraph shader warm-up skipped: no graphics device.");
					return true;
				}
				Shader val2 = FindPresentationShader();
				if ((Object)(object)val2 == (Object)null)
				{
					diagnostic = "Telegraph shader warm-up skipped: no supported unlit shader was found.";
					return false;
				}
				val = new ShaderVariantCollection
				{
					name = "BossMakerAPI.TelegraphShaderWarmup",
					hideFlags = (HideFlags)61
				};
				val.Add(new ShaderVariant(val2, (PassType)0, Array.Empty<string>()));
				val.WarmUp();
				_shaderWarmupSucceeded = true;
				diagnostic = FormattableString.Invariant($"Telegraph shader warm-up: '{((Object)val2).name}', {val.variantCount} variant; {stopwatch.Elapsed.TotalMilliseconds:0.###} ms CPU.");
				return true;
			}
			catch (Exception ex)
			{
				diagnostic = FormattableString.Invariant($"Telegraph shader warm-up failed after {stopwatch.Elapsed.TotalMilliseconds:0.###} ms CPU: {ex.GetType().Name}: {ex.Message}");
				return false;
			}
			finally
			{
				if ((Object)(object)val != (Object)null)
				{
					Object.Destroy((Object)(object)val);
				}
			}
		}

		private static Shader? FindPresentationShader()
		{
			return Shader.Find("Sprites/Default") ?? Shader.Find("Unlit/Color");
		}

		internal void Show(BossTelegraphDefinition definition, ResolvedAbilityGeometry geometry, double telegraphServerTime, double resolveServerTime, double currentServerTime)
		{
			//IL_00cc: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d6: Expected O, but got Unknown
			//IL_00e3: Unknown result type (might be due to invalid IL or missing references)
			if (definition == null)
			{
				throw new ArgumentNullException("definition");
			}
			Hide();
			ClearAfterglow();
			if (definition.Enabled && !(currentServerTime > resolveServerTime - _minimumLeadTime))
			{
				EnsureRig();
				_definition = definition;
				_geometry = geometry;
				_telegraphTime = telegraphServerTime;
				_resolveTime = resolveServerTime;
				_visible = true;
				if ((Object)(object)_root != (Object)null)
				{
					_root.SetActive(true);
				}
				double num = Math.Max(0.001, _resolveTime - _telegraphTime);
				_progress = Mathf.Clamp01((float)((currentServerTime - _telegraphTime) / num));
				Draw();
				UpdateTelegraphStyle(currentServerTime);
				if ((Object)(object)definition.AudioClip != (Object)null)
				{
					_audioObject = new GameObject("BossMakerAPI.AbilityTelegraphAudio");
					_audioObject.transform.position = geometry.Origin;
					AudioSource obj = _audioObject.AddComponent<AudioSource>();
					obj.clip = definition.AudioClip;
					obj.volume = definition.AudioVolume;
					obj.spatialBlend = 1f;
					obj.Play();
					Object.Destroy((Object)(object)_audioObject, Math.Max(0.1f, definition.AudioClip.length + 0.1f));
				}
			}
		}

		internal void Retarget(Vector3 targetPosition)
		{
			//IL_0010: Unknown result type (might be due to invalid IL or missing references)
			if (_visible)
			{
				_geometry = _geometry.Retarget(targetPosition);
				Draw();
			}
		}

		internal void UpdateGeometry(ResolvedAbilityGeometry geometry)
		{
			if (_visible)
			{
				_geometry = geometry;
				Draw();
			}
		}

		internal void Tick(double currentServerTime)
		{
			TickAfterglow(currentServerTime);
			if (_visible && _definition != null)
			{
				if (currentServerTime >= _resolveTime)
				{
					BeginAfterglow(currentServerTime);
					Hide();
				}
				else
				{
					double num = Math.Max(0.001, _resolveTime - _telegraphTime);
					_progress = Mathf.Clamp01((float)((currentServerTime - _telegraphTime) / num));
					UpdateTelegraphStyle(currentServerTime);
				}
			}
		}

		internal void Hide()
		{
			_visible = false;
			_definition = null;
			if ((Object)(object)_root != (Object)null)
			{
				_root.SetActive(false);
			}
			if ((Object)(object)_audioObject != (Object)null)
			{
				AudioSource component = _audioObject.GetComponent<AudioSource>();
				if ((Object)(object)component != (Object)null)
				{
					component.Stop();
				}
				Object.Destroy((Object)(object)_audioObject);
				_audioObject = null;
			}
		}

		private void EnsureRig()
		{
			//IL_0015: Unknown result type (might be due to invalid IL or missing references)
			//IL_001f: Expected O, but got Unknown
			//IL_0109: Unknown result type (might be due to invalid IL or missing references)
			//IL_0113: Expected O, but got Unknown
			if (!((Object)(object)_root != (Object)null))
			{
				_root = new GameObject("BossMakerAPI.AbilityTelegraph");
				_root.SetActive(false);
				_root.transform.SetParent(_owner, false);
				EnsureMaterial();
				_fillRenderer = CreateMeshLayer("DangerFill", _root.transform, out _fillMesh, -2);
				_progressRenderer = CreateMeshLayer("ResolveProgress", _root.transform, out _progressMesh, -1);
				_primary = CreateLine("Primary", _root.transform, 1);
				_secondary = CreateLine("Secondary", _root.transform, 2);
				_pattern = CreateLine("ColorBlindPattern", _root.transform, 4);
				_sweep = CreateLine("ResolveSweep", _root.transform, 3);
				_afterglowRoot = new GameObject("BossMakerAPI.AbilityImpactAfterglow");
				_afterglowRoot.SetActive(false);
				_afterglowRoot.transform.SetParent(_owner, false);
				_afterglowRenderer = CreateMeshLayer("ImpactFill", _afterglowRoot.transform, out _afterglowMesh, 5);
				_impact = CreateLine("ImpactEdge", _afterglowRoot.transform, 6);
				_afterglowRoot.SetActive(false);
			}
		}

		private void EnsureMaterial()
		{
			//IL_0021: Unknown result type (might be due to invalid IL or missing references)
			//IL_0026: Unknown result type (might be due to invalid IL or missing references)
			//IL_0036: Expected O, but got Unknown
			//IL_0053: 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)
			if ((Object)(object)_material != (Object)null)
			{
				return;
			}
			Shader val = FindPresentationShader();
			if (!((Object)(object)val == (Object)null))
			{
				_material = new Material(val)
				{
					name = "BossMakerAPI.TelegraphMaterial"
				};
				if (_material.HasProperty("_Color"))
				{
					_material.SetColor("_Color", Color.white);
				}
				if (_material.HasProperty("_BaseColor"))
				{
					_material.SetColor("_BaseColor", Color.white);
				}
				if (_material.HasProperty("_Surface"))
				{
					_material.SetFloat("_Surface", 1f);
				}
				if (_material.HasProperty("_SrcBlend"))
				{
					_material.SetFloat("_SrcBlend", 5f);
				}
				if (_material.HasProperty("_DstBlend"))
				{
					_material.SetFloat("_DstBlend", 10f);
				}
				if (_material.HasProperty("_ZWrite"))
				{
					_material.SetFloat("_ZWrite", 0f);
				}
				if (_material.HasProperty("_Cull"))
				{
					_material.SetFloat("_Cull", 0f);
				}
				_material.SetOverrideTag("RenderType", "Transparent");
				_material.EnableKeyword("_SURFACE_TYPE_TRANSPARENT");
				_material.renderQueue = 3000;
			}
		}

		private MeshRenderer CreateMeshLayer(string name, Transform parent, out Mesh mesh, int sortingOrder)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_0013: 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_0056: Unknown result type (might be due to invalid IL or missing references)
			//IL_0068: Expected O, but got Unknown
			GameObject val = new GameObject(name);
			val.transform.SetParent(parent, false);
			MeshFilter val2 = val.AddComponent<MeshFilter>();
			MeshRenderer val3 = val.AddComponent<MeshRenderer>();
			((Renderer)val3).receiveShadows = false;
			((Renderer)val3).shadowCastingMode = (ShadowCastingMode)0;
			((Renderer)val3).sortingOrder = sortingOrder;
			if ((Object)(object)_material != (Object)null)
			{
				((Renderer)val3).sharedMaterial = _material;
			}
			mesh = new Mesh
			{
				name = "BossMakerAPI." + name
			};
			mesh.MarkDynamic();
			val2.sharedMesh = mesh;
			return val3;
		}

		private LineRenderer CreateLine(string name, Transform parent, int sortingOrder)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			GameObject val = new GameObject(name);
			val.transform.SetParent(parent, false);
			LineRenderer val2 = val.AddComponent<LineRenderer>();
			val2.positionCount = 0;
			val2.useWorldSpace = true;
			((Renderer)val2).receiveShadows = false;
			((Renderer)val2).shadowCastingMode = (ShadowCastingMode)0;
			((Renderer)val2).sortingOrder = sortingOrder;
			val2.numCapVertices = 2;
			val2.numCornerVertices = 2;
			if ((Object)(object)_material != (Object)null)
			{
				((Renderer)val2).sharedMaterial = _material;
			}
			return val2;
		}

		private void Draw()
		{
			//IL_0071: Unknown result type (might be due to invalid IL or missing references)
			//IL_0076: Unknown result type (might be due to invalid IL or missing references)
			//IL_0077: Unknown result type (might be due to invalid IL or missing references)
			//IL_008d: Expected I4, but got Unknown
			//IL_009e: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ff: Unknown result type (might be due to invalid IL or missing references)
			//IL_0125: Unknown result type (might be due to invalid IL or missing references)
			//IL_0150: Unknown result type (might be due to invalid IL or missing references)
			//IL_015b: Unknown result type (might be due to invalid IL or missing references)
			//IL_018c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0197: Unknown result type (might be due to invalid IL or missing references)
			//IL_01bf: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ca: 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)
			//IL_0206: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)_primary == (Object)null || (Object)(object)_secondary == (Object)null)
			{
				return;
			}
			if ((Object)(object)_fillMesh != (Object)null && (Object)(object)_root != (Object)null)
			{
				BuildAreaMesh(_fillMesh, _root.transform, _geometry, 1f, 1f, 0.006f);
			}
			DrawProgress();
			BossAbilityGeometryKind kind = _geometry.Kind;
			switch ((int)kind)
			{
			case 0:
				DrawRing(_primary, _geometry.Origin, _geometry.Primary, 0.018f);
				DrawRing(_secondary, _geometry.Origin, Math.Max(0.05f, _geometry.Primary - 0.12f), 0.02f);
				break;
			case 1:
				DrawRing(_primary, _geometry.Origin, _geometry.Primary, 0.018f);
				DrawRing(_secondary, _geometry.Origin, _geometry.Secondary, 0.02f);
				break;
			case 2:
				DrawRectangle(_primary, _geometry.Origin, _geometry.Direction, _geometry.Primary, _geometry.Secondary, 0.018f);
				DrawCenterLine(_secondary, _geometry.Origin, _geometry.Direction, _geometry.Primary, 0.02f);
				break;
			case 3:
				DrawCone(_primary, _geometry.Origin, _geometry.Direction, _geometry.Primary, _geometry.Secondary, 0.018f);
				DrawCenterLine(_secondary, _geometry.Origin, _geometry.Direction, _geometry.Primary, 0.02f);
				break;
			}
			if ((Object)(object)_pattern != (Object)null)
			{
				LineRenderer? pattern = _pattern;
				BossTelegraphDefinition? definition = _definition;
				((Renderer)pattern).enabled = definition != null && definition.UseColorBlindPattern;
				if (((Renderer)_pattern).enabled)
				{
					DrawAccessibilityPattern(_pattern, _geometry);
				}
			}
			DrawSweep();
		}

		private static void DrawAccessibilityPattern(LineRenderer line, ResolvedAbilityGeometry geometry)
		{
			//IL_0009: Unknown result type (might be due to invalid IL or missing references)
			//IL_000e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0010: Unknown result type (might be due to invalid IL or missing references)
			//IL_0027: Expected I4, but got Unknown
			//IL_0032: Unknown result type (might be due to invalid IL or missing references)
			//IL_0038: Invalid comparison between Unknown and I4
			//IL_00c4: 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_017c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0188: Unknown result type (might be due to invalid IL or missing references)
			//IL_0124: Unknown result type (might be due to invalid IL or missing references)
			//IL_012b: Unknown result type (might be due to invalid IL or missing references)
			//IL_013a: Unknown result type (might be due to invalid IL or missing references)
			//IL_013f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0144: Unknown result type (might be due to invalid IL or missing references)
			//IL_0147: 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_0151: Unknown result type (might be due to invalid IL or missing references)
			//IL_015b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0160: 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)
			//IL_0219: Unknown result type (might be due to invalid IL or missing references)
			//IL_021e: 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)
			//IL_00a4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a9: Unknown result type (might be due to invalid IL or missing references)
			line.loop = false;
			BossAbilityGeometryKind kind = geometry.Kind;
			switch ((int)kind)
			{
			case 0:
			case 1:
			{
				float primary = geometry.Primary;
				float num5 = (((int)geometry.Kind == 1) ? geometry.Secondary : (geometry.Primary * 0.72f));
				line.positionCount = 32;
				for (int j = 0; j < 32; j++)
				{
					float num6 = (float)j * MathF.PI * 2f / 31f;
					float num7 = ((j % 2 == 0) ? num5 : primary);
					line.SetPosition(j, geometry.Origin + new Vector3(Mathf.Cos(num6) * num7, 0.015f, Mathf.Sin(num6) * num7));
				}
				break;
			}
			case 2:
			{
				Vector3 val = default(Vector3);
				((Vector3)(ref val))..ctor(0f - geometry.Direction.z, 0f, geometry.Direction.x);
				line.positionCount = 16;
				for (int k = 0; k < 16; k++)
				{
					float num8 = (float)k / 15f;
					float num9 = ((k % 2 == 0) ? (-1f) : 1f) * geometry.Secondary * 0.42f;
					line.SetPosition(k, geometry.Origin + geometry.Direction * (geometry.Primary * num8) + val * num9 + Vector3.up * 0.015f);
				}
				break;
			}
			case 3:
			{
				float num = Mathf.Atan2(geometry.Direction.z, geometry.Direction.x);
				float num2 = geometry.Secondary * 0.5f * (MathF.PI / 180f);
				line.positionCount = 16;
				for (int i = 0; i < 16; i++)
				{
					float num3 = Mathf.Lerp(num - num2, num + num2, (float)i / 15f);
					float num4 = ((i % 2 == 0) ? (geometry.Primary * 0.35f) : (geometry.Primary * 0.92f));
					line.SetPosition(i, geometry.Origin + new Vector3(Mathf.Cos(num3) * num4, 0.015f, Mathf.Sin(num3) * num4));
				}
				break;
			}
			}
		}

		private void UpdateTelegraphStyle(double currentServerTime)
		{
			//IL_009b: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00dd: 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)
			//IL_013c: 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)
			//IL_017f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0189: Unknown result type (might be due to invalid IL or missing references)
			if (_definition != null)
			{
				float num = Smooth(_progress);
				float num2 = (float)(currentServerTime * Math.PI * 2.0 * (double)_definition.PulseFrequency);
				float num3 = 0.5f + 0.5f * Mathf.Sin(num2);
				float num4 = Mathf.Lerp(0.82f, 1.16f, num3);
				float num5 = Mathf.Lerp(0.48f, 1f, num) * num4;
				float num6 = _definition.BorderWidth * Mathf.Lerp(0.82f, 1.22f, num);
				ApplyStyle(_primary, _definition.Color, num5, num6, secondary: false);
				ApplyStyle(_secondary, _definition.BorderColor, num5 * 0.92f, num6 * 0.55f, secondary: true);
				ApplyStyle(_pattern, _definition.BorderColor, Mathf.Lerp(0.62f, 1f, num), num6 * 0.48f, secondary: true);
				ApplyStyle(_sweep, _definition.BorderColor, Mathf.Lerp(0.55f, 1f, num), num6 * 0.95f, secondary: false);
				ApplyMeshStyle(_fillRenderer, _definition.Color, Mathf.Lerp(0.1f, 0.24f, num) * Mathf.Lerp(0.86f, 1.08f, num3));
				ApplyMeshStyle(_progressRenderer, Color.Lerp(_definition.Color, _definition.BorderColor, 0.35f), Mathf.Lerp(0.12f, 0.34f, num));
				if ((Object)(object)_fillMesh != (Object)null && (Object)(object)_root != (Object)null)
				{
					BuildAreaMesh(_fillMesh, _root.transform, _geometry, 1f, 1f, 0.006f);
				}
				DrawProgress();
				DrawSweep();
			}
		}

		private void DrawProgress()
		{
			if (!((Object)(object)_progressMesh == (Object)null) && !((Object)(object)_root == (Object)null))
			{
				BuildAreaMesh(_progressMesh, _root.transform, _geometry, Math.Max(0.001f, _progress), 1f, 0.012f);
			}
		}

		private void DrawSweep()
		{
			//IL_0021: Unknown result type (might be due to invalid IL or missing references)
			//IL_0026: Unknown result type (might be due to invalid IL or missing references)
			//IL_0027: Unknown result type (might be due to invalid IL or missing references)
			//IL_003d: Expected I4, but got Unknown
			//IL_004a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0098: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00db: Unknown result type (might be due to invalid IL or missing references)
			//IL_010f: Unknown result type (might be due to invalid IL or missing references)
			//IL_011a: Unknown result type (might be due to invalid IL or missing references)
			if (!((Object)(object)_sweep == (Object)null))
			{
				float num = Smooth(_progress);
				BossAbilityGeometryKind kind = _geometry.Kind;
				switch ((int)kind)
				{
				case 0:
					DrawRing(_sweep, _geometry.Origin, Mathf.Lerp(_geometry.Primary * 1.04f, Math.Max(0.08f, _geometry.Primary * 0.1f), num), 0.022f);
					break;
				case 1:
					DrawRing(_sweep, _geometry.Origin, Mathf.Lerp(_geometry.Primary, _geometry.Secondary, num), 0.022f);
					break;
				case 2:
					DrawCrossbar(_sweep, _geometry.Origin, _geometry.Direction, _geometry.Primary * num, _geometry.Secondary, 0.022f);
					break;
				case 3:
					DrawConeArc(_sweep, _geometry.Origin, _geometry.Direction, Math.Max(0.08f, _geometry.Primary * num), _geometry.Secondary, 0.022f);
					break;
				}
			}
		}

		private void BeginAfterglow(double currentServerTime)
		{
			//IL_003d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0042: Unknown result type (might be due to invalid IL or missing references)
			//IL_004e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0053: Unknown result type (might be due to invalid IL or missing references)
			if (_definition != null && !((Object)(object)_afterglowRoot == (Object)null) && !(currentServerTime > _resolveTime + 0.32))
			{
				_afterglowGeometry = _geometry;
				_afterglowColor = _definition.Color;
				_afterglowBorderColor = _definition.BorderColor;
				_afterglowBorderWidth = _definition.BorderWidth;
				_afterglowStartTime = _resolveTime;
				_afterglowEndTime = _resolveTime + 0.32;
				_afterglowVisible = true;
				_afterglowRoot.SetActive(true);
				TickAfterglow(currentServerTime);
			}
		}

		private void TickAfterglow(double currentServerTime)
		{
			//IL_00af: 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_00bf: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ee: Unknown result type (might be due to invalid IL or missing references)
			if (!_afterglowVisible)
			{
				return;
			}
			if (currentServerTime >= _afterglowEndTime || (Object)(object)_afterglowRoot == (Object)null)
			{
				ClearAfterglow();
				return;
			}
			float num = Mathf.Clamp01((float)((currentServerTime - _afterglowStartTime) / 0.32));
			float num2 = 1f - (1f - num) * (1f - num);
			float num3 = 1f - Smooth(num);
			float expansion = 1f + num2 * 0.1f;
			if ((Object)(object)_afterglowMesh != (Object)null)
			{
				BuildAreaMesh(_afterglowMesh, _afterglowRoot.transform, _afterglowGeometry, 1f, expansion, 0.024f);
			}
			ApplyMeshStyle(_afterglowRenderer, Color.Lerp(_afterglowColor, _afterglowBorderColor, 0.55f), 0.42f * num3);
			DrawGeometryOutline(_impact, _afterglowGeometry, expansion, 0.028f);
			ApplyStyle(_impact, _afterglowBorderColor, num3, _afterglowBorderWidth * Mathf.Lerp(1.45f, 0.55f, num2), secondary: false);
		}

		private void ClearAfterglow()
		{
			_afterglowVisible = false;
			if ((Object)(object)_afterglowRoot != (Object)null)
			{
				_afterglowRoot.SetActive(false);
			}
			if ((Object)(object)_afterglowMesh != (Object)null)
			{
				_afterglowMesh.Clear(false);
			}
			if ((Object)(object)_impact != (Object)null)
			{
				_impact.positionCount = 0;
			}
		}

		private void BuildAreaMesh(Mesh mesh, Transform localSpace, ResolvedAbilityGeometry geometry, float fraction, float expansion, float height)
		{
			//IL_003a: Unknown result type (might be due to invalid IL or missing references)
			//IL_003f: 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_0056: Expected I4, but got Unknown
			//IL_005f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0080: 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_00af: 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_00df: Unknown result type (might be due to invalid IL or missing references)
			//IL_011d: Unknown result type (might be due to invalid IL or missing references)
			_scratchVertices.Clear();
			_scratchTriangles.Clear();
			_scratchColors.Clear();
			fraction = Mathf.Clamp01(fraction);
			expansion = Math.Max(0.01f, expansion);
			BossAbilityGeometryKind kind = geometry.Kind;
			switch ((int)kind)
			{
			case 0:
				AddDisc(localSpace, geometry.Origin, geometry.Primary * expansion, fraction, height);
				break;
			case 1:
				AddAnnulus(localSpace, geometry.Origin, geometry.Secondary * expansion, geometry.Primary * expansion, fraction, height);
				break;
			case 2:
				AddRectangle(localSpace, geometry.Origin, geometry.Direction, geometry.Primary * expansion * fraction, geometry.Secondary * expansion, height);
				break;
			case 3:
				AddConeSector(localSpace, geometry.Origin, geometry.Direction, geometry.Primary * expansion, geometry.Secondary, fraction, height);
				break;
			}
			mesh.Clear(false);
			if (_scratchVertices.Count != 0)
			{
				for (int i = 0; i < _scratchVertices.Count; i++)
				{
					_scratchColors.Add(Color.white);
				}
				mesh.SetVertices(_scratchVertices);
				mesh.SetColors(_scratchColors);
				mesh.SetTriangles(_scratchTriangles, 0, true);
			}
		}

		private void AddDisc(Transform localSpace, Vector3 center, float radius, float fraction, float height)
		{
			//IL_0020: 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)
			//IL_0049: Unknown result type (might be due to invalid IL or missing references)
			//IL_005f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0064: 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)
			float num = Math.Max(0.001f, fraction) * MathF.PI * 2f;
			_scratchVertices.Add(ToLocal(localSpace, center, height));
			for (int i = 0; i <= 64; i++)
			{
				float num2 = -MathF.PI / 2f + num * (float)i / 64f;
				_scratchVertices.Add(ToLocal(localSpace, center + new Vector3(Mathf.Cos(num2) * radius, 0f, Mathf.Sin(num2) * radius), height));
				if (i != 0)
				{
					_scratchTriangles.Add(0);
					_scratchTriangles.Add(i + 1);
					_scratchTriangles.Add(i);
				}
			}
		}

		private void AddAnnulus(Transform localSpace, Vector3 center, float innerRadius, float outerRadius, float fraction, float height)
		{
			//IL_0050: 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_0053: 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_005f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0070: Unknown result type (might be due to invalid IL or missing references)
			//IL_0071: Unknown result type (might be due to invalid IL or missing references)
			//IL_0074: Unknown result type (might be due to invalid IL or missing references)
			//IL_0079: Unknown result type (might be due to invalid IL or missing references)
			//IL_0080: Unknown result type (might be due to invalid IL or missing references)
			float num = Math.Max(0.001f, fraction) * MathF.PI * 2f;
			Vector3 val = default(Vector3);
			for (int i = 0; i <= 64; i++)
			{
				float num2 = -MathF.PI / 2f + num * (float)i / 64f;
				((Vector3)(ref val))..ctor(Mathf.Cos(num2), 0f, Mathf.Sin(num2));
				_scratchVertices.Add(ToLocal(localSpace, center + val * innerRadius, height));
				_scratchVertices.Add(ToLocal(localSpace, center + val * outerRadius, height));
				if (i != 0)
				{
					int num3 = (i - 1) * 2;
					int item = num3 + 1;
					int num4 = i * 2;
					int item2 = num4 + 1;
					_scratchTriangles.Add(num3);
					_scratchTriangles.Add(num4);
					_scratchTriangles.Add(item);
					_scratchTriangles.Add(item);
					_scratchTriangles.Add(num4);
					_scratchTriangles.Add(item2);
				}
			}
		}

		private void AddRectangle(Transform localSpace, Vector3 origin, Vector3 direction, float length, float width, float height)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_000c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0012: 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_0024: Unknown result type (might be due to invalid IL or missing references)
			//IL_0025: Unknown result type (might be due to invalid IL or missing references)
			//IL_0026: Unknown result type (might be due to invalid IL or missing references)
			//IL_0033: Unknown result type (might be due to invalid IL or missing references)
			//IL_0038: Unknown result type (might be due to invalid IL or missing references)
			//IL_003d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0045: Unknown result type (might be due to invalid IL or missing references)
			//IL_0046: Unknown result type (might be due to invalid IL or missing references)
			//IL_0047: Unknown result type (might be due to invalid IL or missing references)
			//IL_004e: Unknown result type (might be due to invalid IL or missing references)
			//IL_005f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0060: 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_0068: Unknown result type (might be due to invalid IL or missing references)
			//IL_0079: 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_007b: 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_0093: Unknown result type (might be due to invalid IL or missing references)
			//IL_0094: Unknown result type (might be due to invalid IL or missing references)
			//IL_0095: Unknown result type (might be due to invalid IL or missing references)
			//IL_009c: Unknown result type (might be due to invalid IL or missing references)
			Vector3 val = new Vector3(0f - direction.z, 0f, direction.x) * (width * 0.5f);
			Vector3 val2 = origin + direction * Math.Max(0.001f, length);
			_scratchVertices.Add(ToLocal(localSpace, origin - val, height));
			_scratchVertices.Add(ToLocal(localSpace, origin + val, height));
			_scratchVertices.Add(ToLocal(localSpace, val2 + val, height));
			_scratchVertices.Add(ToLocal(localSpace, val2 - val, height));
			_scratchTriangles.Add(0);
			_scratchTriangles.Add(2);
			_scratchTriangles.Add(1);
			_scratchTriangles.Add(0);
			_scratchTriangles.Add(3);
			_scratchTriangles.Add(2);
		}

		private void AddConeSector(Transform localSpace, Vector3 origin, Vector3 direction, float radius, float angleDegrees, float fraction, float height)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0006: 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_0043: 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_0080: Unknown result type (might be due to invalid IL or missing references)
			//IL_0085: Unknown result type (might be due to invalid IL or missing references)
			//IL_008c: Unknown result type (might be due to invalid IL or missing references)
			float num = Mathf.Atan2(direction.z, direction.x);
			float num2 = angleDegrees * 0.5f * (MathF.PI / 180f);
			float num3 = num - num2;
			float num4 = angleDegrees * (MathF.PI / 180f) * Math.Max(0.001f, fraction);
			_scratchVertices.Add(ToLocal(localSpace, origin, height));
			for (int i = 0; i <= 64; i++)
			{
				float num5 = num3 + num4 * (float)i / 64f;
				_scratchVertices.Add(ToLocal(localSpace, origin + new Vector3(Mathf.Cos(num5) * radius, 0f, Mathf.Sin(num5) * radius), height));
				if (i != 0)
				{
					_scratchTriangles.Add(0);
					_scratchTriangles.Add(i + 1);
					_scratchTriangles.Add(i);
				}
			}
		}

		private void ApplyMeshStyle(MeshRenderer? renderer, Color color, float alphaMultiplier)
		{
			//IL_0044: 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_0024: Unknown result type (might be due to invalid IL or missing references)
			//IL_002e: Expected O, but got Unknown
			if (!((Object)(object)renderer == (Object)null))
			{
				color.a *= Mathf.Clamp01(alphaMultiplier);
				if (_propertyBlock == null)
				{
					_propertyBlock = new MaterialPropertyBlock();
				}
				_propertyBlock.Clear();
				_propertyBlock.SetColor("_Color", color);
				_propertyBlock.SetColor("_BaseColor", color);
				((Renderer)renderer).SetPropertyBlock(_propertyBlock);
			}
		}

		private static Vector3 ToLocal(Transform localSpace, Vector3 worldPosition, float height)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			//IL_0008: Unknown result type (might be due to invalid IL or missing references)
			//IL_000d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0012: Unknown result type (might be due to invalid IL or missing references)
			return localSpace.InverseTransformPoint(worldPosition + Vector3.up * height);
		}

		private static float Smooth(float value)
		{
			return value * value * (3f - 2f * value);
		}

		private static void DrawGeometryOutline(LineRenderer? line, ResolvedAbilityGeometry geometry, float expansion, float height)
		{
			//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)
			//IL_0012: Unknown result type (might be due to invalid IL or missing references)
			//IL_0028: Expected I4, but got Unknown
			//IL_002c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0044: Unknown result type (might be due to invalid IL or missing references)
			//IL_004b: Unknown result type (might be due to invalid IL or missing references)
			//IL_006c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0073: Unknown result type (might be due to invalid IL or missing references)
			if (!((Object)(object)line == (Object)null))
			{
				BossAbilityGeometryKind kind = geometry.Kind;
				switch ((int)kind)
				{
				case 0:
				case 1:
					DrawRing(line, geometry.Origin, geometry.Primary * expansion, height);
					break;
				case 2:
					DrawRectangle(line, geometry.Origin, geometry.Direction, geometry.Primary * expansion, geometry.Secondary * expansion, height);
					break;
				case 3:
					DrawCone(line, geometry.Origin, geometry.Direction, geometry.Primary * expansion, geometry.Secondary, height);
					break;
				}
			}
		}

		private static void DrawRing(LineRenderer line, Vector3 center, float radius, float height = 0f)
		{
			//IL_002a: 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_0041: Unknown result type (might be due to invalid IL or missing references)
			line.loop = true;
			line.positionCount = 64;
			for (int i = 0; i < 64; i++)
			{
				float num = (float)i * MathF.PI * 2f / 64f;
				line.SetPosition(i, center + new Vector3(Mathf.Cos(num) * radius, height, Mathf.Sin(num) * radius));
			}
		}

		private static void DrawRectangle(LineRenderer line, Vector3 origin, Vector3 direction, float length, float width, float height = 0f)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_000c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0012: 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_0024: Unknown result type (might be due to invalid IL or missing references)
			//IL_0025: Unknown result type (might be due to invalid IL or missing references)
			//IL_0026: Unknown result type (might be due to invalid IL or missing references)
			//IL_0028: Unknown result type (might be due to invalid IL or missing references)
			//IL_002d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0032: Unknown result type (might be due to invalid IL or missing references)
			//IL_0041: 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_004d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0050: 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_0052: Unknown result type (might be due to invalid IL or missing references)
			//IL_0057: 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_0064: Unknown result type (might be due to invalid IL or missing references)
			//IL_0065: 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_006b: Unknown result type (might be due to invalid IL or missing references)
			//IL_006c: 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_0079: 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_007f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0080: Unknown result type (might be due to invalid IL or missing references)
			//IL_008c: Unknown result type (might be due to invalid IL or missing references)
			//IL_008d: Unknown result type (might be due to invalid IL or missing references)
			//IL_008e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0093: Unknown result type (might be due to invalid IL or missing references)
			//IL_0094: Unknown result type (might be due to invalid IL or missing references)
			Vector3 val = new Vector3(0f - direction.z, 0f, direction.x) * (width * 0.5f);
			Vector3 val2 = origin + direction * length;
			line.loop = true;
			line.positionCount = 4;
			Vector3 val3 = Vector3.up * height;
			line.SetPosition(0, origin - val + val3);
			line.SetPosition(1, origin + val + val3);
			line.SetPosition(2, val2 + val + val3);
			line.SetPosition(3, val2 - val + val3);
		}

		private static void DrawCenterLine(LineRenderer line, Vector3 origin, Vector3 direction, float length, float height = 0f)
		{
			//IL_000e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0015: Unknown result type (might be due to invalid IL or missing references)
			//IL_001a: Unknown result type (might be due to invalid IL or missing references)
			//IL_001d: Unknown result type (might be due to invalid IL or missing references)
			//IL_001e: 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_002b: Unknown result type (might be due to invalid IL or missing references)
			//IL_002c: Unknown result type (might be due to invalid IL or missing references)
			//IL_002e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0033: Unknown result type (might be due to invalid IL or missing references)
			//IL_0038: 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)
			line.loop = false;
			line.positionCount = 2;
			Vector3 val = Vector3.up * height;
			line.SetPosition(0, origin + val);
			line.SetPosition(1, origin + direction * length + val);
		}

		private static void DrawCone(LineRenderer line, Vector3 origin, Vector3 direction, float radius, float angleDegrees, float height = 0f)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_0030: Unknown result type (might be due to invalid IL or missing references)
			//IL_0037: Unknown result type (might be due to invalid IL or missing references)
			//IL_003c: Unknown result type (might be due to invalid IL or missing references)
			//IL_003f: 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_0041: Unknown result type (might be due to invalid IL or missing references)
			//IL_0068: 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_0082: Unknown result type (might be due to invalid IL or missing references)
			float num = Mathf.Atan2(direction.z, direction.x);
			float num2 = angleDegrees * 0.5f * (MathF.PI / 180f);
			line.loop = true;
			line.positionCount = 66;
			Vector3 val = Vector3.up * height;
			line.SetPosition(0, origin + val);
			for (int i = 0; i <= 64; i++)
			{
				float num3 = Mathf.Lerp(num - num2, num + num2, (float)i / 64f);
				line.SetPosition(i + 1, origin + new Vector3(Mathf.Cos(num3) * radius, height, Mathf.Sin(num3) * radius));
			}
		}

		private static void DrawCrossbar(LineRenderer line, Vector3 origin, Vector3 direction, float distance, float width, float height)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0003: Unknown result type (might be due to invalid IL or missing references)
			//IL_0008: Unknown result type (might be due to invalid IL or missing references)
			//IL_000d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0014: Unknown result type (might be due to invalid IL or missing references)
			//IL_0019: Unknown result type (might be due to invalid IL or missing references)
			//IL_001e: 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_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_003e: 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_0054: 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_0056: Unknown result type (might be due to invalid IL or missing references)
			//IL_0062: 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_0064: Unknown result type (might be due to invalid IL or missing references)
			Vector3 val = origin + direction * distance + Vector3.up * height;
			Vector3 val2 = new Vector3(0f - direction.z, 0f, direction.x) * (width * 0.5f);
			line.loop = false;
			line.positionCount = 2;
			line.SetPosition(0, val - val2);
			line.SetPosition(1, val + val2);
		}

		private static void DrawConeArc(LineRenderer line, Vector3 origin, Vector3 direction, float radius, float angleDegrees, float height)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0006: 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_005d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0062: Unknown result type (might be due to invalid IL or missing references)
			float num = Mathf.Atan2(direction.z, direction.x);
			float num2 = angleDegrees * 0.5f * (MathF.PI / 180f);
			line.loop = false;
			line.positionCount = 33;
			for (int i = 0; i <= 32; i++)
			{
				float num3 = Mathf.Lerp(num - num2, num + num2, (float)i / 32f);
				line.SetPosition(i, origin + new Vector3(Mathf.Cos(num3) * radius, height, Mathf.Sin(num3) * radius));
			}
		}

		private static void ApplyStyle(LineRenderer? line, Color color, float alphaMultiplier, float width, bool secondary)
		{
			//IL_001c: 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)
			if (!((Object)(object)line == (Object)null))
			{
				color.a *= Mathf.Clamp01(alphaMultiplier);
				line.startColor = color;
				line.endColor = color;
				line.widthMultiplier = Math.Max(0.01f, secondary ? (width * 0.65f) : width);
			}
		}

		public void Dispose()
		{
			Hide();
			ClearAfterglow();
			if ((Object)(object)_root != (Object)null)
			{
				Object.Destroy((Object)(object)_root);
			}
			if ((Object)(object)_afterglowRoot != (Object)null)
			{
				Object.Destroy((Object)(object)_afterglowRoot);
			}
			if ((Object)(object)_fillMesh != (Object)null)
			{
				Object.Destroy((Object)(object)_fillMesh);
			}
			if ((Object)(object)_progressMesh != (Object)null)
			{
				Object.Destroy((Object)(object)_progressMesh);
			}
			if ((Object)(object)_afterglowMesh != (Object)null)
			{
				Object.Destroy((Object)(object)_afterglowMesh);
			}
			if ((Object)(object)_material != (Object)null)
			{
				Object.Destroy((Object)(object)_material);
			}
			_root = null;
			_afterglowRoot = null;
			_primary = null;
			_secondary = null;
			_pattern = null;
			_sweep = null;
			_impact = null;
			_fillMesh = null;
			_progressMesh = null;
			_afterglowMesh = null;
			_fillRenderer = null;
			_progressRenderer = null;
			_afterglowRenderer = null;
			_propertyBlock = null;
			_material = null;
		}
	}
	internal sealed class BossAbilityRuntime : IDisposable
	{
		private readonly BossRuntimeController _controller;

		private readonly BossRuntimeServices _services;

		private readonly DeterministicAbilityScheduler _scheduler;

		private readonly ServerCombatActionRunner _combat;

		private readonly AbilityTelegraphPresenter _telegraph;

		private readonly Dictionary<string, BossAbilityDefinition> _definitions = new Dictionary<string, BossAbilityDefinition>(StringComparer.Ordinal);

		private long _lastStartedEventSequence = -1L;

		private long _lastResolvedEventSequence = -1L;

		private long _lastCancelledEventSequence = -1L;

		private long _presentableSequence = -1L;

		private long _lastPresentedResolutionSequence = -1L;

		private readonly List<Action> _presentationCleanup = new List<Action>();

		private EncounterAbilitySnapshot? _presentationSnapshot;

		private ResolvedAbilityGeometry _activeGeometry;

		private EncounterEntityReference? _activeTarget;

		private bool _activeFollowsTarget;

		private IReadOnlyCollection<Player> _eligiblePlayers = (IReadOnlyCollection<Player>)(object)Array.Empty<Player>();

		private bool _initialized;

		private bool _disposed;

		private bool _schedulesReleased;

		private int _globalScheduleCount;

		internal BossAbilityRuntime(BossRuntimeController controller, BossRuntimeServices services)
		{
			_controller = controller ?? throw new ArgumentNullException("controller");
			_services = services ?? throw new ArgumentNullException("services");
			_scheduler = new DeterministicAbilityScheduler(controller.DeterministicSeed, services.Options.MinimumTelegraphLeadTimeSeconds);
			_combat = new ServerCombatActionRunner(delegate(string message)
			{
				services.Warning(message);
			});
			_telegraph = new AbilityTelegraphPresenter(((Component)controller).transform, services.Options.MinimumTelegraphLeadTimeSeconds);
			IndexDefinitions(controller.Definition.Abilities);
			foreach (BossPhaseDefinition phase in controller.Definition.Phases)
			{
				IndexDefinitions(phase.Abilities);
			}
			if (InstanceFinder.IsClientStarted && _definitions.Values.Any((BossAbilityDefinition value) => value.Telegraph.Enabled))
			{
				if (_telegraph.TryPrepare(out string diagnostic))
				{
					_services.LogDebug(diagnostic);
				}
				else
				{
					_services.Warning("Ability telegraph preparation was deferred: " + diagnostic);
				}
			}
		}

		internal void InitializeAuthoritative(double serverTime)
		{
			if (!_initialized && InstanceFinder.IsServerStarted)
			{
				BossAbilityDefinition[] array = _controller.Definition.Abilities.Where((BossAbilityDefinition value) => (int)value.Trigger > 0).ToArray();
				_globalScheduleCount = _services.ReserveAbilitySchedules(this, array.Length);
				_scheduler.Initialize(array.Take(_globalScheduleCount).ToArray(), serverTime);
				_initialized = true;
			}
		}

		internal AbilitySchedulerCheckpoint CaptureCheckpoint(double serverTime)
		{
			return _scheduler.CaptureCheckpoint(serverTime);
		}

		internal bool TryRestoreCheckpoint(AbilitySchedulerCheckpoint checkpoint, double serverTime, out string error)
		{
			int globalScheduleCount = _globalScheduleCount;
			if (_services.ReserveAbilitySchedules(this, checkpoint.Slots.Count) != checkpoint.Slots.Count)
			{
				_services.ReserveAbilitySchedules(this, globalScheduleCount);
				error = "The saved ability schedules exceed the available global budget.";
				return false;
			}
			if (!_scheduler.TryRestoreCheckpoint(checkpoint, _controller.Definition.Abilities.Where((BossAbilityDefinition value) => (int)value.Trigger > 0).ToArray(), _controller.Definition.Phases, serverTime, out error))
			{
				_services.ReserveAbilitySchedules(this, globalScheduleCount);
				return false;
			}
			_globalScheduleCount = checkpoint.Slots.Count((AbilitySlotCheckpoint slot) => slot.IsGlobal);
			_initialized = true;
			EncounterStateSnapshot? encounterState = _controller.EncounterState;
			_lastStartedEventSequence = (_lastResolvedEventSequence = (_lastCancelledEventSequence = ((encounterState != null) ? encounterState.Sequence : 0)));
			return true;
		}

		internal void PreparePhaseChange(double serverTime)
		{
			if (!_initialized || !InstanceFinder.IsServerStarted)
			{
				return;
			}
			BossAbilityDefinition val = _scheduler.Cancel(clearSchedules: false, serverTime);
			EncounterStateSnapshot? encounterState = _controller.EncounterState;
			EncounterAbilitySnapshot val2 = ((encounterState != null) ? encounterState.ActiveAbility : null);
			if (val != null || (val2 != null && !val2.IsTerminal))
			{
				_combat.CancelAll();
				_telegraph.Hide();
				CleanupTransientPresentation();
				if (val2 != null && !val2.IsTerminal)
				{
					_services.TryCancelScheduledAbility(_controller, "The active phase changed.");
				}
				if (val2 != null)
				{
					_services.CleanupAbilityResources(_controller.EncounterId, val2.AbilityId);
				}
				if (val != null && !string.Equals(val.Id, (val2 != null) ? val2.AbilityId : null, StringComparison.Ordinal))
				{
					_services.CleanupAbilityResources(_controller.EncounterId, val.Id);
				}
				ClearActiveTarget();
			}
		}

		internal void EnterPhase(BossPhaseDefinition phase, bool isInitialSpawn, double serverTime)
		{
			if (phase == null)
			{
				throw new ArgumentNullException("phase");
			}
			if (_initialized && InstanceFinder.IsServerStarted)
			{
				BossAbilityDefinition[] array = phase.Abilities.Where((BossAbilityDefinition value) => (int)value.Trigger != 1).ToArray();
				int num = _services.ReserveAbilitySchedules(this, _globalScheduleCount + array.Length);
				int count = Math.Max(0, num - _globalScheduleCount);
				_scheduler.ActivatePhase(phase.Id, array.Take(count).ToArray(), serverTime, isInitialSpawn);
			}
		}

		internal void Tick(double serverTime)
		{
			if (_disposed)
			{
				return;
			}
			_telegraph.Tick(serverTime);
			RetargetPresentation(serverTime);
			TickReplicatedPresentation(serverTime);
			if (!InstanceFinder.IsServerStarted)
			{
				_combat.Tick(serverTime);
				return;
			}
			InitializeAuthoritative(serverTime);
			if (!_controller.IsAlive || !_controller.IsSpawned)
			{
				CancelTerminal("The boss is no longer active.");
				return;
			}
			_combat.Tick(serverTime);
			for (int i = 0; i < 8; i++)
			{
				if (!_scheduler.TryDequeueState(serverTime, (BossConditionDefinition condition) => _services.EvaluateConditionState(_controller, condition, serverTime), (BossAbilityDefinition ability) => _services.CanScheduleAbility(_controller, ability), out AbilitySchedulerCommand command))
				{
					break;
				}
				switch (command.Kind)
				{
				case AbilitySchedulerCommandKind.BeginTelegraph:
					if (!TryBegin(command))
					{
						_scheduler.RejectActive(serverTime);
					}
					break;
				case AbilitySchedulerCommandKind.Resolve:
					_services.ResolveScheduledAbility(_controller, command, _activeGeometry, _activeTarget, _activeFollowsTarget, _eligiblePlayers, _combat);
					break;
				case AbilitySchedulerCommandKind.BeginRecovery:
					_services.TryBeginAbilityRecovery(_controller);
					break;
				case AbilitySchedulerCommandKind.Complete:
					_services.TryCompleteScheduledAbility(_controller);
					_combat.CancelAll();
					_services.CleanupAbilityResources(_controller.EncounterId, command.Ability.Id);
					ClearActiveTarget();
					break;
				}
			}
		}

		internal void CancelTerminal(string reason)
		{
			if (!_disposed)
			{
				BossAbilityDefinition val = _scheduler.Cancel();
				EncounterStateSnapshot? encounterState = _controller.EncounterState;
				EncounterAbilitySnapshot val2 = ((encounterState != null) ? encounterState.ActiveAbility : null);
				ReleaseSchedules();
				_combat.CancelAll();
				_telegraph.Hide();
				CleanupTransientPresentation();
				if (InstanceFinder.IsServerStarted && val2 != null && !val2.IsTerminal)
				{
					_services.TryCancelScheduledAbility(_controller, reason);
				}
				if (val2 != null)
				{
					_services.CleanupAbilityResources(_controller.EncounterId, val2.AbilityId);
				}
				if (val != null && !string.Equals(val.Id, (val2 != null) ? val2.AbilityId : null, StringComparison.Ordinal))
				{
					_services.CleanupAbilityResources(_controller.EncounterId, val.Id);
				}
				ClearActiveTarget();
			}
		}

		internal void InterruptForStagger(double serverTime)
		{
			if (!_disposed && InstanceFinder.IsServerStarted)
			{
				EncounterStateSnapshot? encounterState = _controller.EncounterState;
				EncounterAbilitySnapshot val = ((encounterState != null) ? encounterState.ActiveAbility : null);
				_scheduler.RejectActive(serverTime);
				_combat.CancelAll();
				_telegraph.Hide();
				CleanupTransientPresentation();
				if (val != null && !val.IsTerminal)
				{
					_services.TryCancelScheduledAbility(_controller, "The boss entered stagger.");
				}
				if (val != null)
				{
					_services.CleanupAbilityResources(_controller.EncounterId, val.AbilityId);
				}
				ClearActiveTarget();
			}
		}

		internal void ApplyPresentation(EncounterAbilitySnapshot? previous, EncounterAbilitySnapshot? current, bool authoritative, double serverTime)
		{
			//IL_003b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0168: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ab: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b1: Invalid comparison between Unknown and I4
			//IL_01b4: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ba: Invalid comparison between Unknown and I4
			//IL_0203: Unknown result type (might be due to invalid IL or missing references)
			//IL_0209: Invalid comparison between Unknown and I4
			if (_disposed)
			{
				return;
			}
			if (current == null)
			{
				_presentationSnapshot = null;
				_presentableSequence = -1L;
				_telegraph.Hide();
				CleanupTransientPresentation();
				ClearActiveTarget();
				return;
			}
			_presentationSnapshot = current;
			if ((int)current.State == 0 && current.Sequence != ((previous != null) ? new long?(previous.Sequence) : ((long?)null)) && _definitions.TryGetValue(current.AbilityId, out BossAbilityDefinition value) && ResolvedAbilityGeometry.TryCreate(current, out var geometry))
			{
				_activeGeometry = geometry;
				_activeTarget = current.Target;
				_activeFollowsTarget = !value.TargetSelector.LockPositionAtTelegraph;
				bool flag = authoritative || serverTime <= current.ResolveServerTime - (double)_services.Options.MinimumTelegraphLeadTimeSeconds;
				if (InstanceFinder.IsClientStarted && flag)
				{
					_telegraph.Show(value.Telegraph, geometry, current.TelegraphServerTime, current.ResolveServerTime, authoritative ? current.TelegraphServerTime : serverTime);
					_presentableSequence = current.Sequence;
				}
				if ((authoritative || flag) && TryAdvance(ref _lastStartedEventSequence, current.Sequence) && _controller.SpawnEventPublished)
				{
					BossEvents.RaiseAbilityStarted(_controller.Handle, current, authoritative);
				}
			}
			if ((int)current.State != 0)
			{
				_telegraph.Hide();
			}
			if (current.IsTerminal)
			{
				CleanupTransientPresentation();
				_services.CleanupAbilityResources(_controller.EncounterId, current.AbilityId);
				ClearActiveTarget();
			}
			if (((int)current.State == 3 || (int)current.State == 1) && previous != null && (authoritative || _lastStartedEventSequence == current.Sequence) && TryAdvance(ref _lastResolvedEventSequence, current.Sequence) && _controller.SpawnEventPublished)
			{
				BossEvents.RaiseAbilityResolved(_controller.Handle, current, authoritative);
			}
			if ((int)current.State == 2 && previous != null && (authoritative || _lastStartedEventSequence == current.Sequence) && TryAdvance(ref _lastCancelledEventSequence, current.Sequence) && _controller.SpawnEventPublished)
			{
				BossEvents.RaiseAbilityCancelled(_controller.Handle, current, authoritative, (string)null);
			}
		}

		private bool TryBegin(AbilitySchedulerCommand command)
		{
			//IL_002b: Unknown result type (might be due to invalid IL or missing references)
			//IL_010b: 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)
			AbilityTargetCandidate boss = new AbilityTargetCandidate(_controller.EncounterId, _controller.NetworkObject.ObjectId, ((Component)_controller).transform.position, _controller.Creature);
			AbilityPlayerCapture abilityPlayerCapture = GameAbilityTargetSource.CapturePlayers(delegate(string message)
			{
				_services.Warning(message);
			});
			IReadOnlyList<AbilityTargetCandidate> eligibleCandidates = abilityPlayerCapture.EligibleCandidates;
			if (!DeterministicAbilityTargetResolver.TrySelect(command.Ability.TargetSelector, boss, eligibleCandidates, _controller.DeterministicSeed, _scheduler.ActivePhaseId, command.Ability.Id, command.AttemptOrdinal, out AbilityTargetSelection selection))
			{
				AbilityTargetFailureDiagnostic abilityTargetFailureDiagnostic = DeterministicAbilityTargetResolver.DiagnoseFailure(command.Ability.TargetSelector, boss, abilityPlayerCapture);
				_services.Warning("Ability '" + command.Ability.Id + "' skipped: " + abilityTargetFailureDiagnostic.Message + ".");
				return false;
			}
			_activeGeometry = ResolvedAbilityGeometry.Create(command.Ability.Geometry, ((Component)_controller).transform, selection.LockedPosition, command.Ability.TargetSelector.Kind);
			_activeTarget = selection.Candidate.ToReference();
			List<Player> list = new List<Player>(eligibleCandidates.Count);
			foreach (AbilityTargetCandidate item in eligibleCandidates)
			{
				object? runtimeEntity = item.RuntimeEntity;
				Player val = (Player)((runtimeEntity is Player) ? runtimeEntity : null);
				if (val != null)
				{
					list.Add(val);
				}
			}
			_eligiblePlayers = list;
			_activeFollowsTarget = !command.Ability.TargetSelector.LockPositionAtTelegraph;
			return _services.TryBeginScheduledAbility(_controller, command, _activeGeometry, _activeTarget);
		}

		private void RetargetPresentation(double serverTime)
		{
			//IL_007a: Unknown result type (might be due to invalid IL or missing references)
			//IL_008c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0091: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00cc: Unknown result type (might be due to invalid IL or missing references)
			if (!_activeFollowsTarget || _presentationSnapshot == null || !_definitions.TryGetValue(_presentationSnapshot.AbilityId, out BossAbilityDefinition value))
			{
				return;
			}
			double num = Math.Max(0.0, value.TargetSelector.LockBeforeResolveSeconds);
			if (num > 0.0 && serverTime + 1E-06 >= _presentationSnapshot.ResolveServerTime - num)
			{
				_activeFollowsTarget = false;
				return;
			}
			Vector3 position;
			if ((int)value.TargetSelector.Kind == 0)
			{
				position = ((Component)_controller).transform.position;
			}
			else if (_activeTarget == null || !PlayerCombatAnchorAdapter.TryGetPosition(GameAbilityTargetSource.ResolvePlayer(_activeTarget, requireServerEligibility: false), out position))
			{
				return;
			}
			_activeGeometry = ResolvedAbilityGeometry.Create(value.Geometry, ((Component)_controller).transform, position, value.TargetSelector.Kind);
			_telegraph.UpdateGeometry(_activeGeometry);
		}

		private void TickReplicatedPresentation(double serverTime)
		{
			//IL_0013: Unknown result type (might be due to invalid IL or missing references)
			if (InstanceFinder.IsClientStarted)
			{
				EncounterAbilitySnapshot presentationSnapshot = _presentationSnapshot;
				if (presentationSnapshot != null && (int)presentationSnapshot.State == 0 && !(serverTime < presentationSnapshot.ResolveServerTime) && !(serverTime > presentationSnapshot.ResolveEndServerTime + 1E-06) && _presentableSequence == presentationSnapshot.Sequence && TryAdvance(ref _lastPresentedResolutionSequence, presentationSnapshot.Sequence) && _definitions.TryGetValue(presentationSnapshot.AbilityId, out BossAbilityDefinition value))
				{
					CleanupTransientPresentation();
					_presentationCleanup.AddRange(_services.ExecuteReplicatedAbilityPresentation(_controller, value, _activeGeometry));
				}
			}
		}

		private void CleanupTransientPresentation()
		{
			for (int num = _presentationCleanup.Count - 1; num >= 0; num--)
			{
				try
				{
					_presentationCleanup[num]();
				}
				catch (Exception ex)
				{
					_services.Warning("Ability presentation cleanup failed: " + ex.Message);
				}
			}
			_presentationCleanup.Clear();
		}

		private void ClearActiveTarget()
		{
			_activeTarget = null;
			_activeFollowsTarget = false;
			_eligiblePlayers = (IReadOnlyCollection<Player>)(object)Array.Empty<Player>();
		}

		private static bool TryAdvance(ref long highWatermark, long sequence)
		{
			if (sequence <= highWatermark)
			{
				return false;
			}
			highWatermark = sequence;
			return true;
		}

		private void IndexDefinitions(IReadOnlyList<BossAbilityDefinition> definitions)
		{
			foreach (BossAbilityDefinition definition in definitions)
			{
				if (definition != null && !_definitions.ContainsKey(definition.Id))
				{
					_definitions.Add(definition.Id, definition);
				}
			}
		}

		public void Dispose()
		{
			if (!_disposed)
			{
				CancelTerminal("The encounter runtime was disposed.");
				_disposed = true;
				_telegraph.Dispose();
				CleanupTransientPresentation();
				ReleaseSchedules();
				_definitions.Clear();
			}
		}

		internal void ResetClientPresentation()
		{
			if (!_disposed)
			{
				_presentableSequence = -1L;
				_telegraph.Dispose();
				CleanupTransientPresentation();
			}
		}

		internal void ResumeClientPresentation(double serverTime)
		{
			//IL_001a: Unknown result type (might be due to invalid IL or missing references)
			EncounterAbilitySnapshot presentationSnapshot = _presentationSnapshot;
			if (!_disposed && InstanceFinder.IsClientStarted && presentationSnapshot != null && (int)presentationSnapshot.State == 0 && !(serverTime > presentationSnapshot.ResolveServerTime - (double)_services.Options.MinimumTelegraphLeadTimeSeconds) && _definitions.TryGetValue(presentationSnapshot.AbilityId, out BossAbilityDefinition value))
			{
				_telegraph.Show(value.Telegraph, _activeGeometry, presentationSnapshot.TelegraphServerTime, presentationSnapshot.ResolveServerTime, serverTime);
				_presentableSequence = presentationSnapshot.Sequence;
			}
		}

		internal void DisposeForSessionStop()
		{
			if (!_disposed)
			{
				_disposed = true;
				_scheduler.Cancel();
				_combat.ClearForSessionStop();
				_presentationSnapshot = null;
				_presentableSequence = -1L;
				_telegraph.Dispose();
				CleanupTransientPresentation();
				ReleaseSchedules();
				ClearActiveTarget();
				_definitions.Clear();
			}
		}

		private void ReleaseSchedules()
		{
			if (!_schedulesReleased)
			{
				_schedulesReleased = true;
				_services.ReleaseAbilitySchedules(this);
			}
		}
	}
	internal readonly struct BossDashMotionPlan
	{
		internal Vector3 InitialVelocity { get; }

		internal Vector3 PlanarDirection { get; }

		internal float OwnedPlanarSpeed { get; }

		internal float MaximumTravelDistance { get; }

		internal float CoastTravelDistance { get; }

		internal float CoastDurationSeconds { get; }

		internal float BrakeDurationSeconds { get; }

		internal float ExitVelocityFraction { get; }

		internal bool Bounded { get; }

		internal BossDashMotionPlan(Vector3 initialVelocity, Vector3 planarDirection, float ownedPlanarSpeed, float maximumTravelDistance, float coastTravelDistance, float coastDurationSeconds, float brakeDurationSeconds, float exitVelocityFraction, bool bounded)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			//IL_0008: Unknown result type (might be due to invalid IL or missing references)
			//IL_0009: Unknown result type (might be due to invalid IL or missing references)
			InitialVelocity = initialVelocity;
			PlanarDirection = planarDirection;
			OwnedPlanarSpeed = ownedPlanarSpeed;
			MaximumTravelDistance = maximumTravelDistance;
			CoastTravelDistance = coastTravelDistance;
			CoastDurationSeconds = coastDurationSeconds;
			BrakeDurationSeconds = brakeDurationSeconds;
			ExitVelocityFraction = exitVelocityFraction;
			Bounded = bounded;
		}
	}
	internal static class BossDashMotionPlanner
	{
		private const float Epsilon = 1E-06f;

		internal static bool TryPlan(Vector3 bossPosition, Vector3 currentVelocity, ResolvedAbilityGeometry geometry, DashAction action, out BossDashMotionPlan plan, out string error)
		{
			//IL_001f: 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_0031: 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_005f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0064: Unknown result type (might be due to invalid IL or missing references)
			//IL_006b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0070: Unknown result type (might be due to invalid IL or missing references)
			//IL_0075: Unknown result type (might be due to invalid IL or missing references)
			//IL_0080: Unknown result type (might be due to invalid IL or missing references)
			//IL_0085: Unknown result type (might be due to invalid IL or missing references)
			//IL_008a: Unknown result type (might be due to invalid IL or missing references)
			//IL_008b: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ca: Unknown result type (might be due to invalid IL or missing references)
			//IL_00cf: Unknown result type (might be due to invalid IL or missing references)
			//IL_0113: Unknown result type (might be due to invalid IL or missing references)
			//IL_0118: 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)
			//IL_011e: Unknown result type (might be due to invalid IL or missing references)
			//IL_012c: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e9: Unknown result type (might be due to invalid IL or missing references)
			//IL_013f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0141: Unknown result type (might be due to invalid IL or missing references)
			//IL_0180: Unknown result type (might be due to invalid IL or missing references)
			//IL_018b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0191: Unknown result type (might be due to invalid IL or missing references)
			//IL_0196: 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_0236: Unknown result type (might be due to invalid IL or missing references)
			plan = default(BossDashMotionPlan);
			error = string.Empty;
			if (action == null)
			{
				error = "DashAction is required.";
				return false;
			}
			Vector3 direction = geometry.Direction;
			direction.y = 0f;
			if (!IsFinite(direction) || ((Vector3)(ref direction)).sqrMagnitude <= 1E-06f)
			{
				error = "The confirmed ability geometry has no usable planar dash direction.";
				return false;
			}
			((Vector3)(ref direction)).Normalize();
			Vector3 val = currentVelocity * action.RetainedVelocityFraction + direction * action.Impulse + Vector3.up * action.VerticalImpulse;
			if (!IsFinite(val))
			{
				error = "The requested dash velocity is not finite.";
				return false;
			}
			float num = 1f;
			if (((Vector3)(ref val)).sqrMagnitude > action.MaximumSpeed * action.MaximumSpeed)
			{
				num = action.MaximumSpeed / ((Vector3)(ref val)).magnitude;
				val *= num;
			}
			float num2 = action.Impulse * num;
			if (action.MaximumTravelDistance <= 0f)
			{
				plan = new BossDashMotionPlan(val, direction, num2, 0f, 0f, 0f, 0f, 1f, bounded: false);
				return true;
			}
			Vector3 val2 = geometry.TargetPosition - bossPosition;
			val2.y = 0f;
			if (!IsFinite(val2))
			{
				error = "The confirmed dash target position is not finite.";
				return false;
			}
			float num3 = Vector3.Dot(val2, direction);
			float num4 = Mathf.Max(0f, num3 - action.StoppingDistance);
			float num5 = Mathf.Min(action.MaximumTravelDistance, num4);
			if (num5 <= 0.001f)
			{
				error = "The confirmed target is already inside the dash stopping distance.";
				return false;
			}
			float num6 = Vector3.Dot(new Vector3(val.x, 0f, val.z), direction);
			if (!IsFinite(num6) || num6 <= 0.001f)
			{
				error = "The requested dash has no usable forward speed.";
				return false;
			}
			float num7 = Mathf.Max(0f, num6 - num2 * (1f - action.ExitVelocityFraction));
			float num8 = (num6 + num7) * 0.5f;
			float num9 = Mathf.Max(0f, action.BrakeDurationSeconds);
			float num10 = ((num8 <= 0.001f) ? 0f : Mathf.Min(num9, num5 / num8));
			float num11 = num8 * num10;
			float num12 = Mathf.Max(0f, num5 - num11);
			float coastDurationSeconds = num12 / num6;
			plan = new BossDashMotionPlan(val, direction, num2, num5, num12, coastDurationSeconds, num10, action.ExitVelocityFraction, bounded: true);
			return true;
		}

		internal static Vector3 RemoveOwnedPlanarVelocity(Vector3 currentVelocity, Vector3 planarDirection, float requestedRemoval, out float removedSpeed)
		{
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_0027: 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_004e: 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_0069: 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_007f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0080: Unknown result type (might be due to invalid IL or missing references)
			//IL_0083: Unknown result type (might be due to invalid IL or missing references)
			//IL_0088: 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)
			removedSpeed = 0f;
			if (!IsFinite(currentVelocity) || !IsFinite(planarDirection) || !IsFinite(requestedRemoval) || requestedRemoval <= 0f)
			{
				return currentVelocity;
			}
			planarDirection.y = 0f;
			if (((Vector3)(ref planarDirection)).sqrMagnitude <= 1E-06f)
			{
				return currentVelocity;
			}
			((Vector3)(ref planarDirection)).Normalize();
			Vector3 val = default(Vector3);
			((Vector3)(ref val))..ctor(currentVelocity.x, 0f, currentVelocity.z);
			float num = Mathf.Max(0f, Vector3.Dot(val, planarDirection));
			removedSpeed = Mathf.Min(requestedRemoval, num);
			return currentVelocity - planarDirection * removedSpeed;
		}

		internal static float ProjectedTravelDistance(Vector3 startPosition, Vector3 currentPosition, Vector3 planarDirection)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0008: Unknown result type (might be due to invalid IL or missing references)
			//IL_0010: 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_0046: Unknown result type (might be due to invalid IL or missing references)
			//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_005e: Unknown result type (might be due to invalid IL or missing references)
			//IL_005f: Unknown result type (might be due to invalid IL or missing references)
			if (!IsFinite(startPosition) || !IsFinite(currentPosition) || !IsFinite(planarDirection))
			{
				return 0f;
			}
			planarDirection.y = 0f;
			if (((Vector3)(ref planarDirection)).sqrMagnitude <= 1E-06f)
			{
				return 0f;
			}
			((Vector3)(ref planarDirection)).Normalize();
			Vector3 val = currentPosition - startPosition;
			val.y = 0f;
			return Mathf.Max(0f, Vector3.Dot(val, planarDirection));
		}

		internal static float ClampOwnedPlanarSpeedToAvailableForward(Vector3 currentVelocity, Vector3 planarDirection, float remainingOwnedSpeed)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0008: Unknown result type (might be due to invalid IL or missing references)
			//IL_004f: 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_006a: 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)
			if (!IsFinite(currentVelocity) || !IsFinite(planarDirection) || !IsFinite(remainingOwnedSpeed) || remainingOwnedSpeed <= 0f)
			{
				return 0f;
			}
			planarDirection.y = 0f;
			if (((Vector3)(ref planarDirection)).sqrMagnitude <= 1E-06f)
			{
				return 0f;
			}
			((Vector3)(ref planarDirection)).Normalize();
			Vector3 val = default(Vector3);
			((Vector3)(ref val))..ctor(currentVelocity.x, 0f, currentVelocity.z);
			float num = Mathf.Max(0f, Vector3.Dot(val, planarDirection));
			return Mathf.Min(remainingOwnedSpeed, num);
		}

		private static bool IsFinite(Vector3 value)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_000d: 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)
			if (IsFinite(value.x) && IsFinite(value.y))
			{
				return IsFinite(value.z);
			}
			return false;
		}

		private static bool IsFinite(float value)
		{
			if (!float.IsNaN(value))
			{
				retur