Decompiled source of TeammateHUD v0.6.4

BepInEx\plugins\TeammateHUD\TeammateHUD.dll

Decompiled 4 days ago
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Reflection;
using System.Runtime.CompilerServices;
using Agents;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using BepInEx.Unity.IL2CPP;
using CellMenu;
using GameData;
using Il2CppInterop.Runtime;
using Il2CppInterop.Runtime.InteropTypes;
using Il2CppInterop.Runtime.InteropTypes.Arrays;
using Il2CppSystem.Collections.Generic;
using Player;
using TMPro;
using UnityEngine;
using UnityEngine.UI;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: AssemblyVersion("0.0.0.0")]
namespace TeammateHUD;

[BepInPlugin("gtfo.teammatehud", "Teammate HUD", "0.6.4")]
public class Plugin : BasePlugin
{
	public const string GUID = "gtfo.teammatehud";

	internal static ManualLogSource LogSource;

	internal static ConfigEntry<string> ToggleKey;

	internal static ConfigEntry<float> Scale;

	internal static ConfigEntry<float> FontSize;

	internal static ConfigEntry<float> OffsetX;

	internal static ConfigEntry<float> OffsetY;

	internal static ConfigEntry<float> RowHeight;

	internal static ConfigEntry<float> Opacity;

	internal static ConfigEntry<bool> ShowHeaders;

	public override void Load()
	{
		LogSource = ((BasePlugin)this).Log;
		ToggleKey = ((BasePlugin)this).Config.Bind<string>("Display", "ToggleKey", "X", "按键切换 HUD 显示/隐藏 (KeyCode 名称, 如 X)");
		Scale = ((BasePlugin)this).Config.Bind<float>("Display", "Scale", 1f, "整体缩放 (1 = 原始大小)");
		FontSize = ((BasePlugin)this).Config.Bind<float>("Display", "FontSize", 20f, "基准字号, 最终字号 = FontSize * Scale");
		OffsetX = ((BasePlugin)this).Config.Bind<float>("Display", "OffsetX", 40f, "HUD 左边距");
		OffsetY = ((BasePlugin)this).Config.Bind<float>("Display", "OffsetY", 300f, "HUD 上边距");
		RowHeight = ((BasePlugin)this).Config.Bind<float>("Display", "RowHeight", 35f, "基准行高, 最终行高 = RowHeight * Scale");
		Opacity = ((BasePlugin)this).Config.Bind<float>("Display", "Opacity", 1f, "整体不透明度 0-1");
		ShowHeaders = ((BasePlugin)this).Config.Bind<bool>("Display", "ShowHeaders", true, "是否显示 HP/PRI/SEC/TOOL/RES 小标题");
		ConfigEntry<int> val = ((BasePlugin)this).Config.Bind<int>("Meta", "ConfigVersion", 0, "内部配置版本, 请勿手动修改");
		if (val.Value < 5)
		{
			Scale.Value = 1f;
			FontSize.Value = 20f;
			RowHeight.Value = 35f;
			ToggleKey.Value = "X";
			val.Value = 5;
			((BasePlugin)this).Log.LogInfo((object)"Teammate HUD config migrated to v5 (toggle = X)");
		}
		((BasePlugin)this).AddComponent<TeammateHudBehaviour>();
		((BasePlugin)this).Log.LogInfo((object)("Teammate HUD loaded (toggle: " + ToggleKey.Value + ")"));
	}
}
public class TeammateHudBehaviour : MonoBehaviour
{
	private class Row
	{
		public GameObject go;

		public RawImage square;

		public TextMeshProUGUI name;

		public RawImage barBg;

		public RawImage barFill;

		public TextMeshProUGUI hp;

		public TextMeshProUGUI ammoStd;

		public TextMeshProUGUI ammoSpl;

		public TextMeshProUGUI ammoCls;

		public TextMeshProUGUI res;
	}

	private bool built;

	private bool loggedRoster;

	private bool loggedFont;

	private bool loggedLocalAmmo;

	private bool loggedRemoteAmmo;

	private float lastRefresh;

	private float lastErrLog;

	private float lastMapScan;

	private bool manualVisible = true;

	private int lastShow = -1;

	private GameObject canvasGo;

	private GameObject contentGo;

	private TMP_FontAsset font;

	private Material fontMat;

	private PlayerGuiLayer layer;

	private PUI_Inventory inventory;

	private GameObject inventoryGo;

	private GameObject mapPage;

	private readonly List<Row> rows = new List<Row>();

	private static readonly Color ColWhite = new Color(0.93f, 0.93f, 0.9f, 1f);

	private static readonly Color ColAmber = new Color(0.91f, 0.7f, 0.33f, 1f);

	private static readonly Color ColRed = new Color(0.89f, 0.38f, 0.33f, 1f);

	private static readonly Color ColGrey = new Color(0.62f, 0.62f, 0.6f, 1f);

	private static readonly Color ColGreen = new Color(0.46f, 0.75f, 0.48f, 1f);

	private static readonly Color ColCyan = new Color(0.41f, 0.75f, 0.83f, 1f);

	private static readonly Color ColPurple = new Color(0.72f, 0.52f, 0.88f, 1f);

	private readonly HashSet<string> loggedItemNames = new HashSet<string>();

