Decompiled source of NpcHealthBars v2.8.0

Mods/NpcHealthBars.dll

Decompiled 3 days ago
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Runtime.Versioning;
using BoneLib.BoneMenu;
using Il2CppInterop.Runtime;
using Il2CppInterop.Runtime.InteropTypes.Arrays;
using Il2CppSLZ.Marrow.AI;
using Il2CppSLZ.Marrow.PuppetMasta;
using Il2CppSystem;
using MelonLoader;
using MelonLoader.Preferences;
using NpcHealthBars;
using UnityEngine;
using UnityEngine.UI;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: MelonInfo(typeof(NpcHealthBarsMod), "NpcHealthBars", "2.7.0", "PeakPenguinzzz", null)]
[assembly: MelonGame("Stress Level Zero", "BONELAB")]
[assembly: AssemblyTitle("ThirdPersonMod")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("ThirdPersonMod")]
[assembly: AssemblyCopyright("Copyright ©  2026")]
[assembly: AssemblyTrademark("")]
[assembly: ComVisible(false)]
[assembly: Guid("15b26708-317a-46bf-9691-0f9ecb456982")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: TargetFramework(".NETFramework,Version=v4.7.2", FrameworkDisplayName = ".NET Framework 4.7.2")]
[assembly: AssemblyVersion("1.0.0.0")]
namespace NpcHealthBars;

public class NpcHealthBarsMod : MelonMod
{
	private sealed class TrackedBar
	{
		public GameObject NpcRoot;

		public BehaviourBaseNav Behaviour;

		public int BehaviourInstanceId;

		public SubBehaviourHealth Health;

		public Transform VisualRoot;

		public Transform TargetRoot;

		public Transform HeadAnchor;

		public Renderer[] Renderers;

		public Collider[] Colliders;

		public Transform[] RigTransforms;

		public Transform BarRoot;

		public Vector3 BarPosition;

		public Canvas Canvas;

		public Image FillImage;

		public RectTransform FillRect;

		public float LastLoggedHealth = float.NaN;

		public float Height;

		public float MaximumHealth;
	}

	private readonly List<TrackedBar> _bars = new List<TrackedBar>();

	private HashSet<int> _activeBehaviourIds = new HashSet<int>();

	private MelonPreferences_Entry<bool> _enabledPreference;

	private bool _enabled;

	private bool _menuBuilt;

	private float _nextScan;

	private Camera _viewCamera;

	private bool _hasLoggedFirstScan;

	private bool _hasLoggedCameraFallback;

	public override void OnInitializeMelon()
	{
		MelonPreferences_Category val = MelonPreferences.CreateCategory("NpcHealthBars");
		_enabledPreference = val.CreateEntry<bool>("Enabled", true, (string)null, (string)null, false, false, (ValueValidator)null, (string)null);
		_enabled = _enabledPreference.Value;
		((MelonBase)this).LoggerInstance.Msg("NPC Health Bars loaded.");
	}

	public override void OnUpdate()
	{
		//IL_0019: 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)
		if (!_menuBuilt && Page.Root != null)
		{
			Page.Root.CreatePage("NPC Health Bars", Color.green, 0, true).CreateBool("Show Health Bars", Color.green, _enabled, (Action<bool>)SetEnabled);
			_menuBuilt = true;
		}
		if (!_enabled)
		{
			ClearTrackedBars();
		}
		else if (Time.unscaledTime >= _nextScan)
		{
			_nextScan = Time.unscaledTime + 0.5f;
			RefreshNpcList();
		}
	}

