Decompiled source of ScarletCore v1.0.5

ScarletCore.dll

Decompiled 5 days ago
using System;
using System.Collections;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using System.Text.Json;
using System.Text.Json.Serialization;
using System.Text.RegularExpressions;
using System.Threading;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Core.Logging.Interpolation;
using BepInEx.Logging;
using BepInEx.Unity.IL2CPP;
using BepInEx.Unity.IL2CPP.Utils.Collections;
using HarmonyLib;
using Il2CppInterop.Runtime;
using Il2CppInterop.Runtime.InteropTypes.Arrays;
using Microsoft.CodeAnalysis;
using ProjectM;
using ProjectM.Gameplay.Systems;
using ProjectM.Gameplay.WarEvents;
using ProjectM.Network;
using ProjectM.Physics;
using ProjectM.Scripting;
using ProjectM.Shared;
using ProjectM.Shared.WarEvents;
using ScarletCore.Data;
using ScarletCore.Events;
using ScarletCore.Patches;
using ScarletCore.Services;
using ScarletCore.Systems;
using ScarletCore.Utils;
using Stunlock.Core;
using Stunlock.Network;
using Unity.Collections;
using Unity.Entities;
using Unity.Mathematics;
using Unity.Transforms;
using UnityEngine;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)]
[assembly: TargetFramework(".NETCoreApp,Version=v6.0", FrameworkDisplayName = ".NET 6.0")]
[assembly: AssemblyCompany("markvaaz")]
[assembly: AssemblyConfiguration("Debug")]
[assembly: AssemblyDescription("Framework and utilities for all Scarlet mods in V Rising")]
[assembly: AssemblyFileVersion("1.0.5.0")]
[assembly: AssemblyInformationalVersion("1.0.5+50068f1ee1e1ab3127114d6419a9e590aa918260")]
[assembly: AssemblyProduct("ScarletCore")]
[assembly: AssemblyTitle("ScarletCore")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.0.5.0")]
[module: UnverifiableCode]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	[AttributeUsage(AttributeTargets.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]
	[Microsoft.CodeAnalysis.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]
	[Microsoft.CodeAnalysis.Embedded]
	[AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)]
	internal sealed class RefSafetyRulesAttribute : Attribute
	{
		public readonly int Version;

		public RefSafetyRulesAttribute(int P_0)
		{
			Version = P_0;
		}
	}
}
namespace ScarletCore
{
	public static class ECSExtensions
	{
		public delegate void WithRefHandler<T>(ref T item);

		public static EntityManager EntityManager => GameSystems.Server.EntityManager;

		public static void With<T>(this Entity entity, WithRefHandler<T> action) where T : struct
		{
			//IL_0001: 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_0016: 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)
			T item = entity.Read<T>();
			action(ref item);
			EntityManager entityManager = EntityManager;
			((EntityManager)(ref entityManager)).SetComponentData<T>(entity, item);
		}

		public static void AddWith<T>(this Entity entity, WithRefHandler<T> action) where T : struct
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0017: Unknown result type (might be due to invalid IL or missing references)
			//IL_000f: Unknown result type (might be due to invalid IL or missing references)
			if (!entity.Has<T>())
			{
				entity.Add<T>();
			}
			entity.With(action);
		}

		public static void HasWith<T>(this Entity entity, WithRefHandler<T> action) where T : struct
		{
			//IL_0001: 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)
			if (entity.Has<T>())
			{
				entity.With(action);
			}
		}

		public static void Write<T>(this Entity entity, T componentData) where T : struct
		{
			//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_0009: Unknown result type (might be due to invalid IL or missing references)
			EntityManager entityManager = EntityManager;
			((EntityManager)(ref entityManager)).SetComponentData<T>(entity, componentData);
		}

		public static T Read<T>(this Entity entity) where T : struct
		{
			//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_0009: Unknown result type (might be due to invalid IL or missing references)
			EntityManager entityManager = EntityManager;
			return ((EntityManager)(ref entityManager)).GetComponentData<T>(entity);
		}

		public static DynamicBuffer<T> ReadBuffer<T>(this Entity entity) where T : struct
		{
			//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_0009: Unknown result type (might be due to invalid IL or missing references)
			//IL_000b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0010: Unknown result type (might be due to invalid IL or missing references)
			//IL_0013: Unknown result type (might be due to invalid IL or missing references)
			EntityManager entityManager = EntityManager;
			return ((EntityManager)(ref entityManager)).GetBuffer<T>(entity, false);
		}

		public static DynamicBuffer<T> AddBuffer<T>(this Entity entity) where T : struct
		{
			//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_0009: Unknown result type (might be due to invalid IL or missing references)
			//IL_000a: 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_0012: Unknown result type (might be due to invalid IL or missing references)
			EntityManager entityManager = EntityManager;
			return ((EntityManager)(ref entityManager)).AddBuffer<T>(entity);
		}

		public static bool TryGetComponent<T>(this Entity entity, out T componentData) where T : struct
		{
			//IL_0008: 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)
			componentData = default(T);
			if (entity.Has<T>())
			{
				componentData = entity.Read<T>();
				return true;
			}
			return false;
		}

		public static bool Has<T>(this Entity entity) where T : struct
		{
			//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_0009: 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)
			EntityManager entityManager = EntityManager;
			return ((EntityManager)(ref entityManager)).HasComponent(entity, new ComponentType(Il2CppType.Of<T>(), (AccessMode)0));
		}

		public static void Add<T>(this Entity entity) where T : struct
		{
			//IL_0001: 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_0013: Unknown result type (might be due to invalid IL or missing references)
			//IL_0016: Unknown result type (might be due to invalid IL or missing references)
			//IL_001d: Unknown result type (might be due to invalid IL or missing references)
			if (!entity.Has<T>())
			{
				EntityManager entityManager = EntityManager;
				((EntityManager)(ref entityManager)).AddComponent(entity, new ComponentType(Il2CppType.Of<T>(), (AccessMode)0));
			}
		}

