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 Myth v1.0.0
MythSuit.dll
Decompiled 14 hours ago
The result has been truncated due to the large size, download it to view full contents!
using System; using System.Collections; 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 BepInEx.Logging; using GameNetcodeStuff; using HarmonyLib; using ModelReplacement; using ModelReplacement.AvatarBodyUpdater; using ModelReplacement.Scripts.Enemies; using ModelReplacement.Scripts.Player; using Unity.Collections; using Unity.Netcode; using UnityEngine; using UnityEngine.InputSystem; using UnityEngine.InputSystem.Controls; using UnityEngine.Rendering; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: AssemblyCopyright("© 2016 cover corp.")] [assembly: AssemblyFileVersion("1.0.0")] [assembly: AssemblyInformationalVersion("1.0.0")] [assembly: AssemblyVersion("1.0.0.0")] namespace MythSuit; public static class MaskedAppearanceCompatibility { private static readonly Type HostType = typeof(BodyReplacementBase).Assembly.GetType("ModelReplacement.Monobehaviors.Enemies.MaskedReplacementBase"); private static readonly FieldInfo ModelField = ((HostType == null) ? null : AccessTools.Field(HostType, "replacementModel")); private static readonly FieldInfo ActiveField = ((HostType == null) ? null : AccessTools.Field(HostType, "IsActive")); private static readonly PropertyInfo AvatarProperty = ((HostType == null) ? null : AccessTools.Property(HostType, "avatar")); private static readonly MethodInfo Replace = ((HostType == null) ? null : AccessTools.Method(HostType, "SetReplacement", new Type[1] { typeof(PlayerControllerB) }, (Type[])null)); private static readonly ManualLogSource Log = Logger.CreateLogSource("Myth masked compatibility"); public static void Install(Harmony harmony) { //IL_004d: Unknown result type (might be due to invalid IL or missing references) //IL_005b: Expected O, but got Unknown //IL_0084: Unknown result type (might be due to invalid IL or missing references) //IL_0091: Expected O, but got Unknown if (Replace == null || ModelField == null || AvatarProperty == null) { Log.LogWarning((object)"Masked API entry points unavailable; player replacements remain enabled."); return; } harmony.Patch((MethodBase)Replace, new HarmonyMethod(typeof(MaskedAppearanceCompatibility), "Assign", (Type[])null), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null); harmony.Patch((MethodBase)AccessTools.Method(typeof(MaskedPlayerEnemy), "Start", (Type[])null, (Type[])null), (HarmonyMethod)null, new HarmonyMethod(typeof(MaskedAppearanceCompatibility), "Spawned", (Type[])null), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null); } private static bool Owns(PlayerControllerB player, out BodyReplacementBase body) { body = null; if (Object.op_Implicit((Object)(object)player) && ModelReplacementAPI.GetPlayerModelReplacement(player, ref body) && Object.op_Implicit((Object)(object)body)) { return ((object)body).GetType().Assembly == typeof(Plugin).Assembly; } return false; } private static void Spawned(MaskedPlayerEnemy __instance) { if (Object.op_Implicit((Object)(object)__instance) && !Object.op_Implicit((Object)(object)((Component)__instance).GetComponent<MaskedAppearanceRetry>())) { ((Component)__instance).gameObject.AddComponent<MaskedAppearanceRetry>().Enemy = __instance; } } internal static void Retry(MaskedPlayerEnemy enemy) { if (!Object.op_Implicit((Object)(object)enemy) || !Object.op_Implicit((Object)(object)enemy.mimickingPlayer) || !Owns(enemy.mimickingPlayer, out var body) || !Object.op_Implicit((Object)(object)body.replacementModel) || (Object)(object)body.viewState == (Object)null) { return; } Component component = ((Component)enemy).GetComponent(HostType); if (!Object.op_Implicit((Object)(object)component)) { ((Component)enemy).gameObject.AddComponent(HostType); return; } object? value = ModelField.GetValue(component); if (!Object.op_Implicit((Object)((value is GameObject) ? value : null))) { Replace.Invoke(component, new object[1] { enemy.mimickingPlayer }); } } private static bool Assign(object __instance, PlayerControllerB __0) { //IL_00cd: 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_016b: Unknown result type (might be due to invalid IL or missing references) //IL_0172: Expected O, but got Unknown if (!Owns(__0, out var body)) { return true; } if (!Object.op_Implicit((Object)(object)body.replacementModel) || (Object)(object)body.viewState == (Object)null) { return false; } object obj = ((__instance is Component) ? __instance : null); MaskedPlayerEnemy val = ((obj != null) ? ((Component)obj).GetComponent<MaskedPlayerEnemy>() : null); if (!Object.op_Implicit((Object)(object)val)) { return true; } GameObject val2 = null; object? value = ModelField.GetValue(__instance); GameObject val3 = (GameObject)((value is GameObject) ? value : null); try { MaskedModelFaceDriver maskedModelFaceDriver = (Object.op_Implicit((Object)(object)val3) ? val3.GetComponent<MaskedModelFaceDriver>() : null); if (Object.op_Implicit((Object)(object)maskedModelFaceDriver) && (Object)(object)maskedModelFaceDriver.SourcePlayer == (Object)(object)__0 && (Object)(object)maskedModelFaceDriver.SourceModel == (Object)(object)body.replacementModel) { return false; } val2 = Object.Instantiate<GameObject>(body.replacementModel); ((Object)val2).name = ((Object)body.replacementModel).name + " (Masked)"; val2.transform.localPosition = Vector3.zero; MaskedModelFaceDriver.DetachPlayerControllers(val2); Renderer[] componentsInChildren = val2.GetComponentsInChildren<Renderer>(true); foreach (Renderer obj2 in componentsInChildren) { ((Component)obj2).gameObject.layer = body.viewState.VisibleLayer; obj2.shadowCastingMode = (ShadowCastingMode)1; obj2.enabled = true; } Camera[] componentsInChildren2 = val2.GetComponentsInChildren<Camera>(true); for (int i = 0; i < componentsInChildren2.Length; i++) { ((Behaviour)componentsInChildren2[i]).enabled = false; } NaturalEyeSockets.Ensure(val2).Aim(Vector2.zero); val2.AddComponent<MaskedModelFaceDriver>().Initialize(val, __0, body.replacementModel); MaskedAvatarUpdater val4 = new MaskedAvatarUpdater(); val4.AssignModelReplacement(((Component)val).gameObject, val2); AvatarProperty.SetValue(__instance, val4, null); ModelField.SetValue(__instance, val2); ActiveField?.SetValue(__instance, true); val2.SetActive(true); SkinnedMeshRenderer[] array = (SkinnedMeshRenderer[])(object)new SkinnedMeshRenderer[3] { val.rendererLOD0, val.rendererLOD1, val.rendererLOD2 }; foreach (SkinnedMeshRenderer val5 in array) { if (Object.op_Implicit((Object)(object)val5)) { ((Renderer)val5).enabled = false; ((Renderer)val5).shadowCastingMode = (ShadowCastingMode)0; } } if (Object.op_Implicit((Object)(object)val3) && (Object)(object)val3 != (Object)(object)val2) { Object.Destroy((Object)(object)val3); } return false; } catch (Exception ex) { if (Object.op_Implicit((Object)(object)val2)) { Object.Destroy((Object)(object)val2); } Log.LogWarning((object)("Masked adapter could not initialize; retaining MRAPI fallback: " + ex)); return true; } } } public sealed class MaskedAppearanceRetry : MonoBehaviour { public MaskedPlayerEnemy Enemy; private float next; private void Update() { if (!(Time.unscaledTime < next)) { next = Time.unscaledTime + 1f; if (!Object.op_Implicit((Object)(object)Enemy) || ((EnemyAI)Enemy).isEnemyDead) { ((Behaviour)this).enabled = false; } else { MaskedAppearanceCompatibility.Retry(Enemy); } } } } [DefaultExecutionOrder(9000)] public sealed class MaskedModelFaceDriver : MonoBehaviour { private sealed class Face { public SkinnedMeshRenderer Renderer; public int Blink; public int Left; public int Right; public int Up; public int Down; public int Open; public int Round; public int Rest = -1; public float RestBase; } public PlayerControllerB SourcePlayer; public GameObject SourceModel; private MaskedPlayerEnemy enemy; private MaskedVanillaBadges.Binding vanillaBadges; private NaturalEyeSockets sockets; private Vector2 gaze; private bool morphGaze; private float nextBlink; private float blinkStart = -10f; private readonly List<Face> faces = new List<Face>(); private AudioSource mirageVoice; private float nextVoiceScan; private float voiceLevel; private readonly float[] voiceSamples = new float[128]; private static int Shape(Mesh mesh, string name) { for (int i = 0; i < mesh.blendShapeCount; i++) { string blendShapeName = mesh.GetBlendShapeName(i); if (blendShapeName == name || blendShapeName.EndsWith("." + name, StringComparison.Ordinal) || blendShapeName.EndsWith("_" + name, StringComparison.Ordinal)) { return i; } } return -1; } private static void Set(Face face, int index, float value) { if (Object.op_Implicit((Object)(object)face.Renderer) && index >= 0) { face.Renderer.SetBlendShapeWeight(index, value); } } public static void DetachPlayerControllers(GameObject clone) { MaskedCloneIsolation.Detach(clone, typeof(MaskedModelFaceDriver).Namespace); } public void Initialize(MaskedPlayerEnemy masked, PlayerControllerB source, GameObject model) { enemy = masked; SourcePlayer = source; SourceModel = model; vanillaBadges = MaskedVanillaBadges.Bind(((Component)masked).gameObject, (Object)(object)this); sockets = NaturalEyeSockets.Ensure(((Component)this).gameObject); nextBlink = Time.time + (float)Random.Range(2, 5); SkinnedMeshRenderer[] componentsInChildren = ((Component)this).GetComponentsInChildren<SkinnedMeshRenderer>(true); foreach (SkinnedMeshRenderer val in componentsInChildren) { if (!Object.op_Implicit((Object)(object)val.sharedMesh) || ((Object)val).name.IndexOf("Ink", StringComparison.OrdinalIgnoreCase) >= 0) { continue; } Mesh sharedMesh = val.sharedMesh; int num = Shape(sharedMesh, "blink"); if (num < 0) { num = Shape(sharedMesh, "Fac_Eye_Close"); } if (num >= 0) { Face face = new Face { Renderer = val, Blink = num, Left = Shape(sharedMesh, "eyes_look_left"), Right = Shape(sharedMesh, "eyes_look_right"), Up = Shape(sharedMesh, "eyes_look_up"), Down = Shape(sharedMesh, "eyes_look_down"), Open = Shape(sharedMesh, "speech_open"), Round = Shape(sharedMesh, "speech_round") }; MythOutfitState component = ((Component)this).GetComponent<MythOutfitState>(); string text = ((Object.op_Implicit((Object)(object)component) && component.CharacterId == "GawrGura") ? "source_一文字" : ((Object.op_Implicit((Object)(object)component) && component.CharacterId == "TakanashiKiara") ? "source_横棒" : null)); if (text != null) { face.Rest = Shape(sharedMesh, text); face.RestBase = ((face.Rest >= 0) ? val.GetBlendShapeWeight(face.Rest) : 0f); } morphGaze |= face.Left >= 0 && face.Right >= 0; faces.Add(face); } } MythAdaptiveLighting component2 = ((Component)this).GetComponent<MythAdaptiveLighting>(); if (!Object.op_Implicit((Object)(object)component2)) { return; } component2.Rebind(); component2.BindContext(delegate { //IL_0052: Unknown result type (might be due to invalid IL or missing references) //IL_0057: Unknown result type (might be due to invalid IL or missing references) //IL_0065: Unknown result type (might be due to invalid IL or missing references) bool factory = Object.op_Implicit((Object)(object)enemy) && !((EnemyAI)enemy).isOutside; int ship; if (Object.op_Implicit((Object)(object)enemy) && Object.op_Implicit((Object)(object)StartOfRound.Instance) && Object.op_Implicit((Object)(object)StartOfRound.Instance.shipInnerRoomBounds)) { Bounds bounds = StartOfRound.Instance.shipInnerRoomBounds.bounds; ship = (((Bounds)(ref bounds)).Contains(((Component)enemy).transform.position) ? 1 : 0); } else { ship = 0; } return new MythLightingContext(factory, (byte)ship != 0); }); } private float MouthLevel() { if (Time.unscaledTime >= nextVoiceScan) { nextVoiceScan = Time.unscaledTime + 1f; mirageVoice = null; Component[] componentsInChildren = ((Component)enemy).GetComponentsInChildren<Component>(true); foreach (Component val in componentsInChildren) { if (Object.op_Implicit((Object)(object)val) && ((object)val).GetType().FullName == "Mirage.Unity.AudioStream+AudioStream") { ref AudioSource reference = ref mirageVoice; object obj = MythRuntimeMembers.Read(val, "AudioSource"); reference = (AudioSource)((obj is AudioSource) ? obj : null); if (Object.op_Implicit((Object)(object)mirageVoice)) { break; } } } } float num = 0f; if (Plugin.Mouth.Value && !((EnemyAI)enemy).isEnemyDead && Object.op_Implicit((Object)(object)mirageVoice) && mirageVoice.isPlaying) { mirageVoice.GetOutputData(voiceSamples, 0); float num2 = 0f; float[] array = voiceSamples; foreach (float num3 in array) { num2 += num3 * num3; } num = Mathf.Clamp01(Mathf.Sqrt(num2 / (float)voiceSamples.Length) * Plugin.VoiceGain.Value); } voiceLevel = Mathf.Lerp(voiceLevel, num, 1f - Mathf.Exp((0f - Mathf.Min(Time.deltaTime, 0.1f)) * 18f)); return voiceLevel; } private void OnDestroy() { MaskedVanillaBadges.Release(vanillaBadges, (Object)(object)this); } private void LateUpdate() { //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_00ef: Unknown result type (might be due to invalid IL or missing references) //IL_00f4: Unknown result type (might be due to invalid IL or missing references) //IL_00fa: 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) //IL_011a: Unknown result type (might be due to invalid IL or missing references) //IL_0113: Unknown result type (might be due to invalid IL or missing references) //IL_00b7: Unknown result type (might be due to invalid IL or missing references) //IL_0096: Unknown result type (might be due to invalid IL or missing references) //IL_009b: Unknown result type (might be due to invalid IL or missing references) //IL_00a5: 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_00c7: Unknown result type (might be due to invalid IL or missing references) //IL_00cc: Unknown result type (might be due to invalid IL or missing references) //IL_00d7: Unknown result type (might be due to invalid IL or missing references) //IL_00e2: Unknown result type (might be due to invalid IL or missing references) //IL_00e7: Unknown result type (might be due to invalid IL or missing references) //IL_00ec: Unknown result type (might be due to invalid IL or missing references) if (!Object.op_Implicit((Object)(object)enemy)) { return; } vanillaBadges?.Hide(); if (!Object.op_Implicit((Object)(object)sockets)) { return; } Vector2 target = Vector2.zero; PlayerControllerB targetPlayer = ((EnemyAI)enemy).targetPlayer; if (!((EnemyAI)enemy).isEnemyDead && Plugin.Eyes.Value && Object.op_Implicit((Object)(object)targetPlayer) && !targetPlayer.isPlayerDead && Object.op_Implicit((Object)(object)sockets.Head)) { target = NaturalEyeMath.Target((Object.op_Implicit((Object)(object)targetPlayer.playerEye) ? targetPlayer.playerEye.position : (((Component)targetPlayer).transform.position + Vector3.up * 1.5f)) - sockets.Head.position, sockets.Forward, sockets.Up); } gaze = NaturalEyeMath.Smooth(gaze, target, Time.deltaTime); sockets.Aim(morphGaze ? Vector2.zero : gaze); if (Time.time >= nextBlink) { blinkStart = Time.time; nextBlink = Time.time + Random.Range(2.5f, 6f); } float num = Time.time - blinkStart; float value = ((!((EnemyAI)enemy).isEnemyDead && Plugin.Blink.Value && num >= 0f && num < 0.18f) ? (Mathf.Sin(num / 0.18f * (float)Math.PI) * 100f) : 0f); float num2 = MouthLevel(); foreach (Face face in faces) { Set(face, face.Rest, face.RestBase * (1f - num2)); Set(face, face.Open, num2 * 85f); Set(face, face.Round, num2 * (1f - num2) * 30f); Set(face, face.Blink, value); Set(face, face.Left, Mathf.Max(0f, (0f - gaze.x) / 12f) * 20f); Set(face, face.Right, Mathf.Max(0f, gaze.x / 12f) * 20f); Set(face, face.Up, Mathf.Max(0f, (0f - gaze.y) / 7f) * 15f); Set(face, face.Down, Mathf.Max(0f, gaze.y / 9f) * 15f); } } } public static class MaskedCloneIsolation { private const BindingFlags Flags = BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic; private static bool IsOwner(Type type) { Type type2 = type; while (type2 != null) { if (type2.Name == "PlayerControllerB" || type2.Name == "BodyReplacementBase") { return true; } type2 = type2.BaseType; } return false; } private static void Clear(Type type, MonoBehaviour component, string field, object value) { FieldInfo field2 = type.GetField(field, BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); if (field2 != null && !field2.IsInitOnly) { field2.SetValue(component, value); } } public static void Detach(GameObject clone, string ownNamespace) { MonoBehaviour[] componentsInChildren = clone.GetComponentsInChildren<MonoBehaviour>(true); foreach (MonoBehaviour val in componentsInChildren) { if (!Object.op_Implicit((Object)(object)val) || ((object)val).GetType().Namespace != ownNamespace) { continue; } Type type = ((object)val).GetType(); bool flag = false; FieldInfo[] fields = type.GetFields(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); foreach (FieldInfo fieldInfo in fields) { if (IsOwner(fieldInfo.FieldType)) { if (!fieldInfo.IsInitOnly) { fieldInfo.SetValue(val, null); } flag = true; } } if (flag || type.Name.EndsWith("ReactionFace", StringComparison.Ordinal) || type.Name.Contains("HeadTracking") || type.Name.EndsWith("Face", StringComparison.Ordinal) || type.Name.Contains("FirstPerson") || type.Name.Contains("RenderDiagnostics") || type.Name.Contains("RuntimeMotionAudit")) { ((Behaviour)val).enabled = false; } if (type.Name.EndsWith("OutfitState", StringComparison.Ordinal)) { Clear(type, val, "HasPlayerBinding", false); Clear(type, val, "Corpse", false); Clear(type, val, "SourceState", null); Clear(type, val, "AutomaticEars", false); type.GetMethod("Rebind", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic, null, Type.EmptyTypes, null)?.Invoke(val, null); } } } } public static class MaskedVanillaBadges { public sealed class Binding { internal GameObject Enemy; internal object[] State; public void Hide() { MeshRenderer[] array = (MeshRenderer[])State[1]; foreach (MeshRenderer val in array) { if (Object.op_Implicit((Object)(object)val) && ((Renderer)val).enabled) { ((Renderer)val).enabled = false; } } } } private const string Chest = "ScavengerModel/metarig/spine/spine.001/spine.002/spine.003/"; private const string StateKey = "RaidNight.SuitMods.MaskedVanillaBadges.v1"; private static Dictionary<GameObject, object[]> Active { get { Dictionary<GameObject, object[]> dictionary = AppDomain.CurrentDomain.GetData("RaidNight.SuitMods.MaskedVanillaBadges.v1") as Dictionary<GameObject, object[]>; if (dictionary == null) { dictionary = new Dictionary<GameObject, object[]>(); AppDomain.CurrentDomain.SetData("RaidNight.SuitMods.MaskedVanillaBadges.v1", dictionary); } return dictionary; } } public static Binding Bind(GameObject enemy, Object owner) { if (!Object.op_Implicit((Object)(object)enemy) || !Object.op_Implicit(owner)) { return null; } if (Active.TryGetValue(enemy, out var value)) { value[0] = owner; Binding binding = new Binding(); binding.Enemy = enemy; binding.State = value; binding.Hide(); return binding; } List<MeshRenderer> list = new List<MeshRenderer>(); string[] array = new string[2] { "LevelSticker", "BetaBadge" }; foreach (string text in array) { Transform val = enemy.transform.Find("ScavengerModel/metarig/spine/spine.001/spine.002/spine.003/" + text); MeshRenderer val2 = (Object.op_Implicit((Object)(object)val) ? ((Component)val).GetComponent<MeshRenderer>() : null); if (Object.op_Implicit((Object)(object)val2)) { list.Add(val2); } } bool[] array2 = new bool[list.Count]; for (int j = 0; j < list.Count; j++) { array2[j] = ((Renderer)list[j]).enabled; } object[] array3 = new object[3] { owner, list.ToArray(), array2 }; Binding obj = new Binding { Enemy = enemy, State = array3 }; Active.Add(enemy, array3); obj.Hide(); return obj; } public static void Release(Binding binding, Object owner) { if (binding == null || binding.State[0] != owner || !Active.TryGetValue(binding.Enemy, out var value) || value != binding.State) { return; } Active.Remove(binding.Enemy); MeshRenderer[] array = (MeshRenderer[])binding.State[1]; bool[] array2 = (bool[])binding.State[2]; for (int i = 0; i < array.Length; i++) { if (Object.op_Implicit((Object)(object)array[i])) { ((Renderer)array[i]).enabled = array2[i]; } } } } [Serializable] public struct MythLightingContext { public bool InsideFactory; public bool InsideShip; public bool Indoors { get { if (!InsideFactory) { return InsideShip; } return true; } } public float Floor { get { if (!Indoors) { return 0.075f; } return 0f; } } public MythLightingContext(bool factory, bool ship) { InsideFactory = factory; InsideShip = ship; } } public sealed class MythCorpseLightingContext { private MythLightingContext context; private bool trackedItem; public MythCorpseLightingContext(MythLightingContext death) { context = death; } public MythLightingContext Observe(bool bodyInShip, bool hasHolder, MythLightingContext holder, bool hasItem, MythLightingContext item) { if (hasHolder) { context = holder; trackedItem = true; } else if (hasItem && trackedItem) { context = item; } if (!bodyInShip) { return context; } return new MythLightingContext(factory: false, ship: true); } } [DefaultExecutionOrder(600)] public sealed class MythAdaptiveLighting : MonoBehaviour { private struct Draw { public Renderer Renderer; public int Slot; public bool Floor; public bool Ink; public Color InkColor; } public Renderer[] receivers; private readonly List<Draw> draws = new List<Draw>(); private MaterialPropertyBlock block; private Func<MythLightingContext> contextReader; private bool initialized; private static readonly int FloorId = Shader.PropertyToID("_GflAmbientFloor"); private static readonly int InkId = Shader.PropertyToID("_InkColor"); public MythLightingContext Context { get; private set; } public float CurrentFloor => Context.Floor; public int FloorSlots { get; private set; } public int InkSlots { get; private set; } private void Awake() { Rebind(); Refresh(); } private void OnEnable() { if (initialized) { Refresh(); } } public void Rebind() { //IL_0009: Unknown result type (might be due to invalid IL or missing references) //IL_0013: Expected O, but got Unknown //IL_00da: Unknown result type (might be due to invalid IL or missing references) //IL_00cc: Unknown result type (might be due to invalid IL or missing references) //IL_00df: Unknown result type (might be due to invalid IL or missing references) if (block == null) { block = new MaterialPropertyBlock(); } draws.Clear(); int floorSlots = (InkSlots = 0); FloorSlots = floorSlots; receivers = ((Component)this).GetComponentsInChildren<Renderer>(true); Renderer[] array = receivers; foreach (Renderer val in array) { Material[] sharedMaterials = val.sharedMaterials; for (int i = 0; i < sharedMaterials.Length; i++) { Material val2 = sharedMaterials[i]; if (!Object.op_Implicit((Object)(object)val2)) { continue; } bool flag = val2.HasProperty(FloorId); bool flag2 = val2.HasProperty(InkId); if (flag || flag2) { draws.Add(new Draw { Renderer = val, Slot = i, Floor = flag, Ink = flag2, InkColor = (flag2 ? val2.GetColor(InkId) : Color.black) }); if (flag) { FloorSlots++; } if (flag2) { InkSlots++; } } } } initialized = true; Apply(Context); } public void BindContext(Func<MythLightingContext> reader) { contextReader = reader; Refresh(); } public MythLightingContext ReadContext() { if (contextReader == null) { return Context; } return contextReader(); } public void InheritContext(MythAdaptiveLighting source) { if (Object.op_Implicit((Object)(object)source)) { BindContext(source.ReadContext); } } public void Refresh() { Apply(ReadContext()); } public void Apply(MythLightingContext context) { //IL_0088: Unknown result type (might be due to invalid IL or missing references) //IL_008d: Unknown result type (might be due to invalid IL or missing references) //IL_00be: Unknown result type (might be due to invalid IL or missing references) //IL_00a8: Unknown result type (might be due to invalid IL or missing references) if (!initialized) { Rebind(); } Context = context; foreach (Draw draw in draws) { if (!Object.op_Implicit((Object)(object)draw.Renderer)) { continue; } block.Clear(); draw.Renderer.GetPropertyBlock(block, draw.Slot); if (draw.Floor) { block.SetFloat(FloorId, context.Floor); } if (draw.Ink) { Color inkColor = draw.InkColor; if (context.Indoors) { ((Color)(ref inkColor))..ctor(0f, 0f, 0f, inkColor.a); } block.SetColor(InkId, inkColor); } draw.Renderer.SetPropertyBlock(block, draw.Slot); } } private void LateUpdate() { Refresh(); } } internal static class MythLightingControl { private sealed class Death { internal ulong Owner; internal MythLightingContext Context; } private static readonly Dictionary<PlayerControllerB, Death> deaths = new Dictionary<PlayerControllerB, Death>(); private static readonly FieldInfo sourceField = AccessTools.Field(typeof(BodyReplacementBase), "replacementModel"); private static readonly FieldInfo shadowField = AccessTools.Field(typeof(BodyReplacementBase), "replacementModelShadow"); private static readonly FieldInfo viewField = AccessTools.Field(typeof(BodyReplacementBase), "replacementViewModel"); private static MythLightingContext Native(PlayerControllerB player) { if (!Object.op_Implicit((Object)(object)player)) { return default(MythLightingContext); } return new MythLightingContext(player.isInsideFactory, player.isInHangarShipRoom); } internal static void Install(Harmony harmony) { //IL_0028: Unknown result type (might be due to invalid IL or missing references) //IL_0035: Expected O, but got Unknown //IL_009e: Unknown result type (might be due to invalid IL or missing references) //IL_00ac: Expected O, but got Unknown //IL_00d4: Unknown result type (might be due to invalid IL or missing references) //IL_00e2: Expected O, but got Unknown //IL_010b: Unknown result type (might be due to invalid IL or missing references) //IL_0118: Expected O, but got Unknown //IL_0069: Unknown result type (might be due to invalid IL or missing references) //IL_0076: Expected O, but got Unknown harmony.Patch((MethodBase)AccessTools.Method(typeof(BodyReplacementBase), "Awake", (Type[])null, (Type[])null), (HarmonyMethod)null, new HarmonyMethod(typeof(MythLightingControl), "Created", (Type[])null), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null); MethodInfo methodInfo = AccessTools.Method(typeof(BodyReplacementBase), "LoadRagdollReplacement", (Type[])null, (Type[])null); if (methodInfo != null) { harmony.Patch((MethodBase)methodInfo, (HarmonyMethod)null, new HarmonyMethod(typeof(MythLightingControl), "Ragdoll", (Type[])null), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null); } harmony.Patch((MethodBase)AccessTools.Method(typeof(PlayerControllerB), "KillPlayer", (Type[])null, (Type[])null), new HarmonyMethod(typeof(MythLightingControl), "CaptureDeath", (Type[])null), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null); harmony.Patch((MethodBase)AccessTools.Method(typeof(PlayerControllerB), "SpawnDeadBody", (Type[])null, (Type[])null), new HarmonyMethod(typeof(MythLightingControl), "CaptureRemoteDeath", (Type[])null), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null); harmony.Patch((MethodBase)AccessTools.Method(typeof(StartOfRound), "ReviveDeadPlayers", (Type[])null, (Type[])null), (HarmonyMethod)null, new HarmonyMethod(typeof(MythLightingControl), "Clear", (Type[])null), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null); } private static void CaptureDeath(PlayerControllerB __instance) { if (Object.op_Implicit((Object)(object)__instance) && !__instance.isPlayerDead) { deaths[__instance] = new Death { Owner = ((NetworkBehaviour)__instance).OwnerClientId, Context = Native(__instance) }; } } private static void CaptureRemoteDeath(PlayerControllerB deadPlayerController) { if (Object.op_Implicit((Object)(object)deadPlayerController) && !((NetworkBehaviour)deadPlayerController).IsOwner) { deaths[deadPlayerController] = new Death { Owner = ((NetworkBehaviour)deadPlayerController).OwnerClientId, Context = Native(deadPlayerController) }; } } private static void Created(BodyReplacementBase __instance) { if (__instance is MythBody mythBody && Object.op_Implicit((Object)(object)((BodyReplacementBase)mythBody).controller)) { FieldInfo[] array = new FieldInfo[3] { sourceField, shadowField, viewField }; for (int i = 0; i < array.Length; i++) { object? obj = array[i]?.GetValue(mythBody); Bind((GameObject)((obj is GameObject) ? obj : null), ((BodyReplacementBase)mythBody).controller); } } } internal static void AttachView(GameObject playerObject, GameObject view) { if (Object.op_Implicit((Object)(object)playerObject) && Object.op_Implicit((Object)(object)view) && Object.op_Implicit((Object)(object)view.GetComponent<MythAdaptiveLighting>())) { Bind(view, playerObject.GetComponent<PlayerControllerB>()); } } private static void Ragdoll(BodyReplacementBase __instance, GameObject __result) { if (__instance is MythBody mythBody && Object.op_Implicit((Object)(object)((BodyReplacementBase)mythBody).controller)) { Bind(__result, ((BodyReplacementBase)mythBody).controller, corpse: true); } } private static void Bind(GameObject model, PlayerControllerB player, bool corpse = false) { if (!Object.op_Implicit((Object)(object)model) || !Object.op_Implicit((Object)(object)player)) { return; } MythAdaptiveLighting mythAdaptiveLighting = model.GetComponent<MythAdaptiveLighting>() ?? model.AddComponent<MythAdaptiveLighting>(); mythAdaptiveLighting.Rebind(); ulong owner = ((NetworkBehaviour)player).OwnerClientId; if (!corpse) { mythAdaptiveLighting.BindContext(() => (!Object.op_Implicit((Object)(object)player) || ((NetworkBehaviour)player).OwnerClientId != owner) ? default(MythLightingContext) : Native(player)); return; } Death value; MythLightingContext death = ((deaths.TryGetValue(player, out value) && value.Owner == owner) ? value.Context : Native(player)); MythCorpseLightingContext corpseContext = new MythCorpseLightingContext(death); DeadBodyInfo nativeBody = player.deadBody; mythAdaptiveLighting.BindContext(delegate { if (!Object.op_Implicit((Object)(object)nativeBody)) { return corpseContext.Observe(bodyInShip: false, hasHolder: false, default(MythLightingContext), hasItem: false, default(MythLightingContext)); } GrabbableObject grabBodyObject = nativeBody.grabBodyObject; PlayerControllerB val = ((Object.op_Implicit((Object)(object)grabBodyObject) && grabBodyObject.isHeld) ? grabBodyObject.playerHeldBy : null); return corpseContext.Observe(nativeBody.isInShip || nativeBody.parentedToShip, Object.op_Implicit((Object)(object)val), Native(val), Object.op_Implicit((Object)(object)grabBodyObject), Object.op_Implicit((Object)(object)grabBodyObject) ? new MythLightingContext(grabBodyObject.isInFactory, grabBodyObject.isInShipRoom) : default(MythLightingContext)); }); } internal static void Clear() { deaths.Clear(); } } public enum AttentionKind { Player, Enemy, Item } public struct AttentionCandidate { public int Key; public AttentionKind Kind; public float Distance; public bool Speaking; public bool Eligible; public AttentionCandidate(int key, AttentionKind kind, float distance, bool speaking = true, bool eligible = true) { Key = key; Kind = kind; Distance = distance; Speaking = speaking; Eligible = eligible; } } public sealed class MythAttentionSelection { 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 MythAttention { private sealed class ItemRenderer { public GrabbableObject Item; public Renderer Renderer; } private readonly MythAttentionSelection selection = new MythAttentionSelection(); 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 = MythSceneCache.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 (MythAttentionSelection.InView(origin, forward, val, range)) { int mask = (Object.op_Implicit((Object)(object)StartOfRound.Instance) ? StartOfRound.Instance.collidersAndRoomMaskAndDefault : (-5)); if (MythAttentionSelection.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 = MythVoiceActivity.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 MythVoiceActivity { 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 = MythFace.Read(player, "voicePlayerState") ?? MythFace.Read(MythFace.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 = MythFace.Read(StartOfRound.Instance, "voiceChatModule"); if (comms != null) { string text = (((NetworkBehaviour)player).IsOwner ? (MythFace.Read(comms, "LocalPlayerName") as string) : (MythFace.Read(player, "voicePlayerName") as string)); if (!string.IsNullOrEmpty(text)) { try { obj = MythRuntimeMembers.CallString(comms, "FindPlayer", text); if (obj != null) { states[instanceID] = obj; } } catch { } } } } bool value3; bool flag = MythRuntimeMembers.TryRead<bool>(obj, "IsSpeaking", out value3) && value3; if (MythRuntimeMembers.TryRead<bool>(obj, "IsConnected", out var value4) && !value4) { return false; } if (!MythRuntimeMembers.TryRead<float>(obj, "Amplitude", out var value5)) { return flag; } return MythAttentionSelection.ActiveSpeech(flag, value5); } internal static void Clear() { comms = null; retry.Clear(); states.Clear(); } } public enum MythExpression : byte { Neutral, Frightened, Hurt, Happy, Surprised, VeryHappy, Dead } public struct MythExpressionContext { public bool Dead; public bool Critical; public bool EnemyNear; public bool Fear; public bool Chased; public bool Dancing; public bool Unsafe { get { if (!EnemyNear && !Fear) { return Chased; } return true; } } } public sealed class MythExpressionSelection { private double hurtUntil = -1.0; private double treasureUntil = -1.0; private bool surprised = true; private int pickups; public void Damage(double now) { hurtUntil = now + 2.0; } public void PickedUp(int value, double now) { if (value > 100) { treasureUntil = now + 3.5; surprised = pickups++ % 2 == 0; } } public void Reset() { hurtUntil = (treasureUntil = -1.0); pickups = 0; surprised = true; } public MythExpression Choose(MythExpressionContext c, double now) { if (c.Dead) { return MythExpression.Dead; } if (c.Critical || now < hurtUntil) { return MythExpression.Hurt; } if (c.Unsafe) { return MythExpression.Frightened; } if (now < treasureUntil) { if (!surprised) { return MythExpression.VeryHappy; } return MythExpression.Surprised; } if (c.Dancing) { return MythExpression.Happy; } return MythExpression.Neutral; } } public struct MythExpressionWeight { public string Shape; public float Weight; public bool Eyes; public bool Mouth; public MythExpressionWeight(string shape, float weight, bool eyes = false, bool mouth = false) { Shape = "expr_" + shape; Weight = weight; Eyes = eyes; Mouth = mouth; } } public static class MythExpressionProfiles { private static readonly MythExpressionWeight[][] profiles = new MythExpressionWeight[7][] { new MythExpressionWeight[0], new MythExpressionWeight[4] { B("worry", 0.75f), B("brow_up", 0.25f), E("surprise", 0.85f), M("triangle", 0.6f) }, new MythExpressionWeight[4] { B("worry", 0.85f), B("serious", 0.25f), E("focus", 0.45f), M("clench", 0.8f) }, new MythExpressionWeight[3] { B("happy_brows", 0.45f), E("smile_eyes", 0.65f), M("smile", 0.85f) }, new MythExpressionWeight[3] { B("brow_up", 0.65f), E("surprise", 0.9f), M("o", 0.65f) }, new MythExpressionWeight[3] { B("happy_brows", 0.65f), E("smile_eyes", 0.85f), M("laugh", 0.85f) }, new MythExpressionWeight[2] { B("worry", 0.7f), M("clench", 0.55f) } }; private static MythExpressionWeight B(string n, float w) { return new MythExpressionWeight(n, w); } private static MythExpressionWeight E(string n, float w) { return new MythExpressionWeight(n, w, eyes: true); } private static MythExpressionWeight M(string n, float w) { return new MythExpressionWeight(n, w, eyes: false, mouth: true); } public static MythExpressionWeight[] Weights(MythExpression state, string character = "") { MythExpressionWeight[] array = profiles[(uint)state]; MythExpressionWeight[] array2 = new MythExpressionWeight[array.Length]; float num = character switch { "GawrGura" => 1f, "MoriCalliope" => 0.78f, "TakanashiKiara" => 1.08f, "NinomaeInanis" => 0.65f, _ => 0.88f, }; for (int i = 0; i < array.Length; i++) { array2[i] = array[i]; array2[i].Weight = Mathf.Clamp01(array[i].Weight * num); } if (state == MythExpression.Neutral) { switch (character) { case "NinomaeInanis": return new MythExpressionWeight[2] { E("focus", 0.12f), M("smile", 0.1f) }; case "GawrGura": return new MythExpressionWeight[1] { new MythExpressionWeight { Shape = "source_一文字", Weight = 1f, Mouth = true } }; case "TakanashiKiara": return new MythExpressionWeight[1] { new MythExpressionWeight { Shape = "source_横棒", Weight = 1f, Mouth = true } }; case "WatsonAmelia": return new MythExpressionWeight[1] { B("serious", 0.1f) }; case "MoriCalliope": return new MythExpressionWeight[2] { B("serious", 0.1f), M("smile", 0.06f) }; } } if (character == "MoriCalliope" && state == MythExpression.Frightened) { return new MythExpressionWeight[3] { B("serious", 0.6f), E("focus", 0.25f), M("clench", 0.3f) }; } if (character == "WatsonAmelia" && state == MythExpression.Happy) { return new MythExpressionWeight[2] { B("happy_brows", 0.25f), M("smile", 0.7f) }; } return array2; } } public sealed class MythExpressionMixer { 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 string character; public MythExpressionMixer(GameObject model) { MythOutfitState component = model.GetComponent<MythOutfitState>(); character = (Object.op_Implicit((Object)(object)component) ? component.CharacterId : ""); foreach (MythExpression value in Enum.GetValues(typeof(MythExpression))) { MythExpressionWeight[] array = MythExpressionProfiles.Weights(value, character); for (int i = 0; i < array.Length; i++) { MythExpressionWeight mythExpressionWeight = array[i]; if (!slots.ContainsKey(mythExpressionWeight.Shape)) { slots[mythExpressionWeight.Shape] = shapes.Count; shapes.Add(mythExpressionWeight.Shape); } } } string[] array2 = new string[12] { "worry", "brow_up", "serious", "happy_brows", "surprise", "focus", "smile_eyes", "triangle", "clench", "smile", "o", "laugh" }; foreach (string text in array2) { if (!slots.ContainsKey("expr_" + text)) { slots["expr_" + text] = shapes.Count; shapes.Add("expr_" + text); } } values = new float[shapes.Count]; target = new float[shapes.Count]; eyes = new bool[shapes.Count]; mouth = new bool[shapes.Count]; foreach (MythExpression value2 in Enum.GetValues(typeof(MythExpression))) { MythExpressionWeight[] array = MythExpressionProfiles.Weights(value2, character); for (int i = 0; i < array.Length; i++) { MythExpressionWeight mythExpressionWeight2 = array[i]; int num = slots[mythExpressionWeight2.Shape]; eyes[num] |= mythExpressionWeight2.Eyes; mouth[num] |= mythExpressionWeight2.Mouth; } } SkinnedMeshRenderer[] componentsInChildren = model.GetComponentsInChildren<SkinnedMeshRenderer>(true); foreach (SkinnedMeshRenderer val in componentsInChildren) { if (Object.op_Implicit((Object)(object)val.sharedMesh) && !MythInkOutline.IsInk(val)) { 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); } } Step(MythExpression.Neutral, 0f, immediate: true); } public void Step(MythExpression state, float delta, bool immediate = false) { Array.Clear(target, 0, target.Length); MythExpressionWeight[] array = MythExpressionProfiles.Weights(state, character); for (int i = 0; i < array.Length; i++) { MythExpressionWeight mythExpressionWeight = array[i]; target[slots[mythExpressionWeight.Shape]] = mythExpressionWeight.Weight; } float num = ((immediate || state == MythExpression.Dead) ? 1f : (1f - Mathf.Exp((0f - Mathf.Clamp(delta, 0f, 0.1f)) * 13f))); for (int j = 0; j < values.Length; j++) { values[j] = Mathf.Lerp(values[j], target[j], num); } foreach (Binding binding in bindings) { if (!Object.op_Implicit((Object)(object)binding.Renderer)) { continue; } float num2 = ((binding.Blink < 0) ? 0f : Mathf.Clamp01(binding.Renderer.GetBlendShapeWeight(binding.Blink) / 100f)); float num3 = ((binding.Open < 0) ? 0f : Mathf.Clamp01(binding.Renderer.GetBlendShapeWeight(binding.Open) / 85f)); if (state == MythExpression.Dead) { num2 = 1f; num3 = 0f; if (binding.Blink >= 0) { binding.Renderer.SetBlendShapeWeight(binding.Blink, 100f); } if (binding.Open >= 0) { binding.Renderer.SetBlendShapeWeight(binding.Open, 0f); } if (binding.Round >= 0) { binding.Renderer.SetBlendShapeWeight(binding.Round, 0f); } } for (int k = 0; k < values.Length; k++) { if (binding.Indices[k] >= 0) { float num4 = values[k]; if (eyes[k]) { num4 *= 1f - num2; } if (mouth[k]) { num4 *= 1f - num3 * (shapes[k].StartsWith("source_", StringComparison.Ordinal) ? 1f : 0.55f); } binding.Renderer.SetBlendShapeWeight(binding.Indices[k], num4 * 100f); } } } } } [DefaultExecutionOrder(280)] public sealed class MythDeathFace : MonoBehaviour { private MythExpressionMixer mixer; public void Initialize() { mixer = new MythExpressionMixer(((Component)this).gameObject); mixer.Step(MythExpression.Dead, 0f, immediate: true); } private void LateUpdate() { if (mixer == null) { Initialize(); } mixer.Step(MythExpression.Dead, 0f, immediate: true); } } public struct MythExpressionRecord { public ulong PlayerId; public ulong Owner; public byte Character; public MythExpression Expression; public uint Revision; } public sealed class MythExpressionStore { private sealed class Entry { public MythExpressionRecord Record; public double At; } private readonly Dictionary<ulong, Entry> records = new Dictionary<ulong, Entry>(); public bool Accept(ulong sender, ulong actualOwner, MythExpressionRecord value, double now) { if (sender != actualOwner || value.Owner != actualOwner || value.Character >= MythOutfitProtocol.Characters.Length || (int)value.Expression > 6 || double.IsNaN(now) || double.IsInfinity(now)) { return false; } if (records.TryGetValue(value.PlayerId, out var value2) && value2.Record.Owner == actualOwner && (value.Revision < value2.Record.Revision || (value.Revision == value2.Record.Revision && (value.Character != value2.Record.Character || value.Expression != value2.Record.Expression)))) { return false; } records[value.PlayerId] = new Entry { Record = value, At = now }; return true; } public bool TryGet(ulong id, double now, out MythExpressionRecord value) { value = default(MythExpressionRecord); if (!records.TryGetValue(id, out var value2) || now - value2.At > 5.0 || now < value2.At) { return false; } value = value2.Record; return true; } public uint NextRevision(ulong id, ulong owner) { if (!records.TryGetValue(id, out var value) || value.Record.Owner != owner) { return 1u; } return value.Record.Revision + 1; } public MythExpressionRecord[] Snapshot(double now) { List<MythExpressionRecord> list = new List<MythExpressionRecord>(); foreach (Entry value in records.Values) { if (now >= value.At && now - value.At <= 5.0) { list.Add(value.Record); } } list.Sort((MythExpressionRecord a, MythExpressionRecord b) => a.PlayerId.CompareTo(b.PlayerId)); return list.ToArray(); } public void RemoveOwner(ulong owner) { List<ulong> list = new List<ulong>(); foreach (KeyValuePair<ulong, Entry> record in records) { if (record.Value.Record.Owner == owner) { list.Add(record.Key); } } foreach (ulong item in list) { records.Remove(item); } } public void Clear() { records.Clear(); } } public static class MythFirstPersonMesh { 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("Myth first-person avatar must be humanoid."); } HashSet<Transform> hashSet = new HashSet<Transform>(); HumanBodyBones[] array = new HumanBodyBones[6]; RuntimeHelpers.InitializeArray(array, (RuntimeFieldHandle)/*OpCode not supported: LdMemberToken*/); HumanBodyBones[] array2 = (HumanBodyBones[])(object)array; foreach (HumanBodyBones val in array2) { Transform boneTransform = componentInChildren.GetBoneTransform(val); if (Object.op_Implicit((Object)(object)boneTransform)) { Transform[] componentsInChildren = ((Component)boneTransform).GetComponentsInChildren<Transform>(true); foreach (Transform item in componentsInChildren) { hashSet.Add(item); } } } return hashSet; } public static void Prime(GameObject model) { HashSet<Transform> arms = ArmBones(model); SkinnedMeshRenderer[] componentsInChildren = model.GetComponentsInChildren<SkinnedMeshRenderer>(true); for (int i = 0; i < componentsInChildren.Length; i++) { Get(componentsInChildren[i], arms); } } public static IEnumerator PrimeIncremental(GameObject model) { HashSet<Transform> arms = ArmBones(model); SkinnedMeshRenderer[] componentsInChildren = model.GetComponentsInChildren<SkinnedMeshRenderer>(true); for (int i = 0; i < componentsInChildren.Length; i++) { Get(componentsInChildren[i], arms); yield return null; } } private static bool Allowed(BoneWeight weight, bool[] bones) { if ((((BoneWeight)(ref weight)).weight0 <= 0f || bones[((BoneWeight)(ref weight)).boneIndex0]) && (((BoneWeight)(ref weight)).weight1 <= 0f || bones[((BoneWeight)(ref weight)).boneIndex1]) && (((BoneWeight)(ref weight)).weight2 <= 0f || bones[((BoneWeight)(ref weight)).boneIndex2])) { if (!(((BoneWeight)(ref weight)).weight3 <= 0f)) { return bones[((BoneWeight)(ref weight)).boneIndex3]; } return true; } return false; } private static Entry Get(SkinnedMeshRenderer renderer, HashSet<Transform> arms) { //IL_00b7: Unknown result type (might be due to invalid IL or missing references) //IL_0202: Unknown result type (might be due to invalid IL or missing references) //IL_0207: Unknown result type (might be due to invalid IL or missing references) //IL_030f: Unknown result type (might be due to invalid IL or missing references) //IL_0314: Unknown result type (might be due to invalid IL or missing references) //IL_032a: Unknown result type (might be due to invalid IL or missing references) //IL_02f7: Unknown result type (might be due to invalid IL or missing references) //IL_02f9: Unknown result type (might be due to invalid IL or missing references) //IL_0344: Expected O, but got Unknown //IL_0461: Unknown result type (might be due to invalid IL or missing references) //IL_0466: Unknown result type (might be due to invalid IL or missing references) Mesh sharedMesh = renderer.sharedMesh; if (!Object.op_Implicit((Object)(object)sharedMesh)) { return null; } if (Cache.TryGetValue(sharedMesh, out var value)) { return value; } if (!sharedMesh.isReadable) { throw new InvalidOperationException("Myth 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("Myth 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 + "_MythFirstPerson", indexFormat = (IndexFormat)(list.Count > 65535) }; val2.vertices = Subset(sharedMesh.vertices, list); if (sharedMesh.normals.Length == sharedMesh.vertexCount) { val2.normals = Subset(sharedMesh.normals, list); } if (sharedMesh.tangents.Length == sharedMesh.vertexCount) { val2.tangents = Subset(sharedMesh.tangents, list); } if (sharedMesh.colors32.Length == sharedMesh.vertexCount) { val2.colors32 = Subset(sharedMesh.colors32, list); } for (int num3 = 0; num3 < 8; num3++) { List<Vector4> list6 = new List<Vector4>(); sharedMesh.GetUVs(num3, list6); if (list6.Count == sharedMesh.vertexCount) { val2.SetUVs(num3, Subset(list6.ToArray(), list)); } } for (int num4 = 0; num4 < sharedMesh.blendShapeCount; num4++) { string blendShapeName = sharedMesh.GetBlendShapeName(num4); if (!blendShapeName.StartsWith("opt_", StringComparison.Ordinal)) { continue; } Vector3[] array6 = (Vector3[])(object)new Vector3[sharedMesh.vertexCount]; sharedMesh.GetBlendShapeFrameVertices(num4, 0, array6, (Vector3[])null, (Vector3[])null); Vector3[] array7 = Subset(array6, list); bool flag = false; Vector3[] array8 = array7; for (int num5 = 0; num5 < array8.Length; num5++) { Vector3 val3 = array8[num5]; if (((Vector3)(ref val3)).sqrMagnitude > 1E-14f) { flag = true; break; } } if (flag) { val2.AddBlendShapeFrame(blendShapeName, sharedMesh.GetBlendShapeFrameWeight(num4, 0), array7, (Vector3[])null, (Vector3[])null); } } val2.boneWeights = array3; val2.bindposes = Subset(sharedMesh.bindposes, list5); val2.subMeshCount = list2.Count; for (int num6 = 0; num6 < list2.Count; num6++) { val2.SetTriangles(list2[num6], num6, false); } val2.RecalculateBounds(); value = new Entry { Mesh = val2, BoneIndices = list5.ToArray(), MaterialSlots = list3.ToArray() }; Cache.Add(sharedMesh, value); return value; } private static T[] Subset<T>(T[] source, List<int> indices) { T[] array = new T[indices.Count]; for (int i = 0; i < indices.Count; i++) { array[i] = source[indices[i]]; } return array; } public static GameObject Convert(GameObject model) { MythSourceRotationGrant component = model.GetComponent<MythSourceRotationGrant>(); MythSourceRotationGrant.Grant[] sourceGrants = (Object.op_Implicit((Object)(object)component) ? component.grants : null); HashSet<Transform> arms = ArmBones(model); SkinnedMeshRenderer[] componentsInChildren = model.GetComponentsInChildren<SkinnedMeshRenderer>(true); foreach (SkinnedMeshRenderer val in componentsInChildren) { Entry entry = Get(val, arms); if (entry == null) { ((Renderer)val).enabled = false; Remove((Object)(object)val); continue; } Transform[] bones = val.bones; Material[] sharedMaterials = ((Renderer)val).sharedMaterials; Transform[] array = (Transform[])(object)new Transform[entry.BoneIndices.Length]; Material[] array2 = (Material[])(object)new Material[entry.MaterialSlots.Length]; for (int j = 0; j < array.Length; j++) { array[j] = bones[entry.BoneIndices[j]]; } for (int k = 0; k < array2.Length; k++) { array2[k] = sharedMaterials[entry.MaterialSlots[k]]; } val.sharedMesh = entry.Mesh; val.bones = array; ((Renderer)val).sharedMaterials = array2; val.quality = (SkinQuality)4; val.updateWhenOffscreen = true; ((Renderer)val).shadowCastingMode = (ShadowCastingMode)0; } StripSimulation(model); MythViewModelPose obj = model.GetComponent<MythViewModelPose>() ?? model.AddComponent<MythViewModelPose>(); obj.SourceGrants = sourceGrants; obj.Initialize(); model.GetComponent<MythAdaptiveLighting>()?.Rebind(); model.GetComponent<MythOutfitState>()?.Rebind(); return model; } public static void StripSimulation(GameObject model) { Collider[] componentsInChildren = model.GetComponentsInChildren<Collider>(true); foreach (Collider obj in componentsInChildren) { obj.enabled = false; Remove((Object)(object)obj); } MonoBehaviour[] componentsInChildren2 = model.GetComponentsInChildren<MonoBehaviour>(true); foreach (MonoBehaviour val in componentsInChildren2) { if (Object.op_Implicit((Object)(object)val)) { switch (((object)val).GetType().FullName) { case "MythSuit.MythSecondaryMotion": case "MythSuit.MythHeadTracking": case "MythSuit.MythFace": case "MythSuit.MythToonFrame": case "MythSuit.MythSourceRotationGrant": case "MythSuit.MythReactionFace": 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 MythFirstPersonPatch { public static void Install(Harmony harmony) { //IL_0067: Unknown result type (might be due to invalid IL or missing references) //IL_0075: Expected O, but got Unknown //IL_009e: Unknown result type (might be due to invalid IL or missing references) //IL_00ab: Expected O, but got Unknown //IL_0105: Unknown result type (might be due to invalid IL or missing references) //IL_0113: Expected O, but got Unknown //IL_0152: Unknown result type (might be due to invalid IL or missing references) //IL_015f: Expected O, but got Unknown Type type = typeof(BodyReplacementBase).Assembly.GetType("ModelReplacement.Scripts.MeshHelper", throwOnError: true); MethodInfo methodInfo = AccessTools.Method(type, "ConvertModelToViewModel", new Type[1] { typeof(GameObject) }, (Type[])null); if (methodInfo == null) { throw new MissingMethodException(type.FullName, "ConvertModelToViewModel"); } harmony.Patch((MethodBase)methodInfo, new HarmonyMethod(typeof(MythFirstPersonPatch), "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(MythFirstPersonPatch), "AfterBodyCreated", (Type[])null), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null); Type type2 = typeof(BodyReplacementBase).Assembly.GetType("ModelReplacement.Scripts.Player.ViewModelUpdater", throwOnError: true); MethodInfo methodInfo2 = AccessTools.Method(type2, "UpdateViewModel", Type.EmptyTypes, (Type[])null); if (methodInfo2 == null) { throw new MissingMethodException(type2.FullName, "UpdateViewModel"); } harmony.Patch((MethodBase)methodInfo2, new HarmonyMethod(typeof(MythFirstPersonPatch), "BeforeViewPose", (Type[])null), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null); harmony.Patch((MethodBase)AccessTools.Method(type2, "AssignViewModelReplacement", new Type[2] { typeof(GameObject), typeof(GameObject) }, (Type[])null), (HarmonyMethod)null, new HarmonyMethod(typeof(MythFirstPersonPatch), "AfterViewAssigned", (Type[])null), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null); } private static bool BeforeConvert(GameObject __0, ref GameObject __result) { if (!Object.op_Implicit((Object)(object)__0) || !((Object)__0).name.StartsWith("Myth_", StringComparison.Ordinal)) { return true; } __result = MythFirstPersonMesh.Convert(__0); return false; } private static void AfterBodyCreated(BodyReplacementBase __instance) { if (!(__instance is MythBody)) { return; } object? value = AccessTools.Field(typeof(BodyReplacementBase), "replacementModel").GetValue(__instance); GameObject val = (GameObject)((value is GameObject) ? value : null); object? value2 = AccessTools.Field(typeof(BodyReplacementBase), "replacementModelShadow").GetValue(__instance); GameObject val2 = (GameObject)((value2 is GameObject) ? value2 : null); if (Object.op_Implicit((Object)(object)val) && Object.op_Implicit((Object)(object)val2)) { MythFirstPersonMesh.StripSimulation(val2); val2.AddComponent<MythShadowPose>().Initialize(val); } object? value3 = AccessTools.Field(typeof(BodyReplacementBase), "replacementViewModel").GetValue(__instance); GameObject val3 = (GameObject)((value3 is GameObject) ? value3 : null); if (Object.op_Implicit((Object)(object)val3) && Object.op_Implicit((Object)(object)__instance.controller)) { MythViewModelPose component = val3.GetComponent<MythViewModelPose>(); SkinnedMeshRenderer thisPlayerModelArms = __instance.controller.thisPlayerModelArms; if (Object.op_Implicit((Object)(object)component) && Object.op_Implicit((Object)(object)thisPlayerModelArms)) { component.Bind(thisPlayerModelArms, __instance.controller.playerModelArmsMetarig); } } } private static bool BeforeViewPose(ViewModelUpdater __instance) { GameObject replacementViewModel = __instance.replacementViewModel; if (!Object.op_Implicit((Object)(object)replacementViewModel)) { return true; } MythViewModelPose component = replacementViewModel.GetComponent<MythViewModelPose>(); if (Object.op_Implicit((Object)(object)component)) { return !component.Step(); } return true; } private static void AfterViewAssigned(GameObject __0, GameObject __1) { if (!Object.op_Implicit((Object)(object)__0) || !Object.op_Implicit((Object)(object)__1)) { return; } MythOutfitControl.AttachView(__0, __1); MythViewModelPose component = __1.GetComponent<MythViewModelPose>(); if (Object.op_Implicit((Object)(object)component)) { PlayerControllerB component2 = __0.GetComponent<PlayerControllerB>(); if (Object.op_Implicit((Object)(object)component2)) { component.Bind(component2.thisPlayerModelArms, component2.playerModelArmsMetarig); } } } } public class MythFootAlignment : 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 == "MythSole.L")); rightSole = ((IEnumerable<Transform>)componentsInChildren).FirstOrDefault((Func<Transform, bool>)((Transform t) => ((Object)t).name == "MythSole.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 MythHandAlignment : 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 MythHeadTracking : MonoBehaviour { public PlayerControllerB Player; private readonly MythAttention attention = new MythAttention(); 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 == "MythGazeFrame")); 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)) {