Decompiled source of BaseqsEnemies v0.2.0
plugins/MuckBaseqsEnemies.dll
Decompiled a day ago
The result has been truncated due to the large size, download it to view full contents!
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; }