	private readonly HashSet<string> loggedRes = new HashSet<string>();

	private readonly HashSet<string> loggedGear = new HashSet<string>();

	private static ManualLogSource Log => Plugin.LogSource;

	private float S => Mathf.Clamp(Plugin.Scale.Value, 0.4f, 2f);

	private float Fs => Mathf.Max(6f, Plugin.FontSize.Value * S);

	private float RowH => Mathf.Max(14f, Plugin.RowHeight.Value * S);

	private float BarW => 106f * S;

	private float BarH => 9f * S;

	public TeammateHudBehaviour(IntPtr ptr)
		: base(ptr)
	{
	}

	private void Update()
	{
		//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_0009: Unknown result type (might be due to invalid IL or missing references)
		//IL_000c: Invalid comparison between Unknown and I4
		//IL_000e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0012: Invalid comparison between Unknown and I4
		//IL_002a: Unknown result type (might be due to invalid IL or missing references)
		try
		{
			bool flag = true;
			try
			{
				eFocusState currentState = FocusStateManager.CurrentState;
				flag = (int)currentState == 4 || (int)currentState == 9;
			}
			catch
			{
			}
			if (flag && Input.GetKeyDown(ParseKey(Plugin.ToggleKey.Value)))
			{
				manualVisible = !manualVisible;
				Log.LogInfo((object)("[TeammateHUD] manual toggle -> " + manualVisible));
			}
			if ((Object)(object)PlayerManager.Current == (Object)null)
			{
				Hide();
			}
			else if ((layer != null || TryGetLayer()) && (!((Object)(object)inventoryGo == (Object)null) || ResolveHudRefs()) && (built || Build()))
			{
				bool flag2 = (Object)(object)inventoryGo != (Object)null && inventoryGo.activeInHierarchy;
				bool flag3 = IsMapOpen();
				bool flag4 = manualVisible && flag2 && !flag3;
				int num = (flag4 ? 1 : 0);
				if (lastShow != num)
				{
					lastShow = num;
					Log.LogInfo((object)("[TeammateHUD] visible=" + flag4 + " (gameHud=" + flag2 + " map=" + flag3 + ")"));
				}
				if ((Object)(object)canvasGo != (Object)null && canvasGo.activeSelf != flag4)
				{
					canvasGo.SetActive(flag4);
				}
				if (flag4 && Time.time - lastRefresh >= 0.1f)
				{
					lastRefresh = Time.time;
					Refresh();
				}
			}
		}
		catch (Exception ex)
		{
			ResetAll();
			if (Time.time - lastErrLog > 5f)
			{
				lastErrLog = Time.time;
				Log.LogWarning((object)("[TeammateHUD] update error: " + ex));
			}
		}
	}

	private void Hide()
	{
		if ((Object)(object)canvasGo != (Object)null && canvasGo.activeSelf)
		{
			canvasGo.SetActive(false);
		}
	}

	private void ResetAll()
	{
		built = false;
		layer = null;
		inventory = null;
		inventoryGo = null;
		rows.Clear();
		try
		{
			if ((Object)(object)canvasGo != (Object)null)
			{
				Object.Destroy((Object)(object)canvasGo);
			}
		}
		catch
		{
		}
		canvasGo = null;
		contentGo = null;
	}

	private static KeyCode ParseKey(string s)
	{
		//IL_0013: Unknown result type (might be due to invalid IL or missing references)
		if (string.IsNullOrEmpty(s) || !Enum.TryParse<KeyCode>(s, ignoreCase: true, out KeyCode result))
		{
			return (KeyCode)289;
		}
		return result;
	}

	private bool TryGetLayer()
	{
		try
		{
			GuiManager current = GuiManager.Current;
			if ((Object)(object)current == (Object)null)
			{
				return false;
			}
			layer = current.m_playerLayer;
			return layer != null;
		}
		catch
		{
			return false;
		}
	}

	private bool ResolveHudRefs()
	{
		try
		{
			if (layer == null)
			{
				return false;
			}
			inventory = layer.Inventory;
			inventoryGo = (((Object)(object)inventory != (Object)null) ? ((Component)inventory).gameObject : null);
			return (Object)(object)inventoryGo != (Object)null;
		}
		catch (Exception ex)
		{
			Log.LogWarning((object)("[TeammateHUD] resolve HUD refs failed: " + ex.Message));
			return false;
		}
	}

