Please disclose if any significant portion of your mod was created using AI tools by adding the 'AI Generated' category. Failing to do so may result in the mod being removed from Thunderstore.
Decompiled source of hololive 5th Generation v1.0.1
NePoLaBoSuit.dll
Decompiled 24 minutes ago
The result has been truncated due to the large size, download it to view full contents!
using System; using System.Collections; using System.Collections.Generic; using System.Diagnostics; using System.IO; using System.Linq; using System.Linq.Expressions; using System.Reflection; using System.Runtime.CompilerServices; using System.Security.Cryptography; using System.Text; using BepInEx; using BepInEx.Configuration; using GameNetcodeStuff; using HarmonyLib; using ModelReplacement; using ModelReplacement.AvatarBodyUpdater; using ModelReplacement.Scripts.Player; using Unity.Collections; using Unity.Netcode; using UnityEngine; using UnityEngine.InputSystem; using UnityEngine.InputSystem.Controls; using UnityEngine.Rendering; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: AssemblyCopyright("© 2016 cover corp.")] [assembly: AssemblyFileVersion("1.0.1")] [assembly: AssemblyInformationalVersion("1.0.1")] [assembly: AssemblyVersion("1.0.1.0")] namespace NePoLaBoSuit; [Serializable] public struct NePoLaBoLightingContext { public bool InsideFactory; public bool InsideShip; public bool Indoors { get { if (!InsideFactory) { return InsideShip; } return true; } } public float Floor { get { if (!Indoors) { return 0.075f; } return 0f; } } public NePoLaBoLightingContext(bool factory, bool ship) { InsideFactory = factory; InsideShip = ship; } } public sealed class NePoLaBoCorpseLightingContext { private NePoLaBoLightingContext context; private bool trackedItem; public NePoLaBoCorpseLightingContext(NePoLaBoLightingContext death) { context = death; } public NePoLaBoLightingContext Observe(bool bodyInShip, bool hasHolder, NePoLaBoLightingContext holder, bool hasItem, NePoLaBoLightingContext item) { if (hasHolder) { context = holder; trackedItem = true; } else if (hasItem && trackedItem) { context = item; } if (!bodyInShip) { return context; } return new NePoLaBoLightingContext(factory: false, ship: true); } } [DefaultExecutionOrder(600)] public sealed class NePoLaBoAdaptiveLighting : MonoBehaviour { private struct Draw { public Renderer Renderer; public int Slot; public bool Floor; public bool Ink; public Color InkColor; } public Renderer[] receivers; private readonly List<Draw> draws = new List<Draw>(); private MaterialPropertyBlock block; private Func<NePoLaBoLightingContext> contextReader; private bool initialized; private static readonly int FloorId = Shader.PropertyToID("_GflAmbientFloor"); private static readonly int InkId = Shader.PropertyToID("_InkColor"); public NePoLaBoLightingContext Context { get; private set; } public float CurrentFloor => Context.Floor; public int FloorSlots { get; private set; } public int InkSlots { get; private set; } private void Awake() { Rebind(); Refresh(); } private void OnEnable() { if (initialized) { Refresh(); } } public void Rebind() { //IL_0009: Unknown result type (might be due to invalid IL or missing references) //IL_0013: Expected O, but got Unknown //IL_00da: Unknown result type (might be due to invalid IL or missing references) //IL_00cc: Unknown result type (might be due to invalid IL or missing references) //IL_00df: Unknown result type (might be due to invalid IL or missing references) if (block == null) { block = new MaterialPropertyBlock(); } draws.Clear(); int floorSlots = (InkSlots = 0); FloorSlots = floorSlots; receivers = ((Component)this).GetComponentsInChildren<Renderer>(true); Renderer[] array = receivers; foreach (Renderer val in array) { Material[] sharedMaterials = val.sharedMaterials; for (int i = 0; i < sharedMaterials.Length; i++) { Material val2 = sharedMaterials[i]; if (!Object.op_Implicit((Object)(object)val2)) { continue; } bool flag = val2.HasProperty(FloorId); bool flag2 = val2.HasProperty(InkId); if (flag || flag2) { draws.Add(new Draw { Renderer = val, Slot = i, Floor = flag, Ink = flag2, InkColor = (flag2 ? val2.GetColor(InkId) : Color.black) }); if (flag) { FloorSlots++; } if (flag2) { InkSlots++; } } } } initialized = true; Apply(Context); } public void BindContext(Func<NePoLaBoLightingContext> reader) { contextReader = reader; Refresh(); } public NePoLaBoLightingContext ReadContext() { if (contextReader == null) { return Context; } return contextReader(); } public void InheritContext(NePoLaBoAdaptiveLighting source) { if (Object.op_Implicit((Object)(object)source)) { BindContext(source.ReadContext); } } public void Refresh() { Apply(ReadContext()); } public void Apply(NePoLaBoLightingContext context) { //IL_0088: Unknown result type (might be due to invalid IL or missing references) //IL_008d: Unknown result type (might be due to invalid IL or missing references) //IL_00be: 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) if (!initialized) { Rebind(); } Context = context; foreach (Draw draw in draws) { if (!Object.op_Implicit((Object)(object)draw.Renderer)) { continue; } block.Clear(); draw.Renderer.GetPropertyBlock(block, draw.Slot); if (draw.Floor) { block.SetFloat(FloorId, context.Floor); } if (draw.Ink) { Color inkColor = draw.InkColor; if (context.Indoors) { ((Color)(ref inkColor))..ctor(0f, 0f, 0f, inkColor.a); } block.SetColor(InkId, inkColor); } draw.Renderer.SetPropertyBlock(block, draw.Slot); } } private void LateUpdate() { Refresh(); } } internal static class NePoLaBoLightingControl { private sealed class Death { internal ulong Owner; internal NePoLaBoLightingContext Context; } private static readonly Dictionary<PlayerControllerB, Death> deaths = new Dictionary<PlayerControllerB, Death>(); private static readonly FieldInfo sourceField = AccessTools.Field(typeof(BodyReplacementBase), "replacementModel"); private static readonly FieldInfo shadowField = AccessTools.Field(typeof(BodyReplacementBase), "replacementModelShadow"); private static readonly FieldInfo viewField = AccessTools.Field(typeof(BodyReplacementBase), "replacementViewModel"); private static NePoLaBoLightingContext Native(PlayerControllerB player) { if (!Object.op_Implicit((Object)(object)player)) { return default(NePoLaBoLightingContext); } return new NePoLaBoLightingContext(player.isInsideFactory, player.isInHangarShipRoom); } internal static void Install(Harmony harmony) { //IL_0028: Unknown result type (might be due to invalid IL or missing references) //IL_0035: Expected O, but got Unknown //IL_009e: Unknown result type (might be due to invalid IL or missing references) //IL_00ac: Expected O, but got Unknown //IL_00d4: Unknown result type (might be due to invalid IL or missing references) //IL_00e2: Expected O, but got Unknown //IL_010b: Unknown result type (might be due to invalid IL or missing references) //IL_0118: Expected O, but got Unknown //IL_0069: Unknown result type (might be due to invalid IL or missing references) //IL_0076: Expected O, but got Unknown harmony.Patch((MethodBase)AccessTools.Method(typeof(BodyReplacementBase), "Awake", (Type[])null, (Type[])null), (HarmonyMethod)null, new HarmonyMethod(typeof(NePoLaBoLightingControl), "Created", (Type[])null), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null); MethodInfo methodInfo = AccessTools.Method(typeof(BodyReplacementBase), "LoadRagdollReplacement", (Type[])null, (Type[])null); if (methodInfo != null) { harmony.Patch((MethodBase)methodInfo, (HarmonyMethod)null, new HarmonyMethod(typeof(NePoLaBoLightingControl), "Ragdoll", (Type[])null), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null); } harmony.Patch((MethodBase)AccessTools.Method(typeof(PlayerControllerB), "KillPlayer", (Type[])null, (Type[])null), new HarmonyMethod(typeof(NePoLaBoLightingControl), "CaptureDeath", (Type[])null), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null); harmony.Patch((MethodBase)AccessTools.Method(typeof(PlayerControllerB), "SpawnDeadBody", (Type[])null, (Type[])null), new HarmonyMethod(typeof(NePoLaBoLightingControl), "CaptureRemoteDeath", (Type[])null), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null); harmony.Patch((MethodBase)AccessTools.Method(typeof(StartOfRound), "ReviveDeadPlayers", (Type[])null, (Type[])null), (HarmonyMethod)null, new HarmonyMethod(typeof(NePoLaBoLightingControl), "Clear", (Type[])null), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null); } private static void CaptureDeath(PlayerControllerB __instance) { if (Object.op_Implicit((Object)(object)__instance) && !__instance.isPlayerDead) { deaths[__instance] = new Death { Owner = ((NetworkBehaviour)__instance).OwnerClientId, Context = Native(__instance) }; } } private static void CaptureRemoteDeath(PlayerControllerB deadPlayerController) { if (Object.op_Implicit((Object)(object)deadPlayerController) && !((NetworkBehaviour)deadPlayerController).IsOwner) { deaths[deadPlayerController] = new Death { Owner = ((NetworkBehaviour)deadPlayerController).OwnerClientId, Context = Native(deadPlayerController) }; } } private static void Created(BodyReplacementBase __instance) { if (__instance is NePoLaBoBody nePoLaBoBody && Object.op_Implicit((Object)(object)((BodyReplacementBase)nePoLaBoBody).controller)) { FieldInfo[] array = new FieldInfo[3] { sourceField, shadowField, viewField }; for (int i = 0; i < array.Length; i++) { object? obj = array[i]?.GetValue(nePoLaBoBody); Bind((GameObject)((obj is GameObject) ? obj : null), ((BodyReplacementBase)nePoLaBoBody).controller); } } } internal static void AttachView(GameObject playerObject, GameObject view) { if (Object.op_Implicit((Object)(object)playerObject) && Object.op_Implicit((Object)(object)view) && Object.op_Implicit((Object)(object)view.GetComponent<NePoLaBoAdaptiveLighting>())) { Bind(view, playerObject.GetComponent<PlayerControllerB>()); } } private static void Ragdoll(BodyReplacementBase __instance, GameObject __result) { if (__instance is NePoLaBoBody nePoLaBoBody && Object.op_Implicit((Object)(object)((BodyReplacementBase)nePoLaBoBody).controller)) { Bind(__result, ((BodyReplacementBase)nePoLaBoBody).controller, corpse: true); } } private static void Bind(GameObject model, PlayerControllerB player, bool corpse = false) { if (!Object.op_Implicit((Object)(object)model) || !Object.op_Implicit((Object)(object)player)) { return; } NePoLaBoAdaptiveLighting nePoLaBoAdaptiveLighting = model.GetComponent<NePoLaBoAdaptiveLighting>() ?? model.AddComponent<NePoLaBoAdaptiveLighting>(); nePoLaBoAdaptiveLighting.Rebind(); ulong owner = ((NetworkBehaviour)player).OwnerClientId; if (!corpse) { nePoLaBoAdaptiveLighting.BindContext(() => (!Object.op_Implicit((Object)(object)player) || ((NetworkBehaviour)player).OwnerClientId != owner) ? default(NePoLaBoLightingContext) : Native(player)); return; } Death value; NePoLaBoLightingContext death = ((deaths.TryGetValue(player, out value) && value.Owner == owner) ? value.Context : Native(player)); NePoLaBoCorpseLightingContext corpseContext = new NePoLaBoCorpseLightingContext(death); DeadBodyInfo nativeBody = player.deadBody; nePoLaBoAdaptiveLighting.BindContext(delegate { if (!Object.op_Implicit((Object)(object)nativeBody)) { return corpseContext.Observe(bodyInShip: false, hasHolder: false, default(NePoLaBoLightingContext), hasItem: false, default(NePoLaBoLightingContext)); } GrabbableObject grabBodyObject = nativeBody.grabBodyObject; PlayerControllerB val = ((Object.op_Implicit((Object)(object)grabBodyObject) && grabBodyObject.isHeld) ? grabBodyObject.playerHeldBy : null); return corpseContext.Observe(nativeBody.isInShip || nativeBody.parentedToShip, Object.op_Implicit((Object)(object)val), Native(val), Object.op_Implicit((Object)(object)grabBodyObject), Object.op_Implicit((Object)(object)grabBodyObject) ? new NePoLaBoLightingContext(grabBodyObject.isInFactory, grabBodyObject.isInShipRoom) : default(NePoLaBoLightingContext)); }); } internal static void Clear() { deaths.Clear(); } } public enum AttentionKind { Player, Enemy, Item } public struct AttentionCandidate { public int Key; public AttentionKind Kind; public float Distance; public bool Speaking; public bool Eligible; public AttentionCandidate(int key, AttentionKind kind, float distance, bool speaking = true, bool eligible = true) { Key = key; Kind = kind; Distance = distance; Speaking = speaking; Eligible = eligible; } } public sealed class NePoLaBoAttentionSelection { private float lastSpeech; private float selectedAt; public int CurrentKey { get; private set; } public bool HasTarget { get; private set; } public AttentionKind CurrentKind { get; private set; } public void Reset() { HasTarget = false; CurrentKey = 0; lastSpeech = (selectedAt = 0f); } public int Choose(IList<AttentionCandidate> candidates, float now, float pauseHold = 1.2f) { AttentionCandidate attentionCandidate = default(AttentionCandidate); AttentionCandidate c = default(AttentionCandidate); AttentionCandidate c2 = default(AttentionCandidate); bool flag = false; bool flag2 = false; bool flag3 = false; foreach (AttentionCandidate candidate in candidates) { if (!candidate.Eligible || float.IsNaN(candidate.Distance) || float.IsInfinity(candidate.Distance) || candidate.Distance < 0f) { continue; } if (HasTarget && candidate.Key == CurrentKey && candidate.Kind == CurrentKind) { attentionCandidate = candidate; flag = true; } if (candidate.Kind == AttentionKind.Player) { if (candidate.Speaking && (!flag2 || candidate.Distance < c.Distance)) { c = candidate; flag2 = true; } } else if (!flag3 || candidate.Kind < c2.Kind || (candidate.Kind == c2.Kind && candidate.Distance < c2.Distance)) { c2 = candidate; flag3 = true; } } if (flag && attentionCandidate.Kind == AttentionKind.Player && attentionCandidate.Speaking) { lastSpeech = now; } if (flag2) { if (flag && attentionCandidate.Kind == AttentionKind.Player && attentionCandidate.Speaking && (now - selectedAt < 0.65f || c.Distance >= attentionCandidate.Distance * 0.7f)) { return CurrentKey; } return Select(c, now); } if (flag && attentionCandidate.Kind == AttentionKind.Player && now - lastSpeech <= Mathf.Clamp(pauseHold, 0f, 5f)) { return CurrentKey; } if (flag3) { if (flag && attentionCandidate.Kind == c2.Kind && attentionCandidate.Kind != AttentionKind.Player && (now - selectedAt < 1.5f || c2.Distance >= attentionCandidate.Distance * 0.7f)) { return CurrentKey; } return Select(c2, now); } Reset(); return 0; } private int Select(AttentionCandidate c, float now) { if (!HasTarget || c.Key != CurrentKey || c.Kind != CurrentKind) { selectedAt = now; } HasTarget = true; CurrentKey = c.Key; CurrentKind = c.Kind; if (c.Kind == AttentionKind.Player && c.Speaking) { lastSpeech = now; } return CurrentKey; } public static bool InView(Vector3 origin, Vector3 forward, Vector3 point, float radius) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_0020: Unknown result type (might be due to invalid IL or missing references) //IL_0021: Unknown result type (might be due to invalid IL or missing references) //IL_0026: Unknown result type (might be due to invalid IL or missing references) //IL_002b: Unknown result type (might be due to invalid IL or missing references) //IL_002c: Unknown result type (might be due to invalid IL or missing references) //IL_002d: Unknown result type (might be due to invalid IL or missing references) //IL_0032: Unknown result type (might be due to invalid IL or missing references) //IL_0037: Unknown result type (might be due to invalid IL or missing references) //IL_0038: Unknown result type (might be due to invalid IL or missing references) //IL_0039: Unknown result type (might be due to invalid IL or missing references) //IL_0046: Unknown result type (might be due to invalid IL or missing references) Vector3 val = point - origin; float sqrMagnitude = ((Vector3)(ref val)).sqrMagnitude; if (sqrMagnitude < 0.0225f || sqrMagnitude > radius * radius) { return false; } Vector3 val2 = Vector3.ProjectOnPlane(val, Vector3.up); Vector3 val3 = Vector3.ProjectOnPlane(forward, Vector3.up); if (Vector3.Angle(val2, val3) <= 65f) { return Mathf.Abs(Mathf.Atan2(val.y, ((Vector3)(ref val2)).magnitude) * 57.29578f) <= 60f; } return false; } public static bool ActiveSpeech(bool speaking, float amplitude) { if (speaking && !float.IsNaN(amplitude) && !float.IsInfinity(amplitude)) { return amplitude >= 0.002f; } return false; } public static bool Visible(Vector3 origin, Vector3 point, int mask, Transform observer, Transform model, Transform target, RaycastHit[] hits) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_0007: 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_001b: 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) Vector3 val = point - origin; float magnitude = ((Vector3)(ref val)).magnitude; if (magnitude < 0.05f) { return true; } int num = Physics.RaycastNonAlloc(origin, val / magnitude, hits, magnitude, mask, (QueryTriggerInteraction)1); if (num == hits.Length) { return false; } for (int i = 0; i < num; i++) { Transform transform = ((RaycastHit)(ref hits[i])).transform; if (Object.op_Implicit((Object)(object)transform) && (!Object.op_Implicit((Object)(object)observer) || !transform.IsChildOf(observer)) && (!Object.op_Implicit((Object)(object)model) || !transform.IsChildOf(model)) && (!Object.op_Implicit((Object)(object)target) || !transform.IsChildOf(target))) { return false; } } return true; } } public sealed class NePoLaBoAttention { private sealed class ItemRenderer { public GrabbableObject Item; public Renderer Renderer; } private readonly NePoLaBoAttentionSelection selection = new NePoLaBoAttentionSelection(); private readonly List<AttentionCandidate> candidates = new List<AttentionCandidate>(64); private readonly Dictionary<int, Object> objects = new Dictionary<int, Object>(); private readonly RaycastHit[] hits = (RaycastHit[])(object)new RaycastHit[24]; private static EnemyAI[] enemies = (EnemyAI[])(object)new EnemyAI[0]; private static GrabbableObject[] items = (GrabbableObject[])(object)new GrabbableObject[0]; private static float nextSceneScan; private static StartOfRound scene; private static readonly Dictionary<int, ItemRenderer> itemRenderers = new Dictionary<int, ItemRenderer>(); private static readonly HashSet<int> aliveItems = new HashSet<int>(); private static readonly List<int> staleItems = new List<int>(); private Object target; private float nextScan; public void Reset() { selection.Reset(); target = null; nextScan = 0f; } private static void ScanScene(float now) { if ((Object)(object)scene != (Object)(object)StartOfRound.Instance) { scene = StartOfRound.Instance; nextSceneScan = 0f; itemRenderers.Clear(); } if (now < nextSceneScan) { return; } nextSceneScan = now + 1f; enemies = NePoLaBoSceneCache.Enemies(now); items = Object.FindObjectsByType<GrabbableObject>((FindObjectsSortMode)0); aliveItems.Clear(); GrabbableObject[] array = items; foreach (GrabbableObject val in array) { if (Object.op_Implicit((Object)(object)val)) { aliveItems.Add(((Object)val).GetInstanceID()); } } staleItems.Clear(); foreach (KeyValuePair<int, ItemRenderer> itemRenderer in itemRenderers) { if (!aliveItems.Contains(itemRenderer.Key)) { staleItems.Add(itemRenderer.Key); } } foreach (int staleItem in staleItems) { itemRenderers.Remove(staleItem); } } internal static void ClearSceneCache() { scene = null; nextSceneScan = 0f; enemies = (EnemyAI[])(object)new EnemyAI[0]; items = (GrabbableObject[])(object)new GrabbableObject[0]; itemRenderers.Clear(); aliveItems.Clear(); staleItems.Clear(); } private static Vector3 Point(Object value) { //IL_003d: Unknown result type (might be due to invalid IL or missing references) //IL_001d: Unknown result type (might be due to invalid IL or missing references) //IL_0022: Unknown result type (might be due to invalid IL or missing references) //IL_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_0102: Unknown result type (might be due to invalid IL or missing references) //IL_0076: Unknown result type (might be due to invalid IL or missing references) //IL_0060: 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_006a: Unknown result type (might be due to invalid IL or missing references) //IL_00f3: 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_00fc: Unknown result type (might be due to invalid IL or missing references) //IL_00e6: Unknown result type (might be due to invalid IL or missing references) PlayerControllerB val = (PlayerControllerB)(object)((value is PlayerControllerB) ? value : null); if (val != null) { if (!Object.op_Implicit((Object)(object)val.playerEye)) { return ((Component)val).transform.position + Vector3.up * 1.6f; } return val.playerEye.position; } EnemyAI val2 = (EnemyAI)(object)((value is EnemyAI) ? value : null); if (val2 != null) { if (!Object.op_Implicit((Object)(object)val2.eye)) { return ((Component)val2).transform.position + Vector3.up; } return val2.eye.position; } GrabbableObject val3 = (GrabbableObject)(object)((value is GrabbableObject) ? value : null); if (val3 != null) { int instanceID = ((Object)val3).GetInstanceID(); if (!itemRenderers.TryGetValue(instanceID, out var value2) || (Object)(object)value2.Item != (Object)(object)val3) { value2 = new ItemRenderer { Item = val3, Renderer = ((Component)val3).GetComponentInChildren<Renderer>() }; itemRenderers[instanceID] = value2; } if (!Object.op_Implicit((Object)(object)value2.Renderer)) { return ((Component)val3).transform.position; } Bounds bounds = value2.Renderer.bounds; return ((Bounds)(ref bounds)).center; } return Vector3.zero; } private void Add(Component value, AttentionKind kind, Vector3 origin, Vector3 forward, float range, bool speaking, PlayerControllerB owner, Transform model) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_0008: Unknown result type (might be due to invalid IL or missing references) //IL_000a: Unknown result type (might be due to invalid IL or missing references) //IL_0030: Unknown result type (might be due to invalid IL or missing references) //IL_0031: Unknown result type (might be due to invalid IL or missing references) //IL_006c: Unknown result type (might be due to invalid IL or missing references) //IL_006d: Unknown result type (might be due to invalid IL or missing references) Vector3 val = Point((Object)(object)value); if (NePoLaBoAttentionSelection.InView(origin, forward, val, range)) { int mask = (Object.op_Implicit((Object)(object)StartOfRound.Instance) ? StartOfRound.Instance.collidersAndRoomMaskAndDefault : (-5)); if (NePoLaBoAttentionSelection.Visible(origin, val, mask, ((Component)owner).transform, model, value.transform, hits)) { int instanceID = ((Object)value).GetInstanceID(); objects[instanceID] = (Object)(object)value; candidates.Add(new AttentionCandidate(instanceID, kind, Vector3.Distance(origin, val), speaking)); } } } public bool Resolve(PlayerControllerB owner, Transform model, Vector3 origin, Vector3 forward, float now, out Vector3 direction) { //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_0004: Unknown result type (might be due to invalid IL or missing references) //IL_02b6: Unknown result type (might be due to invalid IL or missing references) //IL_02bb: Unknown result type (might be due to invalid IL or missing references) //IL_02bc: Unknown result type (might be due to invalid IL or missing references) //IL_02c1: Unknown result type (might be due to invalid IL or missing references) //IL_0153: Unknown result type (might be due to invalid IL or missing references) //IL_0154: Unknown result type (might be due to invalid IL or missing references) //IL_00fa: Unknown result type (might be due to invalid IL or missing references) //IL_00fb: Unknown result type (might be due to invalid IL or missing references) //IL_01ba: Unknown result type (might be due to invalid IL or missing references) //IL_01bb: Unknown result type (might be due to invalid IL or missing references) direction = forward; if (!Object.op_Implicit((Object)(object)owner) || owner.isPlayerDead || !owner.isPlayerControlled || !Object.op_Implicit((Object)(object)StartOfRound.Instance)) { Reset(); return false; } if (now >= nextScan) { nextScan = now + 0.1f; candidates.Clear(); objects.Clear(); ScanScene(now); PlayerControllerB[] allPlayerScripts = StartOfRound.Instance.allPlayerScripts; foreach (PlayerControllerB val in allPlayerScripts) { if (Object.op_Implicit((Object)(object)val) && !((Object)(object)val == (Object)(object)owner) && val.isPlayerControlled && !val.isPlayerDead && ((Component)val).gameObject.activeInHierarchy) { bool flag = NePoLaBoVoiceActivity.IsSpeaking(val); if (flag || (selection.HasTarget && selection.CurrentKind == AttentionKind.Player && selection.CurrentKey == ((Object)val).GetInstanceID())) { Add((Component)(object)val, AttentionKind.Player, origin, forward, Plugin.TalkingPlayersRange.Value, flag, owner, model); } } } EnemyAI[] array = enemies; foreach (EnemyAI val2 in array) { if (Object.op_Implicit((Object)(object)val2) && !val2.isEnemyDead && ((Behaviour)val2).isActiveAndEnabled) { Add((Component)(object)val2, AttentionKind.Enemy, origin, forward, Plugin.EnemiesRange.Value, speaking: false, owner, model); } } GrabbableObject[] array2 = items; foreach (GrabbableObject val3 in array2) { if (Object.op_Implicit((Object)(object)val3) && !val3.isHeld && !val3.isPocketed && !val3.isHeldByEnemy && ((Behaviour)val3).isActiveAndEnabled) { Add((Component)(object)val3, AttentionKind.Item, origin, forward, Plugin.ItemsRange.Value, speaking: false, owner, model); } } int key = selection.Choose(candidates, now, Plugin.SpeechPauseHold.Value); target = ((selection.HasTarget && objects.TryGetValue(key, out var value)) ? value : null); } if (!Object.op_Implicit(target)) { return false; } Object obj = target; PlayerControllerB val4 = (PlayerControllerB)(object)((obj is PlayerControllerB) ? obj : null); if (val4 == null || (val4.isPlayerControlled && !val4.isPlayerDead)) { Object obj2 = target; EnemyAI val5 = (EnemyAI)(object)((obj2 is EnemyAI) ? obj2 : null); if (val5 == null || !val5.isEnemyDead) { Object obj3 = target; GrabbableObject val6 = (GrabbableObject)(object)((obj3 is GrabbableObject) ? obj3 : null); if (val6 == null || (!val6.isHeld && !val6.isPocketed && !val6.isHeldByEnemy)) { direction = Point(target) - origin; return ((Vector3)(ref direction)).sqrMagnitude > 1E-06f; } } } target = null; selection.Reset(); nextScan = 0f; return false; } } internal static class NePoLaBoVoiceActivity { private static object comms; private static readonly Dictionary<int, float> retry = new Dictionary<int, float>(); private static readonly Dictionary<int, object> states = new Dictionary<int, object>(); internal static bool IsSpeaking(PlayerControllerB player) { object obj = NePoLaBoFace.Read(player, "voicePlayerState") ?? NePoLaBoFace.Read(NePoLaBoFace.Read(player, "currentVoiceChatIngameSettings"), "_playerState"); int instanceID = ((Object)player).GetInstanceID(); if (obj == null && states.TryGetValue(instanceID, out var value)) { obj = value; } if (obj == null && (!retry.TryGetValue(instanceID, out var value2) || Time.unscaledTime >= value2)) { retry[instanceID] = Time.unscaledTime + 1f; comms = NePoLaBoFace.Read(StartOfRound.Instance, "voiceChatModule"); if (comms != null) { string text = (((NetworkBehaviour)player).IsOwner ? (NePoLaBoFace.Read(comms, "LocalPlayerName") as string) : (NePoLaBoFace.Read(player, "voicePlayerName") as string)); if (!string.IsNullOrEmpty(text)) { try { obj = NePoLaBoRuntimeMembers.CallString(comms, "FindPlayer", text); if (obj != null) { states[instanceID] = obj; } } catch { } } } } bool value3; bool flag = NePoLaBoRuntimeMembers.TryRead<bool>(obj, "IsSpeaking", out value3) && value3; if (NePoLaBoRuntimeMembers.TryRead<bool>(obj, "IsConnected", out var value4) && !value4) { return false; } if (!NePoLaBoRuntimeMembers.TryRead<float>(obj, "Amplitude", out var value5)) { return flag; } return NePoLaBoAttentionSelection.ActiveSpeech(flag, value5); } internal static void Clear() { comms = null; retry.Clear(); states.Clear(); } } public sealed class NePoLaBoBundleCache { public const string PackedSHA256 = "b4645c092438f78e4ea386655fb8611c69a2d7cf03cabf81b4eeadf7c5e35c94"; public const uint ContentCRC = 4040354875u; private string packedPath; private string pendingPath; private FileStream output; private SHA256 digest; public AssetBundle Bundle { get; private set; } public bool CacheHit { get; private set; } public bool Rebuilt { get; private set; } public bool UsedFallback { get; private set; } public string Warning { get; private set; } public string CachePath { get; private set; } private bool Prepare(string directory) { try { Directory.CreateDirectory(directory); CachePath = Path.Combine(directory, "b4645c092438f78e4ea386655fb8611c69a2d7cf03cabf81b4eeadf7c5e35c94.bundle"); string text = Guid.NewGuid().ToString("N"); packedPath = Path.Combine(directory, "b4645c092438f78e4ea386655fb8611c69a2d7cf03cabf81b4eeadf7c5e35c94." + text + ".packed"); pendingPath = Path.Combine(directory, "b4645c092438f78e4ea386655fb8611c69a2d7cf03cabf81b4eeadf7c5e35c94." + text + ".pending"); return true; } catch (Exception ex) { Warning = "Model cache unavailable: " + ex.Message; return false; } } private bool OpenOutput(Stream source) { try { source.Position = 0L; output = new FileStream(packedPath, FileMode.CreateNew, FileAccess.Write, FileShare.None); digest = SHA256.Create(); return true; } catch (Exception ex) { Warning = "Model cache staging failed: " + ex.Message; CloseOutput(); return false; } } private int Copy(Stream source, byte[] buffer) { try { int num = source.Read(buffer, 0, buffer.Length); if (num > 0) { output.Write(buffer, 0, num); digest.TransformBlock(buffer, 0, num, buffer, 0); } return num; } catch (Exception ex) { Warning = "Model cache write failed: " + ex.Message; return -1; } } private bool FinishOutput() { try { digest.TransformFinalBlock(Array.Empty<byte>(), 0, 0); if (BitConverter.ToString(digest.Hash).Replace("-", "").ToLowerInvariant() != "b4645c092438f78e4ea386655fb8611c69a2d7cf03cabf81b4eeadf7c5e35c94") { Warning = "Embedded model checksum differs; loading directly."; return false; } return true; } catch (Exception ex) { Warning = "Model checksum verification failed: " + ex.Message; return false; } finally { CloseOutput(); } } private void CloseOutput() { output?.Dispose(); output = null; digest?.Dispose(); digest = null; } private void RemoveOwnedTemporaryFiles() { CloseOutput(); string[] array = new string[2] { packedPath, pendingPath }; foreach (string text in array) { if (string.IsNullOrEmpty(text)) { continue; } try { if (File.Exists(text)) { File.Delete(text); } } catch (Exception) { } } } private bool Commit() { try { if (File.Exists(CachePath)) { File.Delete(CachePath); } File.Move(pendingPath, CachePath); return true; } catch (Exception ex) { Warning = "Model cache commit failed: " + ex.Message; return false; } } private AssetBundleCreateRequest LoadFile() { try { return AssetBundle.LoadFromFileAsync(CachePath, 4040354875u); } catch (Exception ex) { Warning = "Model cache load failed: " + ex.Message; return null; } } private AssetBundleRecompressOperation Recompress() { //IL_000c: Unknown result type (might be due to invalid IL or missing references) try { return AssetBundle.RecompressAssetBundleAsync(packedPath, pendingPath, BuildCompression.LZ4Runtime, 4040354875u, (ThreadPriority)0); } catch (Exception ex) { Warning = "Model cache conversion failed: " + ex.Message; return null; } } private AssetBundleCreateRequest LoadDirect(Stream source) { try { source.Position = 0L; return AssetBundle.LoadFromStreamAsync(source, 4040354875u); } catch (Exception ex) { Warning = "Direct model load failed: " + ex.Message; return null; } } public IEnumerator Load(Stream source, string directory) { if (source == null) { Warning = "Missing embedded models."; yield break; } try { if (Prepare(directory)) { if (File.Exists(CachePath)) { AssetBundleCreateRequest warm = LoadFile(); if (warm != null) { yield return warm; if (Object.op_Implicit((Object)(object)warm.assetBundle)) { Bundle = warm.assetBundle; CacheHit = true; yield break; } } } bool staged = OpenOutput(source); if (staged) { byte[] buffer = new byte[2097152]; while (true) { int num = Copy(source, buffer); if (num < 0) { staged = false; break; } if (num == 0) { break; } yield return null; } if (staged) { staged = FinishOutput(); } else { CloseOutput(); } } if (staged) { AssetBundleRecompressOperation convert = Recompress(); if (convert != null) { yield return convert; if (convert.success && Commit()) { AssetBundleCreateRequest warm = LoadFile(); if (warm != null) { yield return warm; if (Object.op_Implicit((Object)(object)warm.assetBundle)) { Bundle = warm.assetBundle; Rebuilt = true; yield break; } } } else { Warning = "Model cache conversion did not complete: " + convert.humanReadableResult; } } } } UsedFallback = true; AssetBundleCreateRequest direct = LoadDirect(source); if (direct != null) { yield return direct; Bundle = direct.assetBundle; } } finally { RemoveOwnedTemporaryFiles(); } } } public sealed class NePoLaBoChestGazeTarget : MonoBehaviour { public Transform chest; public Transform[] breasts = (Transform[])(object)new Transform[0]; public Vector3 Point { get { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0005: Unknown result type (might be due to invalid IL or missing references) //IL_0021: Unknown result type (might be due to invalid IL or missing references) //IL_0024: Unknown result type (might be due to invalid IL or missing references) //IL_0029: Unknown result type (might be due to invalid IL or missing references) //IL_002e: 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_007d: 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_0054: Unknown result type (might be due to invalid IL or missing references) //IL_0059: Unknown result type (might be due to invalid IL or missing references) //IL_0063: Unknown result type (might be due to invalid IL or missing references) //IL_0068: Unknown result type (might be due to invalid IL or missing references) Vector3 val = Vector3.zero; int num = 0; Transform[] array = breasts; foreach (Transform val2 in array) { if (Object.op_Implicit((Object)(object)val2)) { val += val2.position; num++; } } if (num <= 0) { if (!Object.op_Implicit((Object)(object)chest)) { return ((Component)this).transform.position + Vector3.up * 1.3f; } return chest.position; } return val / (float)num; } } } public enum NePoLaBoExpression : byte { Neutral, Frightened, Hurt, Happy, Surprised, VeryHappy, Dead } public struct NePoLaBoExpressionContext { public bool Dead; public bool Critical; public bool EnemyNear; public bool Fear; public bool Chased; public bool Dancing; public bool Unsafe { get { if (!EnemyNear && !Fear) { return Chased; } return true; } } } public sealed class NePoLaBoExpressionSelection { private double hurtUntil = -1.0; private double treasureUntil = -1.0; private bool surprised = true; private int pickups; public void Damage(double now) { hurtUntil = now + 2.0; } public void PickedUp(int value, double now) { if (value > 100) { treasureUntil = now + 3.5; surprised = pickups++ % 2 == 0; } } public void Reset() { hurtUntil = (treasureUntil = -1.0); pickups = 0; surprised = true; } public NePoLaBoExpression Choose(NePoLaBoExpressionContext c, double now) { if (c.Dead) { return NePoLaBoExpression.Dead; } if (c.Critical || now < hurtUntil) { return NePoLaBoExpression.Hurt; } if (c.Unsafe) { return NePoLaBoExpression.Frightened; } if (now < treasureUntil) { if (!surprised) { return NePoLaBoExpression.VeryHappy; } return NePoLaBoExpression.Surprised; } if (c.Dancing) { return NePoLaBoExpression.Happy; } return NePoLaBoExpression.Neutral; } } public struct NePoLaBoExpressionWeight { public string Shape; public float Weight; public bool Eyes; public bool Mouth; public NePoLaBoExpressionWeight(string shape, float weight, bool eyes = false, bool mouth = false) { Shape = "expr_" + shape; Weight = weight; Eyes = eyes; Mouth = mouth; } } public static class NePoLaBoExpressionProfiles { private static readonly NePoLaBoExpressionWeight[][] profiles = new NePoLaBoExpressionWeight[7][] { new NePoLaBoExpressionWeight[0], new NePoLaBoExpressionWeight[4] { B("worry", 0.75f), B("brow_up", 0.25f), E("surprise", 0.85f), M("triangle", 0.6f) }, new NePoLaBoExpressionWeight[4] { B("worry", 0.85f), B("serious", 0.25f), E("focus", 0.45f), M("clench", 0.8f) }, new NePoLaBoExpressionWeight[3] { B("happy_brows", 0.45f), E("smile_eyes", 0.65f), M("smile", 0.85f) }, new NePoLaBoExpressionWeight[3] { B("brow_up", 0.65f), E("surprise", 0.9f), M("o", 0.65f) }, new NePoLaBoExpressionWeight[3] { B("happy_brows", 0.65f), E("smile_eyes", 0.85f), M("laugh", 0.85f) }, new NePoLaBoExpressionWeight[2] { B("worry", 0.7f), M("clench", 0.55f) } }; private static NePoLaBoExpressionWeight B(string n, float w) { return new NePoLaBoExpressionWeight(n, w); } private static NePoLaBoExpressionWeight E(string n, float w) { return new NePoLaBoExpressionWeight(n, w, eyes: true); } private static NePoLaBoExpressionWeight M(string n, float w) { return new NePoLaBoExpressionWeight(n, w, eyes: false, mouth: true); } public static NePoLaBoExpressionWeight[] Weights(NePoLaBoExpression state) { return profiles[(uint)state]; } } public sealed class NePoLaBoExpressionMixer { private sealed class Binding { public SkinnedMeshRenderer Renderer; public int[] Indices; public int Blink; public int Open; public int Round; } private readonly List<string> shapes = new List<string>(); private readonly Dictionary<string, int> slots = new Dictionary<string, int>(); private readonly List<Binding> bindings = new List<Binding>(); private float[] values; private float[] target; private bool[] eyes; private bool[] mouth; private readonly List<Tuple<SkinnedMeshRenderer, int>> angerDraws = new List<Tuple<SkinnedMeshRenderer, int>>(); private readonly MaterialPropertyBlock angerBlock = new MaterialPropertyBlock(); public NePoLaBoExpressionMixer(GameObject model) { //IL_002d: Unknown result type (might be due to invalid IL or missing references) //IL_0037: Expected O, but got Unknown NePoLaBoExpressionWeight[] array; foreach (NePoLaBoExpression value in Enum.GetValues(typeof(NePoLaBoExpression))) { array = NePoLaBoExpressionProfiles.Weights(value); for (int i = 0; i < array.Length; i++) { NePoLaBoExpressionWeight nePoLaBoExpressionWeight = array[i]; if (!slots.ContainsKey(nePoLaBoExpressionWeight.Shape)) { slots[nePoLaBoExpressionWeight.Shape] = shapes.Count; shapes.Add(nePoLaBoExpressionWeight.Shape); } } } array = NePoLaBoPersonalityProfiles.Managed; for (int i = 0; i < array.Length; i++) { NePoLaBoExpressionWeight nePoLaBoExpressionWeight2 = array[i]; if (!slots.ContainsKey(nePoLaBoExpressionWeight2.Shape)) { slots[nePoLaBoExpressionWeight2.Shape] = shapes.Count; shapes.Add(nePoLaBoExpressionWeight2.Shape); } } values = new float[shapes.Count]; target = new float[shapes.Count]; eyes = new bool[shapes.Count]; mouth = new bool[shapes.Count]; foreach (NePoLaBoExpression value2 in Enum.GetValues(typeof(NePoLaBoExpression))) { array = NePoLaBoExpressionProfiles.Weights(value2); for (int i = 0; i < array.Length; i++) { NePoLaBoExpressionWeight nePoLaBoExpressionWeight3 = array[i]; int num = slots[nePoLaBoExpressionWeight3.Shape]; eyes[num] |= nePoLaBoExpressionWeight3.Eyes; mouth[num] |= nePoLaBoExpressionWeight3.Mouth; } } array = NePoLaBoPersonalityProfiles.Managed; for (int i = 0; i < array.Length; i++) { NePoLaBoExpressionWeight nePoLaBoExpressionWeight4 = array[i]; int num2 = slots[nePoLaBoExpressionWeight4.Shape]; eyes[num2] |= nePoLaBoExpressionWeight4.Eyes; mouth[num2] |= nePoLaBoExpressionWeight4.Mouth; } SkinnedMeshRenderer[] componentsInChildren = model.GetComponentsInChildren<SkinnedMeshRenderer>(true); foreach (SkinnedMeshRenderer val in componentsInChildren) { if (!Object.op_Implicit((Object)(object)val.sharedMesh) || NePoLaBoInkOutline.IsInk(val)) { continue; } Binding binding = new Binding { Renderer = val, Indices = new int[shapes.Count], Blink = val.sharedMesh.GetBlendShapeIndex("blink"), Open = val.sharedMesh.GetBlendShapeIndex("speech_open"), Round = val.sharedMesh.GetBlendShapeIndex("speech_round") }; for (int j = 0; j < shapes.Count; j++) { binding.Indices[j] = val.sharedMesh.GetBlendShapeIndex(shapes[j]); } bindings.Add(binding); Material[] sharedMaterials = ((Renderer)val).sharedMaterials; for (int k = 0; k < sharedMaterials.Length; k++) { if (Object.op_Implicit((Object)(object)sharedMaterials[k]) && ((Object)sharedMaterials[k]).name.Contains("_AngerMark_")) { angerDraws.Add(Tuple.Create<SkinnedMeshRenderer, int>(val, k)); } } } } public void Step(NePoLaBoExpression state, float delta, bool immediate = false) { Step("", new NePoLaBoFaceState(state), delta, immediate); } public void Step(string character, NePoLaBoFaceState face, float delta, bool immediate = false) { NePoLaBoExpression expression = face.Expression; Array.Clear(target, 0, target.Length); float num = ((face.Reaction == NePoLaBoReaction.None) ? 1f : ((float)(int)face.Strength / 255f)); NePoLaBoExpressionWeight[] array = NePoLaBoPersonalityProfiles.Weights(character, face); for (int i = 0; i < array.Length; i++) { NePoLaBoExpressionWeight nePoLaBoExpressionWeight = array[i]; target[slots[nePoLaBoExpressionWeight.Shape]] = nePoLaBoExpressionWeight.Weight * ((nePoLaBoExpressionWeight.Shape == "expr_anger_mark") ? 1f : num); } if (character == "ShishiroBotan" && face.Reaction == NePoLaBoReaction.Critical) { target[slots["expr_ears_side"]] = 1f; } if (character == "ShishiroBotan" && face.Reaction == NePoLaBoReaction.Stunned) { target[slots["expr_ears_up"]] = 1f; } foreach (Tuple<SkinnedMeshRenderer, int> angerDraw in angerDraws) { if (Object.op_Implicit((Object)(object)angerDraw.Item1)) { ((Renderer)angerDraw.Item1).GetPropertyBlock(angerBlock, angerDraw.Item2); angerBlock.SetFloat("_GflOpacity", (face.Reaction == NePoLaBoReaction.Angry) ? num : 0f); ((Renderer)angerDraw.Item1).SetPropertyBlock(angerBlock, angerDraw.Item2); } } float num2 = ((immediate || expression == NePoLaBoExpression.Dead) ? 1f : (1f - Mathf.Exp((0f - Mathf.Clamp(delta, 0f, 0.1f)) * 13f))); for (int j = 0; j < values.Length; j++) { values[j] = Mathf.Lerp(values[j], target[j], num2); } foreach (Binding binding in bindings) { if (!Object.op_Implicit((Object)(object)binding.Renderer)) { continue; } float num3 = ((binding.Blink < 0) ? 0f : Mathf.Clamp01(binding.Renderer.GetBlendShapeWeight(binding.Blink) / 100f)); float num4 = ((binding.Open < 0) ? 0f : Mathf.Clamp01(binding.Renderer.GetBlendShapeWeight(binding.Open) / 85f)); if (expression == NePoLaBoExpression.Dead) { num3 = 1f; num4 = 0f; if (binding.Blink >= 0) { binding.Renderer.SetBlendShapeWeight(binding.Blink, 100f); } if (binding.Open >= 0) { binding.Renderer.SetBlendShapeWeight(binding.Open, 0f); } if (binding.Round >= 0) { binding.Renderer.SetBlendShapeWeight(binding.Round, 0f); } } for (int k = 0; k < values.Length; k++) { if (binding.Indices[k] >= 0) { float num5 = values[k]; if (eyes[k]) { num5 *= 1f - num3; } if (mouth[k]) { num5 *= 1f - num4 * 0.55f; } binding.Renderer.SetBlendShapeWeight(binding.Indices[k], num5 * 100f); } } } } } [DefaultExecutionOrder(280)] public sealed class NePoLaBoDeathFace : MonoBehaviour { private NePoLaBoExpressionMixer mixer; public void Initialize() { mixer = new NePoLaBoExpressionMixer(((Component)this).gameObject); mixer.Step(NePoLaBoExpression.Dead, 0f, immediate: true); } private void LateUpdate() { if (mixer == null) { Initialize(); } mixer.Step(NePoLaBoExpression.Dead, 0f, immediate: true); } } public struct NePoLaBoExpressionRecord { public ulong PlayerId; public ulong Owner; public byte Character; public NePoLaBoExpression Expression; public uint Revision; public NePoLaBoReaction Reaction; public byte Strength; public ulong GazePlayerId; public float GazeWeight; } public sealed class NePoLaBoExpressionStore { private sealed class Entry { public NePoLaBoExpressionRecord Record; public double At; } private readonly Dictionary<ulong, Entry> records = new Dictionary<ulong, Entry>(); public bool Accept(ulong sender, ulong actualOwner, NePoLaBoExpressionRecord value, double now) { if (sender != actualOwner || value.Owner != actualOwner || !NePoLaBoPersonalityProfiles.Valid(value.Character, new NePoLaBoFaceState { Expression = value.Expression, Reaction = value.Reaction, Strength = value.Strength }) || float.IsNaN(value.GazeWeight) || float.IsInfinity(value.GazeWeight) || value.GazeWeight < 0f || value.GazeWeight > 1f || (value.GazeWeight > 0f && (value.Character != 3 || value.Reaction != NePoLaBoReaction.Hearts || value.GazePlayerId == value.PlayerId)) || double.IsNaN(now) || double.IsInfinity(now)) { return false; } if (records.TryGetValue(value.PlayerId, out var value2) && value2.Record.Owner == actualOwner && (value.Revision < value2.Record.Revision || (value.Revision == value2.Record.Revision && (value.Character != value2.Record.Character || value.Expression != value2.Record.Expression || value.Reaction != value2.Record.Reaction || value.Strength != value2.Record.Strength || value.GazePlayerId != value2.Record.GazePlayerId || value.GazeWeight != value2.Record.GazeWeight)))) { return false; } records[value.PlayerId] = new Entry { Record = value, At = now }; return true; } public bool TryGet(ulong id, double now, out NePoLaBoExpressionRecord value) { value = default(NePoLaBoExpressionRecord); if (!records.TryGetValue(id, out var value2) || now - value2.At > 5.0 || now < value2.At) { return false; } value = value2.Record; return true; } public uint NextRevision(ulong id, ulong owner) { if (!records.TryGetValue(id, out var value) || value.Record.Owner != owner) { return 1u; } return value.Record.Revision + 1; } public NePoLaBoExpressionRecord[] Snapshot(double now) { List<NePoLaBoExpressionRecord> list = new List<NePoLaBoExpressionRecord>(); foreach (Entry value in records.Values) { if (now >= value.At && now - value.At <= 5.0) { list.Add(value.Record); } } list.Sort((NePoLaBoExpressionRecord a, NePoLaBoExpressionRecord b) => a.PlayerId.CompareTo(b.PlayerId)); return list.ToArray(); } public void RemoveOwner(ulong owner) { List<ulong> list = new List<ulong>(); foreach (KeyValuePair<ulong, Entry> record in records) { if (record.Value.Record.Owner == owner) { list.Add(record.Key); } } foreach (ulong item in list) { records.Remove(item); } } public void Clear() { records.Clear(); } } public static class NePoLaBoFirstPersonMesh { private sealed class Entry { public Mesh Mesh; public int[] BoneIndices; public int[] MaterialSlots; } private static readonly Dictionary<Mesh, Entry> Cache = new Dictionary<Mesh, Entry>(); public static int CachedMeshes => Cache.Count; private static HashSet<Transform> ArmBones(GameObject model) { //IL_0042: Unknown result type (might be due to invalid IL or missing references) //IL_0045: Unknown result type (might be due to invalid IL or missing references) Animator componentInChildren = model.GetComponentInChildren<Animator>(true); if (!Object.op_Implicit((Object)(object)componentInChildren) || !componentInChildren.isHuman) { throw new InvalidOperationException("NePoLaBo first-person avatar must be humanoid."); } HashSet<Transform> hashSet = new HashSet<Transform>(); HumanBodyBones[] array = new HumanBodyBones[6]; RuntimeHelpers.InitializeArray(array, (RuntimeFieldHandle)/*OpCode not supported: LdMemberToken*/); HumanBodyBones[] array2 = (HumanBodyBones[])(object)array; foreach (HumanBodyBones val in array2) { Transform boneTransform = componentInChildren.GetBoneTransform(val); if (Object.op_Implicit((Object)(object)boneTransform)) { Transform[] componentsInChildren = ((Component)boneTransform).GetComponentsInChildren<Transform>(true); foreach (Transform item in componentsInChildren) { hashSet.Add(item); } } } return hashSet; } public static void Prime(GameObject model) { HashSet<Transform> arms = ArmBones(model); SkinnedMeshRenderer[] componentsInChildren = model.GetComponentsInChildren<SkinnedMeshRenderer>(true); for (int i = 0; i < componentsInChildren.Length; i++) { Get(componentsInChildren[i], arms); } } public static IEnumerator PrimeIncremental(GameObject model) { HashSet<Transform> arms = ArmBones(model); SkinnedMeshRenderer[] componentsInChildren = model.GetComponentsInChildren<SkinnedMeshRenderer>(true); for (int i = 0; i < componentsInChildren.Length; i++) { Get(componentsInChildren[i], arms); yield return null; } } private static bool Allowed(BoneWeight weight, bool[] bones) { if ((((BoneWeight)(ref weight)).weight0 <= 0f || bones[((BoneWeight)(ref weight)).boneIndex0]) && (((BoneWeight)(ref weight)).weight1 <= 0f || bones[((BoneWeight)(ref weight)).boneIndex1]) && (((BoneWeight)(ref weight)).weight2 <= 0f || bones[((BoneWeight)(ref weight)).boneIndex2])) { if (!(((BoneWeight)(ref weight)).weight3 <= 0f)) { return bones[((BoneWeight)(ref weight)).boneIndex3]; } return true; } return false; } private static Entry Get(SkinnedMeshRenderer renderer, HashSet<Transform> arms) { //IL_00b7: Unknown result type (might be due to invalid IL or missing references) //IL_0202: Unknown result type (might be due to invalid IL or missing references) //IL_0207: Unknown result type (might be due to invalid IL or missing references) //IL_030f: Unknown result type (might be due to invalid IL or missing references) //IL_0314: Unknown result type (might be due to invalid IL or missing references) //IL_032a: Unknown result type (might be due to invalid IL or missing references) //IL_02f7: Unknown result type (might be due to invalid IL or missing references) //IL_02f9: Unknown result type (might be due to invalid IL or missing references) //IL_0344: Expected O, but got Unknown //IL_0461: Unknown result type (might be due to invalid IL or missing references) //IL_0466: Unknown result type (might be due to invalid IL or missing references) Mesh sharedMesh = renderer.sharedMesh; if (!Object.op_Implicit((Object)(object)sharedMesh)) { return null; } if (Cache.TryGetValue(sharedMesh, out var value)) { return value; } if (!sharedMesh.isReadable) { throw new InvalidOperationException("NePoLaBo first-person source mesh is not readable: " + ((Object)sharedMesh).name); } Transform[] bones = renderer.bones; bool[] array = new bool[bones.Length]; for (int i = 0; i < array.Length; i++) { array[i] = Object.op_Implicit((Object)(object)bones[i]) && arms.Contains(bones[i]); } BoneWeight[] boneWeights = sharedMesh.boneWeights; if (boneWeights.Length != sharedMesh.vertexCount) { throw new InvalidOperationException("NePoLaBo arms require four-weight source skinning."); } bool[] array2 = new bool[sharedMesh.vertexCount]; for (int j = 0; j < boneWeights.Length; j++) { array2[j] = Allowed(boneWeights[j], array); } List<int> list = new List<int>(); Dictionary<int, int> dictionary = new Dictionary<int, int>(); List<int[]> list2 = new List<int[]>(); List<int> list3 = new List<int>(); for (int k = 0; k < sharedMesh.subMeshCount; k++) { int[] triangles = sharedMesh.GetTriangles(k); List<int> list4 = new List<int>(); for (int l = 0; l < triangles.Length; l += 3) { if (!array2[triangles[l]] || !array2[triangles[l + 1]] || !array2[triangles[l + 2]]) { continue; } for (int m = 0; m < 3; m++) { int num = triangles[l + m]; if (!dictionary.TryGetValue(num, out var value2)) { value2 = list.Count; dictionary.Add(num, value2); list.Add(num); } list4.Add(value2); } } if (list4.Count > 0) { list3.Add(k); list2.Add(list4.ToArray()); } } if (list.Count == 0) { Cache.Add(sharedMesh, null); return null; } List<int> list5 = new List<int>(); Dictionary<int, int> dictionary2 = new Dictionary<int, int>(); BoneWeight[] array3 = (BoneWeight[])(object)new BoneWeight[list.Count]; for (int n = 0; n < array3.Length; n++) { BoneWeight val = boneWeights[list[n]]; int[] array4 = new int[4] { ((BoneWeight)(ref val)).boneIndex0, ((BoneWeight)(ref val)).boneIndex1, ((BoneWeight)(ref val)).boneIndex2, ((BoneWeight)(ref val)).boneIndex3 }; float[] array5 = new float[4] { ((BoneWeight)(ref val)).weight0, ((BoneWeight)(ref val)).weight1, ((BoneWeight)(ref val)).weight2, ((BoneWeight)(ref val)).weight3 }; for (int num2 = 0; num2 < 4; num2++) { if (array5[num2] <= 0f) { array4[num2] = 0; continue; } if (!dictionary2.TryGetValue(array4[num2], out var value3)) { value3 = list5.Count; dictionary2.Add(array4[num2], value3); list5.Add(array4[num2]); } array4[num2] = value3; } ((BoneWeight)(ref val)).boneIndex0 = array4[0]; ((BoneWeight)(ref val)).boneIndex1 = array4[1]; ((BoneWeight)(ref val)).boneIndex2 = array4[2]; ((BoneWeight)(ref val)).boneIndex3 = array4[3]; array3[n] = val; } Mesh val2 = new Mesh { name = ((Object)sharedMesh).name + "_NePoLaBoFirstPerson", indexFormat = (IndexFormat)(list.Count > 65535) }; val2.vertices = Subset(sharedMesh.vertices, list); if (sharedMesh.normals.Length == sharedMesh.vertexCount) { val2.normals = Subset(sharedMesh.normals, list); } if (sharedMesh.tangents.Length == sharedMesh.vertexCount) { val2.tangents = Subset(sharedMesh.tangents, list); } if (sharedMesh.colors32.Length == sharedMesh.vertexCount) { val2.colors32 = Subset(sharedMesh.colors32, list); } for (int num3 = 0; num3 < 8; num3++) { List<Vector4> list6 = new List<Vector4>(); sharedMesh.GetUVs(num3, list6); if (list6.Count == sharedMesh.vertexCount) { val2.SetUVs(num3, Subset(list6.ToArray(), list)); } } for (int num4 = 0; num4 < sharedMesh.blendShapeCount; num4++) { string blendShapeName = sharedMesh.GetBlendShapeName(num4); if (!blendShapeName.StartsWith("opt_", StringComparison.Ordinal)) { continue; } Vector3[] array6 = (Vector3[])(object)new Vector3[sharedMesh.vertexCount]; sharedMesh.GetBlendShapeFrameVertices(num4, 0, array6, (Vector3[])null, (Vector3[])null); Vector3[] array7 = Subset(array6, list); bool flag = false; Vector3[] array8 = array7; for (int num5 = 0; num5 < array8.Length; num5++) { Vector3 val3 = array8[num5]; if (((Vector3)(ref val3)).sqrMagnitude > 1E-14f) { flag = true; break; } } if (flag) { val2.AddBlendShapeFrame(blendShapeName, sharedMesh.GetBlendShapeFrameWeight(num4, 0), array7, (Vector3[])null, (Vector3[])null); } } val2.boneWeights = array3; val2.bindposes = Subset(sharedMesh.bindposes, list5); val2.subMeshCount = list2.Count; for (int num6 = 0; num6 < list2.Count; num6++) { val2.SetTriangles(list2[num6], num6, false); } val2.RecalculateBounds(); value = new Entry { Mesh = val2, BoneIndices = list5.ToArray(), MaterialSlots = list3.ToArray() }; Cache.Add(sharedMesh, value); return value; } private static T[] Subset<T>(T[] source, List<int> indices) { T[] array = new T[indices.Count]; for (int i = 0; i < indices.Count; i++) { array[i] = source[indices[i]]; } return array; } public static GameObject Convert(GameObject model) { NePoLaBoSourceRotationGrant component = model.GetComponent<NePoLaBoSourceRotationGrant>(); NePoLaBoSourceRotationGrant.Grant[] sourceGrants = (Object.op_Implicit((Object)(object)component) ? component.grants : null); HashSet<Transform> arms = ArmBones(model); SkinnedMeshRenderer[] componentsInChildren = model.GetComponentsInChildren<SkinnedMeshRenderer>(true); foreach (SkinnedMeshRenderer val in componentsInChildren) { Entry entry = Get(val, arms); if (entry == null) { ((Renderer)val).enabled = false; Remove((Object)(object)val); continue; } Transform[] bones = val.bones; Material[] sharedMaterials = ((Renderer)val).sharedMaterials; Transform[] array = (Transform[])(object)new Transform[entry.BoneIndices.Length]; Material[] array2 = (Material[])(object)new Material[entry.MaterialSlots.Length]; for (int j = 0; j < array.Length; j++) { array[j] = bones[entry.BoneIndices[j]]; } for (int k = 0; k < array2.Length; k++) { array2[k] = sharedMaterials[entry.MaterialSlots[k]]; } val.sharedMesh = entry.Mesh; val.bones = array; ((Renderer)val).sharedMaterials = array2; val.quality = (SkinQuality)4; val.updateWhenOffscreen = true; ((Renderer)val).shadowCastingMode = (ShadowCastingMode)0; } StripSimulation(model); NePoLaBoViewModelPose obj = model.GetComponent<NePoLaBoViewModelPose>() ?? model.AddComponent<NePoLaBoViewModelPose>(); obj.SourceGrants = sourceGrants; obj.Initialize(); model.GetComponent<NePoLaBoAdaptiveLighting>()?.Rebind(); model.GetComponent<NePoLaBoOutfitState>()?.Rebind(); return model; } public static void StripSimulation(GameObject model) { Collider[] componentsInChildren = model.GetComponentsInChildren<Collider>(true); foreach (Collider obj in componentsInChildren) { obj.enabled = false; Remove((Object)(object)obj); } MonoBehaviour[] componentsInChildren2 = model.GetComponentsInChildren<MonoBehaviour>(true); foreach (MonoBehaviour val in componentsInChildren2) { if (Object.op_Implicit((Object)(object)val)) { switch (((object)val).GetType().FullName) { case "NePoLaBoSuit.NePoLaBoSecondaryMotion": case "NePoLaBoSuit.NePoLaBoHeadTracking": case "NePoLaBoSuit.NePoLaBoFace": case "NePoLaBoSuit.NePoLaBoToonFrame": case "NePoLaBoSuit.NePoLaBoSourceRotationGrant": case "NePoLaBoSuit.NePoLaBoReactionFace": case "JigglePhysics.JiggleRigBuilder": ((Behaviour)val).enabled = false; Remove((Object)(object)val); break; } } } } private static void Remove(Object component) { if (Application.isPlaying) { Object.Destroy(component); } else { Object.DestroyImmediate(component); } } public static void Clear() { foreach (Entry value in Cache.Values) { if (value != null && Object.op_Implicit((Object)(object)value.Mesh)) { Remove((Object)(object)value.Mesh); } } Cache.Clear(); } } public static class NePoLaBoFirstPersonPatch { public static void Install(Harmony harmony) { //IL_0067: Unknown result type (might be due to invalid IL or missing references) //IL_0075: Expected O, but got Unknown //IL_009e: Unknown result type (might be due to invalid IL or missing references) //IL_00ab: Expected O, but got Unknown //IL_0105: Unknown result type (might be due to invalid IL or missing references) //IL_0113: Expected O, but got Unknown //IL_0152: Unknown result type (might be due to invalid IL or missing references) //IL_015f: Expected O, but got Unknown Type type = typeof(BodyReplacementBase).Assembly.GetType("ModelReplacement.Scripts.MeshHelper", throwOnError: true); MethodInfo methodInfo = AccessTools.Method(type, "ConvertModelToViewModel", new Type[1] { typeof(GameObject) }, (Type[])null); if (methodInfo == null) { throw new MissingMethodException(type.FullName, "ConvertModelToViewModel"); } harmony.Patch((MethodBase)methodInfo, new HarmonyMethod(typeof(NePoLaBoFirstPersonPatch), "BeforeConvert", (Type[])null), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null); harmony.Patch((MethodBase)AccessTools.Method(typeof(BodyReplacementBase), "Awake", (Type[])null, (Type[])null), (HarmonyMethod)null, new HarmonyMethod(typeof(NePoLaBoFirstPersonPatch), "AfterBodyCreated", (Type[])null), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null); Type type2 = typeof(BodyReplacementBase).Assembly.GetType("ModelReplacement.Scripts.Player.ViewModelUpdater", throwOnError: true); MethodInfo methodInfo2 = AccessTools.Method(type2, "UpdateViewModel", Type.EmptyTypes, (Type[])null); if (methodInfo2 == null) { throw new MissingMethodException(type2.FullName, "UpdateViewModel"); } harmony.Patch((MethodBase)methodInfo2, new HarmonyMethod(typeof(NePoLaBoFirstPersonPatch), "BeforeViewPose", (Type[])null), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null); harmony.Patch((MethodBase)AccessTools.Method(type2, "AssignViewModelReplacement", new Type[2] { typeof(GameObject), typeof(GameObject) }, (Type[])null), (HarmonyMethod)null, new HarmonyMethod(typeof(NePoLaBoFirstPersonPatch), "AfterViewAssigned", (Type[])null), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null); } private static bool BeforeConvert(GameObject __0, ref GameObject __result) { if (!Object.op_Implicit((Object)(object)__0) || !((Object)__0).name.StartsWith("NePoLaBo_", StringComparison.Ordinal)) { return true; } __result = NePoLaBoFirstPersonMesh.Convert(__0); return false; } private static void AfterBodyCreated(BodyReplacementBase __instance) { if (!(__instance is NePoLaBoBody)) { return; } object? value = AccessTools.Field(typeof(BodyReplacementBase), "replacementModel").GetValue(__instance); GameObject val = (GameObject)((value is GameObject) ? value : null); object? value2 = AccessTools.Field(typeof(BodyReplacementBase), "replacementModelShadow").GetValue(__instance); GameObject val2 = (GameObject)((value2 is GameObject) ? value2 : null); if (Object.op_Implicit((Object)(object)val) && Object.op_Implicit((Object)(object)val2)) { NePoLaBoFirstPersonMesh.StripSimulation(val2); val2.AddComponent<NePoLaBoShadowPose>().Initialize(val); } object? value3 = AccessTools.Field(typeof(BodyReplacementBase), "replacementViewModel").GetValue(__instance); GameObject val3 = (GameObject)((value3 is GameObject) ? value3 : null); if (Object.op_Implicit((Object)(object)val3) && Object.op_Implicit((Object)(object)__instance.controller)) { NePoLaBoViewModelPose component = val3.GetComponent<NePoLaBoViewModelPose>(); SkinnedMeshRenderer thisPlayerModelArms = __instance.controller.thisPlayerModelArms; if (Object.op_Implicit((Object)(object)component) && Object.op_Implicit((Object)(object)thisPlayerModelArms)) { component.Bind(thisPlayerModelArms, __instance.controller.playerModelArmsMetarig); } } } private static bool BeforeViewPose(ViewModelUpdater __instance) { GameObject replacementViewModel = __instance.replacementViewModel; if (!Object.op_Implicit((Object)(object)replacementViewModel)) { return true; } NePoLaBoViewModelPose component = replacementViewModel.GetComponent<NePoLaBoViewModelPose>(); if (Object.op_Implicit((Object)(object)component)) { return !component.Step(); } return true; } private static void AfterViewAssigned(GameObject __0, GameObject __1) { if (!Object.op_Implicit((Object)(object)__0) || !Object.op_Implicit((Object)(object)__1)) { return; } NePoLaBoOutfitControl.AttachView(__0, __1); NePoLaBoViewModelPose component = __1.GetComponent<NePoLaBoViewModelPose>(); if (Object.op_Implicit((Object)(object)component)) { PlayerControllerB component2 = __0.GetComponent<PlayerControllerB>(); if (Object.op_Implicit((Object)(object)component2)) { component.Bind(component2.thisPlayerModelArms, component2.playerModelArmsMetarig); } } } } public class NePoLaBoFootAlignment : MonoBehaviour { private Transform hip; private Transform leftSole; private Transform rightSole; private Transform playerLeft; private Transform playerRight; private Vector3 leftReference; private Vector3 rightReference; private SkinnedMeshRenderer source; private bool ready; public float LastCorrection { get; private set; } public void Align(SkinnedMeshRenderer player) { //IL_01de: Unknown result type (might be due to invalid IL or missing references) //IL_01e3: Unknown result type (might be due to invalid IL or missing references) //IL_01f4: Unknown result type (might be due to invalid IL or missing references) //IL_01f9: Unknown result type (might be due to invalid IL or missing references) //IL_020f: Unknown result type (might be due to invalid IL or missing references) //IL_021f: Unknown result type (might be due to invalid IL or missing references) //IL_025a: Unknown result type (might be due to invalid IL or missing references) //IL_025f: Unknown result type (might be due to invalid IL or missing references) //IL_026a: Unknown result type (might be due to invalid IL or missing references) //IL_026f: Unknown result type (might be due to invalid IL or missing references) //IL_01c0: Unknown result type (might be due to invalid IL or missing references) //IL_01c5: 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_01d2: Unknown result type (might be due to invalid IL or missing references) if (!Object.op_Implicit((Object)(object)player)) { return; } if (!ready || (Object)(object)source != (Object)(object)player) { source = player; Animator component = ((Component)this).GetComponent<Animator>(); if (!Object.op_Implicit((Object)(object)component) || !component.isHuman) { return; } hip = component.GetBoneTransform((HumanBodyBones)0); Transform[] componentsInChildren = ((Component)this).GetComponentsInChildren<Transform>(true); leftSole = ((IEnumerable<Transform>)componentsInChildren).FirstOrDefault((Func<Transform, bool>)((Transform t) => ((Object)t).name == "NePoLaBoSole.L")); rightSole = ((IEnumerable<Transform>)componentsInChildren).FirstOrDefault((Func<Transform, bool>)((Transform t) => ((Object)t).name == "NePoLaBoSole.R")); Transform val = ((IEnumerable<Transform>)componentsInChildren).FirstOrDefault((Func<Transform, bool>)((Transform t) => ((Object)t).name == "EmployeeSoleReference.L")); Transform val2 = ((IEnumerable<Transform>)componentsInChildren).FirstOrDefault((Func<Transform, bool>)((Transform t) => ((Object)t).name == "EmployeeSoleReference.R")); playerLeft = ((IEnumerable<Transform>)player.bones).FirstOrDefault((Func<Transform, bool>)((Transform t) => ((Object)t).name == "foot.L")); playerRight = ((IEnumerable<Transform>)player.bones).FirstOrDefault((Func<Transform, bool>)((Transform t) => ((Object)t).name == "foot.R")); ready = Object.op_Implicit((Object)(object)hip) && Object.op_Implicit((Object)(object)leftSole) && Object.op_Implicit((Object)(object)rightSole) && Object.op_Implicit((Object)(object)val) && Object.op_Implicit((Object)(object)val2) && Object.op_Implicit((Object)(object)playerLeft) && Object.op_Implicit((Object)(object)playerRight); if (!ready) { return; } leftReference = val.localPosition; rightReference = val2.localPosition; } float num = Mathf.Min(playerLeft.TransformPoint(leftReference).y, playerRight.TransformPoint(rightReference).y); float num2 = Mathf.Min(leftSole.position.y, rightSole.position.y); LastCorrection = num - num2; if (!float.IsNaN(LastCorrection) && !float.IsInfinity(LastCorrection)) { Transform obj = hip; obj.position += Vector3.up * LastCorrection; } } } public class NePoLaBoHandAlignment : MonoBehaviour { private class Arm { public Transform Upper; public Transform Lower; public Transform Hand; public Transform PlayerUpper; public Transform PlayerLower; public Transform PlayerHand; } private Arm[] arms; private SkinnedMeshRenderer source; public void Align(SkinnedMeshRenderer player) { //IL_01a3: Unknown result type (might be due to invalid IL or missing references) //IL_01a8: Unknown result type (might be due to invalid IL or missing references) //IL_01bf: 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_01ef: Unknown result type (might be due to invalid IL or missing references) //IL_01fb: Unknown result type (might be due to invalid IL or missing references) //IL_0200: Unknown result type (might be due to invalid IL or missing references) //IL_0211: Unknown result type (might be due to invalid IL or missing references) if (!Object.op_Implicit((Object)(object)player)) { return; } if (arms == null || (Object)(object)source != (Object)(object)player) { Animator component = ((Component)this).GetComponent<Animator>(); if (!Object.op_Implicit((Object)(object)component) || !component.isHuman) { return; } source = player; arms = new Arm[2]; for (int i = 0; i < 2; i++) { bool flag = i == 0; string s = (flag ? "L" : "R"); arms[i] = new Arm { Upper = component.GetBoneTransform((HumanBodyBones)(flag ? 13 : 14)), Lower = component.GetBoneTransform((HumanBodyBones)(flag ? 15 : 16)), Hand = component.GetBoneTransform((HumanBodyBones)(flag ? 17 : 18)), PlayerUpper = ((IEnumerable<Transform>)player.bones).FirstOrDefault((Func<Transform, bool>)((Transform t) => ((Object)t).name == "arm." + s + "_upper")), PlayerLower = ((IEnumerable<Transform>)player.bones).FirstOrDefault((Func<Transform, bool>)((Transform t) => ((Object)t).name == "arm." + s + "_lower")), PlayerHand = ((IEnumerable<Transform>)player.bones).FirstOrDefault((Func<Transform, bool>)((Transform t) => ((Object)t).name == "hand." + s)) }; } } Arm[] array = arms; foreach (Arm arm in array) { if (Object.op_Implicit((Object)(object)arm.Upper) && Object.op_Implicit((Object)(object)arm.Lower) && Object.op_Implicit((Object)(object)arm.Hand) && Object.op_Implicit((Object)(object)arm.PlayerUpper) && Object.op_Implicit((Object)(object)arm.PlayerLower) && Object.op_Implicit((Object)(object)arm.PlayerHand)) { Quaternion rotation = arm.Hand.rotation; Aim(arm.Upper, arm.Lower, arm.PlayerLower.position - arm.PlayerUpper.position); Aim(arm.Lower, arm.Hand, arm.PlayerHand.position - arm.PlayerLower.position); arm.Hand.rotation = rotation; } } } private static void Aim(Transform joint, Transform end, Vector3 direction) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_000c: Unknown result type (might be due to invalid IL or missing references) //IL_0011: Unknown result type (might be due to invalid IL or missing references) //IL_002f: Unknown result type (might be due to invalid IL or missing references) //IL_0030: Unknown result type (might be due to invalid IL or missing references) //IL_0031: Unknown result type (might be due to invalid IL or missing references) //IL_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) Vector3 val = end.position - joint.position; if (((Vector3)(ref val)).sqrMagnitude > 1E-08f && ((Vector3)(ref direction)).sqrMagnitude > 1E-08f) { joint.rotation = Quaternion.FromToRotation(val, direction) * joint.rotation; } } } [DefaultExecutionOrder(200)] public class NePoLaBoHeadTracking : MonoBehaviour { public PlayerControllerB Player; private readonly NePoLaBoAttention attention = new NePoLaBoAttention(); public Quaternion? WorldAimFrame; public bool TrackingEnabled = true; private Transform neck; private Transform head; private Quaternion headToLook; private Quaternion neckBase; private Quaternion headBase; private Quaternion neckApplied; private Quaternion headApplied; private Quaternion neutralNeck; private Quaternion neutralHead; private bool ready; private bool applied; private int previousFrame = int.MinValue; private float yaw; private float pitch; private float aimWeight; public const float MaximumYaw = 50f; public const float MaximumUpPitch = 35f; public const float MaximumDownPitch = 45f; public const float MaximumCorrection = 55f; public const float NeckShare = 0.3f; public bool HasAttentionTarget { get; private set; } public Vector3 AttentionDirection { get; private set; } public float CurrentYaw => yaw; public float CurrentPitch => pitch; public float LastCorrectionAngle { get; private set; } public bool Ready => ready; public Vector3 LookForward { get { //IL_001a: Unknown result type (might be due to invalid IL or missing references) //IL_0020: Unknown result type (might be due to invalid IL or missing references) //IL_0025: Unknown result type (might be due to invalid IL or missing references) //IL_002a: Unknown result type (might be due to invalid IL or missing references) //IL_002f: Unknown result type (might be due to invalid IL or missing references) //IL_000e: Unknown result type (might be due to invalid IL or missing references) if (!ready) { return ((Component)this).transform.forward; } return head.rotation * headToLook * Vector3.forward; } } public Vector3 LookUp { get { //IL_001a: Unknown result type (might be due to invalid IL or missing references) //IL_0020: Unknown result type (might be due to invalid IL or missing references) //IL_0025: Unknown result type (might be due to invalid IL or missing references) //IL_002a: Unknown result type (might be due to invalid IL or missing references) //IL_002f: Unknown result type (might be due to invalid IL or missing references) //IL_000e: Unknown result type (might be due to invalid IL or missing references) if (!ready) { return ((Component)this).transform.up; } return head.rotation * headToLook * Vector3.up; } } private void Awake() { Initialize(); } private void Initialize() { //IL_0134: Unknown result type (might be due to invalid IL or missing references) //IL_0139: Unknown result type (might be due to invalid IL or missing references) //IL_014e: Unknown result type (might be due to invalid IL or missing references) //IL_0146: Unknown result type (might be due to invalid IL or missing references) //IL_0153: Unknown result type (might be due to invalid IL or missing references) //IL_0158: Unknown result type (might be due to invalid IL or missing references) //IL_0165: Unknown result type (might be due to invalid IL or missing references) //IL_016a: 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_016c: Unknown result type (might be due to invalid IL or missing references) //IL_0171: Unknown result type (might be due to invalid IL or missing references) //IL_0172: Unknown result type (might be due to invalid IL or missing references) //IL_017f: Unknown result type (might be due to invalid IL or missing references) //IL_0184: Unknown result type (might be due to invalid IL or missing references) //IL_0185: Unknown result type (might be due to invalid IL or missing references) //IL_0186: Unknown result type (might be due to invalid IL or missing references) //IL_018b: Unknown result type (might be due to invalid IL or missing references) //IL_018c: Unknown result type (might be due to invalid IL or missing references) if (ready) { return; } Transform[] componentsInChildren = ((Component)this).GetComponentsInChildren<Transform>(true); Animator componentInChildren = ((Component)this).GetComponentInChildren<Animator>(); neck = ((Object.op_Implicit((Object)(object)componentInChildren) && componentInChildren.isHuman) ? componentInChildren.GetBoneTransform((HumanBodyBones)9) : null); head = ((Object.op_Implicit((Object)(object)componentInChildren) && componentInChildren.isHuman) ? componentInChildren.GetBoneTransform((HumanBodyBones)10) : null); if (!Object.op_Implicit((Object)(object)neck)) { neck = ((IEnumerable<Transform>)componentsInChildren).FirstOrDefault((Func<Transform, bool>)((Transform t) => ((Object)t).name == "DEF-spine.005")); } if (!Object.op_Implicit((Object)(object)head)) { head = ((IEnumerable<Transform>)componentsInChildren).FirstOrDefault((Func<Transform, bool>)((Transform t) => ((Object)t).name == "DEF-spine.006")); } ready = Object.op_Implicit((Object)(object)neck) && Object.op_Implicit((Object)(object)head) && head.IsChildOf(neck); if (ready) { Transform val = ((IEnumerable<Transform>)componentsInChildren).FirstOrDefault((Func<Transform, bool>)((Transform t) => ((Object)t).name == "NePoLaBoGazeFrame")); headToLook = Quaternion.Inverse(head.rotation) * (Object.op_Implicit((Object)(object)val) ? val.rotation : Quaternion.identity); neckBase = (neutralNeck = neck.localRotation); headBase = (neutralHead = head.localRotation); } } private static bool Finite(float value) { if (!float.IsNaN(value)) { return !float.IsInfinity(value); } return false; } private static bool Finite(Vector3 value) { //IL_0000: 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_001a: Unknown result type (might be due to invalid IL or missing references) if (Finite(value.x) && Finite(value.y)) { return Finite(value.z); } return false; } private static bool SameRotation(Quaternion a, Quaternion b) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0014: Unknown result type (might be due to invalid IL or missing references) //IL_001b: Unknown result type (might be due to invalid IL or missing references) //IL_0023: Unknown result type (might be due to invalid IL or missing references) //IL_002a: Unknown result type (might be due to invalid IL or missing references) //IL_0033: 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_0043: Unknown result type (might be due to invalid IL or missing references) //IL_004a: Unknown result type (might be due to invalid IL or missing references) float num = ((!(Quaternion.Dot(a, b) < 0f)) ? 1 : (-1)); float num2 = a.x - num * b.x; float num3 = a.y - num * b.y; float num4 = a.z - num * b.z; float num5 = a.w - num * b.w; return num2 * num2 + num3 * num3 + num4 * num4 + num5 * num5 < 1E-09f; } private void RestoreAppliedPose() { //IL_0017: 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_0040: Unknown result type (might be due to invalid IL or missing references) //IL_0046: Unknown result type (might be due to invalid IL or missing references) //IL_0030: Unknown result type (might be due to invalid IL or missing references) //IL_0059: Unknown result type (might be due to invalid IL or missing references) if (ready && applied) { if (SameRotation(neck.localRotation, neckApplied)) { neck.localRotation = neckBase; } if (SameRotation(head.localRotation, headApplied)) { head.localRotation = headBase; } applied = false; } } public void PrepareForAvatarPose() { RestoreAppliedPose(); } public void StepFromDirection(Vector3 direction, float deltaTime, int frameToken, bool tracking = true) { //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_002d: Unknown result type (might be due to invalid IL or missing references) //IL_0032: Unknown result type (might be due to invalid IL or missing references) //IL_0043: Unknown result type (might be due to invalid IL or missing references) //IL_007d: 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_0082: Unknown result type (might be due to invalid IL or missing references) //IL_00ac: 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_00b4: Unknown result type (might be due to invalid IL or missing references) //IL_00b9: 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_00c0: Unknown result type (might be due to invalid IL or missing references) //IL_00c7: Unknown result type (might be due to invalid IL or missing references) //IL_00ea: Unknown result type (might be due to invalid IL or missing references) //IL_00f1: 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_0100: Unknown result type (might be due to invalid IL or missing references) //IL_0107: Unknown result type (might be due to invalid IL or missing references) //IL_01bb: Unknown result type (might be due to invalid IL or missing references) //IL_01ce: 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_01dd: Unknown result type (might be due to invalid IL or missing references) //IL_01e2: Unknown result type (might be due to invalid IL or missing references) //IL_01e4: Unknown result type (might be due to invalid IL or missing references) //IL_01e9: 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_01f0: Unknown result type (might be due to invalid IL or missing references) //IL_01f5: Unknown result type (might be due to invalid IL or missing references) //IL_01fb: Unknown result type (might be due to invalid IL or missing references) //IL_0200: Unknown result type (might be due to invalid IL or missing references) //IL_0201: Unknown result type (might be due to invalid IL or missing references) //IL_0206: Unknown result type (might be due to invalid IL or missing references) //IL_020d: Unknown result type (might be due to invalid IL or missing references) //IL_0212: Unknown result type (might be due to invalid IL or missing references) //IL_0214: Unknown result type (might be due to invalid IL or missing references) //IL_0219: Unknown result type (might be due to invalid IL or missing references) //IL_022a: Unknown result type (might be due to invalid IL or missing references) //IL_022f: Unknown result type (might be due to invalid IL or missing references) //IL_0235: Unknown result type (might be due to invalid IL or missing references) //IL_0240: Unknown result type (might be due to invalid IL or missing references) //IL_0245: 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_025a: 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_026b: Unknown result type (might be due to invalid IL or missing references) //IL_0270: Unknown result type (might be due to invalid IL or missing references) //IL_0281: Unknown result type (might be due to invalid IL or missing references) //IL_0286: Unknown result type (might be due to invalid IL or missing references) //IL_0292: Unknown result type (might be due to invalid IL or missing references) //IL_0297: Unknown result type (might be due to invalid IL or missing references) Initialize(); if (!ready) { return; } RestoreAppliedPose(); neckBase = neck.localRotation; headBase = head.localRotation; bool flag = tracking && TrackingEnabled && Finite(direction) && ((Vector3)(ref direction)).sqrMagnitude > 1E-08f; Quaternion val = (Quaternion)(((??)WorldAimFrame) ?? ((Component)this).transform.rotation); if (previousFrame != frameToken) { previousFrame = frameToken; float num = yaw; float num2 = pitch; if (flag) { Vector3 val2 = Quaternion.Inverse(val) * ((Vector3)(ref direction)).normalized; num = Mathf.Clamp(Mathf.Atan2(val2.x, val2.z) * 57.29578f, -50f, 50f); num2 = Mathf.Clamp(Mathf.Atan2(val2.y, Mathf.Sqrt(val2.x * val2.x + val2.z * val2.z)) * 57.29578f, -45f, 35f); } float num3 = 1f - Mathf.Exp((0f - Mathf.Clamp(deltaTime, 0f, 0.1f)) * 10f); yaw = Mathf.Lerp(yaw, num, num3); pitch = Mathf.Lerp(pitch, num2, num3); aimWeight = Mathf.Lerp(aimWeight, (float)(flag ? 1 : 0), num3); } LastCorrectionAngle = 0f; if (TrackingEnabled && !(aimWeight < 1E-06f)) { Vector3 val3 = val * Quaternion.Euler(0f - pitch, yaw, 0f) * Vector3.forward; Quaternion val4 = Quaternion.FromToRotation(LookForward, val3); val4 = Quaternion.RotateTowards(Quaternion.identity, val4, 55f); val4 = Quaternion.Slerp(Quaternion.identity, val4, aimWeight); LastCorrectionAngle = Quaternion.Angle(Quaternion.identity, val4); neck.rotation = Quaternion.Slerp(Quaternion.identity, val4, 0.3f) * neck.rotation; head.rotation = Quaternion.Slerp(Quaternion.identity, val4, 0.7f) * head.rotation; neckApplied = neck.localRotation; headApplied = head.localRotation; applied = true; } } public void Step() { //IL_006b: Unknown result type (might be due to invalid IL or missing references) //IL_0099: Unknown result type (might be due to invalid IL or missing references) //IL_0090: Unknown result type (might be due to invalid IL or missing references) //IL_009e: Unknown result type (might be due to invalid IL or missing references) //IL_00a3: Unknown result type (might be due to invalid IL or missing references) //IL_00a8: Unknown result type (might be due to invalid IL or missing references) //IL_00a9: Unknown result type (might be due to invalid IL or missing references) //IL_00aa: Unknown result type (might be due to invalid IL or missing references) //IL_00ea: Unknown result type (might be due to invalid IL or missing references) //IL_00cf: Unknown result type (might be due to invalid IL or missing references) //IL_00d4: Unknown result type (might be due to invalid IL or missing references) //IL_00ff: Unknown result type (might be due to invalid IL or missing references) TrackingEnabled = Plugin.HeadTracking.Value; bool flag = Object.op_Implicit((Object)(object)Player) && TrackingEnabled && !Player.isPlayerDead && Player.isPlayerControlled; Initialize(); WorldAimFrame = (Object.op_Implicit((Object)(object)Player) ? new Quaternion?(((Component)Player).transform.rotation) : ((Quaternion?)null)); Vector3 val = (Quaternion)(((??)WorldAimFrame) ?? ((Component)this).transform.rotation) * Vector3.forward; Vector3 direction = val; HasAttentionTarget = flag && ready && attention.Resolve(Player, ((Component)this).transform, head.position, val, Time.unscaledTime, out direction); AttentionDirection = direction; if (!flag) { attention.Reset(); } StepFromDirection(direction, Time.deltaTime, Time.frameCount, HasAttentionTarget); } public void PrepareNeutralTrackingPose() { //IL_001c: Unknown result type (might be due to invalid IL or missing references) //IL_002d: Unknown result type (might be due to invalid IL or missing references) Initialize(); if (ready) { RestoreAppliedPose(); neck.localRotation = neutralNeck; head.localRotation = neutralHead; } } private void LateUpdate() { Step(); } public void ResetAim() { RestoreAppliedPose(); yaw = (pitch = (aimWeight = 0f)); previousFrame = int.MinValue; LastCorrectionAngle = 0f; HasAttentionTarget = false; attention.Reset(); } private void OnDisable() { ResetAim(); } } [DefaultExecutionOrder(1000)] public sealed class NePoLaBoInkOutline : MonoBehaviour { private sealed class Pair { public SkinnedMeshRenderer Source; public SkinnedMeshRenderer Ink; public Mesh Mesh; public int Shapes; public Bounds Bounds; } public const string Prefix = "NePoLaBo Ink "; private readonly List<Pair> pairs = new List<Pair>(); private bool initialized; public int RendererPairs { get { Initialize(); return pairs.Count; } } public static bool IsInk(SkinnedMeshRenderer r) { if (Object.op_Implicit((Object)(object)r)) { return ((Object)r).name.StartsWith("NePoLaBo Ink ", StringComparison.Ordinal); } return false; } public void Initialize() { if (initialized) { return; } initialized = true; SkinnedMeshRenderer[] componentsInChildren = ((Component)this).GetComponentsInChildren<SkinnedMeshRenderer>(true); foreach (SkinnedMeshRenderer val in componentsInChildren) { if (IsInk(val) && Object.op_Implicit((Object)(object)((Component)val).transform.parent)) { SkinnedMeshRenderer component = ((Component)((Component)val).transform.parent).GetComponent<SkinnedMeshRenderer>(); if (Object.op_Implicit((Object)(object)component)) { pairs.Add(new Pair { Source = component, Ink = val }); } } } } public void Step(bool forceShapes = false) { //IL_0056: Unknown result type (might be due to invalid IL or missing references) //IL_005c: Invalid comparison between Unknown and I4 //IL_00ee: Unknown result type (might be due to invalid IL or missing references) //IL_00f3: Unknown result type (might be due to invalid IL or missing references) //IL_00f6: Unknown result type (might be due to invalid IL or missing references) //IL_00fb: Unknown result type (might be due to invalid IL or missing references) //IL_0105: Unknown result type (might be due to invalid IL or missing references) //IL_0107: Unknown result type (might be due to invalid IL or missing references) //IL_010d: Unknown result type (might be due to invalid IL or missing references) Initialize(); foreach (Pair pair in pairs) { if (!Object.op_Implicit((Object)(object)pair.Source) || !Object.op_Implicit((Object)(object)pair.Ink)) { continue; } SkinnedMeshRenderer source = pair.Source; SkinnedMeshRenderer ink = pair.Ink; bool flag = ((Renderer)source).enabled && (int)((Renderer)source).shadowCastingMode != 3; if (((Renderer)ink).enabled != flag) { ((Renderer)ink).enabled = flag; } int layer = ((Component)source).gameObject.layer; if (((Component)ink).gameObject.layer != layer) { ((Component)ink).gameObject.layer = layer; } if ((Object)(object)pair.Mesh != (Object)(object)source.sharedMesh) { pair.Mesh = source.sharedMesh; ink.sharedMesh = pair.Mesh; pair.Shapes = (Object.op_Implicit((Object)(object)pair.Mesh) ? pair.Mesh.blendShapeCount : 0); } Bounds localBounds = ((Renderer)source).localBounds; if (pair.Bounds != localBounds) { pair.Bounds = localBounds; ((Renderer)ink).localBounds = localBounds; } if (!((Renderer)ink).enabled || (!forceShapes && !((Renderer)source).isVisible && !((Renderer)ink).isVisible)) { continue; } for (int i = 0; i < pair.Shapes; i++) { float blendShapeWeight = source.GetBlendShapeWeight(i); if (ink.GetBlendShapeWeight(i) != blendShapeWeight) { ink.SetBlendShapeWeight(i, blendShapeWeight); } } } } private void Awake() { Initialize(); } private void LateUpdate() { Step(); } } internal sealed class NePoLaBoLootLamyContext { private sealed class Entry { internal ulong Owner; internal PlayerControllerB Player; internal NePoLaBoLootLamyRules Rules = new NePoLaBoLootLamyRules(); } private sealed class Rig { internal GameObject Model; internal Transform[] Breasts; internal Transform Chest; internal NePoLaBoChestGazeTarget Authored; internal int Suit; } internal static ConfigEntry<bool> StarsEnabled; internal static ConfigEntry<bool> HeartsEnabled; internal static ConfigEntry<bool> LadderHearts; internal static ConfigEntry<bool> ChestGaze; internal static ConfigEntry<string> HeartSuits; internal static ConfigEntry<int> LootValue; internal static ConfigEntry<int> PileCount; internal static ConfigEntry<int> PileValue; internal static ConfigEntry<float> Duration; internal static ConfigEntry<float> NearRange; internal static ConfigEntry<float> GazeDelay; internal static ConfigEntry<float> GazeRamp; internal static ConfigEntry<float> PileRadius; internal static ConfigEntry<float> LadderRange; private static readonly Dictionary<ulong, Entry> ledger = new Dictionary<ulong, Entry>(); private static readonly Dictionary<int, Rig> rigs = new Dictionary<int, Rig>(); private static readonly FieldInfo sourceField = AccessTools.Field(typeof(BodyReplacementBase), "replacementModel"); private static StartOfRound scene; private static bool phaseSeeded; private static bool inShipPhase; internal static GrabbableObject[] items = (GrabbableObject[])(object)new GrabbableObject[0]; private static InteractTrigger[] ladders = (InteractTrigger[])(object)new InteractTrigger[0]; private static float nextObjects; private static string suitConfig; private static string[] suitTokens = new string[0]; private readonly bool isLamy; private readonly PlayerControllerB player; private readonly Transform model; private NePoLaBoLootLamyRules rules; private readonly RaycastHit[] hits = (RaycastHit[])(object)new RaycastHit[24]; private float nextScan; private PlayerControllerB nearPlayer; private bool ladderHeart; internal bool Heart { get { if (isLamy && HeartsEnabled.Value) { if (!Object.op_Implicit((Object)(object)nearPlayer)) { return ladderHeart; } return true; } return false; } } internal bool Stars { get { if (StarsEnabled.Value) { return rules.Stars(Time.unscaledTime); } return false; } } internal ulong GazePlayerId { get { if (!Object.op_Implicit((Object)(object)nearPlayer)) { return ulong.MaxValue; } return nearPlayer.playerClientId; } } internal float GazeWeight { get { if (!Plugin.Eyes.Value || !ChestGaze.Value || !Object.op_Implicit((Object)(object)nearPlayer)) { return 0f; } return rules.GazeWeight; } } internal static void Configure(ConfigFile config) { //IL_00a9: Unknown result type (might be due to invalid IL or missing references) //IL_00b3: Expected O, but got Unknown //IL_00d6: Unknown result type (might be due to invalid IL or missing references) //IL_00e0: Expected O, but got Unknown //IL_010a: Unknown result type (might be due to invalid IL or missing references) //IL_0114: Expected O, but got Unknown //IL_0142: Unknown result type (might be due to invalid IL or missing references) //IL_014c: Expected O, but got Unknown //IL_017a: Unknown result type (might be due to invalid IL or missing references) //IL_0184: Expected O, but got Unknown //IL_01b2: Unknown result type (might be due to invalid IL or missing references) //IL_01bc: Expected O, but got Unknown //IL_01ea: Unknown result type (might be due to invalid IL or missing references) //IL_01f4: Expected O, but got Unknown //IL_0222: Unknown result type (might be due to invalid IL or missing references) //IL_022c: Expected O, but got Unknown //IL_025a: Unknown result type (might be due to invalid IL or missing references) //IL_0264: Expected O, but got Unknown StarsEnabled = config.Bind<bool>("Loot expressions", "StarEyes", true, "Star eyes for newly discovered valuable scrap, first pickup, and a qualifying visible ship pile on entry."); HeartsEnabled = config.Bind<bool>("Lamy expressions", "HeartEyes", true, "Heart eyes beside configured suits or below another climber on the same ladder."); LadderHearts = config.Bind<bool>("Lamy expressions", "LadderHeartEyes", true, (ConfigDescription)null); ChestGaze = config.Bind<bool>("Lamy expressions", "GradualChestGaze", true, "Allow only Lamy's eyes to drift toward the nearby target's authored breast bones, with humanoid chest fallback."); HeartSuits = config.Bind<string>("Lamy expressions", "HeartSuitNames", "Elizabeth Rose Bloodflame;Raora Panthera;Fuwawa Abyssgard;Mori Calliope;Shiori Novella;Nerissa Ravencroft;Kronii;Botan", "Semicolon-separated case-insensitive suit-name fragments. Spaces and punctuation are ignored. Empty list disables proximity hearts; ladder hearts remain independent."); LootValue = config.Bind<int>("Loot expressions", "HighValueLootThreshold", 100, new ConfigDescription("Value must be strictly greater than this threshold.", (