	public override void OnLateUpdate()
	{
		//IL_014f: 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_0160: Unknown result type (might be due to invalid IL or missing references)
		//IL_0170: Unknown result type (might be due to invalid IL or missing references)
		//IL_017a: Unknown result type (might be due to invalid IL or missing references)
		//IL_01bc: Unknown result type (might be due to invalid IL or missing references)
		//IL_01c2: Unknown result type (might be due to invalid IL or missing references)
		//IL_01c7: Unknown result type (might be due to invalid IL or missing references)
		//IL_01cc: Unknown result type (might be due to invalid IL or missing references)
		//IL_01e4: Unknown result type (might be due to invalid IL or missing references)
		//IL_01e9: Unknown result type (might be due to invalid IL or missing references)
		//IL_01ee: Unknown result type (might be due to invalid IL or missing references)
		//IL_0299: Unknown result type (might be due to invalid IL or missing references)
		//IL_0283: Unknown result type (might be due to invalid IL or missing references)
		//IL_026d: Unknown result type (might be due to invalid IL or missing references)
		//IL_02c4: Unknown result type (might be due to invalid IL or missing references)
		if (!_enabled)
		{
			ClearTrackedBars();
			return;
		}
		int layer = ((_bars.Count > 0 && _bars[0] != null && (Object)(object)_bars[0].BarRoot != (Object)null) ? ((Component)_bars[0].BarRoot).gameObject.layer : (-1));
		if ((Object)(object)_viewCamera == (Object)null || !((Behaviour)_viewCamera).enabled || !((Component)_viewCamera).gameObject.activeInHierarchy || !CameraSeesLayer(_viewCamera, layer))
		{
			_viewCamera = FindViewCamera(layer);
		}
		if ((Object)(object)_viewCamera == (Object)null && !_hasLoggedCameraFallback)
		{
			((MelonBase)this).LoggerInstance.Warning("No active Unity view camera was found; health bars cannot be positioned until a camera is available.");
			_hasLoggedCameraFallback = true;
		}
		for (int num = _bars.Count - 1; num >= 0; num--)
		{
			TrackedBar trackedBar = _bars[num];
			if (!IsTrackedNpcActive(trackedBar) || !_activeBehaviourIds.Contains(trackedBar.BehaviourInstanceId))
			{
				DestroyTrackedBar(trackedBar);
				_bars.RemoveAt(num);
			}
			else if ((Object)(object)trackedBar.BarRoot == (Object)null)
			{
				_bars.RemoveAt(num);
			}
			else
			{
				trackedBar.BarPosition = GetBarPosition(trackedBar);
				trackedBar.BarRoot.position = trackedBar.BarPosition;
				trackedBar.BarRoot.localScale = Vector3.one * 0.003f;
				if ((Object)(object)_viewCamera != (Object)null)
				{
					if ((Object)(object)trackedBar.Canvas != (Object)null)
					{
						trackedBar.Canvas.worldCamera = _viewCamera;
					}
					Vector3 val = ((Component)_viewCamera).transform.position - trackedBar.BarPosition;
					if (((Vector3)(ref val)).sqrMagnitude > 0.001f)
					{
						trackedBar.BarRoot.rotation = Quaternion.LookRotation(((Vector3)(ref val)).normalized, Vector3.up);
					}
				}
				float maximumHealth = trackedBar.MaximumHealth;
				float num2 = ((trackedBar.Health != null) ? trackedBar.Health.cur_hp : 0f);
				float num3 = ((maximumHealth > 0f) ? Mathf.Clamp01(num2 / maximumHealth) : 0f);
				if ((Object)(object)trackedBar.FillImage != (Object)null)
				{
					((Graphic)trackedBar.FillImage).color = ((num3 > 0.6f) ? new Color(0.18f, 0.92f, 0.25f) : ((num3 > 0.3f) ? new Color(1f, 0.76f, 0.1f) : new Color(0.95f, 0.12f, 0.12f)));
					if ((Object)(object)trackedBar.FillRect != (Object)null)
					{
						trackedBar.FillRect.sizeDelta = new Vector2(216f * num3, -4f);
					}
				}
				if (float.IsNaN(trackedBar.LastLoggedHealth) || Mathf.Abs(num2 - trackedBar.LastLoggedHealth) > 0.01f)
				{
					((MelonBase)this).LoggerInstance.Msg("NPC health value for " + ((Object)trackedBar.NpcRoot).name + ": current=" + num2 + ", displayFull=" + maximumHealth + ", engineMax=" + ReadMaximumHealth(trackedBar.Health));
					trackedBar.LastLoggedHealth = num2;
				}
			}
		}
	}

	private Camera FindViewCamera(int layer)
	{
		Camera[] array = Il2CppArrayBase<Camera>.op_Implicit((Il2CppArrayBase<Camera>)(object)Camera.allCameras);
		Camera[] array2 = array;
		foreach (Camera val in array2)
		{
			if (IsUsableCamera(val) && val.stereoEnabled && CameraSeesLayer(val, layer))
			{
				return val;
			}
		}
		Camera main = Camera.main;
		if (IsUsableCamera(main) && CameraSeesLayer(main, layer))
		{
			return main;
		}
		Camera current = Camera.current;
		if (IsUsableCamera(current) && CameraSeesLayer(current, layer))
		{
			return current;
		}
		array2 = array;
		foreach (Camera val2 in array2)
		{
			if (IsUsableCamera(val2) && CameraSeesLayer(val2, layer))
			{
				return val2;
			}
		}
		if (IsUsableCamera(main))
		{
			return main;
		}
		if (!IsUsableCamera(current))
		{
			return null;
		}
		return current;
	}

	private bool CameraSeesLayer(Camera camera, int layer)
	{
		if (layer >= 0)
		{
			if ((Object)(object)camera != (Object)null)
			{
				return (camera.cullingMask & (1 << layer)) != 0;
			}
			return false;
		}
		return true;
	}

	private bool IsUsableCamera(Camera camera)
	{
		if ((Object)(object)camera != (Object)null && ((Behaviour)camera).enabled)
		{
			return ((Component)camera).gameObject.activeInHierarchy;
		}
		return false;
	}

