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 Justice v1.0.1
JusticeSuit.dll
Decompiled 12 hours ago
The result has been truncated due to the large size, download it to view full contents!
using System; using System.Collections; using System.Collections.Generic; using System.Diagnostics; using System.IO; using System.Linq; using System.Linq.Expressions; using System.Reflection; using System.Runtime.CompilerServices; using System.Text; using BepInEx; using BepInEx.Configuration; using GameNetcodeStuff; using HarmonyLib; using ModelReplacement; using ModelReplacement.AvatarBodyUpdater; using ModelReplacement.Scripts.Player; using Unity.Collections; using Unity.Netcode; using UnityEngine; using UnityEngine.InputSystem; using UnityEngine.InputSystem.Controls; using UnityEngine.Rendering; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: AssemblyFileVersion("1.0.1")] [assembly: AssemblyInformationalVersion("1.0.1")] [assembly: AssemblyVersion("1.0.1.0")] namespace JusticeSuit; [Serializable] public struct JusticeLightingContext { 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 JusticeLightingContext(bool factory, bool ship) { InsideFactory = factory; InsideShip = ship; } } public sealed class JusticeCorpseLightingContext { private JusticeLightingContext context; private bool trackedItem; public JusticeCorpseLightingContext(JusticeLightingContext death) { context = death; } public JusticeLightingContext Observe(bool bodyInShip, bool hasHolder, JusticeLightingContext holder, bool hasItem, JusticeLightingContext item) { if (hasHolder) { context = holder; trackedItem = true; } else if (hasItem && trackedItem) { context = item; } if (!bodyInShip) { return context; } return new JusticeLightingContext(factory: false, ship: true); } } [DefaultExecutionOrder(600)] public sealed class JusticeAdaptiveLighting : 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<JusticeLightingContext> contextReader; private bool initialized; private static readonly int FloorId = Shader.PropertyToID("_GflAmbientFloor"); private static readonly int InkId = Shader.PropertyToID("_InkColor"); public JusticeLightingContext 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<JusticeLightingContext> reader) { contextReader = reader; Refresh(); } public JusticeLightingContext ReadContext() { if (contextReader == null) { return Context; } return contextReader(); } public void InheritContext(JusticeAdaptiveLighting source) { if (Object.op_Implicit((Object)(object)source)) { BindContext(source.ReadContext); } } public void Refresh() { Apply(ReadContext()); } public void Apply(JusticeLightingContext 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 JusticeLightingControl { private sealed class Death { internal ulong Owner; internal JusticeLightingContext 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 JusticeLightingContext Native(PlayerControllerB player) { if (!Object.op_Implicit((Object)(object)player)) { return default(JusticeLightingContext); } return new JusticeLightingContext(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(JusticeLightingControl), "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(JusticeLightingControl), "Ragdoll", (Type[])null), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null); } harmony.Patch((MethodBase)AccessTools.Method(typeof(PlayerControllerB), "KillPlayer", (Type[])null, (Type[])null), new HarmonyMethod(typeof(JusticeLightingControl), "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(JusticeLightingControl), "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(JusticeLightingControl), "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 JusticeBody justiceBody && Object.op_Implicit((Object)(object)((BodyReplacementBase)justiceBody).controller)) { FieldInfo[] array = new FieldInfo[3] { sourceField, shadowField, viewField }; for (int i = 0; i < array.Length; i++) { object? obj = array[i]?.GetValue(justiceBody); Bind((GameObject)((obj is GameObject) ? obj : null), ((BodyReplacementBase)justiceBody).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<JusticeAdaptiveLighting>())) { Bind(view, playerObject.GetComponent<PlayerControllerB>()); } } private static void Ragdoll(BodyReplacementBase __instance, GameObject __result) { if (__instance is JusticeBody justiceBody && Object.op_Implicit((Object)(object)((BodyReplacementBase)justiceBody).controller)) { Bind(__result, ((BodyReplacementBase)justiceBody).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; } JusticeAdaptiveLighting justiceAdaptiveLighting = model.GetComponent<JusticeAdaptiveLighting>() ?? model.AddComponent<JusticeAdaptiveLighting>(); justiceAdaptiveLighting.Rebind(); ulong owner = ((NetworkBehaviour)player).OwnerClientId; if (!corpse) { justiceAdaptiveLighting.BindContext(() => (!Object.op_Implicit((Object)(object)player) || ((NetworkBehaviour)player).OwnerClientId != owner) ? default(JusticeLightingContext) : Native(player)); return; } Death value; JusticeLightingContext death = ((deaths.TryGetValue(player, out value) && value.Owner == owner) ? value.Context : Native(player)); JusticeCorpseLightingContext corpseContext = new JusticeCorpseLightingContext(death); DeadBodyInfo nativeBody = player.deadBody; justiceAdaptiveLighting.BindContext(delegate { if (!Object.op_Implicit((Object)(object)nativeBody)) { return corpseContext.Observe(bodyInShip: false, hasHolder: false, default(JusticeLightingContext), hasItem: false, default(JusticeLightingContext)); } 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 JusticeLightingContext(grabBodyObject.isInFactory, grabBodyObject.isInShipRoom) : default(JusticeLightingContext)); }); } 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 JusticeAttentionSelection { 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 JusticeAttention { private sealed class ItemRenderer { public GrabbableObject Item; public Renderer Renderer; } private readonly JusticeAttentionSelection selection = new JusticeAttentionSelection(); 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 = JusticeSceneCache.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 (JusticeAttentionSelection.InView(origin, forward, val, range)) { int mask = (Object.op_Implicit((Object)(object)StartOfRound.Instance) ? StartOfRound.Instance.collidersAndRoomMaskAndDefault : (-5)); if (JusticeAttentionSelection.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 = JusticeVoiceActivity.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 JusticeVoiceActivity { 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 = JusticeFace.Read(player, "voicePlayerState") ?? JusticeFace.Read(JusticeFace.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 = JusticeFace.Read(StartOfRound.Instance, "voiceChatModule"); if (comms != null) { string text = (((NetworkBehaviour)player).IsOwner ? (JusticeFace.Read(comms, "LocalPlayerName") as string) : (JusticeFace.Read(player, "voicePlayerName") as string)); if (!string.IsNullOrEmpty(text)) { try { obj = JusticeRuntimeMembers.CallString(comms, "FindPlayer", text); if (obj != null) { states[instanceID] = obj; } } catch { } } } } bool value3; bool flag = JusticeRuntimeMembers.TryRead<bool>(obj, "IsSpeaking", out value3) && value3; if (JusticeRuntimeMembers.TryRead<bool>(obj, "IsConnected", out var value4) && !value4) { return false; } if (!JusticeRuntimeMembers.TryRead<float>(obj, "Amplitude", out var value5)) { return flag; } return JusticeAttentionSelection.ActiveSpeech(flag, value5); } internal static void Clear() { comms = null; retry.Clear(); states.Clear(); } } public sealed class JusticeChestGazeTarget : MonoBehaviour { public Transform chest; public Transform[] breasts = (Transform[])(object)new Transform[0]; public Vector3 Point { get { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0005: Unknown result type (might be due to invalid IL or missing references) //IL_0021: Unknown result type (might be due to invalid IL or missing references) //IL_0024: Unknown result type (might be due to invalid IL or missing references) //IL_0029: Unknown result type (might be due to invalid IL or missing references) //IL_002e: Unknown result type (might be due to invalid IL or missing references) //IL_007a: Unknown result type (might be due to invalid IL or missing references) //IL_007d: Unknown result type (might be due to invalid IL or missing references) //IL_0074: Unknown result type (might be due to invalid IL or missing references) //IL_0054: Unknown result type (might be due to invalid IL or missing references) //IL_0059: Unknown result type (might be due to invalid IL or missing references) //IL_0063: Unknown result type (might be due to invalid IL or missing references) //IL_0068: Unknown result type (might be due to invalid IL or missing references) Vector3 val = Vector3.zero; int num = 0; Transform[] array = breasts; foreach (Transform val2 in array) { if (Object.op_Implicit((Object)(object)val2)) { val += val2.position; num++; } } if (num <= 0) { if (!Object.op_Implicit((Object)(object)chest)) { return ((Component)this).transform.position + Vector3.up * 1.3f; } return chest.position; } return val / (float)num; } } } public enum JusticeExpression : byte { Neutral, Frightened, Hurt, Happy, Surprised, VeryHappy, Dead, Stars, Hearts, Curious, Relaxed, Startled, Musical, Protective, Playful, FoodDelight, Determined, ShipCelebrate } public struct JusticeExpressionContext { public bool Dead; public bool Critical; public bool EnemyNear; public bool Fear; public bool Chased; public bool Dancing; public bool StarEyes; public bool HeartEyes; public bool Unsafe { get { if (!EnemyNear && !Fear) { return Chased; } return true; } } } public sealed class JusticeExpressionSelection { 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 JusticeExpression Choose(JusticeExpressionContext c, double now) { if (c.Dead) { return JusticeExpression.Dead; } if (c.Critical || now < hurtUntil) { return JusticeExpression.Hurt; } if (c.Unsafe) { return JusticeExpression.Frightened; } if (c.StarEyes) { return JusticeExpression.Stars; } if (c.HeartEyes) { return JusticeExpression.Hearts; } if (now < treasureUntil) { if (!surprised) { return JusticeExpression.VeryHappy; } return JusticeExpression.Surprised; } if (c.Dancing) { return JusticeExpression.Happy; } return JusticeExpression.Neutral; } } public struct JusticeExpressionWeight { public string Shape; public float Weight; public bool Eyes; public bool Mouth; public JusticeExpressionWeight(string shape, float weight, bool eyes = false, bool mouth = false) { Shape = "expr_" + shape; Weight = weight; Eyes = eyes; Mouth = mouth; } } public static class JusticeExpressionProfiles { private static readonly JusticeExpressionWeight[][] profiles = new JusticeExpressionWeight[9][] { new JusticeExpressionWeight[0], new JusticeExpressionWeight[4] { B("worry", 0.75f), B("brow_up", 0.25f), E("surprise", 0.85f), M("triangle", 0.6f) }, new JusticeExpressionWeight[4] { B("worry", 0.85f), B("serious", 0.25f), E("focus", 0.45f), M("clench", 0.8f) }, new JusticeExpressionWeight[3] { B("happy_brows", 0.45f), E("smile_eyes", 0.65f), M("smile", 0.85f) }, new JusticeExpressionWeight[3] { B("brow_up", 0.65f), E("surprise", 0.9f), M("o", 0.65f) }, new JusticeExpressionWeight[3] { B("happy_brows", 0.65f), E("smile_eyes", 0.85f), M("laugh", 0.85f) }, new JusticeExpressionWeight[2] { B("worry", 0.7f), M("clench", 0.55f) }, new JusticeExpressionWeight[3] { B("brow_up", 0.35f), E("stars", 1f), M("smile", 0.65f) }, new JusticeExpressionWeight[3] { B("happy_brows", 0.35f), E("hearts", 1f), M("smile", 0.75f) } }; private static JusticeExpressionWeight B(string n, float w) { return new JusticeExpressionWeight(n, w); } private static JusticeExpressionWeight E(string n, float w) { return new JusticeExpressionWeight(n, w, eyes: true); } private static JusticeExpressionWeight M(string n, float w) { return new JusticeExpressionWeight(n, w, eyes: false, mouth: true); } public static JusticeExpressionWeight[] Weights(JusticeExpression state) { if ((int)state >= profiles.Length) { return JusticePersonalityProfiles.Weights("", state); } return profiles[(uint)state]; } } public sealed class JusticeExpressionMixer { private sealed class Binding { public SkinnedMeshRenderer Renderer; public int[] Indices; public int Blink; public int Open; public int Round; } private readonly List<string> shapes = new List<string>(); private readonly Dictionary<string, int> slots = new Dictionary<string, int>(); private readonly List<Binding> bindings = new List<Binding>(); private float[] values; private float[] target; private bool[] eyes; private bool[] mouth; private readonly string character; public JusticeExpressionMixer(GameObject model, string member = null) { character = member ?? JusticePersonalityProfiles.Character(((Object)model).name); foreach (JusticeExpression value in Enum.GetValues(typeof(JusticeExpression))) { JusticeExpressionWeight[] array = JusticeExpressionProfiles.Weights(value); for (int i = 0; i < array.Length; i++) { JusticeExpressionWeight justiceExpressionWeight = array[i]; if (!slots.ContainsKey(justiceExpressionWeight.Shape)) { slots[justiceExpressionWeight.Shape] = shapes.Count; shapes.Add(justiceExpressionWeight.Shape); } } } values = new float[shapes.Count]; target = new float[shapes.Count]; eyes = new bool[shapes.Count]; mouth = new bool[shapes.Count]; foreach (JusticeExpression value2 in Enum.GetValues(typeof(JusticeExpression))) { JusticeExpressionWeight[] array = JusticeExpressionProfiles.Weights(value2); for (int i = 0; i < array.Length; i++) { JusticeExpressionWeight justiceExpressionWeight2 = array[i]; int num = slots[justiceExpressionWeight2.Shape]; eyes[num] |= justiceExpressionWeight2.Eyes; mouth[num] |= justiceExpressionWeight2.Mouth; } } SkinnedMeshRenderer[] componentsInChildren = model.GetComponentsInChildren<SkinnedMeshRenderer>(true); foreach (SkinnedMeshRenderer val in componentsInChildren) { if (Object.op_Implicit((Object)(object)val.sharedMesh) && !JusticeInkOutline.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); } } } public void Step(JusticeExpression state, float delta, bool immediate = false) { Array.Clear(target, 0, target.Length); JusticeExpressionWeight[] array = JusticePersonalityProfiles.Weights(character, state); for (int i = 0; i < array.Length; i++) { JusticeExpressionWeight justiceExpressionWeight = array[i]; target[slots[justiceExpressionWeight.Shape]] = justiceExpressionWeight.Weight; } float num = ((immediate || state == JusticeExpression.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 == JusticeExpression.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 * 0.55f; } binding.Renderer.SetBlendShapeWeight(binding.Indices[k], num4 * 100f); } } } } } [DefaultExecutionOrder(280)] public sealed class JusticeDeathFace : MonoBehaviour { private JusticeExpressionMixer mixer; public void Initialize() { mixer = new JusticeExpressionMixer(((Component)this).gameObject); mixer.Step(JusticeExpression.Dead, 0f, immediate: true); } private void LateUpdate() { if (mixer == null) { Initialize(); } mixer.Step(JusticeExpression.Dead, 0f, immediate: true); } } public sealed class JusticeGigiRules { private readonly HashSet<int> discovered = new HashSet<int>(); private bool seeded; private bool inside; private bool shipUsed; private double entry = -100.0; private double starsUntil = -100.0; private double nearStarted = -100.0; private int nearKey = int.MinValue; private float gaze; public bool ShipReactionUsed => shipUsed; public float GazeWeight => gaze; public void SeedShip(bool value) { if (!seeded) { seeded = true; inside = value; } } public void NewRound(bool isInside) { discovered.Clear(); shipUsed = false; starsUntil = (entry = -100.0); inside = isInside; seeded = true; nearKey = int.MinValue; nearStarted = -100.0; gaze = 0f; } public bool NoticeLoot(int key, int value, int threshold, double now, float seconds) { if (value <= threshold || !discovered.Add(key)) { return false; } starsUntil = Math.Max(starsUntil, now + (double)seconds); return true; } public void Ship(bool isInside, bool seesPile, double now, float seconds) { if (!seeded) { SeedShip(isInside); return; } if (isInside && !inside) { entry = now; } inside = isInside; if (isInside && !shipUsed && seesPile && now >= entry && now < entry + (double)seconds) { shipUsed = true; starsUntil = Math.Max(starsUntil, entry + (double)seconds); } } public bool Stars(double now) { return now < starsUntil; } public void Near(int targetKey, bool eligible, double now, float delta, float dwell, float ramp) { if (!eligible) { nearKey = int.MinValue; nearStarted = -100.0; gaze = 0f; return; } if (nearKey != targetKey) { nearKey = targetKey; nearStarted = now; gaze = 0f; } float num = ((now - nearStarted >= (double)dwell) ? 1 : 0); gaze = Mathf.Lerp(gaze, num, 1f - Mathf.Exp((0f - Mathf.Clamp(delta, 0f, 0.1f)) / Mathf.Max(0.1f, ramp))); } public void ResetTransient() { starsUntil = (entry = -100.0); nearKey = int.MinValue; nearStarted = -100.0; gaze = 0f; } public static bool Ladder(bool wearerClimbing, bool otherClimbing, bool sameLadder, float horizontalDistance, float aboveDistance, float maximumDistance) { if (wearerClimbing && otherClimbing && sameLadder && horizontalDistance <= 0.75f && aboveDistance > 0.25f) { return aboveDistance <= maximumDistance; } return false; } public static bool Pile(int count, int value, int minimumCount, int minimumValue) { if (count >= minimumCount) { return value >= minimumValue; } return false; } public static string NormalizeSuit(string value) { if (string.IsNullOrEmpty(value)) { return ""; } StringBuilder stringBuilder = new StringBuilder(); foreach (char c in value) { if (char.IsLetterOrDigit(c)) { stringBuilder.Append(char.ToLowerInvariant(c)); } } return stringBuilder.ToString(); } public static bool SuitMatches(string suit, string[] tokens) { string text = NormalizeSuit(suit); for (int i = 0; i < tokens.Length; i++) { string text2 = NormalizeSuit(tokens[i].Trim()); if (text2.Length > 0 && text.Contains(text2)) { return true; } } return false; } } public struct JusticeExpressionRecord { public ulong PlayerId; public ulong Owner; public byte Character; public JusticeExpression Expression; public uint Revision; public ulong GazePlayerId; public float GazeWeight; } public sealed class JusticeExpressionStore { private sealed class Entry { public JusticeExpressionRecord Record; public double At; } private readonly Dictionary<ulong, Entry> records = new Dictionary<ulong, Entry>(); public bool Accept(ulong sender, ulong actualOwner, JusticeExpressionRecord value, double now) { if (sender != actualOwner || value.Owner != actualOwner || value.Character >= 4 || (int)value.Expression > 17 || ((value.Expression == JusticeExpression.Stars || value.Expression == JusticeExpression.Hearts) && value.Character != 1) || (value.Character == 1 && (int)value.Expression > 8) || !JusticeReactionStore.Valid(value.GazeWeight) || (value.GazeWeight > 0f && (value.Expression != JusticeExpression.Hearts || value.GazePlayerId == value.PlayerId)) || double.IsNaN(now) || double.IsInfinity(now)) { return false; } if (records.TryGetValue(value.PlayerId, out var value2) && value2.Record.Owner == actualOwner && (value.Revision < value2.Record.Revision || (value.Revision == value2.Record.Revision && (value.Character != value2.Record.Character || value.Expression != value2.Record.Expression || value.GazePlayerId != value2.Record.GazePlayerId || value.GazeWeight != value2.Record.GazeWeight)))) { return false; } records[value.PlayerId] = new Entry { Record = value, At = now }; return true; } public bool TryGet(ulong id, double now, out JusticeExpressionRecord value) { value = default(JusticeExpressionRecord); 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 JusticeExpressionRecord[] Snapshot(double now) { List<JusticeExpressionRecord> list = new List<JusticeExpressionRecord>(); foreach (Entry value in records.Values) { if (now >= value.At && now - value.At <= 5.0) { list.Add(value.Record); } } list.Sort((JusticeExpressionRecord a, JusticeExpressionRecord 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 JusticeFirstPersonMesh { 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("Justice first-person avatar must be humanoid."); } HashSet<Transform> hashSet = new HashSet<Transform>(); HumanBodyBones[] array = new HumanBodyBones[6]; RuntimeHelpers.InitializeArray(array, (RuntimeFieldHandle)/*OpCode not supported: LdMemberToken*/); HumanBodyBones[] array2 = (HumanBodyBones[])(object)array; foreach (HumanBodyBones val in array2) { Transform boneTransform = componentInChildren.GetBoneTransform(val); if (Object.op_Implicit((Object)(object)boneTransform)) { Transform[] componentsInChildren = ((Component)boneTransform).GetComponentsInChildren<Transform>(true); foreach (Transform item in componentsInChildren) { hashSet.Add(item); } } } return hashSet; } public static void Prime(GameObject model) { HashSet<Transform> arms = ArmBones(model); SkinnedMeshRenderer[] componentsInChildren = model.GetComponentsInChildren<SkinnedMeshRenderer>(true); for (int i = 0; i < componentsInChildren.Length; i++) { Get(componentsInChildren[i], arms); } } public static IEnumerator PrimeIncremental(GameObject model) { HashSet<Transform> arms = ArmBones(model); SkinnedMeshRenderer[] componentsInChildren = model.GetComponentsInChildren<SkinnedMeshRenderer>(true); for (int i = 0; i < componentsInChildren.Length; i++) { Get(componentsInChildren[i], arms); yield return null; } } private static bool Allowed(BoneWeight weight, bool[] bones) { if ((((BoneWeight)(ref weight)).weight0 <= 0f || bones[((BoneWeight)(ref weight)).boneIndex0]) && (((BoneWeight)(ref weight)).weight1 <= 0f || bones[((BoneWeight)(ref weight)).boneIndex1]) && (((BoneWeight)(ref weight)).weight2 <= 0f || bones[((BoneWeight)(ref weight)).boneIndex2])) { if (!(((BoneWeight)(ref weight)).weight3 <= 0f)) { return bones[((BoneWeight)(ref weight)).boneIndex3]; } return true; } return false; } private static Entry Get(SkinnedMeshRenderer renderer, HashSet<Transform> arms) { //IL_00b7: Unknown result type (might be due to invalid IL or missing references) //IL_0202: Unknown result type (might be due to invalid IL or missing references) //IL_0207: Unknown result type (might be due to invalid IL or missing references) //IL_030f: Unknown result type (might be due to invalid IL or missing references) //IL_0314: Unknown result type (might be due to invalid IL or missing references) //IL_032a: Unknown result type (might be due to invalid IL or missing references) //IL_02f7: Unknown result type (might be due to invalid IL or missing references) //IL_02f9: Unknown result type (might be due to invalid IL or missing references) //IL_0344: Expected O, but got Unknown Mesh sharedMesh = renderer.sharedMesh; if (!Object.op_Implicit((Object)(object)sharedMesh)) { return null; } if (Cache.TryGetValue(sharedMesh, out var value)) { return value; } if (!sharedMesh.isReadable) { throw new InvalidOperationException("Justice 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("Justice 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 + "_JusticeFirstPerson", indexFormat = (IndexFormat)(list.Count > 65535) }; val2.vertices = Subset(sharedMesh.vertices, list); if (sharedMesh.normals.Length == sharedMesh.vertexCount) { val2.normals = Subset(sharedMesh.normals, list); } if (sharedMesh.tangents.Length == sharedMesh.vertexCount) { val2.tangents = Subset(sharedMesh.tangents, list); } if (sharedMesh.colors32.Length == sharedMesh.vertexCount) { val2.colors32 = Subset(sharedMesh.colors32, list); } for (int num3 = 0; num3 < 8; num3++) { List<Vector4> list6 = new List<Vector4>(); sharedMesh.GetUVs(num3, list6); if (list6.Count == sharedMesh.vertexCount) { val2.SetUVs(num3, Subset(list6.ToArray(), list)); } } val2.boneWeights = array3; val2.bindposes = Subset(sharedMesh.bindposes, list5); val2.subMeshCount = list2.Count; for (int num4 = 0; num4 < list2.Count; num4++) { val2.SetTriangles(list2[num4], num4, false); } val2.RecalculateBounds(); value = new Entry { Mesh = val2, BoneIndices = list5.ToArray(), MaterialSlots = list3.ToArray() }; Cache.Add(sharedMesh, value); return value; } private static T[] Subset<T>(T[] source, List<int> indices) { T[] array = new T[indices.Count]; for (int i = 0; i < indices.Count; i++) { array[i] = source[indices[i]]; } return array; } public static GameObject Convert(GameObject model) { JusticeSourceRotationGrant component = model.GetComponent<JusticeSourceRotationGrant>(); JusticeSourceRotationGrant.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); JusticeSourceBillboard[] componentsInChildren2 = model.GetComponentsInChildren<JusticeSourceBillboard>(true); foreach (JusticeSourceBillboard justiceSourceBillboard in componentsInChildren2) { if (Object.op_Implicit((Object)(object)justiceSourceBillboard.sphericalTarget)) { ((Renderer)justiceSourceBillboard.sphericalTarget).enabled = false; Remove((Object)(object)((Component)justiceSourceBillboard.sphericalTarget).gameObject); } ((Behaviour)justiceSourceBillboard).enabled = false; Remove((Object)(object)justiceSourceBillboard); } JusticeSourceFlipbook[] componentsInChildren3 = model.GetComponentsInChildren<JusticeSourceFlipbook>(true); foreach (JusticeSourceFlipbook obj in componentsInChildren3) { ((Behaviour)obj).enabled = false; Remove((Object)(object)obj); } JusticeViewModelPose obj2 = model.GetComponent<JusticeViewModelPose>() ?? model.AddComponent<JusticeViewModelPose>(); obj2.SourceGrants = sourceGrants; obj2.Initialize(); model.GetComponent<JusticeOutfitState>()?.Rebind(); model.GetComponent<JusticeAdaptiveLighting>()?.Rebind(); return model; } public static void StripSimulation(GameObject model) { JusticeFlameLight[] componentsInChildren = model.GetComponentsInChildren<JusticeFlameLight>(true); foreach (JusticeFlameLight obj in componentsInChildren) { Light target = obj.target; ((Behaviour)obj).enabled = false; Remove((Object)(object)obj); if (Object.op_Implicit((Object)(object)target)) { Remove((Object)(object)((Component)target).gameObject); } } Collider[] componentsInChildren2 = model.GetComponentsInChildren<Collider>(true); foreach (Collider obj2 in componentsInChildren2) { obj2.enabled = false; Remove((Object)(object)obj2); } MonoBehaviour[] componentsInChildren3 = model.GetComponentsInChildren<MonoBehaviour>(true); foreach (MonoBehaviour val in componentsInChildren3) { switch (((object)val).GetType().FullName) { case "JusticeSuit.JusticeSecondaryMotion": case "JusticeSuit.JusticeHeadTracking": case "JusticeSuit.JusticeFace": case "JusticeSuit.JusticeToonFrame": case "JusticeSuit.JusticeSourceGearRotation": case "JusticeSuit.JusticeGigiPropellers": case "JusticeSuit.JusticeSourceRotationGrant": case "JusticeSuit.JusticePlayerReaction": 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 JusticeFirstPersonPatch { 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(JusticeFirstPersonPatch), "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(JusticeFirstPersonPatch), "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(JusticeFirstPersonPatch), "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(JusticeFirstPersonPatch), "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("Justice_", StringComparison.Ordinal)) { return true; } __result = JusticeFirstPersonMesh.Convert(__0); return false; } private static void AfterBodyCreated(BodyReplacementBase __instance) { if (!(__instance is JusticeBody)) { 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)) { JusticeFirstPersonMesh.StripSimulation(val2); val2.AddComponent<JusticeShadowPose>().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)) { JusticeViewModelPose component = val3.GetComponent<JusticeViewModelPose>(); 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; } JusticeViewModelPose component = replacementViewModel.GetComponent<JusticeViewModelPose>(); 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; } JusticeOutfitControl.AttachView(__0, __1); JusticeViewModelPose component = __1.GetComponent<JusticeViewModelPose>(); 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); } } } } [DefaultExecutionOrder(470)] public sealed class JusticeFlameLight : MonoBehaviour { public struct FlameFrame { public float LightGain; public float EmissionGain; public float Opacity; public float LifeGain; } public Light target; public Renderer flameRenderer; public int materialSlot; public Renderer[] receivers = (Renderer[])(object)new Renderer[0]; public float baseIntensity = 10f; public float worldRange = 0.2f; public float flickerAmplitude = 0.35f; public float deathDuration = 2f; private Light boundTarget; private Component hdData; private Action<float> setHDRPIntensity; private float legacyBaseIntensity; private bool alive = true; private double deathStartedAt = -1.0; private MaterialPropertyBlock block; private static MaterialPropertyBlock receiverBlock; private Renderer[] boundReceivers; private int[] receiverSlots; private readonly List<Material> receiverMaterials = new List<Material>(); private static readonly int EmissionGainID = Shader.PropertyToID("_JusticeFlameEmissionGain"); private static readonly int OpacityID = Shader.PropertyToID("_JusticeFlameOpacity"); private static readonly int ReceiverID = Shader.PropertyToID("_JusticeChestLightPositionWS"); public bool IsAlive => alive; public double DeathStartedAt => deathStartedAt; public float CurrentMultiplier { get; private set; } = 1f; public FlameFrame CurrentFrame { get; private set; } public bool UsesHDRPIntensity { get { if (Object.op_Implicit((Object)(object)hdData)) { return setHDRPIntensity != null; } return false; } } public Vector4 ReceiverPosition { get { //IL_001e: Unknown result type (might be due to invalid IL or missing references) //IL_0023: Unknown result type (might be due to invalid IL or missing references) //IL_0024: 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_0030: Unknown result type (might be due to invalid IL or missing references) //IL_004b: Unknown result type (might be due to invalid IL or missing references) //IL_000d: Unknown result type (might be due to invalid IL or missing references) if (!Object.op_Implicit((Object)(object)target)) { return Vector4.zero; } Vector3 position = ((Component)target).transform.position; return new Vector4(position.x, position.y, position.z, Mathf.Clamp(worldRange, 0.01f, 0.2f)); } } public static double Clock { get { //IL_0017: Unknown result type (might be due to invalid IL or missing references) //IL_001c: Unknown result type (might be due to invalid IL or missing references) NetworkManager singleton = NetworkManager.Singleton; if (Object.op_Implicit((Object)(object)singleton) && singleton.IsListening) { NetworkTime serverTime = singleton.ServerTime; return ((NetworkTime)(ref serverTime)).Time; } return Time.timeAsDouble; } } private static bool Finite(double value) { if (!double.IsNaN(value)) { return !double.IsInfinity(value); } return false; } private void Bind() { if ((Object)(object)boundTarget == (Object)(object)target) { return; } boundTarget = target; hdData = null; setHDRPIntensity = null; if (!Object.op_Implicit((Object)(object)target)) { return; } legacyBaseIntensity = target.intensity; Component[] components = ((Component)target).GetComponents<Component>(); foreach (Component val in components) { if (!Object.op_Implicit((Object)(object)val) || ((object)val).GetType().FullName != "UnityEngine.Rendering.HighDefinition.HDAdditionalLightData") { continue; } PropertyInfo property = ((object)val).GetType().GetProperty("intensity", BindingFlags.Instance | BindingFlags.Public); if (!(property == null) && !(property.PropertyType != typeof(float)) && !(property.GetSetMethod() == null)) { try { setHDRPIntensity = (Action<float>)Delegate.CreateDelegate(typeof(Action<float>), val, property.GetSetMethod()); hdData = val; break; } catch { setHDRPIntensity = null; hdData = null; break; } } } } public static float Flicker(float time, float amplitude) { return LivingFlicker(time, amplitude); } private static float LivingFlicker(double time, float amplitude) { float num = (float)(time % 360.0) * (float)Math.PI * 2f; return 1f + Mathf.Clamp(amplitude, 0f, 0.5f) * (0.4f * Mathf.Sin(num * 2.1f) + 0.3f * Mathf.Sin(num * 7.3f + 1.7f) + 0.2f * Mathf.Sin(num * 11.1f + 0.3f) + 0.1f * Mathf.Sin(num * 29.4f + 2.3f)); } public void SetLifeState(bool living, double transitionTime) { if (Finite(transitionTime) && living != alive) { alive = living; deathStartedAt = (living ? (-1.0) : transitionTime); } } public FlameFrame Evaluate(double time) { if (!Finite(time)) { return default(FlameFrame); } float num = LivingFlicker(time, flickerAmplitude); if (alive) { return new FlameFrame { LightGain = num, EmissionGain = num, Opacity = 1f, LifeGain = 1f }; } double num2 = Math.Max(0.0, time - deathStartedAt); float num3 = (float)(num2 / Math.Max(0.1, deathDuration)); if (num3 >= 1f) { return default(FlameFrame); } float num4 = (float)(num2 % 360.0) * (float)Math.PI * 2f; float num5 = 0.55f * Mathf.Sin(num4 * 7.1f) + 0.3f * Mathf.Sin(num4 * 13.7f + 1.3f) + 0.15f * Mathf.Sin(num4 * 31.4f + 0.7f); float num6 = Mathf.SmoothStep(0.025f, 1f, Mathf.Clamp01(0.5f + 0.5f * num5)); num6 = Mathf.Lerp(1f, num6, Mathf.SmoothStep(0f, 1f, num3 / 0.15f)); float num7 = Mathf.Pow(Mathf.Max(0f, 1f - num3), 1.65f); float num8 = num * num7 * num6; return new FlameFrame { LightGain = num8, EmissionGain = num8, Opacity = num7 * Mathf.Sqrt(num6), LifeGain = num7 }; } public void ApplyTo(Renderer renderer, int slot, double time) { //IL_001e: Unknown result type (might be due to invalid IL or missing references) //IL_0028: Expected O, but got Unknown if (Object.op_Implicit((Object)(object)renderer) && slot >= 0 && Finite(time)) { if (block == null) { block = new MaterialPropertyBlock(); } FlameFrame flameFrame = Evaluate(time); renderer.GetPropertyBlock(block, slot); block.SetFloat(EmissionGainID, flameFrame.EmissionGain); block.SetFloat(OpacityID, flameFrame.Opacity); renderer.SetPropertyBlock(block, slot); ((Component)renderer).GetComponent<JusticeSourceBillboard>()?.RefreshSpherical(); } } public static void ApplyReceiver(Renderer renderer, int slot, Vector4 positionWSRange) { //IL_0013: 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_0011: Expected O, but got Unknown if (receiverBlock == null) { receiverBlock = new MaterialPropertyBlock(); } ApplyReceiver(renderer, slot, positionWSRange, receiverBlock); } public static void ApplyReceiver(Renderer renderer, int slot, Vector4 positionWSRange, MaterialPropertyBlock scratch) { //IL_001e: Unknown result type (might be due to invalid IL or missing references) if (Object.op_Implicit((Object)(object)renderer) && slot >= 0 && scratch != null) { renderer.GetPropertyBlock(scratch, slot); scratch.SetVector(ReceiverID, positionWSRange); renderer.SetPropertyBlock(scratch, slot); } } private void ApplySourceReceivers() { //IL_00a7: 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_009c: Unknown result type (might be due to invalid IL or missing references) //IL_00a6: Expected O, but got Unknown //IL_00cd: Unknown result type (might be due to invalid IL or missing references) if (boundReceivers != receivers || receiverSlots == null) { boundReceivers = receivers; receiverSlots = new int[(receivers != null) ? receivers.Length : 0]; for (int i = 0; i < receiverSlots.Length; i++) { if (Object.op_Implicit((Object)(object)receivers[i])) { receiverMaterials.Clear(); receivers[i].GetSharedMaterials(receiverMaterials); receiverSlots[i] = receiverMaterials.Count; } } } if (block == null) { block = new MaterialPropertyBlock(); } Vector4 receiverPosition = ReceiverPosition; for (int j = 0; j < receiverSlots.Length; j++) { if (Object.op_Implicit((Object)(object)boundReceivers[j])) { for (int k = 0; k < receiverSlots[j]; k++) { ApplyReceiver(boundReceivers[j], k, receiverPosition, block); } } } } public void Step(double time) { if (!Finite(time)) { return; } Bind(); CurrentFrame = Evaluate(time); CurrentMultiplier = CurrentFrame.LightGain; if (Object.op_Implicit((Object)(object)flameRenderer)) { ApplyTo(flameRenderer, materialSlot, time); } ApplySourceReceivers(); if (Object.op_Implicit((Object)(object)target)) { target.range = Mathf.Clamp(worldRange, 0.01f, 0.2f); ((Behaviour)target).enabled = ((Behaviour)this).enabled && ((Component)this).gameObject.activeInHierarchy && CurrentMultiplier > 0f; if (UsesHDRPIntensity) { setHDRPIntensity(Mathf.Max(0f, baseIntensity) * CurrentMultiplier); } else { target.intensity = Mathf.Max(0f, legacyBaseIntensity) * CurrentMultiplier; } } } private void OnEnable() { Step(Clock); } private void LateUpdate() { Step(Clock); } private void OnDisable() { if (Object.op_Implicit((Object)(object)target)) { ((Behaviour)target).enabled = false; } } } public class JusticeFootAlignment : 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 == "JusticeSole.L")); rightSole = ((IEnumerable<Transform>)componentsInChildren).FirstOrDefault((Func<Transform, bool>)((Transform t) => ((Object)t).name == "JusticeSole.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; } } } internal sealed class JusticeGigiContext { private sealed class Entry { internal ulong Owner; internal PlayerControllerB Player; internal JusticeGigiRules Rules = new JusticeGigiRules(); } private sealed class Rig { internal GameObject Model; internal Transform[] Breasts; internal Transform Chest; internal JusticeChestGazeTarget Authored; internal int Suit; } internal static ConfigEntry<bool> StarsEnabled; internal static ConfigEntry<bool> HeartsEnabled; internal static ConfigEntry<bool> LadderHearts; internal static ConfigEntry<bool> ChestGaze; internal static ConfigEntry<string> HeartSuits; internal static ConfigEntry<int> LootValue; internal static ConfigEntry<int> PileCount; internal static ConfigEntry<int> PileValue; internal static ConfigEntry<float> Duration; internal static ConfigEntry<float> NearRange; internal static ConfigEntry<float> GazeDelay; internal static ConfigEntry<float> GazeRamp; internal static ConfigEntry<float> PileRadius; internal static ConfigEntry<float> LadderRange; private static readonly Dictionary<ulong, Entry> ledger = new Dictionary<ulong, Entry>(); private static readonly Dictionary<int, Rig> rigs = new Dictionary<int, Rig>(); private static readonly FieldInfo sourceField = AccessTools.Field(typeof(BodyReplacementBase), "replacementModel"); private static StartOfRound scene; private static bool phaseSeeded; private static bool inShipPhase; private static GrabbableObject[] items = (GrabbableObject[])(object)new GrabbableObject[0]; private static InteractTrigger[] ladders = (InteractTrigger[])(object)new InteractTrigger[0]; private static float nextObjects; private static string suitConfig; private static string[] suitTokens = new string[0]; private readonly PlayerControllerB player; private readonly Transform model; private JusticeGigiRules rules; private readonly RaycastHit[] hits = (RaycastHit[])(object)new RaycastHit[24]; private float nextScan; private PlayerControllerB nearPlayer; private bool ladderHeart; internal bool Heart { get { if (HeartsEnabled.Value) { if (!Object.op_Implicit((Object)(object)nearPlayer)) { return ladderHeart; } return true; } return false; } } internal bool Stars { get { if (StarsEnabled.Value) { return rules.Stars(Time.unscaledTime); } return false; } } internal ulong GazePlayerId { get { if (!Object.op_Implicit((Object)(object)nearPlayer)) { return ulong.MaxValue; } return nearPlayer.playerClientId; } } internal float GazeWeight { get { if (!Plugin.Eyes.Value || !ChestGaze.Value || !Object.op_Implicit((Object)(object)nearPlayer)) { return 0f; } return rules.GazeWeight; } } internal static void Configure(ConfigFile config) { //IL_00a9: Unknown result type (might be due to invalid IL or missing references) //IL_00b3: Expected O, but got Unknown //IL_00d6: Unknown result type (might be due to invalid IL or missing references) //IL_00e0: Expected O, but got Unknown //IL_010a: Unknown result type (might be due to invalid IL or missing references) //IL_0114: Expected O, but got Unknown //IL_0142: Unknown result type (might be due to invalid IL or missing references) //IL_014c: Expected O, but got Unknown //IL_017a: Unknown result type (might be due to invalid IL or missing references) //IL_0184: Expected O, but got Unknown //IL_01b2: Unknown result type (might be due to invalid IL or missing references) //IL_01bc: Expected O, but got Unknown //IL_01ea: Unknown result type (might be due to invalid IL or missing references) //IL_01f4: Expected O, but got Unknown //IL_0222: Unknown result type (might be due to invalid IL or missing references) //IL_022c: Expected O, but got Unknown //IL_025a: Unknown result type (might be due to invalid IL or missing references) //IL_0264: Expected O, but got Unknown StarsEnabled = config.Bind<bool>("Gigi expressions", "StarEyes", true, "Star eyes for newly discovered valuable scrap, first pickup, and a qualifying visible ship pile on entry."); HeartsEnabled = config.Bind<bool>("Gigi expressions", "HeartEyes", true, "Heart eyes beside configured suits or below another climber on the same ladder."); LadderHearts = config.Bind<bool>("Gigi expressions", "LadderHeartEyes", true, (ConfigDescription)null); ChestGaze = config.Bind<bool>("Gigi expressions", "GradualChestGaze", true, "Allow only Gigi's eyes to drift toward the nearby target's authored breast bones, with humanoid chest fallback."); HeartSuits = config.Bind<string>("Gigi expressions", "HeartSuitNames", "Elizabeth Rose Bloodflame;Raora Panthera;Fuwawa Abyssgard;Mori Calliope;Shiori Novella;Nerissa Ravencroft;Kronii;Botan", "Semicolon-separated case-insensitive suit-name fragments. Spaces and punctuation are ignored. Empty list disables proximity hearts; ladder hearts remain independent."); LootValue = config.Bind<int>("Gigi expressions", "HighValueLootThreshold", 100, new ConfigDescription("Value must be strictly greater than this threshold.", (AcceptableValueBase)(object)new AcceptableValueRange<int>(0, 10000), Array.Empty<object>())); PileCount = config.Bind<int>("Gigi expressions", "ShipPileMinimumItems", 6, new ConfigDescription("Minimum dropped scrap items in a ship pile.", (AcceptableValueBase)(object)new AcceptableValueRange<int>(2, 100), Array.Empty<object>())); PileValue = config.Bind<int>("Gigi expressions", "ShipPileMinimumValue", 500, new ConfigDescription("Minimum total value of that pile.", (AcceptableValueBase)(object)new AcceptableValueRange<int>(0, 100000), Array.Empty<object>())); Duration = config.Bind<float>("Gigi expressions", "StarSeconds", 3.5f, new ConfigDescription("Ship reaction ends this many seconds after entry, at most once per round.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(1f, 8f), Array.Empty<object>())); NearRange = config.Bind<float>("Gigi expressions", "HeartProximityMeters", 1.25f, new ConfigDescription("Very-close player distance; requires front view and a clear line of sight.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0.3f, 3f), Array.Empty<object>())); GazeDelay = config.Bind<float>("Gigi expressions", "ChestGazeDelaySeconds", 2f, new ConfigDescription("Continuous time beside the same target before gaze starts.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 10f), Array.Empty<object>())); GazeRamp = config.Bind<float>("Gigi expressions", "ChestGazeRampSeconds", 1.5f, new ConfigDescription("Exponential eye-only drift time constant.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0.1f, 5f), Array.Empty<object>())); PileRadius = config.Bind<float>("Gigi expressions", "ShipPileRadiusMeters", 2f, new ConfigDescription("Scrap must cluster within this radius of a pile item.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0.25f, 5f), Array.Empty<object>())); LadderRange = config.Bind<float>("Gigi expressions", "LadderAboveMeters", 2.5f, new ConfigDescription("Maximum distance above Gigi on the same ladder.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0.5f, 5f), Array.Empty<object>())); } internal static void Tick() { StartOfRound instance = StartOfRound.Instance; if ((Object)(object)scene != (Object)(object)instance) { Clear(); scene = instance; } if (!Object.op_Implicit((Object)(object)instance)) { return; } bool flag = instance.inShipPhase; if (phaseSeeded && inShipPhase && !flag) { foreach (Entry value in ledger.Values) { value.Rules.NewRound(Object.op_Implicit((Object)(object)value.Player) && value.Player.isInHangarShipRoom); } } inShipPhase = flag; phaseSeeded = true; foreach (Entry value2 in ledger.Values) { if (Object.op_Implicit((Object)(object)value2.Player) && ((NetworkBehaviour)value2.Player).OwnerClientId == value2.Owner) { value2.Rules.Ship(value2.Player.isInHangarShipRoom, seesPile: false, Time.unscaledTime, Duration.Value); } } } internal JusticeGigiContext(PlayerControllerB p, Transform avatar) { Tick(); player = p; model = avatar; if (!ledger.TryGetValue(p.playerClientId, out var value) || value.Owner != ((NetworkBehaviour)p).OwnerClientId) { value = new Entry { Owner = ((NetworkBehaviour)p).OwnerClientId, Player = p }; value.Rules.SeedShip(p.isInHangarShipRoom); ledger[p.playerClientId] = value; } rules = value.Rules; } private static void ScanObjects(float now) { if (!(now < nextObjects)) { nextObjects = now + 1f; items = Object.FindObjectsByType<GrabbableObject>((FindObjectsSortMode)0); ladders = (from t in Object.FindObjectsByType<InteractTrigger>((FindObjectsSortMode)0) where Object.op_Implicit((Object)(object)t) && t.isLadder select t).ToArray(); } } private static bool Scrap(GrabbableObject item) { if (Object.op_Implicit((Object)(object)item) && ((Behaviour)item).isActiveAndEnabled && Object.op_Implicit((Object)(object)item.itemProperties) && item.itemProperties.isScrap && item.scrapValue > 0 && !item.isHeld && !item.isPocketed) { return !item.isHeldByEnemy; } return false; } internal void Pickup(GrabbableObject item, float now) { if (Object.op_Implicit((Object)(object)item) && Object.op_Implicit((Object)(object)item.itemProperties) && item.itemProperties.isScrap && StarsEnabled.Value) { rules.NoticeLoot(((Object)item).GetInstanceID(), item.scrapValue, LootValue.Value, now, Duration.Value); } } private bool Visible(Vector3 point, Transform root, float range) { //IL_0043: 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_0048: Unknown result type (might be due to invalid IL or missing references) //IL_0049: Unknown result type (might be due to invalid IL or missing references) //IL_0055: Unknown result type (might be due to invalid IL or missing references) //IL_005a: Unknown result type (might be due to invalid IL or missing references) //IL_0063: Unknown result type (might be due to invalid IL or missing references) //IL_0064: Unknown result type (might be due to invalid IL or missing references) Vector3 origin = (Object.op_Implicit((Object)(object)player.playerEye) ? player.playerEye.position : (((Component)player).transform.position + Vector3.up * 1.6f)); if (JusticeAttentionSelection.InView(origin, ((Component)player).transform.forward, point, range)) { return JusticeAttentionSelection.Visible(origin, point, Object.op_Implicit((Object)(object)scene) ? scene.collidersAndRoomMaskAndDefault : (-5), ((Component)player).transform, model, root, hits); } return false; } private static string Suit(PlayerControllerB p) { StartOfRound instance = StartOfRound.Instance; List<UnlockableItem> list = ((!Object.op_Implicit((Object)(object)instance)) ? null : instance.unlockablesList?.unlockables); if (list == null || p.currentSuitID < 0 || p.currentSuitID >= list.Count) { return ""; } return list[p.currentSuitID].unlockableName; } private static Rig TargetRig(PlayerControllerB p) { BodyReplacementBase component = ((Component)p).GetComponent<BodyReplacementBase>(); GameObject val = (GameObject)(Object.op_Implicit((Object)(object)component) ? /*isinst with value type is only supported in some contexts*/: null); int instanceID = ((Object)p).GetInstanceID(); if (rigs.TryGetValue(instanceID, out var value) && (Object)(object)value.Model == (Object)(object)val && value.Suit == p.currentSuitID && (!Object.op_Implicit((Object)(object)value.Model) || Object.op_Implicit((Object)(object)value.Chest))) { return value; } Rig rig = new Rig { Model = val, Suit = p.currentSuitID, Breasts = (Transform[])(object)new Transform[0] }; if (Object.op_Implicit((Object)(object)val)) { rig.Authored = val.GetComponent<JusticeChestGazeTarget>(); if (Object.op_Implicit((Object)(object)rig.Authored)) { rig.Chest = rig.Authored.chest; rig.Breasts = rig.Authored.breasts; } else { Transform[] source = (from b in val.GetComponentsInChildren<SkinnedMeshRenderer>(true).SelectMany((SkinnedMeshRenderer s) => s.bones) where Object.op_Implicit((Object)(object)b) select b).Distinct().ToArray(); rig.Breasts = (from b in source.Where(delegate(Transform b) { string text = ((Object)b).name.ToLowerInvariant(); return text.Contains("breast") || text.Contains("bust") || text.Contains("boob") || (text.Contains("胸") && !text.Contains("upper")); }) orderby ((Object)b).name.Length select b).Take(2).ToArray(); Animator componentInChildren = val.GetComponentInChildren<Animator>(); if (Object.op_Implicit((Object)(object)componentInChildren) && componentInChildren.isHuman) { rig.Chest = componentInChildren.GetBoneTransform((HumanBodyBones)54) ?? componentInChildren.GetBoneTransform((HumanBodyBones)8); } if (!Object.op_Implicit((Object)(object)rig.Chest)) { rig.Chest = ((IEnumerable<Transform>)source).FirstOrDefault((Func<Transform, bool>)((Transform b) => ((Object)b).name == "spine_04.x" || ((Object)b).name == "DEF-spine.003")); } } } if (!Object.op_Implicit((Object)(object)rig.Chest) && Object.op_Implicit((Object)(object)p.playerBodyAnimator) && p.playerBodyAnimator.isHuman) { rig.Chest = p.playerBodyAnimator.GetBoneTransform((HumanBodyBones)54) ?? p.playerBodyAnimator.GetBoneTransform((HumanBodyBones)8); } rigs[instanceID] = rig; return rig; } internal static Vector3 ChestPoint(PlayerControllerB p) { //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_001a: 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_0046: Unknown result type (might be due to invalid IL or missing references) //IL_004b: Unknown result type (might be due to invalid IL or missing references) //IL_0050: Unknown result type (might be due to invalid IL or missing references) //IL_009f: Unknown result type (might be due to invalid IL or missing references) //IL_00a2: Unknown result type (might be due to invalid IL or missing references) //IL_0099: Unknown result type (might be due to invalid IL or missing references) //IL_0079: Unknown result type (might be due to invalid IL or missing references) //IL_007e: Unknown result type (might be due to invalid IL or missing references) //IL_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) Rig rig = TargetRig(p); if (Object.op_Implicit((Object)(object)rig.Authored)) { return rig.Authored.Point; } Vector3 val = Vector3.zero; int num = 0; Transform[] breasts = rig.Breasts; foreach (Transform val2 in breasts) { if (Object.op_Implicit((Object)(object)val2)) { val += val2.position; num++; } } if (num <= 0) { if (!Object.op_Implicit((Object)(object)rig.Chest)) { return ((Component)p).transform.position + Vector3.up * 1.3f; } return rig.Chest.position; } return val / (float)num; } private static InteractTrigger LadderOf(PlayerControllerB p) { //IL_0084: Unknown result type (might be due to invalid IL or missing references) //IL_0099: Unknown result type (might be due to invalid IL or missing references) //IL_00aa: Unknown result type (might be due to invalid IL or missing references) //IL_00ca: Unknown result type (might be due to invalid IL or missing references) //IL_00db: Unknown result type (might be due to invalid IL or missing references) //IL_00f8: Unknown result type (might be due to invalid IL or missing references) //IL_0104: Unknown result type (might be due to invalid IL or missing references) //IL_0109: Unknown result type (might be due to invalid IL or missing references) //IL_010e: Unknown result type (might be due to invalid IL or missing references) //IL_0113: Unknown result type (might be due to invalid IL or missing references) //IL_0118: Unknown result type (might be due to invalid IL or missing references) if (!p.isClimbingLadder) { return null; } InteractTrigger currentTriggerInAnimationWith = p.currentTriggerInAnimationWith; if (Object.op_Implicit((Object)(object)currentTriggerInAnimationWith) && currentTriggerInAnimationWith.isLadder) { return currentTriggerInAnimationWith; } InteractTrigger result = null; float num = 0.5625f; InteractTrigger[] array = ladders; foreach (InteractTrigger val in array) { if (!Object.op_Implicit((Object)(object)val) || !Object.op_Implicit((Object)(object)val.ladderHorizontalPosition) || !Object.op_Implicit((Object)(object)val.bottomOfLadderPosition) || !Object.op_Implicit((Object)(object)val.topOfLadderPosition)) { continue; } float y = ((Component)p).transform.position.y; if (!(y < Mathf.Min(val.bottomOfLadderPosition.position.y, val.topOfLadderPosition.position.y) - 0.5f) && !(y > Mathf.Max(val.bottomOfLadderPosition.position.y, val.topOfLadderPosition.position.y) + 0.5f)) { Vector3 val2 = Vector3.ProjectOnPlane(((Component)p).transform.position - val.ladderHorizontalPosition.position, Vector3.up); float sqrMagnitude = ((Vector3)(ref val2)).sqrMagnitude; if (sqrMagnitude < num) { result = val; num = sqrMagnitude; } } } return result; } private bool SeesPile() { //IL_004a: Unknown result type (might be due to invalid IL or missing references) //IL_0095: Unknown result type (might be due to invalid IL or missing references) //IL_00a0: 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) if (!player.isInHangarShipRoom || rules.ShipReactionUsed) { return false; } GrabbableObject[] array = items; foreach (GrabbableObject val in array) { if (!Scrap(val) || !val.isInShipRoom || !Visible(((Component)val).transform.position, ((Component)val).transform, 8f)) { continue; } int num = 0; int num2 = 0; GrabbableObject[] array2 = items; foreach (GrabbableObject val2 in array2) { if (Scrap(val2) && val2.isInShipRoom) { Vector3 val3 = ((Component)val2).transform.position - ((Component)val).transform.position; if (((Vector3)(ref val3)).sqrMagnitude <= PileRadius.Value * PileRadius.Value) { num++; num2 += val2.scrapValue; } } } if (JusticeGigiRules.Pile(num, num2, PileCount.Value, PileValue.Value)) { return true; } } return false; } internal void Evaluate(float now, float delta) { //IL_0434: Unknown result type (might be due to invalid IL or missing references) //IL_0444: Unknown result type (might be due to invalid IL or missing references) //IL_0449: Unknown result type (might be due to invalid IL or missing references) //IL_044e: Unknown result type (might be due to invalid IL or missing references) //IL_01c9: Unknown result type (might be due to invalid IL or missing references) //IL_0301: Unknown result type (might be due to invalid IL or missing references) //IL_0311: Unknown result type (might be due to invalid IL or missing references) //IL_0316: Unknown result type (might be due to invalid IL or missing references) //IL_031b: Unknown result type (might be due to invalid IL or missing references) //IL_03c3: Unknown result type (might be due to invalid IL or missing references) //IL_035f: Unknown result type (might be due to invalid IL or missing references) //IL_0361: Unknown result type (might be due to invalid IL or missing references) //IL_0366: Unknown result type (might be due to invalid IL or missing references) //IL_036b: Unknown result type (might be due to invalid IL or missing references) //IL_0374: Unknown result type (might be due to invalid IL or missing references) Tick(); if (Object.op_Implicit((Object)(object)player) && ((NetworkBehaviour)player).IsOwner && (!ledger.TryGetValue(player.playerClientId, out var value) || value.Owner != ((NetworkBehaviour)player).OwnerClientId || value.Rules != rules)) { Entry entry = new Entry { Owner = ((NetworkBehaviour)player).OwnerClientId, Player = player }; entry.Rules.SeedShip(player.isInHangarShipRoom); ledger[player.playerClientId] = entry; rules = entry.Rules; } if (!Object.op_Implicit((Object)(object)player) || !((NetworkBehaviour)player).IsOwner || player.isPlayerDead || !player.isPlayerControlled) { nearPlayer = null; ladderHeart = false; rules.Near(0, eligible: false, now, delta, GazeDelay.Value, GazeRamp.Value); return; } Vector3 val5; if (now >= nextScan) { nextScan = now + 0.1f; ScanObjects(now); if (suitConfig != HeartSuits.Value) { suitConfig = HeartSuits.Value; suitTokens = suitConfig.Split(';'); } if (StarsEnabled.Value) { GrabbableObject[] array = items; foreach (GrabbableObject val in array) { if (Scrap(val) && !val.isInShipRoom && val.scrapValue > LootValue.Value && Visible(((Component)val).transform.position, ((Component)val).transform, 3f)) { rules.NoticeLoot(((Object)val).GetInstanceID(), val.scrapValue, LootValue.Value, now, Duration.Value); } } rules.Ship(player.isInHangarShipRoom, SeesPile(), now, Duration.Value); } nearPlayer = null; ladderHeart = false; float num = NearRange.Value * NearRange.Value; InteractTrigger val2 = LadderOf(player); if (Object.op_Implicit((Object)(object)scene) && scene.allPlayerScripts != null) { PlayerControllerB[] allPlayerScripts = scene.allPlayerScripts; foreach (PlayerControllerB val3 in allPlayerScripts) { if (!Object.op_Implicit((Object)(object)val3) || (Object)(object)val3 == (Object)(object)player || !val3.isPlayerControlled || val3.isPlayerDead || !((Component)val3).gameObject.activeInHierarchy) { continue; } Vector3 val4 = ((Component)val3).transform.position - ((Component)player).transform.position; if (HeartsEnabled.Value && LadderHearts.Value) { bool isClimbingLadder = player.isClimbingLadder; bool isClimbingLadder2 = val3.isClimbingLadder; bool sameLadder = Object.op_Implicit((Object)(object)val2) && (Object)(object)val2 == (Object)(object)LadderOf(val3); val5 = Vector3.ProjectOnPlane(val4, Vector3.up); if (JusticeGigiRules.Ladder(isClimbingLadder, isClimbingLadder2, sameLadder, ((Vector3)(ref val5)).magnitude, val4.y, LadderRange.Value)) { ladderHeart = true; } } float sqrMagnitude = ((Vector3)(ref val4)).sqrMagnitude; if (HeartsEnabled.Value && !(sqrMagnitude > num) && JusticeGigiRules.SuitMatches(Suit(val3), suitTokens) && Visible(ChestPoint(val3), ((Component)val3).transform, NearRange.Value + 1f)) { nearPlayer = val3; num = sqrMagnitude; } } } } if (Object.op_Implicit((Object)(object)nearPlayer)) { if (!nearPlayer.isPlayerDead && nearPlayer.isPlayerControlled) { val5 = ((Component)nearPlayer).transform.position - ((Component)player).transform.position; if (!(((Vector3)(ref val5)).sqrMagnitude > NearRange.Value * NearRange.Value)) { goto IL_0475; } } nearPlayer = null; } goto IL_0475; IL_0475: rules.Near(Object.op_Implicit((Object)(object)nearPlayer) ? ((Object)nearPlayer).GetInstanceID() : 0, HeartsEnabled.Value && Plugin.Eyes.Value && ChestGaze.Value && Object.op_Implicit((Object)(object)nearPlayer), now, delta, GazeDelay.Value, GazeRamp.Value); } internal void SuppressGaze() { rules.Near(0, eligible: false, Time.unscaledTime, 0f, GazeDelay.Value, GazeRamp.Value); } internal void Revived() { nearPlayer = null; ladderHeart = false; rules.ResetTransient(); nextScan = 0f; } internal static bool Gaze(PlayerControllerB wearer, ulong targetId, float weight