		public static void Remove<T>(this Entity entity) where T : struct
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_000b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0010: Unknown result type (might be due to invalid IL or missing references)
			//IL_0013: 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 (entity.Has<T>())
			{
				EntityManager entityManager = EntityManager;
				((EntityManager)(ref entityManager)).RemoveComponent(entity, new ComponentType(Il2CppType.Of<T>(), (AccessMode)0));
			}
		}

		public static bool TryGetPlayer(this Entity entity, out Entity player)
		{
			//IL_0002: 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_000c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0018: 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)
			player = Entity.Null;
			if (entity.Has<PlayerCharacter>())
			{
				player = entity;
				return true;
			}
			return false;
		}

		public static bool IsPlayer(this Entity entity)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			if (entity.Has<PlayerCharacter>())
			{
				return true;
			}
			return false;
		}

		public static bool TryGetAttached(this Entity entity, out Entity attached)
		{
			//IL_0002: 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_000c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0016: Unknown result type (might be due to invalid IL or missing references)
			//IL_0017: Unknown result type (might be due to invalid IL or missing references)
			//IL_002a: 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_0030: Unknown result type (might be due to invalid IL or missing references)
			attached = Entity.Null;
			if (entity.TryGetComponent<Attach>(out Attach componentData) && componentData.Parent.Exists())
			{
				attached = componentData.Parent;
				return true;
			}
			return false;
		}

		public static bool TryGetTeamEntity(this Entity entity, out Entity teamEntity)
		{
			//IL_0002: 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_000c: 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_001a: Unknown result type (might be due to invalid IL or missing references)
			//IL_001f: Unknown result type (might be due to invalid IL or missing references)
			//IL_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_0031: Unknown result type (might be due to invalid IL or missing references)
			//IL_0032: Unknown result type (might be due to invalid IL or missing references)
			teamEntity = Entity.Null;
			if (entity.TryGetComponent<TeamReference>(out TeamReference componentData))
			{
				Entity value = componentData.Value._Value;
				if (value.Exists())
				{
					teamEntity = value;
					return true;
				}
			}
			return false;
		}

		public static Entity GetUserEntity(this Entity entity)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0016: Unknown result type (might be due to invalid IL or missing references)
			//IL_000d: 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_0013: Unknown result type (might be due to invalid IL or missing references)
			//IL_0024: Unknown result type (might be due to invalid IL or missing references)
			//IL_0029: Unknown result type (might be due to invalid IL or missing references)
			//IL_0020: Unknown result type (might be due to invalid IL or missing references)
			//IL_0021: Unknown result type (might be due to invalid IL or missing references)
			//IL_002c: Unknown result type (might be due to invalid IL or missing references)
			if (entity.TryGetComponent<PlayerCharacter>(out PlayerCharacter componentData))
			{
				return componentData.UserEntity;
			}
			if (entity.Has<User>())
			{
				return entity;
			}
			return Entity.Null;
		}

		public static bool Exists(this Entity entity)
		{
			//IL_0001: 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)
			//IL_000e: 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)
			int result;
			if (!entity.IsNull())
			{
				EntityManager entityManager = EntityManager;
				result = (((EntityManager)(ref entityManager)).Exists(entity) ? 1 : 0);
			}
			else
			{
				result = 0;
			}
			return (byte)result != 0;
		}

		public static bool IsNull(this Entity entity)
		{
			//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_0009: Unknown result type (might be due to invalid IL or missing references)
			Entity @null = Entity.Null;
			return ((Entity)(ref @null)).Equals(entity);
		}

		public static bool IsDisabled(this Entity entity)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			return entity.Has<Disabled>();
		}

		public static PrefabGUID GetPrefabGuid(this Entity entity)
		{
			//IL_0001: 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_0016: 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_000e: 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)
			if (entity.TryGetComponent<PrefabGUID>(out PrefabGUID componentData))
			{
				return componentData;
			}
			return PrefabGUID.Empty;
		}

		public static int GetGuidHash(this Entity entity)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0017: Unknown result type (might be due to invalid IL or missing references)
			//IL_001c: Unknown result type (might be due to invalid IL or missing references)
			if (entity.TryGetComponent<PrefabGUID>(out PrefabGUID componentData))
			{
				return ((PrefabGUID)(ref componentData)).GuidHash;
			}
			PrefabGUID empty = PrefabGUID.Empty;
			return ((PrefabGUID)(ref empty)).GuidHash;
		}

		public static Entity GetOwner(this Entity entity)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_000b: Unknown result type (might be due to invalid IL or missing references)
			//IL_000c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0026: Unknown result type (might be due to invalid IL or missing references)
			//IL_002b: Unknown result type (might be due to invalid IL or missing references)
			//IL_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_0023: 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 (entity.TryGetComponent<EntityOwner>(out EntityOwner componentData) && componentData.Owner.Exists())
			{
				return componentData.Owner;
			}
			return Entity.Null;
		}

		public static bool HasBuff(this Entity entity, PrefabGUID buffPrefabGuid)
		{
			//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_0009: 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)
			ServerGameManager serverGameManager = GameSystems.ServerGameManager;
			return ((ServerGameManager)(ref serverGameManager)).HasBuff(entity, ((PrefabGUID)(ref buffPrefabGuid)).ToIdentifier());
		}

		public static bool TryGetBuffer<T>(this Entity entity, out DynamicBuffer<T> dynamicBuffer) where T : struct
		{
			//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_0009: 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)
			ServerGameManager serverGameManager = GameSystems.ServerGameManager;
			if (((ServerGameManager)(ref serverGameManager)).TryGetBuffer<T>(entity, ref dynamicBuffer))
			{
				return true;
			}
			dynamicBuffer = default(DynamicBuffer<T>);
			return false;
		}

		public static float3 AimPosition(this Entity entity)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0017: Unknown result type (might be due to invalid IL or missing references)
			//IL_001c: Unknown result type (might be due to invalid IL or missing references)
			//IL_000e: 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_0014: 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)
			if (entity.TryGetComponent<EntityInput>(out EntityInput componentData))
			{
				return componentData.AimPosition;
			}
			return float3.zero;
		}

		public static float3 Position(this Entity entity)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0017: Unknown result type (might be due to invalid IL or missing references)
			//IL_001c: Unknown result type (might be due to invalid IL or missing references)
			//IL_000e: 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_0014: 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)
			if (entity.TryGetComponent<Translation>(out Translation componentData))
			{
				return componentData.Value;
			}
			return float3.zero;
		}

		public static int2 GetTileCoord(this Entity entity)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0017: Unknown result type (might be due to invalid IL or missing references)
			//IL_001c: Unknown result type (might be due to invalid IL or missing references)
			//IL_000e: 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_0014: 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)
			if (entity.TryGetComponent<TilePosition>(out TilePosition componentData))
			{
				return componentData.Tile;
			}
			return int2.zero;
		}

		public static int GetUnitLevel(this Entity entity)
		{
			//IL_0001: 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_000f: Unknown result type (might be due to invalid IL or missing references)
			if (entity.TryGetComponent<UnitLevel>(out UnitLevel componentData))
			{
				return componentData.Level._Value;
			}
			return 0;
		}

		public static void Destroy(this Entity entity, bool immediate = false)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0029: Unknown result type (might be due to invalid IL or missing references)
			//IL_002e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0016: Unknown result type (might be due to invalid IL or missing references)
			//IL_001b: 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)
			if (entity.Exists())
			{
				if (immediate)
				{
					EntityManager entityManager = EntityManager;
					((EntityManager)(ref entityManager)).DestroyEntity(entity);
				}
				else
				{
					DestroyUtility.Destroy(EntityManager, entity, (DestroyDebugReason)0, (string)null, 0);
				}
			}
		}

		public static void SetTeam(this Entity entity, Entity teamSource)
		{
			//IL_0001: 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)
			//IL_0011: 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_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_0043: 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_0061: Unknown result type (might be due to invalid IL or missing references)
			//IL_001b: Unknown result type (might be due to invalid IL or missing references)
			if (entity.Has<Team>() && entity.Has<TeamReference>() && teamSource.TryGetComponent<Team>(out Team componentData) && teamSource.TryGetComponent<TeamReference>(out TeamReference componentData2))
			{
				Entity teamRefEntity = componentData2.Value._Value;
				int teamId = componentData.Value;
				entity.With<TeamReference>((WithRefHandler<TeamReference>)delegate(ref TeamReference teamReference)
				{
					//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)
					teamReference.Value._Value = teamRefEntity;
				});
				entity.With<Team>((WithRefHandler<Team>)delegate(ref Team team)
				{
					team.Value = teamId;
				});
			}
		}

		public static void SetPosition(this Entity entity, float3 position)
		{
			//IL_0007: 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_000e: 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_0019: 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)
			if (entity.Has<Translation>())
			{
				entity.With<Translation>((WithRefHandler<Translation>)delegate(ref Translation translation)
				{
					//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)
					translation.Value = position;
				});
			}
			if (entity.Has<LastTranslation>())
			{
				entity.With<LastTranslation>((WithRefHandler<LastTranslation>)delegate(ref LastTranslation lastTranslation)
				{
					//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)
					lastTranslation.Value = position;
				});
			}
		}

		public static void SetFaction(this Entity entity, PrefabGUID factionPrefabGuid)
		{
			//IL_0007: 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_000e: 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)
			if (entity.Has<FactionReference>())
			{
				entity.With<FactionReference>((WithRefHandler<FactionReference>)delegate(ref FactionReference factionReference)
				{
					//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)
					factionReference.FactionGuid._Value = factionPrefabGuid;
				});
			}
		}

		public static bool IsAllies(this Entity entity, Entity player)
		{
			//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_0009: Unknown result type (might be due to invalid IL or missing references)
			//IL_000a: Unknown result type (might be due to invalid IL or missing references)
			ServerGameManager serverGameManager = GameSystems.ServerGameManager;
			return ((ServerGameManager)(ref serverGameManager)).IsAllies(entity, player);
		}

		public static bool IsPlayerOwned(this Entity entity)
		{
			//IL_0001: 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_000f: Unknown result type (might be due to invalid IL or missing references)
			if (entity.TryGetComponent<EntityOwner>(out EntityOwner componentData))
			{
				return componentData.Owner.IsPlayer();
			}
			return false;
		}

		public static Entity GetBuffTarget(this Entity entity)
		{
			//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_0007: 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_000f: Unknown result type (might be due to invalid IL or missing references)
			return CreateGameplayEventServerUtility.GetBuffTarget(EntityManager, entity);
		}
	}
	[BepInPlugin("markvaaz.ScarletCore", "ScarletCore", "1.0.5")]
	public class Plugin : BasePlugin
	{
		private static Harmony _harmony;

		public static Harmony Harmony => _harmony;

		public static Plugin Instance { get; private set; }

		public static ManualLogSource LogInstance { get; private set; }

		public override void Load()
		{
			//IL_0020: Unknown result type (might be due to invalid IL or missing references)
			//IL_0026: Expected O, but got Unknown
			//IL_0072: Unknown result type (might be due to invalid IL or missing references)
			//IL_007c: Expected O, but got Unknown
			Instance = this;
			LogInstance = ((BasePlugin)this).Log;
			ManualLogSource log = ((BasePlugin)this).Log;
			bool flag = default(bool);
			BepInExInfoLogInterpolatedStringHandler val = new BepInExInfoLogInterpolatedStringHandler(27, 2, ref flag);
			if (flag)
			{
				((BepInExLogInterpolatedStringHandler)val).AppendLiteral("Plugin ");
				((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>("markvaaz.ScarletCore");
				((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" version ");
				((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>("1.0.5");
				((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" is loaded!");
			}
			log.LogInfo(val);
			_harmony = new Harmony("markvaaz.ScarletCore");
			_harmony.PatchAll(Assembly.GetExecutingAssembly());
			((BasePlugin)this).Log.LogInfo((object)"ScarletCore event listener auto-initialization setup complete");
		}

		public override bool Unload()
		{
			Harmony harmony = _harmony;
			if (harmony != null)
			{
				harmony.UnpatchSelf();
			}
			return true;
		}
	}
	public static class MyPluginInfo
	{
		public const string PLUGIN_GUID = "markvaaz.ScarletCore";

		public const string PLUGIN_NAME = "ScarletCore";

		public const string PLUGIN_VERSION = "1.0.5";
	}
}
namespace ScarletCore.Utils
{
	public static class Log
	{
		private static ManualLogSource MLS => Plugin.LogInstance;

		public static void Debug(object message)
		{
			ManualLogSource mLS = MLS;
			if (mLS != null)
			{
				mLS.LogDebug(message);
			}
		}

		public static void Info(object message)
		{
			ManualLogSource mLS = MLS;
			if (mLS != null)
			{
				mLS.LogInfo(message);
			}
		}

		public static void Warning(object message)
		{
			ManualLogSource mLS = MLS;
			if (mLS != null)
			{
				mLS.LogWarning(message);
			}
		}

		public static void Error(object message)
		{
			ManualLogSource mLS = MLS;
			if (mLS != null)
			{
				mLS.LogError(message);
			}
		}

		public static void Fatal(object message)
		{
			ManualLogSource mLS = MLS;
			if (mLS != null)
			{
				mLS.LogFatal(message);
			}
		}

		public static void LogLevel(LogLevel level, object message)
		{
			//IL_000c: Unknown result type (might be due to invalid IL or missing references)
			ManualLogSource mLS = MLS;
			if (mLS != null)
			{
				mLS.Log(level, message);
			}
		}

		public static void Components(Entity entity)
		{
			//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_0009: Unknown result type (might be due to invalid IL or missing references)
			//IL_000b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0010: Unknown result type (might be due to invalid IL or missing references)
			//IL_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_0023: 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)
			EntityManager entityManager = GameSystems.EntityManager;
			Enumerator<ComponentType> enumerator = ((EntityManager)(ref entityManager)).GetComponentTypes(entity, (Allocator)2).GetEnumerator();
			while (enumerator.MoveNext())
			{
				ComponentType current = enumerator.Current;
				Info(current);
			}
		}

		public static void Player(PlayerData playerData)
		{
			//IL_00a6: Unknown result type (might be due to invalid IL or missing references)
			//IL_018d: 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)
			if (playerData == null)
			{
				Warning("PlayerData is null");
				return;
			}
			Info("=== PlayerData Information ===");
			Info("  Name: " + playerData.Name);
			Info("  Cached Name: " + (playerData.CachedName ?? "null"));
			Info($"  Platform ID: {playerData.PlatformId}");
			Info($"  Network ID: {playerData.NetworkId}");
			Info($"  Is Online: {playerData.IsOnline}");
			Info($"  Is Admin: {playerData.IsAdmin}");
			Info($"  Connected Since: {playerData.ConnectedSince}");
			Info("  Clan Name: " + (playerData.ClanName ?? "No Clan"));
			Info($"  User Entity: {playerData.UserEntity}");
			Info($"  Character Entity: {playerData.CharacterEntity}");
			Info("==============================");
		}
	}
	public static class MathUtility
	{
		public static float Distance(Entity A, Entity B)
		{
			//IL_0001: 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)
			//IL_0022: 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_0028: Unknown result type (might be due to invalid IL or missing references)
			//IL_0029: Unknown result type (might be due to invalid IL or missing references)
			//IL_002a: Unknown result type (might be due to invalid IL or missing references)
			//IL_002f: 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_0031: Unknown result type (might be due to invalid IL or missing references)
			//IL_0036: 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)
			if (!A.Has<LocalTransform>() || !B.Has<LocalTransform>())
			{
				return float.MaxValue;
			}
			LocalTransform val = A.Read<LocalTransform>();
			LocalTransform val2 = B.Read<LocalTransform>();
			return math.distance(val.Position, val2.Position);
		}

		public static float Distance2D(Entity A, Entity B)
		{
			//IL_0001: 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)
			//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_002b: Unknown result type (might be due to invalid IL or missing references)
			//IL_002c: Unknown result type (might be due to invalid IL or missing references)
			//IL_002d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0032: 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_0034: Unknown result type (might be due to invalid IL or missing references)
			//IL_0039: Unknown result type (might be due to invalid IL or missing references)
			//IL_003a: Unknown result type (might be due to invalid IL or missing references)
			//IL_003b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0040: Unknown result type (might be due to invalid IL or missing references)
			//IL_0041: 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_004d: 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_0058: Unknown result type (might be due to invalid IL or missing references)
			//IL_005e: Unknown result type (might be due to invalid IL or missing references)
			if (!A.Has<LocalTransform>() || !B.Has<LocalTransform>())
			{
				return float.MaxValue;
			}
			LocalTransform val = A.Read<LocalTransform>();
			LocalTransform val2 = B.Read<LocalTransform>();
			float3 position = val.Position;
			float3 position2 = val2.Position;
			return math.distance(new float2(position.x, position.z), new float2(position2.x, position2.z));
		}

		public static float Distance(Entity entity, float3 position)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0017: Unknown result type (might be due to invalid IL or missing references)
			//IL_0018: 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_0024: Unknown result type (might be due to invalid IL or missing references)
			if (!entity.Has<LocalTransform>())
			{
				return float.MaxValue;
			}
			LocalTransform val = entity.Read<LocalTransform>();
			return math.distance(val.Position, position);
		}

		public static float Distance2D(Entity entity, float3 position)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0017: Unknown result type (might be due to invalid IL or missing references)
			//IL_0018: 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_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_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_0036: 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_0042: Unknown result type (might be due to invalid IL or missing references)
			if (!entity.Has<LocalTransform>())
			{
				return float.MaxValue;
			}
			LocalTransform val = entity.Read<LocalTransform>();
			float3 position2 = val.Position;
			return math.distance(new float2(position2.x, position2.z), new float2(position.x, position.z));
		}

		public static float Distance(float3 positionA, float3 positionB)
		{
			//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)
			return math.distance(positionA, positionB);
		}

		public static float Distance2D(float3 positionA, float3 positionB)
		{
			//IL_0001: 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_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)
			//IL_0018: 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)
			return math.distance(new float2(positionA.x, positionA.z), new float2(positionB.x, positionB.z));
		}

		public static bool IsInRange(Entity A, Entity B, float range)
		{
			//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)
			return Distance(A, B) <= range;
		}

		public static bool IsInRange2D(Entity A, Entity B, float range)
		{
			//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)
			return Distance2D(A, B) <= range;
		}

		public static bool IsInRange(Entity entity, float3 position, float range)
		{
			//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)
			return Distance(entity, position) <= range;
		}

		public static bool IsInRange2D(Entity entity, float3 position, float range)
		{
			//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)
			return Distance2D(entity, position) <= range;
		}

		public static bool IsInRange(float3 positionA, float3 positionB, float range)
		{
			//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)
			return Distance(positionA, positionB) <= range;
		}

		public static bool IsInRange2D(float3 positionA, float3 positionB, float range)
		{
			//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)
			return Distance2D(positionA, positionB) <= range;
		}

		public static float3 GetRandomPositionInRadius(float3 center, float radius)
		{
			//IL_0023: 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_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_0050: 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)
			float num = Random.Range(0f, 2f * math.PI);
			float num2 = Random.Range(0f, radius);
			float num3 = center.x + num2 * math.cos(num);
			float num4 = center.z + num2 * math.sin(num);
			return new float3(num3, center.y, num4);
		}

		public static float3 GetRandomPositionInRing(float3 center, float minRadius, float maxRadius)
		{
			//IL_001f: Unknown result type (might be due to invalid IL or missing references)
			//IL_002f: 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_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_0050: Unknown result type (might be due to invalid IL or missing references)
			float num = Random.Range(0f, 2f * math.PI);
			float num2 = Random.Range(minRadius, maxRadius);
			float num3 = center.x + num2 * math.cos(num);
			float num4 = center.z + num2 * math.sin(num);
			return new float3(num3, center.y, num4);
		}

		public static float3 GetRandomPositionAroundEntity(Entity entity, float radius)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0017: Unknown result type (might be due to invalid IL or missing references)
			//IL_0018: 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_0025: 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_000f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0014: Unknown result type (might be due to invalid IL or missing references)
			//IL_002d: Unknown result type (might be due to invalid IL or missing references)
			if (!entity.Has<LocalTransform>())
			{
				return float3.zero;
			}
			LocalTransform val = entity.Read<LocalTransform>();
			return GetRandomPositionInRadius(val.Position, radius);
		}

		public static float3 GetRandomPositionAroundEntity(Entity entity, float minRadius, float maxRadius)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0017: Unknown result type (might be due to invalid IL or missing references)
			//IL_0018: 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_0026: Unknown result type (might be due to invalid IL or missing references)
			//IL_002b: Unknown result type (might be due to invalid IL or missing references)
			//IL_000f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0014: Unknown result type (might be due to invalid IL or missing references)
			//IL_002e: Unknown result type (might be due to invalid IL or missing references)
			if (!entity.Has<LocalTransform>())
			{
				return float3.zero;
			}
			LocalTransform val = entity.Read<LocalTransform>();
			return GetRandomPositionInRing(val.Position, minRadius, maxRadius);
		}

		public static float NormalizeAngle(float angle)
		{
			while (angle < 0f)
			{
				angle += 2f * math.PI;
			}
			while (angle >= 2f * math.PI)
			{
				angle -= 2f * math.PI;
			}
			return angle;
		}

		public static float GetAngleBetween(float3 from, float3 to)
		{
			//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_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_0009: 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)
			float3 val = to - from;
			return math.atan2(val.z, val.x);
		}

		public static float GetAngleBetween(Entity from, Entity to)
		{
			//IL_0001: 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)
			//IL_0022: 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_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_002e: Unknown result type (might be due to invalid IL or missing references)
			//IL_002f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0034: Unknown result type (might be due to invalid IL or missing references)
			//IL_0039: Unknown result type (might be due to invalid IL or missing references)
			//IL_003a: Unknown result type (might be due to invalid IL or missing references)
			//IL_003b: Unknown result type (might be due to invalid IL or missing references)
			if (!from.Has<LocalTransform>() || !to.Has<LocalTransform>())
			{
				return 0f;
			}
			float3 position = from.Read<LocalTransform>().Position;
			float3 position2 = to.Read<LocalTransform>().Position;
			return GetAngleBetween(position, position2);
		}

		public static float3 Lerp(float3 from, float3 to, float t)
		{
			//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_0013: Unknown result type (might be due to invalid IL or missing references)
			//IL_0018: Unknown result type (might be due to invalid IL or missing references)
			//IL_001b: Unknown result type (might be due to invalid IL or missing references)
			return math.lerp(from, to, math.clamp(t, 0f, 1f));
		}

		public static float3 ClampPosition(float3 position, float3 minBounds, float3 maxBounds)
		{
			//IL_0001: 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_000d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0018: 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_0024: Unknown result type (might be due to invalid IL or missing references)
			//IL_002f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0035: Unknown result type (might be due to invalid IL or missing references)
			//IL_003b: 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_004b: 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)
			return new float3(math.clamp(position.x, minBounds.x, maxBounds.x), math.clamp(position.y, minBounds.y, maxBounds.y), math.clamp(position.z, minBounds.z, maxBounds.z));
		}

		public static bool IsWithinBounds(float3 position, float3 minBounds, float3 maxBounds)
		{
			//IL_0001: 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_0015: 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_0023: 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_0039: 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_0047: 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)
			return position.x >= minBounds.x && position.x <= maxBounds.x && position.y >= minBounds.y && position.y <= maxBounds.y && position.z >= minBounds.z && position.z <= maxBounds.z;
		}

		public static float3 GetDirection(float3 from, float3 to)
		{
			//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_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_0009: Unknown result type (might be due to invalid IL or missing references)
			//IL_000a: 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_0012: Unknown result type (might be due to invalid IL or missing references)
			float3 val = to - from;
			return math.normalize(val);
		}

		public static float3 GetDirection(Entity from, Entity to)
		{
			//IL_0001: 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)
			//IL_0022: 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_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_002e: Unknown result type (might be due to invalid IL or missing references)
			//IL_002f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0034: Unknown result type (might be due to invalid IL or missing references)
			//IL_0039: Unknown result type (might be due to invalid IL or missing references)
			//IL_003a: Unknown result type (might be due to invalid IL or missing references)
			//IL_003b: 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)
			//IL_001a: Unknown result type (might be due to invalid IL or missing references)
			//IL_001f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0044: Unknown result type (might be due to invalid IL or missing references)
			if (!from.Has<LocalTransform>() || !to.Has<LocalTransform>())
			{
				return float3.zero;
			}
			float3 position = from.Read<LocalTransform>().Position;
			float3 position2 = to.Read<LocalTransform>().Position;
			return GetDirection(position, position2);
		}

		public static float3 GetClosestPointOnLine(float3 point, float3 lineStart, float3 lineEnd)
		{
			//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_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_0009: 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_0025: 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_002b: Unknown result type (might be due to invalid IL or missing references)
			//IL_002c: Unknown result type (might be due to invalid IL or missing references)
			//IL_002d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0032: 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_0034: 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_004c: 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_0054: 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_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_005d: Unknown result type (might be due to invalid IL or missing references)
			float3 val = lineEnd - lineStart;
			float num = math.length(val);
			if (num == 0f)
			{
				return lineStart;
			}
			float3 val2 = val / num;
			float3 val3 = point - lineStart;
			float num2 = math.dot(val3, val2);
			num2 = math.clamp(num2, 0f, num);
			return lineStart + val2 * num2;
		}

		public static int2 WorldToGrid(float3 worldPosition, float gridSize = 1f)
		{
			//IL_0001: 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_001d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0022: 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)
			return new int2((int)math.floor(worldPosition.x / gridSize), (int)math.floor(worldPosition.z / gridSize));
		}

		public static float3 GridToWorld(int2 gridPosition, float gridSize = 1f, float yHeight = 0f)
		{
			//IL_0001: 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_0024: Unknown result type (might be due to invalid IL or missing references)
			//IL_0029: Unknown result type (might be due to invalid IL or missing references)
			//IL_002c: Unknown result type (might be due to invalid IL or missing references)
			return new float3((float)gridPosition.x * gridSize + gridSize * 0.5f, yHeight, (float)gridPosition.y * gridSize + gridSize * 0.5f);
		}

		public static bool IsPointInCircle(float3 point, float3 circleCenter, float radius)
		{
			//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)
			return Distance2D(point, circleCenter) <= radius;
		}

		public static bool IsPointInRectangle(float3 point, float3 rectCenter, float2 rectSize)
		{
			//IL_0001: 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_000c: 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_0015: Unknown result type (might be due to invalid IL or missing references)
			//IL_0021: Unknown result type (might be due to invalid IL or missing references)
			//IL_0027: 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_003e: 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_004c: Unknown result type (might be due to invalid IL or missing references)
			float2 val = rectSize * 0.5f;
			float2 val2 = default(float2);
			((float2)(ref val2))..ctor(math.abs(point.x - rectCenter.x), math.abs(point.z - rectCenter.z));
			return val2.x <= val.x && val2.y <= val.y;
		}

		public static float3 RotatePointAround(float3 point, float3 pivot, float angleRadians)
		{
			//IL_000f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0010: Unknown result type (might be due to invalid IL or missing references)
			//IL_0011: Unknown result type (might be due to invalid IL or missing references)
			//IL_0016: Unknown result type (might be due to invalid IL or missing references)
			//IL_0019: Unknown result type (might be due to invalid IL or missing references)
			//IL_0021: Unknown result type (might be due to invalid IL or missing references)
			//IL_002a: 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_0038: 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_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_0051: Unknown result type (might be due to invalid IL or missing references)
			float num = math.cos(angleRadians);
			float num2 = math.sin(angleRadians);
			float3 val = point - pivot;
			float3 val2 = default(float3);
			((float3)(ref val2))..ctor(val.x * num - val.z * num2, val.y, val.x * num2 + val.z * num);
			return val2 + pivot;
		}
	}
	public static class RichTextFormatter
	{
		public static readonly string Red = "#ff0000";

		public static readonly string Green = "#00ff00";

		public static readonly string Blue = "#0000ff";

		public static readonly string Yellow = "#ffff00";

		public static readonly string Orange = "#ffa500";

		public static readonly string Purple = "#800080";

		public static readonly string Pink = "#ffc0cb";

		public static readonly string White = "#ffffff";

		public static readonly string Gray = "#808080";

		public static readonly string Cyan = "#00ffff";

		public static readonly string HighlightColor = "#a963ff";

		public static readonly string HighlightErrorColor = "#ff4040";

		public static readonly string HighlightWarningColor = "#ffff00";

		public static readonly string TextColor = "#ffffff";

		public static readonly string ErrorTextColor = "#ff8f8f";

		public static readonly string WarningTextColor = "#ffff9e";

		public static string Bold(this string text)
		{
			return "<b>" + text + "</b>";
		}

		public static string Italic(this string text)
		{
			return "<i>" + text + "</i>";
		}

		public static string Underline(this string text)
		{
			return "<u>" + text + "</u>";
		}

		public static string ToRed(this string text)
		{
			return "<color=red>" + text + "</color>";
		}

		public static string ToGreen(this string text)
		{
			return "<color=green>" + text + "</color>";
		}

		public static string ToBlue(this string text)
		{
			return "<color=blue>" + text + "</color>";
		}

		public static string ToYellow(this string text)
		{
			return "<color=yellow>" + text + "</color>";
		}

		public static string ToWhite(this string text)
		{
			return "<color=white>" + text + "</color>";
		}

		public static string ToBlack(this string text)
		{
			return "<color=black>" + text + "</color>";
		}

		public static string ToGray(this string text)
		{
			return "<color=#cccccc>" + text + "</color>";
		}

		public static string WithColor(this string text, string hex)
		{
			return $"<color={hex}>{text}</color>";
		}

		public static string Format(this string text, List<string> highlightColors = null)
		{
			if (highlightColors == null)
			{
				highlightColors = new List<string>(1) { HighlightColor };
			}
			return ApplyFormatting(text, TextColor, highlightColors);
		}

		public static string FormatError(this string text)
		{
			return ApplyFormatting(text, ErrorTextColor, new List<string>(1) { HighlightErrorColor });
		}

		public static string FormatWarning(this string text)
		{
			return ApplyFormatting(text, WarningTextColor, new List<string>(1) { HighlightWarningColor });
		}

		public static string FormatSuccess(this string text)
		{
			return ApplyFormatting(text, TextColor, new List<string>(1) { Green });
		}

		public static string FormatInfo(this string text)
		{
			return ApplyFormatting(text, TextColor, new List<string>(1) { Blue });
		}

		public static string AsError(this string text)
		{
			return ("[ERROR] " + text).WithColor(Red);
		}

		public static string AsSuccess(this string text)
		{
			return ("[SUCCESS] " + text).WithColor(Green);
		}

		public static string AsWarning(this string text)
		{
			return ("[WARNING] " + text).WithColor(Yellow);
		}

		public static string AsInfo(this string text)
		{
			return ("[INFO] " + text).WithColor(Blue);
		}

		public static string AsAnnouncement(this string text)
		{
			return ("[ANNOUNCEMENT] " + text).WithColor(Orange);
		}

		public static string AsList(this string text)
		{
			return "[LIST] " + text;
		}

		public static string AsPlayerJoin(this string playerName)
		{
			return (playerName + " has joined the server!").WithColor(Green);
		}

		public static string AsPlayerLeave(this string playerName)
		{
			return (playerName + " has left the server").WithColor(Gray);
		}

		public static string AsPlayerDeath(this string victimName, string killerName = null)
		{
			return string.IsNullOrEmpty(killerName) ? (victimName + " has died").WithColor(Red) : (victimName + " was killed by " + killerName).WithColor(Red);
		}

		public static string AsProgressBar(this string label, int current, int max, int barLength = 20)
		{
			float num = (float)current / (float)max;
			int num2 = (int)(num * (float)barLength);
			int count = barLength - num2;
			string value = new string('█', num2) + new string('░', count);
			return $"{label}: [{value}] {current}/{max} ({num:P0})".WithColor(Cyan);
		}

		public static string AsBoxedTitle(this string title)
		{
			string value = new string('═', title.Length + 4);
			return $"╔{value}╗\n║  {title}  ║\n╚{value}╝";
		}

		public static string AsBoxedContent(this string content, string title)
		{
			int num = title.Length + 4;
			string[] array = content.Split('\n');
			string text = "";
			string[] array2 = array;
			foreach (string text2 in array2)
			{
				int count = Math.Max(0, num - text2.Length - 2);
				text = text + "║ " + text2 + new string(' ', count) + " ║\n";
			}
			return text.TrimEnd('\n');
		}

		public static string AsSeparator(this char character, int length = 40)
		{
			return new string(character, length).WithColor(Gray);
		}

		public static string AsCountdown(this string action, int seconds)
		{
			if (seconds > 60)
			{
				int num = seconds / 60;
				return $"{action} in {num} minute{((num != 1) ? "s" : "")}!".AsWarning();
			}
			if (seconds > 10)
			{
				return $"{action} in {seconds} seconds!".AsWarning();
			}
			if (seconds > 0)
			{
				return $"{action} in {seconds}!".AsError();
			}
			return (action + " NOW!").AsError();
		}

		private static string ApplyFormatting(string text, string baseColor, List<string> highlightColors)
		{
			string pattern = "\\*\\*(.*?)\\*\\*";
			string pattern2 = "\\*(.*?)\\*";
			string pattern3 = "__(.*?)__";
			string pattern4 = "~(.*?)~";
			string input = Regex.Replace(text, pattern, (Match m) => m.Groups[1].Value.Bold());
			input = Regex.Replace(input, pattern2, (Match m) => m.Groups[1].Value.Italic());
			input = Regex.Replace(input, pattern3, (Match m) => m.Groups[1].Value.Underline());
			int highlightIndex = 0;
			input = Regex.Replace(input, pattern4, delegate(Match m)
			{
				string text2 = ((highlightIndex < highlightColors.Count) ? highlightColors[highlightIndex] : HighlightColor);
				if (text2 == null)
				{
					text2 = HighlightColor;
				}
				highlightIndex++;
				return m.Groups[1].Value.WithColor(text2);
			});
			return input.WithColor(baseColor);
		}
	}
}
namespace ScarletCore.Systems
{
	public readonly record struct ActionId(int Value)
	{
		private static int _nextId;

		public static ActionId Next()
		{
			return new ActionId(Interlocked.Increment(ref _nextId));
		}
	}
	public enum ActionType
	{
		OncePerFrame,
		NextFrame,
		RepeatingSeconds,
		RepeatingFrames,
		DelayedSeconds,
		DelayedFrames
	}
	public class ScheduledAction
	{
		public Action<Action> ActionWithCancel { get; set; }

		public Action Action { get; set; }

		public ActionType Type { get; set; }

		public float Interval { get; set; }

		public float NextExecutionTime { get; set; }

		public int FrameInterval { get; set; }

		public int NextExecutionFrame { get; set; }

		public int LastExecutionFrame { get; set; } = -1;


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


		public ActionId Id { get; set; }

		public bool ShouldCancel { get; set; } = false;


		public int MaxExecutions { get; set; } = -1;


		public int ExecutionCount { get; set; } = 0;


		public float MinInterval { get; set; } = 0f;


		public float MaxInterval { get; set; } = 0f;


		public ScheduledAction(Action action, ActionType type, float interval = 0f, int frameInterval = 0, ActionId id = default(ActionId), int maxExecutions = -1)
		{
			Action = action;
			Type = type;
			Interval = interval;
			FrameInterval = frameInterval;
			Id = ((id.Value == 0) ? ActionId.Next() : id);
			MaxExecutions = maxExecutions;
			InitializeTiming(type, interval, frameInterval);
		}

		public ScheduledAction(Action<Action> actionWithCancel, ActionType type, float interval = 0f, int frameInterval = 0, ActionId id = default(ActionId), int maxExecutions = -1)
		{
			ActionWithCancel = actionWithCancel;
			Type = type;
			Interval = interval;
			FrameInterval = frameInterval;
			Id = ((id.Value == 0) ? ActionId.Next() : id);
			MaxExecutions = maxExecutions;
			InitializeTiming(type, interval, frameInterval);
		}

		private void InitializeTiming(ActionType type, float interval, int frameInterval)
		{
			switch (type)
			{
			case ActionType.RepeatingSeconds:
			case ActionType.DelayedSeconds:
				NextExecutionTime = Time.time + interval;
				break;
			case ActionType.RepeatingFrames:
			case ActionType.DelayedFrames:
				NextExecutionFrame = Time.frameCount + frameInterval;
				break;
			case ActionType.NextFrame:
				NextExecutionFrame = Time.frameCount + 1;
				break;
			}
		}
	}
	public static class ActionScheduler
	{
		private static readonly List<ScheduledAction> _scheduledActions = new List<ScheduledAction>();

		private static readonly List<ScheduledAction> _actionsToRemove = new List<ScheduledAction>();

		private static readonly Dictionary<ActionId, ScheduledAction> _actionLookup = new Dictionary<ActionId, ScheduledAction>();

		private static readonly List<ScheduledAction> _activeActions = new List<ScheduledAction>();

		public static int Count => _scheduledActions.Count;

		public static void Execute()
		{
			float time = Time.time;
			int frameCount = Time.frameCount;
			lock (_scheduledActions)
			{
				_activeActions.Clear();
				_activeActions.AddRange(_scheduledActions);
			}
			foreach (ScheduledAction action in _activeActions)
			{
				bool flag;
				lock (_scheduledActions)
				{
					flag = _scheduledActions.Contains(action);
				}
				if (!flag)
				{
					continue;
				}
				if (!action.IsActive || action.ShouldCancel)
				{
					if (action.ShouldCancel)
					{
						_actionsToRemove.Add(action);
					}
					continue;
				}
				bool flag2 = false;
				bool flag3 = false;
				switch (action.Type)
				{
				case ActionType.OncePerFrame:
					if (action.LastExecutionFrame != frameCount)
					{
						flag2 = true;
						action.LastExecutionFrame = frameCount;
					}
					break;
				case ActionType.NextFrame:
					if (frameCount >= action.NextExecutionFrame)
					{
						flag2 = true;
						flag3 = true;
					}
					break;
				case ActionType.RepeatingSeconds:
					if (time >= action.NextExecutionTime)
					{
						flag2 = true;
						if (action.MinInterval > 0f && action.MaxInterval > action.MinInterval)
						{
							action.NextExecutionTime = time + GetRandomInterval(action.MinInterval, action.MaxInterval);
						}
						else
						{
							action.NextExecutionTime = time + action.Interval;
						}
					}
					break;
				case ActionType.RepeatingFrames:
					if (frameCount >= action.NextExecutionFrame)
					{
						flag2 = true;
						action.NextExecutionFrame = frameCount + action.FrameInterval;
					}
					break;
				case ActionType.DelayedSeconds:
					if (time >= action.NextExecutionTime)
					{
						flag2 = true;
						flag3 = true;
					}
					break;
				case ActionType.DelayedFrames:
					if (frameCount >= action.NextExecutionFrame)
					{
						flag2 = true;
						flag3 = true;
					}
					break;
				}
				if (flag2)
				{
					try
					{
						if (action.ActionWithCancel != null)
						{
							action.ActionWithCancel(delegate
							{
								action.ShouldCancel = true;
							});
						}
						else
						{
							action.Action?.Invoke();
						}
						action.ExecutionCount++;
						if (action.MaxExecutions > 0 && action.ExecutionCount >= action.MaxExecutions)
						{
							flag3 = true;
						}
					}
					catch (Exception value)
					{
						Log.Error($"Error executing scheduled action {action.Id}: {value}");
						flag3 = true;
					}
				}
				if (flag3)
				{
					_actionsToRemove.Add(action);
				}
			}
			if (_actionsToRemove.Count <= 0)
			{
				return;
			}
			lock (_scheduledActions)
			{
				foreach (ScheduledAction item in _actionsToRemove)
				{
					_scheduledActions.Remove(item);
					_actionLookup.Remove(item.Id);
				}
			}
			_actionsToRemove.Clear();
		}

		private static void AddActionInternal(ScheduledAction scheduledAction)
		{
			lock (_scheduledActions)
			{
				_scheduledActions.Add(scheduledAction);
				_actionLookup[scheduledAction.Id] = scheduledAction;
			}
		}

		public static ActionId OncePerFrame(Action<Action> action, int maxExecutions = -1)
		{
			ScheduledAction scheduledAction = new ScheduledAction(action, ActionType.OncePerFrame, 0f, 0, default(ActionId), maxExecutions);
			AddActionInternal(scheduledAction);
			return scheduledAction.Id;
		}

		public static ActionId OncePerFrame(Action action, int maxExecutions = -1)
		{
			ScheduledAction scheduledAction = new ScheduledAction(action, ActionType.OncePerFrame, 0f, 0, default(ActionId), maxExecutions);
			AddActionInternal(scheduledAction);
			return scheduledAction.Id;
		}

		public static ActionId NextFrame(Action<Action> action)
		{
			ScheduledAction scheduledAction = new ScheduledAction(action, ActionType.NextFrame);
			AddActionInternal(scheduledAction);
			return scheduledAction.Id;
		}

		public static ActionId NextFrame(Action action)
		{
			ScheduledAction scheduledAction = new ScheduledAction(action, ActionType.NextFrame);
			AddActionInternal(scheduledAction);
			return scheduledAction.Id;
		}

		public static ActionId Repeating(Action<Action> action, float intervalSeconds, int maxExecutions = -1)
		{
			ScheduledAction scheduledAction = new ScheduledAction(action, ActionType.RepeatingSeconds, intervalSeconds, 0, default(ActionId), maxExecutions);
			AddActionInternal(scheduledAction);
			return scheduledAction.Id;
		}

		public static ActionId Repeating(Action action, float intervalSeconds, int maxExecutions = -1)
		{
			ScheduledAction scheduledAction = new ScheduledAction(action, ActionType.RepeatingSeconds, intervalSeconds, 0, default(ActionId), maxExecutions);
			AddActionInternal(scheduledAction);
			return scheduledAction.Id;
		}

		public static ActionId RepeatingFrames(Action<Action> action, int frameInterval, int maxExecutions = -1)
		{
			ScheduledAction scheduledAction = new ScheduledAction(action, ActionType.RepeatingFrames, 0f, frameInterval, default(ActionId), maxExecutions);
			AddActionInternal(scheduledAction);
			return scheduledAction.Id;
		}

		public static ActionId RepeatingFrames(Action action, int frameInterval, int maxExecutions = -1)
		{
			ScheduledAction scheduledAction = new ScheduledAction(action, ActionType.RepeatingFrames, 0f, frameInterval, default(ActionId), maxExecutions);
			AddActionInternal(scheduledAction);
			return scheduledAction.Id;
		}

		public static ActionId Delayed(Action<Action> action, float delaySeconds)
		{
			ScheduledAction scheduledAction = new ScheduledAction(action, ActionType.DelayedSeconds, delaySeconds);
			AddActionInternal(scheduledAction);
			return scheduledAction.Id;
		}

		public static ActionId Delayed(Action action, float delaySeconds)
		{
			ScheduledAction scheduledAction = new ScheduledAction(action, ActionType.DelayedSeconds, delaySeconds);
			AddActionInternal(scheduledAction);
			return scheduledAction.Id;
		}

		public static ActionId DelayedFrames(Action<Action> action, int delayFrames)
		{
			ScheduledAction scheduledAction = new ScheduledAction(action, ActionType.DelayedFrames, 0f, delayFrames);
			AddActionInternal(scheduledAction);
			return scheduledAction.Id;
		}

		public static ActionId DelayedFrames(Action action, int delayFrames)
		{
			ScheduledAction scheduledAction = new ScheduledAction(action, ActionType.DelayedFrames, 0f, delayFrames);
			AddActionInternal(scheduledAction);
			return scheduledAction.Id;
		}

		public static bool CancelAction(ActionId actionId)
		{
			lock (_scheduledActions)
			{
				if (_actionLookup.TryGetValue(actionId, out var value))
				{
					bool flag = _scheduledActions.Remove(value);
					if (flag)
					{
						_actionLookup.Remove(actionId);
					}
					return flag;
				}
				return false;
			}
		}

		public static void PauseAction(ActionId actionId)
		{
			lock (_scheduledActions)
			{
				if (_actionLookup.TryGetValue(actionId, out var value))
				{
					value.IsActive = false;
				}
			}
		}

		public static void ResumeAction(ActionId actionId)
		{
			lock (_scheduledActions)
			{
				if (_actionLookup.TryGetValue(actionId, out var value))
				{
					value.IsActive = true;
				}
			}
		}

		public static void ClearAllActions()
		{
			lock (_scheduledActions)
			{
				_scheduledActions.Clear();
				_actionLookup.Clear();
			}
			_actionsToRemove.Clear();
		}

		public static int GetExecutionCount(ActionId actionId)
		{
			if (_actionLookup.TryGetValue(actionId, out var value))
			{
				return value.ExecutionCount;
			}
			return 0;
		}

		public static int GetMaxExecutions(ActionId actionId)
		{
			if (_actionLookup.TryGetValue(actionId, out var value))
			{
				return value.MaxExecutions;
			}
			return -1;
		}

		public static int GetRemainingExecutions(ActionId actionId)
		{
			if (_actionLookup.TryGetValue(actionId, out var value))
			{
				if (value.MaxExecutions <= 0)
				{
					return -1;
				}
				return Math.Max(0, value.MaxExecutions - value.ExecutionCount);
			}
			return -1;
		}

		public static ActionSequence CreateSequence()
		{
			return new ActionSequence();
		}

		public static bool CancelSequence(ActionId sequenceId)
		{
			return CancelAction(sequenceId);
		}

		public static ActionId RepeatingRandom(Action<Action> action, float minIntervalSeconds, float maxIntervalSeconds, int maxExecutions = -1)
		{
			ScheduledAction scheduledAction = new ScheduledAction(action, ActionType.RepeatingSeconds, GetRandomInterval(minIntervalSeconds, maxIntervalSeconds), 0, default(ActionId), maxExecutions);
			scheduledAction.MinInterval = minIntervalSeconds;
			scheduledAction.MaxInterval = maxIntervalSeconds;
			AddActionInternal(scheduledAction);
			return scheduledAction.Id;
		}

		public static ActionId RepeatingRandom(Action action, float minIntervalSeconds, float maxIntervalSeconds, int maxExecutions = -1)
		{
			ScheduledAction scheduledAction = new ScheduledAction(action, ActionType.RepeatingSeconds, GetRandomInterval(minIntervalSeconds, maxIntervalSeconds), 0, default(ActionId), maxExecutions);
			scheduledAction.MinInterval = minIntervalSeconds;
			scheduledAction.MaxInterval = maxIntervalSeconds;
			AddActionInternal(scheduledAction);
			return scheduledAction.Id;
		}

		private static float GetRandomInterval(float minInterval, float maxInterval)
		{
			return Random.Range(minInterval, maxInterval);
		}
	}
	public class SequenceStep
	{
		public enum StepType
		{
			Action,
			ActionWithCancel,
			WaitSeconds,
			WaitFrames,
			WaitRandomSeconds
		}

		public StepType Type { get; set; }

		public Action Action { get; set; }

		public Action<Action> ActionWithCancel { get; set; }

		public float WaitSeconds { get; set; }

		public int WaitFrames { get; set; }

		public float MinWaitSeconds { get; set; }

		public float MaxWaitSeconds { get; set; }
	}
	public class ActionSequence
	{
		private readonly List<SequenceStep> _steps = new List<SequenceStep>();

		private int _currentStepIndex = 0;

		private float _waitUntilTime;

		private int _waitUntilFrame;

		private bool _isWaiting = false;

		private bool _isCancelled = false;

		private ActionId _actionId;

		public int CurrentStepIndex => _currentStepIndex;

		public int TotalSteps => _steps.Count;

		public bool IsWaiting => _isWaiting;

		public bool IsCancelled => _isCancelled;

		public bool IsComplete => _currentStepIndex >= _steps.Count && !_isWaiting;

		public ActionSequence Then(Action action)
		{
			_steps.Add(new SequenceStep
			{
				Type = SequenceStep.StepType.Action,
				Action = action
			});
			return this;
		}

		public ActionSequence Then(Action<Action> action)
		{
			_steps.Add(new SequenceStep
			{
				Type = SequenceStep.StepType.ActionWithCancel,
				ActionWithCancel = action
			});
			return this;
		}

		public ActionSequence ThenWait(float seconds)
		{
			_steps.Add(new SequenceStep
			{
				Type = SequenceStep.StepType.WaitSeconds,
				WaitSeconds = seconds
			});
			return this;
		}

		public ActionSequence ThenWaitFrames(int frames)
		{
			_steps.Add(new SequenceStep
			{
				Type = SequenceStep.StepType.WaitFrames,
				WaitFrames = frames
			});
			return this;
		}

		public ActionSequence ThenWaitRandom(float minSeconds, float maxSeconds)
		{
			_steps.Add(new SequenceStep
			{
				Type = SequenceStep.StepType.WaitRandomSeconds,
				MinWaitSeconds = minSeconds,
				MaxWaitSeconds = maxSeconds
			});
			return this;
		}

		public ActionId Execute()
		{
			_currentStepIndex = 0;
			_isWaiting = false;
			_isCancelled = false;
			_actionId = ActionScheduler.OncePerFrame(delegate(Action cancel)
			{
				ExecuteNextStep(cancel);
			});
			return _actionId;
		}

		private void ExecuteNextStep(Action cancelSequence)
		{
			if (_isCancelled)
			{
				cancelSequence();
				return;
			}
			if (_isWaiting)
			{
				SequenceStep sequenceStep = _steps[_currentStepIndex];
				if (sequenceStep.Type == SequenceStep.StepType.WaitSeconds)
				{
					if (Time.time >= _waitUntilTime)
					{
						_isWaiting = false;
						_currentStepIndex++;
					}
				}
				else if (sequenceStep.Type == SequenceStep.StepType.WaitFrames)
				{
					if (Time.frameCount >= _waitUntilFrame)
					{
						_isWaiting = false;
						_currentStepIndex++;
					}
				}
				else if (sequenceStep.Type == SequenceStep.StepType.WaitRandomSeconds && Time.time >= _waitUntilTime)
				{
					_isWaiting = false;
					_currentStepIndex++;
				}
				return;
			}
			if (_currentStepIndex >= _steps.Count)
			{
				cancelSequence();
				return;
			}
			SequenceStep sequenceStep2 = _steps[_currentStepIndex];
			try
			{
				switch (sequenceStep2.Type)
				{
				case SequenceStep.StepType.Action:
					sequenceStep2.Action?.Invoke();
					_currentStepIndex++;
					break;
				case SequenceStep.StepType.ActionWithCancel:
					sequenceStep2.ActionWithCancel?.Invoke(delegate
					{
						_isCancelled = true;
					});
					_currentStepIndex++;
					break;
				case SequenceStep.StepType.WaitSeconds:
					_waitUntilTime = Time.time + sequenceStep2.WaitSeconds;
					_isWaiting = true;
					break;
				case SequenceStep.StepType.WaitFrames:
					_waitUntilFrame = Time.frameCount + sequenceStep2.WaitFrames;
					_isWaiting = true;
					break;
				case SequenceStep.StepType.WaitRandomSeconds:
				{
					float num = Random.Range(sequenceStep2.MinWaitSeconds, sequenceStep2.MaxWaitSeconds);
					_waitUntilTime = Time.time + num;
					_isWaiting = true;
					break;
				}
				}
			}
			catch (Exception value)
			{
				Log.Error($"Error executing sequence step {_currentStepIndex}: {value}");
				cancelSequence();
			}
		}

		public void Cancel()
		{
			_isCancelled = true;
		}
	}
	public readonly record struct CoroutineId(int Value)
	{
		private static int _nextId;

		public static CoroutineId Next()
		{
			return new CoroutineId(Interlocked.Increment(ref _nextId));
		}
	}
	public class ManagedCoroutine
	{
		public Coroutine Coroutine { get; set; }

		public CoroutineId Id { get; set; }

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


		public string Name { get; set; }

		public Action OnComplete { get; set; }

		public int MaxExecutions { get; set; } = -1;


		public int ExecutionCount { get; set; } = 0;


		public bool IsPaused { get; set; } = false;


		public DateTime? PausedAt { get; set; }

		public ManagedCoroutine(Coroutine coroutine, CoroutineId id, string name = null, int maxExecutions = -1)
		{
			Coroutine = coroutine;
			Id = id;
			Name = name ?? $"Coroutine_{id.Value}";
			MaxExecutions = maxExecutions;
		}
	}
	public class CoroutineHandler
	{
		private static GameObject _gameObject;

		private static IgnorePhysicsDebugSystem _coroutineManager;

		private static readonly Dictionary<CoroutineId, ManagedCoroutine> _managedCoroutines = new Dictionary<CoroutineId, ManagedCoroutine>();

		private static CoroutineId? _autoCleanupId;

		private static bool _autoCleanupEnabled = false;

		private static readonly object _autoCleanupLock = new object();

		public static int ActiveCoroutineCount => _managedCoroutines.Count;

		private static IgnorePhysicsDebugSystem GetCoroutineManager()
		{
			//IL_0016: Unknown result type (might be due to invalid IL or missing references)
			//IL_0020: Expected O, but got Unknown
			if ((Object)(object)_gameObject == (Object)null)
			{
				_gameObject = new GameObject("ScarletCore_CoroutineHandler");
				Object.DontDestroyOnLoad((Object)(object)_gameObject);
			}
			if ((Object)(object)_coroutineManager == (Object)null)
			{
				_coroutineManager = _gameObject.AddComponent<IgnorePhysicsDebugSystem>();
			}
			return _coroutineManager;
		}

		private static CoroutineId StartManagedCoroutine(IEnumerator coroutineEnumerator, string name = null, Action onComplete = null, int maxExecutions = -1)
		{
			CoroutineId coroutineId = CoroutineId.Next();
			ManagedCoroutine managedCoroutine = new ManagedCoroutine(null, coroutineId, name, maxExecutions)
			{
				OnComplete = onComplete
			};
			_managedCoroutines[coroutineId] = managedCoroutine;
			IEnumerator enumerator = WrapCoroutineWithTracking(coroutineEnumerator, coroutineId);
			Coroutine coroutine = ((MonoBehaviour)GetCoroutineManager()).StartCoroutine(CollectionExtensions.WrapToIl2Cpp(enumerator));
			managedCoroutine.Coroutine = coroutine;
			return coroutineId;
		}

		private static IEnumerator WrapCoroutineWithTracking(IEnumerator originalCoroutine, CoroutineId id)
		{
			try
			{
				while (originalCoroutine.MoveNext())
				{
					if (_managedCoroutines.TryGetValue(id, out var managedCoroutine2))
					{
						while (managedCoroutine2.IsPaused && managedCoroutine2.IsActive)
						{
							yield return (object)new WaitForSeconds(0.1f);
						}
						if (!managedCoroutine2.IsActive)
						{
							break;
						}
					}
					yield return originalCoroutine.Current;
					managedCoroutine2 = null;
				}
			}
			finally
			{
				if (_managedCoroutines.TryGetValue(id, out var managedCoroutine))
				{
					managedCoroutine.OnComplete?.Invoke();
					_managedCoroutines.Remove(id);
				}
			}
		}

		public static CoroutineId StartGeneric(Action action, float delay, string name = null)
		{
			return StartManagedCoroutine(GenericCoroutine(action, delay), name);
		}

		private static IEnumerator GenericCoroutine(Action action, float delay)
		{
			yield return (object)new WaitForSeconds(delay);
			action?.Invoke();
		}

		public static CoroutineId StartRepeating(Action action, float delay, string name = null, int maxExecutions = -1)
		{
			CoroutineId coroutineId = CoroutineId.Next();
			ManagedCoroutine managedCoroutine = new ManagedCoroutine(null, coroutineId, name, maxExecutions);
			_managedCoroutines[coroutineId] = managedCoroutine;
			IEnumerator enumerator = WrapCoroutineWithTracking(RepeatingCoroutineWithMax(action, delay, maxExecutions, coroutineId), coroutineId);
			Coroutine coroutine = ((MonoBehaviour)GetCoroutineManager()).StartCoroutine(CollectionExtensions.WrapToIl2Cpp(enumerator));
			managedCoroutine.Coroutine = coroutine;
			return coroutineId;
		}

		public static CoroutineId StartRepeating(Action<Action> actionWithCancel, float delay, string name = null, int maxExecutions = -1)
		{
			CoroutineId coroutineId = CoroutineId.Next();
			ManagedCoroutine managedCoroutine = new ManagedCoroutine(null, coroutineId, name, maxExecutions);
			_managedCoroutines[coroutineId] = managedCoroutine;
			IEnumerator enumerator = WrapCoroutineWithTracking(RepeatingCoroutineWithCancelAndMax(actionWithCancel, delay, maxExecutions, coroutineId), coroutineId);
			Coroutine coroutine = ((MonoBehaviour)GetCoroutineManager()).StartCoroutine(CollectionExtensions.WrapToIl2Cpp(enumerator));
			managedCoroutine.Coroutine = coroutine;
			return coroutineId;
		}

		private static IEnumerator RepeatingCoroutineWithMax(Action action, float delay, int maxExecutions, CoroutineId id)
		{
			int executionCount = 0;
			while (maxExecutions < 0 || executionCount < maxExecutions)
			{
				yield return (object)new WaitForSeconds(delay);
				action?.Invoke();
				executionCount++;
				if (_managedCoroutines.TryGetValue(id, out var managedCoroutine))
				{
					managedCoroutine.ExecutionCount = executionCount;
				}
				managedCoroutine = null;
			}
		}

		private static IEnumerator RepeatingCoroutineWithCancelAndMax(Action<Action> action, float delay, int maxExecutions, CoroutineId id)
		{
			bool shouldCancel = false;
			Action cancelAction = delegate
			{
				shouldCancel = true;
			};
			int executionCount = 0;
			while (!shouldCancel && (maxExecutions < 0 || executionCount < maxExecutions))
			{
				yield return (object)new WaitForSeconds(delay);
				if (!shouldCancel)
				{
					action?.Invoke(cancelAction);
					executionCount++;
					if (_managedCoroutines.TryGetValue(id, out var managedCoroutine))
					{
						managedCoroutine.ExecutionCount = executionCount;
					}
					managedCoroutine = null;
				}
			}
		}

		public static CoroutineId StartRepeating(Action action, float delay, int repeatCount, string name = null, Action onComplete = null)
		{
			return StartManagedCoroutine(RepeatingCoroutine(action, delay, repeatCount), name, onComplete);
		}

		private static IEnumerator RepeatingCoroutine(Action action, float delay, int repeatCount)
		{
			for (int i = 0; i < repeatCount; i++)
			{
				yield return (object)new WaitForSeconds(delay);
				action?.Invoke();
			}
		}

		public static CoroutineId StartFrameRepeating(Action action, int frameInterval, string name = null, int maxExecutions = -1)
		{
			CoroutineId coroutineId = CoroutineId.Next();
			ManagedCoroutine managedCoroutine = new ManagedCoroutine(null, coroutineId, name, maxExecutions);
			_managedCoroutines[coroutineId] = managedCoroutine;
			IEnumerator enumerator = WrapCoroutineWithTracking(FrameCoroutineWithMax(action, frameInterval, maxExecutions, coroutineId), coroutineId);
			Coroutine coroutine = ((MonoBehaviour)GetCoroutineManager()).StartCoroutine(CollectionExtensions.WrapToIl2Cpp(enumerator));
			managedCoroutine.Coroutine = coroutine;
			return coroutineId;
		}

		public static CoroutineId StartFrameRepeating(Action<Action> actionWithCancel, int frameInterval, string name = null, int maxExecutions = -1)
		{
			CoroutineId coroutineId = CoroutineId.Next();
			ManagedCoroutine managedCoroutine = new ManagedCoroutine(null, coroutineId, name, maxExecutions);
			_managedCoroutines[coroutineId] = managedCoroutine;
			IEnumerator enumerator = WrapCoroutineWithTracking(FrameCoroutineWithCancelAndMax(actionWithCancel, frameInterval, maxExecutions, coroutineId), coroutineId);
			Coroutine coroutine = ((MonoBehaviour)GetCoroutineManager()).StartCoroutine(CollectionExtensions.WrapToIl2Cpp(enumerator));
			managedCoroutine.Coroutine = coroutine;
			return coroutineId;
		}

		private static IEnumerator FrameCoroutineWithMax(Action action, int frameInterval, int maxExecutions, CoroutineId id)
		{
			int executionCount = 0;
			while (maxExecutions < 0 || executionCount < maxExecutions)
			{
				for (int i = 0; i < frameInterval; i++)
				{
					yield return null;
				}
				action?.Invoke();
				executionCount++;
				if (_managedCoroutines.TryGetValue(id, out var managedCoroutine))
				{
					managedCoroutine.ExecutionCount = executionCount;
				}
				managedCoroutine = null;
			}
		}

		private static IEnumerator FrameCoroutineWithCancelAndMax(Action<Action> action, int frameInterval, int maxExecutions, CoroutineId id)
		{
			bool shouldCancel = false;
			Action cancelAction = delegate
			{
				shouldCancel = true;
			};
			int executionCount = 0;
			while (!shouldCancel && (maxExecutions < 0 || executionCount < maxExecutions))
			{
				for (int i = 0; i < frameInterval; i++)
				{
					if (shouldCancel)
					{
						break;
					}
					yield return null;
				}
				if (!shouldCancel)
				{
					action?.Invoke(cancelAction);
					executionCount++;
					if (_managedCoroutines.TryGetValue(id, out var managedCoroutine))
					{
						managedCoroutine.ExecutionCount = executionCount;
					}
					managedCoroutine = null;
				}
			}
		}

		public static CoroutineId StartRandomInterval(Action action, float minDelay, float maxDelay, string name = null, int maxExecutions = -1)
		{
			CoroutineId coroutineId = CoroutineId.Next();
			ManagedCoroutine managedCoroutine = new ManagedCoroutine(null, coroutineId, name, maxExecutions);
			_managedCoroutines[coroutineId] = managedCoroutine;
			IEnumerator enumerator = WrapCoroutineWithTracking(RandomIntervalCoroutineWithMax(action, minDelay, maxDelay, maxExecutions, coroutineId), coroutineId);
			Coroutine coroutine = ((MonoBehaviour)GetCoroutineManager()).StartCoroutine(CollectionExtensions.WrapToIl2Cpp(enumerator));
			managedCoroutine.Coroutine = coroutine;
			return coroutineId;
		}

		public static CoroutineId StartRandomInterval(Action<Action> actionWithCancel, float minDelay, float maxDelay, string name = null, int maxExecutions = -1)
		{
			CoroutineId coroutineId = CoroutineId.Next();
			ManagedCoroutine managedCoroutine = new ManagedCoroutine(null, coroutineId, name, maxExecutions);
			_managedCoroutines[coroutineId] = managedCoroutine;
			IEnumerator enumerator = WrapCoroutineWithTracking(RandomIntervalCoroutineWithCancelAndMax(actionWithCancel, minDelay, maxDelay, maxExecutions, coroutineId), coroutineId);
			Coroutine coroutine = ((MonoBehaviour)GetCoroutineManager()).StartCoroutine(CollectionExtensions.WrapToIl2Cpp(enumerator));
			managedCoroutine.Coroutine = coroutine;
			return coroutineId;
		}

		private static IEnumerator RandomIntervalCoroutineWithMax(Action action, float minDelay, float maxDelay, int maxExecutions, CoroutineId id)
		{
			int executionCount = 0;
			while (maxExecutions < 0 || executionCount < maxExecutions)
			{
				float delay = Random.Range(minDelay, maxDelay);
				yield return (object)new WaitForSeconds(delay);
				action?.Invoke();
				executionCount++;
				if (_managedCoroutines.TryGetValue(id, out var managedCoroutine))
				{
					managedCoroutine.ExecutionCount = executionCount;
				}
				managedCoroutine = null;
			}
		}

		private static IEnumerator RandomIntervalCoroutineWithCancelAndMax(Action<Action> action, float minDelay, float maxDelay, int maxExecutions, CoroutineId id)
		{
			bool shouldCancel = false;
			Action cancelAction = delegate
			{
				shouldCancel = true;
			};
			int executionCount = 0;
			while (!shouldCancel && (maxExecutions < 0 || executionCount < maxExecutions))
			{
				float delay = Random.Range(minDelay, maxDelay);
				yield return (object)new WaitForSeconds(delay);
				if (!shouldCancel)
				{
					action?.Invoke(cancelAction);
					executionCount++;
					if (_managedCoroutines.TryGetValue(id, out var managedCoroutine))
					{
						managedCoroutine.ExecutionCount = executionCount;
					}
					managedCoroutine = null;
				}
			}
		}

		public static CoroutineId NextFrame(Action action, string name = null)
		{
			return StartManagedCoroutine(NextFrameCoroutine(action), name);
		}

		private static IEnumerator NextFrameCoroutine(Action action)
		{
			yield return null;
			action?.Invoke();
		}

		public static bool StopCoroutine(CoroutineId id)
		{
			if (_managedCoroutines.TryGetValue(id, out var value))
			{
				if (value.Coroutine != null && (Object)(object)_coroutineManager != (Object)null)
				{
					((MonoBehaviour)_coroutineManager).StopCoroutine(value.Coroutine);
				}
				value.OnComplete?.Invoke();
				return _managedCoroutines.Remove(id);
			}
			return false;
		}

		public static void PauseCoroutine(CoroutineId id)
		{
			if (_managedCoroutines.TryGetValue(id, out var value))
			{
				value.IsPaused = true;
				value.PausedAt = DateTime.UtcNow;
			}
		}

		public static void ResumeCoroutine(CoroutineId id)
		{
			if (_managedCoroutines.TryGetValue(id, out var value))
			{
				value.IsPaused = false;
				value.PausedAt = null;
			}
		}

		public static void StopAllCoroutines()
		{
			if ((Object)(object)_coroutineManager != (Object)null)
			{
				((MonoBehaviour)_coroutineManager).StopAllCoroutines();
			}
			foreach (ManagedCoroutine value in _managedCoroutines.Values)
			{
				value.OnComplete?.Invoke();
			}
			_managedCoroutines.Clear();
		}

		public static bool IsCoroutineRunning(CoroutineId id)
		{
			return _managedCoroutines.ContainsKey(id) && _managedCoroutines[id].IsActive;
		}

		public static string[] GetActiveCoroutineNames()
		{
			string[] array = new string[_managedCoroutines.Count];
			int num = 0;
			foreach (ManagedCoroutine value in _managedCoroutines.Values)
			{
				array[num++] = value.Name;
			}
			return array;
		}

		public static int GetExecutionCount(CoroutineId id)
		{
			ManagedCoroutine value;
			return _managedCoroutines.TryGetValue(id, out value) ? value.ExecutionCount : 0;
		}

		public static int GetMaxExecutions(CoroutineId id)
		{
			ManagedCoroutine value;
			return _managedCoroutines.TryGetValue(id, out value) ? value.MaxExecutions : (-1);
		}

		public static int GetRemainingExecutions(CoroutineId id)
		{
			if (_managedCoroutines.TryGetValue(id, out var value))
			{
				if (value.MaxExecutions <= 0)
				{
					return -1;
				}
				return Math.Max(0, value.MaxExecutions - value.ExecutionCount);
			}
			return -1;
		}

		public static int CleanupCompletedCoroutines()
		{
			List<CoroutineId> list = new List<CoroutineId>();
			int num = 0;
			foreach (KeyValuePair<CoroutineId, ManagedCoroutine> managedCoroutine in _managedCoroutines)
			{
				CoroutineId key = managedCoroutine.Key;
				ManagedCoroutine value = managedCoroutine.Value;
				bool flag = false;
				if (value.Coroutine == null)
				{
					flag = true;
				}
				else if (value.MaxExecutions > 0 && value.ExecutionCount >= value.MaxExecutions)
				{
					flag = true;
				}
				else if ((Object)(object)_coroutineManager == (Object)null && (Object)(object)_gameObject == (Object)null)
				{
					flag = true;
				}
				if (flag)
				{
					list.Add(key);
				}
			}
			foreach (CoroutineId item in list)
			{
				if (_managedCoroutines.TryGetValue(item, out var value2))
				{
					try
					{
						value2.OnComplete?.Invoke();
					}
					catch (Exception ex)
					{
						Log.Error("Error invoking OnComplete for coroutine " + value2.Name + ": " + ex.Message);
					}
					if (_managedCoroutines.Remove(item))
					{
						num++;
					}
				}
			}
			return num;
		}

		public static CoroutineId EnableAutoCleanup(float intervalSeconds = 30f)
		{
			lock (_autoCleanupLock)
			{
				if (_autoCleanupEnabled && _autoCleanupId.HasValue)
				{
					StopCoroutine(_autoCleanupId.Value);
					_autoCleanupEnabled = false;
					_autoCleanupId = null;
				}
				_autoCleanupId = StartRepeating((Action)delegate
				{
					int num = CleanupCompletedCoroutines();
					if (num > 0)
					{
						Log.Info($"Auto-cleanup removed {num} completed coroutines");
					}
				}, intervalSeconds, "AutoCleanup", -1);
				_autoCleanupEnabled = true;
				return _autoCleanupId.Value;
			}
		}

		public static void DisableAutoCleanup()
		{
			lock (_autoCleanupLock)
			{
				if (_autoCleanupEnabled && _autoCleanupId.HasValue)
				{
					StopCoroutine(_autoCleanupId.Value);
					_autoCleanupEnabled = false;
					_autoCleanupId = null;
				}
			}
		}

		public static Dictionary<string, object> GetCoroutineStatistics()
		{
			Dictionary<string, object> dictionary = new Dictionary<string, object>();
			int num = 0;
			int num2 = 0;
			int num3 = 0;
			int num4 = 0;
			int num5 = 0;
			foreach (ManagedCoroutine value in _managedCoroutines.Values)
			{
				if (value.IsActive)
				{
					num++;
				}
				else
				{
					num2++;
				}
				if (value.MaxExecutions < 0)
				{
					num3++;
				}
				else
				{
					num4++;
				}
				num5 += value.ExecutionCount;
			}
			dictionary["TotalCoroutines"] = _managedCoroutines.Count;
			dictionary["ActiveCoroutines"] = num;
			dictionary["InactiveCoroutines"] = num2;
			dictionary["InfiniteCoroutines"] = num3;
			dictionary["LimitedCoroutines"] = num4;
			dictionary["TotalExecutions"] = num5;
			dictionary["AutoCleanupEnabled"] = _autoCleanupEnabled;
			return dictionary;
		}

		public static int ForceCleanup(bool onlyInactive = false, bool onlyCompleted = true)
		{
			List<CoroutineId> list = new List<CoroutineId>();
			int num = 0;
			foreach (KeyValuePair<CoroutineId, ManagedCoroutine> managedCoroutine in _managedCoroutines)
			{
				CoroutineId key = managedCoroutine.Key;
				ManagedCoroutine value = managedCoroutine.Value;
				bool flag = false;
				if (onlyInactive && !value.IsActive)
				{
					flag = true;
				}
				else if (onlyCompleted && value.MaxExecutions > 0 && value.ExecutionCount >= value.MaxExecutions)
				{
					flag = true;
				}
				else if (!onlyInactive && !onlyCompleted)
				{
					flag = true;
				}
				if (flag)
				{
					list.Add(key);
				}
			}
			foreach (CoroutineId item in list)
			{
				if (StopCoroutine(item))
				{
					num++;
				}
			}
			return num;
		}

		public static bool IsCoroutinePaused(CoroutineId id)
		{
			ManagedCoroutine value;
			return _managedCoroutines.TryGetValue(id, out value) && value.IsPaused;
		}

		public static TimeSpan? GetPauseDuration(CoroutineId id)
		{
			if (_managedCoroutines.TryGetValue(id, out var value) && value.IsPaused && value.PausedAt.HasValue)
			{
				return DateTime.UtcNow - value.PausedAt.Value;
			}
			return null;
		}

		public static bool TogglePauseCoroutine(CoroutineId id