	private Vector3 GetBarPosition(TrackedBar tracked)
	{
		//IL_0050: 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_0056: 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_0091: Unknown result type (might be due to invalid IL or missing references)
		//IL_00a4: Unknown result type (might be due to invalid IL or missing references)
		//IL_010b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0117: Unknown result type (might be due to invalid IL or missing references)
		//IL_0129: Unknown result type (might be due to invalid IL or missing references)
		//IL_0133: Unknown result type (might be due to invalid IL or missing references)
		//IL_00b7: Unknown result type (might be due to invalid IL or missing references)
		//IL_018a: Unknown result type (might be due to invalid IL or missing references)
		//IL_018b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0191: Unknown result type (might be due to invalid IL or missing references)
		//IL_0196: Unknown result type (might be due to invalid IL or missing references)
		//IL_014d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0152: Unknown result type (might be due to invalid IL or missing references)
		//IL_015c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0161: Unknown result type (might be due to invalid IL or missing references)
		//IL_0166: Unknown result type (might be due to invalid IL or missing references)
		//IL_0168: Unknown result type (might be due to invalid IL or missing references)
		//IL_016f: 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_017d: Unknown result type (might be due to invalid IL or missing references)
		//IL_00dd: Unknown result type (might be due to invalid IL or missing references)
		//IL_00e7: Unknown result type (might be due to invalid IL or missing references)
		//IL_0187: Unknown result type (might be due to invalid IL or missing references)
		//IL_00f7: Unknown result type (might be due to invalid IL or missing references)
		Transform val = (((Object)(object)tracked.TargetRoot != (Object)null) ? tracked.TargetRoot : tracked.VisualRoot);
		if ((Object)(object)val == (Object)null && (Object)(object)tracked.NpcRoot != (Object)null)
		{
			val = tracked.NpcRoot.transform;
		}
		if ((Object)(object)val == (Object)null)
		{
			return Vector3.zero;
		}
		Vector3 position = val.position;
		float num = position.y + 6f;
		float num2 = Mathf.Clamp(tracked.Height, 1.8f, 3.5f);
		if (TryGetBounds(tracked.Renderers, tracked.Colliders, out var bounds) && ((Bounds)(ref bounds)).size.y > 0.7f && ((Bounds)(ref bounds)).size.y < 6.5f && ((Bounds)(ref bounds)).size.x < 4f && ((Bounds)(ref bounds)).size.z < 4f && ((Bounds)(ref bounds)).max.y > position.y + 0.8f && ((Bounds)(ref bounds)).max.y < num)
		{
			return new Vector3(((Bounds)(ref bounds)).center.x, ((Bounds)(ref bounds)).max.y + 0.18f, ((Bounds)(ref bounds)).center.z);
		}
		if ((Object)(object)tracked.HeadAnchor != (Object)null)
		{
			Vector3 val2 = tracked.HeadAnchor.position + Vector3.up * 0.22f;
			if (val2.y > position.y + 0.7f && val2.y < num)
			{
				return val2;
			}
		}
		return position + Vector3.up * num2;
	}

	private void SetEnabled(bool enabled)
	{
		_enabled = enabled;
		_enabledPreference.Value = enabled;
		MelonPreferences.Save();
		if (enabled)
		{
			_nextScan = 0f;
		}
		else
		{
			ClearTrackedBars();
		}
	}

	private bool IsTrackedNpcActive(TrackedBar tracked)
	{
		if (tracked == null || (Object)(object)tracked.NpcRoot == (Object)null || (Object)(object)tracked.Behaviour == (Object)null || tracked.Health == null || (Object)(object)tracked.VisualRoot == (Object)null)
		{
			return false;
		}
		if (tracked.NpcRoot.activeInHierarchy && ((Behaviour)tracked.Behaviour).enabled)
		{
			return ((Component)tracked.Behaviour).gameObject.activeInHierarchy;
		}
		return false;
	}

	private void DestroyTrackedBar(TrackedBar tracked)
	{
		if (tracked != null && (Object)(object)tracked.BarRoot != (Object)null)
		{
			Object.Destroy((Object)(object)((Component)tracked.BarRoot).gameObject);
		}
	}

	private void ClearTrackedBars()
	{
		foreach (TrackedBar bar in _bars)
		{
			if (bar != null && (Object)(object)bar.BarRoot != (Object)null)
			{
				Object.Destroy((Object)(object)((Component)bar.BarRoot).gameObject);
			}
		}
		_bars.Clear();
	}

