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 English Advent v1.0.0
AdventSuit.dll
Decompiled 21 hours 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 BepInEx; using BepInEx.Configuration; using GameNetcodeStuff; using HarmonyLib; using ModelReplacement; using ModelReplacement.AvatarBodyUpdater; 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: AssemblyVersion("0.0.0.0")] namespace AdventSuit; 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 AdventAttentionSelection { 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 AdventAttention { private sealed class ItemRenderer { public GrabbableObject Item; public Renderer Renderer; } private readonly AdventAttentionSelection selection = new AdventAttentionSelection(); 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 = AdventSceneCache.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 (AdventAttentionSelection.InView(origin, forward, val, range)) { int mask = (Object.op_Implicit((Object)(object)StartOfRound.Instance) ? StartOfRound.Instance.collidersAndRoomMaskAndDefault : (-5)); if (AdventAttentionSelection.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 = AdventVoiceActivity.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 AdventVoiceActivity { 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 = AdventFace.Read(player, "voicePlayerState") ?? AdventFace.Read(AdventFace.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 = AdventFace.Read(StartOfRound.Instance, "voiceChatModule"); if (comms != null) { string text = (((NetworkBehaviour)player).IsOwner ? (AdventFace.Read(comms, "LocalPlayerName") as string) : (AdventFace.Read(player, "voicePlayerName") as string)); if (!string.IsNullOrEmpty(text)) { try { obj = AdventRuntimeMembers.CallString(comms, "FindPlayer", text); if (obj != null) { states[instanceID] = obj; } } catch { } } } } bool value3; bool flag = AdventRuntimeMembers.TryRead<bool>(obj, "IsSpeaking", out value3) && value3; if (AdventRuntimeMembers.TryRead<bool>(obj, "IsConnected", out var value4) && !value4) { return false; } if (!AdventRuntimeMembers.TryRead<float>(obj, "Amplitude", out var value5)) { return flag; } return AdventAttentionSelection.ActiveSpeech(flag, value5); } internal static void Clear() { comms = null; retry.Clear(); states.Clear(); } } [DefaultExecutionOrder(600)] public sealed class AdventBijouAccessories : MonoBehaviour { private SkinnedMeshRenderer[] crown; private SkinnedMeshRenderer[] ornaments; public bool CrownShown { get; private set; } = true; public bool OrnamentsShown { get; private set; } = true; public void Initialize() { if (crown == null) { SkinnedMeshRenderer[] componentsInChildren = ((Component)this).GetComponentsInChildren<SkinnedMeshRenderer>(true); crown = componentsInChildren.Where((SkinnedMeshRenderer r) => ((Object)r).name == "AdventBijouCrown").ToArray(); ornaments = componentsInChildren.Where((SkinnedMeshRenderer r) => ((Object)r).name == "AdventBijouOrnaments").ToArray(); } } public void Apply(bool showCrown, bool showOrnaments) { Initialize(); SkinnedMeshRenderer[] array; if (CrownShown != showCrown) { CrownShown = showCrown; array = crown; foreach (SkinnedMeshRenderer val in array) { if (Object.op_Implicit((Object)(object)val)) { ((Renderer)val).enabled = showCrown; } } } if (OrnamentsShown == showOrnaments) { return; } OrnamentsShown = showOrnaments; array = ornaments; foreach (SkinnedMeshRenderer val2 in array) { if (Object.op_Implicit((Object)(object)val2)) { ((Renderer)val2).enabled = showOrnaments; } } } public void EnforceVisibility() { if (CrownShown && OrnamentsShown) { return; } SkinnedMeshRenderer[] array; if (!CrownShown) { array = crown; foreach (SkinnedMeshRenderer val in array) { if (Object.op_Implicit((Object)(object)val) && ((Renderer)val).enabled) { ((Renderer)val).enabled = false; } } } if (OrnamentsShown) { return; } array = ornaments; foreach (SkinnedMeshRenderer val2 in array) { if (Object.op_Implicit((Object)(object)val2) && ((Renderer)val2).enabled) { ((Renderer)val2).enabled = false; } } } private void LateUpdate() { EnforceVisibility(); } } public static class AdventBijouControl { private sealed class State { public bool Crown; public bool Ornaments; } private static readonly Dictionary<PlayerControllerB, AdventBijouAccessories> models = new Dictionary<PlayerControllerB, AdventBijouAccessories>(); private static readonly Dictionary<PlayerControllerB, State> settings = new Dictionary<PlayerControllerB, State>(); public static void Bind(PlayerControllerB player, GameObject model, string character) { if (character != "KosekiBijou" || !Object.op_Implicit((Object)(object)player)) { return; } AdventBijouAccessories component = model.GetComponent<AdventBijouAccessories>(); if (Object.op_Implicit((Object)(object)component)) { models[player] = component; if (!settings.ContainsKey(player)) { settings[player] = new State { Crown = Plugin.BijouCrownShown.Value, Ornaments = Plugin.BijouOrnamentsShown.Value }; } component.Apply(CrownShown(player), OrnamentsShown(player)); } } public static bool CrownShown(PlayerControllerB player) { if (Object.op_Implicit((Object)(object)player) && !((NetworkBehaviour)player).IsOwner) { return AdventExpressionNetwork.BijouCrownShown(player.playerClientId); } if (Object.op_Implicit((Object)(object)player) && settings.TryGetValue(player, out var value)) { return value.Crown; } return true; } public static bool OrnamentsShown(PlayerControllerB player) { if (Object.op_Implicit((Object)(object)player) && !((NetworkBehaviour)player).IsOwner) { return AdventExpressionNetwork.BijouOrnamentsShown(player.playerClientId); } if (Object.op_Implicit((Object)(object)player) && settings.TryGetValue(player, out var value)) { return value.Ornaments; } return true; } public static void Tick() { //IL_0077: Unknown result type (might be due to invalid IL or missing references) //IL_00ab: Unknown result type (might be due to invalid IL or missing references) //IL_0084: Unknown result type (might be due to invalid IL or missing references) //IL_00b8: Unknown result type (might be due to invalid IL or missing references) Keyboard current = Keyboard.current; foreach (KeyValuePair<PlayerControllerB, AdventBijouAccessories> model in models) { PlayerControllerB key = model.Key; if (!Object.op_Implicit((Object)(object)key) || !Object.op_Implicit((Object)(object)model.Value)) { continue; } if (((NetworkBehaviour)key).IsOwner && current != null && !key.isTypingChat && !key.inTerminalMenu && settings.TryGetValue(key, out var value)) { if ((int)Plugin.BijouCrownKey.Value != 0 && ((ButtonControl)current[Plugin.BijouCrownKey.Value]).wasPressedThisFrame) { value.Crown = !value.Crown; } if ((int)Plugin.BijouOrnamentsKey.Value != 0 && ((ButtonControl)current[Plugin.BijouOrnamentsKey.Value]).wasPressedThisFrame) { value.Ornaments = !value.Ornaments; } } model.Value.Apply(CrownShown(key), OrnamentsShown(key)); } } public static void Clear() { models.Clear(); settings.Clear(); } } [DefaultExecutionOrder(600)] public sealed class AdventClawToggle : MonoBehaviour { public string Character; private SkinnedMeshRenderer[] renderers; public bool Shown { get; private set; } = true; public void Initialize() { if (renderers == null) { renderers = (from r in ((Component)this).GetComponentsInChildren<SkinnedMeshRenderer>(true) where ((Object)r).name == "AdventClaws" select r).ToArray(); } } public void Apply(bool shown) { Initialize(); if (Shown == shown) { return; } Shown = shown; SkinnedMeshRenderer[] array = renderers; foreach (SkinnedMeshRenderer val in array) { if (Object.op_Implicit((Object)(object)val)) { ((Renderer)val).enabled = shown; } } } public void EnforceVisibility() { if (Shown) { return; } SkinnedMeshRenderer[] array = renderers; foreach (SkinnedMeshRenderer val in array) { if (Object.op_Implicit((Object)(object)val) && ((Renderer)val).enabled) { ((Renderer)val).enabled = false; } } } private void LateUpdate() { EnforceVisibility(); } } public static class AdventClawControl { private sealed class Entry { public AdventClawToggle Body; public AdventClawToggle View; public string Character; } private static readonly Dictionary<PlayerControllerB, Entry> models = new Dictionary<PlayerControllerB, Entry>(); private static readonly Dictionary<PlayerControllerB, bool> settings = new Dictionary<PlayerControllerB, bool>(); public static void Bind(PlayerControllerB player, GameObject model, string character) { AdventClawToggle component = model.GetComponent<AdventClawToggle>(); if (Object.op_Implicit((Object)(object)player) && Object.op_Implicit((Object)(object)component)) { component.Initialize(); models[player] = new Entry { Body = component, Character = character }; if (!settings.ContainsKey(player)) { settings[player] = Plugin.ClawsShown.Value; } component.Apply(Shown(player, character)); } } public static void AttachViews(AdventBody owner) { if (!Object.op_Implicit((Object)(object)owner) || !Object.op_Implicit((Object)(object)((BodyReplacementBase)owner).controller) || !models.TryGetValue(((BodyReplacementBase)owner).controller, out var value)) { return; } object obj = AdventRuntimeMembers.Read(AdventRuntimeMembers.Read(owner, "viewModelAvatar"), "replacementViewModel"); GameObject val = (GameObject)((obj is GameObject) ? obj : null); if (Object.op_Implicit((Object)(object)val)) { value.View = val.GetComponent<AdventClawToggle>(); if (Object.op_Implicit((Object)(object)value.View)) { value.View.Apply(Shown(((BodyReplacementBase)owner).controller, value.Character)); } } } public static bool Shown(PlayerControllerB player, string character) { if (Object.op_Implicit((Object)(object)player) && !((NetworkBehaviour)player).IsOwner) { return AdventExpressionNetwork.ClawsShown(player.playerClientId, character); } bool value = default(bool); return !Object.op_Implicit((Object)(object)player) || !settings.TryGetValue(player, out value) || value; } public static void Tick() { //IL_006b: Unknown result type (might be due to invalid IL or missing references) //IL_0078: Unknown result type (might be due to invalid IL or missing references) Keyboard current = Keyboard.current; foreach (KeyValuePair<PlayerControllerB, Entry> model in models) { PlayerControllerB key = model.Key; Entry value = model.Value; if (Object.op_Implicit((Object)(object)key) && Object.op_Implicit((Object)(object)value.Body)) { if (((NetworkBehaviour)key).IsOwner && current != null && !key.isTypingChat && !key.inTerminalMenu && (int)Plugin.ClawKey.Value != 0 && ((ButtonControl)current[Plugin.ClawKey.Value]).wasPressedThisFrame) { settings[key] = !Shown(key, value.Character); } bool shown = Shown(key, value.Character); value.Body.Apply(shown); if (Object.op_Implicit((Object)(object)value.View)) { value.View.Apply(shown); } } } } public static void Clear() { models.Clear(); settings.Clear(); } } public enum AdventExpression : byte { Neutral, Frightened, Hurt, Happy, Surprised, VeryHappy, Dead, CrazySmile, IntenseCrazySmile, Crying, Excited, Worried, BigGrin } public struct AdventExpressionContext { public bool Dead; public bool Critical; public bool EnemyNear; public bool Fear; public bool Chased; public bool Dancing; public bool Driving; public bool WeaponHeld; public bool TwinVisibleClose; public bool TwinUnsafe; public bool TwinDeadNear; public bool AdventCorpseVisible; public bool Unsafe { get { if (!EnemyNear && !Fear) { return Chased; } return true; } } } public sealed class AdventExpressionSelection { public string Character; private float hurtUntil = -1f; private float weaponUntil = -1f; private float treasureUntil = -1f; private bool surprised = true; private int pickups; public void Damage(float now) { hurtUntil = now + 2f; } public void WeaponUsed(float now) { weaponUntil = now + 3f; } public void PickedUp(int value, float now) { if (value > 100) { treasureUntil = now + 3.5f; surprised = pickups++ % 2 == 0; } } public AdventExpression Choose(AdventExpressionContext c, float now) { if (c.Dead) { return AdventExpression.Dead; } if (c.Critical || now < hurtUntil) { return AdventExpression.Hurt; } bool flag = Character == "FuwawaAbyssgard" || Character == "MococoAbyssgard"; if (c.Unsafe || (flag && c.TwinVisibleClose && c.TwinUnsafe)) { return AdventExpression.Frightened; } if (flag && c.TwinDeadNear) { return AdventExpression.Crying; } if (Character == "NerissaRavencroft" && c.AdventCorpseVisible) { return AdventExpression.Worried; } if (now < weaponUntil) { if (Character == "ShioriNovella") { return AdventExpression.IntenseCrazySmile; } if (Character == "KosekiBijou") { return AdventExpression.BigGrin; } } if (c.Driving) { if (Character == "ShioriNovella") { return AdventExpression.CrazySmile; } if (Character == "KosekiBijou") { return AdventExpression.Excited; } } if (now < treasureUntil) { if (!surprised) { return AdventExpression.VeryHappy; } return AdventExpression.Surprised; } if (c.Dancing) { return AdventExpression.Happy; } if (flag && c.TwinVisibleClose && !c.TwinUnsafe) { return AdventExpression.Happy; } if (Character == "ShioriNovella" && c.WeaponHeld) { return AdventExpression.CrazySmile; } return AdventExpression.Neutral; } } public struct AdventExpressionWeight { public string Shape; public float Weight; public bool Eyes; public bool Mouth; public AdventExpressionWeight(string shape, float weight, bool eyes = false, bool mouth = false) { Shape = "expr_" + shape; Weight = weight; Eyes = eyes; Mouth = mouth; } } public static class AdventExpressionProfiles { private static readonly AdventExpressionWeight[][] Profiles = new AdventExpressionWeight[13][] { new AdventExpressionWeight[0], new AdventExpressionWeight[4] { B("worry", 0.75f), B("brow_up", 0.25f), E("surprise", 0.85f), M("triangle", 0.6f) }, new AdventExpressionWeight[4] { B("worry", 0.85f), B("serious", 0.25f), E("focus", 0.45f), M("clench", 0.8f) }, new AdventExpressionWeight[3] { B("happy_brows", 0.45f), E("smile_eyes", 0.65f), M("smile", 0.85f) }, new AdventExpressionWeight[3] { B("brow_up", 0.65f), E("surprise", 0.9f), M("o", 0.65f) }, new AdventExpressionWeight[3] { B("happy_brows", 0.65f), E("smile_eyes", 0.85f), M("laugh", 0.85f) }, new AdventExpressionWeight[2] { B("worry", 0.7f), M("clench", 0.55f) }, new AdventExpressionWeight[4] { B("angry", 0.3f), E("focus", 0.35f), E("small_pupils", 0.25f), M("crazy", 0.8f) }, new AdventExpressionWeight[4] { B("angry", 0.45f), E("surprise", 0.3f), E("small_pupils", 0.65f), M("crazy", 1f) }, new AdventExpressionWeight[5] { B("worry", 1f), E("relaxed", 0.4f), M("mouth_down", 0.75f), B("tears", 1f), B("sad_ears", 0.65f) }, new AdventExpressionWeight[3] { B("brow_up", 0.4f), E("surprise", 0.4f), M("grin", 0.9f) }, new AdventExpressionWeight[3] { B("worry", 0.9f), E("surprise", 0.2f), M("mouth_down", 0.4f) }, new AdventExpressionWeight[3] { B("angry", 0.15f), E("focus", 0.3f), M("grin", 1f) } }; private static AdventExpressionWeight B(string n, float w) { return new AdventExpressionWeight(n, w); } private static AdventExpressionWeight E(string n, float w) { return new AdventExpressionWeight(n, w, eyes: true); } private static AdventExpressionWeight M(string n, float w) { return new AdventExpressionWeight(n, w, eyes: false, mouth: true); } public static AdventExpressionWeight[] Weights(AdventExpression state) { return Profiles[(uint)state]; } } public sealed class AdventExpressionMixer { 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 float death; public AdventExpressionMixer(GameObject model) { foreach (AdventExpression value in Enum.GetValues(typeof(AdventExpression))) { AdventExpressionWeight[] array = AdventExpressionProfiles.Weights(value); for (int i = 0; i < array.Length; i++) { AdventExpressionWeight adventExpressionWeight = array[i]; if (!slots.ContainsKey(adventExpressionWeight.Shape)) { slots[adventExpressionWeight.Shape] = shapes.Count; shapes.Add(adventExpressionWeight.Shape); } } } values = new float[shapes.Count]; target = new float[shapes.Count]; eyes = new bool[shapes.Count]; mouth = new bool[shapes.Count]; foreach (AdventExpression value2 in Enum.GetValues(typeof(AdventExpression))) { AdventExpressionWeight[] array = AdventExpressionProfiles.Weights(value2); for (int i = 0; i < array.Length; i++) { AdventExpressionWeight adventExpressionWeight2 = array[i]; int num = slots[adventExpressionWeight2.Shape]; eyes[num] |= adventExpressionWeight2.Eyes; mouth[num] |= adventExpressionWeight2.Mouth; } } SkinnedMeshRenderer[] componentsInChildren = model.GetComponentsInChildren<SkinnedMeshRenderer>(true); foreach (SkinnedMeshRenderer val in componentsInChildren) { if (Object.op_Implicit((Object)(object)val.sharedMesh)) { 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); } } } public void Step(AdventExpression state, float delta, bool immediate = false) { Array.Clear(target, 0, target.Length); AdventExpressionWeight[] array = AdventExpressionProfiles.Weights(state); for (int i = 0; i < array.Length; i++) { AdventExpressionWeight adventExpressionWeight = array[i]; target[slots[adventExpressionWeight.Shape]] = adventExpressionWeight.Weight; } float num = ((immediate || state == AdventExpression.Dead) ? 1f : (1f - Mathf.Exp((0f - Mathf.Min(delta, 0.1f)) * 13f))); death = Mathf.Lerp(death, (float)((state == AdventExpression.Dead) ? 1 : 0), num); for (int j = 0; j < values.Length; j++) { values[j] = Mathf.Lerp(values[j], target[j], num); } foreach (Binding binding in bindings) { if (!Object.op_Implicit((Object)(object)binding.Renderer)) { continue; } float num2 = ((binding.Blink < 0) ? 0f : (binding.Renderer.GetBlendShapeWeight(binding.Blink) / 100f)); float num3 = ((binding.Open < 0) ? 0f : (binding.Renderer.GetBlendShapeWeight(binding.Open) / 85f)); if (death > 0.001f) { num2 = death; if (binding.Blink >= 0) { binding.Renderer.SetBlendShapeWeight(binding.Blink, death * 100f); } if (binding.Open >= 0) { binding.Renderer.SetBlendShapeWeight(binding.Open, 0f); } if (binding.Round >= 0) { binding.Renderer.SetBlendShapeWeight(binding.Round, 0f); } num3 = 0f; } for (int k = 0; k < values.Length; k++) { if (binding.Indices[k] >= 0) { float num4 = values[k]; if (eyes[k]) { num4 *= 1f - num2; } if (mouth[k]) { num4 *= 1f - num3 * 0.55f; } binding.Renderer.SetBlendShapeWeight(binding.Indices[k], num4 * 100f); } } } } } [DefaultExecutionOrder(280)] public sealed class AdventDeathFace : MonoBehaviour { private AdventExpressionMixer mixer; public void Initialize() { mixer = new AdventExpressionMixer(((Component)this).gameObject); mixer.Step(AdventExpression.Dead, 0f, immediate: true); } private void LateUpdate() { if (mixer == null) { Initialize(); } mixer.Step(AdventExpression.Dead, Time.deltaTime, immediate: true); } } public sealed class AdventEyeGlow : MonoBehaviour { private sealed class Slot { public SkinnedMeshRenderer Renderer; public Material[] Original; public Material[] Glow; } private readonly List<Slot> slots = new List<Slot>(); private readonly List<Material> owned = new List<Material>(); private static readonly Dictionary<Material, Material> originals = new Dictionary<Material, Material>(); private bool initialized; public bool Enabled { get; private set; } public int EyeMaterials { get; private set; } public void Initialize() { //IL_009b: Unknown result type (might be due to invalid IL or missing references) //IL_00a0: Unknown result type (might be due to invalid IL or missing references) //IL_00b9: Expected O, but got Unknown if (initialized) { return; } initialized = true; SkinnedMeshRenderer[] componentsInChildren = ((Component)this).GetComponentsInChildren<SkinnedMeshRenderer>(true); foreach (SkinnedMeshRenderer val in componentsInChildren) { Material[] sharedMaterials = ((Renderer)val).sharedMaterials; Material[] array = (Material[])sharedMaterials.Clone(); bool flag = false; for (int j = 0; j < sharedMaterials.Length; j++) { Material val2 = sharedMaterials[j]; if (Object.op_Implicit((Object)(object)val2)) { if (originals.TryGetValue(val2, out var value)) { val2 = (sharedMaterials[j] = value); } if (((Object)val2).name.StartsWith("ShioriNovella_Material_05", StringComparison.Ordinal) || ((Object)val2).name.StartsWith("ShioriNovella_Material_06", StringComparison.Ordinal)) { Material val3 = new Material(val2) { name = ((Object)val2).name + " - Amber iris glow" }; val3.SetFloat("_GflYellowEyeGlow", 2.6f); val3.SetFloat("_GflEmissionUnlit", 1f); array[j] = val3; owned.Add(val3); originals[val3] = val2; EyeMaterials++; flag = true; } } } if (flag) { slots.Add(new Slot { Renderer = val, Original = sharedMaterials, Glow = array }); ((Renderer)val).sharedMaterials = sharedMaterials; } } } public void Apply(bool enabled) { Initialize(); if (Enabled == enabled) { return; } Enabled = enabled; foreach (Slot slot in slots) { if (Object.op_Implicit((Object)(object)slot.Renderer)) { ((Renderer)slot.Renderer).sharedMaterials = (enabled ? slot.Glow : slot.Original); } } } private void OnDestroy() { foreach (Slot slot in slots) { if (Object.op_Implicit((Object)(object)slot.Renderer)) { ((Renderer)slot.Renderer).sharedMaterials = slot.Original; } } foreach (Material item in owned) { originals.Remove(item); if (Object.op_Implicit((Object)(object)item)) { Object.Destroy((Object)(object)item); } } } } public static class AdventEyeGlowControl { private static readonly Dictionary<PlayerControllerB, AdventEyeGlow> models = new Dictionary<PlayerControllerB, AdventEyeGlow>(); private static readonly Dictionary<PlayerControllerB, bool> settings = new Dictionary<PlayerControllerB, bool>(); public static void Bind(PlayerControllerB player, GameObject model, string character) { if (!(character != "ShioriNovella") && Object.op_Implicit((Object)(object)player)) { AdventEyeGlow adventEyeGlow = model.GetComponent<AdventEyeGlow>() ?? model.AddComponent<AdventEyeGlow>(); adventEyeGlow.Initialize(); models[player] = adventEyeGlow; if (!settings.ContainsKey(player)) { settings[player] = Plugin.YellowEyeGlow.Value; } adventEyeGlow.Apply(Enabled(player)); } } public static bool Enabled(PlayerControllerB player) { if (Object.op_Implicit((Object)(object)player)) { if (!((NetworkBehaviour)player).IsOwner) { return AdventExpressionNetwork.EyeGlow(player.playerClientId); } bool value; return settings.TryGetValue(player, out value) && value; } return false; } public static void Tick() { //IL_0062: Unknown result type (might be due to invalid IL or missing references) //IL_006f: Unknown result type (might be due to invalid IL or missing references) Keyboard current = Keyboard.current; foreach (KeyValuePair<PlayerControllerB, AdventEyeGlow> model in models) { if (Object.op_Implicit((Object)(object)model.Key) && Object.op_Implicit((Object)(object)model.Value)) { PlayerControllerB key = model.Key; if (((NetworkBehaviour)key).IsOwner && current != null && !key.isTypingChat && !key.inTerminalMenu && (int)Plugin.EyeGlowKey.Value != 0 && ((ButtonControl)current[Plugin.EyeGlowKey.Value]).wasPressedThisFrame) { settings[key] = !Enabled(key); } model.Value.Apply(Enabled(key)); } } } public static void Clear() { models.Clear(); settings.Clear(); } } public static class AdventFirstPersonMesh { 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("Advent 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 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("Advent 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("Advent 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 + "_AdventFirstPerson", 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)); } } val2.boneWeights = array3; val2.bindposes = Subset(sharedMesh.bindposes, list5); val2.subMeshCount = list2.Count; for (int num4 = 0; num4 < list2.Count; num4++) { val2.SetTriangles(list2[num4], num4, 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) { AdventJacketToggle component = model.GetComponent<AdventJacketToggle>(); if (Object.op_Implicit((Object)(object)component)) { component.PrepareForViewConversion(); } 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); AdventJacketToggle component2 = model.GetComponent<AdventJacketToggle>(); if (Object.op_Implicit((Object)(object)component2)) { component2.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) { switch (((object)val).GetType().FullName) { case "AdventSuit.AdventLollipopMount": case "AdventSuit.AdventSecondaryMotion": case "AdventSuit.AdventHeadTracking": case "AdventSuit.AdventFootGrounding": case "AdventSuit.AdventFace": case "AdventSuit.AdventReactionFace": case "AdventSuit.AdventDeathFace": case "AdventSuit.AdventToonFrame": 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 AdventFirstPersonPatch { 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 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(AdventFirstPersonPatch), "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(AdventFirstPersonPatch), "AfterBodyCreated", (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("Advent_", StringComparison.Ordinal)) { return true; } __result = AdventFirstPersonMesh.Convert(__0); return false; } private static void AfterBodyCreated(BodyReplacementBase __instance) { if (__instance is AdventBody) { 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)) { AdventFirstPersonMesh.StripSimulation(val2); val2.AddComponent<AdventShadowPose>().Initialize(val); } AdventOutfitControl.AttachViews(__instance as AdventBody); AdventClawControl.AttachViews(__instance as AdventBody); } } } public class AdventFootAlignment : 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 == "AdventSole.L")); rightSole = ((IEnumerable<Transform>)componentsInChildren).FirstOrDefault((Func<Transform, bool>)((Transform t) => ((Object)t).name == "AdventSole.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 AdventHandAlignment : 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 AdventHeadTracking : MonoBehaviour { public PlayerControllerB Player; private readonly AdventAttention attention = new AdventAttention(); 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 == "AdventGazeFrame")); 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(); } } public sealed class AdventJacketToggle : MonoBehaviour { private sealed class MaterialSlot { public SkinnedMeshRenderer Renderer; public Material[] On; public Material[] Off; } private sealed class Variant { public Mesh On; public Mesh Off; public int Removed; } private sealed class Slot { public SkinnedMeshRenderer Renderer; public Variant Mesh; } public string Character; public string[] JacketMaterials = new string[0]; public string[] DrawstringBones = new string[0]; public string[] PhysicsBones = new string[0]; public Texture CleanBodyTexture; private readonly List<MaterialSlot> materialSlots = new List<MaterialSlot>(); private readonly List<Material> owned = new List<Material>(); private SkinnedMeshRenderer[] uncovered = (SkinnedMeshRenderer[])(object)new SkinnedMeshRenderer[0]; private static readonly Dictionary<Mesh, Variant> cache = new Dictionary<Mesh, Variant>(); private static readonly Dictionary<Mesh, Mesh> originals = new Dictionary<Mesh, Mesh>(); private static readonly Dictionary<Material, Material> materialOrigins = new Dictionary<Material, Material>(); private readonly List<Slot> slots = new List<Slot>(); private AdventSecondaryMotion motion; private AdventSecondaryMotion.Node[] allNodes; private AdventSecondaryMotion.Node[] uncoveredNodes; private bool initialized; public bool Shown { get; private set; } = true; public int RemovedTriangles => slots.Sum((Slot s) => s.Mesh.Removed); private bool MaterialIsJacket(Material m) { if (Object.op_Implicit((Object)(object)m)) { return JacketMaterials.Any((string n) => ((Object)m).name.StartsWith(n, StringComparison.Ordinal)); } return false; } private Variant Get(SkinnedMeshRenderer renderer) { //IL_008c: Unknown result type (might be due to invalid IL or missing references) //IL_0091: Unknown result type (might be due to invalid IL or missing references) //IL_027a: Unknown result type (might be due to invalid IL or missing references) Mesh val = renderer.sharedMesh; if (originals.TryGetValue(val, out var value)) { val = value; } if (cache.TryGetValue(val, out var value2)) { return value2; } BoneWeight[] boneWeights = val.boneWeights; HashSet<int> hashSet = new HashSet<int>(from i in Enumerable.Range(0, renderer.bones.Length) where DrawstringBones.Contains(((Object)renderer.bones[i]).name) select i); bool[] array = new bool[boneWeights.Length]; for (int num = 0; num < boneWeights.Length; num++) { BoneWeight val2 = boneWeights[num]; array[num] = (hashSet.Contains(((BoneWeight)(ref val2)).boneIndex0) ? ((BoneWeight)(ref val2)).weight0 : 0f) + (hashSet.Contains(((BoneWeight)(ref val2)).boneIndex1) ? ((BoneWeight)(ref val2)).weight1 : 0f) + (hashSet.Contains(((BoneWeight)(ref val2)).boneIndex2) ? ((BoneWeight)(ref val2)).weight2 : 0f) + (hashSet.Contains(((BoneWeight)(ref val2)).boneIndex3) ? ((BoneWeight)(ref val2)).weight3 : 0f) > 0.25f; } Material[] sharedMaterials = ((Renderer)renderer).sharedMaterials; int[][] array2 = new int[val.subMeshCount][]; int num2 = 0; for (int num3 = 0; num3 < array2.Length; num3++) { int[] triangles = val.GetTriangles(num3); if (num3 < sharedMaterials.Length && MaterialIsJacket(sharedMaterials[num3])) { num2 += triangles.Length / 3; array2[num3] = new int[0]; continue; } List<int> list = new List<int>(); for (int num4 = 0; num4 < triangles.Length; num4 += 3) { if (array[triangles[num4]] && array[triangles[num4 + 1]] && array[triangles[num4 + 2]]) { num2++; continue; } list.Add(triangles[num4]); list.Add(triangles[num4 + 1]); list.Add(triangles[num4 + 2]); } array2[num3] = list.ToArray(); } if (num2 == 0) { value2 = new Variant { On = val, Off = val }; cache[val] = value2; return value2; } Mesh val3 = Object.Instantiate<Mesh>(val); ((Object)val3).name = ((Object)val).name + "_JacketOff"; for (int num5 = 0; num5 < array2.Length; num5++) { val3.SetTriangles(array2[num5], num5, false); } val3.bounds = val.bounds; value2 = new Variant { On = val, Off = val3, Removed = num2 }; cache[val] = value2; originals[val3] = val; return value2; } public void Prime() { SkinnedMeshRenderer[] componentsInChildren = ((Component)this).GetComponentsInChildren<SkinnedMeshRenderer>(true); foreach (SkinnedMeshRenderer val in componentsInChildren) { if (Object.op_Implicit((Object)(object)val.sharedMesh)) { Get(val); } } } public void Initialize() { //IL_016b: Unknown result type (might be due to invalid IL or missing references) //IL_0172: Expected O, but got Unknown if (initialized) { return; } initialized = true; uncovered = (from r in ((Component)this).GetComponentsInChildren<SkinnedMeshRenderer>(true) where ((Object)r).name == "FuwawaJacketOffSleeves" select r).ToArray(); SkinnedMeshRenderer[] array = uncovered; for (int num = 0; num < array.Length; num++) { ((Renderer)array[num]).enabled = !Shown; } array = ((Component)this).GetComponentsInChildren<SkinnedMeshRenderer>(true); foreach (SkinnedMeshRenderer val in array) { if (!Object.op_Implicit((Object)(object)val.sharedMesh)) { continue; } Variant variant = Get(val); if (variant.Removed > 0) { slots.Add(new Slot { Renderer = val, Mesh = variant }); } if (!Object.op_Implicit((Object)(object)CleanBodyTexture)) { continue; } Material[] sharedMaterials = ((Renderer)val).sharedMaterials; for (int num2 = 0; num2 < sharedMaterials.Length; num2++) { if (materialOrigins.TryGetValue(sharedMaterials[num2], out var value)) { sharedMaterials[num2] = value; } } ((Renderer)val).sharedMaterials = sharedMaterials; Material[] array2 = (Material[])sharedMaterials.Clone(); bool flag = false; for (int num3 = 0; num3 < sharedMaterials.Length; num3++) { if (((Object)sharedMaterials[num3]).name.StartsWith("MococoAbyssgard_Material_00") || ((Object)sharedMaterials[num3]).name.StartsWith("MococoAbyssgard_Material_01") || ((Object)sharedMaterials[num3]).name.StartsWith("MococoAbyssgard_Material_03")) { Material val2 = new Material(sharedMaterials[num3]); val2.SetTexture("_BaseColorMap", CleanBodyTexture); array2[num3] = val2; owned.Add(val2); materialOrigins[val2] = sharedMaterials[num3]; flag = true; } } if (flag) { materialSlots.Add(new MaterialSlot { Renderer = val, On = sharedMaterials, Off = array2 }); } } motion = ((Component)this).GetComponent<AdventSecondaryMotion>(); if (Object.op_Implicit((Object)(object)motion)) { allNodes = motion.nodes; uncoveredNodes = allNodes.Where((AdventSecondaryMotion.Node n) => Object.op_Implicit((Object)(object)n.bone) && !PhysicsBones.Contains(((Object)n.bone).name)).ToArray(); } } public void Rebind() { foreach (MaterialSlot materialSlot in materialSlots) { if (Object.op_Implicit((Object)(object)materialSlot.Renderer)) { ((Renderer)materialSlot.Renderer).sharedMaterials = materialSlot.On; } } foreach (Material item in owned) { materialOrigins.Remove(item); if (Object.op_Implicit((Object)(object)item)) { Object.Destroy((Object)(object)item); } } materialSlots.Clear(); owned.Clear(); slots.Clear(); initialized = false; Shown = true; Initialize(); } public void PrepareForViewConversion() { SkinnedMeshRenderer[] componentsInChildren = ((Component)this).GetComponentsInChildren<SkinnedMeshRenderer>(true); foreach (SkinnedMeshRenderer val in componentsInChildren) { if (Object.op_Implicit((Object)(object)val.sharedMesh) && originals.TryGetValue(val.sharedMesh, out var value)) { val.sharedMesh = value; } } } public void Apply(bool shown) { Initialize(); if (Shown == shown) { return; } Shown = shown; foreach (Slot slot in slots) { if (Object.op_Implicit((Object)(object)slot.Renderer)) { slot.Renderer.sharedMesh = (shown ? slot.Mesh.On : slot.Mesh.Off); int blendShapeIndex = slot.Renderer.sharedMesh.GetBlendShapeIndex("jacket_off_fit"); if (blendShapeIndex >= 0) { slot.Renderer.SetBlendShapeWeight(blendShapeIndex, (float)((!shown) ? 100 : 0)); } } } SkinnedMeshRenderer[] array = uncovered; foreach (SkinnedMeshRenderer val in array) { if (Object.op_Implicit((Object)(object)val)) { ((Renderer)val).enabled = !shown; } } foreach (MaterialSlot materialSlot in materialSlots) { if (Object.op_Implicit((Object)(object)materialSlot.Renderer)) { ((Renderer)materialSlot.Renderer).sharedMaterials = (shown ? materialSlot.On : materialSlot.Off); } } if (Object.op_Implicit((Object)(object)motion) && ((Behaviour)motion).enabled) { motion.PrepareForAvatarPose(); motion.nodes = (shown ? allNodes : uncoveredNodes); motion.ResetSimulation(); } } private void OnDestroy() { foreach (MaterialSlot materialSlot in materialSlots) { if (Object.op_Implicit((Object)(object)materialSlot.Renderer)) { ((Renderer)materialSlot.Renderer).sharedMaterials = materialSlot.On; } } foreach (Material item in owned) { materialOrigins.Remove(item); if (Object.op_Implicit((Object)(object)item)) { Object.Destroy((Object)(object)item); } } } public static void ClearCache() { foreach (Variant value in cache.Values) { if (Object.op_Implicit((Object)(object)value.Off) && (Object)(object)value.Off != (Object)(object)value.On) { Object.Destroy((Object)(object)value.Off); } } cache.Clear(); originals.Clear(); materialOrigins.Clear(); } } public static class AdventOutfitControl { private sealed class Entry { public AdventJacketToggle Body; public AdventJacketToggle View; public string Character; } private static readonly Dictionary<PlayerControllerB, Entry> models = new Dictionary<PlayerControllerB, Entry>(); private static readonly Dictionary<PlayerControllerB, bool> settings = new Dictionary<PlayerControllerB, bool>(); public static void Bind(PlayerControllerB player, GameObject model, string character) { AdventJacketToggle component = model.GetComponent<AdventJacketToggle>(); if (Object.op_Implicit((Object)(object)player) && Object.op_Implicit((Object)(object)component)) { component.Initialize(); models[player] = new Entry { Body = component, Character = character }; if (!settings.ContainsKey(player)) { settings[player] = Plugin.JacketShown.Value; } component.Apply(Shown(player, character)); } } public static void AttachViews(AdventBody owner) { if (!Object.op_Implicit((Object)(object)owner) || !Object.op_Implicit((Object)(object)((BodyReplacementBase)owner).controller) || !models.TryGetValue(((BodyReplacementBase)owner).controller, out var value)) { return; } object obj = AdventRuntimeMembers.Read(AdventRuntimeMembers.Read(owner, "viewModelAvatar"), "replacementViewModel"); GameObject val = (GameObject)((obj is GameObject) ? obj : null); if (Object.op_Implicit((Object)(object)val)) { value.View = val.GetComponent<AdventJacketToggle>(); if (Object.op_Implicit((Object)(object)value.View)) { value.View.Rebind(); value.View.Apply(Shown(((BodyReplacementBase)owner).controller, value.Character)); } } } public static bool Shown(PlayerControllerB player, string character) { if (Object.op_Implicit((Object)(object)player) && !((NetworkBehaviour)player).IsOwner) { return AdventExpressionNetwork.JacketShown(player.playerClientId, character); } bool value = default(bool); return !Object.op_Implicit((Object)(object)player) || !settings.TryGetValue(player, out value) || value; } public static void Tick() { //IL_006b: Unknown result type (might be due to invalid IL or missing references) //IL_0078: Unknown result type (might be due to invalid IL or missing references) Keyboard current = Keyboard.current; foreach (KeyValuePair<PlayerControllerB, Entry> model in models) { PlayerControllerB key = model.Key; Entry value = model.Value; if (Object.op_Implicit((Object)(object)key) && Object.op_Implicit((Object)(object)value.Body)) { if (((NetworkBehaviour)key).IsOwner && current != null && !key.isTypingChat && !key.inTerminalMenu && (int)Plugin.JacketKey.Value != 0 && ((ButtonControl)current[Plugin.JacketKey.Value]).wasPressedThisFrame) { settings[key] = !Shown(key, value.Character); } bool shown = Shown(key, value.Character); value.Body.Apply(shown); if (Object.op_Implicit((Object)(object)value.View)) { value.View.Apply(shown); } } } } public static void Clear() { models.Clear(); settings.Clear(); AdventJacketToggle.ClearCache(); } } [DefaultExecutionOrder(270)] public sealed class AdventReactionFace : MonoBehaviour { internal static readonly Dictionary<PlayerControllerB, AdventReactionFace> Players = new Dictionary<PlayerControllerB, AdventReactionFace>(); internal static readonly Dictionary<ulong, string> CorpseCharacters = new Dictionary<ulong, string>(); public PlayerControllerB Player; public string Character; private AdventBody body; private AdventExpressionMixer mixer; private readonly AdventExpressionSelection selection = new AdventExpressionSelection(); private readonly HashSet<int> inventory = new HashSet<int>(); private readonly HashSet<int> currentInventory = new HashSet<int>(); private int health; private float nextContext; private AdventExpressionContext context; private AdventExpression sent = (AdventExpression)255; private bool sentUnsafe; private bool sentGlow; private bool sentJacket = true; private bool sentClaws = true; private bool sentCrown = true; private bool sentOrnaments = true; private float nextHeartbeat; private Component customEmotes; private float nextEmoteLookup; private readonly RaycastHit[] hits = (RaycastHit[])(object)new RaycastHit[24]; private static Type emoteType; private static bool emoteTypeResolved; private static EnemyAI[] enemies = (EnemyAI[])(object)new EnemyAI[0]; private static VehicleController[] vehicles = (VehicleController[])(object)new VehicleController[0]; private static StartOfRound scene; private static float nextSceneScan; internal AdventExpression Current { get; private set; } public void Initialize(AdventBody owner, PlayerControllerB player, string character) { body = owner; Player = player; Character = character; selection.Character = character; health = player.health; SeedInventory(); mixer = new AdventExpressionMixer(((Component)this).gameObject); Players[player] = this; } private void SeedInventory() { inventory.Clear(); if (Player.ItemSlots == null) { return; } GrabbableObject[] itemSlots = Player.ItemSlots; foreach (GrabbableObject val in itemSlots) { if (Object.op_Implicit((Object)(object)val)) { inventory.Add(((Object)val).GetInstanceID()); } } } internal void Damage() { selection.Damage(Time.unscaledTime); } internal void WeaponUsed() { selection.WeaponUsed(Time.unscaledTime); } private static void Scan(float now) { if ((Object)(object)scene != (Object)(object)StartOfRound.Instance) { scene = StartOfRound.Instance; nextSceneScan = 0f; enemies = (EnemyAI[])(object)new EnemyAI[0]; vehicles = (VehicleController[])(object)new VehicleController[0]; CorpseCharacters.Clear(); } if (!(now < nextSceneScan)) { nextSceneScan = now + 1f; enemies = AdventSceneCache.Enemies(now); vehicles = Object.FindObjectsByType<VehicleController>((FindObjectsSortMode)0); } } internal static bool DangerousNearOrChasing(PlayerControllerB p) { //IL_0058: Unknown result type (might be due to invalid IL or missing references) //IL_0063: Unknown result type (might be due to invalid IL or missing references) //IL_0068: Unknown result type (might be due to invalid IL or missing references) //IL_006d: Unknown result type (might be due to invalid IL or missing references) EnemyAI[] array = enemies; foreach (EnemyAI val in array) { if (!Object.op_Implicit((Object)(object)val) || val.isEnemyDead || !((Behaviour)val).isActiveAndEnabled) { continue; } string name = ((object)val).GetType().Name; if (!(name == "DocileLocustBeesAI") && !(name == "DoublewingAI")) { Vector3 val2 = ((Component)val).transform.position - ((Component)p).transform.position; if (((Vector3)(ref val2)).sqrMagnitude <= 36f || ((Object)(object)val.targetPlayer == (Object)(object)p && (val.movingTowardsTargetPlayer || val.currentBehaviourStateIndex > 0))) { return true; } } } return false; } private static Type OptionalEmoteType() { if (emoteTypeResolved) { return emoteType; } emoteTypeResolved = true; Assembly[] assemblies = AppDomain.CurrentDomain.GetAssemblies(); foreach (Assembly assembly in assemblies) { try { Type type = assembly.GetType("TooManyEmotes.EmoteControllerPlayer", throwOnError: false); if (type != null) { emoteType = type; break; } } catch (TypeLoadException) { } } return emoteType; } private bool Dancing() { //IL_00d7: Unknown result type (might be due to invalid IL or missing references) //IL_00dc: Unknown result type (might be due to invalid IL or missing references) if (Time.unscaledTime >= nextEmoteLookup) { nextEmoteLookup = Time.unscaledTime + 2f; Type type = OptionalEmoteType(); customEmotes = ((type != null) ? ((Component)Player).GetComponent(type) : null); } bool value = default(bool); if (Object.op_Implicit((Object)(object)customEmotes) && AdventRuntimeMembers.TryRead<bool>(customEmotes, "isPerformingEmote", out value) && value) { if (AdventRuntimeMembers.TryRead<bool>(AdventRuntimeMembers.Read(customEmotes, "performingEmote"), "isPose", out var value2)) { return !value2; } return true; } if (!Player.performingEmote) { return false; } if (AdventRuntimeMembers.TryRead<int>(body, "danceNumber", out var value3) && value3 == 1) { return true; } if (!Object.op_Implicit((Object)(object)Player.playerBodyAnimator)) { return false; } AnimatorStateInfo currentAnimatorStateInfo = Player.playerBodyAnimator.GetCurrentAnimatorStateInfo(1); return ((AnimatorStateInfo)(ref currentAnimatorStateInfo)).IsName("Emotes.Emote1"); } private static Transform View(PlayerControllerB p) { if (!Object.op_Implicit((Object)(object)p.gameplayCamera)) { if (!Object.op_Implicit((Object)(object)p.playerEye)) { return ((Component)p).transform; } return p.playerEye; } return ((Component)p.gameplayCamera).transform; } private bool Sees(PlayerControllerB target, Vector3 point, Transform targetRoot, float radius) { //IL_000d: Unknown result type (might be due to invalid IL or missing references) //IL_0013: Unknown result type (might be due to invalid IL or missing references) //IL_0018: 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_0028: Unknown result type (might be due to invalid IL or missing references) Transform val = View(Player); if (AdventAttentionSelection.InView(val.position, val.forward, point, radius)) { return AdventAttentionSelection.Visible(val.position, point, Object.op_Implicit((Object)(object)StartOfRound.Instance) ? StartOfRound.Instance.collidersAndRoomMaskAndDefault : (-5), ((Component)Player).transform, ((Component)this).transform, targetRoot, hits); } return false; } internal static string Id(PlayerControllerB p) { if (Players.TryGetValue(p, out var value) && Object.op_Implicit((Object)(object)value)) { return value.Character; } if (CorpseCharacters.TryGetValue(p.playerClientId, out var value2)) { return value2; } return AdventExpressionNetwork.CharacterOf(p.playerClientId); } private AdventExpressionContext Gather(float now) { //IL_0341: Unknown result type (might be due to invalid IL or missing references) //IL_026d: Unknown result type (might be due to invalid IL or missing references) //IL_0282: Unknown result type (might be due to invalid IL or missing references) //IL_027d: Unknown result type (might be due to invalid IL or missing references) //IL_0291: Unknown result type (might be due to invalid IL or missing references) //IL_029e: Unknown result type (might be due to invalid IL or missing references) //IL_02a3: Unknown result type (might be due to invalid IL or missing references) //IL_02a8: Unknown result type (might be due to invalid IL or missing references) //IL_02ea: Unknown result type (might be due to invalid IL or missing references) Scan(now); AdventExpressionContext result = new AdventExpressionContext { Dead = Player.isPlayerDead, Critical = (Player.criticallyInjured || Player.health < 10), EnemyNear = DangerousNearOrChasing(Player), Fear = (((NetworkBehaviour)Player).IsOwner && Object.op_Implicit((Object)(object)StartOfRound.Instance) && (StartOfRound.Instance.fearLevel > 0.01f || StartOfRound.Instance.fearLevelIncreasing)), Dancing = Dancing() }; VehicleController[] array = vehicles; foreach (VehicleController val in array) { if (Object.op_Implicit((Object)(object)val) && (Object)(object)val.currentDriver == (Object)(object)Player) { result.Driving = true; break; } } GrabbableObject val2 = (Object.op_Implicit((Object)(object)Player.currentlyHeldObjectServer) ? Player.currentlyHeldObjectServer : Play