	private bool Build()
	{
		//IL_00a5: Unknown result type (might be due to invalid IL or missing references)
		//IL_00af: Expected O, but got Unknown
		//IL_00e8: 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_013d: Expected O, but got Unknown
		//IL_016f: 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_0199: 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_01db: Unknown result type (might be due to invalid IL or missing references)
		//IL_0327: Unknown result type (might be due to invalid IL or missing references)
		//IL_0331: Expected O, but got Unknown
		//IL_0365: Unknown result type (might be due to invalid IL or missing references)
		//IL_037a: Unknown result type (might be due to invalid IL or missing references)
		//IL_038f: Unknown result type (might be due to invalid IL or missing references)
		//IL_03ac: Unknown result type (might be due to invalid IL or missing references)
		//IL_03c6: Unknown result type (might be due to invalid IL or missing references)
		//IL_040e: Unknown result type (might be due to invalid IL or missing references)
		//IL_045a: Unknown result type (might be due to invalid IL or missing references)
		//IL_04af: Unknown result type (might be due to invalid IL or missing references)
		//IL_04f0: Unknown result type (might be due to invalid IL or missing references)
		//IL_053c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0588: Unknown result type (might be due to invalid IL or missing references)
		//IL_05d4: Unknown result type (might be due to invalid IL or missing references)
		//IL_0620: Unknown result type (might be due to invalid IL or missing references)
		//IL_066c: Unknown result type (might be due to invalid IL or missing references)
		//IL_02e2: Unknown result type (might be due to invalid IL or missing references)
		if ((Object)(object)inventoryGo == (Object)null && !ResolveHudRefs())
		{
			return false;
		}
		Material mat = null;
		float srcSize = 0f;
		font = FindFont(out mat, out srcSize);
		if ((Object)(object)font == (Object)null)
		{
			if (!loggedFont)
			{
				loggedFont = true;
				Log.LogWarning((object)"[TeammateHUD] HUD font not found");
			}
			return false;
		}
		fontMat = mat;
		if (!loggedFont)
		{
			loggedFont = true;
			Log.LogInfo((object)("[TeammateHUD] font=" + ((Object)font).name + " srcSize=" + srcSize));
		}
		canvasGo = new GameObject("TeammateHUD_Canvas");
		Canvas obj = canvasGo.AddComponent<Canvas>();
		obj.renderMode = (RenderMode)0;
		obj.sortingOrder = 32000;
		CanvasScaler obj2 = canvasGo.AddComponent<CanvasScaler>();
		obj2.uiScaleMode = (ScaleMode)1;
		obj2.referenceResolution = new Vector2(1920f, 1080f);
		obj2.screenMatchMode = (ScreenMatchMode)0;
		obj2.matchWidthOrHeight = 1f;
		canvasGo.AddComponent<CanvasGroup>().alpha = Mathf.Clamp01(Plugin.Opacity.Value);
		Object.DontDestroyOnLoad((Object)(object)canvasGo);
		contentGo = new GameObject("rows");
		contentGo.transform.SetParent(canvasGo.transform, false);
		RectTransform obj3 = contentGo.AddComponent<RectTransform>();
		obj3.anchorMin = new Vector2(0f, 1f);
		obj3.anchorMax = new Vector2(0f, 1f);
		obj3.pivot = new Vector2(0f, 1f);
		obj3.sizeDelta = new Vector2(596f * S, 230f * S);
		obj3.anchoredPosition = new Vector2(Plugin.OffsetX.Value, 0f - Plugin.OffsetY.Value);
		float fs = Fs;
		if (Plugin.ShowHeaders.Value)
		{
			string[] array = new string[5] { "HP", "PRI", "SEC", "TOOL", "RES" };
			float[] array2 = new float[5] { 310f, 362f, 414f, 466f, 524f };
			float[] array3 = new float[5] { 72f, 48f, 48f, 48f, 84f };
			for (int i = 0; i < array.Length; i++)
			{
				((TMP_Text)MakeText(contentGo.transform, "h" + i, (array2[i] - array3[i] * 0.5f) * S, 0f - RowH + 2f * S, array3[i] * S, RowH, fs * 0.75f, (TextAlignmentOptions)514, new Color(ColGrey.r, ColGrey.g, ColGrey.b, 0.6f))).text = array[i];
			}
		}
		for (int j = 0; j < 4; j++)
		{
			Row row = new Row();
			row.go = new GameObject("row" + j);
			row.go.transform.SetParent(contentGo.transform, false);
			RectTransform obj4 = row.go.AddComponent<RectTransform>();
			obj4.anchorMin = new Vector2(0f, 1f);
			obj4.anchorMax = new Vector2(0f, 1f);
			obj4.pivot = new Vector2(0f, 1f);
			obj4.sizeDelta = new Vector2(596f * S, RowH);
			obj4.anchoredPosition = new Vector2(0f, (float)(-j) * RowH);
			row.square = MakeRaw(row.go.transform, "sq", 13f * S, RowH, 10f * S, 10f * S, Color.white);
			row.name = MakeText(row.go.transform, "name", 31f * S, 0f, 124f * S, RowH, fs, (TextAlignmentOptions)513, ColWhite);
			row.barBg = MakeRaw(row.go.transform, "barbg", 161f * S, RowH, BarW, BarH, new Color(0f, 0f, 0f, 0.65f));
			row.barFill = MakeRaw(row.go.transform, "barfill", 161f * S, RowH, BarW, BarH, ColWhite);
			row.hp = MakeText(row.go.transform, "hp", 274f * S, 0f, 72f * S, RowH, fs, (TextAlignmentOptions)514, ColWhite);
			row.ammoStd = MakeText(row.go.transform, "a1", 338f * S, 0f, 48f * S, RowH, fs, (TextAlignmentOptions)514, ColWhite);
			row.ammoSpl = MakeText(row.go.transform, "a2", 390f * S, 0f, 48f * S, RowH, fs, (TextAlignmentOptions)514, ColWhite);
			row.ammoCls = MakeText(row.go.transform, "a3", 442f * S, 0f, 48f * S, RowH, fs, (TextAlignmentOptions)514, ColWhite);
			row.res = MakeText(row.go.transform, "res", 482f * S, 0f, 84f * S, RowH, fs, (TextAlignmentOptions)514, ColWhite);
			row.go.SetActive(false);
			rows.Add(row);
		}
		built = true;
		Log.LogInfo((object)("[TeammateHUD] UI built, scale=" + S));
		return true;
	}