	private void RefreshNpcList()
	{
		if (!_enabled)
		{
			return;
		}
		try
		{
			BehaviourBaseNav[] array = Il2CppArrayBase<BehaviourBaseNav>.op_Implicit(Object.FindObjectsOfType<BehaviourBaseNav>());
			AIBrain[] array2 = Il2CppArrayBase<AIBrain>.op_Implicit(Object.FindObjectsOfType<AIBrain>());
			PuppetMaster[] array3 = Il2CppArrayBase<PuppetMaster>.op_Implicit(Object.FindObjectsOfType<PuppetMaster>());
			HashSet<int> hashSet = new HashSet<int>();
			BehaviourBaseNav[] array4 = array;
			foreach (BehaviourBaseNav val in array4)
			{
				if ((Object)(object)val != (Object)null && ((Component)val).gameObject.activeInHierarchy)
				{
					hashSet.Add(((Object)val).GetInstanceID());
				}
				TryAddHealthBar(val);
			}
			AIBrain[] array5 = array2;
			foreach (AIBrain val2 in array5)
			{
				if ((Object)(object)val2 != (Object)null && (Object)(object)val2.behaviour != (Object)null)
				{
					if (((Component)val2.behaviour).gameObject.activeInHierarchy)
					{
						hashSet.Add(((Object)val2.behaviour).GetInstanceID());
					}
					TryAddHealthBar(val2.behaviour);
				}
			}
			PuppetMaster[] array6 = array3;
			foreach (PuppetMaster val3 in array6)
			{
				if ((Object)(object)val3 == (Object)null)
				{
					continue;
				}
				BehaviourBaseNav val4 = ((Component)val3).GetComponentInParent<BehaviourBaseNav>();
				if ((Object)(object)val4 == (Object)null)
				{
					val4 = ((Component)val3).GetComponentInChildren<BehaviourBaseNav>(true);
				}
				if ((Object)(object)val4 != (Object)null)
				{
					if (((Component)val4).gameObject.activeInHierarchy)
					{
						hashSet.Add(((Object)val4).GetInstanceID());
					}
					TryAddHealthBar(val4);
				}
			}
			_activeBehaviourIds = hashSet;
			for (int num = _bars.Count - 1; num >= 0; num--)
			{
				TrackedBar trackedBar = _bars[num];
				if (!IsTrackedNpcActive(trackedBar) || !_activeBehaviourIds.Contains(trackedBar.BehaviourInstanceId))
				{
					DestroyTrackedBar(trackedBar);
					_bars.RemoveAt(num);
				}
			}
			if (!_hasLoggedFirstScan)
			{
				((MelonBase)this).LoggerInstance.Msg("NPC scan found " + array.Length + " behaviors, " + array2.Length + " AI brains, " + array3.Length + " puppet rigs; showing " + _bars.Count + " bars.");
				_hasLoggedFirstScan = true;
			}
		}
		catch (Exception ex)
		{
			((MelonBase)this).LoggerInstance.Warning("NPC health bar scan failed: " + ex.Message);
		}
	}

