Please disclose if any significant portion of your mod was created using AI tools by adding the 'AI Generated' category. Failing to do so may result in the mod being removed from Thunderstore.
Decompiled source of TheDeadRemain v0.1.1
TheDeadRemain.dll
Decompiled 14 hours 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.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using System.Text; using BepInEx; using BepInEx.Configuration; using BepInEx.Logging; using HarmonyLib; using UnityEngine; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: TargetFramework(".NETFramework,Version=v4.7.2", FrameworkDisplayName = ".NET Framework 4.7.2")] [assembly: AssemblyVersion("0.0.0.0")] namespace TheDeadRemain; public sealed class CarcassHandle : IEquatable<CarcassHandle> { public ZDOID Id { get; private set; } internal CarcassHandle(ZDOID id) { //IL_0007: Unknown result type (might be due to invalid IL or missing references) Id = id; } public bool Equals(CarcassHandle other) { //IL_0004: Unknown result type (might be due to invalid IL or missing references) //IL_000a: Unknown result type (might be due to invalid IL or missing references) if ((object)other != null) { return Id == other.Id; } return false; } public override bool Equals(object obj) { return Equals(obj as CarcassHandle); } public override int GetHashCode() { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0006: Unknown result type (might be due to invalid IL or missing references) return ((object)Id/*cast due to .constrained prefix*/).GetHashCode(); } public static bool operator ==(CarcassHandle a, CarcassHandle b) { //IL_000f: Unknown result type (might be due to invalid IL or missing references) //IL_0015: Unknown result type (might be due to invalid IL or missing references) if ((object)a == b) { return true; } if ((object)a == null || (object)b == null) { return false; } return a.Id == b.Id; } public static bool operator !=(CarcassHandle a, CarcassHandle b) { return !(a == b); } public override string ToString() { //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_000b: Unknown result type (might be due to invalid IL or missing references) return "Carcass " + ((object)Id/*cast due to .constrained prefix*/).ToString(); } } public static class DeadRemainApi { public const int ApiVersion = 1; public const int StageFresh = 0; public const int StagePicked = 1; public const int StageBones = 2; public const int StageGone = 3; private const float DeathMatchSeconds = 10f; private static readonly List<ZDO> ZdoBuffer = new List<ZDO>(); private static bool Ready { get { if (TdrConfig.Enabled != null && TdrConfig.Enabled.Value && (Object)(object)ZNet.instance != (Object)null && ZDOMan.instance != null) { return (Object)(object)ZNetScene.instance != (Object)null; } return false; } } public static event Action<CarcassHandle> CarcassCreated; public static event Action<CarcassHandle> CarcassStageChanged; public static CarcassHandle RegisterCarcass(Character c) { //IL_0021: Unknown result type (might be due to invalid IL or missing references) //IL_0029: Unknown result type (might be due to invalid IL or missing references) //IL_00a3: Unknown result type (might be due to invalid IL or missing references) //IL_00ae: 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) try { if (!Ready || c == null) { return null; } if (CarcassFactory.TryGetRecent(c, out var id) && ZDOMan.instance.GetZDO(id) != null) { return new CarcassHandle(id); } if ((Object)(object)c == (Object)null) { return null; } ZNetView val = Reflect.NView(c); if ((Object)(object)val == (Object)null || !val.IsValid() || !val.IsOwner()) { return FindDeathCarcass(c, val); } if (c.IsDead() || c.GetHealth() <= 0f) { return null; } string reason; Carcass carcass = CarcassFactory.CreateFromPrefab(Utils.GetPrefabName(((Component)c).gameObject), ((Component)c).transform.position, ((Component)c).transform.rotation, c, out reason); if ((Object)(object)carcass == (Object)null) { Plugin.Verbose("The Dead Remain API: RegisterCarcass(" + ((Object)c).name + ") refused: " + reason); } return ((Object)(object)carcass != (Object)null) ? new CarcassHandle(carcass.Id) : null; } catch (Exception ex) { Plugin.LogOnce("api-register", "The Dead Remain API: RegisterCarcass threw (" + ex.Message + ")."); return null; } } public static CarcassHandle RegisterCarcass(string creaturePrefab, Vector3 pos, Quaternion rot) { //IL_000c: Unknown result type (might be due to invalid IL or missing references) //IL_000d: Unknown result type (might be due to invalid IL or missing references) //IL_0043: Unknown result type (might be due to invalid IL or missing references) try { if (!Ready) { return null; } string reason; Carcass carcass = CarcassFactory.CreateFromPrefab(creaturePrefab, pos, rot, null, out reason); if ((Object)(object)carcass == (Object)null) { Plugin.Verbose("The Dead Remain API: RegisterCarcass(" + creaturePrefab + ") refused: " + reason); } return ((Object)(object)carcass != (Object)null) ? new CarcassHandle(carcass.Id) : null; } catch (Exception ex) { Plugin.LogOnce("api-register-prefab", "The Dead Remain API: RegisterCarcass(prefab) threw (" + ex.Message + ")."); return null; } } public static List<CarcassHandle> GetCarcassesInRange(Vector3 p, float r) { //IL_0024: Unknown result type (might be due to invalid IL or missing references) //IL_0058: Unknown result type (might be due to invalid IL or missing references) List<CarcassHandle> list = new List<CarcassHandle>(); try { if (!Ready) { return list; } double nowDay = GameTime.NowDay; ZdoBuffer.Clear(); CarcassRegistry.CarcassZdosInRange(p, r, ZdoBuffer); for (int i = 0; i < ZdoBuffer.Count; i++) { if (!(CarcassRegistry.PredictedProgress(ZdoBuffer[i], nowDay) >= 3f)) { list.Add(new CarcassHandle(ZdoBuffer[i].m_uid)); } } ZdoBuffer.Clear(); } catch (Exception ex) { Plugin.LogOnce("api-range", "The Dead Remain API: GetCarcassesInRange threw (" + ex.Message + ")."); } return list; } public static CarcassHandle FindNearestCarcass(Vector3 p, float r) { //IL_001e: Unknown result type (might be due to invalid IL or missing references) //IL_0056: Unknown result type (might be due to invalid IL or missing references) //IL_005b: Unknown result type (might be due to invalid IL or missing references) //IL_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_009c: Unknown result type (might be due to invalid IL or missing references) try { if (!Ready) { return null; } double nowDay = GameTime.NowDay; ZdoBuffer.Clear(); CarcassRegistry.CarcassZdosInRange(p, r, ZdoBuffer); ZDO val = null; float num = float.MaxValue; for (int i = 0; i < ZdoBuffer.Count; i++) { ZDO val2 = ZdoBuffer[i]; if (!(CarcassRegistry.PredictedProgress(val2, nowDay) >= 3f)) { Vector3 val3 = CarcassRegistry.CenterOf(val2) - p; float sqrMagnitude = ((Vector3)(ref val3)).sqrMagnitude; if (!(sqrMagnitude >= num)) { num = sqrMagnitude; val = val2; } } } ZdoBuffer.Clear(); return (val != null) ? new CarcassHandle(val.m_uid) : null; } catch (Exception ex) { Plugin.LogOnce("api-nearest", "The Dead Remain API: FindNearestCarcass threw (" + ex.Message + ")."); return null; } } public static int GetStage(CarcassHandle h) { float num = ProgressOf(h); if (!(num < 0f)) { return Mathf.Min(3, (int)Mathf.Floor(num)); } return 3; } public static float GetScentStrength(CarcassHandle h) { float num = ProgressOf(h); if (num < 0f || num >= 2f) { return 0f; } if (num < 1f) { return Mathf.Lerp(1f, 0.6f, num); } return Mathf.Lerp(0.5f, 0.2f, num - 1f); } public static bool IsFeedingSlotFree(CarcassHandle h) { //IL_0015: Unknown result type (might be due to invalid IL or missing references) try { if (!Ready || h == null) { return false; } if (CarcassRegistry.TryGet(h.Id, out var carcass)) { return FeedingSlots.IsSlotFree(carcass); } float num = ProgressOf(h); return num >= 0f && num < 2f; } catch (Exception ex) { Plugin.LogOnce("api-slot", "The Dead Remain API: IsFeedingSlotFree threw (" + ex.Message + ")."); return false; } } public static bool ClaimFeedingSlot(CarcassHandle h, Character c) { //IL_001e: Unknown result type (might be due to invalid IL or missing references) try { if (!Ready || h == null || (Object)(object)c == (Object)null) { return false; } Carcass carcass; return CarcassRegistry.TryGet(h.Id, out carcass) && FeedingSlots.Claim(carcass, c); } catch (Exception ex) { Plugin.LogOnce("api-claim", "The Dead Remain API: ClaimFeedingSlot threw (" + ex.Message + ")."); return false; } } public static void ReleaseFeedingSlot(CarcassHandle h, Character c) { //IL_0022: Unknown result type (might be due to invalid IL or missing references) try { if (!(h == null) && !((Object)(object)c == (Object)null) && !((Object)(object)ZNet.instance == (Object)null)) { FeedingSlots.Release(h.Id, c); } } catch (Exception ex) { Plugin.LogOnce("api-release", "The Dead Remain API: ReleaseFeedingSlot threw (" + ex.Message + ")."); } } public static bool TryGetCarcassCenter(CarcassHandle h, out Vector3 center) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_0023: Unknown result type (might be due to invalid IL or missing references) //IL_0053: Unknown result type (might be due to invalid IL or missing references) //IL_003f: Unknown result type (might be due to invalid IL or missing references) //IL_0044: Unknown result type (might be due to invalid IL or missing references) //IL_0085: Unknown result type (might be due to invalid IL or missing references) //IL_008a: Unknown result type (might be due to invalid IL or missing references) center = Vector3.zero; try { if (!Ready || h == null) { return false; } if (CarcassRegistry.TryGet(h.Id, out var carcass)) { if (carcass.Removing) { return false; } center = carcass.Center; return true; } ZDO zDO = ZDOMan.instance.GetZDO(h.Id); if (zDO == null || !CarcassRegistry.IsCarcassZdo(zDO)) { return false; } if (CarcassRegistry.PredictedProgress(zDO, GameTime.NowDay) >= 3f) { return false; } center = CarcassRegistry.CenterOf(zDO); return true; } catch (Exception ex) { Plugin.LogOnce("api-center", "The Dead Remain API: TryGetCarcassCenter threw (" + ex.Message + ")."); return false; } } public static bool TieToCarcass(GameObject go, Vector3 near, float radius) { //IL_0015: Unknown result type (might be due to invalid IL or missing references) try { if (!Ready || (Object)(object)go == (Object)null) { return false; } return TiedObjects.Tie(go, near, radius); } catch (Exception ex) { Plugin.LogOnce("api-tie", "The Dead Remain API: TieToCarcass threw (" + ex.Message + ")."); return false; } } public static bool TieToCarcassOf(GameObject go, GameObject source) { try { if (!Ready || (Object)(object)go == (Object)null || (Object)(object)source == (Object)null) { return false; } return TiedObjects.TieToSource(go, source); } catch (Exception ex) { Plugin.LogOnce("api-tie-of", "The Dead Remain API: TieToCarcassOf threw (" + ex.Message + ")."); return false; } } private static CarcassHandle FindDeathCarcass(Character c, ZNetView view) { //IL_0012: Unknown result type (might be due to invalid IL or missing references) //IL_0017: Unknown result type (might be due to invalid IL or missing references) //IL_0059: Unknown result type (might be due to invalid IL or missing references) //IL_0123: 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_00dc: Unknown result type (might be due to invalid IL or missing references) //IL_00e1: Unknown result type (might be due to invalid IL or missing references) string prefabName = Utils.GetPrefabName(((Component)c).gameObject); Vector3 position = ((Component)c).transform.position; long num = (((Object)(object)view != (Object)null && view.IsValid()) ? view.GetZDO().GetOwner() : 0); double nowDay = GameTime.NowDay; double num2 = GameTime.RealSecondsToDays(10.0); ZdoBuffer.Clear(); CarcassRegistry.CarcassZdosInRange(position, Mathf.Max(4f, CarcassFactory.SizeOf(c)), ZdoBuffer); ZDO val = null; float num3 = float.MaxValue; for (int i = 0; i < ZdoBuffer.Count; i++) { ZDO val2 = ZdoBuffer[i]; if (!(val2.GetString(ZdoKeys.Species, "") != prefabName) && (num == 0L || val2.GetOwner() == num) && !(Math.Abs(nowDay - (double)val2.GetFloat(ZdoKeys.DeathDay, -1000f)) > num2)) { Vector3 val3 = CarcassRegistry.CenterOf(val2) - position; float sqrMagnitude = ((Vector3)(ref val3)).sqrMagnitude; if (!(sqrMagnitude >= num3)) { num3 = sqrMagnitude; val = val2; } } } ZdoBuffer.Clear(); if (val == null) { return null; } return new CarcassHandle(val.m_uid); } private static float ProgressOf(CarcassHandle h) { //IL_001c: Unknown result type (might be due to invalid IL or missing references) //IL_0048: Unknown result type (might be due to invalid IL or missing references) try { if (!Ready || h == null) { return -1f; } if (CarcassRegistry.TryGet(h.Id, out var carcass)) { return carcass.Removing ? (-1f) : carcass.Progress; } ZDO zDO = ZDOMan.instance.GetZDO(h.Id); if (zDO == null || !CarcassRegistry.IsCarcassZdo(zDO)) { return -1f; } float num = CarcassRegistry.PredictedProgress(zDO, GameTime.NowDay); return (num >= 3f) ? (-1f) : num; } catch (Exception ex) { Plugin.LogOnce("api-progress", "The Dead Remain API: reading a carcass threw (" + ex.Message + ")."); return -1f; } } internal static void RaiseCreated(ZDOID id) { //IL_0005: Unknown result type (might be due to invalid IL or missing references) Raise(DeadRemainApi.CarcassCreated, id, "CarcassCreated"); } internal static void RaiseStageChanged(ZDOID id) { //IL_0005: Unknown result type (might be due to invalid IL or missing references) Raise(DeadRemainApi.CarcassStageChanged, id, "CarcassStageChanged"); } private static void Raise(Action<CarcassHandle> handlers, ZDOID id, string name) { //IL_0004: Unknown result type (might be due to invalid IL or missing references) if (handlers == null) { return; } CarcassHandle obj = new CarcassHandle(id); Delegate[] invocationList = handlers.GetInvocationList(); for (int i = 0; i < invocationList.Length; i++) { try { ((Action<CarcassHandle>)invocationList[i])(obj); } catch (Exception ex) { Plugin.LogOnce("api-event-" + name + "-" + invocationList[i].Method.Name, "The Dead Remain API: a " + name + " handler (" + invocationList[i].Method.DeclaringType?.ToString() + "." + invocationList[i].Method.Name + ") threw (" + ex.Message + ")."); } } } } internal enum BirdState { Waiting, Arriving, Circling, Descending, Feeding, Ascending, Scatter, Leaving, Gone } internal sealed class Bird { private const float Gravity = 9.81f; private const float CruiseSpeed = 8f; private const float ArriveSpeed = 11f; private const float GlideSpeed = 9.5f; private const float ApproachSpeed = 6.5f; private const float TouchdownSpeed = 1f; private const float ScatterSpeed = 10f; private const float LeaveSpeed = 11f; private const float ApproachRadius = 4.5f; private const float ApproachAngle = 0.75f; private const float ApproachHeight = 2.2f; private const float Clearance = 6f; private const float TreeAllowance = 20f; private const float MaxArriveDistance = 400f; private const float FlarePitch = 38f; private const float PeckSeconds = 0.38f; private const float HopSeconds = 0.32f; private const float HopHeight = 0.18f; private const float NoGround = -10000f; internal BirdState State; internal BirdView View; internal float Delay; internal Vector3 Pos; internal float Yaw; private float yawRate; private float speed; private float vy; private float pitch; private float roll; private float stateTime; private float groundY = -10000f; private float nextGround; private readonly float radiusOffset; private readonly float heightOffset; private readonly float speedFactor; private readonly float bobPhase; private readonly float bobRate; private readonly float breathePhase; private readonly float breatheRate; private readonly float noiseSeed; private readonly float sizeJitter; private readonly float animJitter; private bool flapping = true; private float flapLeft; private float animSpeed = 1f; private float nextDescent; private int segment; private float pathU; private float startSpeed; private Vector3 pathCenter; private float a0; private float aA; private float r0; private float rA; private float y0; private float yA; private Vector3 b0; private Vector3 b1; private Vector3 b2; private Vector3 b3; private float flare; internal Vector3 Spot; private float feedLeft; private float nextLook; private float lookYaw; private float nextPeck; private float peckTime = -1f; private float hopTime = -1f; private Vector3 hopFrom; private Vector3 hopTo; private Vector3 target; private float scatterWide; private Vector3 leaveDir; private float leaveY; internal bool IsDown { get { if (State != BirdState.Descending) { return State == BirdState.Feeding; } return true; } } internal Bird(Flock flock) { radiusOffset = flock.Range(-4f, 4f); heightOffset = flock.Range(-4f, 4f); speedFactor = flock.Range(0.9f, 1.1f); bobPhase = flock.Range(0f, 6.283f); bobRate = 6.283f / flock.Range(9f, 16f); breathePhase = flock.Range(0f, 6.283f); breatheRate = 6.283f / flock.Range(11f, 19f); noiseSeed = flock.Range(0f, 100f); sizeJitter = flock.Range(0.92f, 1.08f); animJitter = flock.Range(0.9f, 1.12f); flapLeft = flock.Range(0.2f, 2f); } private void SetState(BirdState state) { State = state; stateTime = 0f; } internal void PlaceOnCircle(Flock flock, float angle) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_0010: Unknown result type (might be due to invalid IL or missing references) //IL_0026: Unknown result type (might be due to invalid IL or missing references) //IL_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) Vector3 circleCentre = flock.CircleCentre; float num = CircleRadius(flock); Pos = new Vector3(circleCentre.x + Mathf.Cos(angle) * num, CircleY(flock), circleCentre.z + Mathf.Sin(angle) * num); Yaw = TangentYaw(flock, angle); speed = 8f * speedFactor; vy = 0f; yawRate = (float)(-flock.Dir) * (speed / num) * 57.29578f; SetState(BirdState.Circling); nextDescent = flock.Range(2f, 20f); } internal bool PlaceLanded(Flock flock, float angle) { //IL_0008: Unknown result type (might be due to invalid IL or missing references) //IL_000d: Unknown result type (might be due to invalid IL or missing references) //IL_0010: Unknown result type (might be due to invalid IL or missing references) //IL_001f: Unknown result type (might be due to invalid IL or missing references) //IL_0025: Unknown result type (might be due to invalid IL or missing references) //IL_0034: Unknown result type (might be due to invalid IL or missing references) //IL_0045: Unknown result type (might be due to invalid IL or missing references) //IL_0046: Unknown result type (might be due to invalid IL or missing references) //IL_004c: Unknown result type (might be due to invalid IL or missing references) //IL_004d: Unknown result type (might be due to invalid IL or missing references) //IL_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) float num = flock.LandingRadius(); Vector3 center = flock.Center; if (!flock.FindSpot(this, new Vector3(center.x + Mathf.Cos(angle) * num, center.y, center.z + Mathf.Sin(angle) * num), out var spot)) { return false; } Spot = spot; Pos = spot; Yaw = YawTo(Spot, center) + flock.Range(-60f, 60f); Land(flock); feedLeft = flock.Range(2f, 15f); return true; } internal void BeginArriving(Flock flock) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_0030: Unknown result type (might be due to invalid IL or missing references) //IL_0050: Unknown result type (might be due to invalid IL or missing references) //IL_0054: Unknown result type (might be due to invalid IL or missing references) //IL_0059: Unknown result type (might be due to invalid IL or missing references) //IL_005f: Unknown result type (might be due to invalid IL or missing references) //IL_00d7: Unknown result type (might be due to invalid IL or missing references) //IL_00dc: Unknown result type (might be due to invalid IL or missing references) //IL_006b: Unknown result type (might be due to invalid IL or missing references) //IL_0075: Unknown result type (might be due to invalid IL or missing references) //IL_007a: Unknown result type (might be due to invalid IL or missing references) //IL_007c: 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_0099: Unknown result type (might be due to invalid IL or missing references) //IL_0086: Unknown result type (might be due to invalid IL or missing references) //IL_0088: Unknown result type (might be due to invalid IL or missing references) //IL_00bc: Unknown result type (might be due to invalid IL or missing references) //IL_00cb: Unknown result type (might be due to invalid IL or missing references) //IL_00d0: Unknown result type (might be due to invalid IL or missing references) Vector3 center = flock.Center; float num = flock.ArrivalBearing + flock.Range(-0.7f, 0.7f); float distance = flock.Range(90f, 120f); float height = center.y + flock.BaseHeight + flock.Range(6f, 16f); Pos = ArrivalPoint(center, num, distance, height); if (!BirdFlocks.Unseen(Pos)) { Vector3 val = ArrivalPoint(center, num + (float)Math.PI, distance, height); if (BirdFlocks.Unseen(val)) { Pos = val; } else { float num2 = DistancePastView(center, num, distance); float num3 = DistancePastView(center, num + (float)Math.PI, distance); if (num3 < num2) { num += (float)Math.PI; num2 = num3; } Pos = ArrivalPoint(center, num, Mathf.Min(num2, 400f), height); } } Yaw = YawTo(Pos, center); speed = 11f * speedFactor; vy = 0f; yawRate = 0f; SetState(BirdState.Arriving); } private static Vector3 ArrivalPoint(Vector3 c, float bearing, float distance, float height) { //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_0012: Unknown result type (might be due to invalid IL or missing references) //IL_0028: Unknown result type (might be due to invalid IL or missing references) //IL_002e: Unknown result type (might be due to invalid IL or missing references) //IL_004a: Unknown result type (might be due to invalid IL or missing references) Vector3 val = default(Vector3); ((Vector3)(ref val))..ctor(c.x + Mathf.Cos(bearing) * distance, height, c.z + Mathf.Sin(bearing) * distance); val.y = Mathf.Max(val.y, SolidHeight(val) + 6f + 8f); return val; } private static float DistancePastView(Vector3 c, float bearing, float distance) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0005: Unknown result type (might be due to invalid IL or missing references) //IL_000b: 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) Vector3 cameraPos = BirdFlocks.CameraPos; float num = cameraPos.x - c.x; float num2 = cameraPos.z - c.z; float num3 = num * Mathf.Cos(bearing) + num2 * Mathf.Sin(bearing); float num4 = num * num + num2 * num2 - num3 * num3; float unseenDistance = BirdFlocks.UnseenDistance; if (num4 >= unseenDistance * unseenDistance) { return distance; } return Mathf.Max(distance, num3 + Mathf.Sqrt(unseenDistance * unseenDistance - num4) + 1f); } internal void Update(Flock flock, float dt) { stateTime += dt; switch (State) { default: return; case BirdState.Waiting: Delay -= dt; if (Delay <= 0f) { BeginArriving(flock); } return; case BirdState.Arriving: UpdateArriving(flock, dt); break; case BirdState.Circling: UpdateCircling(flock, dt); break; case BirdState.Descending: UpdateDescending(flock, dt); break; case BirdState.Feeding: UpdateFeeding(flock, dt); return; case BirdState.Ascending: UpdateAscending(flock, dt); break; case BirdState.Scatter: UpdateScatter(flock, dt); break; case BirdState.Leaving: UpdateLeaving(flock, dt); break; } if (State != BirdState.Feeding) { Orient(flock, dt); } } internal void ApplyView(Flock flock) { //IL_0106: 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_003e: Unknown result type (might be due to invalid IL or missing references) //IL_0043: Unknown result type (might be due to invalid IL or missing references) //IL_0064: 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_0070: Unknown result type (might be due to invalid IL or missing references) //IL_0075: Unknown result type (might be due to invalid IL or missing references) //IL_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_0093: 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_00e3: Unknown result type (might be due to invalid IL or missing references) if (View == null) { return; } View.SetScale(TdrConfig.BirdScale.Value * sizeJitter); if (State == BirdState.Feeding) { View.SetLanded(value: true); Vector3 val = Spot; if (hopTime >= 0f) { float num = Mathf.Clamp01(hopTime / 0.32f); val = Vector3.Lerp(hopFrom, hopTo, num) + Vector3.up * (0.72f * num * (1f - num)); } float num2 = ((peckTime >= 0f) ? (Mathf.Sin(Mathf.Clamp01(peckTime / 0.38f) * (float)Math.PI) * 30f) : 0f); View.T.SetPositionAndRotation(val, Quaternion.Euler(num2, Yaw, 0f)); } else { View.SetLanded(value: false); View.T.SetPositionAndRotation(Pos, Quaternion.Euler(pitch, Yaw, roll)); View.SetFlapping(flapping); View.SetAnimSpeed(animSpeed * animJitter); } } private void UpdateArriving(Flock flock, float dt) { //IL_0044: Unknown result type (might be due to invalid IL or missing references) //IL_004a: Unknown result type (might be due to invalid IL or missing references) //IL_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) FlyCircle(flock, 11f * speedFactor, 3f, 3f, 3f, dt); Flap(flock, vy > 1.2f, dt); animSpeed = 1f; Vector3 val = Pos - flock.CircleCentre; val.y = 0f; if (Mathf.Abs(((Vector3)(ref val)).magnitude - CircleRadius(flock)) < 5f && Mathf.Abs(Pos.y - FlightY(flock)) < 5f) { SetState(BirdState.Circling); nextDescent = flock.Range(6f, 20f); } } private void UpdateCircling(Flock flock, float dt) { FlyCircle(flock, 8f * speedFactor, 3f, 3f, 2.5f, dt); Flap(flock, vy > 1.2f, dt); animSpeed = 1f; nextDescent -= dt; if (!(nextDescent > 0f) && (!flock.MayDescend() || !TryStartDescent(flock))) { nextDescent = flock.Range(3f, 9f); } } private void UpdateAscending(Flock flock, float dt) { float accel = ((stateTime < 0.4f) ? 2f : 3.5f); FlyCircle(flock, 8f * speedFactor, accel, 4.5f, 1.5f, dt); Flap(flock, force: true, dt); animSpeed = ((stateTime < 1.5f) ? 1.25f : 1f); if (stateTime > 2f && Mathf.Abs(Pos.y - FlightY(flock)) < 2.5f) { SetState(BirdState.Circling); animSpeed = 1f; nextDescent = flock.Range(6f, 20f); } } private void FlyCircle(Flock flock, float cruise, float accel, float climbMax, float sinkMax, float dt) { //IL_0009: Unknown result type (might be due to invalid IL or missing references) //IL_000e: Unknown result type (might be due to invalid IL or missing references) //IL_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_0026: Unknown result type (might be due to invalid IL or missing references) //IL_002b: Unknown result type (might be due to invalid IL or missing references) //IL_0051: 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_004a: 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_007f: Unknown result type (might be due to invalid IL or missing references) //IL_008c: Unknown result type (might be due to invalid IL or missing references) //IL_0093: Unknown result type (might be due to invalid IL or missing references) //IL_0064: Unknown result type (might be due to invalid IL or missing references) //IL_0070: Unknown result type (might be due to invalid IL or missing references) //IL_0078: Unknown result type (might be due to invalid IL or missing references) //IL_00b3: Unknown result type (might be due to invalid IL or missing references) //IL_00b7: Unknown result type (might be due to invalid IL or missing references) //IL_00bc: Unknown result type (might be due to invalid IL or missing references) //IL_00c1: Unknown result type (might be due to invalid IL or missing references) //IL_0107: Unknown result type (might be due to invalid IL or missing references) SampleGround(dt); Vector3 circleCentre = flock.CircleCentre; float num = CircleRadius(flock); float targetY = FlightY(flock); Vector3 val = Pos - circleCentre; val.y = 0f; float magnitude = ((Vector3)(ref val)).magnitude; Vector3 val2 = ((magnitude > 0.01f) ? (val / magnitude) : Vector3.right); Vector3 val3 = ((flock.Dir > 0) ? new Vector3(0f - val2.z, 0f, val2.x) : new Vector3(val2.z, 0f, 0f - val2.x)); float num2 = Mathf.Clamp((magnitude - num) / 6f, -1.5f, 1.5f); Vector3 desired = val3 - val2 * num2; float num3 = 1f - Mathf.Clamp01(Mathf.Abs(magnitude - num) / 12f); float feedForward = (float)(-flock.Dir) * (speed / Mathf.Max(magnitude, 3f)) * 57.29578f * num3; SteerHeading(desired, feedForward, dt); speed = Mathf.MoveTowards(speed, cruise, accel * dt); SteerClimb(targetY, climbMax, sinkMax, dt); Integrate(dt); } private float CircleRadius(Flock flock) { return Mathf.Max(flock.BaseRadius + radiusOffset + 1.5f * Mathf.Sin(flock.Clock * breatheRate + breathePhase) + flock.AlarmBlend * (flock.BaseRadius * 0.6f + 4f), 3f + flock.Size); } private float CircleY(Flock flock) { return flock.Center.y + flock.BaseHeight + heightOffset + 1.8f * Mathf.Sin(flock.Clock * bobRate + bobPhase) + flock.AlarmBlend * 10f; } private float FlightY(Flock flock) { return Mathf.Max(CircleY(flock), groundY + 6f); } private static float TangentYaw(Flock flock, float angle) { //IL_003a: Unknown result type (might be due to invalid IL or missing references) //IL_0046: Unknown result type (might be due to invalid IL or missing references) //IL_004c: Unknown result type (might be due to invalid IL or missing references) //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_0033: Unknown result type (might be due to invalid IL or missing references) //IL_0051: Unknown result type (might be due to invalid IL or missing references) //IL_0052: Unknown result type (might be due to invalid IL or missing references) //IL_0058: Unknown result type (might be due to invalid IL or missing references) Vector3 val = default(Vector3); ((Vector3)(ref val))..ctor(Mathf.Cos(angle), 0f, Mathf.Sin(angle)); Vector3 val2 = ((flock.Dir > 0) ? new Vector3(0f - val.z, 0f, val.x) : new Vector3(val.z, 0f, 0f - val.x)); return Mathf.Atan2(val2.x, val2.z) * 57.29578f; } private bool TryStartDescent(Flock flock) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_0008: Unknown result type (might be due to invalid IL or missing references) //IL_000d: Unknown result type (might be due to invalid IL or missing references) //IL_000e: Unknown result type (might be due to invalid IL or missing references) //IL_0013: Unknown result type (might be due to invalid IL or missing references) //IL_0032: 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_005d: Unknown result type (might be due to invalid IL or missing references) //IL_00cc: Unknown result type (might be due to invalid IL or missing references) //IL_00dd: 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_00fb: Unknown result type (might be due to invalid IL or missing references) //IL_010a: Unknown result type (might be due to invalid IL or missing references) //IL_010b: Unknown result type (might be due to invalid IL or missing references) //IL_014b: Unknown result type (might be due to invalid IL or missing references) //IL_015f: Unknown result type (might be due to invalid IL or missing references) //IL_0178: Unknown result type (might be due to invalid IL or missing references) //IL_017e: Unknown result type (might be due to invalid IL or missing references) //IL_019d: Unknown result type (might be due to invalid IL or missing references) //IL_01d0: Unknown result type (might be due to invalid IL or missing references) //IL_01d2: Unknown result type (might be due to invalid IL or missing references) //IL_01dd: Unknown result type (might be due to invalid IL or missing references) //IL_01e2: Unknown result type (might be due to invalid IL or missing references) //IL_01e7: Unknown result type (might be due to invalid IL or missing references) //IL_01ef: Unknown result type (might be due to invalid IL or missing references) //IL_01f4: Unknown result type (might be due to invalid IL or missing references) //IL_01a8: 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_0249: Unknown result type (might be due to invalid IL or missing references) //IL_0250: Unknown result type (might be due to invalid IL or missing references) //IL_0221: Unknown result type (might be due to invalid IL or missing references) //IL_022d: Unknown result type (might be due to invalid IL or missing references) //IL_0235: Unknown result type (might be due to invalid IL or missing references) //IL_01be: Unknown result type (might be due to invalid IL or missing references) //IL_0255: Unknown result type (might be due to invalid IL or missing references) //IL_0257: Unknown result type (might be due to invalid IL or missing references) //IL_0259: Unknown result type (might be due to invalid IL or missing references) //IL_025b: Unknown result type (might be due to invalid IL or missing references) //IL_0260: Unknown result type (might be due to invalid IL or missing references) //IL_0282: Unknown result type (might be due to invalid IL or missing references) //IL_0284: Unknown result type (might be due to invalid IL or missing references) //IL_028a: Unknown result type (might be due to invalid IL or missing references) //IL_028c: Unknown result type (might be due to invalid IL or missing references) //IL_0296: Unknown result type (might be due to invalid IL or missing references) //IL_029b: Unknown result type (might be due to invalid IL or missing references) //IL_02a0: Unknown result type (might be due to invalid IL or missing references) //IL_02a5: Unknown result type (might be due to invalid IL or missing references) //IL_02a8: Unknown result type (might be due to invalid IL or missing references) //IL_02ad: Unknown result type (might be due to invalid IL or missing references) //IL_02b2: Unknown result type (might be due to invalid IL or missing references) //IL_02d4: Unknown result type (might be due to invalid IL or missing references) //IL_02ce: Unknown result type (might be due to invalid IL or missing references) //IL_02d9: Unknown result type (might be due to invalid IL or missing references) //IL_02dc: Unknown result type (might be due to invalid IL or missing references) //IL_02de: Unknown result type (might be due to invalid IL or missing references) //IL_02e8: Unknown result type (might be due to invalid IL or missing references) //IL_02ed: Unknown result type (might be due to invalid IL or missing references) //IL_02f2: Unknown result type (might be due to invalid IL or missing references) //IL_02fc: Unknown result type (might be due to invalid IL or missing references) //IL_0301: Unknown result type (might be due to invalid IL or missing references) //IL_0306: Unknown result type (might be due to invalid IL or missing references) //IL_030c: Unknown result type (might be due to invalid IL or missing references) //IL_030e: Unknown result type (might be due to invalid IL or missing references) //IL_0314: Unknown result type (might be due to invalid IL or missing references) //IL_0316: Unknown result type (might be due to invalid IL or missing references) Vector3 center = flock.Center; Vector3 val = Pos - center; val.y = 0f; float num = Mathf.Max(((Vector3)(ref val)).magnitude, 3f); float num2 = Mathf.Atan2(val.z, val.x); float num3 = flock.Dir; float num4 = Mathf.Max(0f, Pos.y - (center.y + 2.2f)); float num5 = Mathf.Clamp((float)Math.PI * (0.8f + num4 / 22f), (float)Math.PI * 3f / 4f, 6.9115043f); Vector3 near = default(Vector3); Vector3 near2 = default(Vector3); Vector3 val4 = default(Vector3); for (int i = 0; i < 6; i++) { float num6 = num5 * flock.Range(0.8f, 1.25f); float num7 = num2 + num3 * (num6 + 0.75f); float num8 = flock.LandingRadius(); ((Vector3)(ref near))..ctor(center.x + Mathf.Cos(num7) * num8, center.y, center.z + Mathf.Sin(num7) * num8); if (flock.FindSpot(this, near, out var spot)) { pathCenter = center; a0 = num2; r0 = num; y0 = Pos.y; aA = num2 + num3 * num6; rA = num8 + 4.5f; yA = spot.y + 2.2f; ((Vector3)(ref near2))..ctor(center.x + Mathf.Cos(aA) * rA, center.y, center.z + Mathf.Sin(aA) * rA); if (flock.GroundAt(near2, out var ground) && ground.y > yA - 1f) { yA = ground.y + 1.5f; } Vector3 val2 = spot - Vector3.up * flock.TouchdownDrop; Vector3 val3 = SpiralPoint(1f); ((Vector3)(ref val4))..ctor(Mathf.Cos(aA), 0f, Mathf.Sin(aA)); Vector3 val5 = ((num3 > 0f) ? new Vector3(0f - val4.z, 0f, val4.x) : new Vector3(val4.z, 0f, 0f - val4.x)); Vector3 val6 = val2 - val3; val6.y = 0f; float num9 = Mathf.Max(((Vector3)(ref val6)).magnitude, 1f); b0 = val3; b1 = val3 + val5 * (num9 * 0.45f); Vector3 val7 = val2 - b1; val7.y = 0f; val7 = ((((Vector3)(ref val7)).sqrMagnitude > 0.0001f) ? ((Vector3)(ref val7)).normalized : val5); b2 = val2 - val7 * (num9 * 0.3f) + Vector3.up * 0.5f; b3 = val2; Spot = spot; segment = 0; pathU = 0f; startSpeed = speed; flare = 0f; SetState(BirdState.Descending); return true; } } return false; } private void UpdateDescending(Flock flock, float dt) { //IL_0077: Unknown result type (might be due to invalid IL or missing references) //IL_007c: Unknown result type (might be due to invalid IL or missing references) //IL_007e: Unknown result type (might be due to invalid IL or missing references) float num; if (segment == 0) { num = Mathf.Lerp(startSpeed, 9.5f, Smooth01(pathU / 0.3f)); num = Mathf.Lerp(num, 6.5f, Smooth01((pathU - 0.7f) / 0.3f)); } else { num = Mathf.Lerp(6.5f, 1f, Smooth01(pathU)); } Vector3 next = AdvancePath(Mathf.Max(num, 0.6f), dt); FollowPath(next, dt); if (segment == 0) { flare = 0f; flapping = false; animSpeed = 1f; if (pathU >= 1f) { segment = 1; pathU = 0f; } } else { flare = Smooth01((pathU - 0.35f) / 0.45f) * (1f - 0.6f * Smooth01((pathU - 0.85f) / 0.15f)); animSpeed = ((flapping = pathU > 0.4f) ? 1.25f : 1f); if (pathU >= 1f) { Land(flock); } } } private Vector3 PathPoint(float u) { //IL_001e: Unknown result type (might be due to invalid IL or missing references) //IL_0023: Unknown result type (might be due to invalid IL or missing references) //IL_0034: Unknown result type (might be due to invalid IL or missing references) //IL_0039: Unknown result type (might be due to invalid IL or missing references) //IL_003e: 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_0064: 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_006e: Unknown result type (might be due to invalid IL or missing references) //IL_000a: Unknown result type (might be due to invalid IL or missing references) if (segment == 0) { return SpiralPoint(u); } float num = 1f - u; return num * num * num * b0 + 3f * num * num * u * b1 + 3f * num * u * u * b2 + u * u * u * b3; } private Vector3 SpiralPoint(float u) { //IL_0067: Unknown result type (might be due to invalid IL or missing references) float num = Smooth01(u); float num2 = Mathf.Lerp(a0, aA, u); float num3 = Mathf.Lerp(r0, rA, num); return new Vector3(pathCenter.x + Mathf.Cos(num2) * num3, Mathf.Lerp(y0, yA, num), pathCenter.z + Mathf.Sin(num2) * num3); } private Vector3 AdvancePath(float metresPerSecond, float dt) { //IL_0030: Unknown result type (might be due to invalid IL or missing references) //IL_0037: Unknown result type (might be due to invalid IL or missing references) //IL_003c: Unknown result type (might be due to invalid IL or missing references) //IL_0041: 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) float num = Mathf.Max(0f, pathU - 0.01f); float num2 = Mathf.Min(1f, pathU + 0.01f); Vector3 val = PathPoint(num2) - PathPoint(num); float num3 = ((Vector3)(ref val)).magnitude / Mathf.Max(num2 - num, 0.0001f); pathU = Mathf.Min(1f, pathU + metresPerSecond * dt / Mathf.Max(num3, 0.05f)); return PathPoint(pathU); } private void FollowPath(Vector3 next, float dt) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_000c: Unknown result type (might be due to invalid IL or missing references) //IL_000e: Unknown result type (might be due to invalid IL or missing references) //IL_000f: Unknown result type (might be due to invalid IL or missing references) //IL_001f: Unknown result type (might be due to invalid IL or missing references) //IL_002a: Unknown result type (might be due to invalid IL or missing references) //IL_006c: Unknown result type (might be due to invalid IL or missing references) //IL_0097: Unknown result type (might be due to invalid IL or missing references) //IL_009d: Unknown result type (might be due to invalid IL or missing references) Vector3 val = next - Pos; Pos = next; if (!(dt <= 1E-05f)) { Vector3 val2 = default(Vector3); ((Vector3)(ref val2))..ctor(val.x, 0f, val.z); float magnitude = ((Vector3)(ref val2)).magnitude; float num = 1f - Mathf.Exp(-10f * dt); speed = Mathf.Lerp(speed, magnitude / dt, num); vy = Mathf.Lerp(vy, val.y / dt, num); if (!(magnitude < 0.0001f)) { float yaw = Yaw; Yaw = Mathf.LerpAngle(Yaw, Mathf.Atan2(val2.x, val2.z) * 57.29578f, num); yawRate = Mathf.Lerp(yawRate, Mathf.DeltaAngle(yaw, Yaw) / dt, 1f - Mathf.Exp(-6f * dt)); } } } private void Land(Flock flock) { //IL_0009: Unknown result type (might be due to invalid IL or missing references) //IL_000e: Unknown result type (might be due to invalid IL or missing references) //IL_006d: Unknown result type (might be due to invalid IL or missing references) //IL_0073: Unknown result type (might be due to invalid IL or missing references) SetState(BirdState.Feeding); Pos = Spot; speed = 0f; vy = 0f; yawRate = 0f; pitch = 0f; roll = 0f; flare = 0f; peckTime = -1f; hopTime = -1f; lookYaw = YawTo(Spot, flock.Center) + flock.Range(-45f, 45f); feedLeft = flock.Range(5f, 15f); nextLook = flock.Range(0.6f, 2f); nextPeck = flock.Range(0.3f, 1.2f); } private void UpdateFeeding(Flock flock, float dt) { //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_0147: Unknown result type (might be due to invalid IL or missing references) //IL_014d: Unknown result type (might be due to invalid IL or missing references) feedLeft -= dt; if (feedLeft <= 0f && hopTime < 0f) { TakeOff(flock, panic: false); SetState(BirdState.Ascending); return; } Yaw = Mathf.MoveTowardsAngle(Yaw, lookYaw, 160f * dt); if (hopTime >= 0f) { hopTime += dt; if (hopTime >= 0.32f) { hopTime = -1f; Spot = hopTo; } } if (peckTime >= 0f) { peckTime += dt; if (peckTime >= 0.38f) { peckTime = -1f; } } else if (hopTime < 0f) { nextPeck -= dt; if (nextPeck <= 0f) { peckTime = 0f; nextPeck = flock.Range(0.4f, 1.8f); } } nextLook -= dt; if (!(nextLook > 0f)) { nextLook = flock.Range(0.8f, 2.6f); lookYaw = YawTo(Spot, flock.Center) + flock.Range(-70f, 70f); if (peckTime < 0f && hopTime < 0f && flock.Range(0f, 1f) < 0.3f) { TryHop(flock); } } } private void TryHop(Flock flock) { //IL_003d: Unknown result type (might be due to invalid IL or missing references) //IL_0042: Unknown result type (might be due to invalid IL or missing references) //IL_0047: Unknown result type (might be due to invalid IL or missing references) //IL_004d: Unknown result type (might be due to invalid IL or missing references) //IL_0052: Unknown result type (might be due to invalid IL or missing references) //IL_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_005a: Unknown result type (might be due to invalid IL or missing references) //IL_005f: Unknown result type (might be due to invalid IL or missing references) //IL_0061: Unknown result type (might be due to invalid IL or missing references) //IL_0064: Unknown result type (might be due to invalid IL or missing references) //IL_008b: 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_00b7: Unknown result type (might be due to invalid IL or missing references) //IL_00bc: Unknown result type (might be due to invalid IL or missing references) //IL_00c2: Unknown result type (might be due to invalid IL or missing references) //IL_00c4: Unknown result type (might be due to invalid IL or missing references) //IL_00d5: 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) float num = flock.Range(0f, 360f); float num2 = flock.Range(0.25f, 0.55f); for (int i = 0; i < 2; i++) { Vector3 val = Quaternion.Euler(0f, num + (float)i * 180f, 0f) * Vector3.forward * num2; Vector3 val2 = Spot + val; float num3 = Utils.DistanceXZ(val2, flock.Center); if (!(num3 < flock.MinLandRadius) && !(num3 > flock.MaxLandRadius + 0.6f) && flock.GroundAt(val2, out var ground) && !(Mathf.Abs(ground.y - Spot.y) > 0.6f)) { hopFrom = Spot; hopTo = ground; hopTime = 0f; lookYaw = Mathf.Atan2(val.x, val.z) * 57.29578f; break; } } } private void TakeOff(Flock flock, bool panic) { //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_0041: Unknown result type (might be due to invalid IL or missing references) //IL_0046: Unknown result type (might be due to invalid IL or missing references) //IL_004b: Unknown result type (might be due to invalid IL or missing references) //IL_000f: Unknown result type (might be due to invalid IL or missing references) //IL_0014: Unknown result type (might be due to invalid IL or missing references) if (hopTime >= 0f) { Spot = hopTo; } hopTime = -1f; peckTime = -1f; Pos = Spot - Vector3.up * flock.TouchdownDrop; speed = (panic ? 1.5f : 0.8f); vy = (panic ? 5f : 3f); yawRate = 0f; roll = 0f; pitch = -20f; flapping = true; flapLeft = flock.Range(1f, 1.6f); groundY = -10000f; nextGround = 0f; } internal void BeginScatter(Flock flock, Vector3 from) { //IL_002a: Unknown result type (might be due to invalid IL or missing references) //IL_002f: Unknown result type (might be due to invalid IL or missing references) //IL_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_003c: Unknown result type (might be due to invalid IL or missing references) //IL_0082: Unknown result type (might be due to invalid IL or missing references) //IL_0087: Unknown result type (might be due to invalid IL or missing references) //IL_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_009c: Unknown result type (might be due to invalid IL or missing references) //IL_0071: Unknown result type (might be due to invalid IL or missing references) //IL_0076: 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_0080: 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_00c2: Unknown result type (might be due to invalid IL or missing references) //IL_00af: Unknown result type (might be due to invalid IL or missing references) //IL_00c7: Unknown result type (might be due to invalid IL or missing references) //IL_00cc: Unknown result type (might be due to invalid IL or missing references) //IL_010e: Unknown result type (might be due to invalid IL or missing references) //IL_010f: Unknown result type (might be due to invalid IL or missing references) //IL_0116: Unknown result type (might be due to invalid IL or missing references) //IL_011b: Unknown result type (might be due to invalid IL or missing references) //IL_0120: Unknown result type (might be due to invalid IL or missing references) //IL_012b: Unknown result type (might be due to invalid IL or missing references) //IL_00db: Unknown result type (might be due to invalid IL or missing references) //IL_00dc: Unknown result type (might be due to invalid IL or missing references) if (State == BirdState.Feeding) { TakeOff(flock, panic: true); } else { vy = Mathf.Max(vy, 2.5f); } Vector3 center = flock.Center; Vector3 val = Pos - center; val.y = 0f; if (((Vector3)(ref val)).sqrMagnitude < 0.01f) { val = Quaternion.Euler(0f, flock.Range(0f, 360f), 0f) * Vector3.forward; } Vector3 val2 = Pos - from; val2.y = 0f; Vector3 val3 = ((Vector3)(ref val)).normalized + ((((Vector3)(ref val2)).sqrMagnitude > 0.01f) ? (((Vector3)(ref val2)).normalized * 0.8f) : Vector3.zero); if (((Vector3)(ref val3)).sqrMagnitude < 0.01f) { val3 = val; } ((Vector3)(ref val3)).Normalize(); scatterWide = flock.BaseRadius * 1.6f + 6f + flock.Range(0f, 6f); target = center + val3 * scatterWide; target.y = center.y + flock.BaseHeight + 10f + heightOffset; flare = 0f; SetState(BirdState.Scatter); } private void UpdateScatter(Flock flock, float dt) { //IL_0009: Unknown result type (might be due to invalid IL or missing references) //IL_000f: Unknown result type (might be due to invalid IL or missing references) //IL_0014: 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_00cd: Unknown result type (might be due to invalid IL or missing references) SampleGround(dt); SteerHeading(target - Pos, 0f, dt); speed = Mathf.MoveTowards(speed, 10f * speedFactor, 6f * dt); SteerClimb(Mathf.Max(target.y, groundY + 6f), 7f, 2f, dt); Integrate(dt); flapping = true; animSpeed = 1.35f; if (stateTime > 7f || (stateTime > 2f && (Pos.y > target.y - 4f || Utils.DistanceXZ(Pos, flock.Center) > scatterWide))) { SetState(BirdState.Circling); animSpeed = 1f; nextDescent = flock.Range(6f, 20f); } } internal void BeginLeaving(Flock flock, float bearing) { //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) if (State == BirdState.Waiting || State == BirdState.Gone) { SetState(BirdState.Gone); return; } if (State == BirdState.Feeding) { TakeOff(flock, panic: false); } float num = bearing + flock.Range(-0.9f, 0.9f); leaveDir = new Vector3(Mathf.Cos(num), 0f, Mathf.Sin(num)); leaveY = flock.Center.y + flock.BaseHeight + flock.Range(25f, 40f); flare = 0f; animSpeed = 1f; SetState(BirdState.Leaving); } internal void Vanish() { SetState(BirdState.Gone); } internal void Rejoin(Flock flock) { if (State == BirdState.Leaving) { SetState(BirdState.Circling); nextDescent = flock.Range(6f, 20f); } } private void UpdateLeaving(Flock flock, float dt) { //IL_0009: Unknown result type (might be due to invalid IL or missing references) SampleGround(dt); SteerHeading(leaveDir, 0f, dt); speed = Mathf.MoveTowards(speed, 11f * speedFactor, 3f * dt); SteerClimb(Mathf.Max(leaveY, groundY + 6f), 4f, 2f, dt); Integrate(dt); Flap(flock, vy > 1.2f || stateTime < 1.5f, dt); if (stateTime > (2f * TdrConfig.BirdsVisibleDistance.Value + 120f) / 11f) { SetState(BirdState.Gone); } } private void SteerHeading(Vector3 desired, float feedForward, float dt) { //IL_001b: Unknown result type (might be due to invalid IL or missing references) //IL_0021: Unknown result type (might be due to invalid IL or missing references) desired.y = 0f; if (!(((Vector3)(ref desired)).sqrMagnitude < 1E-06f)) { float num = Mathf.Atan2(desired.x, desired.z) * 57.29578f; float num2 = Mathf.Lerp(300f, 75f, Mathf.Clamp01(speed / 8f)); float num3 = Mathf.Clamp(feedForward + Mathf.DeltaAngle(Yaw, num) * 2.5f, 0f - num2, num2); yawRate = Mathf.Lerp(yawRate, num3, 1f - Mathf.Exp(-4f * dt)); Yaw = Mathf.Repeat(Yaw + yawRate * dt, 360f); } } private void SteerClimb(float targetY, float climbMax, float sinkMax, float dt) { float num = Mathf.Clamp((targetY - Pos.y) * 0.7f, 0f - sinkMax, climbMax); vy = Mathf.Lerp(vy, num, 1f - Mathf.Exp(-2.5f * dt)); } private void Integrate(float dt) { //IL_000f: 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_003f: Unknown result type (might be due to invalid IL or missing references) //IL_0044: Unknown result type (might be due to invalid IL or missing references) float num = Yaw * ((float)Math.PI / 180f); Pos += new Vector3(Mathf.Sin(num) * speed * dt, vy * dt, Mathf.Cos(num) * speed * dt); } private void SampleGround(float dt) { //IL_0029: Unknown result type (might be due to invalid IL or missing references) nextGround -= dt; if (!(nextGround > 0f)) { nextGround = 0.4f; groundY = SolidHeight(Pos); } } private static float SolidHeight(Vector3 point) { //IL_0012: Unknown result type (might be due to invalid IL or missing references) //IL_002f: Unknown result type (might be due to invalid IL or missing references) //IL_0035: Unknown result type (might be due to invalid IL or missing references) float result = default(float); if ((Object)(object)ZoneSystem.instance != (Object)null && ZoneSystem.instance.GetSolidHeight(point, ref result, 1000)) { return result; } if (WorldGenerator.instance != null) { return WorldGenerator.instance.GetHeight(point.x, point.z) + 20f; } return -10000f; } private void Flap(Flock flock, bool force, float dt) { flapLeft -= dt; if (force) { flapping = true; if (flapLeft < 0.3f) { flapLeft = 0.3f; } } else if (!(flapLeft > 0f)) { flapping = !flapping; flapLeft = (flapping ? flock.Kind.FlapSeconds : flock.Kind.SailSeconds) * flock.Range(0.75f, 1.3f); } } private void Orient(Flock flock, float dt) { float num = (0f - Mathf.Atan(speed * yawRate * ((float)Math.PI / 180f) / 9.81f)) * 57.29578f; num = Mathf.Clamp(num, -55f, 55f); float num2 = (0f - Mathf.Atan2(vy, Mathf.Max(speed, 1f))) * 57.29578f * 0.8f; num2 = Mathf.Clamp(num2, -55f, 45f) * (1f - flare) - flare * 38f; float num3 = flock.Clock * 0.35f; num += (Mathf.PerlinNoise(noiseSeed, num3) - 0.5f) * 10f; num2 += (Mathf.PerlinNoise(num3, noiseSeed) - 0.5f) * 5f; float num4 = 1f - Mathf.Exp(-3.5f * dt); roll = Mathf.Lerp(roll, num, num4); pitch = Mathf.Lerp(pitch, num2, num4); } private static float YawTo(Vector3 from, Vector3 to) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_000d: Unknown result type (might be due to invalid IL or missing references) //IL_0013: Unknown result type (might be due to invalid IL or missing references) return Mathf.Atan2(to.x - from.x, to.z - from.z) * 57.29578f; } private static float Smooth01(float x) { x = Mathf.Clamp01(x); return x * x * (3f - 2f * x); } } internal static class BirdFlocks { private const int MaxFlocks = 40; private const float MaintainSeconds = 0.5f; private const float HideMargin = 10f; private const float FreshArrivalSeconds = 180f; private const float ArrivalWindowSeconds = 90f; private const float NightGraceSeconds = 5f; private const float WaterRecheckSeconds = 20f; private const float ClusterRadius = 15f; private const float UnseenMargin = 20f; private const float OffScreenMinDistance = 60f; private const float ScreenMargin = 1.15f; private static readonly List<Flock> Flocks = new List<Flock>(); private static readonly Dictionary<ZDOID, Flock> ById = new Dictionary<ZDOID, Flock>(); private static readonly Dictionary<ZDOID, float> WetUntil = new Dictionary<ZDOID, float>(); private static readonly List<ZDOID> Stale = new List<ZDOID>(); private static bool hooked; private static bool allowedKnown; private static bool allowed; private static float allowedSince = -1000f; private static float darkFor; private static float envSeen = -1f; private static float nextMaintain; private static Vector3 cameraPos; private static bool haveCamera; private static Quaternion cameraToLocal = Quaternion.identity; private static float tanHalfWidth = 1f; private static float tanHalfHeight = 1f; internal static bool HaveCamera => haveCamera; internal static Vector3 CameraPos => cameraPos; internal static float UnseenDistance => TdrConfig.BirdsVisibleDistance.Value + 20f; internal static bool Unseen(Vector3 point) { //IL_0009: Unknown result type (might be due to invalid IL or missing references) //IL_000a: Unknown result type (might be due to invalid IL or missing references) //IL_000f: Unknown result type (might be due to invalid IL or missing references) //IL_0014: 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_0021: Unknown result type (might be due to invalid IL or missing references) //IL_0028: Unknown result type (might be due to invalid IL or missing references) //IL_002e: Unknown result type (might be due to invalid IL or missing references) //IL_004d: Unknown result type (might be due to invalid IL or missing references) //IL_0052: Unknown result type (might be due to invalid IL or missing references) //IL_0053: Unknown result type (might be due to invalid IL or missing references) //IL_0058: Unknown result type (might be due to invalid IL or missing references) //IL_0059: 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_0073: 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_008c: Unknown result type (might be due to invalid IL or missing references) if (!haveCamera) { return true; } Vector3 val = point - cameraPos; float unseenDistance = UnseenDistance; if (val.x * val.x + val.z * val.z >= unseenDistance * unseenDistance) { return true; } if (((Vector3)(ref val)).sqrMagnitude < 3600f) { return false; } Vector3 val2 = cameraToLocal * val; if (val2.z <= 0f) { return true; } if (!(Mathf.Abs(val2.x) > val2.z * tanHalfWidth)) { return Mathf.Abs(val2.y) > val2.z * tanHalfHeight; } return true; } internal static void Tick() { //IL_004a: 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_005e: 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_011a: Unknown result type (might be due to invalid IL or missing references) //IL_0185: Unknown result type (might be due to invalid IL or missing references) if (CarcassVisuals.Headless) { return; } Hook(); float time = Time.time; float dt = Mathf.Min(Time.deltaTime, 0.1f); UpdateAllowed(time, dt); Camera mainCamera = Utils.GetMainCamera(); haveCamera = (Object)(object)mainCamera != (Object)null; if (haveCamera) { Transform transform = ((Component)mainCamera).transform; cameraPos = transform.position; cameraToLocal = Quaternion.Inverse(transform.rotation); tanHalfHeight = Mathf.Tan(mainCamera.fieldOfView * 0.5f * ((float)Math.PI / 180f)) * 1.15f; tanHalfWidth = tanHalfHeight * mainCamera.aspect; } if (time >= nextMaintain) { nextMaintain = time + 0.5f; Maintain(time); } if (Flocks.Count == 0) { return; } float value = TdrConfig.BirdsVisibleDistance.Value; for (int num = Flocks.Count - 1; num >= 0; num--) { if (num >= Flocks.Count) { continue; } Flock flock = Flocks[num]; bool flag = haveCamera && ((!flock.Leaving || !flock.Visible) ? flock.WithinView(cameraPos, value + (flock.Visible ? 10f : 0f)) : flock.AnyBirdWithin(cameraPos, value + 40f)); if (flag != flock.Visible) { flock.SetVisible(flag); } if (!flag) { if (flock.Leaving) { RemoveAt(num); } continue; } try { flock.Update(dt, cameraPos, value); } catch (Exception ex) { Plugin.LogOnce("bird-flock", "The Dead Remain: a bird flock threw (" + ex.GetType().Name + ": " + ex.Message + "); that flock is removed.\n" + ex.StackTrace); RemoveAt(num); continue; } if (flock.Finished) { RemoveAt(num); } } } internal static void ClearAll() { for (int i = 0; i < Flocks.Count; i++) { Flocks[i].ReleaseAll(); } Flocks.Clear(); ById.Clear(); WetUntil.Clear(); BirdKinds.ClearAll(); allowedKnown = false; allowed = false; allowedSince = -1000f; darkFor = 0f; envSeen = -1f; nextMaintain = 0f; haveCamera = false; } internal static int LandedBirdCount(Carcass carcass) { //IL_000b: Unknown result type (might be due to invalid IL or missing references) if (carcass == null) { return 0; } if (!ById.TryGetValue(carcass.Id, out var value) || !value.Visible || value.Leaving) { return 0; } return value.LandedCount; } internal static string StatusLine() { int num = 0; int num2 = 0; for (int i = 0; i < Flocks.Count; i++) { if (Flocks[i].Visible) { num++; num2 += Flocks[i].LandedCount; } } StringBuilder stringBuilder = new StringBuilder(); stringBuilder.Append("flocks ").Append(Flocks.Count).Append(" (") .Append(num) .Append(" shown), birds ") .Append(BirdKinds.LiveCount) .Append(", feeding ") .Append(num2) .Append(allowed ? "" : ", birds away (night or off)"); return stringBuilder.ToString(); } private static void Maintain(float now) { //IL_0084: Unknown result type (might be due to invalid IL or missing references) //IL_00bd: Unknown result type (might be due to invalid IL or missing references) //IL_00d9: Unknown result type (might be due to invalid IL or missing references) for (int i = 0; i < Flocks.Count; i++) { Flock flock = Flocks[i]; if (!flock.Leaving && (!allowed || !StillWanted(flock.Carcass))) { LeaveFlock(flock, allowed ? "carcass" : "night"); } } if (!allowed) { return; } IReadOnlyList<Carcass> loaded = CarcassRegistry.Loaded; for (int j = 0; j < loaded.Count; j++) { Carcass carcass = loaded[j]; if (!StillWanted(carcass)) { continue; } if (ById.TryGetValue(carcass.Id, out var value)) { if (value.Leaving) { value.Rejoin(carcass); } else { value.Carcass = carcass; } } else if (!IsWet(carcass, now) && !CoveredByFlock(carcass.Center) && (Flocks.Count < 40 || MakeRoom(carcass.Center))) { Create(carcass, now); } } if (WetUntil.Count > 64) { PruneWet(now); } } private static bool CoveredByFlock(Vector3 center) { //IL_0027: Unknown result type (might be due to invalid IL or missing references) //IL_002c: Unknown result type (might be due to invalid IL or missing references) //IL_002d: Unknown result type (might be due to invalid IL or missing references) //IL_0032: Unknown result type (might be due to invalid IL or missing references) float num = 225f; for (int i = 0; i < Flocks.Count; i++) { if (!Flocks[i].Leaving) { Vector3 val = Flocks[i].Center - center; if (((Vector3)(ref val)).sqrMagnitude < num) { return true; } } } return false; } private static bool StillWanted(Carcass carcass) { if ((Object)(object)carcass != (Object)null && carcass.IsValid && !carcass.Removing && carcass.Settled) { return carcass.Stage < 2; } return false; } private static void Create(Carcass carcass, float now) { //IL_000c: Unknown result type (might be due to invalid IL or missing references) //IL_0058: Unknown result type (might be due to invalid IL or missing references) //IL_00b1: 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) BirdKind birdKind = BirdKinds.For(carcass); if (birdKind != null) { uint num = Hash(carcass.Id); int count = Mathf.Clamp(TdrConfig.BirdsPerFlock.Value + (int)(num % 3) - 1, 1, 13); bool flag = Arrives(carcass, now); Flock flock = new Flock(carcass, birdKind, num >> 2, count, flag); Flocks.Add(flock); ById[carcass.Id] = flock; if (Plugin.LogEvents) { Plugin.Event("flock " + birdKind.Name + " x" + count + " over " + carcass.Species + " " + ((object)carcass.Id/*cast due to .constrained prefix*/).ToString() + (flag ? " (arriving)" : " (already there)")); } } } private static bool Arrives(Carcass carcass, float now) { if (now - allowedSince < 90f) { return true; } return GameTime.DaysToRealSeconds(GameTime.NowDay - (double)carcass.DeathDay) < 180.0; } private static bool MakeRoom(Vector3 candidate) { //IL_000b: Unknown result type (might be due to invalid IL or missing references) //IL_000c: Unknown result type (might be due to invalid IL or missing references) //IL_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_0040: Unknown result type (might be due to invalid IL or missing references) //IL_0045: Unknown result type (might be due to invalid IL or missing references) //IL_004a: Unknown result type (might be due to invalid IL or missing references) //IL_004f: Unknown result type (might be due to invalid IL or missing references) if (!haveCamera) { return false; } int num = -1; Vector3 val = candidate - cameraPos; float num2 = ((Vector3)(ref val)).sqrMagnitude; for (int i = 0; i < Flocks.Count; i++) { if (!Flocks[i].Visible) { val = Flocks[i].Center - cameraPos; float sqrMagnitude = ((Vector3)(ref val)).sqrMagnitude; if (!(sqrMagnitude <= num2)) { num2 = sqrMagnitude; num = i; } } } if (num < 0) { return false; } RemoveAt(num); return true; } private static void LeaveFlock(Flock flock, string reason) { //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) if (!flock.Leaving) { flock.Leave(); if (Plugin.LogEvents) { Plugin.Event("flock leaves " + flock.SpeciesName + " " + ((object)flock.Id/*cast due to .constrained prefix*/).ToString() + " (" + reason + ")"); } } } private static void RemoveAt(int index) { //IL_0018: 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) Flock flock = Flocks[index]; flock.ReleaseAll(); if (ById.TryGetValue(flock.Id, out var value) && value == flock) { ById.Remove(flock.Id); } Flocks.RemoveAt(index); } private static bool IsWet(Carcass carcass, float now) { //IL_0006: 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_0021: Unknown result type (might be due to invalid IL or missing references) //IL_002e: Unknown result type (might be due to invalid IL or missing references) //IL_0055: Unknown result type (might be due to invalid IL or missing references) //IL_0042: Unknown result type (might be due to invalid IL or missing references) if (WetUntil.TryGetValue(carcass.Id, out var value) && now < value) { return true; } Vector3 center = carcass.Center; if (Floating.GetLiquidLevel(center, 1f, (LiquidType)10) <= center.y + 0.25f) { WetUntil.Remove(carcass.Id); return false; } WetUntil[carcass.Id] = now + 20f; return true; } private static void PruneWet(float now) { //IL_0030: Unknown result type (might be due to invalid IL or missing references) //IL_0062: Unknown result type (might be due to invalid IL or missing references) Stale.Clear(); foreach (KeyValuePair<ZDOID, float> item in WetUntil) { if (now >= item.Value) { Stale.Add(item.Key); } } for (int i = 0; i < Stale.Count; i++) { WetUntil.Remove(Stale[i]); } Stale.Clear(); } private static void UpdateAllowed(float now, float dt) { if ((Object)(object)EnvMan.instance == (Object)null) { envSeen = -1f; return; } if (envSeen < 0f) { envSeen = now; } if (now - envSeen < 1f) { return; } bool value = TdrConfig.EnableBirds.Value; bool flag = value && (TdrConfig.BirdsAtNight.Value || EnvMan.IsDaylight()); if (!allowedKnown) { allowedKnown = true; allowed = flag; allowedSince = -1000f; darkFor = 0f; } else if (flag) { darkFor = 0f; if (!allowed) { allowed = true; allowedSince = now; nextMaintain = 0f; } } else { darkFor += dt; if (allowed && (!value || darkFor >= 5f)) { allowed = false; nextMaintain = 0f; } } } private static void Hook() { if (!hooked) { hooked = true; CarcassEvents.Loaded += OnLoaded; CarcassEvents.Unloaded += OnUnloaded; CarcassEvents.StageChanged += OnStageChanged; } } private static void OnLoaded(Carcass carcass) { nextMaintain = 0f; } private static void OnUnloaded(Carcass carcass) { //IL_0009: Unknown result type (might be due to invalid IL or missing references) if (carcass != null && ById.TryGetValue(carcass.Id, out var value) && value.Carcass == carcass) { value.Carcass = null; LeaveFlock(value, "unloaded"); } } private static void OnStageChanged(Carcass carcass) { //IL_0012: Unknown result type (might be due to invalid IL or missing references) if (carcass != null && carcass.Stage >= 2 && ById.TryGetValue(carcass.Id, out var value)) { LeaveFlock(value, Stages.Name(carcass.Stage)); } } private unsafe static uint Hash(ZDOID id) { int hashCode = ((object)(*(ZDOID*)(&id))/*cast due to .constrained prefix*/).GetHashCode(); int num = (hashCode ^ (hashCode >>> 16)) * 2146121005; int num2 = (num ^ (num >>> 15)) * -2073254261; return (uint)(num2 ^ (num2 >>> 16)); } } internal sealed class BirdView { internal BirdKind Kind; internal GameObject Root; internal Transform T; internal GameObject Fly; internal GameObject Land; internal Animator Animator; private bool landed; private int flapping = -1; private float animSpeed = -1f; private float scale = -1f; internal void Reset() { landed = false; flapping = -1; animSpeed = -1f; scale = -1f; if ((Object)(object)Fly != (Object)null) { Fly.SetActive(true); } if ((Object)(object)Land != (Object)null) { Land.SetActive(false); } } internal void SetLanded(bool value) { if (landed == value) { return; } landed = value; if (!((Object)(object)Land == (Object)null)) { Land.SetActive(value); if ((Object)(object)Fly != (Object)null) { Fly.SetActive(!value); } if (!value) { flapping = -1; animSpeed = -1f; } } } internal void SetFlapping(bool value) { int num = (value ? 1 : 0); if (flapping != num && !landed && !((Object)(object)Animator == (Object)null) && BirdKinds.HasFlapping(Kind, Animator)) { flapping = num; Animator.SetBool(BirdKinds.FlappingHash, value); } } internal void SetAnimSpeed(float value) { if (!((Object)(object)Animator == (Object)null) && !landed && !(Mathf.Abs(animSpeed - value) < 0.01f)) { animSpeed = value; Animator.speed = value; } } internal void SetScale(float value) { //IL_0025: Unknown result type (might be due to invalid IL or missing references) if (!(Mathf.Abs(scale - value) < 0.001f)) { scale = value; T.localScale = new Vector3(value, value, value); } } } internal sealed class BirdKind { internal string Name; internal GameObject FlyTemplate; internal GameObject LandTemplate; internal EffectList Caw; internal float FlapSeconds = 2f; internal float SailSeconds = 1.5f; internal float FlyLift; internal int ReadyFrame; internal int FlapParam = -1; internal readonly Stack<BirdView> Free = new Stack<BirdView>(); } internal static class BirdKinds { internal const string Crow = "Crow"; internal const string Seagull = "Seagal"; internal const string AshCrow = "AshCrow"; internal static readonly int FlappingHash = Animator.StringToHash("flapping"); private static readonly Dictionary<string, BirdKind> Kinds = new Dictionary<string, BirdKind>(); private static readonly List<Component> ComponentBuffer = new List<Component>(); private static readonly List<BirdView> Live = new List<BirdView>(); private static GameObject holder; private static GameObject root; internal static int LiveCount => Live.Count; internal static float WaterLevel { get { if (!((Object)(object)ZoneSystem.instance != (Object)null)) { return 30f; } return ZoneSystem.instance.m_waterLevel; } } internal static BirdKind For(Carcass carcass) { //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_000e: Invalid comparison between Unknown and I4 //IL_0019: Unknown result type (might be due to invalid IL or missing references) //IL_0023: Invalid comparison between Unknown and I4 //IL_0026: Unknown result type (might be due to invalid IL or missing references) //IL_002c: Invalid comparison between Unknown and I4 //IL_002f: Unknown result type (might be due to invalid IL or missing references) string text = "Crow"; if ((int)carcass.Biome == 32) { text = "AshCrow"; } else if ((int)carcass.Biome == 256 || ((int)carcass.Biome != 2 && carcass.Center.y < WaterLevel + 2f)) { text = "Seagal"; } BirdKind birdKind = Get(text); if (birdKind == null && text != "Crow") { birdKind = Get("Crow"); } return birdKind; } internal static bool IsReady(BirdKind kind) { if (kind != null) { return Time.frameCount >= kind.ReadyFrame; } return false; } private static BirdKind Get(string name) { if (Kinds.TryGetValue(name, out var value)) { return value; } if ((Object)(object)ZNetScene.instance == (Object)null) { return null; } try { value = Build(name); } catch (Exception ex) { value = null; Plugin.LogOnce("bird-build-" + name, "The Dead Remain: copying the " + name + " models threw (" + ex.Message + ")."); } Kinds[name] = value; if (value == null) { Plugin.LogOnce("bird-kind-" + name, "The Dead Remain: bird prefab '" + name + "' is missing or has no models; no " + name + " flocks."); } return value; } private static BirdKind Build(string name) { //IL_00d6: 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_0053: Expected O, but got Unknown GameObject prefab = ZNetScene.instance.GetPrefab(name); if ((Object)(object)prefab == (Object)null) { return null; } RandomFlyingBird component = prefab.GetComponent<RandomFlyingBird>(); if ((Object)(object)component == (Object)null || (Object)(object)component.m_flyingModel == (Object)null) { return null; } if ((Object)(object)holder == (Object)null) { holder = new GameObject("TDR_BirdTemplates"); holder.SetActive(false); } BirdKind birdKind = new BirdKind { Name = name, Caw = component.m_randomNoise, FlapSeconds = Mathf.Max(0.3f, component.m_flapDuration), SailSeconds = Mathf.Max(0.3f, component.m_sailDuration) }; birdKind.FlyTemplate = Template(component.m_flyingModel, prefab.transform, name + "_flying"); birdKind.FlyLift = Mathf.Max(0f, birdKind.FlyTemplate.transform.localPosition.y); if (!component.m_singleModel && (Object)(object)component.m_landedModel != (Object)null) { birdKind.LandTemplate = Template(component.m_landedModel, prefab.transform, name + "_landed"); } birdKind.ReadyFrame = Time.frameCount + 2; Plugin.Verbose("The Dead Remain: bird models copied from " + name + " (landed model " + ((Object)(object)birdKind.LandTemplate != (Object)null) + ")."); return birdKind; } private static GameObject Template(GameObject model, Transform prefabRoot, string label) { //IL_0028: Unknown result type (might be due to invalid IL or missing references) //IL_002d: Unknown result type (might be due to invalid IL or missing references) //IL_0039: Unknown result type (might be due to invalid IL or missing references) //IL_003e: Unknown result type (might be due to invalid IL or missing references) //IL_0044: 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_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_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_0061: Unknown result type (might be due to invalid IL or missing references) //IL_0067: Unknown result type (might be due to invalid IL or missing references) //IL_0072: Unknown result type (might be due to invalid IL or missing references) //IL_0078: Unknown result type (might be due to invalid IL or missing references) //IL_0083: 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_0094: Unknown result type (might be due to invalid IL or missing references) GameObject obj = Object.Instantiate<GameObject>(model, holder.transform, false); ((Object)obj).name = label; Transform transform = model.transform; Transform transform2 = obj.transform; transform2.localPosition = prefabRoot.InverseTransformPoint(transform.position); transform2.localRotation = Quaternion.Inverse(prefabRoot.rotation) * transform.rotation; Vector3 lossyScale = transform.lossyScale; Vector3 lossyScale2 = prefabRoot.lossyScale; transform2.localScale = new Vector3(Ratio(lossyScale.x, lossyScale2.x), Ratio(lossyScale.y, lossyScale2.y), Ratio(lossyScale.z, lossyScale2.z)); obj.SetActive(true); Strip(obj); return obj; } private static void Strip(GameObject copy) { ComponentBuffer.Clear(); copy.GetComponentsInChildren<Component>(true, ComponentBuffer); for (int i = 0; i < 3; i++) { for (int j = 0; j < ComponentBuffer.Count; j++) { Component val = ComponentBuffer[j]; if (!((Object)(object)val == (Object)null) && !Keep(val) && StripPass(val) == i) { Object.Destroy((Object)(object)val); } } } ComponentBuffer.Clear(); } private static bool Keep(Component component) { if (!(component is Transform) && !(component is Animator) && !(component is MeshFilter) && !(component is MeshRenderer)) { return component is SkinnedMeshRenderer; } return true; } private static int StripPass(Component component) { if (component is Joint) { return 0; } if (component is Rigidbody) { return 2; } return 1; } private static float Ratio(float a, float b) { if (!(Mathf.Abs(b) > 1E-06f)) { return a; } return a / b; } internal static bool HasFlapping(BirdKind kind, Animator animator) { //IL_002b: Unknown result type (might be due to invalid IL or missing references) //IL_0031: Invalid comparison between Unknown and I4 if (kind.FlapParam < 0) { if (!((Behaviour)animator).isActiveAndEnabled) { return false; } kind.FlapParam = 0; AnimatorControllerParameter[] parameters = animator.parameters; for (int i = 0; i < parameters.Length; i++) { if ((int)parameters[i].type == 4 && parameters[i].name == "flapping") { kind.FlapParam = 1; break; } } if (kind.FlapParam == 0) { Plugin.LogOnce("bird-flap-" + kind.Name, "The Dead Remain: the " + kind.Name + " animator has no 'flapping' switch; its birds only glide."); } } return kind.FlapParam == 1; } internal static BirdView Take(BirdKind kind) { //IL_0075: Unknown result type (might be due to invalid IL or missing references) //IL_007b: Expected O, but got Unknown //IL_005b: Unknown result type (might be due to invalid IL or missing references) //IL_0065: Expected O, but got Unknown while (kind.Free.Count > 0) { BirdView birdView = kind.Free.Pop(); if (!((Object)(object)birdView.Root == (Object)null)) { birdView.Root.SetActive(true); birdView.Reset(); Live.Add(birdView); return birdView; } } if ((Object)(object)root == (Object)null) { root = new GameObject("TDR_Birds"); } GameObject val = new GameObject("TDR_Bird_" + kind.Name); val.transform.SetParent(root.transform, false); BirdView birdView2 = new BirdView { Kind = kind, Root = val, T = val.transform }; birdView2.Fly = Object.Instantiate<GameObject>(kind.FlyTemplate, val.transform, false); birdView2.Animator = birdView2.Fly.GetComponentInChildren<Animator>(true); if ((Object)(object)kind.LandTemplate != (Object)null) { birdView2.Land = Object.Instantiate<GameObject>(kind.LandTemplate, val.transform, false); } birdView2.Reset(); Live.Add(birdView2); return birdView2; } internal static void Release(BirdView view) { if (view != null) { Live.Remove(view); if (!((Object)(object)view.Root == (Object)null)) { view.Root.SetActive(false); view.Kind.Free.Push(view); } } } internal static void Caw(BirdKind kind, Vector3 position) { //IL_0020: Unknown result type (might be due to invalid IL or missing references) //IL_0021: Unknown result type (might be due to invalid IL or missing references) //IL_002f: Unknown result type (might be due to invalid IL or missing references) //IL_0035: Unknown result type (might be due to invalid IL or missing references) if (kind == null || kind.Caw == null || !kind.Caw.HasEffects()) { return; } try { kind.Caw.Create(position, Quaternion.identity, (Transform)null, 1f, -1, default(ZDOID)); } catch (Exception ex) { Plugin.LogOnce("bird-caw", "The Dead Remain: a bird caw threw (" + ex.Message + ")."); } } internal static void ClearAll() { for (int i = 0; i < Live.Count; i++) { if ((Object)(object)Live[i].Root != (Object)null) { Object.Destroy((Object)(object)Live[i].Root); } } Live.Clear(); foreach (KeyValuePair<string, BirdKind> kind in Kinds) { if (kind.Value == null) { continue; } while (kind.Value.Free.Count > 0) { BirdView birdView = kind.Value.Free.Pop(); if ((Object)(object)birdView.Root != (Object)null) { Object.Destroy((Object)(object)birdView.Root); } } } Kinds.Clear(); if ((Object)(object)root != (Object)null) { Object.Destroy((Object)(object)root); } root = null; if ((Object)(object)holder != (Object)null) { Object.Destroy((Object)(object)holder); } holder = null; } } internal sealed class Flock { private const float FlushCheckSeconds = 0.25f; private const float SpotSpacing = 0.7f; private const float AmbientCawMin = 25f; private const float AmbientCawMax = 60f; private const float TwoPi = (float)Math.PI * 2f; internal const float VanishMargin = 40f; internal readonly ZDOID Id; internal readonly BirdKind Kind; internal readonly List<Bird> Birds = new List<Bird>(); internal readonly int Dir; internal readonly float ArrivalBearing; internal readonly string SpeciesName; internal Carcass Carcass; internal Vector3 Center; internal float Size; internal float Clock; internal bool Leaving; internal bool Visible; internal float AlarmLeft; internal float AlarmBlend; private readonly Random rng; private readonly float driftPhase; private bool intruderNear; private bool cawedThisFlush; private float nextFlushCheck; private float nextAmbientCaw; private static readonly RaycastHit[] Hits = (RaycastHit[])(object)new RaycastHit[16]; private static int groundMask = -1; private static int skyMask; internal float BaseRadius => Mathf.Max(TdrConfig.CircleRadius.Value, Size + 4f); internal float BaseHeight => Mathf.Max(TdrConfig.CircleHeight.Value, Size + 4f); internal Vector3 CircleCentre => Center + new Vector3(Mathf.Sin(Clock * 0.031f + driftPhase) * 2.5f, 0f, Mathf.Cos(Clock * 0.027f + driftPhase * 1.3f) * 2.5f); internal float TouchdownDrop => Kind.FlyLift * TdrConfig.BirdScale.Value * 0.8f; internal float MinLandRadius => Mathf.Max(1f, Size * 0.45f + 0.4f); internal float MaxLandRadius => Mathf.Max(2.5f, MinLandRadius + 1.2f); internal bool Finished => Birds.Count == 0; internal int LandedCount { get { int num = 0; for (int i = 0; i < Birds.Count; i++) { if (Birds[i].State == BirdState.Feeding) { num++; } } return num; } } internal Flock(Carcass carcass, BirdKind kind, uint seed, int count, bool arrive) { //IL_0013: Unknown result type (might be due to invalid IL or missing references) //IL_0018: Unknown result type (might be due to invalid IL or missing references) //IL_002d: Unknown result type (might be due to invalid IL or missing references) //IL_0032: Unknown result type (might be due to invalid IL or missing references) Id = carcass.Id; Kind = kind; Carcass = carcass; Center = carcass.Center; Size = carcass.Size; SpeciesName = carcass.Species; rng = new Random((int)seed); Dir = (((seed & 1) == 0) ? 1 : (-1)); ArrivalBearing = Range(0f, (float)Math.PI * 2f); driftPhase = Range(0f, (float)Math.PI * 2f); nextFlushCheck = Range(0f, 0.25f); nextAmbientCaw = Range(8f, 30f); float num = Range(0f, (float)Math.PI * 2f); float num2 = Range(2f, 5f); int num3 = 0; for (int i = 0; i < count; i++) { Bird bird = new Bird(this); Birds.Add(bird); float angle = num + (float)i * ((float)Math.PI * 2f) / (float)count + Range(-0.3f, 0.3f); if (arrive) { bird.State = BirdState.Waiting; bird.Delay = num2; num2 += Range(1.5f, 6f); } else if ((num3 + 1) * 2 <= count && Range(0f, 1f) < 0.5f && bird.PlaceLanded(this, angle)) { num3++; } else { bird.PlaceOnCircle(this, angle); } } } internal float Range(float min, float max) { return min + (float)rng.NextDouble() * (max - min); } internal float LandingRadius() { return Range(MinLandRadius, MaxLandRadius); } internal bool WithinView(Vector3 cameraPos, float distance) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_000c: Unknown result type (might be due to invalid IL or missing references) Vector3 val = Center - cameraPos; return ((Vector3)(ref val)).sqrMagnitude < distance * distance; } internal bool AnyBirdWithin(Vector3 cameraPos, float distance) { //IL_0027: Unknown result type (might be due to invalid IL or missing references) //IL_002c: Unknown result type (might be due to invalid IL or missing references) //IL_002d: Unknown result type (might be due to invalid IL or missing references) //IL_0032: Unknown result type (might be due to invalid IL or missing references) float num = distance * distance; for (int i = 0; i < Birds.Count; i++) { Bird bird = Birds[i]; if (bird.State != BirdState.Waiting && bird.State != BirdState.Gone) { Vector3 val = bird.Pos - cameraPos; if (((Vector3)(ref val)).sqrMagnitude < num) { return true; } } } return false; } internal void Update(float dt, Vector3 cameraPos, float showDistance) { //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_0140: Unknown result type (might be due to invalid IL or missing references) //IL_0145: Unknown result type (might be due to invalid IL or missing references) //IL_0146: Unknown result type (might be due to invalid IL or missing references) //IL_014b: Unknown result type (might be due to invalid IL or missing references) Clock += dt; if (!Leaving && (Object)(object)Carcass != (Object)null && Carcass.IsValid) { Center = Carcass.Center; } AlarmLeft = Mathf.Max(0f, AlarmLeft - dt); AlarmBlend = Mathf.MoveTowards(AlarmBlend, (AlarmLeft > 0f) ? 1f : 0f, dt / 5f); if (!Leaving) { nextFlushCheck -= dt; if (nextFlushCheck <= 0f) { nextFlushCheck = 0.25f; CheckFlush(); } nextAmbientCaw -= dt; if (nextAmbientCaw <= 0f) { nextAmbientCaw = Range(25f, 60f); AmbientCaw(); } } float num = showDistance + 40f; num *= num; bool flag = BirdKinds.IsReady(Kind); for (int num2 = Birds.Count - 1; num2 >= 0; num2--) { Bird bird = Birds[num2]; bird.Update(this, dt); if (bird.State == BirdState.Leaving) { Vector3 val = bird.Pos - cameraPos; if (((Vector3)(ref val)).sqrMagnitude > num) { bird.Vanish(); } } if (bird.State == BirdState.Gone) { BirdKinds.Release(bird.View); bird.View = null; Birds.RemoveAt(num2); } else { if (bird.State == BirdState.Waiting) { continue; } if (bird.View == null) { if (!flag) { continue; } bird.View = BirdKinds.Take(Kind); } bird.ApplyView(this); } } } internal void SetVisible(bool visible) { Visible = visible; if (!visible) { ReleaseAll(); } } internal void ReleaseAll() { for (int i = 0; i < Birds.Count; i++) { if (Birds[i].View != null) { BirdKinds.Release(Birds[i].View); Birds[i].View = null; } } } private void CheckFlush() { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0043: Unknown result type (might be due to invalid IL or missing references) //IL_0048: Unknown result type (might be due to invalid IL or missing references) //IL_004c: Unknown result type (might be due to invalid IL or missing references) //IL_0051: Unknown result type (might be due to invalid IL or missing references) //IL_00a4: Unknown result type (might be due to invalid IL or missing references) //IL_00fd: 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_008c: 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_009b: Unknown result type (might be due to invalid IL or missing references) //IL_007e: Unknown result type (might be due to invalid IL or missing references) //IL_013e: Unknown result type (might be due to invalid IL or missing references) //IL_0143: 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) Character val = NearestCharacter(Center, TdrConfig.FlushRange.Value); if ((Object)(object)val == (Object)null) { intruderNear = false; return; } if (!intruderNear) { intruderNear = true; cawedThisFlush = false; } Vector3 position = ((Component)val).transform.position; int num = 0; Vector3 position2 = Center; for (int i = 0; i < Birds.Count; i++) { Bird bird = Birds[i]; if (bird.IsDown) { if (num == 0) { position2 = ((bird.State == BirdState.Feeding) ? (bird.Spot + Vector3.up * 0.3f) : bird.Pos); } bird.BeginScatter(this, position); num++; } } if (num != 0) { AlarmLeft = Mathf.Max(AlarmLeft, Range(20f, 40f)); if (!cawedThisFlush) { cawedThisFlush = true; BirdKinds.Caw(Kind, position2); } if (Plugin.LogEvents) { Plugin.Event("birds flushed " + num + " at " + SpeciesName + " " + ((object)Id/*cast due to .constrained prefix*/).ToString() + " by " + Utils.GetPrefabName(((Component)val).gameObject)); } } } private static Character NearestCharacter(Vector3 point, float range) { //IL_0033: Unknown result type (might be due to invalid IL or missing references) //IL_0038: Unknown result type (might be due to invalid IL or missing references) //IL_0039: Unknown result type (might be due to invalid IL or missing references) //IL_003e: Unknown result type (might be due to invalid IL or missing references) List<Character> allCharacters = Character.GetAllCharacters(); Character result = null; float num = range * range; for (int i = 0; i < allCharacters.Count; i++) { Character val = allCharacters[i]; if (!((Object)(object)val == (Object)null) && !val.IsDead()) { Vector3 val2 = ((Component)val).transform.position - point; float sqrMagnitude = ((Vector3)(ref val2)).sqrMagnitude; if (!(sqrMagnitude >= num)) { num = sqrMagnitude; result = val; } } } return result; } internal bool MayDescend() { if (Leaving || intruderNear || AlarmLeft > 0f) { return false; } if ((Object)(object)Carcass == (Object)null || !Carcass.IsFeedable) { return false; } int num = 0; int num2 = 0; for (int i = 0; i < Birds.Count; i++) { Bird bird = Birds[i]; if (bird.State != BirdState.Waiting && bird.State != BirdState.Gone) { num++; if (bird.IsDown) { num2++; } } } return num2 * 2 < num; } private void AmbientCaw() { //IL_0054: Unknown result type (might be due to invalid IL or missing references) if (Birds.Count == 0) { return; } int num = rng.Next(Birds.Count); for (int i = 0; i < Birds.Count; i++) { Bird bird = Birds[(num + i) % Birds.Count]; if (bird.State == BirdState.Circling) { BirdKinds.Caw(Kind, bird.Pos); break; } } } internal void Leave() { //IL_0030: Unknown result type (might be due to invalid IL or missing references) //IL_0035: Unknown result type (might be due to invalid IL or missing references) //IL_003a: Unknown result type (might be due to invalid IL or missing references) //IL_003f: Unknown result type (might be due to invalid IL or missing references) //IL_0040: Unknown result type (might be due to invalid IL or missing references) //IL_0046: Unknown result type (might be due to invalid IL or missing references) //IL_004d: Unknown result type (might be due to invalid IL or missing references) //IL_0053: Unknown result type (might be due to invalid IL or missing references) //IL_0062: Unknown result type (might be due to invalid IL or missing references) //IL_0068: Unknown result type (might be due to invalid IL or missing references) if (Leaving) { return; } Leaving = true; intruderNear = false; float bearing = Range(0f, (float)Math.PI * 2f); if (BirdFlocks.HaveCamera) { Vector3 val = Center - BirdFlocks.CameraPos; if (val.x * val.x + val.z * val.z > 25f) { bearing = Mathf.Atan2(val.z, val.x) + Range(-0.5f, 0.5f); } } for (int i = 0; i < Birds.Count; i++) { Birds[i].BeginLeaving(this, bearing); } } internal void Rejoin(Carcass carcass) { //IL_0010: Unknown result type (might be due to invalid IL or missing references) //IL_0015: Unknown result type (might be due to invalid IL or missing references) Leaving = false; Carcass = carcass; Center = carcass.Center; Size = carcass.Size; for (int i = 0; i < Birds.Count; i++) { Birds[i].Rejoin(this); } } internal bool FindSpot(Bird self, Vector3 near, out Vector3 spot) { //IL_0001: Unknown result type (might be due to invalid IL or missing refere