Decompiled source of BaseqsEnemies v0.2.0

plugins/MuckBaseqsEnemies.dll

Decompiled a day ago
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Globalization;
using System.IO;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Text;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using HarmonyLib;
using Microsoft.CodeAnalysis;
using UnityEngine;
using UnityEngine.AI;
using UnityEngine.Rendering;
using UnityEngine.SceneManagement;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETStandard,Version=v2.0", FrameworkDisplayName = ".NET Standard 2.0")]
[assembly: AssemblyCompany("MuckBaseqsEnemies")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyDescription("New Muck enemies. The first is The Bear, a neutral daytime mini-boss.")]
[assembly: AssemblyFileVersion("0.2.0.0")]
[assembly: AssemblyInformationalVersion("0.2.0+5caa96df932c509d2f99e20681f4a02fa2d68991")]
[assembly: AssemblyProduct("Baseq's Enemies")]
[assembly: AssemblyTitle("MuckBaseqsEnemies")]
[assembly: InternalsVisibleTo("MuckBaseqsEnemies.Tests")]
[assembly: AssemblyVersion("0.2.0.0")]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[Embedded]
	internal sealed class IsReadOnlyAttribute : Attribute
	{
	}
}
namespace MuckBaseqsEnemies
{
	[BepInPlugin("evan.muck.baseqsenemies", "Baseq's Enemies", "0.2.0")]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	public class BaseqsPlugin : BaseUnityPlugin
	{
		public const string Guid = "evan.muck.baseqsenemies";

		internal static ManualLogSource Log;

		internal static BearConfig Cfg;

		private static readonly HashSet<string> Logged = new HashSet<string>();

		private void Awake()
		{
			//IL_0020: Unknown result type (might be due to invalid IL or missing references)
			//IL_0026: Expected O, but got Unknown
			Log = ((BaseUnityPlugin)this).Logger;
			Cfg = new BearConfig(((BaseUnityPlugin)this).Config);
			Harmony val = new Harmony("evan.muck.baseqsenemies");
			Type[] array = new Type[9]
			{
				typeof(SpawnMobAdoptPatch),
				typeof(BearStartPatch),
				typeof(BearHitPatch),
				typeof(BearLootPatch),
				typeof(ChatBoxAppendPatch),
				typeof(BearMoveLockPatch),
				typeof(BearJumpLockPatch),
				typeof(BearUseLockPatch),
				typeof(BearHitboxLockPatch)
			};
			for (int i = 0; i < array.Length; i++)
			{
				if (!TryPatch(val, array[i]))
				{
					val.UnpatchSelf();
					Log.LogError((object)("Baseq's Enemies: " + array[i].Name + " failed. Mod disabled."));
					return;
				}
			}
			BearRunner.Ensure();
			Log.LogInfo((object)"Baseq's Enemies 0.2.0 loaded. The host spawns The Bear. Every player should install it.");
		}

		private static bool TryPatch(Harmony harmony, Type type)
		{
			try
			{
				harmony.CreateClassProcessor(type).Patch();
				return true;
			}
			catch (Exception ex)
			{
				Log.LogError((object)("Baseq's Enemies patch " + type.Name + " failed: " + ex));
				return false;
			}
		}

		internal static void LogOnce(string key, string message)
		{
			if (Log != null)
			{
				bool flag = Cfg != null && Cfg.VerboseLogging.Value;
				if (Logged.Add(key) || flag)
				{
					Log.LogWarning((object)message);
				}
			}
		}
	}
	internal sealed class BearConfig
	{
		public readonly ConfigEntry<bool> Enabled;

		public readonly ConfigEntry<float> DayChance;

		public readonly ConfigEntry<float> NightChance;

		public readonly ConfigEntry<float> CheckSeconds;

		public readonly ConfigEntry<int> MaxAliveDay;

		public readonly ConfigEntry<int> MaxAliveNight;

		public readonly ConfigEntry<int> FirstDay;

		public readonly ConfigEntry<float> MinDistance;

		public readonly ConfigEntry<float> MaxDistance;

		public readonly ConfigEntry<int> ClawDamage;

		public readonly ConfigEntry<int> BiteDamage;

		public readonly ConfigEntry<int> LeapDamage;

		public readonly ConfigEntry<int> GoldMin;

		public readonly ConfigEntry<int> GoldMax;

		public readonly ConfigEntry<int> ThrashBase;

		public readonly ConfigEntry<int> ThrashPerDay;

		public readonly ConfigEntry<int> ThrashCap;

		public readonly ConfigEntry<float> FleeSpeed;

		public readonly ConfigEntry<bool> SpawnDuringWaveRun;

		public readonly ConfigEntry<bool> VerboseLogging;

		public readonly ConfigEntry<bool> SpawnHotkey;