	private void TryAddHealthBar(BehaviourBaseNav behaviour)
	{
		//IL_015b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0160: Unknown result type (might be due to invalid IL or missing references)
		//IL_0165: Unknown result type (might be due to invalid IL or missing references)
		//IL_01e3: Unknown result type (might be due to invalid IL or missing references)
		//IL_01f6: Unknown result type (might be due to invalid IL or missing references)
		//IL_0210: 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_0263: Unknown result type (might be due to invalid IL or missing references)
		//IL_0268: 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_0282: Unknown result type (might be due to invalid IL or missing references)
		//IL_02f5: Unknown result type (might be due to invalid IL or missing references)
		//IL_02fa: Unknown result type (might be due to invalid IL or missing references)
		//IL_0308: Unknown result type (might be due to invalid IL or missing references)
		//IL_0319: Unknown result type (might be due to invalid IL or missing references)
		//IL_0323: Unknown result type (might be due to invalid IL or missing references)
		//IL_033a: Unknown result type (might be due to invalid IL or missing references)
		//IL_033f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0354: Unknown result type (might be due to invalid IL or missing references)
		//IL_0359: Unknown result type (might be due to invalid IL or missing references)
		//IL_0381: Unknown result type (might be due to invalid IL or missing references)
		//IL_0386: Unknown result type (might be due to invalid IL or missing references)
		//IL_03c5: Unknown result type (might be due to invalid IL or missing references)
		//IL_03ca: Unknown result type (might be due to invalid IL or missing references)
		//IL_03e5: Unknown result type (might be due to invalid IL or missing references)
		//IL_03ea: Unknown result type (might be due to invalid IL or missing references)
		if (!_enabled || (Object)(object)behaviour == (Object)null)
		{
			return;
		}
		SubBehaviourHealth health = behaviour.health;
		if (health == null)
		{
			return;
		}
		PuppetMaster puppetMaster = ((BehaviourBase)behaviour).puppetMaster;
		GameObject val = (((Object)(object)puppetMaster != (Object)null) ? ((Component)puppetMaster).gameObject : ((Component)((Component)behaviour).transform.root).gameObject);
		if ((Object)(object)val == (Object)null || FindTracked(val) != null)
		{
			return;
		}
		Transform val2 = (((Object)(object)puppetMaster != (Object)null) ? puppetMaster.targetRoot : null);
		Animator val3 = (((Object)(object)puppetMaster != (Object)null) ? puppetMaster.targetAnimator : null);
		if ((Object)(object)val3 == (Object)null && (Object)(object)val2 != (Object)null)
		{
			val3 = ((Component)val2).GetComponentInChildren<Animator>(true);
		}
		if ((Object)(object)val3 == (Object)null)
		{
			val3 = val.GetComponentInChildren<Animator>(true);
			if ((Object)(object)val3 == (Object)null)
			{
				val3 = ((Component)behaviour).GetComponentInChildren<Animator>(true);
			}
		}
		if ((Object)(object)val2 == (Object)null && (Object)(object)val3 != (Object)null)
		{
			val2 = ((Component)val3).transform;
		}
		if ((Object)(object)val2 == (Object)null)
		{
			val2 = ((Component)behaviour).transform;
		}
		Transform val4 = val2;
		Transform val5 = null;
		if ((Object)(object)val3 != (Object)null && val3.isHuman)
		{
			try
			{
				val5 = val3.GetBoneTransform((HumanBodyBones)10);
			}
			catch
			{
			}
		}
		List<Renderer> list = new List<Renderer>();
		AddRenderers(list, val4);
		AddRenderers(list, val2);
		AddRenderers(list, ((Object)(object)val3 != (Object)null) ? ((Component)val3).transform : null);
		AddRenderers(list, val.transform);
		Vector3 position = val2.position;
		int num = AddNearbySkinnedRenderers(list, position);
		Renderer[] array = list.ToArray();
		List<Collider> list2 = new List<Collider>();
		AddColliders(list2, val4);
		AddColliders(list2, val2);
		AddColliders(list2, val.transform);
		Collider[] colliders = list2.ToArray();
		List<Transform> list3 = new List<Transform>();
		AddTransforms(list3, val.transform);
		AddTransforms(list3, val2);
		Transform[] rigTransforms = list3.ToArray();
		Bounds bounds;
		bool flag = TryGetBounds(array, colliders, out bounds);
		float height = ((flag && ((Bounds)(ref bounds)).size.y > 0.7f && ((Bounds)(ref bounds)).size.y < 5.5f) ? Mathf.Clamp(((Bounds)(ref bounds)).size.y, 1.8f, 3.5f) : 2.1f);
		int layer = ((Component)val2).gameObject.layer;
		float num2 = float.PositiveInfinity;
		Renderer[] array2 = array;
		foreach (Renderer val6 in array2)
		{
			if (val6 is SkinnedMeshRenderer)
			{
				Bounds bounds2 = val6.bounds;
				Vector3 center = ((Bounds)(ref bounds2)).center;
				float num3 = center.x - val2.position.x;
				float num4 = center.z - val2.position.z;
				float num5 = num3 * num3 + num4 * num4;
				if (num5 < num2)
				{
					num2 = num5;
					layer = ((Component)val6).gameObject.layer;
				}
			}
		}
		TrackedBar trackedBar = CreateBar(val, behaviour, health, val4, val2, height, val5, array, colliders, rigTransforms, layer);
		if (trackedBar != null)
		{
			_bars.Add(trackedBar);
			trackedBar.BarPosition = GetBarPosition(trackedBar);
			trackedBar.BarRoot.position = trackedBar.BarPosition;
			trackedBar.BarRoot.localScale = Vector3.one * 0.003f;
			string text = (flag ? (((Bounds)(ref bounds)).min.y + ".." + ((Bounds)(ref bounds)).max.y) : "none");
			string text2 = (((Object)(object)val5 != (Object)null) ? val5.position.y.ToString() : "none");
			((MelonBase)this).LoggerInstance.Msg("Health bar tracking NPC: " + ((Object)val).name + " at " + ((object)trackedBar.BarRoot.position/*cast due to .constrained prefix*/).ToString() + " (targetRootY=" + val2.position.y + ", headY=" + text2 + ", boundsY=" + text + ", nearbySkinnedRenderers=" + num + ", layer=" + layer + ", cameraSeesLayer=" + (((Object)(object)_viewCamera == (Object)null) ? "unknown" : ((_viewCamera.cullingMask & (1 << layer)) != 0).ToString()) + ")");
		}
	}