	private TMP_FontAsset FindFont(out Material mat, out float srcSize)
	{
		mat = null;
		srcSize = 0f;
		try
		{
			if (layer != null)
			{
				PUI_TeammateStatusItem s_teammate = PlayerGuiLayer.s_teammate;
				if ((Object)(object)s_teammate != (Object)null)
				{
					TextMeshProUGUI healthText = s_teammate.m_healthText;
					if ((Object)(object)healthText != (Object)null && (Object)(object)((TMP_Text)healthText).font != (Object)null)
					{
						mat = ((TMP_Text)healthText).fontSharedMaterial;
						srcSize = ((TMP_Text)healthText).fontSize;
						return ((TMP_Text)healthText).font;
					}
				}
				PUI_LocalPlayerStatus playerStatus = layer.m_playerStatus;
				if ((Object)(object)playerStatus != (Object)null)
				{
					TextMeshPro healthText2 = playerStatus.m_healthText;
					if ((Object)(object)healthText2 != (Object)null && (Object)(object)((TMP_Text)healthText2).font != (Object)null)
					{
						mat = ((TMP_Text)healthText2).fontSharedMaterial;
						srcSize = ((TMP_Text)healthText2).fontSize;
						return ((TMP_Text)healthText2).font;
					}
				}
				PUI_Inventory val = layer.Inventory;
				if ((Object)(object)val != (Object)null)
				{
					TextMeshPro headerTxt = val.m_headerTxt;
					if ((Object)(object)headerTxt != (Object)null && (Object)(object)((TMP_Text)headerTxt).font != (Object)null)
					{
						mat = ((TMP_Text)headerTxt).fontSharedMaterial;
						srcSize = ((TMP_Text)headerTxt).fontSize;
						return ((TMP_Text)headerTxt).font;
					}
				}
			}
		}
		catch (Exception ex)
		{
			Log.LogWarning((object)("[TeammateHUD] hud font lookup failed: " + ex.Message));
		}
		try
		{
			TMP_FontAsset defaultFontAsset = TMP_Settings.defaultFontAsset;
			if ((Object)(object)defaultFontAsset != (Object)null)
			{
				return defaultFontAsset;
			}
		}
		catch
		{
		}
		return null;
	}

	private bool IsMapOpen()
	{
		try
		{
			if ((Object)(object)mapPage == (Object)null && Time.time - lastMapScan > 3f)
			{
				lastMapScan = Time.time;
				Il2CppReferenceArray<Object> val = Resources.FindObjectsOfTypeAll(Il2CppType.Of<CM_PageMap>());
				if (val != null)
				{
					for (int i = 0; i < ((Il2CppArrayBase<Object>)(object)val).Length; i++)
					{
						Object val2 = ((Il2CppArrayBase<Object>)(object)val)[i];
						if (!(val2 == (Object)null))
						{
							Component val3 = ((Il2CppObjectBase)val2).TryCast<Component>();
							if (!((Object)(object)val3 == (Object)null))
							{
								mapPage = val3.gameObject;
								break;
							}
						}
					}
				}
			}
			return (Object)(object)mapPage != (Object)null && mapPage.activeInHierarchy;
		}
		catch
		{
			return false;
		}
	}

