Decompiled source of NpcWalk v1.0.0
plugins/Melissa.NpcWalk.dll
Decompiled 12 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.ComponentModel; using System.Diagnostics; using System.Diagnostics.CodeAnalysis; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using System.Security; using System.Security.Permissions; using BepInEx; using BepInEx.Bootstrap; using BepInEx.Configuration; using BepInEx.Logging; using FishNet.Object; using FishyUI; using HarmonyLib; using Microsoft.CodeAnalysis; using SpongeMods.ModMenu; using UnityEngine; using UnityEngine.SceneManagement; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: IgnoresAccessChecksTo("Assembly-CSharp")] [assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")] [assembly: AssemblyCompany("Melissa.NpcWalk")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyFileVersion("1.0.0.0")] [assembly: AssemblyInformationalVersion("1.0.0")] [assembly: AssemblyProduct("Melissa.NpcWalk")] [assembly: AssemblyTitle("NpcWalk")] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("1.0.0.0")] [module: UnverifiableCode] [module: RefSafetyRules(11)] namespace System.Runtime.CompilerServices { [CompilerGenerated] [Embedded] [AttributeUsage(AttributeTargets.Class | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Parameter | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter, AllowMultiple = false, Inherited = false)] internal sealed class NullableAttribute : Attribute { public readonly byte[] NullableFlags; public NullableAttribute(byte P_0) { NullableFlags = new byte[1] { P_0 }; } public NullableAttribute(byte[] P_0) { NullableFlags = P_0; } } [CompilerGenerated] [Embedded] [AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Method | AttributeTargets.Interface | AttributeTargets.Delegate, AllowMultiple = false, Inherited = false)] internal sealed class NullableContextAttribute : Attribute { public readonly byte Flag; public NullableContextAttribute(byte P_0) { Flag = P_0; } } [CompilerGenerated] [Embedded] [AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)] internal sealed class RefSafetyRulesAttribute : Attribute { public readonly int Version; public RefSafetyRulesAttribute(int P_0) { Version = P_0; } } } namespace BepInEx { [AttributeUsage(AttributeTargets.Class, Inherited = false, AllowMultiple = false)] [Conditional("CodeGeneration")] [Embedded] internal sealed class BepInAutoPluginAttribute : Attribute { public BepInAutoPluginAttribute(string? id = null, string? name = null, string? version = null) { } } } namespace BepInEx.Preloader.Core.Patching { [AttributeUsage(AttributeTargets.Class, Inherited = false, AllowMultiple = false)] [Conditional("CodeGeneration")] [Embedded] internal sealed class PatcherAutoPluginAttribute : Attribute { public PatcherAutoPluginAttribute(string? id = null, string? name = null, string? version = null) { } } } namespace Microsoft.CodeAnalysis { [Embedded] internal sealed class EmbeddedAttribute : Attribute { } } namespace NpcWalk { internal sealed class NpcCarry : MonoBehaviour { private int _worth; private string _label = "Corpse"; private bool _carried; private Player? _carrier; public static NpcCarry Attach(GameObject corpse, string label, int worth) { NpcCarry npcCarry = corpse.GetComponent<NpcCarry>(); if ((Object)(object)npcCarry == (Object)null) { npcCarry = corpse.AddComponent<NpcCarry>(); } npcCarry._worth = worth; npcCarry._label = label; npcCarry.SetupInteract(); return npcCarry; } private void SetupInteract() { //IL_0005: Unknown result type (might be due to invalid IL or missing references) //IL_000b: Expected O, but got Unknown //IL_002a: 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) try { GameObject val = new GameObject("CorpseInteract"); val.SetActive(false); val.transform.SetParent(((Component)this).transform, false); val.transform.localPosition = Vector3.up * 1f; SphereCollider val2 = val.AddComponent<SphereCollider>(); val2.radius = 1.1f; ((Collider)val2).isTrigger = true; CorpseInteractable corpseInteractable = val.AddComponent<CorpseInteractable>(); corpseInteractable.Carry = this; Type typeFromHandle = typeof(Interactable); typeFromHandle.GetField("_interactCol", BindingFlags.Instance | BindingFlags.NonPublic)?.SetValue(corpseInteractable, val2); typeFromHandle.GetField("_textTarget", BindingFlags.Instance | BindingFlags.NonPublic)?.SetValue(corpseInteractable, ((Component)this).transform); val.SetActive(true); ((Interactable)corpseInteractable).ToggleIsInteractable(true); Interactable val3 = Interactable.Get((Collider)(object)val2); Plugin.Log.LogInfo((object)$"[NpcCarry] '{((Object)this).name}' pickup ready (${_worth}), registered={(Object)(object)val3 == (Object)(object)corpseInteractable}"); } catch (Exception ex) { Plugin.Log.LogWarning((object)("[NpcCarry] interact setup fail: " + ex.Message)); } } public void ToggleCarry(Player player) { if (_carried) { Drop(); } else { Pickup(player); } } private void Pickup(Player player) { //IL_0077: 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) try { Transform val = null; try { PlayerHands hands = player.Hands; val = ((hands != null) ? hands.HandBoneRight : null); } catch { } if ((Object)(object)val == (Object)null) { Plugin.Log.LogWarning((object)"[NpcCarry] no hand bone, cannot carry"); return; } ((Component)this).GetComponent<NpcRagdoll.RagdollFreezer>()?.FreezeNow(); _carrier = player; _carried = true; ((Component)this).transform.SetParent(val, false); ((Component)this).transform.localPosition = new Vector3(0f, -1.05f, 0.25f); ((Component)this).transform.localRotation = Quaternion.Euler(15f, 0f, 0f); CorpseInteractable componentInChildren = ((Component)this).GetComponentInChildren<CorpseInteractable>(true); if (componentInChildren != null) { ((Interactable)componentInChildren).ToggleIsInteractable(false); } Plugin.Log.LogInfo((object)("[NpcCarry] '" + ((Object)this).name + "' picked up by '" + ((Object)player).name + "'")); } catch (Exception ex) { Plugin.Log.LogWarning((object)("[NpcCarry] pickup fail: " + ex.Message)); } } private void Drop() { //IL_0058: Unknown result type (might be due to invalid IL or missing references) try { _carried = false; _carrier = null; ((Component)this).transform.SetParent((Transform)null, true); ((Component)this).GetComponent<NpcRagdoll.RagdollFreezer>()?.WakeFor(3f); CorpseInteractable componentInChildren = ((Component)this).GetComponentInChildren<CorpseInteractable>(true); if (componentInChildren != null) { ((Interactable)componentInChildren).ToggleIsInteractable(true); } Plugin.Log.LogInfo((object)$"[NpcCarry] '{((Object)this).name}' dropped at {((Component)this).transform.position}"); } catch (Exception ex) { Plugin.Log.LogWarning((object)("[NpcCarry] drop fail: " + ex.Message)); } } internal string PriceText() { return $"{_label}\n${_worth}\n{SpriteManager.GetPickUpInput()}"; } } internal sealed class CorpseInteractable : Interactable { internal NpcCarry? Carry; private string _hoverText = ""; public override void Hover() { //IL_0034: 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) _hoverText = (((Object)(object)Carry != (Object)null) ? Carry.PriceText() : "Corpse"); PlayerUI.SetLookAtText(_hoverText, ((Interactable)this).TextTarget, default(Vector3), false); ((Interactable)this).Hover(); } public override void UnHover() { PlayerUI.HideLookAtText(_hoverText); ((Interactable)this).UnHover(); } public override void Interact(Player player) { ((Interactable)this).Interact(player); ((Interactable)this).UnHover(); Carry?.ToggleCarry(player); } } [HarmonyPatch(typeof(NPC), "GetEyeDir")] internal static class NpcEyePatch { private const float FovHalfAngle = 65f; private static FieldInfo? _eyePosF; private static FieldInfo? _defaultEyeRotF; private static float _nextDbg; private static bool Prefix(NPC __instance, ref Quaternion __result) { //IL_0181: Unknown result type (might be due to invalid IL or missing references) //IL_0186: 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_00bd: Unknown result type (might be due to invalid IL or missing references) //IL_00be: Unknown result type (might be due to invalid IL or missing references) //IL_00bf: Unknown result type (might be due to invalid IL or missing references) //IL_00c4: Unknown result type (might be due to invalid IL or missing references) //IL_01cc: Unknown result type (might be due to invalid IL or missing references) //IL_01d1: Unknown result type (might be due to invalid IL or missing references) //IL_01c2: 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_0083: Unknown result type (might be due to invalid IL or missing references) //IL_0074: Unknown result type (might be due to invalid IL or missing references) //IL_0086: Unknown result type (might be due to invalid IL or missing references) try { Type typeFromHandle = typeof(NPC); if ((object)_eyePosF == null) { _eyePosF = typeFromHandle.GetField("_eyePos", BindingFlags.Instance | BindingFlags.NonPublic); } if ((object)_defaultEyeRotF == null) { _defaultEyeRotF = typeFromHandle.GetField("_defaultEyeRot", BindingFlags.Instance | BindingFlags.NonPublic); } if (_eyePosF == null || _defaultEyeRotF == null) { return true; } Vector3 val = (Vector3)(_eyePosF.GetValue(__instance) ?? ((object)((Component)__instance).transform.position)); Player val2 = null; try { val2 = PlayerManager.GetNearestAlivePlayer(val); } catch { } if ((Object)(object)val2 == (Object)null || (Object)(object)val2.CamObject == (Object)null) { return true; } Vector3 position = val2.CamObject.position; Vector3 val3 = position - val; float magnitude = ((Vector3)(ref val3)).magnitude; if (magnitude < 0.001f) { return true; } float num = 14f; try { FieldInfo field = typeFromHandle.GetField("_playerEyeContactMaxDist", BindingFlags.Instance | BindingFlags.NonPublic); if (field != null) { num = (float)(field.GetValue(__instance) ?? ((object)14f)); } } catch { } bool flag = magnitude <= num; bool flag2 = true; if (Time.time >= _nextDbg) { _nextDbg = Time.time + 5f; Plugin.Log.LogInfo((object)$"[NpcEyes] '{((Object)__instance).name}' dist={magnitude:F1}/{num:F0} ang={Vector3.Angle(((Component)__instance).transform.forward, val3):F0} tracking={flag && flag2}"); } if (!flag || !flag2) { __result = (Quaternion)(_defaultEyeRotF.GetValue(__instance) ?? ((object)Quaternion.identity)); return false; } } catch { } return true; } } internal sealed class NpcHealth : MonoBehaviour { private NPC? _npc; private int _hp; private bool _dead; private float _lastDamageTime = -10f; public bool Dead => _dead; public int Hp => _hp; public bool WasRecentlyDamaged() { return Time.time - _lastDamageTime < 0.8f; } private void Awake() { _npc = ((Component)this).GetComponent<NPC>(); _hp = Plugin.NpcHealth.Value; } public static bool IsServer() { try { return (Object)(object)Server.Instance != (Object)null && ((NetworkBehaviour)Server.Instance).IsServerInitialized; } catch { return false; } } public void TakeDamage(int amount, Player? killer, bool ranged, Vector3 point) { if (!Plugin.CanKill.Value) { return; } Plugin.Log.LogInfo((object)$"[NpcHealth] TakeDamage enter '{((Object)this).name}' amt={amount} dead={_dead} server={IsServer()}"); if (!_dead && amount > 0 && IsServer()) { _hp -= Mathf.Abs(amount); _lastDamageTime = Time.time; Plugin.Log.LogInfo((object)string.Format("[NpcHealth] '{0}' took {1} {2} dmg from '{3}' hp={4}", ((Object)this).name, amount, ranged ? "ranged" : "melee", ((killer != null) ? ((Object)killer).name : null) ?? "?", _hp)); if (_hp <= 0) { Die(killer, ranged); } } } private void Die(Player? killer, bool ranged) { //IL_0162: Unknown result type (might be due to invalid IL or missing references) _dead = true; NpcWalker component = ((Component)this).GetComponent<NpcWalker>(); if ((Object)(object)component != (Object)null) { component.Die(); } Interactable[] componentsInChildren = ((Component)this).GetComponentsInChildren<Interactable>(true); foreach (Interactable val in componentsInChildren) { try { if ((Object)(object)val != (Object)null) { val.ToggleIsInteractable(false); ((Behaviour)val).enabled = false; } } catch { } } NpcRagdoll.Build(((Component)this).gameObject); float num = (ranged ? Plugin.RangedMult.Value : Plugin.MeleeMult.Value); int num2 = Mathf.Max(1, Mathf.RoundToInt((float)Plugin.BaseBounty.Value * num)); string text = (ranged ? "Ranged" : "Melee"); NpcCarry.Attach(((Component)this).gameObject, ((Object)(object)_npc != (Object)null) ? ((Object)_npc).name : ((Object)this).name, num2); try { Player val2 = killer ?? Player.LocalPlayer; if ((Object)(object)val2 != (Object)null) { MoneyManager.AddMoney(num2, val2); } } catch (Exception ex) { Plugin.Log.LogWarning((object)("[NpcHealth] bounty pay fail: " + ex.Message)); } try { Player val3 = killer ?? Player.LocalPlayer; if (val3 != null) { PlayerKillScore killScore = val3.KillScore; if (killScore != null) { killScore.AddKillScore(((Object)(object)_npc != (Object)null) ? ((Object)_npc).name : ((Object)this).name, num2, new List<Bonus> { new Bonus(text, num) }); } } } catch (Exception ex2) { Plugin.Log.LogWarning((object)("[NpcHealth] killscore fail: " + ex2.Message)); } Plugin.Log.LogInfo((object)$"[NpcHealth] '{((Object)this).name}' died ({text}) bounty=${num2}"); } } [HarmonyPatch(typeof(DazedUtils), "PlayDeadPlayerHitEffects")] internal static class NpcHitHook { private static bool Prefix(Vector3 point, Vector3 dir, int damage, Player playerWhoHit) { //IL_002a: Unknown result type (might be due to invalid IL or missing references) //IL_0065: Unknown result type (might be due to invalid IL or missing references) //IL_009d: Unknown result type (might be due to invalid IL or missing references) try { if (!Plugin.CanKill.Value) { return true; } string arg = CallerName(); Plugin.Log.LogInfo((object)$"[NpcHitHook] fx call by {arg} dmg={damage} at {point}"); if (!NpcHealth.IsServer()) { Plugin.Log.LogInfo((object)"[NpcHitHook] not server, skip"); return true; } if (!IsNpcDamageCall()) { return true; } bool ranged = IsRangedCall(); NpcHealth npcHealth = NearestAliveNpc(point, 1.2f); if ((Object)(object)npcHealth == (Object)null) { Plugin.Log.LogInfo((object)"[NpcHitHook] no alive NPC near hit point"); return true; } if (npcHealth.WasRecentlyDamaged()) { return true; } npcHealth.TakeDamage(damage, playerWhoHit, ranged, point); } catch (Exception ex) { Plugin.Log.LogWarning((object)("[NpcHitHook] fail: " + ex.Message)); } return true; } private static string CallerName() { try { StackTrace stackTrace = new StackTrace(); for (int i = 1; i < 8 && i < stackTrace.FrameCount; i++) { MethodBase methodBase = stackTrace.GetFrame(i)?.GetMethod(); if (!(methodBase == null) && !(methodBase.DeclaringType == null) && !(methodBase.DeclaringType == typeof(NpcHitHook))) { return methodBase.DeclaringType.Name + "::" + methodBase.Name; } } } catch { } return "?"; } private static bool IsNpcDamageCall() { StackTrace stackTrace = new StackTrace(); for (int i = 1; i < 8 && i < stackTrace.FrameCount; i++) { MethodBase methodBase = stackTrace.GetFrame(i)?.GetMethod(); if (!(methodBase == null) && !(methodBase.DeclaringType == null)) { switch (methodBase.DeclaringType.Name) { case "PlayerPunching": case "Melee": case "Weapon": case "ProjectileManager": return true; case "DeadPlayer": return false; } } } return false; } private static bool IsRangedCall() { StackTrace stackTrace = new StackTrace(); for (int i = 1; i < 8 && i < stackTrace.FrameCount; i++) { MethodBase methodBase = stackTrace.GetFrame(i)?.GetMethod(); if (!(methodBase == null) && !(methodBase.DeclaringType == null)) { switch (methodBase.DeclaringType.Name) { case "Weapon": case "ProjectileManager": return true; case "PlayerPunching": case "Melee": return false; } } } return false; } private static NpcHealth? NearestAliveNpc(Vector3 point, float maxDist) { //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_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_004e: 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) NpcHealth[] array = Object.FindObjectsByType<NpcHealth>((FindObjectsInactive)1, (FindObjectsSortMode)0); NpcHealth result = null; float num = maxDist * maxDist; NpcHealth[] array2 = array; foreach (NpcHealth npcHealth in array2) { if (!((Object)(object)npcHealth == (Object)null) && !npcHealth.Dead) { Vector3 val = ((Component)npcHealth).transform.position + Vector3.up * 1f - point; float sqrMagnitude = ((Vector3)(ref val)).sqrMagnitude; if (sqrMagnitude < num) { num = sqrMagnitude; result = npcHealth; } } } return result; } internal static NpcHealth? FromHit(Transform? t) { if ((Object)(object)t == (Object)null) { return null; } NPC val = ((Component)t).GetComponent<NPC>() ?? ((Component)t).GetComponentInParent<NPC>(); if ((Object)(object)val == (Object)null) { return null; } NpcHealth component = ((Component)val).GetComponent<NpcHealth>(); if (!((Object)(object)component != (Object)null) || component.Dead) { return null; } return component; } } [HarmonyPatch(typeof(PlayerPunching), "HitTarget")] internal static class PunchHitPatch { private static void Postfix(PlayerPunching __instance, int side, Transform[] ____curTarget, Player ____player, int ____damage) { //IL_005a: Unknown result type (might be due to invalid IL or missing references) try { if (!Plugin.CanKill.Value || !NpcHealth.IsServer() || ____curTarget == null || side < 0 || side >= ____curTarget.Length) { return; } NpcHealth npcHealth = NpcHitHook.FromHit(____curTarget[side]); if (!((Object)(object)npcHealth == (Object)null)) { int amount; try { amount = (ServerSettings.OneShotEnabled ? 99999 : ____damage); } catch { amount = ____damage; } npcHealth.TakeDamage(amount, ____player, ranged: false, ((Component)npcHealth).transform.position); } } catch (Exception ex) { Plugin.Log.LogWarning((object)("[PunchHitPatch] fail: " + ex.Message)); } } } [HarmonyPatch(typeof(ProjectileManager), "Hit")] internal static class ProjectileHitPatch { private static void Postfix(Projectile projectile, RaycastHit hit) { //IL_0040: Unknown result type (might be due to invalid IL or missing references) try { if (Plugin.CanKill.Value && NpcHealth.IsServer() && projectile != null) { NpcHealth npcHealth = NpcHitHook.FromHit(((RaycastHit)(ref hit)).transform); if (!((Object)(object)npcHealth == (Object)null)) { npcHealth.TakeDamage(projectile.Damage, projectile.Owner, ranged: true, ((RaycastHit)(ref hit)).point); } } } catch (Exception ex) { Plugin.Log.LogWarning((object)("[ProjectileHitPatch] fail: " + ex.Message)); } } } internal static class NpcRagdoll { private readonly struct BoneSpec { public readonly string Name; public readonly float Mass; public readonly float Radius; public BoneSpec(string name, float mass, float radius) { Name = name; Mass = mass; Radius = radius; } } internal sealed class RagdollFreezer : MonoBehaviour { private readonly List<Rigidbody> _bodies = new List<Rigidbody>(); private float _deadline = -1f; private float _quietSince = -1f; public void Arm(IEnumerable<Rigidbody> bodies) { _bodies.Clear(); _bodies.AddRange(bodies); _deadline = Time.time + 12f; _quietSince = -1f; } public void FreezeNow() { //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) foreach (Rigidbody body in _bodies) { if (!((Object)(object)body == (Object)null)) { try { body.linearVelocity = Vector3.zero; body.angularVelocity = Vector3.zero; body.isKinematic = true; } catch { } } } _deadline = -1f; _quietSince = -1f; } public void WakeFor(float seconds) { foreach (Rigidbody body in _bodies) { if ((Object)(object)body != (Object)null) { try { body.isKinematic = false; } catch { } } } _deadline = Time.time + Mathf.Max(seconds, 3f) + 8f; _quietSince = -1f; } private void Update() { //IL_006b: Unknown result type (might be due to invalid IL or missing references) //IL_0070: Unknown result type (might be due to invalid IL or missing references) //IL_0080: Unknown result type (might be due to invalid IL or missing references) //IL_0085: Unknown result type (might be due to invalid IL or missing references) if (_deadline < 0f) { return; } if (Time.time >= _deadline) { FreezeNow(); Plugin.Log.LogInfo((object)("[NpcRagdoll] '" + ((Object)this).name + "' frozen by timeout")); return; } bool flag = true; foreach (Rigidbody body in _bodies) { if ((Object)(object)body == (Object)null || body.isKinematic) { continue; } Vector3 val = body.linearVelocity; if (!(((Vector3)(ref val)).sqrMagnitude > 0.16f)) { val = body.angularVelocity; if (!(((Vector3)(ref val)).sqrMagnitude > 0.5f)) { continue; } } flag = false; break; } if (!flag) { _quietSince = -1f; return; } if (_quietSince < 0f) { _quietSince = Time.time; } if (Time.time - _quietSince >= 1f) { FreezeNow(); Plugin.Log.LogInfo((object)("[NpcRagdoll] '" + ((Object)this).name + "' settled, frozen")); } } } private static readonly BoneSpec[] Bones = new BoneSpec[10] { new BoneSpec("Body", 22f, 0.3f), new BoneSpec("Head", 5f, 0.18f), new BoneSpec("ArmUpper_L", 4f, 0.11f), new BoneSpec("ArmUpper_R", 4f, 0.11f), new BoneSpec("ArmLower_L", 3f, 0.09f), new BoneSpec("ArmLower_R", 3f, 0.09f), new BoneSpec("LegUpper_L", 6f, 0.13f), new BoneSpec("LegUpper_R", 6f, 0.13f), new BoneSpec("LegLower_L", 4f, 0.1f), new BoneSpec("LegLower_R", 4f, 0.1f) }; public static void Build(GameObject root) { //IL_01c1: Unknown result type (might be due to invalid IL or missing references) //IL_01c6: Unknown result type (might be due to invalid IL or missing references) //IL_01ca: Unknown result type (might be due to invalid IL or missing references) //IL_01cf: Unknown result type (might be due to invalid IL or missing references) //IL_01d3: Unknown result type (might be due to invalid IL or missing references) //IL_01d8: Unknown result type (might be due to invalid IL or missing references) //IL_01dc: Unknown result type (might be due to invalid IL or missing references) //IL_01e1: Unknown result type (might be due to invalid IL or missing references) //IL_0241: Unknown result type (might be due to invalid IL or missing references) //IL_024a: Unknown result type (might be due to invalid IL or missing references) //IL_0253: Unknown result type (might be due to invalid IL or missing references) //IL_025c: Unknown result type (might be due to invalid IL or missing references) Collider[] componentsInChildren = root.GetComponentsInChildren<Collider>(true); foreach (Collider val in componentsInChildren) { if (!((Object)(object)val == (Object)null) && !val.isTrigger) { val.isTrigger = true; } } Dictionary<Transform, Rigidbody> dictionary = new Dictionary<Transform, Rigidbody>(); int num = 0; BoneSpec[] bones = Bones; for (int j = 0; j < bones.Length; j++) { BoneSpec boneSpec = bones[j]; Transform val2 = null; Transform[] componentsInChildren2 = root.GetComponentsInChildren<Transform>(true); foreach (Transform val3 in componentsInChildren2) { if ((Object)(object)val3 != (Object)null && ((Object)val3).name == boneSpec.Name) { val2 = val3; break; } } if ((Object)(object)val2 == (Object)null || (Object)(object)((Component)val2).GetComponent<Rigidbody>() != (Object)null) { continue; } try { SphereCollider val4 = ((Component)val2).gameObject.AddComponent<SphereCollider>(); val4.radius = boneSpec.Radius; ((Collider)val4).isTrigger = false; Rigidbody val5 = ((Component)val2).gameObject.AddComponent<Rigidbody>(); val5.mass = boneSpec.Mass; val5.linearDamping = 1.5f; val5.angularDamping = 5f; val5.collisionDetectionMode = (CollisionDetectionMode)0; val5.interpolation = (RigidbodyInterpolation)1; val5.sleepThreshold = 0.3f; dictionary[val2] = val5; Rigidbody value = null; Transform parent = val2.parent; while ((Object)(object)parent != (Object)null && !dictionary.TryGetValue(parent, out value)) { parent = parent.parent; } if ((Object)(object)parent != (Object)null && (Object)(object)value != (Object)null) { CharacterJoint val6 = ((Component)val2).gameObject.AddComponent<CharacterJoint>(); ((Joint)val6).connectedBody = value; val6.enableProjection = false; bool flag = boneSpec.Name.StartsWith("Leg"); SoftJointLimit lowTwistLimit = val6.lowTwistLimit; SoftJointLimit highTwistLimit = val6.highTwistLimit; SoftJointLimit swing1Limit = val6.swing1Limit; SoftJointLimit swing2Limit = val6.swing2Limit; ((SoftJointLimit)(ref lowTwistLimit)).limit = (flag ? (-25f) : (-60f)); ((SoftJointLimit)(ref highTwistLimit)).limit = (flag ? 25f : 60f); ((SoftJointLimit)(ref swing1Limit)).limit = (flag ? 30f : 80f); ((SoftJointLimit)(ref swing2Limit)).limit = (flag ? 30f : 80f); val6.lowTwistLimit = lowTwistLimit; val6.highTwistLimit = highTwistLimit; val6.swing1Limit = swing1Limit; val6.swing2Limit = swing2Limit; } num++; } catch (Exception ex) { Plugin.Log.LogWarning((object)("[NpcRagdoll] bone '" + boneSpec.Name + "' fail: " + ex.Message)); } } Plugin.Log.LogInfo((object)$"[NpcRagdoll] '{((Object)root).name}' ragdolled ({num} bodies)"); RagdollFreezer ragdollFreezer = root.GetComponent<RagdollFreezer>(); if ((Object)(object)ragdollFreezer == (Object)null) { ragdollFreezer = root.AddComponent<RagdollFreezer>(); } ragdollFreezer.Arm(dictionary.Values); } } internal static class NpcSpongeMenu { [MethodImpl(MethodImplOptions.NoInlining)] public static void Ensure() { SpongeMenu.Tab("Melissa.NpcWalk", "NPC Walk", 60).Heading("Walking").Toggle("Enabled (off = walk home, stand)", Plugin.Enabled) .Toggle("Sitting NPCs wander", Plugin.SittingWalk) .Note("Speed in m/s. Radius = roam step, leash at 2x.") .Number("Walk speed", Plugin.WalkSpeed, 0f, 5f) .Number("Wander radius", Plugin.WanderRadius, 1f, 8f) .Number("Look distance", Plugin.LookDistance, 0f, 15f) .Heading("Fun") .Toggle("Party mode (hop + spin)", Plugin.PartyMode); } } internal static class NpcSpongeBridge { [MethodImpl(MethodImplOptions.NoInlining)] public static void Ensure() { try { NpcSpongeMenu.Ensure(); } catch (Exception ex) { Plugin.Log.LogWarning((object)("SpongeMenu init fail: " + ex.Message)); } } } internal static class NpcUi { private static Window? _window; [MethodImpl(MethodImplOptions.NoInlining)] public static void Ensure() { if (_window != null) { return; } _window = Window.Create("npcwalk", "NPC Walk", 420f, 480f); if (_window != null) { _window.OpenInMenus = true; _window.Frosted = false; _window.Resizable = false; _window.Rows().Header("walking").Toggle("enabled", Plugin.Enabled) .Tip("off = everyone walks home and stands still.") .Toggle("sitting walk", Plugin.SittingWalk) .Tip("sitting NPCs get up and wander too.") .Slider("walk speed", Plugin.WalkSpeed, 0f, 5f) .Tip("m/s. 1.2 is a stroll, 4 is a jog.") .Slider("wander radius", Plugin.WanderRadius, 1f, 8f) .Slider("look distance", Plugin.LookDistance, 0f, 15f) .Space(0.4f) .Header("fun") .Toggle("party mode", Plugin.PartyMode) .Tip("hopping and spinning. pure fun.") .Space(0.4f) .Header("controls") .Keybind("menu key", Plugin.MenuKey) .Tip("opens this window.") .Readout("debug", (Func<string>)(() => NpcWalkController.Summary)); } } [MethodImpl(MethodImplOptions.NoInlining)] public static void Toggle() { Ensure(); Window? window = _window; if (window != null) { window.Toggle(); } } [MethodImpl(MethodImplOptions.NoInlining)] public static void Refresh() { Window? window = _window; if (window != null) { window.Refresh(); } } } internal static class NpcUiBridge { [MethodImpl(MethodImplOptions.NoInlining)] public static void Ensure() { try { NpcUi.Ensure(); } catch (Exception ex) { Plugin.Log.LogWarning((object)("FishyUI init fail: " + ex.Message)); } } [MethodImpl(MethodImplOptions.NoInlining)] public static void Toggle() { try { NpcUi.Toggle(); } catch (Exception ex) { Plugin.Log.LogWarning((object)("FishyUI toggle fail: " + ex.Message)); } } } internal static class NpcWalkController { private static float _nextScan; private static bool _probed; private static bool _fullProbeDone; private const float ScanInterval = 5f; private static readonly Dictionary<NPC, (float dist, float sqr, float rot)> _origEyes = new Dictionary<NPC, (float, float, float)>(); public static string Summary { get { try { NPC[] array = Object.FindObjectsByType<NPC>((FindObjectsInactive)1, (FindObjectsSortMode)0); NpcWalker[] array2 = Object.FindObjectsByType<NpcWalker>((FindObjectsInactive)1, (FindObjectsSortMode)0); int num = 0; int num2 = 0; NPC[] array3 = array; foreach (NPC val in array3) { if (!((Object)(object)val == (Object)null)) { if ((Object)(object)((Component)val).GetComponent<NpcHealth>() != (Object)null && ((Component)val).GetComponent<NpcHealth>().Dead) { num2++; } else if (IsSitting(val)) { num++; } } } return $"npc={array.Length} walking={array2.Length} sitting={num} dead={num2}"; } catch { return "n/a"; } } } public static void Init() { _nextScan = 0f; _probed = false; _fullProbeDone = false; Plugin.Log.LogInfo((object)"NpcWalkController init: scanning NPC..."); Scan(now: true); } public static void Tick() { if (!Plugin.Enabled.Value) { RestoreEyes(); if (Time.unscaledTime >= _nextScan) { Scan(now: false); } CollectRetired(); } else { if (Time.unscaledTime >= _nextScan) { Scan(now: false); } CollectRetired(); } } private static void CollectRetired() { NpcWalker[] array = Object.FindObjectsByType<NpcWalker>((FindObjectsInactive)1, (FindObjectsSortMode)0); NpcWalker[] array2 = array; foreach (NpcWalker npcWalker in array2) { if ((Object)(object)npcWalker != (Object)null && npcWalker.RetiredDone) { Object.Destroy((Object)(object)npcWalker); } } } public static void Dispose() { NpcWalker[] array = Object.FindObjectsByType<NpcWalker>((FindObjectsInactive)1, (FindObjectsSortMode)0); foreach (NpcWalker npcWalker in array) { if ((Object)(object)npcWalker != (Object)null) { Object.Destroy((Object)(object)npcWalker); } } } public static void RefreshWalkers() { NPC[] array = Object.FindObjectsByType<NPC>((FindObjectsInactive)1, (FindObjectsSortMode)0); if (!Plugin.Enabled.Value) { NPC[] array2 = array; foreach (NPC val in array2) { if (val != null) { ((Component)val).GetComponent<NpcWalker>()?.TeleportHome(); } } _nextScan = Time.unscaledTime + 5f; return; } NPC[] array3 = array; foreach (NPC val2 in array3) { if (!((Object)(object)val2 == (Object)null)) { bool flag = !IsStationary(val2) && (!IsSitting(val2) || Plugin.SittingWalk.Value); NpcWalker component = ((Component)val2).GetComponent<NpcWalker>(); if (flag && (Object)(object)component == (Object)null) { ((Component)val2).gameObject.AddComponent<NpcWalker>(); Plugin.Log.LogInfo((object)$"NpcWalker attached to NPC id={val2.ID} '{((Object)val2).name}' (refresh)"); } else if (!flag && (Object)(object)component != (Object)null && !component.Retired) { component.GoHomeAndStop(); Plugin.Log.LogInfo((object)$"NPC id={val2.ID} '{((Object)val2).name}' retiring home"); } } } _nextScan = Time.unscaledTime + 5f; } private static void Scan(bool now) { //IL_0183: Unknown result type (might be due to invalid IL or missing references) _nextScan = Time.unscaledTime + 5f; NPC[] array; try { array = Object.FindObjectsByType<NPC>((FindObjectsInactive)1, (FindObjectsSortMode)0); } catch (Exception ex) { Plugin.Log.LogWarning((object)("Find NPC fail: " + ex.Message)); return; } if (array.Length == 0) { if (now) { Plugin.Log.LogWarning((object)"No NPC found (menu scene? go to island). Will rescan."); } return; } Plugin.Log.LogInfo((object)$"NPC count: {array.Length}"); NPC[] array2 = array; foreach (NPC val in array2) { if ((Object)(object)val == (Object)null) { continue; } if (!_probed) { Probe(val); } if (Plugin.CanKill.Value && (Object)(object)((Component)val).GetComponent<NpcHealth>() == (Object)null) { ((Component)val).gameObject.AddComponent<NpcHealth>(); Plugin.Log.LogInfo((object)$"NpcHealth attached to NPC id={val.ID} '{((Object)val).name}'"); } if (IsStationary(val) || (IsSitting(val) && !Plugin.SittingWalk.Value)) { if ((Object)(object)((Component)val).GetComponent<NpcWalker>() == (Object)null) { Plugin.Log.LogInfo((object)$"NPC id={val.ID} '{((Object)val).name}' stays put (stationary/sitting)"); } } else { NpcWalker component = ((Component)val).GetComponent<NpcWalker>(); if ((Object)(object)component == (Object)null) { component = ((Component)val).gameObject.AddComponent<NpcWalker>(); Plugin.Log.LogInfo((object)$"NpcWalker attached to NPC id={val.ID} '{((Object)val).name}' pos={((Component)val).transform.position}"); } } ExtendEyeContact(val); } _probed = true; } internal static bool IsStationary(NPC npc) { try { string text = Plugin.StationaryNpcs.Value ?? ""; string[] array = text.Split(','); foreach (string text2 in array) { string text3 = text2.Trim(); if (text3.Length != 0) { if (text3.Equals(npc.ID.ToString(), StringComparison.OrdinalIgnoreCase)) { return true; } if (((Object)npc).name.IndexOf(text3, StringComparison.OrdinalIgnoreCase) >= 0) { return true; } } } } catch { } return false; } internal static bool IsSitting(NPC npc) { //IL_007a: Unknown result type (might be due to invalid IL or missing references) //IL_0080: Unknown result type (might be due to invalid IL or missing references) //IL_0085: Unknown result type (might be due to invalid IL or missing references) //IL_008a: Unknown result type (might be due to invalid IL or missing references) //IL_008b: Unknown result type (might be due to invalid IL or missing references) //IL_0096: 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_00a1: Unknown result type (might be due to invalid IL or missing references) //IL_00ab: Unknown result type (might be due to invalid IL or missing references) try { Transform val = null; Transform val2 = null; Transform[] componentsInChildren = ((Component)npc).GetComponentsInChildren<Transform>(true); foreach (Transform val3 in componentsInChildren) { if (!((Object)(object)val3 == (Object)null)) { if (((Object)val3).name == "LegUpper_L") { val = val3; } else if (((Object)val3).name == "LegLower_L") { val2 = val3; } } } if ((Object)(object)val == (Object)null || (Object)(object)val2 == (Object)null) { return false; } Vector3 val4 = val2.position - val.position; Vector3 val5 = new Vector3(val4.x, 0f, val4.z); float magnitude = ((Vector3)(ref val5)).magnitude; float num = Mathf.Abs(val4.y); bool flag = magnitude > num * 0.9f; if (flag) { Plugin.Log.LogInfo((object)$"NPC id={npc.ID} '{((Object)npc).name}' detected sitting (thigh h={magnitude:F2} v={num:F2})"); } return flag; } catch { } return false; } private static void ExtendEyeContact(NPC npc) { try { Type typeFromHandle = typeof(NPC); FieldInfo field = typeFromHandle.GetField("_playerEyeContactMaxDist", BindingFlags.Instance | BindingFlags.NonPublic); FieldInfo field2 = typeFromHandle.GetField("_playerEyeContactMaxDistSqr", BindingFlags.Instance | BindingFlags.NonPublic); FieldInfo field3 = typeFromHandle.GetField("_maxEyeRot", BindingFlags.Instance | BindingFlags.NonPublic); if (!(field == null) && !(field2 == null) && !(field3 == null)) { if (!_origEyes.ContainsKey(npc)) { _origEyes[npc] = ((float)(field.GetValue(npc) ?? ((object)4f)), (float)(field2.GetValue(npc) ?? ((object)16f)), (float)(field3.GetValue(npc) ?? ((object)45f))); } field.SetValue(npc, 14f); field2.SetValue(npc, 196f); field3.SetValue(npc, 180f); } } catch (Exception ex) { Plugin.Log.LogWarning((object)("ExtendEyeContact fail on '" + ((Object)npc).name + "': " + ex.Message)); } } private static void RestoreEyes() { if (_origEyes.Count == 0) { return; } try { Type typeFromHandle = typeof(NPC); FieldInfo field = typeFromHandle.GetField("_playerEyeContactMaxDist", BindingFlags.Instance | BindingFlags.NonPublic); FieldInfo field2 = typeFromHandle.GetField("_playerEyeContactMaxDistSqr", BindingFlags.Instance | BindingFlags.NonPublic); FieldInfo field3 = typeFromHandle.GetField("_maxEyeRot", BindingFlags.Instance | BindingFlags.NonPublic); if (field == null || field2 == null || field3 == null) { return; } foreach (KeyValuePair<NPC, (float, float, float)> origEye in _origEyes) { if (!((Object)(object)origEye.Key == (Object)null)) { try { field.SetValue(origEye.Key, origEye.Value.Item1); field2.SetValue(origEye.Key, origEye.Value.Item2); field3.SetValue(origEye.Key, origEye.Value.Item3); } catch { } } } } catch (Exception ex) { Plugin.Log.LogWarning((object)("RestoreEyes fail: " + ex.Message)); } finally { _origEyes.Clear(); } } private static void Probe(NPC npc) { //IL_0039: 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_0255: Unknown result type (might be due to invalid IL or missing references) //IL_025c: Expected O, but got Unknown //IL_020e: Unknown result type (might be due to invalid IL or missing references) //IL_03d1: Unknown result type (might be due to invalid IL or missing references) //IL_03d6: Unknown result type (might be due to invalid IL or missing references) //IL_03e4: Unknown result type (might be due to invalid IL or missing references) //IL_03e9: Unknown result type (might be due to invalid IL or missing references) //IL_0474: Unknown result type (might be due to invalid IL or missing references) //IL_0479: Unknown result type (might be due to invalid IL or missing references) //IL_0467: Unknown result type (might be due to invalid IL or missing references) //IL_046d: Unknown result type (might be due to invalid IL or missing references) GameObject gameObject = ((Component)npc).gameObject; List<string> obj = new List<string> { $"PROBE NPC id={npc.ID} name='{((Object)gameObject).name}'", $" pos={gameObject.transform.position} rot={gameObject.transform.eulerAngles}" }; Animator componentInChildren = gameObject.GetComponentInChildren<Animator>(true); obj.Add(" Animator=" + (((componentInChildren != null) ? ((Object)componentInChildren).name : null) ?? "none")); Animation componentInChildren2 = gameObject.GetComponentInChildren<Animation>(true); obj.Add(" Animation(legacy)=" + (((componentInChildren2 != null) ? ((Object)componentInChildren2).name : null) ?? "none")); Rigidbody componentInChildren3 = gameObject.GetComponentInChildren<Rigidbody>(true); obj.Add(" Rigidbody=" + (((componentInChildren3 != null) ? ((Object)componentInChildren3).name : null) ?? "none")); CharacterController componentInChildren4 = gameObject.GetComponentInChildren<CharacterController>(true); obj.Add(" CharacterController=" + (((componentInChildren4 != null) ? ((Object)componentInChildren4).name : null) ?? "none")); obj.Add(" Collider=" + (((object)gameObject.GetComponentInChildren<Collider>(true))?.GetType().Name ?? "none")); List<string> list = obj; Component component = gameObject.GetComponent("NavMeshAgent"); list.Add(" NavMeshAgent=" + (((Object)(object)component != (Object)null) ? ((Object)component).name : "none")); Component component2 = gameObject.GetComponent("PlayerLegs"); list.Add(" PlayerLegs=" + (((Object)(object)component2 != (Object)null) ? "FOUND" : "none")); Animator componentInChildren5 = gameObject.GetComponentInChildren<Animator>(true); if ((Object)(object)componentInChildren5 != (Object)null) { RuntimeAnimatorController runtimeAnimatorController = componentInChildren5.runtimeAnimatorController; list.Add(" AnimatorController=" + (((runtimeAnimatorController != null) ? ((Object)runtimeAnimatorController).name : null) ?? "none")); if (componentInChildren5.parameters != null) { AnimatorControllerParameter[] parameters = componentInChildren5.parameters; foreach (AnimatorControllerParameter val in parameters) { list.Add($" param: {val.name} ({val.type})"); } } } Animation componentInChildren6 = gameObject.GetComponentInChildren<Animation>(true); if ((Object)(object)componentInChildren6 != (Object)null) { foreach (AnimationState item in componentInChildren6) { AnimationState val2 = item; list.Add(" legacy clip: " + val2.name); } } Transform[] componentsInChildren = gameObject.GetComponentsInChildren<Transform>(true); list.Add($" children={componentsInChildren.Length}"); bool flag = !_fullProbeDone; _fullProbeDone = true; int num = (flag ? componentsInChildren.Length : Math.Min(20, componentsInChildren.Length)); for (int j = 0; j < num; j++) { list.Add($" [{j}] {((Object)componentsInChildren[j]).name}"); } if (flag) { list.Add($" root tag='{gameObject.tag}' layer={LayerMask.LayerToName(gameObject.layer)}({gameObject.layer})"); Collider[] componentsInChildren2 = gameObject.GetComponentsInChildren<Collider>(true); foreach (Collider val3 in componentsInChildren2) { if (!((Object)(object)val3 == (Object)null)) { list.Add($" col: '{((Object)val3).name}' {((object)val3).GetType().Name} tag='{((Component)val3).tag}' layer={LayerMask.LayerToName(((Component)val3).gameObject.layer)} trig={val3.isTrigger}"); } } try { LayerMask val4 = GameInfo.ProjectileHitLayer; object arg = ((LayerMask)(ref val4)).value; val4 = GameInfo.NpcProjectileHitLayer; list.Add($" masks: projHit={arg} npcProjHit={((LayerMask)(ref val4)).value}"); PropertyInfo[] properties = typeof(GameInfo).GetProperties(BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic); foreach (PropertyInfo propertyInfo in properties) { if (!(propertyInfo.PropertyType == typeof(LayerMask)) || !propertyInfo.Name.ToLower().Contains("layer")) { continue; } object obj2 = propertyInfo.GetValue(null); if (obj2 == null) { val4 = default(LayerMask); obj2 = val4; } LayerMask val5 = (LayerMask)obj2; List<string> list2 = new List<string>(); for (int m = 0; m < 32; m++) { if ((((LayerMask)(ref val5)).value & (1 << m)) != 0) { string text = LayerMask.LayerToName(m); list2.Add(string.IsNullOrEmpty(text) ? m.ToString() : $"{m}:{text}"); } } list.Add(string.Format(" mask {0}={1} [{2}]", propertyInfo.Name, ((LayerMask)(ref val5)).value, string.Join(",", list2))); } } catch (Exception ex) { list.Add(" masks fail: " + ex.Message); } HashSet<string> hashSet = new HashSet<string>(); Component[] componentsInChildren3 = gameObject.GetComponentsInChildren<Component>(true); foreach (Component val6 in componentsInChildren3) { if (!((Object)(object)val6 == (Object)null)) { hashSet.Add(((object)val6).GetType().FullName ?? ((object)val6).GetType().Name); } } list.Add($" components={hashSet.Count}"); foreach (string item2 in hashSet) { list.Add(" comp: " + item2); } } foreach (string item3 in list) { Plugin.Log.LogInfo((object)item3); } } } internal sealed class NpcWalker : MonoBehaviour { private Vector3 _home; private Quaternion _homeRot = Quaternion.identity; private Vector3 _target; private float _idleTimer; private bool _hasTarget; private float _walkPhase; private Vector3 _velocity; private Vector3 _lastPos; private float _nextDiagLog; private Rigidbody? _rb; private bool _ownBody; private CapsuleCollider? _col; private bool _ownCollider; private bool _grounded; private float _groundY; private float _climbTime; private const float StepHeight = 0.45f; private const float StepLiftSpeed = 2.2f; private float _stuckTime; private float _veerYaw; private Vector3? _faceLock; private int _pickFails; private Random? _rng; private bool _retire; private bool _retiredDone; private float _nextPartyHop; private float _spinLeft; private bool _vanillaFrozen; private float _nextEyeFix; private const float TurnSpeed = 120f; private const float Accel = 12f; private const float MaxStepY = 1.2f; private Transform? _body; private Transform? _armL; private Transform? _armR; private Transform? _armLowL; private Transform? _armLowR; private Transform? _head; private Transform? _legL; private Transform? _legR; private Transform? _shinL; private Transform? _shinR; private Vector3 _bodyOrigPos; private Quaternion _bodyOrigRot = Quaternion.identity; private Quaternion _armLOrig = Quaternion.identity; private Quaternion _armROrig = Quaternion.identity; private Quaternion _armLowLOrig = Quaternion.identity; private Quaternion _armLowROrig = Quaternion.identity; private Quaternion _headOrig = Quaternion.identity; private Quaternion _legLOrig = Quaternion.identity; private Quaternion _legROrig = Quaternion.identity; private Quaternion _shinLOrig = Quaternion.identity; private Quaternion _shinROrig = Quaternion.identity; private Transform? _handBoneL; private Transform? _handBoneR; private readonly List<(Transform t, Transform? parent, Vector3 pos, Quaternion rot)> _reparented = new List<(Transform, Transform, Vector3, Quaternion)>(); private readonly List<Behaviour> _ikLocks = new List<Behaviour>(); private float _idleStillTime; private static FieldInfo? _eyePosField; private static FieldInfo? _eyesField; internal bool Retired => _retire; internal bool RetiredDone => _retiredDone; private void Start() { //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_000c: Unknown result type (might be due to invalid IL or missing references) //IL_0018: Unknown result type (might be due to invalid IL or missing references) //IL_001d: Unknown result type (might be due to invalid IL or missing references) //IL_0029: Unknown result type (might be due to invalid IL or missing references) //IL_002e: Unknown result type (might be due to invalid IL or missing references) //IL_00db: Unknown result type (might be due to invalid IL or missing references) _home = ((Component)this).transform.position; _homeRot = ((Component)this).transform.rotation; _lastPos = ((Component)this).transform.position; _rng = new Random(StableSeed(((Object)this).name)); _idleTimer = RngRange(Plugin.IdleMin.Value, Plugin.IdleMax.Value); _walkPhase = RngRange(0f, MathF.PI * 2f); _nextPartyHop = Time.time + RngRange(2f, 4f); CacheRig(); DisableArmIkLocks(); EnsurePhysics(); if (!Plugin.Enabled.Value) { TeleportHome(); } Plugin.Log.LogInfo((object)($"[NpcWalker] start '{((Object)this).name}' home={_home} body={(Object)(object)_body != (Object)null} armL={(Object)(object)_armL != (Object)null} armR={(Object)(object)_armR != (Object)null} " + $"rb={(Object)(object)_rb != (Object)null} col={(Object)(object)_col != (Object)null} ownBody={_ownBody}")); } public void TeleportHome() { //IL_0057: 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_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_0014: Unknown result type (might be due to invalid IL or missing references) //IL_0024: Unknown result type (might be due to invalid IL or missing references) //IL_0035: 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_007a: Unknown result type (might be due to invalid IL or missing references) //IL_007f: Unknown result type (might be due to invalid IL or missing references) try { if ((Object)(object)_rb != (Object)null) { _rb.linearVelocity = Vector3.zero; _rb.angularVelocity = Vector3.zero; _rb.MovePosition(_home); _rb.MoveRotation(_homeRot); } ((Component)this).transform.SetPositionAndRotation(_home, _homeRot); _lastPos = _home; } catch { } _target = _home; _hasTarget = false; _stuckTime = 0f; _idleTimer = RngRange(Plugin.IdleMin.Value, Plugin.IdleMax.Value); RestoreBonePose(); SetIkLocks(on: true); _vanillaFrozen = true; } private void EnsurePhysics() { //IL_00b9: Unknown result type (might be due to invalid IL or missing references) //IL_00c0: Expected O, but got Unknown //IL_00ec: Unknown result type (might be due to invalid IL or missing references) //IL_0128: Unknown result type (might be due to invalid IL or missing references) CapsuleCollider val = null; CapsuleCollider[] componentsInChildren = ((Component)this).GetComponentsInChildren<CapsuleCollider>(true); foreach (CapsuleCollider val2 in componentsInChildren) { if ((Object)(object)val2 != (Object)null && !((Collider)val2).isTrigger) { val = val2; break; } } if ((Object)(object)val == (Object)null) { string text = "NPC"; int layer = ((Component)this).gameObject.layer; Transform[] componentsInChildren2 = ((Component)this).GetComponentsInChildren<Transform>(true); foreach (Transform val3 in componentsInChildren2) { if ((Object)(object)val3 != (Object)null && (Object)(object)val3 != (Object)(object)((Component)this).transform && ((Component)val3).CompareTag("NPC")) { text = ((Component)val3).tag; layer = ((Component)val3).gameObject.layer; break; } } GameObject val4 = new GameObject("NpcWalkBody"); val4.tag = text; val4.layer = layer; val4.transform.SetParent(((Component)this).transform, false); val4.transform.localPosition = Vector3.zero; CapsuleCollider val5 = val4.AddComponent<CapsuleCollider>(); val5.height = 1.7f; val5.radius = 0.32f; val5.center = new Vector3(0f, 0.9f, 0f); ((Collider)val5).isTrigger = false; _ownCollider = true; val = val5; Plugin.Log.LogInfo((object)$"[NpcWalker] '{((Object)this).name}': added solid body tag='{text}' layer={layer}"); } _col = val; _rb = ((Component)this).GetComponent<Rigidbody>(); if ((Object)(object)_rb == (Object)null) { _rb = ((Component)this).gameObject.AddComponent<Rigidbody>(); _ownBody = true; } _rb.mass = 70f; _rb.linearDamping = 0f; _rb.angularDamping = 10f; _rb.collisionDetectionMode = (CollisionDetectionMode)0; _rb.interpolation = (RigidbodyInterpolation)1; _rb.constraints = (RigidbodyConstraints)112; } private void DisableArmIkLocks() { Behaviour[] componentsInChildren = ((Component)this).GetComponentsInChildren<Behaviour>(true); foreach (Behaviour val in componentsInChildren) { if ((Object)(object)val == (Object)null || val is NpcWalker) { continue; } string text = ((object)val).GetType().FullName ?? ((object)val).GetType().Name; if (text.IndexOf("ik", StringComparison.OrdinalIgnoreCase) >= 0 && !(val is Animator) && !(val is Animation)) { if (!_ikLocks.Contains(val)) { _ikLocks.Add(val); } try { val.enabled = false; Plugin.Log.LogInfo((object)("[NpcWalker] '" + ((Object)this).name + "': disabled arm lock '" + text + "' on '" + ((Object)val).name + "'")); } catch (Exception ex) { Plugin.Log.LogWarning((object)("[NpcWalker] disable '" + text + "' fail: " + ex.Message)); } } } } private void SetIkLocks(bool on) { foreach (Behaviour ikLock in _ikLocks) { if ((Object)(object)ikLock == (Object)null) { continue; } try { if (ikLock.enabled != on) { ikLock.enabled = on; } } catch { } } } private void OnDestroy() { SetIkLocks(on: true); RestorePose(); try { if (_ownBody && (Object)(object)_rb != (Object)null) { Object.Destroy((Object)(object)_rb); } if (_ownCollider && (Object)(object)_col != (Object)null) { Object.Destroy((Object)(object)((Component)_col).gameObject); } } catch { } } public void Die() { try { if (_ownBody && (Object)(object)_rb != (Object)null) { Object.Destroy((Object)(object)_rb); } if (_ownCollider && (Object)(object)_col != (Object)null) { Object.Destroy((Object)(object)((Component)_col).gameObject); } } catch { } _rb = null; _col = null; ((Behaviour)this).enabled = false; } private void CacheRig() { //IL_008a: 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_009b: Unknown result type (might be due to invalid IL or missing references) //IL_00a0: Unknown result type (might be due to invalid IL or missing references) //IL_00ba: Unknown result type (might be due to invalid IL or missing references) //IL_00bf: Unknown result type (might be due to invalid IL or missing references) //IL_00d9: Unknown result type (might be due to invalid IL or missing references) //IL_00de: Unknown result type (might be due to invalid IL or missing references) //IL_00f8: 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_0117: Unknown result type (might be due to invalid IL or missing references) //IL_011c: Unknown result type (might be due to invalid IL or missing references) //IL_0136: Unknown result type (might be due to invalid IL or missing references) //IL_013b: Unknown result type (might be due to invalid IL or missing references) //IL_0199: Unknown result type (might be due to invalid IL or missing references) //IL_019e: Unknown result type (might be due to invalid IL or missing references) //IL_01ea: 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_01cb: 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_021c: 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) _body = FindDeep("Body") ?? FindDeep("Character"); _armL = FindDeep("ArmUpper_L"); _armR = FindDeep("ArmUpper_R"); _armLowL = FindDeep("ArmLower_L"); _armLowR = FindDeep("ArmLower_R"); _head = FindDeep("Head"); if ((Object)(object)_body != (Object)null) { _bodyOrigPos = _body.localPosition; _bodyOrigRot = _body.localRotation; } if ((Object)(object)_armL != (Object)null) { _armLOrig = _armL.localRotation; } if ((Object)(object)_armR != (Object)null) { _armROrig = _armR.localRotation; } if ((Object)(object)_armLowL != (Object)null) { _armLowLOrig = _armLowL.localRotation; } if ((Object)(object)_armLowR != (Object)null) { _armLowROrig = _armLowR.localRotation; } if ((Object)(object)_head != (Object)null) { _headOrig = _head.localRotation; } _legL = FindDeep("LegUpper_L"); _legR = FindDeep("LegUpper_R"); _shinL = FindDeep("LegLower_L"); _shinR = FindDeep("LegLower_R"); if ((Object)(object)_legL != (Object)null) { _legLOrig = _legL.localRotation; } if ((Object)(object)_legR != (Object)null && (Object)(object)_legR != (Object)(object)_legL) { _legROrig = _legR.localRotation; } if ((Object)(object)_shinL != (Object)null) { _shinLOrig = _shinL.localRotation; } if ((Object)(object)_shinR != (Object)null && (Object)(object)_shinR != (Object)(object)_shinL) { _shinROrig = _shinR.localRotation; } ManualLogSource log = Plugin.Log; string[] obj = new string[10] { "[NpcWalker] rig '", ((Object)this).name, "': legL=", null, null, null, null, null, null, null }; Transform? legL = _legL; obj[3] = ((legL != null) ? ((Object)legL).name : null) ?? "none"; obj[4] = " legR="; Transform? legR = _legR; obj[5] = ((legR != null) ? ((Object)legR).name : null) ?? "none"; obj[6] = " shinL="; Transform? shinL = _shinL; obj[7] = ((shinL != null) ? ((Object)shinL).name : null) ?? "none"; obj[8] = " shinR="; Transform? shinR = _shinR; obj[9] = ((shinR != null) ? ((Object)shinR).name : null) ?? "none"; log.LogInfo((object)string.Concat(obj)); CacheHandGlue(); } private void CacheHandGlue() { _handBoneL = FindDeep("Hand_L"); _handBoneR = FindDeep("Hand_R"); AttachDeco(_handBoneL, FindDeep("HandLeft"), FindDeep("LeftHand")); AttachDeco(_handBoneR, FindDeep("HandRight"), FindDeep("RightHand")); ManualLogSource log = Plugin.Log; string[] obj = new string[8] { "[NpcWalker] hands '", ((Object)this).name, "': boneL=", null, null, null, null, null }; Transform? handBoneL = _handBoneL; obj[3] = ((handBoneL != null) ? ((Object)handBoneL).name : null) ?? "none"; obj[4] = " boneR="; Transform? handBoneR = _handBoneR; obj[5] = ((handBoneR != null) ? ((Object)handBoneR).name : null) ?? "none"; obj[6] = " "; obj[7] = $"reparented={_reparented.Count}"; log.LogInfo((object)string.Concat(obj)); } private void AttachDeco(Transform? handBone, params Transform?[] candidates) { //IL_00ab: Unknown result type (might be due to invalid IL or missing references) //IL_00b2: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)handBone == (Object)null) { return; } List<Transform> list = new List<Transform>(); foreach (Transform val in candidates) { if ((Object)(object)val == (Object)null || (Object)(object)val == (Object)(object)handBone) { continue; } bool flag = false; foreach (Transform val2 in candidates) { if ((Object)(object)val2 != (Object)null && (Object)(object)val2 != (Object)(object)val && val.IsChildOf(val2)) { flag = true; break; } } if (!flag) { list.Add(val); } } foreach (Transform item in list) { try { _reparented.Add((item, item.parent, item.localPosition, item.localRotation)); item.SetParent(handBone, true); Plugin.Log.LogInfo((object)("[NpcWalker] '" + ((Object)this).name + "': hand chain '" + ((Object)item).name + "' attached to '" + ((Object)handBone).name + "'")); } catch (Exception ex) { Plugin.Log.LogWarning((object)("[NpcWalker] attach '" + ((Object)item).name + "' fail: " + ex.Message)); } } } private Transform? FindByPart(params string[] parts) { Transform[] componentsInChildren = ((Component)this).GetComponentsInChildren<Transform>(true); foreach (Transform val in componentsInChildren) { string text = ((Object)val).name.ToLowerInvariant().Replace("_", "").Replace("-", "") .Replace(" ", ""); foreach (string value in parts) { if (text.Contains(value)) { return val; } } } return null; } private Transform? FindLastByPart(params string[] parts) { Transform result = null; Transform[] componentsInChildren = ((Component)this).GetComponentsInChildren<Transform>(true); foreach (Transform val in componentsInChildren) { string text = ((Object)val).name.ToLowerInvariant().Replace("_", "").Replace("-", "") .Replace(" ", ""); foreach (string value in parts) { if (text.Contains(value)) { result = val; } } } return result; } public void GoHomeAndStop() { _retire = true; TeleportHome(); _retiredDone = true; } private bool Homing() { if (!Plugin.Enabled.Value) { return !_retiredDone; } return false; } private void RefreshEyeAnchor() { //IL_00b8: 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_00da: 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_00e2: Unknown result type (might be due to invalid IL or missing references) //IL_00e7: Unknown result type (might be due to invalid IL or missing references) //IL_0102: Unknown result type (might be due to invalid IL or missing references) //IL_0106: Unknown result type (might be due to invalid IL or missing references) //IL_010b: Unknown result type (might be due to invalid IL or missing references) //IL_010c: Unknown result type (might be due to invalid IL or missing references) //IL_0110: Unknown result type (might be due to invalid IL or missing references) //IL_011a: Unknown result type (might be due to invalid IL or missing references) //IL_011f: Unknown result type (might be due to invalid IL or missing references) //IL_0124: Unknown result type (might be due to invalid IL or missing references) //IL_012b: Unknown result type (might be due to invalid IL or missing references) if (Time.time < _nextEyeFix) { return; } _nextEyeFix = Time.time + 0.2f; try { Type typeFromHandle = typeof(NPC); if ((object)_eyePosField == null) { _eyePosField = typeFromHandle.GetField("_eyePos", BindingFlags.Instance | BindingFlags.NonPublic); } if ((object)_eyesField == null) { _eyesField = typeFromHandle.GetField("_eyes", BindingFlags.Instance | BindingFlags.NonPublic); } if (_eyePosField == null || _eyesField == null) { return; } NPC component = ((Component)this).GetComponent<NPC>(); if ((Object)(object)component == (Object)null || !(_eyesField.GetValue(component) is Transform[] array) || array.Length == 0 || (Object)(object)array[0] == (Object)null) { return; } Vector3 val = Vector3.zero; int num = 0; Transform[] array2 = array; foreach (Transform val2 in array2) { if (!((Object)(object)val2 == (Object)null)) { val += val2.position; num++; } } if (num != 0) { val /= (float)num; val -= array[0].up * 0.3f; _eyePosField.SetValue(component, val); } } catch { } } private static int StableSeed(string name) { //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) uint num = 2166136261u; Scene activeScene = SceneManager.GetActiveScene(); string text = name + "@" + ((Scene)(ref activeScene)).name; string text2 = text; foreach (char c in text2) { num ^= c; num *= 16777619; } return (int)num; } private float RngRange(float a, float b) { return (float)((double)a + (_rng?.NextDouble() ?? 0.5) * (double)(b - a)); } private bool RngChance(double p) { return (_rng?.NextDouble() ?? 0.5) < p; } private int RngSign() { if (!((_rng?.NextDouble() ?? 0.5) < 0.5)) { return 1; } return -1; } private float RngAngle(float magnitude) { return (float)((_rng?.NextDouble() ?? 0.5) * 2.0 - 1.0) * magnitude; } private Transform? FindDeep(string n) { Transform[] componentsInChildren = ((Component)this).GetComponentsInChildren<Transform>(true); foreach (Transform val in componentsInChildren) { if (((Object)val).name == n) { return val; } } return null; } private void Update() { //IL_0016: Unknown result type (might be due to invalid IL or missing references) //IL_001c: Unknown result type (might be due to invalid IL or missing references) //IL_0021: 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_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_0067: 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_0155: Unknown result type (might be due to invalid IL or missing references) //IL_0163: Unknown result type (might be due to invalid IL or missing references) float deltaTime = Time.deltaTime; if (deltaTime <= 0f) { return; } _velocity = (((Component)this).transform.position - _lastPos) / Mathf.Max(deltaTime, 0.0001f); _lastPos = ((Component)this).transform.position; Vector3 val = new Vector3(_velocity.x, 0f, _velocity.z); float magnitude = ((Vector3)(ref val)).magnitude; RefreshEyeAnchor(); if ((Object)(object)_rb == (Object)null) { ApplyIdle(deltaTime); return; } if (Homing() || _retire) { if (!_vanillaFrozen) { TeleportHome(); } if (_retire) { _retiredDone = true; } SetIkLocks(on: true); } else if (magnitude < 0.15f) { ApplyIdle(deltaTime); _idleStillTime += deltaTime; if (_idleStillTime > 1.5f) { SetIkLocks(on: true); } } else { _idleStillTime = 0f; SetIkLocks(on: false); ApplyWalk(deltaTime); } if (Time.unscaledTime >= _nextDiagLog) { _nextDiagLog = Time.unscaledTime + 15f; Plugin.Log.LogInfo((object)($"[NpcWalker] '{((Object)this).name}' pos={((Component)this).transform.position} home={_home} hasTarget={_hasTarget} " + $"idle={_idleTimer:F1} spd={magnitude:F2} grounded={_grounded} stuck={_stuckTime:F1} veer={_veerYaw:F0} fails={_pickFails}")); } } private void FixedUpdate() { //IL_001b: 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_0097: Unknown result type (might be due to invalid IL or missing references) //IL_00a8: Unknown result type (might be due to invalid IL or missing references) //IL_00ad: 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_00cd: Unknown result type (might be due to invalid IL or missing references) //IL_00d2: 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) //IL_00e7: 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_01ba: Unknown result type (might be due to invalid IL or missing references) //IL_01bf: Unknown result type (might be due to invalid IL or missing references) //IL_01c2: Unknown result type (might be due to invalid IL or missing references) //IL_01cd: Unknown result type (might be due to invalid IL or missing references) //IL_0135: Unknown result type (might be due to invalid IL or missing references) //IL_0238: Unknown result type (might be due to invalid IL or missing references) //IL_023d: Unknown result type (might be due to invalid IL or missing references) //IL_017d: Unknown result type (might be due to invalid IL or missing references) //IL_0182: Unknown result type (might be due to invalid IL or missing references) //IL_0193: Unknown result type (might be due to invalid IL or missing references) //IL_035a: Unknown result type (might be due to invalid IL or missing references) //IL_0365: Unknown result type (might be due to invalid IL or missing references) //IL_036a: Unknown result type (might be due to invalid IL or missing references) //IL_036f: Unknown result type (might be due to invalid IL or missing references) //IL_031f: Unknown result type (might be due to invalid IL or missing references) //IL_0320: Unknown result type (might be due to invalid IL or missing references) //IL_0330: Unknown result type (might be due to invalid IL or missing references) //IL_0335: Unknown result type (might be due to invalid IL or missing references) //IL_033c: Unknown result type (might be due to invalid IL or missing references) //IL_0342: Unknown result type (might be due to invalid IL or missing references) //IL_0348: Unknown result type (might be due to invalid IL or missing references) //IL_034e: 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_0265: Unknown result type (might be due to invalid IL or missing references) //IL_026a: Unknown result type (might be due to invalid IL or missing references) //IL_0278: Unknown result type (might be due to invalid IL or missing references) //IL_027d: 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_029a: Unknown result type (might be due to invalid IL or missing references) //IL_029f: Unknown result type (might be due to invalid IL or missing references) //IL_0164: Unknown result type (might be due to invalid IL or missing references) //IL_0407: Unknown result type (might be due to invalid IL or missing references) //IL_0412: Unknown result type (might be due to invalid IL or missing references) //IL_0418: Unknown result type (might be due to invalid IL or missing references) //IL_041d: Unknown result type (might be due to invalid IL or missing references) //IL_038c: Unknown result type (might be due to invalid IL or missing references) //IL_038d: Unknown result type (might be due to invalid IL or missing references) //IL_039d: Unknown result type (might be due to invalid IL or missing references) //IL_03a2: Unknown result type (might be due to invalid IL or missing references) //IL_03a9: Unknown result type (might be due to invalid IL or missing references) //IL_03af: Unknown result type (might be due to invalid IL or missing references) //IL_03b5: Unknown result type (might be due to invalid IL or missing references) //IL_03bb: Unknown result type (might be due to invalid IL or missing references) //IL_02d2: Unknown result type (might be due to invalid IL or missing references) //IL_02d3: Unknown result type (might be due to invalid IL or missing references) //IL_02e3: 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_02ef: Unknown result type (might be due to invalid IL or missing references) //IL_02f5: Unknown result type (might be due to invalid IL or missing references) //IL_02fb: 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_04f6: Unknown result type (might be due to invalid IL or missing references) //IL_04f8: Unknown result type (might be due to invalid IL or missing references) //IL_04fd: Unknown result type (might be due to invalid IL or missing references) //IL_0502: Unknown result type (might be due to invalid IL or missing references) //IL_0517: Unknown result type (might be due to invalid IL or missing references) //IL_051c: Unknown result type (might be due to invalid IL or missing references) //IL_0521: Unknown result type (might be due to invalid IL or missing references) //IL_052f: Unknown result type (might be due to invalid IL or missing references) //IL_0534: Unknown result type (might be due to invalid IL or missing references) //IL_0541: Unknown result type (might be due to invalid IL or missing references) //IL_0572: Unknown result type (might be due to invalid IL or missing references) //IL_0577: Unknown result type (might be due to invalid IL or missing references) //IL_0581: Unknown result type (might be due to invalid IL or missing references) //IL_0586: Unknown result type (might be due to invalid IL or missing references) //IL_0591: Unknown result type (might be due to invalid IL or missing references) //IL_059b: Unknown result type (might be due to invalid IL or missing references) //IL_05a0: Unknown result type (might be due to invalid IL or missing references) //IL_05a5: Unknown result type (might be due to invalid IL or missing references) //IL_05a7: Unknown result type (might be due to invalid IL or missing references) //IL_05b4: Unknown result type (might be due to invalid IL or missing references) //IL_0801: Unknown result type (might be due to invalid IL or missing references) //IL_0810: Unknown result type (might be due to invalid IL or missing references) //IL_0815: Unknown result type (might be due to invalid IL or missing references) //IL_0817: Unknown result type (might be due to invalid IL or missing references) //IL_0818: Unknown result type (might be due to invalid IL or missing references) //IL_0825: Unknown result type (might be due to invalid IL or missing references) //IL_082a: Unknown result type (might be due to invalid IL or missing references) //IL_082b: Unknown result type (might be due to invalid IL or missing references) //IL_05f7: Unknown result type (might be due to invalid IL or missing references) //IL_0866: Unknown result type (might be due to invalid IL or missing references) //IL_086b: Unknown result type (might be due to invalid IL or missing references) //IL_087b: Unknown result type (might be due to invalid IL or missing references) //IL_0880: Unknown result type (might be due to invalid IL or missing references) //IL_066d: Unknown result type (might be due to invalid IL or missing references) //IL_0672: Unknown result type (might be due to invalid IL or missing references) //IL_067c: Unknown result type (might be due to invalid IL or missing references) //IL_0681: Unknown result type (might be due to invalid IL or missing references) //IL_068c: Unknown result type (might be due to invalid IL or missing references) //IL_0696: Unknown result type (might be due to invalid IL or missing references) //IL_069b: Unknown result type (might be due to invalid IL or missing references) //IL_06a0: Unknown result type (might be due to invalid IL or missing references) //IL_06a2: Unknown result type (might be due to invalid IL or missing references) //IL_06aa: Unknown result type (might be due to invalid IL or missing references) //IL_0938: Unknown result type (might be due to invalid IL or missing references) //IL_0940: Unknown result type (might be due to invalid IL or missing references) //IL_0946: Unknown result type (might be due to invalid IL or missing references) //IL_0903: Unknown result type (might be due to invalid IL or missing references) //IL_0914: Unknown result type (might be due to invalid IL or missing references) //IL_0919: Unknown result type (might be due to invalid IL or missing references) //IL_06dd: Unknown result type (might be due to invalid IL or missing references) //IL_06e8: Unknown result type (might be due to invalid IL or missing references) //IL_06f2: Unknown result type (might be due to invalid IL or missing references) //IL_06f7: Unknown result type (might be due to invalid IL or missing references) //IL_06fc: Unknown result type (might be due to invalid IL or missing references) //IL_0706: Unknown result type (might be due to invalid IL or missing references) //IL_070b: Unknown result type (might be due to invalid IL or missing references) //IL_0710: Unknown result type (might be due to invalid IL or missing references) //IL_0712: Unknown result type (might be due to invalid IL or missing references) //IL_0714: Unknown result type (might be due to invalid IL or missing references) //IL_0734: Unknown result type (might be due to invalid IL or missing references) //IL_0739: Unknown result type (might be due to invalid IL or missing references) //IL_074c: Unknown result type (might be due to invalid IL or missing references) //IL_075c: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)_rb == (Object)null) { return; } GroundCheckFixed(); if (((Component)this).transform.position.y < -30f || ((Component)this).transform.position.y < _home.y - 4f) { Plugin.Log.LogWarning((object)$"[NpcWalker] '{((Object)this).name}' fell out of world ({((Component)this).transform.position.y:F1} vs home {_home.y:F1}), rescuing home"); _rb.linearVelocity = Vector3.zero; _rb.MovePosition(_home + Vector3.up * 1f); ((Component)this).transform.SetPositionAndRotation(_home + Vector3.up * 1f, _homeRot); _hasTarget = false; _idleTimer = RngRange(Plugin.IdleMin.Value, Plugin.IdleMax.Value); return; } if (!Homing() && !_retire && (((Component)this).transform.position.y < _home.y - 1.2f || (WaterY() > -999f && ((Component)this).transform.position.y < WaterY() + 0.1f))) { _target = _home; _target.y = ((Component)this).transform.position.y; _hasTarget = true; _stuckTime = 0f; } Vector3 linearVelocity = _rb.linearVelocity; Vector3 val = default(Vector3); ((Vector3)(ref val))..ctor(linearVelocity.x, 0f, linearVelocity.z); if (!_hasTarget && !Homing() && !_retire) { _idleTimer -= Time.fixedDeltaTime; if (_idleTimer <= 0f && !_faceLock.HasValue) { PickTarget(); } } if (_faceLock.HasValue) { Vector3 value = _faceLock.Value; value.y = 0f; if (((Vector3)(ref value)).sqrMagnitude > 0.001f) { Quaternion val2 = Quaternion.LookRotation(((Vector3)(ref value)).normalized, Vector3.up); _rb.MoveRotation(Quaternion.RotateTowards(_rb.rotation, val2, 180f * Time.fixedDeltaTime)); if (Quaternion.Angle(_rb.rotation, val2) < 12f) { _faceLock = null; _idleTimer = 0.2f; } } else { _faceLock = null; } val = Vector3.MoveTowards(val, Vector3.zero, 18f * Time.fixedDeltaTime); _rb.linearVelocity = new Vector3(val.x, linearVelocity.y, val.z); _stuckTime = 0f; return; } if (!_hasTarget) { val = Vector3.MoveTowards(val, Vector3.zero, 14.400001f * Time.fixedDeltaTime); _rb.linearVelocity = new Vector3(val.x, linearVelocity.y, val.z); return; } Vector3 val3 = _target - ((Component)this).transform.position; val3.y = 0f; float magnitude = ((Vector3)(ref val3)).magnitude; if (magnitude < 0.5f) { val = Vector3.MoveTowards(val, Vector3.zero, 14.400001f * Time.fixedDeltaTime); _rb.linearVelocity = new Vector3(val.x, linearVelocity.y, val.z); _stuckTime = 0f; _hasTarget = false; _idleTimer = RngRange(Plugin.IdleMin.Value, Plugin.IdleMax.Value); if (_retire) { _retiredDone = true; } return; } Vector3 val4 = new Vector3(linearVelocity.x, 0f, linearVelocity.z); float magnitude2 = ((Vector3)(ref val4)).magnitude; if (_grounded && magnitude2 < 0.2f) { _stuckTime += Time.fixedDeltaTime; } else { _stuckTime = 0f; } if (_stuckTime > 1.5f) { _stuckTime = 0f; _hasTarget = false; _idleTimer = RngRange(0.4f, 1f); _veerYaw += (float)RngSign() * RngRange(90f, 150f); _veerYaw = Mathf.DeltaAngle(0f, _veerYaw); _pickFails = 99; return; } _veerYaw = Mathf.Clamp(Mathf.DeltaAngle(0f, _veerYaw), -70f, 70f); Quaternion val5 = Quaternion.LookRotation(val3 / magnitude, Vector3.up) * Quaternion.Euler(0f, _veerYaw, 0f); _rb.MoveRotation(Quaternion.RotateTowards(_rb.rotation, val5, 120f * Time.fixedDeltaTime)); _veerYaw = Mathf.MoveTowards(_veerYaw, 0f, 150f * Time.fixedDeltaTime); Vector3 val6 = ((Component)this).transform.position + Vector3.up * 0.45f + ((Component)this).transform.forward * 0.2f; RaycastHit val7 = default(RaycastHit); if (Physics.SphereCast(val6, 0.3f, ((Component)this).transform.forward, ref val7, 0.8f, -1, (QueryTriggerInteraction)1) && !IsSelf(((RaycastHit)(ref val7)).transform)) { if (((RaycastHit)(ref val7)).distance < 0.45f) { _faceLock = EscapeDir(out var _); _hasTarget = false; _idleTimer = 0.2f; _stuckTime = 0f; _veerYaw = 0f; return; } if (IsPlayer(((RaycastHit)(ref val7)).transform)) { _veerYaw += (float)RngSign() * 25f; _stuckTime = 0f; } else { Vector3 val8 = ((Component)this).transform.position + Vector3.up * 1.55f + ((Component)this).transform.forward * 0.35f; RaycastHit val9 = default(RaycastHit); bool flag = !Physics.Raycast(val8, ((Component)this).transform.forward, ref val9, 0.75f, -1, (QueryTriggerInteraction)1) || IsPlayer(((RaycastHit)(ref val9)).transform); float num = float.NegativeInfinity; Vector3 val10 = ((Component)this).transform.position + ((Component)this).transform.forward * 0.55f + Vector3.up * 0.6f; RaycastHit[] array = Physics.RaycastAll(val10, Vector3.down, 1.5f, -1, (QueryTriggerInteraction)1); RaycastHit[] array2 = array; for (int i = 0; i < array2.Length; i++) { RaycastHit val11 = array2[i]; if (!IsSelf(((RaycastHit)(ref val11)).transform) && ((RaycastHit)(ref val11)).point.y > num) { num = ((RaycastHit)(ref val11)).point.y; } } float num2 = num - _groundY; if (_grounded && flag && num2 > 0.05f && num2 <= 0.45f) { _climbTime = 0.45f; } else if (!flag || num2 > 0.45f) { _hasTarget = false; _idleTimer = RngRange(0.3f, 0.8f); _veerYaw += (float)RngSign() * RngRange(60f, 120f); return; } } } Vector3 val12 = ((Component)this).transform.forward * Plugin.WalkSpeed.Value; val = Vector3.MoveTowards(val, val12, 12f * Time.fixedDeltaTime); float y = linearVelocity.y; if (_climbTime > 0f && _grounded) { _climbTime -= Time.fixedDeltaTime; _rb.MovePosition(_rb.position + Vector3.up * (2.2f * Time.fixedDeltaTime)); } if (Plugin.PartyMode.Value && _grounded && Time.time >= _nextPartyHop) { _nextPartyHop = Time.time + RngRange(1.5f, 3.5f); _spinLeft = 360f; } if (_spinLeft > 0f) { float num3 = Mathf.Min(_spinLeft, 720f * Time.fixedDeltaTime); _rb.MoveRotation(_rb.rotation * Quaternion.Euler(0f, num3, 0f)); _spinLeft -= num3; } _rb.linearVelocity = new Vector3(val.x, y, val.z); } private void GroundCheckFixed() { //IL_001c: 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_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_0042: 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_0078: 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_00a3: Unknown result type (might be due to invalid IL or missing references) _grounded = false; if ((Object)(object)_col == (Object)null) { return; } Vector3 val = ((Component)this).transform.position + Vector3.up * (_col.radius + 0.35f); RaycastHit val2 = default(RaycastHit); if (Physics.SphereCast(val, _col.radius * 0.9f, Vector3.down, ref val2, 0.8f, -1, (QueryTriggerInteraction)1) && !IsSelf(((RaycastHit)(ref val2)).transform)) { float num = Vector3.Angle(Vector3.up, ((RaycastHit)(ref val2)).normal); _grounded = num < 50f; if (_grounded) { _groundY = ((RaycastHit)(ref val2)).point.y; } } } private void PickTarget() { //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_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_0058: 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_0072: Unknown result type (might be due to invalid IL or missing references) //IL_0077: Unknown result type (might be due to invalid IL or missing references) //IL_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_0095: Unknown result type (might be due to invalid IL or missing references) //IL_009a: Unknown result type (might be due to invalid IL or missing references) //IL_00a2: Unknown result type (might be due to invalid IL or missing references) //IL_00a7: Unknown result type (might be due to invalid IL or missing references) //IL_00a9: Unknown result type (might be due to invalid IL or missing references) //IL_00ae: Unknown result type (might be due to invalid IL or missing references) //IL_016b: Unknown result type (might be due to invalid IL or missing references) //IL_0189: Unknown result type (might be due to invalid IL or missing references) //IL_018e: Unknown result type (might be due to invalid IL or missing references) //IL_0193: Unknown result type (might be due to invalid IL or missing references) //IL_0195: Unknown result type (might be due to invalid IL or missing references) //IL_019c: 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_010e: Unknown result type (might be due to invalid IL or missing references) //IL_0119: Unknown result type (might be due to invalid IL or missing references) //IL_011e: Unknown result type (might be due to invalid IL or missing references) //IL_0125: Unknown result type (might be due to invalid IL or missing references) //IL_012a: Unknown result type (might be due to invalid IL or missing references) //IL_012f: Unknown result type (might be due to invalid IL or missing references) //IL_01ae: Unknown result type (might be due to invalid IL or missing references) //IL_01b7: Unknown result type (might be due to invalid IL or missing references) //IL_01b8: Unknown result type (might be due to invalid IL or missing references) //IL_01c9: Unknown result type (might be due to invalid IL or missing references) _vanillaFrozen = false; float num = Mathf.Max(2f, Plugin.WanderRadius.Value * 2f); Vector3 val = ((Component)this).transform.position - _home; val.y = 0f; for (int i = 0; i < 4; i++) { Vector3 val3; if (((Vector3)(ref val)).magnitude > num) { Vector3 val2 = -((Vector3)(ref val)).normalized * RngRange(1.5f, 3f); val2 = Quaternion.Euler(0f, RngAngle(40f), 0f) * val2; val3 = ((Component)this).transform.position + val2; } else if (i < 3 && RngChance(0.699999988079071)) { float num2 = RngAngle(65f); float num3 = RngRange(0.8f, Mathf.Max(1f, Plugin.WanderRadius.Value)); val3 = ((Component)this).transform.position + Quaternion.Euler(0f, num2, 0f) * ((Component)this).transform.forward * num3; } else { float num4 = RngRange(0f, MathF.PI * 2f); float num5 = RngRange(0.8f, Mathf.Max(1f, Plugin.WanderRadius.Value)); val3 = ((Component)this).transform.position + new Vector3(Mathf.Cos(num4) * num5, 0f, Mathf.Sin(num4) * num5); } if (HasGroundNear(val3, ((Component)this).transform.position.y) && WalkOutClear(val3)) { _target = val3; _target.y = ((Component)this).transform.position.y; _hasTarget = true; _stuckTime = 0f; _pickFails = 0; return; } } _pickFails++; if (_pickFails >= 3) { _pickFails = 0; if (TryEscape()) { return; } } _hasTarget = false; _idleTimer = RngRange(0.4f, 0.9f); _veerYaw += RngRange(90f, 150f); } private Vector3 EscapeDir(out float clearDist) { //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) //IL_0015: Unknown result type (might be due to invalid IL or missing references) //IL_001a: Unknown result type (might be due to invalid IL or missing references) //IL_001f: Unknown result type (might be due to invalid IL or missing references) //IL_002c: Unknown result type (might be due to invalid IL or missing references) //IL_0031: Unknown result type (might be due to invalid IL or missing references) //IL_0036: Unknown result type (might be due to invalid IL or missing references) //IL_0051: Unknown result type (might be due to invalid IL or missing references) //IL_0056: Unknown result type (might be due to invalid IL or missing references) //IL_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_0069: Unknown result type (might be due to invalid IL or missing references) //IL_006f: 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_00b1: 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) Vector3 val = ((Component)this).transform.position + Vector3.up * 0.9f; float num = 0f; Vector3 result = -((Component)this).transform.forward; RaycastHit val3 = default(RaycastHit); for (int i = 0; i < 8; i++) { float num2 = (float)i * 45f; Vector3 val2 = Quaternion.Euler(0f, num2, 0f) * Vector3.forward; float num3 = 1.6f; if (Physics.SphereCast(val, 0.3f, val2, ref val3, 1.6f, -1, (QueryTriggerInteraction)1) && !IsSelf(((RaycastHit)(ref val3)).transform)) { num3 = Mathf.Max(0f, ((RaycastHit)(ref val3)).distance - 0.35f); } if (num3 > num) { num = num3; result = val2; } } clearDist = num; return result; } private bool TryEscape() { //IL_0003: Unknown result type (might be due to invalid IL or missing references) //IL_0008: Unknown result type (might be due to invalid IL or missing references) //IL_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_0067: 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_0071: Unknown result type (might be due to invalid IL or missing references) //IL_0082: Unknown result type (might be due to invalid IL or missing references) float clearDist; Vector3 val = EscapeDir(out clearDist); if (clearDist < 0.35f) { Plugin.Log.LogInfo((object)("[NpcWalker] '" + ((Object)this).name + "' fully boxed in, waiting")); _hasTarget = false; _idleTimer = RngRange(3f, 6f); return true; } _target = ((Component)this).transform.position + val * Mathf.Min(clearDist, 1.6f); _target.y = ((Component)this).transform.position.y; _hasTarget = true; _stuckTime = 0f; return true; } private bool WalkOutClear(Vector3 candidate) { //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) //IL_0015: Unknown result type (might be due to invalid IL or missing references) //IL_001a: Unknown result type (might be due to invalid IL or missing references) //IL_001f: 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_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_0031: 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_0062: 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_0068: 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) Vector3 val = ((Component)this).transform.position + Vector3.up * 0.9f; Vector3 val2 = candidate - ((Component)this).transform.position; val2.y = 0f; float num = Mathf.Min(((Vector3)(ref val2)).magnitude, 1.2f); if (num < 0.2f) { return false; } val2 /= ((Vector3)(ref val2)).magnitude; RaycastHit val3 = default(RaycastHit); if (Physics.SphereCast(val, 0.3f, val2, ref val3, num, -1, (QueryTriggerInteraction)1) && !IsSelf(((RaycastHit)(ref val3)).transform)) { return false; } return true; } private bool IsSelf(Transform? t) { if ((Object)(object)t == (Object)null) { return false; } if (!((Object)(object)t == (Object)(object)((Component)this).transform)) { return t.IsChildOf(((Component)this).transform); } return true; } private static bool IsPlayer(Transform? t) { if ((Object)(object)t == (Object)null) { return false; } try { return (Object)(object)PlayerManager.GetPlayerFromBodyPart(t) != (Object)null; } catch { return false; } } private bool HasGroundNear(Vector3 pos, float refY) { //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_0003: Unknown result type (might be due to invalid IL or missing references) //IL_000d: Unknown result type (might be due to invalid IL or missing references) //IL_0012: Unknown result type (might be due to invalid IL or missing references) //IL_0017: 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_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_0057: 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_0098: Unknown result type (might be due to invalid IL or missing references) Ray val = default(Ray); ((Ray)(ref val))..ctor(pos + Vector3.up * 1.5f, Vector3.down); RaycastHit[] array = Physics.RaycastAll(val, 8f, -1, (QueryTriggerInteraction)1); float num = WaterY(); RaycastHit[] array2 = array; for (int i = 0; i < array2.Length; i++) { RaycastHit val2 = array2[i]; if (!IsSelf(((RaycastHit)(ref val2)).transform) && !(Mathf.Abs(((RaycastHit)(ref val2)).point.y - refY) > 1.2f) && !(((RaycastHit)(ref val2)).point.y < _home.y - 0.8f) && (!(num > -999f) || !(((RaycastHit)(ref val2)).point.y < num + 0.15f))) { return true; } } return false; } private static float WaterY() { try { return WaterManager.WaterHeight; } catch { return -1000f; } } private void ApplyWalk(float dt) { //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_00e7: Unknown result type (might be due to invalid IL or missing references) //I