	private int AddNearbySkinnedRenderers(List<Renderer> list, Vector3 actorPosition)
	{
		//IL_011a: Unknown result type (might be due to invalid IL or missing references)
		//IL_011f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0123: Unknown result type (might be due to invalid IL or missing references)
		//IL_0128: Unknown result type (might be due to invalid IL or missing references)
		//IL_0040: 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)
		//IL_0049: Unknown result type (might be due to invalid IL or missing references)
		//IL_005f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0075: 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_0159: Unknown result type (might be due to invalid IL or missing references)
		//IL_015e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0162: Unknown result type (might be due to invalid IL or missing references)
		//IL_009b: Unknown result type (might be due to invalid IL or missing references)
		//IL_00a5: Unknown result type (might be due to invalid IL or missing references)
		//IL_00ae: Unknown result type (might be due to invalid IL or missing references)
		//IL_00b8: Unknown result type (might be due to invalid IL or missing references)
		//IL_00cd: Unknown result type (might be due to invalid IL or missing references)
		//IL_00d7: Unknown result type (might be due to invalid IL or missing references)
		//IL_0178: Unknown result type (might be due to invalid IL or missing references)
		//IL_018e: Unknown result type (might be due to invalid IL or missing references)
		//IL_01a4: Unknown result type (might be due to invalid IL or missing references)
		//IL_01b7: Unknown result type (might be due to invalid IL or missing references)
		//IL_01c1: Unknown result type (might be due to invalid IL or missing references)
		//IL_01ca: Unknown result type (might be due to invalid IL or missing references)
		//IL_01d4: Unknown result type (might be due to invalid IL or missing references)
		//IL_01df: Unknown result type (might be due to invalid IL or missing references)
		//IL_01e9: Unknown result type (might be due to invalid IL or missing references)
		SkinnedMeshRenderer[] array = Il2CppArrayBase<SkinnedMeshRenderer>.op_Implicit(Object.FindObjectsOfType<SkinnedMeshRenderer>());
		SkinnedMeshRenderer val = null;
		float num = 3.0625f;
		SkinnedMeshRenderer[] array2 = array;
		foreach (SkinnedMeshRenderer val2 in array2)
		{
			if ((Object)(object)val2 == (Object)null || !((Renderer)val2).enabled)
			{
				continue;
			}
			Bounds bounds = ((Renderer)val2).bounds;
			if (!(((Bounds)(ref bounds)).size.y < 0.25f) && !(((Bounds)(ref bounds)).size.y > 6.5f) && !(((Bounds)(ref bounds)).size.x > 4f) && !(((Bounds)(ref bounds)).size.z > 4f))
			{
				float num2 = ((Bounds)(ref bounds)).center.x - actorPosition.x;
				float num3 = ((Bounds)(ref bounds)).center.z - actorPosition.z;
				float num4 = num2 * num2 + num3 * num3;
				float num5 = ((Bounds)(ref bounds)).center.y - actorPosition.y;
				if (!(num4 > num) && !(num5 < -2.5f) && !(num5 > 6f))
				{
					num = num4;
					val = val2;
				}
			}
		}
		if ((Object)(object)val == (Object)null)
		{
			return 0;
		}
		Bounds bounds2 = ((Renderer)val).bounds;
		Vector3 center = ((Bounds)(ref bounds2)).center;
		int num6 = 0;
		array2 = array;
		foreach (SkinnedMeshRenderer val3 in array2)
		{
			if ((Object)(object)val3 == (Object)null || !((Renderer)val3).enabled)
			{
				continue;
			}
			Bounds bounds3 = ((Renderer)val3).bounds;
			if (!(((Bounds)(ref bounds3)).size.y < 0.15f) && !(((Bounds)(ref bounds3)).size.y > 6.5f) && !(((Bounds)(ref bounds3)).size.x > 4f) && !(((Bounds)(ref bounds3)).size.z > 4f))
			{
				float num7 = ((Bounds)(ref bounds3)).center.x - center.x;
				float num8 = ((Bounds)(ref bounds3)).center.z - center.z;
				float num9 = ((Bounds)(ref bounds3)).center.y - actorPosition.y;
				if (!(num7 * num7 + num8 * num8 > 0.64000005f) && !(num9 < -2.5f) && !(num9 > 6f) && !list.Contains((Renderer)(object)val3))
				{
					list.Add((Renderer)(object)val3);
					num6++;
				}
			}
		}
		return num6;
	}

	private void AddRenderers(List<Renderer> list, Transform root)
	{
		if ((Object)(object)root == (Object)null)
		{
			return;
		}
		Renderer[] array = Il2CppArrayBase<Renderer>.op_Implicit(((Component)root).GetComponentsInChildren<Renderer>(true));
		foreach (Renderer val in array)
		{
			if ((Object)(object)val != (Object)null && !list.Contains(val))
			{
				list.Add(val);
			}
		}
	}

	private void AddColliders(List<Collider> list, Transform root)
	{
		if ((Object)(object)root == (Object)null)
		{
			return;
		}
		Collider[] array = Il2CppArrayBase<Collider>.op_Implicit(((Component)root).GetComponentsInChildren<Collider>(true));
		foreach (Collider val in array)
		{
			if ((Object)(object)val != (Object)null && !list.Contains(val))
			{
				list.Add(val);
			}
		}
	}