	private void Refresh()
	{
		//IL_02cc: Unknown result type (might be due to invalid IL or missing references)
		//IL_02ed: Unknown result type (might be due to invalid IL or missing references)
		//IL_0290: Unknown result type (might be due to invalid IL or missing references)
		//IL_0295: Unknown result type (might be due to invalid IL or missing references)
		//IL_0394: Unknown result type (might be due to invalid IL or missing references)
		//IL_03a5: Unknown result type (might be due to invalid IL or missing references)
		//IL_03c6: Unknown result type (might be due to invalid IL or missing references)
		//IL_040a: Unknown result type (might be due to invalid IL or missing references)
		//IL_041b: Unknown result type (might be due to invalid IL or missing references)
		//IL_042c: 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_02ad: Unknown result type (might be due to invalid IL or missing references)
		//IL_02b2: Unknown result type (might be due to invalid IL or missing references)
		//IL_047d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0482: Unknown result type (might be due to invalid IL or missing references)
		//IL_04b7: Unknown result type (might be due to invalid IL or missing references)
		//IL_04c5: Unknown result type (might be due to invalid IL or missing references)
		//IL_04f1: Unknown result type (might be due to invalid IL or missing references)
		//IL_0476: Unknown result type (might be due to invalid IL or missing references)
		//IL_046f: Unknown result type (might be due to invalid IL or missing references)
		if ((Object)(object)PlayerManager.Current == (Object)null)
		{
			return;
		}
		List<PlayerAgent> playerAgentsInLevel = PlayerManager.PlayerAgentsInLevel;
		List<PlayerAgent> list = new List<PlayerAgent>();
		if (playerAgentsInLevel != null)
		{
			for (int i = 0; i < playerAgentsInLevel.Count; i++)
			{
				PlayerAgent val = playerAgentsInLevel[i];
				if ((Object)(object)val != (Object)null)
				{
					list.Add(val);
				}
			}
		}
		list.Sort(delegate(PlayerAgent a, PlayerAgent b)
		{
			int num9 = ((!((Agent)a).IsLocallyOwned) ? 1 : 0);
			int num10 = ((!((Agent)b).IsLocallyOwned) ? 1 : 0);
			return (num9 != num10) ? (num9 - num10) : a.PlayerSlotIndex.CompareTo(b.PlayerSlotIndex);
		});
		PlayerAgent val2 = null;
		for (int num = 0; num < list.Count; num++)
		{
			if (((Agent)list[num]).IsLocallyOwned)
			{
				val2 = list[num];
				break;
			}
		}
		if (!loggedLocalAmmo && (Object)(object)val2 != (Object)null)
		{
			loggedLocalAmmo = true;
			LogAmmoSet(val2, "local");
		}
		list.RemoveAll((PlayerAgent p) => ((Agent)p).IsLocallyOwned);
		if (!loggedRemoteAmmo && list.Count > 0)
		{
			loggedRemoteAmmo = true;
			LogAmmoSet(list[0], "remote");
		}
		if (!loggedRoster && list.Count > 0)
		{
			loggedRoster = true;
			for (int num2 = 0; num2 < list.Count; num2++)
			{
				PlayerAgent val3 = list[num2];
				string text = "[TeammateHUD] roster[" + num2 + "] name=" + val3.PlayerName + " local=" + ((Agent)val3).IsLocallyOwned + " slot=" + val3.PlayerSlotIndex + " alive=" + ((Agent)val3).Alive;
				try
				{
					Dam_PlayerDamageBase damage = val3.Damage;
					if ((Object)(object)damage != (Object)null)
					{
						text = text + " hp=" + ((Dam_SyncedDamageBase)damage).Health + "/" + ((Dam_SyncedDamageBase)damage).HealthMax;
					}
				}
				catch
				{
				}
				Log.LogInfo((object)text);
			}
		}
		for (int num3 = 0; num3 < rows.Count; num3++)
		{
			Row row = rows[num3];
			if (num3 >= list.Count)
			{
				row.go.SetActive(false);
				continue;
			}
			PlayerAgent val4 = list[num3];
			row.go.SetActive(true);
			Color color = ColWhite;
			try
			{
				if ((Object)(object)val4.Owner != (Object)null)
				{
					color = val4.Owner.PlayerColor;
				}
			}
			catch
			{
			}
			color.a = 1f;
			((Graphic)row.square).color = color;
			((TMP_Text)row.name).text = val4.PlayerName;
			((Graphic)row.name).color = color;
			float num4 = 0f;
			float num5 = 1f;
			bool flag = false;
			try
			{
				Dam_PlayerDamageBase damage2 = val4.Damage;
				if ((Object)(object)damage2 != (Object)null)
				{
					num4 = ((Dam_SyncedDamageBase)damage2).Health;
					num5 = ((Dam_SyncedDamageBase)damage2).HealthMax;
					flag = true;
				}
			}
			catch
			{
			}
			if (num5 <= 0.01f)
			{
				num5 = 1f;
			}
			int num6;
			float num7;
			if (((Agent)val4).Alive)
			{
				if (flag)
				{
					num6 = ((num4 <= 0.01f) ? 1 : 0);
					if (num6 != 0)
					{
						goto IL_0370;
					}
				}
				else
				{
					num6 = 0;
				}
				num7 = Mathf.Clamp01(num4 / num5);
				goto IL_0375;
			}
			num6 = 1;
			goto IL_0370;
			IL_0375:
			float num8 = num7;
			if (num6 != 0)
			{
				((TMP_Text)row.hp).text = "DOWN";
				((Graphic)row.hp).color = ColRed;
				((Graphic)row.name).color = ColRed;
				((Graphic)row.barFill).rectTransform.sizeDelta = new Vector2(0f, BarH);
				((TMP_Text)row.ammoStd).text = "-";
				((TMP_Text)row.ammoSpl).text = "-";
				((TMP_Text)row.ammoCls).text = "-";
				((Graphic)row.ammoStd).color = ColGrey;
				((Graphic)row.ammoSpl).color = ColGrey;
				((Graphic)row.ammoCls).color = ColGrey;
				((TMP_Text)row.res).text = "";
				((Graphic)row.res).color = ColGrey;
				continue;
			}
			Color color2 = ((num8 >= 0.6f) ? ColWhite : ((num8 >= 0.3f) ? ColAmber : ColRed));
			((TMP_Text)row.hp).text = Mathf.RoundToInt(num8 * 100f) + "%";
			((Graphic)row.hp).color = color2;
			((Graphic)row.barFill).color = color2;
			((Graphic)row.barFill).rectTransform.sizeDelta = new Vector2(Mathf.Max(0f, BarW * num8), BarH);
			PlayerBackpack val5 = null;
			try
			{
				if ((Object)(object)val4.Owner != (Object)null)
				{
					val5 = PlayerBackpackManager.GetBackpack(val4.Owner);
				}
			}
			catch
			{
			}
			PlayerAmmoStorage store = ((val5 != null) ? val5.AmmoStorage : null);
			ItemDataBlock gearDataBlock = GetGearDataBlock(val5, (InventorySlot)3);
			SetAmmo(store, (InventorySlot)1, row.ammoStd);
			SetAmmo(store, (InventorySlot)2, row.ammoSpl);
			SetAmmo(store, (InventorySlot)3, row.ammoCls, gearDataBlock);
			SetResource(row, val4);
			continue;
			IL_0370:
			num7 = 0f;
			goto IL_0375;
		}
	}