		public BearConfig(ConfigFile cfg)
		{
			//IL_004c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0056: Expected O, but got Unknown
			//IL_0085: Unknown result type (might be due to invalid IL or missing references)
			//IL_008f: Expected O, but got Unknown
			//IL_00be: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c8: Expected O, but got Unknown
			//IL_00eb: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f5: Expected O, but got Unknown
			//IL_0118: Unknown result type (might be due to invalid IL or missing references)
			//IL_0122: Expected O, but got Unknown
			//IL_0293: Unknown result type (might be due to invalid IL or missing references)
			//IL_029d: Expected O, but got Unknown
			Enabled = cfg.Bind<bool>("Bear", "Enabled", true, "Spawn The Bear. Default on: installing the mod is the opt-in. Host only. A client with this off still shows a bear the host spawned.");
			DayChance = cfg.Bind<float>("Bear", "DayChance", 0.35f, new ConfigDescription("Chance per check, while DayCycle.time is under 0.5, to spawn one bear if the day cap is not full. Host only.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 1f), Array.Empty<object>()));
			NightChance = cfg.Bind<float>("Bear", "NightChance", 0.08f, new ConfigDescription("Chance per check at night. Lower than day, so a night bear is rare. Host only.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 1f), Array.Empty<object>()));
			CheckSeconds = cfg.Bind<float>("Bear", "CheckSeconds", 20f, new ConfigDescription("Seconds between spawn checks. Host only.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(5f, 120f), Array.Empty<object>()));
			MaxAliveDay = cfg.Bind<int>("Bear", "MaxAliveDay", 2, new ConfigDescription("Cap on living bears during the day. Host only.", (AcceptableValueBase)(object)new AcceptableValueRange<int>(0, 6), Array.Empty<object>()));
			MaxAliveNight = cfg.Bind<int>("Bear", "MaxAliveNight", 1, new ConfigDescription("Cap on living bears at night. Host only.", (AcceptableValueBase)(object)new AcceptableValueRange<int>(0, 4), Array.Empty<object>()));
			FirstDay = cfg.Bind<int>("Bear", "SpawnFromDay", 1, "Earliest GameLoop.currentDay that can spawn a bear, inclusive. The clock starts at -1, so 1 is the second morning. Host only.");
			MinDistance = cfg.Bind<float>("Bear", "MinDistance", 48f, "Closest a natural spawn may be to the player it anchored on, in metres. Host only.");
			MaxDistance = cfg.Bind<float>("Bear", "MaxDistance", 84f, "Farthest a natural spawn may be from that player, in metres. Host only.");
			ClawDamage = cfg.Bind<int>("Bear", "ClawDamage", 18, "Damage of the close swipe, before Muck's mob-damage multiplier. Day 0 multiplies by about 0.9, so 18 lands near 16. The host writes the base into the sync line.");
			BiteDamage = cfg.Bind<int>("Bear", "BiteDamage", 12, "Damage of one bite while grabbed, before the mob-damage multiplier. Day 0 lands near 10. One bite a second. Host writes the base into the sync line.");
			LeapDamage = cfg.Bind<int>("Bear", "LeapDamage", 34, "Damage of the leap landing, before the mob-damage multiplier. Day 0 lands near 30. Host writes the base into the sync line.");
			GoldMin = cfg.Bind<int>("Bear", "GoldMin", 48, "Minimum coins in the death drop. Host only.");
			GoldMax = cfg.Bind<int>("Bear", "GoldMax", 72, "Maximum coins in the death drop. Host only.");
			ThrashBase = cfg.Bind<int>("Bear", "ThrashBase", 6, "Movement-key taps to break the grab on day 0. Host decides. Synced only by the host releasing the grab.");
			ThrashPerDay = cfg.Bind<int>("Bear", "ThrashPerDay", 2, "Extra taps added for each GameLoop.currentDay.");
			ThrashCap = cfg.Bind<int>("Bear", "ThrashCap", 28, "Upper bound on taps, so a late day stays a mash and not a lock.");
			FleeSpeed = cfg.Bind<float>("Bear", "FleeSpeed", 20f, new ConfigDescription("Metres per second the wolf agent runs while carrying a grabbed player. The charge is 16. Host only.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(8f, 28f), Array.Empty<object>()));
			SpawnDuringWaveRun = cfg.Bind<bool>("Bear", "SpawnDuringWaveRun", false, "Wave Run pins the clock inside the day and owns spawning. Off, the bear does not spawn during a Wave Run. On, it uses the day chance the whole run. Host only.");
			VerboseLogging = cfg.Bind<bool>("Debug", "VerboseLogging", false, "Log each spawn and each attack pick. Not gameplay.");
			SpawnHotkey = cfg.Bind<bool>("Debug", "SpawnHotkey", false, "Host only. F10 spawns a bear on dry navmesh near you, ignoring the day roll and the caps. F6 to F9 belong to RoR2 Enemies. For playtests.");
		}
	}
	internal struct Vec3
	{
		public float X;

		public float Y;

		public float Z;

		public Vec3(float x, float y, float z)
		{
			X = x;
			Y = y;
			Z = z;
		}
	}
	internal sealed class BearMaterial
	{
		public float R;

		public float G;

		public float B;

		public float Emission;

		public bool Glows => Emission > 0f;
	}
	internal sealed class BearPartMesh
	{
		public string Object;

		public string Group;

		public string Material;

		public Vec3 Pivot;

		public Vec3[] Positions;

		public Vec3[] Normals;

		public int Triangles;
	}
	internal sealed class BearModel
	{
		public BearPartMesh[] Parts;

		public Dictionary<string, BearMaterial> Materials;

		public float Height;

		public float PlayerHeight;

		public int Triangles;
	}
	internal static class BearArt
	{
		private sealed class RawPart
		{
			public List<Vec3> Positions = new List<Vec3>();

			public List<Vec3> Normals = new List<Vec3>();
		}

		public const string ObjResource = "MuckBaseqsEnemies.art.bear.obj";

		public const string PartsResource = "MuckBaseqsEnemies.art.bear.parts.json";

		public const int TriangleBudget = 2000;

		public static BearModel Load(string objText, string jsonText, out string error)
		{
			error = null;
			try
			{
				Dictionary<string, RawPart> dictionary = ParseObj(objText);
				Dictionary<string, object> dictionary2 = (Dictionary<string, object>)JsonReader.Parse(jsonText);
				List<object> list = (List<object>)dictionary2["parts"];
				Dictionary<string, object> obj = (Dictionary<string, object>)dictionary2["materials"];
				Dictionary<string, BearMaterial> dictionary3 = new Dictionary<string, BearMaterial>();
				foreach (KeyValuePair<string, object> item in obj)
				{
					Dictionary<string, object> dictionary4 = (Dictionary<string, object>)item.Value;
					List<object> list2 = (List<object>)dictionary4["rgb"];
					dictionary3[item.Key] = new BearMaterial
					{
						R = (float)(double)list2[0],
						G = (float)(double)list2[1],
						B = (float)(double)list2[2],
						Emission = (float)(double)dictionary4["emission"]
					};
				}
				List<BearPartMesh> list3 = new List<BearPartMesh>();
				float num = float.MaxValue;
				float num2 = float.MinValue;
				int num3 = 0;
				for (int i = 0; i < list.Count; i++)
				{
					Dictionary<string, object> dictionary5 = (Dictionary<string, object>)list[i];
					string text = (string)dictionary5["object"];
					if (!dictionary.TryGetValue(text, out var value))
					{
						error = "OBJ has no object " + text;
						return null;
					}
					List<object> list4 = (List<object>)dictionary5["pivot_unity"];
					Vec3 pivot = new Vec3((float)(double)list4[0], (float)(double)list4[1], (float)(double)list4[2]);
					Vec3[] array = new Vec3[value.Positions.Count];
					for (int j = 0; j < array.Length; j++)
					{
						array[j] = new Vec3(value.Positions[j].X - pivot.X, value.Positions[j].Y - pivot.Y, value.Positions[j].Z - pivot.Z);
						float y = value.Positions[j].Y;
						if (y < num)
						{
							num = y;
						}
						if (y > num2)
						{
							num2 = y;
						}
					}
					string text2 = (string)dictionary5["material"];
					if (!dictionary3.ContainsKey(text2))
					{
						error = "missing material " + text2;
						return null;
					}
					int num4 = array.Length / 3;
					num3 += num4;
					list3.Add(new BearPartMesh
					{
						Object = text,
						Group = (string)dictionary5["group"],
						Material = text2,
						Pivot = pivot,
						Positions = array,
						Normals = value.Normals.ToArray(),
						Triangles = num4
					});
				}
				float playerHeight = (dictionary2.ContainsKey("player_height") ? ((float)(double)dictionary2["player_height"]) : 3.816f);
				return new BearModel
				{
					Parts = list3.ToArray(),
					Materials = dictionary3,
					Height = num2 - num,
					PlayerHeight = playerHeight,
					Triangles = num3
				};
			}
			catch (Exception ex)
			{
				error = ex.Message;
				return null;
			}
		}

		public static string ReadEmbedded(string name)
		{
			using Stream stream = typeof(BearArt).Assembly.GetManifestResourceStream(name);
			if (stream == null)
			{
				throw new FileNotFoundException("Embedded resource missing.", name);
			}
			using StreamReader streamReader = new StreamReader(stream);
			return streamReader.ReadToEnd();
		}

		private static Dictionary<string, RawPart> ParseObj(string text)
		{
			List<Vec3> list = new List<Vec3>();
			List<Vec3> list2 = new List<Vec3>();
			Dictionary<string, RawPart> dictionary = new Dictionary<string, RawPart>();
			RawPart rawPart = null;
			if (text == null)
			{
				throw new FormatException("OBJ is null.");
			}
			int num = 0;
			while (num < text.Length)
			{
				int num2 = text.IndexOf('\n', num);
				if (num2 < 0)
				{
					num2 = text.Length;
				}
				string text2 = text.Substring(num, num2 - num).Trim();
				num = num2 + 1;
				if (text2.Length == 0 || text2[0] == '#')
				{
					continue;
				}
				if (text2.StartsWith("o ", StringComparison.Ordinal))
				{
					rawPart = new RawPart();
					dictionary[text2.Substring(2).Trim()] = rawPart;
				}
				else if (text2.StartsWith("v ", StringComparison.Ordinal))
				{
					list.Add(Triple(text2));
				}
				else if (text2.StartsWith("vn ", StringComparison.Ordinal))
				{
					list2.Add(Triple(text2));
				}
				else
				{
					if (!text2.StartsWith("f ", StringComparison.Ordinal) || rawPart == null)
					{
						continue;
					}
					string[] array = text2.Split(new char[1] { ' ' }, StringSplitOptions.RemoveEmptyEntries);
					if (array.Length != 4)
					{
						throw new FormatException("face is not a triangle: " + text2);
					}
					for (int i = 1; i < 4; i++)
					{
						string[] array2 = array[i].Split(new char[1] { '/' });
						int num3 = int.Parse(array2[0], CultureInfo.InvariantCulture);
						if (num3 < 0)
						{
							num3 = list.Count + 1 + num3;
						}
						Vec3 item = list[num3 - 1];
						Vec3 item2 = new Vec3(0f, 1f, 0f);
						if (array2.Length >= 3 && array2[2].Length > 0)
						{
							int num4 = int.Parse(array2[2], CultureInfo.InvariantCulture);
							if (num4 < 0)
							{
								num4 = list2.Count + 1 + num4;
							}
							if (num4 >= 1 && num4 <= list2.Count)
							{
								item2 = list2[num4 - 1];
							}
						}
						rawPart.Positions.Add(item);
						rawPart.Normals.Add(item2);
					}
				}
			}
			return dictionary;
		}

		private static Vec3 Triple(string line)
		{
			string[] array = line.Split(new char[1] { ' ' }, StringSplitOptions.RemoveEmptyEntries);
			return new Vec3(float.Parse(array[1], CultureInfo.InvariantCulture), float.Parse(array[2], CultureInfo.InvariantCulture), float.Parse(array[3], CultureInfo.InvariantCulture));
		}
	}
	internal enum BearPhase
	{
		Calm,
		Roar,
		Pick,
		ChargeTell,
		Charge,
		Grab,
		LeapTell,
		Leap,
		LeapImpact,
		ClawWindup,
		Claw,
		ClawLag
	}
	internal struct BearMemory
	{
		public BearPhase Phase;

		public bool Aggro;

		public float PhaseUntil;

		public float ChargeReadyAt;

		public float LeapReadyAt;

		public float ClawReadyAt;

		public float NextRoarAt;

		public float NextBiteAt;

		public int BiteSeq;

		public int ClawSeq;

		public int LeapSeq;

		public int GrabId;

		public int RegrabId;

		public float RegrabUntil;

		public float LaneX;

		public float LaneY;

		public float LaneZ;

		public float LaneDx;

		public float LaneDz;

		public float LandX;

		public float LandY;

		public float LandZ;

		public float WanderX;

		public float WanderZ;

		public float WanderUntil;

		public static BearMemory Fresh()
		{
			return new BearMemory
			{
				Phase = BearPhase.Calm,
				GrabId = -1,
				RegrabId = -1
			};
		}
	}
	internal readonly struct BearSense
	{
		public readonly float Now;

		public readonly float Distance;

		public readonly bool HasTarget;

		public readonly int Taps;

		public readonly int TapsNeeded;

		public readonly bool GrabbedAlive;

		public BearSense(float now, float distance, bool hasTarget, int taps, int tapsNeeded, bool grabbedAlive)
		{
			Now = now;
			Distance = distance;
			HasTarget = hasTarget;
			Taps = taps;
			TapsNeeded = tapsNeeded;
			GrabbedAlive = grabbedAlive;
		}
	}
	internal static class BearBrain
	{
		public const float OpeningRoar = 1.2f;

		public const float RepeatRoar = 0.7f;

		public const float RoarInterval = 3.5f;

		public const float ChargeTell = 1.15f;

		public const float ChargeSpeed = 16f;

		public const float ChargeMin = 8f;

		public const float ChargeMax = 22f;

		public const float ChargeCooldown = 8f;

		public const float LeapTell = 0.9f;

		public const float LeapAir = 0.75f;

		public const float LeapImpact = 0.2f;

		public const float LeapMin = 6f;

		public const float LeapMax = 16f;

		public const float LeapCooldown = 7f;

		public const float ClawRange = 4.5f;

		public const float ClawWindup = 0.4f;

		public const float ClawActive = 0.22f;

		public const float ClawLag = 1.15f;

		public const float ClawCooldown = 2.4f;

		public const float BiteInterval = 1f;

		public const float GrabMax = 12f;

		public const float RegrabDelay = 1.25f;

		public const float WalkSpeed = 5.5f;

		public const float FleeSpeed = 20f;

		public const float FleeHold = 0f;

		public const float LeapHeight = 2.4f;

		public const float WanderPause = 5f;

		public static float ChargeDuration => 0.875f;

		public static float FleePace(float configured)
		{
			if (configured < 8f)
			{
				return 8f;
			}
			if (configured > 28f)
			{
				return 28f;
			}
			return configured;
		}

		public static void FleeDirection(float forwardX, float forwardZ, float awayX, float awayZ, int others, out float dx, out float dz)
		{
			float x = ((others > 0) ? awayX : forwardX);
			float z = ((others > 0) ? awayZ : forwardZ);
			if (!Unit(x, z, out dx, out dz) && !Unit(forwardX, forwardZ, out dx, out dz))
			{
				dx = 0f;
				dz = 1f;
			}
		}

		public static void FleeAdvance(float x, float z, float dx, float dz, float pace, float dt, out float nx, out float nz)
		{
			if (dt < 0f)
			{
				dt = 0f;
			}
			if (pace < 0f)
			{
				pace = 0f;
			}
			nx = x + dx * pace * dt;
			nz = z + dz * pace * dt;
		}

		private static bool Unit(float x, float z, out float dx, out float dz)
		{
			float num = (float)Math.Sqrt(x * x + z * z);
			if (num < 0.0001f)
			{
				dx = 0f;
				dz = 0f;
				return false;
			}
			dx = x / num;
			dz = z / num;
			return true;
		}

		public static bool NeedsWander(in BearMemory m, float now)
		{
			if (!m.Aggro)
			{
				return now >= m.WanderUntil;
			}
			return false;
		}

		public static void SetWander(ref BearMemory m, float now, float x, float z)
		{
			m.WanderX = x;
			m.WanderZ = z;
			m.WanderUntil = now + 5f;
		}

		public static void Aggro(ref BearMemory m, float now)
		{
			if (!m.Aggro)
			{
				m.Aggro = true;
				m.Phase = BearPhase.Roar;
				m.PhaseUntil = now + 1.2f;
				m.NextRoarAt = now + 3.5f;
				m.ClawReadyAt = now + 1.2f;
				m.ChargeReadyAt = now + 1.2f;
				m.LeapReadyAt = now + 1.2f + 1.5f;
				m.GrabId = -1;
			}
		}

		public static bool CanGrab(in BearMemory m, int playerId, float now)
		{
			if (playerId < 0)
			{
				return false;
			}
			if (m.Phase != BearPhase.Charge)
			{
				return false;
			}
			if (m.GrabId >= 0)
			{
				return false;
			}
			if (playerId == m.RegrabId && now < m.RegrabUntil)
			{
				return false;
			}
			return true;
		}

		public static void BeginGrab(ref BearMemory m, int playerId, float now)
		{
			m.Phase = BearPhase.Grab;
			m.GrabId = playerId;
			m.PhaseUntil = now + 12f;
			m.NextBiteAt = now + 1f;
			m.ChargeReadyAt = now + 8f;
		}

		public static void Tick(ref BearMemory m, in BearSense s)
		{
			if (!m.Aggro)
			{
				m.Phase = BearPhase.Calm;
				m.GrabId = -1;
				return;
			}
			if (m.Phase == BearPhase.Grab && (s.Taps >= s.TapsNeeded || !s.GrabbedAlive || s.Now >= m.PhaseUntil))
			{
				Release(ref m, s.Now);
				return;
			}
			if (m.Phase != BearPhase.Pick && m.Phase != BearPhase.Calm && s.Now < m.PhaseUntil)
			{
				if (m.Phase == BearPhase.Grab && s.GrabbedAlive && s.Now >= m.NextBiteAt)
				{
					m.BiteSeq++;
					m.NextBiteAt = s.Now + 1f;
				}
				return;
			}
			switch (m.Phase)
			{
			case BearPhase.Roar:
			case BearPhase.ClawLag:
				m.Phase = BearPhase.Pick;
				break;
			case BearPhase.ChargeTell:
				m.Phase = BearPhase.Charge;
				m.PhaseUntil = s.Now + ChargeDuration;
				return;
			case BearPhase.Charge:
				m.ChargeReadyAt = s.Now + 8f;
				m.Phase = BearPhase.Pick;
				break;
			case BearPhase.LeapTell:
				m.Phase = BearPhase.Leap;
				m.PhaseUntil = s.Now + 0.75f;
				return;
			case BearPhase.Leap:
				m.Phase = BearPhase.LeapImpact;
				m.PhaseUntil = s.Now + 0.2f;
				m.LeapSeq++;
				return;
			case BearPhase.LeapImpact:
				m.LeapReadyAt = s.Now + 7f;
				m.Phase = BearPhase.Pick;
				break;
			case BearPhase.ClawWindup:
				m.Phase = BearPhase.Claw;
				m.PhaseUntil = s.Now + 0.22f;
				m.ClawSeq++;
				return;
			case BearPhase.Claw:
				m.Phase = BearPhase.ClawLag;
				m.PhaseUntil = s.Now + 1.15f;
				m.ClawReadyAt = s.Now + 1.15f + 2.4f;
				return;
			case BearPhase.Grab:
				Release(ref m, s.Now);
				return;
			}
			if (m.Phase == BearPhase.Pick)
			{
				Pick(ref m, in s);
			}
		}

		private static void Pick(ref BearMemory m, in BearSense s)
		{
			if (s.Now >= m.NextRoarAt)
			{
				m.Phase = BearPhase.Roar;
				m.PhaseUntil = s.Now + 0.7f;
				m.NextRoarAt = s.Now + 3.5f;
			}
			else if (s.HasTarget)
			{
				if (s.Distance <= 4.5f && s.Now >= m.ClawReadyAt)
				{
					m.Phase = BearPhase.ClawWindup;
					m.PhaseUntil = s.Now + 0.4f;
				}
				else if (s.Distance >= 6f && s.Distance <= 16f && s.Now >= m.LeapReadyAt)
				{
					m.Phase = BearPhase.LeapTell;
					m.PhaseUntil = s.Now + 0.9f;
				}
				else if (s.Distance >= 8f && s.Distance <= 22f && s.Now >= m.ChargeReadyAt)
				{
					m.Phase = BearPhase.ChargeTell;
					m.PhaseUntil = s.Now + 1.15f;
				}
			}
		}

		private static void Release(ref BearMemory m, float now)
		{
			m.RegrabId = m.GrabId;
			m.RegrabUntil = now + 1.25f;
			m.GrabId = -1;
			m.Phase = BearPhase.Roar;
			m.PhaseUntil = now + 0.7f;
			m.NextRoarAt = now + 3.5f;
		}
	}
	internal readonly struct Rgb
	{
		public readonly float R;

		public readonly float G;

		public readonly float B;

		public bool WashedOut
		{
			get
			{
				float num = ((R < G) ? R : G);
				if (B < num)
				{
					num = B;
				}
				float num2 = ((R > G) ? R : G);
				if (B > num2)
				{
					num2 = B;
				}
				return num2 - num <= 0.1f;
			}
		}

		public Rgb(float r, float g, float b)
		{
			R = r;
			G = g;
			B = b;
		}
	}
	internal static class BearEyes
	{
		public static readonly Rgb Calm = new Rgb(0.95f, 0.55f, 0.08f);

		public static readonly Rgb Angry = new Rgb(0.86f, 0.07f, 0.05f);

		public static Rgb For(bool aggro)
		{
			if (!aggro)
			{
				return Calm;
			}
			return Angry;
		}
	}
	internal static class BearHits
	{
		public const float LaneHalfWidth = 1.35f;

		public const float LaneLength = 14f;

		public const float NoseForward = 5.75f;

		public const float NoseUp = 5.05f;

		public const float ContactSkin = 0.4f;

		public const float BiteDepth = 1.15f;

		public const float SnapSkin = 0.75f;

		public const float SnapDepth = 2f;

		public const float MouthHalfWidth = 1.05f;

		public const float MouthReachDown = 9.5f;

		public const float MouthReachUp = 6f;

		public const float LeapRadius = 3.2f;

		public const float ClawRange = 4.6f;

		public const float ClawAngle = 75f;

		public const float VerticalSlack = 4f;

		public static bool InLane(float ox, float oy, float oz, float dx, float dz, float length, float halfWidth, float px, float py, float pz)
		{
			if (length <= 0f || halfWidth <= 0f)
			{
				return false;
			}
			if (Math.Abs(py - oy) > 4f)
			{
				return false;
			}
			float num = px - ox;
			float num2 = pz - oz;
			float num3 = num * dx + num2 * dz;
			if (num3 < -0.75f || num3 > length + 0.75f)
			{
				return false;
			}
			float num4 = num * dz - num2 * dx;
			return num4 * num4 <= halfWidth * halfWidth;
		}

		public static bool AtMouth(float mx, float my, float mz, float dx, float dz, float px, float py, float pz, bool catchingUp)
		{
			float num = (float)Math.Sqrt(dx * dx + dz * dz);
			if (num < 1E-06f)
			{
				dx = 0f;
				dz = 1f;
			}
			else
			{
				dx /= num;
				dz /= num;
			}
			float num2 = px - mx;
			float num3 = pz - mz;
			float num4 = num2 * dx + num3 * dz;
			float num5 = (catchingUp ? 0.75f : 0.4f);
			float num6 = (catchingUp ? 2f : 1.15f);
			if (num4 > num5 || num4 < 0f - num6)
			{
				return false;
			}
			float num7 = num2 * dz - num3 * dx;
			if (num7 * num7 > 1.1024998f)
			{
				return false;
			}
			if (py + 3.816f < my - 9.5f)
			{
				return false;
			}
			if (py > my + 6f)
			{
				return false;
			}
			return true;
		}

		public static bool InDisc(float x, float y, float z, float px, float py, float pz, float radius)
		{
			if (radius <= 0f)
			{
				return false;
			}
			if (Math.Abs(py - y) > 4f)
			{
				return false;
			}
			float num = px - x;
			float num2 = pz - z;
			return num * num + num2 * num2 <= radius * radius;
		}

		public static bool InSwipe(float ox, float oy, float oz, float fx, float fz, float px, float py, float pz, float range, float angleDeg)
		{
			if (range <= 0f)
			{
				return false;
			}
			if (Math.Abs(py - oy) > 4f)
			{
				return false;
			}
			float num = px - ox;
			float num2 = pz - oz;
			float num3 = num * num + num2 * num2;
			if (num3 > range * range || num3 < 1E-08f)
			{
				return false;
			}
			float num4 = (float)Math.Sqrt(num3);
			float num5 = (num * fx + num2 * fz) / num4;
			double num6 = Math.Cos((double)angleDeg * Math.PI / 180.0);
			return (double)num5 >= num6;
		}

		public static float ChargeHeight(float y, float sampleX, float sampleZ, float nextX, float nextZ, float sampleY, bool hit)
		{
			if (!hit)
			{
				return y;
			}
			float num = sampleX - nextX;
			float num2 = sampleZ - nextZ;
			if (num * num + num2 * num2 > 4f)
			{
				return y;
			}
			return sampleY;
		}

		public static void Flatten(float x, float z, out float dx, out float dz)
		{
			double num = Math.Sqrt(x * x + z * z);
			if (num < 1E-06)
			{
				dx = 0f;
				dz = 1f;
			}
			else
			{
				dx = (float)((double)x / num);
				dz = (float)((double)z / num);
			}
		}
	}
	internal static class BearMarker
	{
		public const float Tag = 0.001953125f;

		public const string BaseMob = "Wolf";

		public const double Tolerance = 0.001;

		public static float Encode(float healthOnGrid)
		{
			double num = healthOnGrid;
			if (num < 0.0625)
			{
				num = 0.0625;
			}
			return (float)(Math.Floor(num * 16.0) / 16.0 + 1.0 / 512.0);
		}

		public static bool IsBear(float bossMultiplier, string mobName)
		{
			if (!NameIsWolf(mobName))
			{
				return false;
			}
			double num = bossMultiplier;
			if (double.IsNaN(num) || double.IsInfinity(num) || num <= 0.0)
			{
				return false;
			}
			double num2 = Math.Floor(num * 16.0) / 16.0;
			double num3 = (num - num2) * 512.0;
			int num4 = (int)Math.Round(num3);
			if (Math.Abs(num3 - (double)num4) < 0.001)
			{
				return num4 == 1;
			}
			return false;
		}

		public static bool NameIsWolf(string mobName)
		{
			if (string.IsNullOrEmpty(mobName))
			{
				return false;
			}
			return string.Equals(mobName, "Wolf", StringComparison.OrdinalIgnoreCase);
		}

		public static bool OnSixteenthGrid(float bossMultiplier)
		{
			if (!(bossMultiplier > 0f) || float.IsInfinity(bossMultiplier))
			{
				return false;
			}
			double num = (double)bossMultiplier * 16.0;
			return Math.Abs(num - Math.Round(num)) <= 0.0016;
		}

		public static bool Ror2KindCode(float bossMultiplier)
		{
			double num = bossMultiplier;
			double num2 = Math.Floor(num * 16.0) / 16.0;
			double num3 = (num - num2) * 256.0;
			int num4 = (int)Math.Round(num3);
			if (Math.Abs(num3 - (double)num4) < 0.001 && num4 >= 1)
			{
				return num4 <= 15;
			}
			return false;
		}

		public static bool GlacialOddSixtyFourth(float bossMultiplier)
		{
			if (!(bossMultiplier > 0f) || float.IsInfinity(bossMultiplier))
			{
				return false;
			}
			double num = (double)bossMultiplier * 64.0;
			double num2 = Math.Round(num);
			if (Math.Abs(num - num2) > 0.0064)
			{
				return false;
			}
			return Math.Abs(num2 % 2.0) == 1.0;
		}
	}
	internal static class BearMash
	{
		public const string Prompt = "Mash to break free";

		public static bool Show(bool held, bool dead)
		{
			if (held)
			{
				return !dead;
			}
			return false;
		}

		public static float Fill(int taps, int need)
		{
			if (need < 1)
			{
				need = 1;
			}
			if (taps < 0)
			{
				taps = 0;
			}
			if (taps > need)
			{
				taps = need;
			}
			return (float)taps / (float)need;
		}

		public static string Count(int taps, int need)
		{
			if (need < 1)
			{
				need = 1;
			}
			if (taps < 0)
			{
				taps = 0;
			}
			if (taps > need)
			{
				taps = need;
			}
			return taps + " / " + need;
		}
	}
	internal enum BearBeat
	{
		Idle,
		Roar,
		Paw,
		Bite,
		ClawWindup,
		Claw,
		ClawLag,
		Charge,
		LeapTell,
		Leap,
		Maul
	}
	internal readonly struct PartMotion
	{
		public readonly float PitchDeg;

		public readonly float Lift;

		public readonly float YawDeg;

		public readonly float RollDeg;

		public bool IsStill
		{
			get
			{
				if (PitchDeg == 0f && Lift == 0f && YawDeg == 0f)
				{
					return RollDeg == 0f;
				}
				return false;
			}
		}

		public static PartMotion Still => new PartMotion(0f, 0f);

		public PartMotion(float pitchDeg, float lift, float yawDeg = 0f, float rollDeg = 0f)
		{
			PitchDeg = pitchDeg;
			Lift = lift;
			YawDeg = yawDeg;
			RollDeg = rollDeg;
		}
	}
	internal static class BearPose
	{
		public static BearBeat BeatFor(BearPhase phase)
		{
			return phase switch
			{
				BearPhase.Roar => BearBeat.Roar, 
				BearPhase.ChargeTell => BearBeat.Paw, 
				BearPhase.Charge => BearBeat.Charge, 
				BearPhase.Grab => BearBeat.Bite, 
				BearPhase.LeapTell => BearBeat.LeapTell, 
				BearPhase.Leap => BearBeat.Leap, 
				BearPhase.LeapImpact => BearBeat.Maul, 
				BearPhase.ClawWindup => BearBeat.ClawWindup, 
				BearPhase.Claw => BearBeat.Claw, 
				BearPhase.ClawLag => BearBeat.ClawLag, 
				_ => BearBeat.Idle, 
			};
		}

		public static string ParentGroup(string group)
		{
			switch (group)
			{
			case "neck":
			case "tail":
			case "leg_fl":
			case "leg_fr":
			case "leg_bl":
			case "leg_br":
				return "spine";
			case "head":
				return "neck";
			case "jaw":
				return "head";
			case "shin_fl":
				return "leg_fl";
			case "shin_fr":
				return "leg_fr";
			case "shin_bl":
				return "leg_bl";
			case "shin_br":
				return "leg_br";
			case "paw_fl":
				return "shin_fl";
			case "paw_fr":
				return "shin_fr";
			case "paw_bl":
				return "shin_bl";
			case "paw_br":
				return "shin_br";
			case "claw_fl":
				return "paw_fl";
			case "claw_fr":
				return "paw_fr";
			default:
				return null;
			}
		}

		public static PartMotion For(string group, BearBeat beat, float t, float cycle)
		{
			if (group == null)
			{
				return PartMotion.Still;
			}
			if (t < 0f)
			{
				t = 0f;
			}
			if (t > 1f)
			{
				t = 1f;
			}
			if (cycle < 0f)
			{
				cycle = 0f;
			}
			cycle -= (float)Math.Floor(cycle);
			return beat switch
			{
				BearBeat.Roar => Roar(group, t), 
				BearBeat.Paw => Paw(group, t), 
				BearBeat.Bite => Bite(group, cycle), 
				BearBeat.ClawWindup => ClawWind(group, t), 
				BearBeat.Claw => Claw(group, t), 
				BearBeat.ClawLag => ClawLag(group, t), 
				BearBeat.Charge => Run(group, cycle), 
				BearBeat.LeapTell => Crouch(group, t), 
				BearBeat.Leap => Leap(group, t), 
				BearBeat.Maul => Maul(group, t), 
				_ => PartMotion.Still, 
			};
		}

		private static PartMotion Roar(string group, float t)
		{
			switch (group)
			{
			case "jaw":
				return new PartMotion(34f * t, 0f);
			case "head":
				return new PartMotion(-16f * t, 0f);
			case "neck":
				return new PartMotion(-14f * t, 0f);
			case "spine":
				return new PartMotion(-6f * t, 0f);
			case "tail":
				return new PartMotion(14f * t, 0f);
			default:
				if (Front(group) && group.StartsWith("leg_", StringComparison.Ordinal))
				{
					return new PartMotion(-8f * t, 0f);
				}
				return PartMotion.Still;
			}
		}

		private static PartMotion Paw(string group, float t)
		{
			bool flag = t < 0.65f;
			float num = (flag ? (t / 0.65f) : ((t - 0.65f) / 0.35f));
			bool flag2 = Front(group);
			if (flag2 && group.StartsWith("leg_", StringComparison.Ordinal))
			{
				return new PartMotion(flag ? (-52f * num) : (-52f + 74f * num), 0f);
			}
			if (flag2 && group.StartsWith("shin_", StringComparison.Ordinal))
			{
				return new PartMotion(flag ? (28f * num) : (28f - 16f * num), 0f);
			}
			if (flag2 && group.StartsWith("paw_", StringComparison.Ordinal))
			{
				return new PartMotion(flag ? (-14f * num) : (-14f + 30f * num), flag ? (0.12f * num) : (0.12f * (1f - num)));
			}
			if (flag2 && group.StartsWith("claw_", StringComparison.Ordinal))
			{
				return new PartMotion(flag ? (-24f * num) : (-24f + 40f * num), 0f);
			}
			if (!flag2 && group.StartsWith("leg_", StringComparison.Ordinal))
			{
				return new PartMotion(flag ? (12f * num) : (12f * (1f - num)), 0f);
			}
			return group switch
			{
				"spine" => new PartMotion(flag ? (-10f * num) : (-10f + 28f * num), 0f), 
				"neck" => new PartMotion(-6f * (flag ? num : 1f), 0f), 
				"head" => new PartMotion(-12f, 0f), 
				"jaw" => new PartMotion(flag ? (18f * num) : 18f, 0f), 
				"tail" => new PartMotion(flag ? (6f * num) : (6f * (1f - num)), 0f), 
				_ => PartMotion.Still, 
			};
		}

		private static PartMotion Bite(string group, float cycle)
		{
			float num = (float)Math.Sin((double)cycle * Math.PI);
			switch (group)
			{
			case "jaw":
				return new PartMotion(8f + 28f * num, 0f);
			case "head":
				return new PartMotion(5f + 6f * num, 0f);
			case "neck":
				return new PartMotion(3f * num, 0f);
			default:
				if (group.StartsWith("claw_", StringComparison.Ordinal))
				{
					return new PartMotion(-12f, 0f);
				}
				return PartMotion.Still;
			}
		}

		private static PartMotion ClawWind(string group, float t)
		{
			if (Front(group) && group.StartsWith("leg_", StringComparison.Ordinal))
			{
				return new PartMotion(-56f * t, 0f);
			}
			if (Front(group) && group.StartsWith("shin_", StringComparison.Ordinal))
			{
				return new PartMotion(22f * t, 0f);
			}
			if (Front(group) && group.StartsWith("paw_", StringComparison.Ordinal))
			{
				return new PartMotion(-10f * t, 0f);
			}
			if (Front(group) && group.StartsWith("claw_", StringComparison.Ordinal))
			{
				return new PartMotion(-26f * t, 0f);
			}
			if (group == "spine")
			{
				return new PartMotion(-8f * t, 0f);
			}
			if (group == "head")
			{
				return new PartMotion(8f * t, 0f);
			}
			if (!Front(group) && group.StartsWith("leg_", StringComparison.Ordinal))
			{
				return new PartMotion(10f * t, 0f);
			}
			return PartMotion.Still;
		}

		private static PartMotion Claw(string group, float t)
		{
			if (Front(group) && group.StartsWith("leg_", StringComparison.Ordinal))
			{
				return new PartMotion(Lerp(-56f, 20f, t), 0f);
			}
			if (Front(group) && group.StartsWith("shin_", StringComparison.Ordinal))
			{
				return new PartMotion(Lerp(22f, 6f, t), 0f);
			}
			if (Front(group) && group.StartsWith("paw_", StringComparison.Ordinal))
			{
				return new PartMotion(Lerp(-10f, 12f, t), 0f);
			}
			if (Front(group) && group.StartsWith("claw_", StringComparison.Ordinal))
			{
				return new PartMotion(Lerp(-26f, 18f, t), 0f);
			}
			if (group == "spine")
			{
				return new PartMotion(Lerp(-8f, 12f, t), 0f);
			}
			if (group == "head")
			{
				return new PartMotion(Lerp(8f, 2f, t), 0f);
			}
			return PartMotion.Still;
		}

		private static PartMotion ClawLag(string group, float t)
		{
			if (Front(group) && group.StartsWith("leg_", StringComparison.Ordinal))
			{
				return new PartMotion(Lerp(20f, 0f, t), 0f);
			}
			if (Front(group) && group.StartsWith("claw_", StringComparison.Ordinal))
			{
				return new PartMotion(Lerp(18f, 0f, t), 0f);
			}
			if (group == "spine")
			{
				return new PartMotion(Lerp(12f, 0f, t), 0f);
			}
			return PartMotion.Still;
		}

		private static PartMotion Run(string group, float cycle)
		{
			float num = (float)Math.Sin((double)cycle * Math.PI * 2.0);
			bool num2 = Front(group);
			bool flag = group.EndsWith("l", StringComparison.Ordinal);
			float num3 = (num2 ? (-28f) : 24f) * (flag ? 1f : (-1f)) * num;
			if (group.StartsWith("leg_", StringComparison.Ordinal))
			{
				return new PartMotion(num3, 0f);
			}
			if (group.StartsWith("shin_", StringComparison.Ordinal))
			{
				return new PartMotion(18f + 0.35f * Math.Abs(num3), 0f);
			}
			if (group.StartsWith("paw_", StringComparison.Ordinal))
			{
				return new PartMotion(-0.3f * num3, 0f);
			}
			if (group.StartsWith("claw_", StringComparison.Ordinal))
			{
				return new PartMotion(-0.45f * num3, 0f);
			}
			return group switch
			{
				"spine" => new PartMotion(4f * num, 0.05f * Math.Abs(num)), 
				"tail" => new PartMotion(8f * num, 0f, 16f * num), 
				"neck" => new PartMotion(-4f, 0f), 
				"head" => new PartMotion(-3f, 0f), 
				_ => PartMotion.Still, 
			};
		}

		private static PartMotion Crouch(string group, float t)
		{
			if (group == "spine")
			{
				return new PartMotion(14f * t, 0f);
			}
			if (Front(group) && group.StartsWith("leg_", StringComparison.Ordinal))
			{
				return new PartMotion(16f * t, 0f);
			}
			if (Front(group) && group.StartsWith("shin_", StringComparison.Ordinal))
			{
				return new PartMotion(24f * t, 0f);
			}
			if (!Front(group) && group.StartsWith("leg_", StringComparison.Ordinal))
			{
				return new PartMotion(-10f * t, 0f);
			}
			if (group == "head")
			{
				return new PartMotion(-8f * t, 0f);
			}
			return PartMotion.Still;
		}

		private static PartMotion Leap(string group, float t)
		{
			if (group == "spine")
			{
				return new PartMotion(Lerp(14f, -24f, t), 0f);
			}
			if (Front(group) && group.StartsWith("leg_", StringComparison.Ordinal))
			{
				return new PartMotion(Lerp(16f, -50f, t), 0f);
			}
			if (Front(group) && group.StartsWith("shin_", StringComparison.Ordinal))
			{
				return new PartMotion(Lerp(24f, 8f, t), 0f);
			}
			if (!Front(group) && group.StartsWith("leg_", StringComparison.Ordinal))
			{
				return new PartMotion(Lerp(-10f, 36f, t), 0f);
			}
			if (!Front(group) && group.StartsWith("shin_", StringComparison.Ordinal))
			{
				return new PartMotion(18f * t, 0f);
			}
			return group switch
			{
				"tail" => new PartMotion(Lerp(0f, 20f, t), 0f), 
				"head" => new PartMotion(Lerp(-8f, -14f, t), 0f), 
				"jaw" => new PartMotion(10f * t, 0f), 
				_ => PartMotion.Still, 
			};
		}

		private static PartMotion Maul(string group, float t)
		{
			if (group == "spine")
			{
				return new PartMotion(Lerp(-24f, 20f, t), 0f);
			}
			if (Front(group) && group.StartsWith("leg_", StringComparison.Ordinal))
			{
				return new PartMotion(Lerp(-50f, 18f, t), 0f);
			}
			if (Front(group) && group.StartsWith("paw_", StringComparison.Ordinal))
			{
				return new PartMotion(16f * t, 0f);
			}
			if (Front(group) && group.StartsWith("claw_", StringComparison.Ordinal))
			{
				return new PartMotion(14f * t, 0f);
			}
			if (group == "jaw")
			{
				return new PartMotion(16f * t, 0f);
			}
			if (group == "head")
			{
				return new PartMotion(Lerp(-14f, 6f, t), 0f);
			}
			return PartMotion.Still;
		}

		private static bool Front(string group)
		{
			return group.IndexOf("_f", StringComparison.Ordinal) >= 0;
		}

		private static float Lerp(float a, float b, float t)
		{
			return a + (b - a) * t;
		}
	}
	internal static class BearPublish
	{
		public const float MotionHeartbeat = 2f;

		public const float IdleHeartbeat = 5f;

		public static float Heartbeat(BearPhase phase)
		{
			if ((uint)(phase - 3) <= 4u)
			{
				return 2f;
			}
			return 5f;
		}

		public static bool Due(bool changed, float sinceLast, BearPhase phase)
		{
			if (changed)
			{
				return true;
			}
			if (sinceLast < 0f)
			{
				sinceLast = 0f;
			}
			return sinceLast >= Heartbeat(phase);
		}
	}
	internal static class BearRig
	{
		internal struct Mat
		{
			public float M00;

			public float M01;

			public float M02;

			public float M10;

			public float M11;

			public float M12;

			public float M20;

			public float M21;

			public float M22;

			public static Mat Identity => new Mat
			{
				M00 = 1f,
				M11 = 1f,
				M22 = 1f
			};

			public Vec3 Mul(Vec3 v)
			{
				return new Vec3(M00 * v.X + M01 * v.Y + M02 * v.Z, M10 * v.X + M11 * v.Y + M12 * v.Z, M20 * v.X + M21 * v.Y + M22 * v.Z);
			}

			public Mat Mul(Mat b)
			{
				return new Mat
				{
					M00 = M00 * b.M00 + M01 * b.M10 + M02 * b.M20,
					M01 = M00 * b.M01 + M01 * b.M11 + M02 * b.M21,
					M02 = M00 * b.M02 + M01 * b.M12 + M02 * b.M22,
					M10 = M10 * b.M00 + M11 * b.M10 + M12 * b.M20,
					M11 = M10 * b.M01 + M11 * b.M11 + M12 * b.M21,
					M12 = M10 * b.M02 + M11 * b.M12 + M12 * b.M22,
					M20 = M20 * b.M00 + M21 * b.M10 + M22 * b.M20,
					M21 = M20 * b.M01 + M21 * b.M11 + M22 * b.M21,
					M22 = M20 * b.M02 + M21 * b.M12 + M22 * b.M22
				};
			}

			public static Mat Euler(float pitchDeg, float yawDeg, float rollDeg)
			{
				float num = Rad(pitchDeg);
				float num2 = Rad(yawDeg);
				float num3 = Rad(rollDeg);
				float num4 = (float)Math.Cos(num);
				float num5 = (float)Math.Sin(num);
				float num6 = (float)Math.Cos(num2);
				float num7 = (float)Math.Sin(num2);
				float num8 = (float)Math.Cos(num3);
				float num9 = (float)Math.Sin(num3);
				Mat b = new Mat
				{
					M00 = 1f,
					M11 = num4,
					M12 = 0f - num5,
					M21 = num5,
					M22 = num4
				};
				Mat mat = new Mat
				{
					M00 = num6,
					M02 = num7,
					M11 = 1f,
					M20 = 0f - num7,
					M22 = num6
				};
				Mat b2 = new Mat
				{
					M00 = num8,
					M01 = 0f - num9,
					M10 = num9,
					M11 = num8,
					M22 = 1f
				};
				return mat.Mul(b).Mul(b2);
			}

			private static float Rad(float deg)
			{
				return deg * MathF.PI / 180f;
			}
		}

		internal struct Joint
		{
			public Vec3 Position;

			public Mat Rotation;
		}

		public const float AttachTolerance = 0.02f;

		public static Vec3 Offset(Vec3 child, Vec3 parent, float lift)
		{
			return new Vec3(child.X - parent.X, child.Y - parent.Y + lift, child.Z - parent.Z);
		}

		public static Dictionary<string, Joint> Evaluate(Dictionary<string, Vec3> rest, BearBeat beat, float t, float cycle)
		{
			Dictionary<string, Joint> dictionary = new Dictionary<string, Joint>();
			if (rest == null || rest.Count == 0)
			{
				return dictionary;
			}
			List<string> list = new List<string>(rest.Keys);
			int num = 0;
			Joint value2 = default(Joint);
			while (list.Count > 0 && num++ < 32)
			{
				int count = list.Count;
				for (int num2 = list.Count - 1; num2 >= 0; num2--)
				{
					string text = list[num2];
					string text2 = BearPose.ParentGroup(text);
					if (text2 == null || !rest.ContainsKey(text2) || dictionary.ContainsKey(text2))
					{
						PartMotion partMotion = BearPose.For(text, beat, t, cycle);
						Mat mat = Mat.Euler(partMotion.PitchDeg, partMotion.YawDeg, partMotion.RollDeg);
						if (text2 != null && dictionary.TryGetValue(text2, out var value))
						{
							Vec3 v = Offset(rest[text], rest[text2], partMotion.Lift);
							value2.Position = Add(value.Position, value.Rotation.Mul(v));
							value2.Rotation = value.Rotation.Mul(mat);
						}
						else
						{
							Vec3 position = rest[text];
							position.Y += partMotion.Lift;
							value2.Position = position;
							value2.Rotation = mat;
						}
						dictionary[text] = value2;
						list.RemoveAt(num2);
					}
				}
				if (list.Count == count)
				{
					break;
				}
			}
			return dictionary;
		}

		public static float Length(Vec3 v)
		{
			return (float)Math.Sqrt(v.X * v.X + v.Y * v.Y + v.Z * v.Z);
		}

		public static Vec3 Add(Vec3 a, Vec3 b)
		{
			return new Vec3(a.X + b.X, a.Y + b.Y, a.Z + b.Z);
		}

		public static Vec3 Sub(Vec3 a, Vec3 b)
		{
			return new Vec3(a.X - b.X, a.Y - b.Y, a.Z - b.Z);
		}
	}
	internal static class BearRoar
	{
		public const float BodyPitch = 0.78f;

		public const float ChestPitch = 0.56f;

		public const float ChestGain = 0.45f;

		public const float ChestDelay = 0.035f;

		public const float LowHz = 1400f;

		public static float[] MixDown(float[] interleaved, int channels)
		{
			if (interleaved == null || interleaved.Length == 0 || channels < 1)
			{
				return new float[0];
			}
			int num = interleaved.Length / channels;
			float[] array = new float[num];
			for (int i = 0; i < num; i++)
			{
				float num2 = 0f;
				int num3 = i * channels;
				for (int j = 0; j < channels && num3 + j < interleaved.Length; j++)
				{
					num2 += interleaved[num3 + j];
				}
				array[i] = num2 / (float)channels;
			}
			return array;
		}

		public static float[] Shape(float[] mono, int sampleRate)
		{
			if (mono == null || mono.Length == 0)
			{
				return new float[0];
			}
			if (sampleRate < 1000)
			{
				sampleRate = 1000;
			}
			float[] array = Resample(mono, 0.78f);
			float[] array2 = Resample(mono, 0.56f);
			int num = (int)(0.035f * (float)sampleRate);
			if (num < 0)
			{
				num = 0;
			}
			int num2 = array.Length;
			if (array2.Length + num > num2)
			{
				num2 = array2.Length + num;
			}
			float[] array3 = new float[num2];
			for (int i = 0; i < array.Length; i++)
			{
				array3[i] = array[i];
			}
			for (int j = 0; j < array2.Length; j++)
			{
				array3[j + num] += array2[j] * 0.45f;
			}
			LowPass(array3, sampleRate, 1400f);
			Normalize(array3);
			return array3;
		}

		private static float[] Resample(float[] source, float pitch)
		{
			if (pitch < 0.25f)
			{
				pitch = 0.25f;
			}
			if (pitch > 2f)
			{
				pitch = 2f;
			}
			int num = (int)Math.Ceiling((float)source.Length / pitch);
			if (num < 1)
			{
				num = 1;
			}
			float[] array = new float[num];
			for (int i = 0; i < num; i++)
			{
				float num2 = (float)i * pitch;
				int num3 = (int)num2;
				if (num3 >= source.Length - 1)
				{
					array[i] = source[^1];
					continue;
				}
				float num4 = num2 - (float)num3;
				array[i] = source[num3] * (1f - num4) + source[num3 + 1] * num4;
			}
			return array;
		}

		private static void LowPass(float[] samples, int sampleRate, float hz)
		{
			double num = 1.0 - Math.Exp(Math.PI * -2.0 * (double)hz / (double)sampleRate);
			if (num < 0.0)
			{
				num = 0.0;
			}
			if (num > 1.0)
			{
				num = 1.0;
			}
			float num2 = 0f;
			for (int i = 0; i < samples.Length; i++)
			{
				num2 = (samples[i] = num2 + (float)(num * (double)(samples[i] - num2)));
			}
		}

		private static void Normalize(float[] samples)
		{
			float num = 0f;
			for (int i = 0; i < samples.Length; i++)
			{
				float num2 = ((samples[i] < 0f) ? (0f - samples[i]) : samples[i]);
				if (num2 > num)
				{
					num = num2;
				}
			}
			if (!(num < 1E-05f))
			{
				float num3 = 0.9f / num;
				for (int j = 0; j < samples.Length; j++)
				{
					samples[j] *= num3;
				}
			}
		}
	}
	internal static class BearSpawn
	{
		public const int DefaultFirstDay = 1;

		public const float ParkX = 3000f;

		public const float ParkY = 300f;

		public const float ParkZ = 3000f;

		public const float ParkRadius = 80f;

		public static bool Allow(bool enabled, bool waveRunActive, bool spawnDuringWaveRun)
		{
			if (!enabled)
			{
				return false;
			}
			if (waveRunActive && !spawnDuringWaveRun)
			{
				return false;
			}
			return true;
		}

		public static bool Roll(int day, int firstDay, bool daytime, float roll, float dayChance, float nightChance, int alive, int capDay, int capNight)
		{
			if (day < firstDay)
			{
				return false;
			}
			int num = (daytime ? capDay : capNight);
			if (num < 1 || alive >= num || alive < 0)
			{
				return false;
			}
			float num2 = (daytime ? dayChance : nightChance);
			if (num2 < 0f)
			{
				num2 = 0f;
			}
			if (num2 > 1f)
			{
				num2 = 1f;
			}
			if (roll < 0f)
			{
				roll = 0f;
			}
			return roll < num2;
		}

		public static bool PlaceOk(float fromAnchor, float nearestPlayer, float min, float max, float minAny)
		{
			if (max < min)
			{
				return false;
			}
			if (fromAnchor >= min && fromAnchor <= max)
			{
				return nearestPlayer >= minAny;
			}
			return false;
		}

		public static bool Parked(float x, float y, float z)
		{
			float num = x - 3000f;
			float num2 = y - 300f;
			float num3 = z - 3000f;
			return num * num + num2 * num2 + num3 * num3 <= 6400f;
		}

		public static bool Footing(bool groundHit, bool water, bool navMesh, bool parked)
		{
			if (groundHit && !water && navMesh)
			{
				return !parked;
			}
			return false;
		}
	}
	internal static class BearStats
	{
		public const float PlayerHeight = 3.816f;

		public const int ChiefBaseHp = 650;

		public const int DifficultyEasy = 0;

		public const int DifficultyNormal = 1;

		public const int DifficultyGamer = 2;

		public static float MobHpMultiplier(int day, int difficulty)
		{
			if (day < 0)
			{
				day = 0;
			}
			float num = 1.05f;
			float num2 = 0.24f;
			float num3 = 1.5f;
			switch (difficulty)
			{
			case 0:
				num = 0.9f;
				num2 = 0.2f;
				num3 = 1.32f;
				break;
			case 2:
				num = 1.3f;
				num2 = 0.3f;
				num3 = 1.8f;
				break;
			}
			return num + (float)Math.Pow(num2 * (float)day, num3);
		}

		public static float NightBossScale(int playersAlive)
		{
			if (playersAlive < 0)
			{
				playersAlive = 0;
			}
			return 0.85f + 0.15f * (float)playersAlive;
		}

		public static int ChiefHp(int baseHp, float mobHpMultiplier, int playersAlive)
		{
			if (baseHp < 1)
			{
				baseHp = 1;
			}
			if (float.IsNaN(mobHpMultiplier) || float.IsInfinity(mobHpMultiplier) || mobHpMultiplier < 0f)
			{
				mobHpMultiplier = 0f;
			}
			float num = NightBossScale(playersAlive);
			int num2 = (int)((double)baseHp * (double)mobHpMultiplier * (double)num);
			if (num2 >= 1)
			{
				return num2;
			}
			return 1;
		}

		public static int TapsRequired(int day, int baseTaps, int perDay, int cap)
		{
			if (day < 0)
			{
				day = 0;
			}
			if (baseTaps < 1)
			{
				baseTaps = 1;
			}
			if (perDay < 0)
			{
				perDay = 0;
			}
			if (cap < 1)
			{
				cap = 1;
			}
			long num = baseTaps + (long)perDay * (long)day;
			if (num > cap)
			{
				num = cap;
			}
			if (num < 1)
			{
				num = 1L;
			}
			return (int)num;
		}

		public static int AcceptTaps(int have, int reported, float dt, float maxPerSecond)
		{
			if (reported <= have)
			{
				return have;
			}
			if (maxPerSecond < 1f)
			{
				maxPerSecond = 1f;
			}
			double num = (((double)dt < 0.05) ? 0.05 : ((double)dt));
			int num2 = (int)Math.Floor((double)maxPerSecond * num);
			if (num2 < 1)
			{
				num2 = 1;
			}
			int num3 = reported;
			if (num3 > have + num2)
			{
				num3 = have + num2;
			}
			return num3;
		}

		public static int Coins(int salt, int min, int max)
		{
			if (max < min)
			{
				int num = min;
				min = max;
				max = num;
			}
			if (min < 1)
			{
				min = 1;
			}
			if (max < min)
			{
				max = min;
			}
			int num2 = max - min + 1;
			int num3 = salt % num2;
			if (num3 < 0)
			{
				num3 += num2;
			}
			return min + num3;
		}

		public static bool IsDay(float dayTime)
		{
			return dayTime < 0.5f;
		}
	}
	internal enum BearCue
	{
		Roar,
		Paw,
		Bite,
		Claw,
		Impact
	}
	internal readonly struct BearClipNote
	{
		public readonly string Name;

		public readonly float Length;

		public readonly string Role;

		public BearClipNote(string name, float length, string role)
		{
			Name = name ?? "";
			Length = length;
			Role = role ?? "";
		}
	}
	internal static class BearVoice
	{
		public const int RoarMinimum = 80;

		public const int PawMinimum = 40;

		public const int BiteMinimum = 60;

		public const int ClawMinimum = 40;

		public const int ImpactMinimum = 40;

		public static int Minimum(BearCue cue)
		{
			return cue switch
			{
				BearCue.Roar => 80, 
				BearCue.Paw => 40, 
				BearCue.Bite => 60, 
				BearCue.Claw => 40, 
				_ => 40, 
			};
		}

		public static int Score(BearCue cue, BearClipNote note)
		{
			string name = note.Name.ToLowerInvariant();
			string role = note.Role;
			int num = 0;
			bool flag = Has(name, "armor") || Has(name, "armour") || Has(name, "click") || Has(name, "hover") || Has(name, "inventory") || Has(name, "tutorial") || Has(name, "pickup");
			bool num2 = Has(name, "song") || Has(name, "music") || Has(name, "theme") || note.Length > 8f;
			if (flag)
			{
				num -= 200;
			}
			if (num2)
			{
				num -= 200;
			}
			switch (cue)
			{
			case BearCue.Roar:
				if (role == "dragon-roar")
				{
					num += 180;
				}
				if (Has(name, "roar"))
				{
					num += 100;
				}
				if (Has(name, "dragon"))
				{
					num += 40;
				}
				if (Has(name, "growl") || Has(name, "howl") || Has(name, "scream") || Has(name, "bellow") || Has(name, "yell"))
				{
					num += 50;
				}
				if (Has(name, "gronk") || Has(name, "chunk") || Has(name, "guardian"))
				{
					num += 20;
				}
				if (role == "dragon-wing" && !Has(name, "roar"))
				{
					num -= 80;
				}
				if (role == "boss")
				{
					num += 30;
				}
				if (note.Length >= 0.8f && note.Length <= 8f)
				{
					num += 25;
				}
				if (note.Length > 0f && note.Length < 0.25f)
				{
					num -= 60;
				}
				break;
			case BearCue.Paw:
				if (role == "foot")
				{
					num += 70;
				}
				if (Has(name, "step") || Has(name, "stomp") || Has(name, "foot") || Has(name, "thud"))
				{
					num += 40;
				}
				if (Has(name, "wood"))
				{
					num -= 15;
				}
				break;
			case BearCue.Bite:
				if (role == "eat")
				{
					num += 100;
				}
				if (Has(name, "eat") || Has(name, "bite") || Has(name, "chomp") || Has(name, "chew"))
				{
					num += 60;
				}
				break;
			case BearCue.Claw:
				if (role == "swing")
				{
					num += 100;
				}
				if (role == "hit")
				{
					num += 45;
				}
				if (Has(name, "swing") || Has(name, "slash") || Has(name, "whoosh") || Has(name, "swipe") || Has(name, "swoosh"))
				{
					num += 60;
				}
				break;
			default:
				if (role == "hit")
				{
					num += 50;
				}
				if (role == "foot")
				{
					num += 30;
				}
				if (Has(name, "thud") || Has(name, "slam") || Has(name, "stomp") || Has(name, "impact"))
				{
					num += 40;
				}
				break;
			}
			return num;
		}

		public static int Best(BearCue cue, BearClipNote[] notes)
		{
			if (notes == null || notes.Length == 0)
			{
				return -1;
			}
			int num = Minimum(cue);
			int num2 = -1;
			int num3 = num - 1;
			for (int i = 0; i < notes.Length; i++)
			{
				int num4 = Score(cue, notes[i]);
				if (num4 > num3)
				{
					num3 = num4;
					num2 = i;
				}
			}
			if (num2 < 0 || num3 < num)
			{
				return -1;
			}
			return num2;
		}

		private static bool Has(string name, string token)
		{
			return name.IndexOf(token, StringComparison.Ordinal) >= 0;
		}
	}
	internal struct BearSnap
	{
		public int Seq;

		public int Id;

		public BearPhase Phase;

		public float X;

		public float Y;

		public float Z;

		public float Dx;

		public float Dz;

		public float Lx;

		public float Ly;

		public float Lz;

		public int Grab;

		public int Target;

		public bool Aggro;

		public int BiteN;

		public int ClawN;

		public int LeapN;

		public int BiteD;

		public int ClawD;

		public int LeapD;

		public float Lane;

		public float Radius;

		public int Need;
	}
	internal static class BearWire
	{
		public const string StatePrefix = "~bq1 ";

		public const string ThrashPrefix = "~bq1t ";

		public const string HitPrefix = "~bq1h ";

		private static readonly CultureInfo Inv = CultureInfo.InvariantCulture;

		public static bool IsHidden(string message)
		{
			return message?.StartsWith("~bq", StringComparison.Ordinal) ?? false;
		}

		public static string State(in BearSnap s)
		{
			return string.Format(Inv, "~bq1 {0} {1} {2} {3:0.00} {4:0.00} {5:0.00} {6:0.000} {7:0.000} {8:0.00} {9:0.00} {10:0.00} {11} {12} {13} {14} {15} {16} {17} {18} {19} {20:0.00} {21:0.00} {22}", s.Seq, s.Id, (int)s.Phase, s.X, s.Y, s.Z, s.Dx, s.Dz, s.Lx, s.Ly, s.Lz, s.Grab, s.Target, s.Aggro ? 1 : 0, s.BiteN, s.ClawN, s.LeapN, s.BiteD, s.ClawD, s.LeapD, s.Lane, s.Radius, s.Need);
		}

		public static bool TryState(string message, out BearSnap snap)
		{
			snap = default(BearSnap);
			if (message == null || !message.StartsWith("~bq1 ", StringComparison.Ordinal))
			{
				return false;
			}
			string[] array = message.Split(new char[1] { ' ' });
			if (array.Length != 24)
			{
				return false;
			}
			if (!Int(array[1], out snap.Seq) || !Int(array[2], out snap.Id) || !Int(array[3], out var value))
			{
				return false;
			}
			if (value < 0 || value > 11)
			{
				return false;
			}
			snap.Phase = (BearPhase)value;
			if (!F(array[4], out snap.X) || !F(array[5], out snap.Y) || !F(array[6], out snap.Z))
			{
				return false;
			}
			if (!F(array[7], out snap.Dx) || !F(array[8], out snap.Dz))
			{
				return false;
			}
			if (!F(array[9], out snap.Lx) || !F(array[10], out snap.Ly) || !F(array[11], out snap.Lz))
			{
				return false;
			}
			if (!Int(array[12], out snap.Grab) || !Int(array[13], out snap.Target) || !Int(array[14], out var value2))
			{
				return false;
			}
			snap.Aggro = value2 != 0;
			if (!Int(array[15], out snap.BiteN) || !Int(array[16], out snap.ClawN) || !Int(array[17], out snap.LeapN))
			{
				return false;
			}
			if (!Int(array[18], out snap.BiteD) || !Int(array[19], out snap.ClawD) || !Int(array[20], out snap.LeapD))
			{
				return false;
			}
			if (!F(array[21], out snap.Lane) || !F(array[22], out snap.Radius) || !Int(array[23], out snap.Need))
			{
				return false;
			}
			return snap.Need >= 0;
		}

		public static string Thrash(int mobId, int taps)
		{
			return string.Format(Inv, "~bq1t {0} {1}", mobId, taps);
		}

		public static bool TryThrash(string message, out int mobId, out int taps)
		{
			mobId = -1;
			taps = 0;
			if (message == null || !message.StartsWith("~bq1t ", StringComparison.Ordinal))
			{
				return false;
			}
			string[] array = message.Split(new char[1] { ' ' });
			if (array.Length != 3)
			{
				return false;
			}
			if (Int(array[1], out mobId) && Int(array[2], out taps))
			{
				return taps >= 0;
			}
			return false;
		}

		public static string Hit(int mobId)
		{
			return string.Format(Inv, "~bq1h {0}", mobId);
		}

		public static bool TryHit(string message, out int mobId)
		{
			mobId = -1;
			if (message == null || !message.StartsWith("~bq1h ", StringComparison.Ordinal))
			{
				return false;
			}
			string[] array = message.Split(new char[1] { ' ' });
			if (array.Length == 2)
			{
				return Int(array[1], out mobId);
			}
			return false;
		}

		public static bool AcceptState(int fromUser)
		{
			return fromUser < 0;
		}

		public static bool AcceptThrash(int fromUser, int grabId)
		{
			if (fromUser >= 0)
			{
				return fromUser == grabId;
			}
			return false;
		}

		public static bool AcceptHit(int fromUser)
		{
			return fromUser >= 0;
		}

		public static bool CountTapsLocally(bool serverOwner)
		{
			return serverOwner;
		}

		private static bool Int(string text, out int value)
		{
			return int.TryParse(text, NumberStyles.Integer, Inv, out value);
		}

		private static bool F(string text, out float value)
		{
			return float.TryParse(text, NumberStyles.Float, Inv, out value);
		}
	}
	internal sealed class JsonReader
	{
		private readonly string text;

		private int pos;

		private JsonReader(string text)
		{
			this.text = text;
		}

		public static object Parse(string text)
		{
			if (text == null)
			{
				throw new FormatException("JSON text is null.");
			}
			JsonReader jsonReader = new JsonReader(text);
			object result = jsonReader.ReadValue();
			jsonReader.SkipWhitespace();
			if (jsonReader.pos != text.Length)
			{
				throw jsonReader.Error("trailing characters");
			}
			return result;
		}

		private object ReadValue()
		{
			SkipWhitespace();
			if (pos >= text.Length)
			{
				throw Error("unexpected end");
			}
			char c = text[pos];
			switch (c)
			{
			case '{':
				return ReadObject();
			case '[':
				return ReadArray();
			case '"':
				return ReadString();
			case 't':
				Expect("true");
				return true;
			case 'f':
				Expect("false");
				return false;
			case 'n':
				Expect("null");
				return null;
			default:
				switch (c)
				{
				case '-':
				case '0':
				case '1':
				case '2':
				case '3':
				case '4':
				case '5':
				case '6':
				case '7':
				case '8':
				case '9':
					return ReadNumber();
				default:
					throw Error("unexpected '" + c + "'");
				}
			}
		}

		private Dictionary<string, object> ReadObject()
		{
			Dictionary<string, object> dictionary = new Dictionary<string, object>();
			pos++;
			SkipWhitespace();
			if (Peek() == '}')
			{
				pos++;
				return dictionary;
			}
			while (true)
			{
				SkipWhitespace();
				if (Peek() != '"')
				{
					throw Error("expected a key");
				}
				string key = ReadString();
				SkipWhitespace();
				if (Peek() != ':')
				{
					break;
				}
				pos++;
				dictionary[key] = ReadValue();
				SkipWhitespace();
				char c = Peek();
				pos++;
				switch (c)
				{
				case ',':
					break;
				case '}':
					return dictionary;
				default:
					throw Error("expected ',' or '}'");
				}
			}
			throw Error("expected ':'");
		}

		private List<object> ReadArray()
		{
			List<object> list = new List<object>();
			pos++;
			SkipWhitespace();
			if (Peek() == ']')
			{
				pos++;
				return list;
			}
			while (true)
			{
				list.Add(ReadValue());
				SkipWhitespace();
				char c = Peek();
				pos++;
				switch (c)
				{
				case ',':
					break;
				case ']':
					return list;
				default:
					throw Error("expected ',' or ']'");
				}
			}
		}

		private string ReadString()
		{
			pos++;
			StringBuilder stringBuilder = new StringBuilder();
			while (pos < text.Length)
			{
				char c = text[pos++];
				switch (c)
				{
				case '"':
					return stringBuilder.ToString();
				default:
					stringBuilder.Append(c);
					break;
				case '\\':
					if (pos >= text.Length)
					{
						throw Error("unterminated escape");
					}
					switch (text[pos++])
					{
					case '"':
						stringBuilder.Append('"');
						break;
					case '\\':
						stringBuilder.Append('\\');
						break;
					case '/':
						stringBuilder.Append('/');
						break;
					case 'b':
						stringBuilder.Append('\b');
						break;
					case 'f':
						stringBuilder.Append('\f');
						break;
					case 'n':
						stringBuilder.Append('\n');
						break;
					case 'r':
						stringBuilder.Append('\r');
						break;
					case 't':
						stringBuilder.Append('\t');
						break;
					case 'u':
						if (pos + 4 > text.Length)
						{
							throw Error("short \\u escape");
						}
						stringBuilder.Append((char)int.Parse(text.Substring(pos, 4), NumberStyles.HexNumber, CultureInfo.InvariantCulture));
						pos += 4;
						break;
					default:
						throw Error("bad escape");
					}
					break;
				}
			}
			throw Error("unterminated string");
		}

		private double ReadNumber()
		{
			int num = pos;
			while (pos < this.text.Length && "+-0123456789.eE".IndexOf(this.text[pos]) >= 0)
			{
				pos++;
			}
			string text = this.text.Substring(num, pos - num);
			if (!double.TryParse(text, NumberStyles.Float, CultureInfo.InvariantCulture, out var result))
			{
				throw Error("bad number '" + text + "'");
			}
			return result;
		}

		private void Expect(string word)
		{
			if (string.CompareOrdinal(text, pos, word, 0, word.Length) != 0)
			{
				throw Error("expected '" + word + "'");
			}
			pos += word.Length;
		}

		private char Peek()
		{
			if (pos >= text.Length)
			{
				return '\0';
			}
			return text[pos];
		}

		private void SkipWhitespace()
		{
			while (pos < text.Length && char.IsWhiteSpace(text[pos]))
			{
				pos++;
			}
		}

		private FormatException Error(string what)
		{
			return new FormatException("JSON: " + what + " at offset " + pos + ".");
		}
	}
	[HarmonyPatch]
	internal static class BearHitPatch
	{
		private static MethodBase TargetMethod()
		{
			return AccessTools.DeclaredMethod(typeof(HitableMob), "Hit", new Type[5]
			{
				typeof(int),
				typeof(float),
				typeof(int),
				typeof(Vector3),
				typeof(int)
			}, (Type[])null);
		}

		private static void Postfix(HitableMob __instance)
		{
			try
			{
				BearActor component = ((Component)__instance).GetComponent<BearActor>();
				if (!((Object)(object)component == (Object)null))
				{
					if (LocalClient.serverOwner)
					{
						component.Aggro(Time.time);
					}
					else
					{
						ClientSend.SendChatMessage(BearWire.Hit(component.Id));
					}
				}
			}
			catch (Exception ex)
			{
				BaseqsPlugin.LogOnce("hit", "Baseq's Enemies: aggro notice failed. " + ex.Message);
			}
		}
	}
	[HarmonyPatch(typeof(PlayerMovement), "Movement", new Type[]
	{
		typeof(float),
		typeof(float)
	})]
	internal static class BearMoveLockPatch
	{
		private static bool Prefix()
		{
			return !BearGrab.LocalHeld();
		}
	}
	[HarmonyPatch(typeof(PlayerMovement), "Jump")]
	internal static class BearJumpLockPatch
	{
		private static bool Prefix()
		{
			return !BearGrab.LocalHeld();
		}
	}
	[HarmonyPatch(typeof(UseInventory), "Use")]
	internal static class BearUseLockPatch
	{
		private static bool Prefix()
		{
			return !BearGrab.LocalHeld();
		}
	}
	[HarmonyPatch(typeof(HitBox), "UseHitbox")]
	internal static class BearHitboxLockPatch
	{
		private static bool Prefix(HitBox __instance)
		{
			if (!BearGrab.LocalHeld())
			{
				return true;
			}
			if ((Object)(object)__instance == (Object)null || (Object)(object)PlayerMovement.Instance == (Object)null)
			{
				return true;
			}
			Transform transform = ((Component)PlayerMovement.Instance).transform;
			Transform transform2 = ((Component)__instance).transform;
			if ((Object)(object)transform2 != (Object)(object)transform)
			{
				return !transform2.IsChildOf(transform);
			}
			return false;
		}
	}
	[HarmonyPatch]
	internal static class BearLootPatch
	{
		private static MethodBase TargetMethod()
		{
			return AccessTools.DeclaredMethod(typeof(LootExtra), "DropMobLoot", new Type[4]
			{
				typeof(Transform),
				typeof(LootDrop),
				typeof(int),
				typeof(float)
			}, (Type[])null);
		}

		private static void Prefix(Transform __0, ref LootDrop __1)
		{
			try
			{
				if (!((Object)(object)__0 == (Object)null) && !((Object)(object)((Component)__0).GetComponent<BearActor>() == (Object)null))
				{
					LootDrop val = BearLoot.Table();
					if (!((Object)(object)val == (Object)null))
					{
						__1 = val;
					}
				}
			}
			catch (Exception ex)
			{
				BaseqsPlugin.LogOnce("loot", "Baseq's Enemies: loot swap failed. " + ex.Message);
			}
		}
	}
	[HarmonyPatch]
	internal static class BearStartPatch
	{
		private static MethodBase TargetMethod()
		{
			return AccessTools.DeclaredMethod(typeof(HitableMob), "Start", Type.EmptyTypes, (Type[])null);
		}

		private static void Postfix(HitableMob __instance)
		{
			try
			{
				if (!((Object)(object)((Component)__instance).GetComponent<BearActor>() == (Object)null))
				{
					BearHealth.Apply((Hitable)(object)__instance);
				}
			}
			catch (Exception ex)
			{
				BaseqsPlugin.LogOnce("hp", "Baseq's Enemies: bear health failed. " + ex.Message);
			}
		}
	}
	[HarmonyPatch(typeof(ChatBox), "AppendMessage", new Type[]
	{
		typeof(int),
		typeof(string),
		typeof(string)
	})]
	internal static class ChatBoxAppendPatch
	{
		private static bool Prefix(int __0, string __1)
		{
			if (!BearWire.IsHidden(__1))
			{
				return true;
			}
			try
			{
				BearInbox.Dispatch(__0, __1);
			}
			catch (Exception ex)
			{
				BaseqsPlugin.LogOnce("chat", "Baseq's Enemies: sync line failed. " + ex.Message);
			}
			return false;
		}
	}
	[HarmonyPatch]
	internal static class SpawnMobAdoptPatch
	{
		private static MethodBase TargetMethod()
		{
			return AccessTools.DeclaredMethod(typeof(MobSpawner), "SpawnMob", new Type[7]
			{
				typeof(Vector3),
				typeof(int),
				typeof(int),
				typeof(float),
				typeof(float),
				typeof(BossType),
				typeof(int)
			}, (Type[])null);
		}

		private static void Postfix(MobSpawner __instance, int __1, int __2, float __4)
		{
			try
			{
				if (!((Object)(object)__instance == (Object)null) && __instance.allMobs != null && __1 >= 0 && __1 < __instance.allMobs.Length && !((Object)(object)__instance.allMobs[__1] == (Object)null) && BearMarker.IsBear(__4, __instance.allMobs[__1].name) && !((Object)(object)MobManager.Instance == (Object)null) && MobManager.Instance.mobs != null && MobManager.Instance.mobs.TryGetValue(__2, out var value) && !((Object)(object)value == (Object)null) && !((Object)(object)((Component)value).GetComponent<BearActor>() != (Object)null))
				{
					((Component)value).gameObject.AddComponent<BearActor>();
				}
			}
			catch (Exception ex)
			{
				BaseqsPlugin.LogOnce("adopt", "Baseq's Enemies: could not adopt bear " + __2 + ". " + ex.Message);
			}
		}
	}
	internal sealed class BearActor : MonoBehaviour
	{
		public static readonly List<BearActor> All = new List<BearActor>();

		private BearMemory memory;

		private BearVisuals visuals;

		private GameObject tell;

		private BearPhase told;

		private int taps;

		private int shownBite;

		private bool pinned;

		private float phaseStart;

		private float lastPublish = -999f;

		private bool publishNow;

		private Vector3 leapStart;

		private int id = -1;

		private bool navSynced;

		public float LastTapAt;

		public int Id => id;

		public BearMemory Memory => memory;

		public int CurrentGrab()
		{
			return ShownGrab();
		}

		public int AcceptedTaps()
		{
			return taps;
		}

		public int NeededTaps()
		{
			return TapsNeeded();
		}

		public static int Living()
		{
			int num = 0;
			for (int num2 = All.Count - 1; num2 >= 0; num2--)
			{
				BearActor bearActor = All[num2];
				if ((Object)(object)bearActor == (Object)null)
				{
					All.RemoveAt(num2);
				}
				else
				{
					Hitable component = ((Component)bearActor).GetComponent<Hitable>();
					if ((Object)(object)component != (Object)null && component.hp > 0)
					{
						num++;
					}
				}
			}
			return num;
		}

		public static BearActor Find(int mobId)
		{
			for (int i = 0; i < All.Count; i++)
			{
				if ((Object)(object)All[i] != (Object)null && All[i].id == mobId)
				{
					return All[i];
				}
			}
			return null;
		}

		public void Aggro(float now)
		{
			bool num = memory.Aggro;
			BearBrain.Aggro(ref memory, now);
			if (!num)
			{
				publishNow = true;
				phaseStart = now;
				if (BaseqsPlugin.Cfg != null && BaseqsPlugin.Cfg.VerboseLogging.Value)
				{
					BaseqsPlugin.Log.LogInfo((object)("Baseq's Enemies: bear " + id + " aggro."));
				}
			}
		}

		public void AcceptReported(int reported, float dt)
		{
			if (memory.Phase == BearPhase.Grab)
			{
				taps = BearStats.AcceptTaps(taps, reported, dt, 12f);
			}
		}

		public BearSnap Capture(int seq)
		{
			//IL_000c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0011: Unknown result type (might be due to invalid IL or missing references)
			//IL_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_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_00b4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ce: Unknown result type (might be due to invalid IL or missing references)
			//IL_00db: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e8: Unknown result type (might be due to invalid IL or missing references)
			BearConfig cfg = BaseqsPlugin.Cfg;
			Vector3 position = ((Component)this).transform.position;
			Vector3 forward = ((Component)this).transform.forward;
			forward.y = 0f;
			if (((Vector3)(ref forward)).sqrMagnitude < 1E-06f)
			{
				forward = Vector3.forward;
			}
			((Vector3)(ref forward)).Normalize();
			if (memory.Phase == BearPhase.Charge || memory.Phase == BearPhase.ChargeTell)
			{
				((Vector3)(ref forward))..ctor(memory.LaneDx, 0f, memory.LaneDz);
			}
			return new BearSnap
			{
				Seq = seq,
				Id = id,
				Phase = memory.Phase,
				X = position.x,
				Y = position.y,
				Z = position.z,
				Dx = forward.x,
				Dz = forward.z,
				Lx = memory.LandX,
				Ly = memory.LandY,
				Lz = memory.LandZ,
				Grab = memory.GrabId,
				Target = -1,
				Aggro = memory.Aggro,
				BiteN = memory.BiteSeq,
				ClawN = memory.ClawSeq,
				LeapN = memory.LeapSeq,
				BiteD = (cfg?.BiteDamage.Value ?? 12),
				ClawD = (cfg?.ClawDamage.Value ?? 18),
				LeapD = (cfg?.LeapDamage.Value ?? 34),
				Lane = 14f,
				Radius = 3.2f,
				Need = TapsNeeded()
			};
		}

		private void Awake()
		{
			Mob component = ((Component)this).GetComponent<Mob>();
			id = (((Object)(object)component != (Object)null) ? component.id : (-1));
			memory = BearMemory.Fresh();
			All.Add(this);
		}

		private void Start()
		{
			visuals = ((Component)this).gameObject.AddComponent<BearVisuals>();
			visuals.Build();
			BearHealth.Apply(((Component)this).GetComponent<Hitable>());
			if (LocalClient.serverOwner)
			{
				SilenceVanilla();
			}
		}

		private void OnDestroy()
		{
			All.Remove(this);
			if ((Object)(object)tell != (Object)null)
			{
				Object.Destroy((Object)(object)tell);
			}
		}

		private void Update()
		{
			if (!((Object)(object)visuals == (Object)null))
			{
				if (LocalClient.serverOwner)
				{
					HostUpdate();
				}
				else
				{
					ClientUpdate();
				}
			}
		}

		private void LateUpdate()
		{
			//IL_005f: Unknown result type (might be due to invalid IL or missing references)
			//IL_011d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0089: Unknown result type (might be due to invalid IL or missing references)
			//IL_008e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0095: Unknown result type (might be due to invalid IL or missing references)
			//IL_009a: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ca: Unknown result type (might be due to invalid IL or missing references)
			//IL_00cd: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00df: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ed: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fb: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bb: Unknown result type (might be due to invalid IL or missing references)
			int num = ShownGrab();
			if (num < 0 || !((Object)(object)LocalClient.instance != (Object)null) || num != LocalClient.instance.myId || (Object)(object)PlayerMovement.Instance == (Object)null)
			{
				pinned = false;
				return;
			}
			Transform transform = ((Component)PlayerMovement.Instance).transform;
			Rigidbody rb = PlayerMovement.Instance.GetRb();
			if ((Object)(object)rb != (Object)null)
			{
				rb.velocity = Vector3.zero;
			}
			if ((Object)(object)visuals == (Object)null)
			{
				return;
			}
			if (!pinned)
			{
				Vector3 val = visuals.Mouth();
				Vector3 forward = ((Component)this).transform.forward;
				forward.y = 0f;
				if (((Vector3)(ref forward)).sqrMagnitude < 1E-06f)
				{
					forward = Vector3.forward;
				}
				((Vector3)(ref forward)).Normalize();
				Vector3 position = transform.position;
				pinned = BearHits.AtMouth(val.x, val.y, val.z, forward.x, forward.z, position.x, position.y, position.z, catchingUp: true);
				if (!pinned)
				{
					return;
				}
			}
			transform.position = visuals.Mouth();
		}

		private int ShownGrab()
		{
			if (LocalClient.serverOwner)
			{
				return memory.GrabId;
			}
			if (BearSync.TryGet(id, out var snap))
			{
				return snap.Grab;
			}
			return -1;
		}

		private void HostUpdate()
		{
			//IL_00c9: Unknown result type (might be due to invalid IL or missing references)
			float time = Time.time;
			SilenceVanilla();
			Hitable component = ((Component)this).GetComponent<Hitable>();
			if ((Object)(object)component != (Object)null && component.hp > 0 && component.hp < component.maxHp)
			{
				Aggro(time);
			}
			float distance;
			PlayerManager val = Nearest(out distance);
			int tapsNeeded = TapsNeeded();
			BearSense s = new BearSense(time, distance, (Object)(object)val != (Object)null, taps, tapsNeeded, GrabbedAlive());
			BearPhase phase = memory.Phase;
			int biteSeq = memory.BiteSeq;
			BearBrain.Tick(ref memory, in s);
			if (memory.Phase != phase)
			{
				Enter(phase, memory.Phase, val, time);
			}
			if (memory.BiteSeq != biteSeq)
			{
				BearAudio.Bite(((Component)this).transform.position);
			}
			Move(val, time);
			Pose(memory.Phase, time);
			visuals.TintEyes(memory.Aggro);
			ShowTell(memory.Phase);
			if (memory.Phase != phase || memory.BiteSeq != biteSeq)
			{
				publishNow = true;
			}
			if (BearPublish.Due(publishNow, time - lastPublish, memory.Phase))
			{
				BearSync.Publish(this);
				publishNow = false;
				lastPublish = time;
			}
		}

		private void ClientUpdate()
		{
			//IL_0035: 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_0051: Unknown result type (might be due to invalid IL or missing references)
			//IL_0087: Unknown result type (might be due to invalid IL or missing references)
			//IL_0088: Unknown result type (might be due to invalid IL or missing references)
			//IL_008d: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f8: Unknown result type (might be due to invalid IL or missing references)
			if (!BearSync.TryGet(id, out var snap))
			{
				return;
			}
			Vector3 val = default(Vector3);
			((Vector3)(ref val))..ctor(snap.X, snap.Y, snap.Z);
			((Component)this).transform.position = Vector3.Lerp(((Component)this).transform.position, val, 1f - Mathf.Exp(-10f * Time.deltaTime));
			Vector3 val2 = default(Vector3);
			((Vector3)(ref val2))..ctor(snap.Dx, 0f, snap.Dz);
			if (((Vector3)(ref val2)).sqrMagnitude > 1E-06f)
			{
				((Component)this).transform.rotation = Quaternion.LookRotation(val2, Vector3.up);
			}
			if (snap.Phase != told)
			{
				phaseStart = Time.time;
				BearAudio.Play(snap.Phase, val);
				if (snap.Phase == BearPhase.Grab)
				{
					taps = 0;
				}
			}
			if (snap.BiteN != shownBite && snap.Phase == BearPhase.Grab)
			{
				shownBite = snap.BiteN;
				if (snap.BiteN > 0)
				{
					BearAudio.Bite(val);
				}
			}
			Pose(snap.Phase, Time.time);
			visuals.TintEyes(snap.Aggro);
			ShowTell(snap.Phase, snap);
		}

		private void Enter(BearPhase from, BearPhase to, PlayerManager target, float now)
		{
			//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)
			//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)
			//IL_003d: Unknown result type (might be due to invalid IL or missing references)
			//IL_006a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0085: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a0: Unknown result type (might be due to invalid IL or missing references)
			//IL_0106: Unknown result type (might be due to invalid IL or missing references)
			//IL_010b: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ce: Unknown result type (might be due to invalid IL or missing references)
			//IL_00df: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f0: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a2: Unknown result type (might be due to invalid IL or missing references)
			phaseStart = now;
			if (to == BearPhase.ChargeTell && (Object)(object)target != (Object)null)
			{
				Vector3 val = ((Component)target).transform.position - ((Component)this).transform.position;
				BearHits.Flatten(val.x, val.z, out memory.LaneDx, out memory.LaneDz);
				memory.LaneX = ((Component)this).transform.position.x;
				memory.LaneY = ((Component)this).transform.position.y;
				memory.LaneZ = ((Component)this).transform.position.z;
			}
			if (to == BearPhase.LeapTell && (Object)(object)target != (Object)null)
			{
				Vector3 position = ((Component)target).transform.position;
				memory.LandX = position.x;
				memory.LandY = position.y;
				memory.LandZ = position.z;
			}
			if (to == BearPhase.Leap)
			{
				leapStart = ((Component)this).transform.position;
			}
			if (to == BearPhase.Grab)
			{
				taps = 0;
				LastTapAt = now;
				float num = BearBrain.FleePace((BaseqsPlugin.Cfg != null) ? BaseqsPlugin.Cfg.FleeSpeed.Value : 20f);
				BaseqsPlugin.Log.LogInfo((object)("Baseq's Enemies: bear " + id + " grab -> flee at " + num.ToString("0.#") + " m/s."));
			}
			if (from == BearPhase.Grab)
			{
				taps = 0;
			}
			BearAudio.Play(to, ((Component)this).transform.position);
			if (BaseqsPlugin.Cfg != null && BaseqsPlugin.Cfg.VerboseLogging.Value)
			{
				BaseqsPlugin.Log.LogInfo((object)("Baseq's Enemies: bear " + id + " " + to.ToString() + "."));
			}
		}

		private void Move(PlayerManager target, float now)
		{
			//IL_0089: Unknown result type (might be due to invalid IL or missing references)
			//IL_008e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0094: Unknown result type (might be due to invalid IL or missing references)
			//IL_009e: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a9: Unknown result type (might be due to invalid IL or missing references)
			//IL_0189: Unknown result type (might be due to invalid IL or missing references)
			//IL_018e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0192: Unknown result type (might be due to invalid IL or missing references)
			//IL_0197: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a6: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d1: Unknown result type (might be due to invalid IL or missing references)
			//IL_0207: Unknown result type (might be due to invalid IL or missing references)
			//IL_0102: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bb: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00cf: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00df: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e7: Unknown result type (might be due to invalid IL or missing references)
			//IL_011c: Unknown result type (might be due to invalid IL or missing references)
			//IL_011d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0122: Unknown result type (might be due to invalid IL or missing references)
			NavMeshAgent agent = (((Object)(object)((Component)this).GetComponent<Mob>() != (Object)null) ? ((Component)this).GetComponent<Mob>().agent : null);
			switch (memory.Phase)
			{
			case BearPhase.Charge:
			{
				StopAgent(agent);
				Vector3 val2 = default(Vector3);
				((Vector3)(ref val2))..ctor(memory.LaneDx, 0f, memory.LaneDz);
				Vector3 val3 = ((Component)this).transform.position + val2 * 16f * Time.deltaTime;
				NavMeshHit val4 = default(NavMeshHit);
				if (NavMesh.SamplePosition(val3, ref val4, 8f, -1))
				{
					val3.y = BearHits.ChargeHeight(val3.y, ((NavMeshHit)(ref val4)).position.x, ((NavMeshHit)(ref val4)).position.z, val3.x, val3.z, ((NavMeshHit)(ref val4)).position.y, hit: true);
				}
				((Component)this).transform.position = val3;
				if (((Vector3)(ref val2)).sqrMagnitude > 1E-06f)
				{
					((Component)this).transform.rotation = Quaternion.LookRotation(val2, Vector3.up);
				}
				TryGrab(now);
				if (memory.Phase == BearPhase.Grab)
				{
					Flee(agent);
				}
				break;
			}
			case BearPhase.Leap:
			{
				StopAgent(agent);
				float num = Fraction(0.75f);
				Vector3 val = default(Vector3);
				((Vector3)(ref val))..ctor(memory.LandX, memory.LandY, memory.LandZ);
				Vector3 position = Vector3.Lerp(leapStart, val, num);
				position.y = Mathf.Lerp(leapStart.y, val.y, num) + 9.6f * num * (1f - num);
				((Component)this).transform.position = position;
				break;
			}
			case BearPhase.LeapImpact:
				StopAgent(agent);
				((Component)this).transform.position = new Vector3(memory.LandX, memory.LandY, memory.LandZ);
				break;
			case BearPhase.Grab:
				Flee(agent);
				break;
			case BearPhase.Pick:
				Approach(agent, target);
				break;
			case BearPhase.Calm:
				Wander(agent, now);
				break;
			default:
				StopAgent(agent);
				Face(target);
				break;
			}
		}

		private void TryGrab(float now)
		{
			//IL_005c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0061: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b1: Unknown result type (might be due to invalid IL or missing references)
			//IL_0076: Unknown result type (might be due to invalid IL or missing references)
			//IL_0081: Unknown result type (might be due to invalid IL or missing references)
			//IL_008b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0090: Unknown result type (might be due to invalid IL or missing references)
			//IL_0095: Unknown result type (might be due to invalid IL or missing references)
			//IL_009f: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bf: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ef: Unknown result type (might be due to invalid IL or missing references)
			//IL_0100: Unknown result type (might be due to invalid IL or missing references)
			//IL_0106: Unknown result type (might be due to invalid IL or missing references)
			if (GameManager.players == null)
			{
				return;
			}
			foreach (KeyValuePair<int, PlayerManager> player in GameManager.players)
			{
				PlayerManager value = player.Value;
				if ((Object)(object)value == (Object)null || value.dead || !BearBrain.CanGrab(in memory, value.id, now))
				{
					continue;
				}
				Vector3 position = ((Component)value).transform.position;
				Vector3 val = (((Object)(object)visuals != (Object)null) ? visuals.Mouth() : (((Component)this).transform.position + ((Component)this).transform.forward * 5.75f + Vector3.up * 5.05f));
				if (BearHits.AtMouth(val.x, val.y, val.z, memory.LaneDx, memory.LaneDz, position.x, position.y, position.z, catchingUp: false))
				{
					float num = position.y - val.y;
					if (num < 0f)
					{
						num = 0f - num;
					}
					BaseqsPlugin.Log.LogInfo((object)("Baseq's Enemies: bear " + id + " grab contact dy " + num.ToString("0.0", CultureInfo.InvariantCulture) + "."));
					BearBrain.BeginGrab(ref memory, value.id, now);
					Enter(BearPhase.Charge, BearPhase.Grab, null, now);
					publishNow = true;
					break;
				}
			}
		}

		private void Approach(NavMeshAgent agent, PlayerManager target)
		{
			//IL_0044: 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_0030: Unknown result type (might be due to invalid IL or missing references)
			//IL_007b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0082: Unknown result type (might be due to invalid IL or missing references)
			//IL_0088: Unknown result type (might be due to invalid IL or missing references)
			//IL_0092: Unknown result type (might be due to invalid IL or missing references)
			//IL_0097: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)target == (Object)null)
			{
				StopAgent(agent);
				return;
			}
			Face(target);
			float num = WolfPace();
			if ((Object)(object)agent == (Object)null || !Follow(agent, ((Component)target).transform.position, num, rush: false))
			{
				Vector3 val = ((Component)target).transform.position - ((Component)this).transform.position;
				val.y = 0f;
				if (((Vector3)(ref val)).sqrMagnitude > 0.0001f)
				{
					Transform transform = ((Component)this).transform;
					transform.position += ((Vector3)(ref val)).normalized * num * Time.deltaTime;
				}
			}
		}

		private void Wander(NavMeshAgent agent, float now)
		{
			//IL_00b5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00cf: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00db: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e0: 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_010b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0110: Unknown result type (might be due to invalid IL or missing references)
			//IL_0115: Unknown result type (might be due to invalid IL or missing references)
			//IL_005b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0060: Unknown result type (might be due to invalid IL or missing references)
			//IL_0063: Unknown result type (might be due to invalid IL or missing references)
			//IL_0068: Unknown result type (might be due to invalid IL or missing references)
			//IL_006d: Unknown result type (might be due to invalid IL or missing references)
			//IL_006e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0037: Unknown result type (might be due to invalid IL or missing references)
			//IL_003c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0142: Unknown result type (might be due to invalid IL or missing references)
			//IL_0149: Unknown result type (might be due to invalid IL or missing references)
			//IL_014f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0159: Unknown result type (might be due to invalid IL or missing references)
			//IL_015e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0131: Unknown result type (might be due to invalid IL or missing references)
			//IL_008f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0096: Unknown result type (might be due to invalid IL or missing references)
			//IL_0081: Unknown result type (might be due to invalid IL or missing references)
			//IL_0086: Unknown result type (might be due to invalid IL or missing references)
			if (BearBrain.NeedsWander(in memory, now))
			{
				Vector3 val = Random.insideUnitSphere;
				val.y = 0f;
				if (((Vector3)(ref val)).sqrMagnitude < 0.0001f)
				{
					val = ((Component)this).transform.forward;
				}
				((Vector3)(ref val)).Normalize();
				float num = Random.Range(6f, 14f);
				Vector3 val2;
				NavMeshHit val3 = default(NavMeshHit);
				if (NavMesh.SamplePosition(val2 = ((Component)this).transform.position + val * num, ref val3, 8f, -1))
				{
					val2 = ((NavMeshHit)(ref val3)).position;
				}
				BearBrain.SetWander(ref memory, now, val2.x, val2.z);
			}
			Vector3 val4 = default(Vector3);
			((Vector3)(ref val4))..ctor(memory.WanderX, ((Component)this).transform.position.y, memory.WanderZ);
			Vector3 val5 = val4 - ((Component)this).transform.position;
			val5.y = 0f;
			if (((Vector3)(ref val5)).sqrMagnitude < 1f)
			{
				StopAgent(agent);
				return;
			}
			((Component)this).transform.rotation = Quaternion.LookRotation(((Vector3)(ref val5)).normalized, Vector3.up);
			float num2 = WolfPace();
			if ((Object)(object)agent == (Object)null || !Follow(agent, val4, num2, rush: false))
			{
				Transform transform = ((Component)this).transform;
				transform.position += ((Vector3)(ref val5)).normalized * num2 * Time.deltaTime;
			}
		}

		private void Flee(NavMeshAgent agent)
		{
			//IL_00d2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00de: Unknown result type (might be due to invalid IL or missing references)
			//IL_011a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0128: Unknown result type (might be due to invalid IL or missing references)
			//IL_0132: Unknown result type (might be due to invalid IL or missing references)
			//IL_0137: Unknown result type (might be due to invalid IL or missing references)
			//IL_013c: Unknown result type (might be due to invalid IL or missing references)
			//IL_013e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0151: Unknown result type (might be due to invalid IL or missing references)
			//IL_0161: Unknown result type (might be due to invalid IL or missing references)
			//IL_0171: Unknown result type (might be due to invalid IL or missing references)
			//IL_0181: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c4: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c6: Unknown result type (might be due to invalid IL or missing references)
			//IL_01cb: Unknown result type (might be due to invalid IL or missing references)
			//IL_0199: Unknown result type (might be due to invalid IL or missing references)
			//IL_019e: Unknown result type (might be due to invalid IL or missing references)
			//IL_01f3: Unknown result type (might be due to invalid IL or missing references)
			//IL_0203: Unknown result type (might be due to invalid IL or missing references)
			//IL_022b: Unknown result type (might be due to invalid IL or missing references)
			//IL_023c: Unknown result type (might be due to invalid IL or missing references)
			//IL_01e0: Unknown result type (might be due to invalid IL or missing references)
			//IL_02a4: Unknown result type (might be due to invalid IL or missing references)
			//IL_024f: Unknown result type (might be due to invalid IL or missing references)
			//IL_025f: Unknown result type (might be due to invalid IL or missing references)
			//IL_026f: Unknown result type (might be due to invalid IL or missing references)
			//IL_027f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0069: Unknown result type (might be due to invalid IL or missing references)
			//IL_007a: Unknown result type (might be due to invalid IL or missing references)
			//IL_008e: Unknown result type (might be due to invalid IL or missing references)
			//IL_009f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0297: Unknown result type (might be due to invalid IL or missing references)
			//IL_029c: Unknown result type (might be due to invalid IL or missing references)
			float num = 0f;
			float num2 = 0f;
			int num3 = 0;
			if (GameManager.players != null)
			{
				foreach (KeyValuePair<int, PlayerManager> player in GameManager.players)
				{
					PlayerManager value = player.Value;
					if (!((Object)(object)value == (Object)null) && !value.dead && value.id != memory.GrabId)
					{
						num += ((Component)this).transform.position.x - ((Component)value).transform.position.x;
						num2 += ((Component)this).transform.position.z - ((Component)value).transform.position.z;
						num3++;
					}
				}
			}
			Vector3 forward = ((Component)this).transform.forward;
			BearBrain.FleeDirection(forward.x, forward.z, num, num2, num3, out var dx, out var dz);
			float num4 = BearBrain.FleePace((BaseqsPlugin.Cfg != null) ? BaseqsPlugin.Cfg.FleeSpeed.Value : 20f);
			Vector3 val = ((Component)this).transform.position + new Vector3(dx, 0f, dz) * 24f;
			NavMeshHit val2 = default(NavMeshHit);
			if (NavMesh.SamplePosition(val, ref val2, 12f, -1) && (((NavMeshHit)(ref val2)).position.x - ((Component)this).transform.position.x) * dx + (((NavMeshHit)(ref val2)).position.z - ((Component)this).transform.position.z) * dz > 2f)
			{
				val = ((NavMeshHit)(ref val2)).position;
			}
			Vector3 val3 = default(Vector3);
			((Vector3)(ref val3))..ctor(dx, 0f, dz);
			if (((Vector3)(ref val3)).sqrMagnitude > 1E-06f)
			{
				((Component)this).transform.rotation = Quaternion.LookRotation(val3, Vector3.up);
			}
			if (!((Object)(object)agent != (Object)null) || !Follow(agent, val, num4, rush: true))
			{
				BearBrain.FleeAdvance(((Component)this).transform.position.x, ((Component)this).transform.position.z, dx, dz, num4, Time.deltaTime, out var nx, out var nz);
				Vector3 position = default(Vector3);
				((Vector3)(ref position))..ctor(nx, ((Component)this).transform.position.y, nz);
				NavMeshHit val4 = default(NavMeshHit);
				if (NavMesh.SamplePosition(position, ref val4, 4f, -1) && (((NavMeshHit)(ref val4)).position.x - ((Component)this).transform.position.x) * dx + (((NavMeshHit)(ref val4)).position.z - ((Component)this).transform.position.z) * dz > 0.02f)
				{
					position = ((NavMeshHit)(ref val4)).position;
				}
				((Component)this).transform.position = position;
			}
		}

		private void Face(PlayerManager target)
		{
			//IL_0010: 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_0020: 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_0049: Unknown result type (might be due to invalid IL or missing references)
			//IL_004e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0053: Unknown result type (might be due to invalid IL or missing references)
			if (!((Object)(object)target == (Object)null))
			{
				Vector3 val = ((Component)target).transform.position - ((Component)this).transform.position;
				val.y = 0f;
				if (!(((Vector3)(ref val)).sqrMagnitude < 1E-06f))
				{
					((Component)this).transform.rotation = Quaternion.LookRotation(((Vector3)(ref val)).normalized, Vector3.up);
				}
			}
		}

		private float WolfPace()
		{
			Mob component = ((Component)this).GetComponent<Mob>();
			if ((Object)(object)component != (Object)null && (Object)(object)component.mobType != (Object)null && component.mobType.speed > 0.5f)
			{
				return component.mobType.speed;
			}
			return 5.5f;
		}

		private void StopAgent(NavMeshAgent agent)
		{
			navSynced = false;
			if ((Object)(object)agent == (Object)null || !((Behaviour)agent).isActiveAndEnabled || !agent.isOnNavMesh)
			{
				return;
			}