	private void AddTransforms(List<Transform> list, Transform root)
	{
		if ((Object)(object)root == (Object)null)
		{
			return;
		}
		Transform[] array = Il2CppArrayBase<Transform>.op_Implicit(((Component)root).GetComponentsInChildren<Transform>(true));
		foreach (Transform val in array)
		{
			if ((Object)(object)val != (Object)null && !list.Contains(val))
			{
				list.Add(val);
			}
		}
	}

	private bool TryGetBounds(Renderer[] renderers, Collider[] colliders, out Bounds bounds)
	{
		//IL_0003: Unknown result type (might be due to invalid IL or missing references)
		//IL_0008: Unknown result type (might be due to invalid IL or missing references)
		//IL_000d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0012: Unknown result type (might be due to invalid IL or missing references)
		//IL_004a: Unknown result type (might be due to invalid IL or missing references)
		//IL_003a: Unknown result type (might be due to invalid IL or missing references)
		//IL_003f: Unknown result type (might be due to invalid IL or missing references)
		//IL_00a1: Unknown result type (might be due to invalid IL or missing references)
		//IL_0090: 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)
		bool flag = false;
		bounds = new Bounds(Vector3.zero, Vector3.one);
		if (renderers != null)
		{
			foreach (Renderer val in renderers)
			{
				if (!((Object)(object)val == (Object)null) && val.enabled)
				{
					if (!flag)
					{
						bounds = val.bounds;
						flag = true;
					}
					else
					{
						((Bounds)(ref bounds)).Encapsulate(val.bounds);
					}
				}
			}
		}
		if (colliders != null)
		{
			foreach (Collider val2 in colliders)
			{
				if (!((Object)(object)val2 == (Object)null) && val2.enabled && !val2.isTrigger)
				{
					if (!flag)
					{
						bounds = val2.bounds;
						flag = true;
					}
					else
					{
						((Bounds)(ref bounds)).Encapsulate(val2.bounds);
					}
				}
			}
		}
		return flag;
	}

	private TrackedBar FindTracked(GameObject npcRoot)
	{
		foreach (TrackedBar bar in _bars)
		{
			if (bar != null && (Object)(object)bar.NpcRoot == (Object)(object)npcRoot)
			{
				return bar;
			}
		}
		return null;
	}

	private float ReadDisplayMaximumHealth(SubBehaviourHealth health)
	{
		if (health == null)
		{
			return 100f;
		}
		float cur_hp = health.cur_hp;
		if (!(cur_hp > 0.001f))
		{
			return ReadMaximumHealth(health);
		}
		return cur_hp;
	}