	private static Color AmmoColor(float pct)
	{
		//IL_0008: 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)
		//IL_0016: Unknown result type (might be due to invalid IL or missing references)
		if (pct < 30f)
		{
			return ColRed;
		}
		if (pct < 55f)
		{
			return ColAmber;
		}
		return ColWhite;
	}

	private void LogAmmoSet(PlayerAgent a, string tag)
	{
		try
		{
			PlayerBackpack val = (((Object)(object)a.Owner != (Object)null) ? PlayerBackpackManager.GetBackpack(a.Owner) : null);
			PlayerAmmoStorage val2 = ((val != null) ? val.AmmoStorage : null);
			if (val2 == null)
			{
				Log.LogInfo((object)("[TeammateHUD] ammo[" + tag + "] store=null"));
				return;
			}
			InventorySlot[] array = new InventorySlot[3];
			RuntimeHelpers.InitializeArray(array, (RuntimeFieldHandle)/*OpCode not supported: LdMemberToken*/);
			InventorySlot[] array2 = (InventorySlot[])(object)array;
			for (int i = 0; i < array2.Length; i++)
			{
				InventorySlotAmmo inventorySlotAmmo = val2.GetInventorySlotAmmo(array2[i]);
				if (inventorySlotAmmo != null)
				{
					float num = 0f;
					try
					{
						num = val2.GetClipAmmoFromSlot(array2[i]);
					}
					catch
					{
					}
					Log.LogInfo((object)("[TeammateHUD] ammo[" + tag + "] slot=" + ((object)Unsafe.As<InventorySlot, InventorySlot>(ref array2[i])/*cast due to .constrained prefix*/).ToString() + " clip=" + num + " pack=" + inventorySlotAmmo.BulletsInPack + " clipSize=" + inventorySlotAmmo.BulletClipSize + " packMax=" + inventorySlotAmmo.BulletsMaxCap + " ammoInPack=" + inventorySlotAmmo.AmmoInPack + " ammoMaxCap=" + inventorySlotAmmo.AmmoMaxCap + " relInPack=" + inventorySlotAmmo.RelInPack + " bulletsRelInPack=" + inventorySlotAmmo.BulletsRelInPack));
				}
			}
		}
		catch (Exception ex)
		{
			Log.LogWarning((object)("[TeammateHUD] ammo log failed: " + ex.Message));
		}
	}

	private void SetAmmo(PlayerAmmoStorage store, InventorySlot slot, TextMeshProUGUI t, ItemDataBlock gearDb = null)
	{
		//IL_018d: Unknown result type (might be due to invalid IL or missing references)
		//IL_000f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0174: Unknown result type (might be due to invalid IL or missing references)
		//IL_00ab: Unknown result type (might be due to invalid IL or missing references)
		//IL_0026: 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_0041: 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_009b: Unknown result type (might be due to invalid IL or missing references)
		//IL_010a: Unknown result type (might be due to invalid IL or missing references)
		if (store == null)
		{
			((TMP_Text)t).text = "--";
			((Graphic)t).color = ColGrey;
			return;
		}
		try
		{
			if (gearDb != null)
			{
				LogGearOnce(gearDb, store, slot);
				if (IsBioTool(gearDb))
				{
					((TMP_Text)t).text = "BIO";
					((Graphic)t).color = ColWhite;
					return;
				}
				if (gearDb.GUIShowAmmoInfinite)
				{
					((TMP_Text)t).text = "∞";
					((Graphic)t).color = ColGrey;
					return;
				}
				if (!gearDb.GUIShowAmmoClip && !gearDb.GUIShowAmmoPack && !gearDb.GUIShowAmmoTotalRel)
				{
					((TMP_Text)t).text = "";
					((Graphic)t).color = ColGrey;
					return;
				}
			}
			InventorySlotAmmo inventorySlotAmmo = store.GetInventorySlotAmmo(slot);
			if (inventorySlotAmmo == null || inventorySlotAmmo.BulletsMaxCap <= 0)
			{
				((TMP_Text)t).text = "∞";
				((Graphic)t).color = ColGrey;
				return;
			}
			float relInPack = inventorySlotAmmo.RelInPack;
			float num = ((relInPack <= 1.001f) ? (relInPack * 100f) : relInPack);
			if (num <= 0.01f || num > 100f)
			{
				float num2 = 0f;
				try
				{
					num2 = store.GetClipAmmoFromSlot(slot);
				}
				catch
				{
				}
				float num3 = inventorySlotAmmo.BulletClipSize + inventorySlotAmmo.BulletsMaxCap;
				if (num3 > 0.01f)
				{
					num = (num2 + (float)inventorySlotAmmo.BulletsInPack) / num3 * 100f;
				}
			}
			num = Mathf.Clamp(num, 0f, 100f);
			((TMP_Text)t).text = Mathf.RoundToInt(num) + "%";
			((Graphic)t).color = AmmoColor(num);
		}
		catch
		{
			((TMP_Text)t).text = "--";
			((Graphic)t).color = ColGrey;
		}
	}

	private static ItemDataBlock GetGearDataBlock(PlayerBackpack bp, InventorySlot slot)
	{
		//IL_0007: 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_0079: Unknown result type (might be due to invalid IL or missing references)
		if (bp == null)
		{
			return null;
		}
		try
		{
			BackpackItem val = default(BackpackItem);
			if (bp.TryGetBackpackItem(slot, ref val) && val != null && (Object)(object)val.Instance != (Object)null)
			{
				return val.Instance.ItemDataBlock;
			}
		}
		catch
		{
		}
		try
		{
			List<BackpackItem> backpackItems = bp.BackpackItems;
			if (backpackItems != null)
			{
				for (int i = 0; i < backpackItems.Count; i++)
				{
					BackpackItem val2 = backpackItems[i];
					if (val2 != null && !((Object)(object)val2.Instance == (Object)null))
					{
						ItemDataBlock itemDataBlock = val2.Instance.ItemDataBlock;
						if (itemDataBlock != null && itemDataBlock.inventorySlot == slot)
						{
							return itemDataBlock;
						}
					}
				}
			}
		}
		catch
		{
		}
		return null;
	}

	private static bool IsBioTool(ItemDataBlock db)
	{
		try
		{
			string publicName = db.publicName;
			if (string.IsNullOrEmpty(publicName))
			{
				return false;
			}
			string text = publicName.ToLowerInvariant();
			return text.Contains("bio") || text.Contains("tracker") || text.Contains("scan");
		}
		catch
		{
			return false;
		}
	}

	private unsafe void LogGearOnce(ItemDataBlock db, PlayerAmmoStorage store, InventorySlot slot)
	{
		//IL_00d6: Unknown result type (might be due to invalid IL or missing references)
		try
		{
			string publicName = db.publicName;
			string item = ((publicName == null) ? "?" : publicName) + "|" + ((object)(*(InventorySlot*)(&slot))/*cast due to .constrained prefix*/).ToString();
			if (!loggedGear.Add(item))
			{
				return;
			}
			string text = "[TeammateHUD] tool gear slot=" + ((object)(*(InventorySlot*)(&slot))/*cast due to .constrained prefix*/).ToString() + " name=" + publicName + " clip=" + db.GUIShowAmmoClip + " pack=" + db.GUIShowAmmoPack + " rel=" + db.GUIShowAmmoTotalRel + " inf=" + db.GUIShowAmmoInfinite;
			try
			{
				InventorySlotAmmo inventorySlotAmmo = store.GetInventorySlotAmmo(slot);
				if (inventorySlotAmmo != null)
				{
					text = text + " ammoMaxCap=" + inventorySlotAmmo.BulletsMaxCap + " relInPack=" + inventorySlotAmmo.RelInPack + " bulletsInPack=" + inventorySlotAmmo.BulletsInPack;
				}
			}
			catch
			{
			}
			Log.LogInfo((object)text);
		}
		catch
		{
		}
	}