	private float ReadMaximumHealth(SubBehaviourHealth health)
	{
		if (health == null)
		{
			return 100f;
		}
		string[] obj = new string[5] { "maxHitPoints", "max_Health", "maxHealth", "max_hp", "MaxHealth" };
		Type type = ((object)health).GetType();
		string[] array = obj;
		foreach (string name in array)
		{
			try
			{
				PropertyInfo property = type.GetProperty(name, BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
				if (property != null && property.PropertyType == typeof(float))
				{
					return Mathf.Max(1f, (float)property.GetValue(health, null));
				}
				FieldInfo field = type.GetField(name, BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
				if (field != null && field.FieldType == typeof(float))
				{
					return Mathf.Max(1f, (float)field.GetValue(health));
				}
			}
			catch
			{
			}
		}
		return 100f;
	}

	private TrackedBar CreateBar(GameObject npcRoot, BehaviourBaseNav behaviour, SubBehaviourHealth health, Transform visualRoot, Transform targetRoot, float height, Transform headAnchor, Renderer[] renderers, Collider[] colliders, Transform[] rigTransforms, int renderLayer)
	{
		//IL_0018: Unknown result type (might be due to invalid IL or missing references)
		//IL_001e: Expected O, but got Unknown
		//IL_0061: Unknown result type (might be due to invalid IL or missing references)
		//IL_0071: Unknown result type (might be due to invalid IL or missing references)
		//IL_007b: Unknown result type (might be due to invalid IL or missing references)
		//IL_00ad: Unknown result type (might be due to invalid IL or missing references)
		//IL_00b2: Unknown result type (might be due to invalid IL or missing references)
		//IL_00b9: Unknown result type (might be due to invalid IL or missing references)
		//IL_00c0: Unknown result type (might be due to invalid IL or missing references)
		//IL_00d9: Unknown result type (might be due to invalid IL or missing references)
		//IL_00e4: Unknown result type (might be due to invalid IL or missing references)
		//IL_00ef: Unknown result type (might be due to invalid IL or missing references)
		//IL_00fa: Unknown result type (might be due to invalid IL or missing references)
		//IL_0119: Unknown result type (might be due to invalid IL or missing references)
		//IL_014b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0150: Unknown result type (might be due to invalid IL or missing references)
		//IL_0157: Unknown result type (might be due to invalid IL or missing references)
		//IL_015f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0184: Unknown result type (might be due to invalid IL or missing references)
		//IL_019a: Unknown result type (might be due to invalid IL or missing references)
		//IL_01b0: Unknown result type (might be due to invalid IL or missing references)
		//IL_01c6: Unknown result type (might be due to invalid IL or missing references)
		//IL_01dc: Unknown result type (might be due to invalid IL or missing references)
		//IL_01ff: Unknown result type (might be due to invalid IL or missing references)
		//IL_0285: Unknown result type (might be due to invalid IL or missing references)
		//IL_028a: Unknown result type (might be due to invalid IL or missing references)
		//IL_02b5: Unknown result type (might be due to invalid IL or missing references)
		//IL_02ba: Unknown result type (might be due to invalid IL or missing references)
		//IL_02c7: Unknown result type (might be due to invalid IL or missing references)
		GameObject val = new GameObject("NpcHealthBar", new Il2CppReferenceArray<Type>((Type[])(object)new Type[1] { Il2CppType.Of<RectTransform>() }));
		val.layer = 5;
		Canvas val2 = val.AddComponent<Canvas>();
		val2.renderMode = (RenderMode)2;
		val2.worldCamera = _viewCamera;
		val2.overrideSorting = true;
		val2.sortingOrder = 32760;
		val.GetComponent<RectTransform>().sizeDelta = new Vector2(220f, 24f);
		val.transform.localScale = Vector3.one * 0.003f;
		GameObject val3 = new GameObject("Background", new Il2CppReferenceArray<Type>((Type[])(object)new Type[3]
		{
			Il2CppType.Of<RectTransform>(),
			Il2CppType.Of<CanvasRenderer>(),
			Il2CppType.Of<Image>()
		}))
		{
			layer = 5
		};
		RectTransform component = val3.GetComponent<RectTransform>();
		Image component2 = val3.GetComponent<Image>();
		val3.transform.SetParent(val.transform, false);
		component.anchorMin = Vector2.zero;
		component.anchorMax = Vector2.one;
		component.offsetMin = Vector2.zero;
		component.offsetMax = Vector2.zero;
		((Graphic)component2).color = new Color(0.02f, 0.02f, 0.02f, 0.95f);
		GameObject val4 = new GameObject("HealthFill", new Il2CppReferenceArray<Type>((Type[])(object)new Type[3]
		{
			Il2CppType.Of<RectTransform>(),
			Il2CppType.Of<CanvasRenderer>(),
			Il2CppType.Of<Image>()
		}))
		{
			layer = 5
		};
		RectTransform component3 = val4.GetComponent<RectTransform>();
		Image component4 = val4.GetComponent<Image>();
		val4.transform.SetParent(val.transform, false);
		component3.anchorMin = new Vector2(0f, 0f);
		component3.anchorMax = new Vector2(0f, 1f);
		component3.pivot = new Vector2(0f, 0.5f);
		component3.anchoredPosition = new Vector2(2f, 0f);
		component3.sizeDelta = new Vector2(216f, -4f);
		component4.type = (Type)0;
		((Graphic)component4).color = new Color(0.18f, 0.92f, 0.25f);
		TrackedBar trackedBar = new TrackedBar
		{
			NpcRoot = npcRoot,
			Behaviour = behaviour,
			BehaviourInstanceId = (((Object)(object)behaviour != (Object)null) ? ((Object)behaviour).GetInstanceID() : 0),
			Health = health,
			MaximumHealth = ReadDisplayMaximumHealth(health),
			VisualRoot = visualRoot,
			TargetRoot = targetRoot,
			HeadAnchor = headAnchor,
			Renderers = renderers,
			Colliders = colliders,
			RigTransforms = rigTransforms,
			BarRoot = val.transform,
			BarPosition = Vector3.zero,
			Canvas = val2,
			FillImage = component4,
			FillRect = component3,
			Height = height
		};
		trackedBar.BarPosition = GetBarPosition(trackedBar);
		val.transform.position = trackedBar.BarPosition;
		return trackedBar;
	}

	private void SetAllBarsActive(bool active)
	{
		foreach (TrackedBar bar in _bars)
		{
			if (bar != null && (Object)(object)bar.BarRoot != (Object)null)
			{
				((Component)bar.BarRoot).gameObject.SetActive(active);
			}
		}
	}

	public override void OnSceneWasLoaded(int buildIndex, string sceneName)
	{
		ClearTrackedBars();
		_nextScan = 0f;
	}

	public override void OnDeinitializeMelon()
	{
		ClearTrackedBars();
	}
}