	private void SetResource(Row r, PlayerAgent a)
	{
		//IL_0016: 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_01ba: Unknown result type (might be due to invalid IL or missing references)
		//IL_01bf: Unknown result type (might be due to invalid IL or missing references)
		//IL_01d2: Unknown result type (might be due to invalid IL or missing references)
		//IL_01d7: Unknown result type (might be due to invalid IL or missing references)
		//IL_01e8: Unknown result type (might be due to invalid IL or missing references)
		//IL_01ed: Unknown result type (might be due to invalid IL or missing references)
		//IL_01fe: Unknown result type (might be due to invalid IL or missing references)
		//IL_0203: Unknown result type (might be due to invalid IL or missing references)
		//IL_0216: Unknown result type (might be due to invalid IL or missing references)
		//IL_021b: Unknown result type (might be due to invalid IL or missing references)
		((TMP_Text)r.res).text = "";
		((Graphic)r.res).color = ColGrey;
		try
		{
			if ((Object)(object)a.Owner == (Object)null)
			{
				return;
			}
			PlayerBackpack backpack = PlayerBackpackManager.GetBackpack(a.Owner);
			if (backpack == null)
			{
				return;
			}
			int num = 0;
			int num2 = 0;
			int num3 = 0;
			int num4 = 0;
			List<BackpackItem> backpackItems = backpack.BackpackItems;
			if (backpackItems != null)
			{
				for (int i = 0; i < backpackItems.Count; i++)
				{
					BackpackItem val = backpackItems[i];
					if (val == null)
					{
						continue;
					}
					Item instance = val.Instance;
					if ((Object)(object)instance == (Object)null)
					{
						continue;
					}
					ItemDataBlock itemDataBlock = instance.ItemDataBlock;
					if (itemDataBlock == null)
					{
						continue;
					}
					string publicName = itemDataBlock.publicName;
					if (!string.IsNullOrEmpty(publicName))
					{
						string text = publicName.ToLowerInvariant();
						string text2 = null;
						if (text.Contains("ammo"))
						{
							num++;
							text2 = "AM";
						}
						else if (text.Contains("health") || text.Contains("med") || text.Contains("heal"))
						{
							num2++;
							text2 = "HP";
						}
						else if (text.Contains("tool"))
						{
							num3++;
							text2 = "TO";
						}
						else if (text.Contains("disinfect") || text.Contains("disinf") || text.Contains("sanit"))
						{
							num4++;
							text2 = "DI";
						}
						if (text2 != null && loggedItemNames.Add(publicName + "|" + text2))
						{
							Log.LogInfo((object)("[TeammateHUD] resource item name=" + publicName + " -> " + text2));
						}
					}
				}
			}
			string text3 = null;
			Color color = ColGrey;
			int num5 = 0;
			if (num > 0)
			{
				text3 = "AM";
				num5 = num;
				color = ColRed;
			}
			if (num2 > num5)
			{
				text3 = "HP";
				num5 = num2;
				color = ColGreen;
			}
			if (num3 > num5)
			{
				text3 = "TO";
				num5 = num3;
				color = ColCyan;
			}
			if (num4 > num5)
			{
				text3 = "DI";
				num5 = num4;
				color = ColPurple;
			}
			if (text3 == null)
			{
				return;
			}
			float num6 = 0f;
			try
			{
				PlayerAmmoStorage ammoStorage = backpack.AmmoStorage;
				if (ammoStorage != null)
				{
					InventorySlotAmmo resourcePackAmmo = ammoStorage.ResourcePackAmmo;
					if (resourcePackAmmo != null)
					{
						num6 = resourcePackAmmo.RelInPack;
						if (num6 <= 0.0001f && resourcePackAmmo.AmmoMaxCap > 0.01f)
						{
							num6 = resourcePackAmmo.AmmoInPack / resourcePackAmmo.AmmoMaxCap;
						}
						if (!loggedRes.Contains(text3))
						{
							loggedRes.Add(text3);
							Log.LogInfo((object)("[TeammateHUD] res type=" + text3 + " rel=" + num6 + " inPack=" + resourcePackAmmo.AmmoInPack + " maxCap=" + resourcePackAmmo.AmmoMaxCap + " itemCount=" + num5));
						}
					}
				}
			}
			catch (Exception ex)
			{
				Log.LogWarning((object)("[TeammateHUD] res ammo read failed: " + ex.Message));
			}
			if (!(num6 <= 0.001f))
			{
				int num7 = Mathf.Clamp(Mathf.RoundToInt(num6 * 5f), 1, 6);
				((TMP_Text)r.res).text = text3 + " " + num7;
				((Graphic)r.res).color = color;
			}
		}
		catch
		{
		}
	}

	private TextMeshProUGUI MakeText(Transform parent, string name, float x, float yDown, float w, float h, float size, TextAlignmentOptions align, Color color)
	{
		//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_0013: 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_0039: Unknown result type (might be due to invalid IL or missing references)
		//IL_004e: Unknown result type (might be due to invalid IL or missing references)
		//IL_005d: Unknown result type (might be due to invalid IL or missing references)
		//IL_006b: 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_00ce: Unknown result type (might be due to invalid IL or missing references)
		GameObject val = new GameObject(name);
		val.transform.SetParent(parent, false);
		RectTransform obj = val.AddComponent<RectTransform>();
		obj.anchorMin = new Vector2(0f, 1f);
		obj.anchorMax = new Vector2(0f, 1f);
		obj.pivot = new Vector2(0f, 1f);
		obj.sizeDelta = new Vector2(w, h);
		obj.anchoredPosition = new Vector2(x, 0f - yDown);
		TextMeshProUGUI val2 = val.AddComponent<TextMeshProUGUI>();
		if ((Object)(object)font != (Object)null)
		{
			((TMP_Text)val2).font = font;
		}
		if ((Object)(object)fontMat != (Object)null)
		{
			((TMP_Text)val2).fontSharedMaterial = fontMat;
		}
		((TMP_Text)val2).fontSize = size;
		((TMP_Text)val2).alignment = align;
		((TMP_Text)val2).enableWordWrapping = false;
		((Graphic)val2).raycastTarget = false;
		((Graphic)val2).color = color;
		return val2;
	}

	private RawImage MakeRaw(Transform parent, string name, float x, float rowH, float w, float h, Color c)
	{
		//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_0013: 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_0039: Unknown result type (might be due to invalid IL or missing references)
		//IL_004e: Unknown result type (might be due to invalid IL or missing references)
		//IL_005d: 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_008c: Unknown result type (might be due to invalid IL or missing references)
		GameObject val = new GameObject(name);
		val.transform.SetParent(parent, false);
		RectTransform obj = val.AddComponent<RectTransform>();
		obj.anchorMin = new Vector2(0f, 1f);
		obj.anchorMax = new Vector2(0f, 1f);
		obj.pivot = new Vector2(0f, 0.5f);
		obj.sizeDelta = new Vector2(w, h);
		obj.anchoredPosition = new Vector2(x, (0f - rowH) * 0.5f);
		RawImage obj2 = val.AddComponent<RawImage>();
		obj2.texture = (Texture)(object)Texture2D.whiteTexture;
		((Graphic)obj2).color = c;
		((Graphic)obj2).raycastTarget = false;
		return obj2;
	}
}