Decompiled source of PlayersInfo v0.1.1

PlayersInfo.dll

Decompiled 2 weeks ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.Globalization;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using System.Text;
using BepInEx;
using BepInEx.Bootstrap;
using BepInEx.Configuration;
using BepInEx.Logging;
using DG.Tweening;
using HarmonyLib;
using Microsoft.CodeAnalysis;
using Photon.Pun;
using PlayersInfo.Helpers;
using PlayersInfo.MonoBehaviours;
using PlayersInfo.Patches;
using TMPro;
using UnityEngine;
using UnityEngine.SceneManagement;
using UnityEngine.UI;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: AssemblyTitle("PlayersInfo")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("P R C")]
[assembly: AssemblyProduct("PlayersInfo")]
[assembly: AssemblyCopyright("Copyright © P R C 2026")]
[assembly: AssemblyTrademark("")]
[assembly: ComVisible(false)]
[assembly: Guid("ea6b8f7a-e2d5-4b3e-9025-f87255eeac89")]
[assembly: AssemblyFileVersion("0.1.1.0")]
[assembly: TargetFramework(".NETFramework,Version=v4.7.2", FrameworkDisplayName = ".NET Framework 4.7.2")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("0.1.1.0")]
[module: UnverifiableCode]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	[AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)]
	internal sealed class RefSafetyRulesAttribute : Attribute
	{
		public readonly int Version;

		public RefSafetyRulesAttribute(int P_0)
		{
			Version = P_0;
		}
	}
}
namespace PlayersInfo
{
	[BepInPlugin("com.players.info", "PlayersInfo", "0.1.1")]
	public class PlayersInfoPlugin : BaseUnityPlugin
	{
		public enum HudAnchor
		{
			TopLeft,
			TopRight,
			BottomLeft,
			BottomRight
		}

		[CompilerGenerated]
		private sealed class <DeferredLanguageRefresh>d__28 : IEnumerator<object>, IDisposable, IEnumerator
		{
			private int <>1__state;

			private object <>2__current;

			public PlayersInfoPlugin <>4__this;

			object IEnumerator<object>.Current
			{
				[DebuggerHidden]
				get
				{
					return <>2__current;
				}
			}

			object IEnumerator.Current
			{
				[DebuggerHidden]
				get
				{
					return <>2__current;
				}
			}

			[DebuggerHidden]
			public <DeferredLanguageRefresh>d__28(int <>1__state)
			{
				this.<>1__state = <>1__state;
			}

			[DebuggerHidden]
			void IDisposable.Dispose()
			{
				<>1__state = -2;
			}

			private bool MoveNext()
			{
				//IL_0024: Unknown result type (might be due to invalid IL or missing references)
				//IL_002e: Expected O, but got Unknown
				int num = <>1__state;
				PlayersInfoPlugin playersInfoPlugin = <>4__this;
				switch (num)
				{
				default:
					return false;
				case 0:
					<>1__state = -1;
					<>2__current = (object)new WaitForSeconds(8f);
					<>1__state = 1;
					return true;
				case 1:
				{
					<>1__state = -1;
					bool flag = LanguageHelper.DetectChineseLanguage();
					if (flag == LanguageHelper.IsChinese)
					{
						return false;
					}
					LanguageHelper.IsChinese = flag;
					ModConfigLocalization.ApplyLocalizedDescriptions();
					try
					{
						((BaseUnityPlugin)playersInfoPlugin).Config.Save();
					}
					catch
					{
					}
					ModConfigLocalization.RefreshCache();
					PluginLogger.Info("Config descriptions updated to " + (LanguageHelper.IsChinese ? "Chinese" : "English") + ".");
					return false;
				}
				}
			}

			bool IEnumerator.MoveNext()
			{
				//ILSpy generated this explicit interface implementation from .override directive in MoveNext
				return this.MoveNext();
			}

			[DebuggerHidden]
			void IEnumerator.Reset()
			{
				throw new NotSupportedException();
			}
		}

		public const string PluginGuid = "com.players.info";

		public const string PluginName = "PlayersInfo";

		public const string PluginVersion = "0.1.1";

		public static ConfigEntry<bool> CfgModEnabled;

		public static ConfigEntry<bool> CfgEnableStaminaBar;

		public static ConfigEntry<bool> CfgShowStaminaValue;

		public static ConfigEntry<bool> CfgEnableInventoryRow;

		public static ConfigEntry<HudAnchor> CfgAnchor;

		public static ConfigEntry<float> CfgOffsetX;

		public static ConfigEntry<float> CfgOffsetY;

		public static ConfigEntry<float> CfgNearbyRange;

		public static ConfigEntry<int> CfgMaxNearbyCount;

		public static ConfigEntry<bool> CfgRoundStamina;

		public static ConfigEntry<bool> CfgDebugLogging;

		private Harmony _harmony;

		private float _nextSafeTick;

		private const float SafeTickInterval = 1f;

		private const string DisplaySection = "Display";

		private const string AdvancedSection = "Advanced";

		private static readonly FieldInfo OrphanedEntriesField = typeof(ConfigFile).GetField("<OrphanedEntries>k__BackingField", BindingFlags.Instance | BindingFlags.NonPublic);

		private void Awake()
		{
			//IL_0021: Unknown result type (might be due to invalid IL or missing references)
			//IL_002b: Expected O, but got Unknown
			try
			{
				PluginLogger.Log = ((BaseUnityPlugin)this).Logger;
				LanguageHelper.IsChinese = LanguageHelper.DetectChineseLanguage();
				BindConfig();
				_harmony = new Harmony("com.players.info");
				_harmony.PatchAll();
				try
				{
					ModConfigLocalization.PatchDisplayNames(_harmony);
				}
				catch (Exception ex)
				{
					PluginLogger.ThrottleWarn("modconfig_patch", "ModConfig localization patch skipped: " + ex.Message);
				}
				SceneManager.sceneLoaded += OnSceneLoaded;
				((MonoBehaviour)this).StartCoroutine(DeferredLanguageRefresh());
				if (CfgModEnabled.Value)
				{
					TeamRosterTracker.EnsureExists();
				}
				PluginLogger.Info("PlayersInfo v0.1.1 loaded. Lang=" + (LanguageHelper.IsChinese ? "zh" : "en"));
			}
			catch (Exception arg)
			{
				((BaseUnityPlugin)this).Logger.LogError((object)string.Format("[{0}] Awake failed: {1}", "PlayersInfo", arg));
			}
		}

		private void BindConfig()
		{
			//IL_016a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0174: Expected O, but got Unknown
			//IL_01c1: Unknown result type (might be due to invalid IL or missing references)
			//IL_01cb: Expected O, but got Unknown
			//IL_0218: Unknown result type (might be due to invalid IL or missing references)
			//IL_0222: Expected O, but got Unknown
			//IL_0263: Unknown result type (might be due to invalid IL or missing references)
			//IL_026d: Expected O, but got Unknown
			CfgModEnabled = ((BaseUnityPlugin)this).Config.Bind<bool>("Display", "Enabled", ReadLegacyValue("General", "Enabled", fallback: true), LanguageHelper.L("Master switch. Turn off to disable all features.", "总开关,关闭后全部功能失效。"));
			CfgEnableStaminaBar = ((BaseUnityPlugin)this).Config.Bind<bool>("Display", "EnableStaminaBar", ReadLegacyValue("Features", "EnableStaminaBar", fallback: true), LanguageHelper.L("Show teammate stamina bars (with extra stamina).", "显示队友体力条(含临时体力)。"));
			CfgShowStaminaValue = ((BaseUnityPlugin)this).Config.Bind<bool>("Display", "ShowStaminaValue", ReadLegacyValue("Features", "ShowStaminaValue", fallback: true), LanguageHelper.L("Show numeric stamina value on the bar.", "在体力条右侧显示数值。"));
			CfgEnableInventoryRow = ((BaseUnityPlugin)this).Config.Bind<bool>("Display", "EnableInventoryRow", ReadLegacyValue("Features", "EnableInventoryRow", fallback: true), LanguageHelper.L("Show teammate inventory (main 3 + temp + backpack + backpack inner 4).", "显示队友物品栏(主 3 + 临时 + 背包槽 + 背包内部 4 格)。"));
			CfgAnchor = ((BaseUnityPlugin)this).Config.Bind<HudAnchor>("Display", "Anchor", ReadLegacyValue("Layout", "Anchor", HudAnchor.TopLeft), LanguageHelper.L("HUD anchor corner on screen.", "HUD 屏幕锚点位置。"));
			CfgOffsetX = ((BaseUnityPlugin)this).Config.Bind<float>("Display", "OffsetX", ReadLegacyValue("Layout", "OffsetX", 0f), new ConfigDescription(LanguageHelper.L("Additional X offset in pixels.", "X 方向像素偏移。"), (AcceptableValueBase)(object)new AcceptableValueRange<float>(-800f, 800f), Array.Empty<object>()));
			CfgOffsetY = ((BaseUnityPlugin)this).Config.Bind<float>("Display", "OffsetY", ReadLegacyValue("Layout", "OffsetY", 0f), new ConfigDescription(LanguageHelper.L("Additional Y offset in pixels.", "Y 方向像素偏移。"), (AcceptableValueBase)(object)new AcceptableValueRange<float>(-800f, 800f), Array.Empty<object>()));
			CfgNearbyRange = ((BaseUnityPlugin)this).Config.Bind<float>("Display", "NearbyRange", ReadLegacyValue("Nearby", "NearbyRange", 30f), new ConfigDescription(LanguageHelper.L("Max distance (meters) to show a teammate bar. 0 = unlimited.", "显示队友体力条的最大距离(米)。0 表示不限。"), (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 500f), Array.Empty<object>()));
			CfgMaxNearbyCount = ((BaseUnityPlugin)this).Config.Bind<int>("Display", "MaxNearbyCount", ReadLegacyValue("Nearby", "MaxNearbyCount", 3), new ConfigDescription(LanguageHelper.L("Max number of nearest teammates to show bars for.", "最多显示几个最近的队友体力条。"), (AcceptableValueBase)(object)new AcceptableValueRange<int>(0, 8), Array.Empty<object>()));
			CfgRoundStamina = ((BaseUnityPlugin)this).Config.Bind<bool>("Display", "RoundStaminaValue", ReadLegacyValue("Features", "RoundStaminaValue", fallback: true), LanguageHelper.L("If true, round stamina numeric value to nearest integer; else 1 decimal.", "为 true 时体力数值四舍五入到整数,否则显示 1 位小数。"));
			CfgDebugLogging = ((BaseUnityPlugin)this).Config.Bind<bool>("Advanced", "DebugLogging", ReadLegacyValue("Diagnostics", "DebugLogging", fallback: false), LanguageHelper.L("Enable verbose diagnostic logs for distance, stamina, inventory, and cloned UI internals.", "启用详细诊断日志(距离、体力、物品栏和克隆 UI 内部状态)。"));
			ModConfigLocalization.ApplyLocalizedDescriptions();
			RemoveLegacyConfigEntries();
			CfgModEnabled.SettingChanged += OnStructuralConfigChanged;
			CfgEnableStaminaBar.SettingChanged += OnStructuralConfigChanged;
			CfgShowStaminaValue.SettingChanged += OnStructuralConfigChanged;
			CfgEnableInventoryRow.SettingChanged += OnStructuralConfigChanged;
		}

		private T ReadLegacyValue<T>(string section, string key, T fallback)
		{
			//IL_0046: Unknown result type (might be due to invalid IL or missing references)
			//IL_0052: Expected O, but got Unknown
			try
			{
				ConfigEntry<T> val = default(ConfigEntry<T>);
				if (((BaseUnityPlugin)this).Config.TryGetEntry<T>(section, key, ref val))
				{
					return val.Value;
				}
				if (OrphanedEntriesField != null && OrphanedEntriesField.GetValue(((BaseUnityPlugin)this).Config) is Dictionary<ConfigDefinition, string> dictionary && dictionary.TryGetValue(new ConfigDefinition(section, key), out var value))
				{
					if (typeof(T).IsEnum)
					{
						return (T)Enum.Parse(typeof(T), value, ignoreCase: true);
					}
					return (T)Convert.ChangeType(value, typeof(T), CultureInfo.InvariantCulture);
				}
			}
			catch
			{
			}
			return fallback;
		}

		private void RemoveLegacyConfigEntries()
		{
			if ((0u | (RemoveConfigEntry("General", "Enabled") ? 1u : 0u) | (RemoveConfigEntry("Features", "EnableStaminaBar") ? 1u : 0u) | (RemoveConfigEntry("Features", "ShowStaminaValue") ? 1u : 0u) | (RemoveConfigEntry("Features", "EnableInventoryRow") ? 1u : 0u) | (RemoveConfigEntry("Features", "RoundStaminaValue") ? 1u : 0u) | (RemoveConfigEntry("Layout", "Anchor") ? 1u : 0u) | (RemoveConfigEntry("Layout", "OffsetX") ? 1u : 0u) | (RemoveConfigEntry("Layout", "OffsetY") ? 1u : 0u) | (RemoveConfigEntry("Nearby", "NearbyRange") ? 1u : 0u) | (RemoveConfigEntry("Nearby", "MaxNearbyCount") ? 1u : 0u) | (RemoveConfigEntry("Diagnostics", "DebugLogging") ? 1u : 0u)) == 0)
			{
				return;
			}
			try
			{
				((BaseUnityPlugin)this).Config.Save();
				PluginLogger.Info("Migrated config sections to Display/Advanced.");
			}
			catch (Exception ex)
			{
				PluginLogger.ThrottleWarn("cfg_migrate_save", "Config migration save failed: " + ex.Message);
			}
		}

		private bool RemoveConfigEntry(string section, string key)
		{
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			//IL_0008: Expected O, but got Unknown
			try
			{
				ConfigDefinition val = new ConfigDefinition(section, key);
				bool result = false;
				if (((BaseUnityPlugin)this).Config.ContainsKey(val))
				{
					result = ((BaseUnityPlugin)this).Config.Remove(val);
				}
				if (OrphanedEntriesField != null && OrphanedEntriesField.GetValue(((BaseUnityPlugin)this).Config) is Dictionary<ConfigDefinition, string> dictionary && dictionary.Remove(val))
				{
					result = true;
				}
				return result;
			}
			catch
			{
				return false;
			}
		}

		private void OnStructuralConfigChanged(object sender, EventArgs e)
		{
			OnAnyConfigChanged();
		}

		private void OnAnyConfigChanged()
		{
			try
			{
				if (!CfgModEnabled.Value)
				{
					if ((Object)(object)TeammateBarsCoordinator.Instance != (Object)null)
					{
						TeammateBarsCoordinator.Instance.ClearAll();
					}
					IconSpriteCache.Clear();
				}
				else
				{
					TeamRosterTracker tracker = TeamRosterTracker.EnsureExists();
					TeammateBarsCoordinator teammateBarsCoordinator = TeammateBarsCoordinator.EnsureExists();
					teammateBarsCoordinator.Init();
					teammateBarsCoordinator.AttachToTracker(tracker);
					teammateBarsCoordinator.OnConfigChanged();
				}
			}
			catch (Exception ex)
			{
				PluginLogger.ThrottleError("cfg_changed", "OnAnyConfigChanged failed: " + ex.Message);
			}
		}

		[IteratorStateMachine(typeof(<DeferredLanguageRefresh>d__28))]
		private IEnumerator DeferredLanguageRefresh()
		{
			//yield-return decompiler failed: Unexpected instruction in Iterator.Dispose()
			return new <DeferredLanguageRefresh>d__28(0)
			{
				<>4__this = this
			};
		}

		private void OnSceneLoaded(Scene scene, LoadSceneMode mode)
		{
			try
			{
				IconSpriteCache.Clear();
				if ((Object)(object)TeamRosterTracker.Instance != (Object)null)
				{
					TeamRosterTracker.Instance.ClearForSceneReload();
				}
				if ((Object)(object)TeammateBarsCoordinator.Instance != (Object)null)
				{
					TeammateBarsCoordinator.Instance.ClearAll();
				}
				LocalStaminaBarPatch.ResetForSceneReload();
				PluginLogger.ClearThrottle();
			}
			catch (Exception ex)
			{
				PluginLogger.Error("OnSceneLoaded cleanup failed: " + ex.Message);
			}
		}

		private void Update()
		{
			if (!(Time.unscaledTime < _nextSafeTick))
			{
				_nextSafeTick = Time.unscaledTime + 1f;
				SafeTick();
			}
		}

		private void SafeTick()
		{
			try
			{
				if (CfgModEnabled.Value && !((Object)(object)TeamRosterTracker.Instance == (Object)null) && (Object)(object)TeammateBarsCoordinator.Instance == (Object)null && (Object)(object)Character.localCharacter != (Object)null)
				{
					TeamRosterTracker instance = TeamRosterTracker.Instance;
					TeammateBarsCoordinator teammateBarsCoordinator = TeammateBarsCoordinator.EnsureExists();
					teammateBarsCoordinator.Init();
					teammateBarsCoordinator.AttachToTracker(instance);
					instance.RequestRescan();
					PluginLogger.ThrottleInfo("coord_fallback", "BarsCoordinator fallback-initialized in SafeTick.");
				}
			}
			catch (Exception ex)
			{
				PluginLogger.ThrottleError("safetick", "SafeTick failed: " + ex.Message);
			}
		}

		private void OnDestroy()
		{
			try
			{
				SceneManager.sceneLoaded -= OnSceneLoaded;
				if (CfgModEnabled != null)
				{
					CfgModEnabled.SettingChanged -= OnStructuralConfigChanged;
				}
				if (CfgEnableStaminaBar != null)
				{
					CfgEnableStaminaBar.SettingChanged -= OnStructuralConfigChanged;
				}
				if (CfgShowStaminaValue != null)
				{
					CfgShowStaminaValue.SettingChanged -= OnStructuralConfigChanged;
				}
				if (CfgEnableInventoryRow != null)
				{
					CfgEnableInventoryRow.SettingChanged -= OnStructuralConfigChanged;
				}
				Harmony harmony = _harmony;
				if (harmony != null)
				{
					harmony.UnpatchSelf();
				}
			}
			catch
			{
			}
		}
	}
}
namespace PlayersInfo.Patches
{
	[HarmonyPatch(typeof(GUIManager), "Start")]
	internal static class GUIManagerReadyPatch
	{
		[HarmonyPostfix]
		private static void Postfix()
		{
			try
			{
				TeamRosterTracker teamRosterTracker = TeamRosterTracker.EnsureExists();
				TeammateBarsCoordinator teammateBarsCoordinator = TeammateBarsCoordinator.EnsureExists();
				teammateBarsCoordinator.Init();
				teammateBarsCoordinator.AttachToTracker(teamRosterTracker);
				teamRosterTracker.RequestRescan();
				PluginLogger.Info("Teammate bars initialized on GUIManager.Start");
			}
			catch (Exception ex)
			{
				PluginLogger.Error("GUIManagerReadyPatch failed: " + ex.Message);
			}
		}
	}
	[HarmonyPatch(typeof(StaminaBar), "Update")]
	internal static class LocalStaminaBarPatch
	{
		private static TMP_Text _staminaValueText;

		private static TMP_Text _extraValueText;

		private static TMP_Text[] _afflictionTexts;

		private static StaminaBar _initedFor;

		[HarmonyPostfix]
		private static void Postfix(StaminaBar __instance)
		{
			//IL_00ff: Unknown result type (might be due to invalid IL or missing references)
			//IL_0297: Unknown result type (might be due to invalid IL or missing references)
			//IL_0171: Unknown result type (might be due to invalid IL or missing references)
			//IL_0234: Unknown result type (might be due to invalid IL or missing references)
			try
			{
				if ((Object)(object)__instance == (Object)null || (Object)(object)GUIManager.instance == (Object)null || (Object)(object)GUIManager.instance.bar == (Object)null || __instance != GUIManager.instance.bar)
				{
					return;
				}
				if (PlayersInfoPlugin.CfgModEnabled != null && !PlayersInfoPlugin.CfgModEnabled.Value)
				{
					HideAll();
					return;
				}
				if (_initedFor != __instance)
				{
					ResetForSceneReload();
				}
				EnsureInit(__instance);
				bool flag = PlayersInfoPlugin.CfgShowStaminaValue == null || PlayersInfoPlugin.CfgShowStaminaValue.Value;
				float num = 0f;
				float num2 = 0f;
				try
				{
					Character localCharacter = Character.localCharacter;
					if ((Object)(object)localCharacter != (Object)null && (Object)(object)localCharacter.data != (Object)null)
					{
						num = localCharacter.data.currentStamina;
						num2 = localCharacter.data.extraStamina;
					}
				}
				catch
				{
				}
				if ((Object)(object)_staminaValueText != (Object)null)
				{
					if (flag && (Object)(object)__instance.staminaBar != (Object)null)
					{
						UpdateValueText(_staminaValueText, num * 100f, __instance.staminaBar.sizeDelta.x);
					}
					else
					{
						SetActive(_staminaValueText, active: false);
					}
				}
				if ((Object)(object)_extraValueText != (Object)null)
				{
					bool flag2 = (Object)(object)__instance.extraBar != (Object)null && ((Component)__instance.extraBar).gameObject.activeSelf;
					if (flag && flag2 && (Object)(object)__instance.extraBarStamina != (Object)null)
					{
						UpdateValueText(_extraValueText, num2 * 100f, __instance.extraBarStamina.sizeDelta.x);
					}
					else
					{
						SetActive(_extraValueText, active: false);
					}
				}
				if (__instance.afflictions == null || _afflictionTexts == null)
				{
					return;
				}
				CharacterAfflictions val = null;
				try
				{
					Character localCharacter2 = Character.localCharacter;
					if ((Object)(object)localCharacter2 != (Object)null && localCharacter2.refs != null)
					{
						val = localCharacter2.refs.afflictions;
					}
				}
				catch
				{
				}
				int num3 = Mathf.Min(__instance.afflictions.Length, _afflictionTexts.Length);
				for (int i = 0; i < num3; i++)
				{
					BarAffliction val2 = __instance.afflictions[i];
					TMP_Text val3 = _afflictionTexts[i];
					if ((Object)(object)val2 == (Object)null || (Object)(object)val3 == (Object)null)
					{
						continue;
					}
					float num4 = 0f;
					try
					{
						if ((Object)(object)val != (Object)null)
						{
							num4 = val.GetCurrentStatus(val2.afflictionType);
						}
					}
					catch
					{
					}
					if (flag && num4 > 0.01f && val2.width > 18f)
					{
						int num5 = Mathf.Clamp(Mathf.RoundToInt(num4 * 100f), 0, 999);
						string text = ((val2.width > 60f) ? AfflictionTimeHelper.FormatTime(AfflictionTimeHelper.GetReductionTimeRemaining(val, val2.afflictionType)) : string.Empty);
						val3.text = (string.IsNullOrEmpty(text) ? num5.ToString() : (num5 + "(" + text + ")"));
						SetActive(val3, active: true);
					}
					else
					{
						SetActive(val3, active: false);
					}
				}
			}
			catch (Exception ex)
			{
				PluginLogger.ThrottleError("local_bar_patch", "LocalStaminaBarPatch failed: " + ex.Message);
			}
		}

		public static void ResetForSceneReload()
		{
			_staminaValueText = null;
			_extraValueText = null;
			_afflictionTexts = null;
			_initedFor = null;
		}

		private static void EnsureInit(StaminaBar bar)
		{
			if (_initedFor == bar && (Object)(object)_staminaValueText != (Object)null)
			{
				return;
			}
			try
			{
				if ((Object)(object)bar.staminaBar != (Object)null && (Object)(object)_staminaValueText == (Object)null)
				{
					_staminaValueText = AddStretchText(((Component)bar.staminaBar).gameObject, "PI_LocalStaminaValue", 20f, bold: false);
				}
				if ((Object)(object)bar.extraBarStamina != (Object)null && (Object)(object)_extraValueText == (Object)null)
				{
					_extraValueText = AddStretchText(((Component)bar.extraBarStamina).gameObject, "PI_LocalExtraStaminaValue", 20f, bold: false);
				}
				if (bar.afflictions != null && _afflictionTexts == null)
				{
					_afflictionTexts = (TMP_Text[])(object)new TMP_Text[bar.afflictions.Length];
					for (int i = 0; i < bar.afflictions.Length; i++)
					{
						BarAffliction val = bar.afflictions[i];
						if (!((Object)(object)val == (Object)null))
						{
							_afflictionTexts[i] = AddStretchText(((Component)val).gameObject, "PI_LocalAffPct_" + i, 16f, bold: true);
						}
					}
				}
				_initedFor = bar;
			}
			catch (Exception ex)
			{
				PluginLogger.ThrottleWarn("local_bar_init", "LocalStaminaBarPatch.EnsureInit failed: " + ex.Message);
			}
		}

		private static void UpdateValueText(TMP_Text txt, float value01Mul100, float widthPx)
		{
			bool flag = true;
			try
			{
				flag = PlayersInfoPlugin.CfgRoundStamina == null || PlayersInfoPlugin.CfgRoundStamina.Value;
			}
			catch
			{
			}
			if (widthPx < 15f)
			{
				SetActive(txt, active: false);
				return;
			}
			if (flag || widthPx < 30f)
			{
				txt.text = Mathf.Round(value01Mul100).ToString();
			}
			else
			{
				txt.text = value01Mul100.ToString("F1");
			}
			SetActive(txt, active: true);
		}

		private static void SetActive(TMP_Text txt, bool active)
		{
			if (!((Object)(object)txt == (Object)null) && (Object)(object)((Component)txt).gameObject != (Object)null && ((Component)txt).gameObject.activeSelf != active)
			{
				((Component)txt).gameObject.SetActive(active);
			}
		}

		private static void HideAll()
		{
			SetActive(_staminaValueText, active: false);
			SetActive(_extraValueText, active: false);
			if (_afflictionTexts != null)
			{
				for (int i = 0; i < _afflictionTexts.Length; i++)
				{
					SetActive(_afflictionTexts[i], active: false);
				}
			}
		}

		private static TMP_Text AddStretchText(GameObject host, string name, float fontSize, bool bold)
		{
			//IL_0033: 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_004a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0051: Unknown result type (might be due to invalid IL or missing references)
			//IL_005c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0067: 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_00c0: 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)
			try
			{
				if ((Object)(object)host == (Object)null)
				{
					return null;
				}
				if (!host.activeSelf)
				{
					host.SetActive(true);
				}
				GameObject val = new GameObject(name, new Type[1] { typeof(RectTransform) });
				val.transform.SetParent(host.transform, false);
				RectTransform component = val.GetComponent<RectTransform>();
				component.anchorMin = Vector2.zero;
				component.anchorMax = Vector2.one;
				component.offsetMin = Vector2.zero;
				component.offsetMax = Vector2.zero;
				TextMeshProUGUI obj = val.AddComponent<TextMeshProUGUI>();
				((TMP_Text)obj).font = FontHelper.GetChineseCapable();
				((TMP_Text)obj).fontSize = fontSize;
				((TMP_Text)obj).fontStyle = (FontStyles)0;
				((TMP_Text)obj).alignment = (TextAlignmentOptions)514;
				((Graphic)obj).raycastTarget = false;
				((TMP_Text)obj).textWrappingMode = (TextWrappingModes)0;
				TmpOutlineHelper.Apply((TMP_Text)(object)obj, 0.08f, new Color32((byte)0, (byte)0, (byte)0, byte.MaxValue));
				((TMP_Text)obj).text = string.Empty;
				((TMP_Text)obj).transform.localScale = Vector3.one;
				return (TMP_Text)(object)obj;
			}
			catch (Exception ex)
			{
				PluginLogger.ThrottleWarn("local_bar_text", "LocalStaminaBarPatch.AddStretchText failed: " + ex.Message);
				return null;
			}
		}
	}
}
namespace PlayersInfo.MonoBehaviours
{
	internal class TeammateBarDriver : MonoBehaviour
	{
		public Character Target;

		public Image backing;

		public RectTransform fullBar;

		public RectTransform staminaBar;

		public Image staminaGlow;

		public Image extraStaminaGlow;

		public RectTransform maxStaminaBar;

		public RectTransform staminaBarOutline;

		public RectTransform staminaBarOutlineOverflowBar;

		public RectTransform extraBar;

		public RectTransform extraBarStamina;

		public RectTransform extraBarOutline;

		public Vector2 extraBarInitialSize = new Vector2(45f, 45f);

		public float staminaBarOffset;

		public float minStaminaBarWidth = 20f;

		public GameObject shield;

		public GameObject campfire;

		public Color defaultBackingColor;

		public Color outOfStaminaBackingColor;

		public TMP_Text nameLabel;

		public TMP_Text staminaValueText;

		public TMP_Text extraValueText;

		public BarAffliction[] afflictions;

		public TMP_Text[] afflictionTexts;

		public float minAfflictionWidth = 15f;

		public TeammateInventoryRow InventoryRow;

		private float desiredStaminaSize;

		private float desiredMaxStaminaSize;

		private float desiredExtraStaminaSize;

		private float cachedExtraStam;

		private float sinTime;

		private float TAU = (float)Math.PI * 2f;

		private bool outOfStamina;

		private float _nextExtraValLogTime;

		private int _lastStaminaShownInt = int.MinValue;

		private int _lastStaminaShownTenth = int.MinValue;

		private bool _lastStaminaWasFloat;

		private int _lastExtraShownInt = int.MinValue;

		private bool _cachedInvincible;

		private float _nextInvincibleProbeTime;

		private static FieldInfo _fiIsInvincible;

		private static bool _fiResolved;

		public void BindTarget(Character c)
		{
			//IL_0095: Unknown result type (might be due to invalid IL or missing references)
			//IL_00dc: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e6: Unknown result type (might be due to invalid IL or missing references)
			//IL_011c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0126: Unknown result type (might be due to invalid IL or missing references)
			//IL_02b0: 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)
			Target = c;
			desiredStaminaSize = 0f;
			desiredMaxStaminaSize = 0f;
			desiredExtraStaminaSize = 0f;
			cachedExtraStam = 0f;
			outOfStamina = false;
			_cachedInvincible = false;
			_nextInvincibleProbeTime = 0f;
			_lastStaminaShownInt = int.MinValue;
			_lastStaminaShownTenth = int.MinValue;
			_lastStaminaWasFloat = false;
			_lastExtraShownInt = int.MinValue;
			try
			{
				if ((Object)(object)extraBar != (Object)null)
				{
					ShortcutExtensions.DOKill((Component)(object)extraBar, false);
					extraBar.sizeDelta = Vector2.zero;
					((Component)extraBar).gameObject.SetActive(false);
				}
				if ((Object)(object)extraBarStamina != (Object)null)
				{
					ShortcutExtensions.DOKill((Component)(object)extraBarStamina, false);
					extraBarStamina.sizeDelta = new Vector2(6f, extraBarStamina.sizeDelta.y);
				}
				if ((Object)(object)extraBarOutline != (Object)null)
				{
					ShortcutExtensions.DOKill((Component)(object)extraBarOutline, false);
					extraBarOutline.sizeDelta = new Vector2(20f, extraBarOutline.sizeDelta.y);
				}
				cachedExtraStam = 0f;
				desiredExtraStaminaSize = 0f;
			}
			catch
			{
			}
			if (afflictions != null)
			{
				for (int i = 0; i < afflictions.Length; i++)
				{
					BarAffliction val = afflictions[i];
					if (!((Object)(object)val == (Object)null))
					{
						val.size = 0f;
						try
						{
							val.width = 0f;
						}
						catch
						{
						}
						if ((Object)(object)((Component)val).gameObject != (Object)null)
						{
							((Component)val).gameObject.SetActive(false);
						}
					}
				}
			}
			try
			{
				if ((Object)(object)c != (Object)null && (Object)(object)c.data != (Object)null && (Object)(object)fullBar != (Object)null)
				{
					float x = fullBar.sizeDelta.x;
					desiredStaminaSize = Mathf.Max(0f, c.data.currentStamina * x + staminaBarOffset);
					desiredExtraStaminaSize = Mathf.Max(0f, c.data.extraStamina * x);
					if ((Object)(object)extraBar != (Object)null && ((Component)extraBar).gameObject.activeSelf)
					{
						cachedExtraStam = desiredExtraStaminaSize;
					}
				}
			}
			catch
			{
			}
			if ((Object)(object)nameLabel != (Object)null && (Object)(object)c != (Object)null)
			{
				nameLabel.text = SafeGetName(c);
				if (c.refs != null && (Object)(object)c.refs.customization != (Object)null)
				{
					((Graphic)nameLabel).color = c.refs.customization.PlayerColor;
				}
			}
			if ((Object)(object)staminaValueText != (Object)null)
			{
				staminaValueText.text = string.Empty;
				if (((Component)staminaValueText).gameObject.activeSelf)
				{
					((Component)staminaValueText).gameObject.SetActive(false);
				}
			}
			if ((Object)(object)extraValueText != (Object)null)
			{
				extraValueText.text = string.Empty;
				if (((Component)extraValueText).gameObject.activeSelf)
				{
					((Component)extraValueText).gameObject.SetActive(false);
				}
			}
			if (afflictionTexts == null)
			{
				return;
			}
			for (int j = 0; j < afflictionTexts.Length; j++)
			{
				TMP_Text val2 = afflictionTexts[j];
				if (!((Object)(object)val2 == (Object)null))
				{
					val2.text = string.Empty;
					if (((Component)val2).gameObject.activeSelf)
					{
						((Component)val2).gameObject.SetActive(false);
					}
				}
			}
		}

		private void Update()
		{
			try
			{
				DoUpdate();
			}
			catch (Exception ex)
			{
				PluginLogger.ThrottleError("bar_driver", "TeammateBarDriver Update failed: " + ex.Message);
			}
		}

		private void DoUpdate()
		{
			//IL_022c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0231: Unknown result type (might be due to invalid IL or missing references)
			//IL_0235: Unknown result type (might be due to invalid IL or missing references)
			//IL_0253: Unknown result type (might be due to invalid IL or missing references)
			//IL_0265: Unknown result type (might be due to invalid IL or missing references)
			//IL_02d3: Unknown result type (might be due to invalid IL or missing references)
			//IL_02d8: 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_033d: 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_03c7: Unknown result type (might be due to invalid IL or missing references)
			//IL_0139: Unknown result type (might be due to invalid IL or missing references)
			//IL_013e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0141: 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_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)
			//IL_009d: 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_04ff: 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_017d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0185: Unknown result type (might be due to invalid IL or missing references)
			//IL_01e0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b1: Unknown result type (might be due to invalid IL or missing references)
			//IL_0603: Unknown result type (might be due to invalid IL or missing references)
			//IL_065e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0663: Unknown result type (might be due to invalid IL or missing references)
			//IL_0667: Unknown result type (might be due to invalid IL or missing references)
			//IL_0695: Unknown result type (might be due to invalid IL or missing references)
			//IL_06b0: Unknown result type (might be due to invalid IL or missing references)
			//IL_06b5: Unknown result type (might be due to invalid IL or missing references)
			//IL_06bd: Unknown result type (might be due to invalid IL or missing references)
			//IL_0718: Unknown result type (might be due to invalid IL or missing references)
			//IL_0749: Unknown result type (might be due to invalid IL or missing references)
			//IL_0753: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)Target == (Object)null || ((object)Target).Equals((object?)null) || (Object)(object)Target.data == (Object)null || (Object)(object)fullBar == (Object)null || (Object)(object)staminaBar == (Object)null)
			{
				return;
			}
			if ((Object)(object)nameLabel != (Object)null && Target.refs != null && (Object)(object)Target.refs.customization != (Object)null)
			{
				Color playerColor = Target.refs.customization.PlayerColor;
				if (((Graphic)nameLabel).color != playerColor)
				{
					((Graphic)nameLabel).color = playerColor;
				}
			}
			float x = fullBar.sizeDelta.x;
			desiredStaminaSize = Mathf.Max(0f, Target.data.currentStamina * x + staminaBarOffset);
			if (Target.data.currentStamina <= 0.005f)
			{
				if (!outOfStamina)
				{
					outOfStamina = true;
					OutOfStaminaPulse();
				}
			}
			else
			{
				outOfStamina = false;
			}
			float num = Time.deltaTime * 10f;
			Vector2 sizeDelta = staminaBar.sizeDelta;
			sizeDelta.x = Mathf.Lerp(sizeDelta.x, desiredStaminaSize, num);
			staminaBar.sizeDelta = sizeDelta;
			if ((Object)(object)staminaGlow != (Object)null)
			{
				Color color = ((Graphic)staminaGlow).color;
				float num2 = Mathf.Clamp01((staminaBar.sizeDelta.x - desiredStaminaSize) * 0.5f);
				sinTime += num * num2;
				color.a = num2 * 0.4f - Mathf.Abs(Mathf.Sin(sinTime)) * 0.2f;
				((Graphic)staminaGlow).color = color;
			}
			try
			{
				desiredMaxStaminaSize = Mathf.Max(0f, Target.GetMaxStamina() * x + staminaBarOffset);
			}
			catch
			{
				desiredMaxStaminaSize = x;
			}
			if ((Object)(object)maxStaminaBar != (Object)null)
			{
				Vector2 sizeDelta2 = maxStaminaBar.sizeDelta;
				sizeDelta2.x = Mathf.Lerp(sizeDelta2.x, desiredMaxStaminaSize, num);
				maxStaminaBar.sizeDelta = sizeDelta2;
				((Component)maxStaminaBar).gameObject.SetActive(sizeDelta2.x > minStaminaBarWidth);
			}
			float num3 = 1f;
			try
			{
				if (Target.refs != null && (Object)(object)Target.refs.afflictions != (Object)null)
				{
					num3 = Target.refs.afflictions.statusSum;
				}
			}
			catch
			{
			}
			if ((Object)(object)staminaBarOutline != (Object)null)
			{
				Vector2 sizeDelta3 = staminaBarOutline.sizeDelta;
				sizeDelta3.x = 14f + Mathf.Max(1f, num3) * x;
				staminaBarOutline.sizeDelta = sizeDelta3;
			}
			if ((Object)(object)staminaBarOutlineOverflowBar != (Object)null)
			{
				((Component)staminaBarOutlineOverflowBar).gameObject.SetActive((double)num3 > 1.005);
			}
			((Component)staminaBar).gameObject.SetActive(staminaBar.sizeDelta.x > minStaminaBarWidth);
			if (afflictions != null && Target.refs != null && (Object)(object)Target.refs.afflictions != (Object)null)
			{
				CharacterAfflictions val = Target.refs.afflictions;
				for (int i = 0; i < afflictions.Length; i++)
				{
					BarAffliction val2 = afflictions[i];
					if ((Object)(object)val2 == (Object)null)
					{
						continue;
					}
					float num4 = 0f;
					try
					{
						num4 = val.GetCurrentStatus(val2.afflictionType);
					}
					catch
					{
					}
					float num5 = x * num4;
					if (num4 > 0.01f)
					{
						if (num5 < minAfflictionWidth)
						{
							num5 = minAfflictionWidth;
						}
						val2.size = num5;
						if (!((Component)val2).gameObject.activeSelf)
						{
							((Component)val2).gameObject.SetActive(true);
						}
					}
					else
					{
						val2.size = 0f;
						if (((Component)val2).gameObject.activeSelf)
						{
							((Component)val2).gameObject.SetActive(false);
						}
					}
					try
					{
						val2.width = Mathf.Lerp(val2.width, val2.size, Mathf.Min(Time.deltaTime * 10f, 0.1f));
					}
					catch
					{
					}
					if (afflictionTexts == null || i >= afflictionTexts.Length)
					{
						continue;
					}
					TMP_Text val3 = afflictionTexts[i];
					if (!((Object)(object)val3 != (Object)null))
					{
						continue;
					}
					if (num4 > 0.01f && val2.width > 18f)
					{
						int num6 = Mathf.Clamp(Mathf.RoundToInt(num4 * 100f), 0, 999);
						string text = ((val2.width > 60f) ? AfflictionTimeHelper.FormatTime(AfflictionTimeHelper.GetReductionTimeRemaining(val, val2.afflictionType)) : string.Empty);
						val3.text = (string.IsNullOrEmpty(text) ? num6.ToString() : (num6 + "(" + text + ")"));
						if (!((Component)val3).gameObject.activeSelf)
						{
							((Component)val3).gameObject.SetActive(true);
						}
					}
					else if (((Component)val3).gameObject.activeSelf)
					{
						((Component)val3).gameObject.SetActive(false);
					}
				}
			}
			float num7 = (((Object)(object)Target.data != (Object)null) ? Target.data.extraStamina : 0f);
			bool flag = num7 > 0.001f;
			if ((Object)(object)extraBar != (Object)null)
			{
				if (flag)
				{
					if (!((Component)extraBar).gameObject.activeSelf)
					{
						ShortcutExtensions.DOKill((Component)(object)extraBar, false);
						extraBar.sizeDelta = extraBarInitialSize;
						((Component)extraBar).gameObject.SetActive(true);
					}
					desiredExtraStaminaSize = Mathf.Max(0f, num7 * x);
					cachedExtraStam = Mathf.Lerp(cachedExtraStam, desiredExtraStaminaSize, num);
					if ((Object)(object)extraBarOutline != (Object)null)
					{
						Vector2 sizeDelta4 = extraBarOutline.sizeDelta;
						sizeDelta4.x = Mathf.Lerp(sizeDelta4.x, Mathf.Max(20f, desiredExtraStaminaSize + 12f), num);
						extraBarOutline.sizeDelta = sizeDelta4;
					}
					if ((Object)(object)extraStaminaGlow != (Object)null)
					{
						Color color2 = ((Graphic)extraStaminaGlow).color;
						float num8 = Mathf.Clamp01((extraBar.sizeDelta.x - desiredExtraStaminaSize) * 0.5f);
						sinTime += num * num8;
						color2.a = num8 * 0.4f - Mathf.Abs(Mathf.Sin(sinTime)) * 0.2f;
						((Graphic)extraStaminaGlow).color = color2;
					}
					if ((Object)(object)extraBarStamina != (Object)null)
					{
						extraBarStamina.sizeDelta = new Vector2(Mathf.Max(6f, cachedExtraStam), extraBarStamina.sizeDelta.y);
					}
				}
				else
				{
					if (((Component)extraBar).gameObject.activeSelf)
					{
						ShortcutExtensions.DOKill((Component)(object)extraBar, false);
						((Component)extraBar).gameObject.SetActive(false);
					}
					cachedExtraStam = 0f;
					desiredExtraStaminaSize = 0f;
				}
			}
			if ((Object)(object)shield != (Object)null)
			{
				if (Time.unscaledTime >= _nextInvincibleProbeTime)
				{
					_nextInvincibleProbeTime = Time.unscaledTime + 0.25f;
					try
					{
						_cachedInvincible = GetIsInvincible(Target.data);
					}
					catch
					{
						_cachedInvincible = false;
					}
				}
				try
				{
					shield.SetActive(_cachedInvincible);
				}
				catch
				{
				}
			}
			if ((Object)(object)campfire != (Object)null)
			{
				try
				{
					bool flag2 = Target.refs == null || !((Object)(object)Target.refs.afflictions != (Object)null) || Target.refs.afflictions.canGetHungry;
					campfire.SetActive(!flag2);
				}
				catch
				{
				}
			}
			if (sinTime > TAU)
			{
				sinTime -= TAU;
			}
			UpdateValueTexts();
		}

		private void UpdateValueTexts()
		{
			//IL_0098: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)Target == (Object)null || (Object)(object)Target.data == (Object)null)
			{
				return;
			}
			bool flag = true;
			try
			{
				flag = PlayersInfoPlugin.CfgRoundStamina == null || PlayersInfoPlugin.CfgRoundStamina.Value;
			}
			catch
			{
			}
			float num = Target.data.currentStamina * 100f;
			float num2 = Target.data.extraStamina * 100f;
			if ((Object)(object)staminaValueText != (Object)null)
			{
				float num3 = (((Object)(object)staminaBar != (Object)null) ? staminaBar.sizeDelta.x : 0f);
				if (num3 < 15f)
				{
					if (((Component)staminaValueText).gameObject.activeSelf)
					{
						((Component)staminaValueText).gameObject.SetActive(false);
					}
				}
				else
				{
					if (!flag && !(num3 < 30f))
					{
						int num4 = Mathf.RoundToInt(num * 10f);
						if (num4 != _lastStaminaShownTenth || !_lastStaminaWasFloat)
						{
							staminaValueText.text = ((float)num4 / 10f).ToString("F1");
							_lastStaminaShownTenth = num4;
							_lastStaminaWasFloat = true;
						}
					}
					else
					{
						int num5 = Mathf.RoundToInt(num);
						if (num5 != _lastStaminaShownInt || _lastStaminaWasFloat)
						{
							staminaValueText.text = num5.ToString();
							_lastStaminaShownInt = num5;
							_lastStaminaWasFloat = false;
						}
					}
					if (!((Component)staminaValueText).gameObject.activeSelf)
					{
						((Component)staminaValueText).gameObject.SetActive(true);
					}
				}
			}
			if (!((Object)(object)extraValueText != (Object)null))
			{
				return;
			}
			if (num2 < 0.5f)
			{
				if (((Component)extraValueText).gameObject.activeSelf)
				{
					((Component)extraValueText).gameObject.SetActive(false);
				}
				return;
			}
			int num6 = Mathf.RoundToInt(num2);
			if (num6 != _lastExtraShownInt)
			{
				extraValueText.text = "+" + num6;
				_lastExtraShownInt = num6;
			}
			if (!((Component)extraValueText).gameObject.activeSelf)
			{
				((Component)extraValueText).gameObject.SetActive(true);
			}
			if (!PluginLogger.DebugEnabled || !(Time.unscaledTime >= _nextExtraValLogTime))
			{
				return;
			}
			_nextExtraValLogTime = Time.unscaledTime + 3f;
			try
			{
				float currentStamina = Target.data.currentStamina;
				float extraStamina = Target.data.extraStamina;
				string text = SafeGetName(Target);
				PluginLogger.Debug("[ExtraVal] mate=" + text + " rawExtra=" + extraStamina.ToString("F4") + " shown=+" + Mathf.Round(extraStamina * 100f) + " rawMain=" + currentStamina.ToString("F4"));
			}
			catch
			{
			}
		}

		private void OutOfStaminaPulse()
		{
			//IL_0017: Unknown result type (might be due to invalid IL or missing references)
			//IL_0028: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)backing == (Object)null)
			{
				return;
			}
			try
			{
				((Graphic)backing).color = outOfStaminaBackingColor;
				DOTweenModuleUI.DOColor(backing, defaultBackingColor, 0.5f);
			}
			catch
			{
			}
		}

		private static bool GetIsInvincible(CharacterData data)
		{
			if ((Object)(object)data == (Object)null)
			{
				return false;
			}
			if (!_fiResolved)
			{
				_fiResolved = true;
				try
				{
					_fiIsInvincible = typeof(CharacterData).GetField("isInvincible", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
				}
				catch
				{
				}
			}
			if (_fiIsInvincible == null)
			{
				return false;
			}
			try
			{
				return (bool)_fiIsInvincible.GetValue(data);
			}
			catch
			{
				return false;
			}
		}

		private static string SafeGetName(Character c)
		{
			if ((Object)(object)c == (Object)null)
			{
				return string.Empty;
			}
			try
			{
				if ((Object)(object)((MonoBehaviourPun)c).photonView != (Object)null && ((MonoBehaviourPun)c).photonView.Owner != null)
				{
					string nickName = ((MonoBehaviourPun)c).photonView.Owner.NickName;
					if (!string.IsNullOrEmpty(nickName))
					{
						return nickName;
					}
				}
			}
			catch
			{
			}
			try
			{
				return string.IsNullOrEmpty(c.characterName) ? ((Object)c).name : c.characterName;
			}
			catch
			{
				return "Player";
			}
		}
	}
	internal class TeammateBarsCoordinator : MonoBehaviour
	{
		private struct RetainedEntry
		{
			public Character ch;

			public float lostTime;
		}

		private readonly List<TeammateBarDriver> _pool = new List<TeammateBarDriver>();

		private StaminaBar _origBar;

		private float _nextRefreshTime;

		private const float RefreshInterval = 0.25f;

		private float _nextDistLogTime;

		private const float ReorderDelay = 0.75f;

		private static readonly List<KeyValuePair<float, Character>> _scratch = new List<KeyValuePair<float, Character>>();

		private static readonly List<Character> s_visibleScratch = new List<Character>();

		private static readonly Dictionary<int, Character> s_visibleById = new Dictionary<int, Character>();

		private static readonly HashSet<int> s_seenStableIds = new HashSet<int>();

		private const float HysteresisMargin = 5f;

		private static readonly HashSet<int> s_displayOrderSet = new HashSet<int>();

		private const float RetainOnLossDelay = 1.5f;

		private static readonly Dictionary<int, RetainedEntry> s_retainedById = new Dictionary<int, RetainedEntry>();

		private static readonly Dictionary<int, int> s_viewIdToActor = new Dictionary<int, int>();

		private readonly List<int> _displayOrder = new List<int>();

		private readonly List<int> _pendingOrder = new List<int>();

		private float _pendingOrderSince = -1f;

		private static readonly Comparison<KeyValuePair<float, Character>> s_distCmp = (KeyValuePair<float, Character> a, KeyValuePair<float, Character> b) => a.Key.CompareTo(b.Key);

		public static TeammateBarsCoordinator Instance { get; private set; }

		public static TeammateBarsCoordinator EnsureExists()
		{
			//IL_0018: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)Instance != (Object)null)
			{
				return Instance;
			}
			Instance = new GameObject("PlayersInfo.BarsCoordinator").AddComponent<TeammateBarsCoordinator>();
			return Instance;
		}

		private void OnDestroy()
		{
			if ((Object)(object)TeamRosterTracker.Instance != (Object)null)
			{
				TeamRosterTracker.Instance.OnRosterChanged -= HandleRosterChanged;
			}
			if ((Object)(object)Instance == (Object)(object)this)
			{
				Instance = null;
			}
		}

		public void Init()
		{
			try
			{
				if ((Object)(object)GUIManager.instance == (Object)null || (Object)(object)GUIManager.instance.bar == (Object)null)
				{
					PluginLogger.ThrottleWarn("bars_init", "GUIManager.instance.bar not ready, skip init.");
					return;
				}
				_origBar = GUIManager.instance.bar;
				FixBarGroupOnce();
			}
			catch (Exception ex)
			{
				PluginLogger.Error("BarsCoordinator.Init failed: " + ex.Message);
			}
		}

		private void FixBarGroupOnce()
		{
			//IL_002c: Unknown result type (might be due to invalid IL or missing references)
			try
			{
				Transform parent = ((Component)_origBar).transform.parent;
				RectTransform val = (RectTransform)(object)((parent is RectTransform) ? parent : null);
				if (!((Object)(object)val == (Object)null))
				{
					val.sizeDelta = new Vector2(600f, 600f);
					ApplyConfiguredAnchor(val);
					VerticalLayoutGroup component = ((Component)val).GetComponent<VerticalLayoutGroup>();
					if ((Object)(object)component != (Object)null)
					{
						((HorizontalOrVerticalLayoutGroup)component).spacing = 25f;
					}
				}
			}
			catch (Exception ex)
			{
				PluginLogger.ThrottleWarn("fix_bargroup", "FixBarGroup failed: " + ex.Message);
			}
		}

		private static void ApplyConfiguredAnchor(RectTransform rt)
		{
			//IL_0073: 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_008a: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f1: Unknown result type (might be due to invalid IL or missing references)
			//IL_010f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0115: Unknown result type (might be due to invalid IL or missing references)
			//IL_0126: Unknown result type (might be due to invalid IL or missing references)
			//IL_013f: Unknown result type (might be due to invalid IL or missing references)
			//IL_015d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0163: 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_018d: Unknown result type (might be due to invalid IL or missing references)
			PlayersInfoPlugin.HudAnchor hudAnchor = ((PlayersInfoPlugin.CfgAnchor != null) ? PlayersInfoPlugin.CfgAnchor.Value : PlayersInfoPlugin.HudAnchor.TopLeft);
			float num = ((PlayersInfoPlugin.CfgOffsetX != null) ? PlayersInfoPlugin.CfgOffsetX.Value : 0f);
			float num2 = ((PlayersInfoPlugin.CfgOffsetY != null) ? PlayersInfoPlugin.CfgOffsetY.Value : 0f);
			Vector2 val = default(Vector2);
			switch (hudAnchor)
			{
			case PlayersInfoPlugin.HudAnchor.TopRight:
				((Vector2)(ref val))..ctor(1f, 1f);
				rt.anchorMax = val;
				rt.anchorMin = val;
				rt.pivot = new Vector2(1f, 1f);
				rt.anchoredPosition = new Vector2(-20f + num, -20f + num2);
				break;
			case PlayersInfoPlugin.HudAnchor.BottomLeft:
				((Vector2)(ref val))..ctor(0f, 0f);
				rt.anchorMax = val;
				rt.anchorMin = val;
				rt.pivot = new Vector2(0f, 0f);
				rt.anchoredPosition = new Vector2(20f + num, 20f + num2);
				break;
			case PlayersInfoPlugin.HudAnchor.BottomRight:
				((Vector2)(ref val))..ctor(1f, 0f);
				rt.anchorMax = val;
				rt.anchorMin = val;
				rt.pivot = new Vector2(1f, 0f);
				rt.anchoredPosition = new Vector2(-20f + num, 20f + num2);
				break;
			default:
				((Vector2)(ref val))..ctor(0f, 1f);
				rt.anchorMax = val;
				rt.anchorMin = val;
				rt.pivot = new Vector2(0f, 1f);
				rt.anchoredPosition = new Vector2(20f + num, -20f + num2);
				break;
			}
		}

		public void AttachToTracker(TeamRosterTracker tracker)
		{
			if (!((Object)(object)tracker == (Object)null))
			{
				tracker.OnRosterChanged -= HandleRosterChanged;
				tracker.OnRosterChanged += HandleRosterChanged;
				_nextRefreshTime = 0f;
			}
		}

		private void HandleRosterChanged()
		{
			_nextRefreshTime = 0f;
		}

		private void Update()
		{
			if (Time.unscaledTime < _nextRefreshTime)
			{
				return;
			}
			_nextRefreshTime = Time.unscaledTime + 0.25f;
			try
			{
				RefreshNearby();
			}
			catch (Exception ex)
			{
				PluginLogger.ThrottleError("bars_refresh", "RefreshNearby failed: " + ex.Message);
			}
		}

		private void RefreshNearby()
		{
			//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_01a5: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a9: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)_origBar == (Object)null)
			{
				Init();
				if ((Object)(object)_origBar == (Object)null)
				{
					return;
				}
			}
			if (PlayersInfoPlugin.CfgModEnabled == null || !PlayersInfoPlugin.CfgModEnabled.Value || (PlayersInfoPlugin.CfgEnableStaminaBar != null && !PlayersInfoPlugin.CfgEnableStaminaBar.Value))
			{
				HideAll();
				return;
			}
			FixBarGroupOnce();
			SyncExtraTextPlacement();
			TeamRosterTracker instance = TeamRosterTracker.Instance;
			if ((Object)(object)instance == (Object)null)
			{
				return;
			}
			Character localCharacter = Character.localCharacter;
			if ((Object)(object)localCharacter == (Object)null || ((object)localCharacter).Equals((object?)null))
			{
				HideAll();
				return;
			}
			int num = ((PlayersInfoPlugin.CfgMaxNearbyCount != null) ? PlayersInfoPlugin.CfgMaxNearbyCount.Value : 3);
			float num2 = ((PlayersInfoPlugin.CfgNearbyRange != null) ? PlayersInfoPlugin.CfgNearbyRange.Value : 30f);
			if (num <= 0)
			{
				HideAll();
				return;
			}
			_scratch.Clear();
			s_visibleScratch.Clear();
			s_visibleById.Clear();
			s_seenStableIds.Clear();
			s_displayOrderSet.Clear();
			for (int i = 0; i < _displayOrder.Count; i++)
			{
				s_displayOrderSet.Add(_displayOrder[i]);
			}
			IReadOnlyList<Character> teammates = instance.Teammates;
			bool flag = (Object)(object)localCharacter.data != (Object)null && localCharacter.data.dead;
			Vector3 center = localCharacter.Center;
			for (int j = 0; j < teammates.Count; j++)
			{
				Character val = teammates[j];
				if ((Object)(object)val == (Object)null || ((object)val).Equals((object?)null) || (Object)(object)val.data == (Object)null || (Object)(object)((MonoBehaviourPun)val).photonView == (Object)null)
				{
					continue;
				}
				float num3 = (flag ? ((float)((MonoBehaviourPun)val).photonView.ViewID) : Vector3.Distance(center, val.Center));
				if (!flag && num2 > 0f)
				{
					int stableCharacterId = GetStableCharacterId(val);
					float num4 = (s_displayOrderSet.Contains(stableCharacterId) ? (num2 + 5f) : num2);
					if (num3 > num4)
					{
						continue;
					}
				}
				_scratch.Add(new KeyValuePair<float, Character>(num3, val));
			}
			_scratch.Sort(s_distCmp);
			for (int k = 0; k < _scratch.Count; k++)
			{
				if (s_visibleScratch.Count >= num)
				{
					break;
				}
				Character value = _scratch[k].Value;
				int stableCharacterId2 = GetStableCharacterId(value);
				if (stableCharacterId2 != int.MinValue && s_seenStableIds.Add(stableCharacterId2))
				{
					s_visibleScratch.Add(value);
					s_visibleById[stableCharacterId2] = value;
					s_retainedById[stableCharacterId2] = new RetainedEntry
					{
						ch = value,
						lostTime = -1f
					};
				}
			}
			float unscaledTime = Time.unscaledTime;
			for (int l = 0; l < _displayOrder.Count; l++)
			{
				int num5 = _displayOrder[l];
				if (s_visibleById.TryGetValue(num5, out var value2))
				{
					s_retainedById[num5] = new RetainedEntry
					{
						ch = value2,
						lostTime = -1f
					};
					continue;
				}
				if (s_visibleScratch.Count >= num)
				{
					s_retainedById.Remove(num5);
					continue;
				}
				Character val2 = null;
				if (s_retainedById.TryGetValue(num5, out var value3))
				{
					if (value3.lostTime < 0f)
					{
						value3.lostTime = unscaledTime;
						s_retainedById[num5] = value3;
					}
					if (unscaledTime - value3.lostTime <= 1.5f && (Object)(object)value3.ch != (Object)null && !((object)value3.ch).Equals((object?)null))
					{
						val2 = value3.ch;
					}
					else
					{
						s_retainedById.Remove(num5);
					}
				}
				else
				{
					for (int m = 0; m < teammates.Count; m++)
					{
						Character val3 = teammates[m];
						if (!((Object)(object)val3 == (Object)null) && !((object)val3).Equals((object?)null) && !((Object)(object)((MonoBehaviourPun)val3).photonView == (Object)null) && GetStableCharacterId(val3) == num5)
						{
							val2 = val3;
							s_retainedById[num5] = new RetainedEntry
							{
								ch = val3,
								lostTime = unscaledTime
							};
							break;
						}
					}
				}
				if ((Object)(object)val2 != (Object)null)
				{
					s_visibleScratch.Add(val2);
					s_visibleById[num5] = val2;
				}
			}
			int count = s_visibleScratch.Count;
			ResolveDisplayOrder(s_visibleScratch);
			if (PluginLogger.DebugEnabled && Time.unscaledTime >= _nextDistLogTime)
			{
				_nextDistLogTime = Time.unscaledTime + 2f;
				try
				{
					StringBuilder stringBuilder = new StringBuilder();
					stringBuilder.Append("[Dist] local->mates(").Append(_scratch.Count).Append(", range=")
						.Append(num2.ToString("F0"))
						.Append("): ");
					for (int n = 0; n < _scratch.Count; n++)
					{
						if (n > 0)
						{
							stringBuilder.Append(", ");
						}
						KeyValuePair<float, Character> keyValuePair = _scratch[n];
						string value4 = (((Object)(object)keyValuePair.Value != (Object)null) ? (keyValuePair.Value.characterName ?? ((Object)keyValuePair.Value).name) : "?");
						stringBuilder.Append(value4).Append("=").Append(keyValuePair.Key.ToString("F1"))
							.Append("m");
					}
					PluginLogger.Debug(stringBuilder.ToString());
				}
				catch
				{
				}
			}
			while (_pool.Count < count)
			{
				TeammateBarDriver teammateBarDriver = CreateBar();
				if ((Object)(object)teammateBarDriver == (Object)null)
				{
					break;
				}
				_pool.Add(teammateBarDriver);
			}
			for (int num6 = 0; num6 < _pool.Count; num6++)
			{
				TeammateBarDriver teammateBarDriver2 = _pool[num6];
				if ((Object)(object)teammateBarDriver2 == (Object)null)
				{
					continue;
				}
				if (num6 < count)
				{
					if (num6 >= _displayOrder.Count || !s_visibleById.TryGetValue(_displayOrder[num6], out var value5) || (Object)(object)value5 == (Object)null)
					{
						if (((Component)teammateBarDriver2).gameObject.activeSelf)
						{
							((Component)teammateBarDriver2).gameObject.SetActive(false);
						}
						continue;
					}
					if (!((Component)teammateBarDriver2).gameObject.activeSelf)
					{
						((Component)teammateBarDriver2).gameObject.SetActive(true);
					}
					if ((Object)(object)teammateBarDriver2.Target != (Object)(object)value5)
					{
						teammateBarDriver2.BindTarget(value5);
					}
					if ((Object)(object)teammateBarDriver2.InventoryRow != (Object)null)
					{
						teammateBarDriver2.InventoryRow.Target = value5;
					}
				}
				else if (((Component)teammateBarDriver2).gameObject.activeSelf)
				{
					((Component)teammateBarDriver2).gameObject.SetActive(false);
				}
			}
		}

		private void HideAll()
		{
			for (int i = 0; i < _pool.Count; i++)
			{
				TeammateBarDriver teammateBarDriver = _pool[i];
				if ((Object)(object)teammateBarDriver != (Object)null && (Object)(object)((Component)teammateBarDriver).gameObject != (Object)null && ((Component)teammateBarDriver).gameObject.activeSelf)
				{
					((Component)teammateBarDriver).gameObject.SetActive(false);
				}
			}
		}

		private TeammateBarDriver CreateBar()
		{
			//IL_0111: Unknown result type (might be due to invalid IL or missing references)
			//IL_0116: Unknown result type (might be due to invalid IL or missing references)
			//IL_011d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0122: 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_035b: Unknown result type (might be due to invalid IL or missing references)
			//IL_036f: Unknown result type (might be due to invalid IL or missing references)
			//IL_02ab: Unknown result type (might be due to invalid IL or missing references)
			//IL_02b0: Unknown result type (might be due to invalid IL or missing references)
			//IL_02ef: Unknown result type (might be due to invalid IL or missing references)
			//IL_0304: 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_032d: Unknown result type (might be due to invalid IL or missing references)
			try
			{
				Transform transform = ((Component)_origBar).transform;
				Transform val = Object.Instantiate<Transform>(transform, transform.parent);
				((Object)val).name = "TeammateBar_Clone";
				val.SetAsFirstSibling();
				GameObject gameObject = ((Component)val).gameObject;
				CleanupClonedPatchArtifacts(val);
				StaminaBar component = gameObject.GetComponent<StaminaBar>();
				TeammateBarDriver teammateBarDriver = gameObject.AddComponent<TeammateBarDriver>();
				if ((Object)(object)component != (Object)null)
				{
					teammateBarDriver.backing = component.backing;
					teammateBarDriver.fullBar = component.fullBar;
					teammateBarDriver.staminaBar = component.staminaBar;
					teammateBarDriver.staminaGlow = component.staminaGlow;
					teammateBarDriver.extraStaminaGlow = component.extraStaminaGlow;
					teammateBarDriver.maxStaminaBar = component.maxStaminaBar;
					teammateBarDriver.staminaBarOutline = component.staminaBarOutline;
					teammateBarDriver.staminaBarOutlineOverflowBar = component.staminaBarOutlineOverflowBar;
					teammateBarDriver.extraBar = component.extraBar;
					teammateBarDriver.extraBarStamina = component.extraBarStamina;
					teammateBarDriver.extraBarOutline = component.extraBarOutline;
					teammateBarDriver.staminaBarOffset = component.staminaBarOffset;
					teammateBarDriver.minStaminaBarWidth = component.minStaminaBarWidth;
					teammateBarDriver.minAfflictionWidth = component.minAfflictionWidth;
					teammateBarDriver.shield = component.shield;
					teammateBarDriver.campfire = component.campfire;
					teammateBarDriver.defaultBackingColor = component.defaultBackingColor;
					teammateBarDriver.outOfStaminaBackingColor = component.outOfStaminaBackingColor;
					teammateBarDriver.afflictions = component.afflictions;
					teammateBarDriver.extraBar = null;
					teammateBarDriver.extraBarStamina = null;
					teammateBarDriver.extraBarOutline = null;
					teammateBarDriver.extraStaminaGlow = null;
					Object.Destroy((Object)(object)component);
				}
				else
				{
					teammateBarDriver.afflictions = gameObject.GetComponentsInChildren<BarAffliction>(true);
				}
				teammateBarDriver.nameLabel = TryAddNameLabel(gameObject);
				int num;
				if (PlayersInfoPlugin.CfgShowStaminaValue != null)
				{
					num = (PlayersInfoPlugin.CfgShowStaminaValue.Value ? 1 : 0);
					if (num == 0)
					{
						goto IL_01b2;
					}
				}
				else
				{
					num = 1;
				}
				if ((Object)(object)teammateBarDriver.staminaBar != (Object)null)
				{
					teammateBarDriver.staminaValueText = AddValueText(((Component)teammateBarDriver.staminaBar).gameObject, "StaminaValue");
				}
				goto IL_01b2;
				IL_01b2:
				if (num != 0 && (Object)(object)teammateBarDriver.fullBar != (Object)null)
				{
					teammateBarDriver.extraValueText = AddSideText(teammateBarDriver.fullBar, "PI_MateExtraValue", ShouldPlaceExtraTextOnRight(), new Color(0.55f, 1f, 0.35f));
				}
				if (teammateBarDriver.afflictions != null && teammateBarDriver.afflictions.Length != 0)
				{
					teammateBarDriver.afflictionTexts = (TMP_Text[])(object)new TMP_Text[teammateBarDriver.afflictions.Length];
					for (int i = 0; i < teammateBarDriver.afflictions.Length; i++)
					{
						BarAffliction val2 = teammateBarDriver.afflictions[i];
						if (!((Object)(object)val2 == (Object)null))
						{
							teammateBarDriver.afflictionTexts[i] = AddAfflictionText(((Component)val2).gameObject, "AfflictionPct_" + i);
						}
					}
				}
				if ((Object)(object)teammateBarDriver.fullBar != (Object)null)
				{
					RectTransform parent = (RectTransform)(object)((val is RectTransform) ? val : null);
					if (PlayersInfoPlugin.CfgEnableInventoryRow != null && PlayersInfoPlugin.CfgEnableInventoryRow.Value)
					{
						Rect rect = teammateBarDriver.fullBar.rect;
						float totalWidth = Mathf.Max(180f, ((Rect)(ref rect)).width);
						teammateBarDriver.InventoryRow = TeammateInventoryRow.Build(parent, totalWidth, 22f, 1.5f);
						RectTransform component2 = ((Component)teammateBarDriver.InventoryRow).GetComponent<RectTransform>();
						component2.anchorMin = new Vector2(0f, 0.5f);
						component2.anchorMax = new Vector2(0f, 0.5f);
						component2.pivot = new Vector2(0f, 0.5f);
						component2.anchoredPosition = new Vector2(148f, 34f);
					}
				}
				if ((Object)(object)teammateBarDriver.nameLabel != (Object)null)
				{
					RectTransform rectTransform = teammateBarDriver.nameLabel.rectTransform;
					rectTransform.sizeDelta = new Vector2(140f, 22f);
					rectTransform.anchoredPosition = new Vector2(0f, 34f);
				}
				return teammateBarDriver;
			}
			catch (Exception ex)
			{
				PluginLogger.Error("CreateBar failed: " + ex.Message);
				return null;
			}
		}

		private static bool ShouldPlaceExtraTextOnRight()
		{
			PlayersInfoPlugin.HudAnchor hudAnchor = ((PlayersInfoPlugin.CfgAnchor != null) ? PlayersInfoPlugin.CfgAnchor.Value : PlayersInfoPlugin.HudAnchor.TopLeft);
			if (hudAnchor != 0)
			{
				return hudAnchor == PlayersInfoPlugin.HudAnchor.BottomLeft;
			}
			return true;
		}

		private void SyncExtraTextPlacement()
		{
			bool flag = ShouldPlaceExtraTextOnRight();
			for (int i = 0; i < _pool.Count; i++)
			{
				TeammateBarDriver teammateBarDriver = _pool[i];
				if (!((Object)(object)teammateBarDriver == (Object)null) && !((Object)(object)teammateBarDriver.extraValueText == (Object)null))
				{
					ConfigureSideText(teammateBarDriver.extraValueText.rectTransform, flag);
					teammateBarDriver.extraValueText.alignment = (TextAlignmentOptions)(flag ? 4097 : 4100);
				}
			}
		}

		private static void ConfigureSideText(RectTransform rt, bool rightSide)
		{
			//IL_006e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0083: Unknown result type (might be due to invalid IL or missing references)
			//IL_0098: 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_0018: 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_0042: Unknown result type (might be due to invalid IL or missing references)
			//IL_0057: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c2: Unknown result type (might be due to invalid IL or missing references)
			if (!((Object)(object)rt == (Object)null))
			{
				if (rightSide)
				{
					rt.anchorMin = new Vector2(1f, 0.5f);
					rt.anchorMax = new Vector2(1f, 0.5f);
					rt.pivot = new Vector2(0f, 0.5f);
					rt.anchoredPosition = new Vector2(8f, 0f);
				}
				else
				{
					rt.anchorMin = new Vector2(0f, 0.5f);
					rt.anchorMax = new Vector2(0f, 0.5f);
					rt.pivot = new Vector2(1f, 0.5f);
					rt.anchoredPosition = new Vector2(-8f, 0f);
				}
				rt.sizeDelta = new Vector2(120f, 24f);
			}
		}

		private TMP_Text AddSideText(RectTransform host, string name, bool rightSide, Color color, float fontSize = 16f)
		{
			//IL_0024: Unknown result type (might be due to invalid IL or missing references)
			//IL_002a: Expected O, but got Unknown
			//IL_0079: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a3: Unknown result type (might be due to invalid IL or missing references)
			try
			{
				if ((Object)(object)host == (Object)null)
				{
					return null;
				}
				GameObject val = new GameObject(name, new Type[1] { typeof(RectTransform) });
				val.transform.SetParent((Transform)(object)host, false);
				ConfigureSideText(val.GetComponent<RectTransform>(), rightSide);
				TextMeshProUGUI obj = val.AddComponent<TextMeshProUGUI>();
				((TMP_Text)obj).font = FontHelper.GetChineseCapable();
				((TMP_Text)obj).fontSize = fontSize;
				((TMP_Text)obj).fontStyle = (FontStyles)1;
				((TMP_Text)obj).alignment = (TextAlignmentOptions)(rightSide ? 4097 : 4100);
				((Graphic)obj).color = color;
				((Graphic)obj).raycastTarget = false;
				((TMP_Text)obj).textWrappingMode = (TextWrappingModes)0;
				((TMP_Text)obj).overflowMode = (TextOverflowModes)0;
				TmpOutlineHelper.Apply((TMP_Text)(object)obj, 0.08f, new Color32((byte)0, (byte)0, (byte)0, (byte)220));
				((TMP_Text)obj).text = string.Empty;
				val.SetActive(false);
				return (TMP_Text)(object)obj;
			}
			catch (Exception ex)
			{
				PluginLogger.ThrottleWarn("side_text_" + name, "AddSideText failed: " + ex.Message);
				return null;
			}
		}

		private TMP_Text TryAddNameLabel(GameObject cloneGo)
		{
			//IL_0018: 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_002f: 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_0055: 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_007f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0093: 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)
			try
			{
				GameObject val = new GameObject("TeammateNameLabel", new Type[1] { typeof(RectTransform) });
				val.transform.SetParent(cloneGo.transform, false);
				RectTransform component = val.GetComponent<RectTransform>();
				component.anchorMin = new Vector2(0f, 0.5f);
				component.anchorMax = new Vector2(0f, 0.5f);
				component.pivot = new Vector2(0f, 0.5f);
				component.sizeDelta = new Vector2(240f, 22f);
				component.anchoredPosition = new Vector2(0f, 52f);
				TextMeshProUGUI obj = val.AddComponent<TextMeshProUGUI>();
				((TMP_Text)obj).font = FontHelper.GetChineseCapable();
				((TMP_Text)obj).fontSize = 18f;
				((TMP_Text)obj).fontStyle = (FontStyles)1;
				((TMP_Text)obj).alignment = (TextAlignmentOptions)4097;
				((Graphic)obj).raycastTarget = false;
				((TMP_Text)obj).textWrappingMode = (TextWrappingModes)0;
				TmpOutlineHelper.Apply((TMP_Text)(object)obj, 0.08f, new Color32((byte)0, (byte)0, (byte)0, (byte)200));
				((TMP_Text)obj).text = string.Empty;
				return (TMP_Text)(object)obj;
			}
			catch (Exception ex)
			{
				PluginLogger.ThrottleWarn("name_label", "AddNameLabel failed: " + ex.Message);
				return null;
			}
		}

		private static void CleanupClonedPatchArtifacts(Transform root)
		{
			if ((Object)(object)root == (Object)null)
			{
				return;
			}
			try
			{
				Transform[] componentsInChildren = ((Component)root).GetComponentsInChildren<Transform>(true);
				foreach (Transform val in componentsInChildren)
				{
					if (!((Object)(object)val == (Object)null) && !((Object)(object)val == (Object)(object)root))
					{
						string name = ((Object)val).name;
						if (!string.IsNullOrEmpty(name) && name.StartsWith("PI_Local"))
						{
							Object.Destroy((Object)(object)((Component)val).gameObject);
						}
					}
				}
			}
			catch (Exception ex)
			{
				PluginLogger.ThrottleWarn("clone_cleanup", "CleanupClonedPatchArtifacts failed: " + ex.Message);
			}
		}

		private static void TryBackfillExtraBarFields(TeammateBarDriver driver, Transform root, StaminaBar origBar)
		{
			if ((Object)(object)driver == (Object)null || (Object)(object)root == (Object)null)
			{
				return;
			}
			try
			{
				if ((Object)(object)driver.extraBar != (Object)null && !((Transform)driver.extraBar).IsChildOf(root))
				{
					driver.extraBar = null;
				}
				if ((Object)(object)driver.extraBarStamina != (Object)null && !((Transform)driver.extraBarStamina).IsChildOf(root))
				{
					driver.extraBarStamina = null;
				}
				if ((Object)(object)driver.extraBarOutline != (Object)null && !((Transform)driver.extraBarOutline).IsChildOf(root))
				{
					driver.extraBarOutline = null;
				}
				if ((Object)(object)driver.extraStaminaGlow != (Object)null && !((Component)driver.extraStaminaGlow).transform.IsChildOf(root))
				{
					driver.extraStaminaGlow = null;
				}
				if ((Object)(object)driver.staminaGlow != (Object)null && !((Component)driver.staminaGlow).transform.IsChildOf(root))
				{
					driver.staminaGlow = null;
				}
				if ((Object)(object)driver.fullBar != (Object)null && !((Transform)driver.fullBar).IsChildOf(root))
				{
					driver.fullBar = null;
				}
				if ((Object)(object)driver.staminaBar != (Object)null && !((Transform)driver.staminaBar).IsChildOf(root))
				{
					driver.staminaBar = null;
				}
				if ((Object)(object)driver.maxStaminaBar != (Object)null && !((Transform)driver.maxStaminaBar).IsChildOf(root))
				{
					driver.maxStaminaBar = null;
				}
				if ((Object)(object)driver.staminaBarOutline != (Object)null && !((Transform)driver.staminaBarOutline).IsChildOf(root))
				{
					driver.staminaBarOutline = null;
				}
				if ((Object)(object)driver.staminaBarOutlineOverflowBar != (Object)null && !((Transform)driver.staminaBarOutlineOverflowBar).IsChildOf(root))
				{
					driver.staminaBarOutlineOverflowBar = null;
				}
				if ((Object)(object)driver.backing != (Object)null && !((Component)driver.backing).transform.IsChildOf(root))
				{
					driver.backing = null;
				}
				if ((Object)(object)driver.shield != (Object)null && !driver.shield.transform.IsChildOf(root))
				{
					driver.shield = null;
				}
				if ((Object)(object)driver.campfire != (Object)null && !driver.campfire.transform.IsChildOf(root))
				{
					driver.campfire = null;
				}
				RectTransform[] componentsInChildren = ((Component)root).GetComponentsInChildren<RectTransform>(true);
				try
				{
					StringBuilder stringBuilder = new StringBuilder();
					stringBuilder.Append("[CloneDump] ").Append(((Object)root).name).Append(" tree:");
					foreach (RectTransform val in componentsInChildren)
					{
						if (!((Object)(object)val == (Object)null))
						{
							stringBuilder.Append(" ").Append(((Object)val).name);
						}
					}
					PluginLogger.Debug(stringBuilder.ToString());
				}
				catch
				{
				}
				foreach (RectTransform val2 in componentsInChildren)
				{
					if ((Object)(object)val2 == (Object)null || (Object)(object)val2 == (Object)(object)root)
					{
						continue;
					}
					string name = ((Object)val2).name;
					if (string.IsNullOrEmpty(name))
					{
						continue;
					}
					string text = name.ToLowerInvariant();
					if (text.Contains("extra"))
					{
						if ((Object)(object)driver.extraBarOutline == (Object)null && text.Contains("outline"))
						{
							driver.extraBarOutline = val2;
						}
						else if ((Object)(object)driver.extraBarStamina == (Object)null && text.Contains("stamina"))
						{
							driver.extraBarStamina = val2;
						}
						else if ((Object)(object)driver.extraBar == (Object)null && !text.Contains("outline") && !text.Contains("glow"))
						{
							driver.extraBar = val2;
						}
					}
					if ((Object)(object)driver.fullBar == (Object)null && text == "fullbar")
					{
						driver.fullBar = val2;
					}
					if ((Object)(object)driver.staminaBar == (Object)null && (text == "staminabar" || text == "stamina"))
					{
						driver.staminaBar = val2;
					}
					if ((Object)(object)driver.maxStaminaBar == (Object)null && text.Contains("maxstamina"))
					{
						driver.maxStaminaBar = val2;
					}
					if ((Object)(object)driver.staminaBarOutline == (Object)null && (text == "staminabaroutline" || text == "outline"))
					{
						driver.staminaBarOutline = val2;
					}
				}
				if ((Object)(object)driver.extraStaminaGlow == (Object)null)
				{
					Image[] componentsInChildren2 = ((Component)root).GetComponentsInChildren<Image>(true);
					foreach (Image val3 in componentsInChildren2)
					{
						if (!((Object)(object)val3 == (Object)null))
						{
							string text2 = (((Object)val3).name ?? string.Empty).ToLowerInvariant();
							if (text2.Contains("extra") && text2.Contains("glow"))
							{
								driver.extraStaminaGlow = val3;
								break;
							}
						}
					}
				}
				if ((Object)(object)driver.extraBar == (Object)null || (Object)(object)driver.extraBarStamina == (Object)null)
				{
					BuildExtraBarFromOrig(driver, root, origBar);
				}
				PluginLogger.Debug("[CloneExtra] extraBar=" + (((Object)(object)driver.extraBar != (Object)null) ? ((Object)driver.extraBar).name : "null") + " extraBarStamina=" + (((Object)(object)driver.extraBarStamina != (Object)null) ? ((Object)driver.extraBarStamina).name : "null") + " extraBarOutline=" + (((Object)(object)driver.extraBarOutline != (Object)null) ? ((Object)driver.extraBarOutline).name : "null") + " fullBar=" + (((Object)(object)driver.fullBar != (Object)null) ? ((Object)driver.fullBar).name : "null") + " staminaBar=" + (((Object)(object)driver.staminaBar != (Object)null) ? ((Object)driver.staminaBar).name : "null"));
			}
			catch (Exception ex)
			{
				PluginLogger.ThrottleWarn("backfill_extra", "TryBackfillExtraBarFields failed: " + ex.Message);
			}
		}

		private static void BuildExtraBarFromOrig(TeammateBarDriver driver, Transform root, StaminaBar origBar)
		{
			//IL_019c: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b2: 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_00ae: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00cf: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d4: Unknown result type (might be due to invalid IL or missing references)
			//IL_011b: 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_0135: Unknown result type (might be due to invalid IL or missing references)
			//IL_0142: Unknown result type (might be due to invalid IL or missing references)
			//IL_014f: 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_0167: Unknown result type (might be due to invalid IL or missing references)
			//IL_0172: Unknown result type (might be due to invalid IL or missing references)
			//IL_0177: Unknown result type (might be due to invalid IL or missing references)
			//IL_017c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0185: Unknown result type (might be due to invalid IL or missing references)
			//IL_018a: Unknown result type (might be due to invalid IL or missing references)
			//IL_018c: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)driver == (Object)null || (Object)(object)root == (Object)null)
			{
				return;
			}
			try
			{
				if ((Object)(object)origBar != (Object)null && (Object)(object)origBar.extraBar != (Object)null)
				{
					RectTransform extraBar = origBar.extraBar;
					Transform parent = ((Transform)extraBar).parent;
					string[] obj = new string[10]
					{
						"[ExtraBuild] origParent=",
						((Object)(object)parent != (Object)null) ? ((Object)parent).name : "null",
						" origBar=",
						((Object)origBar).name,
						" origBar.fullBar=",
						((Object)(object)origBar.fullBar != (Object)null) ? ((Object)origBar.fullBar).name : "null",
						" origExtra.size=",
						null,
						null,
						null
					};
					Vector2 val = extraBar.sizeDelta;
					obj[7] = ((object)(Vector2)(ref val)).ToString();
					obj[8] = " origExtra.pos=";
					val = extraBar.anchoredPosition;
					obj[9] = ((object)(Vector2)(ref val)).ToString();
					PluginLogger.Debug(string.Concat(obj));
					GameObject val2 = Object.Instantiate<GameObject>(((Component)extraBar).gameObject, root, false);
					((Object)val2).name = "PI_ExtraBar";
					val2.SetActive(false);
					RectTransform component = val2.GetComponent<RectTransform>();
					component.anchorMin = extraBar.anchorMin;
					component.anchorMax = extraBar.anchorMax;
					component.pivot = extraBar.pivot;
					component.sizeDelta = extraBar.sizeDelta;
					((Transform)component).localScale = ((Transform)extraBar).localScale;
					((Transform)component).localRotation = ((Transform)extraBar).localRotation;
					try
					{
						Vector3 val3 = ((Transform)extraBar).position - ((Component)origBar).transform.position;
						val2.transform.position = root.position + val3;
					}
					catch
					{
						component.anchoredPosition = extraBar.anchoredPosition;
					}
					driver.extraBar = component;
					driver.extraBarInitialSize = extraBar.sizeDelta;
					string text = (((Object)(object)origBar.extraBarStamina != (Object)null) ? ((Object)origBar.extraBarStamina).name : null);
					string text2 = (((Object)(object)origBar.extraBarOutline != (Object)null) ? ((Object)origBar.extraBarOutline).name : null);
					string text3 = (((Object)(object)origBar.extraStaminaGlow != (Object)null) ? ((Object)origBar.extraStaminaGlow).name : null);
					RectTransform[] componentsInChildren = ((Component)component).GetComponentsInChildren<RectTransform>(true);
					foreach (RectTransform val4 in componentsInChildren)
					{
						if (!((Object)(object)val4 == (Object)null) && !((Object)(object)val4 == (Object)(object)component))
						{
							if ((Object)(object)driver.extraBarStamina == (Object)null && text != null && ((Object)val4).name == text)
							{
								driver.extraBarStamina = val4;
							}
							if ((Object)(object)driver.extraBarOutline == (Object)null && text2 != null && ((Object)val4).name == text2)
							{
								driver.extraBarOutline = val4;
							}
						}
					}
					if (text3 != null)
					{
						Image[] componentsInChildren2 = ((Component)component).GetComponentsInChildren<Image>(true);
						for (int j = 0; j < componentsInChildren2.Length; j++)
						{
							if ((Object)(object)componentsInChildren2[j] != (Object)null && ((Object)componentsInChildren2[j]).name == text3)
							{
								driver.extraStaminaGlow = componentsInChildren2[j];
								break;
							}
						}
					}
					PluginLogger.Debug("[ExtraBuild] cloned from orig under " + ((Object)root).name + " stam=" + (((Object)(object)driver.extraBarStamina != (Object)null) ? ((Object)driver.extraBarStamina).name : "null") + " outline=" + (((Object)(object)driver.extraBarOutline != (Object)null) ? ((Object)driver.extraBarOutline).name : "null"));
					return;
				}
			}
			catch (Exception ex)
			{
				PluginLogger.ThrottleWarn("extra_clone", "BuildExtraBarFromOrig clone failed: " + ex.Message);
			}
			BuildSimpleExtraBar(driver);
		}

		private static void BuildSimpleExtraBar(TeammateBarDriver driver)
		{
			//IL_0038: Unknown result type (might be due to invalid IL or missing references)
			//IL_003e: Expected O, but got Unknown
			//IL_0051: Unknown result type (might be due to invalid IL or missing references)
			//IL_0057: Expected O, but got Unknown
			//IL_0062: Unknown result type (might be due to invalid IL or missing references)
			//IL_0077: 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)
			//IL_00a1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ec: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f1: Unknown result type (might be due to invalid IL or missing references)
			//IL_0103: 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_010f: Expected O, but got Unknown
			//IL_011a: Unknown result type (might be due to invalid IL or missing references)
			//IL_012f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0144: 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_016e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0192: Unknown result type (might be due to invalid IL or missing references)
			//IL_01bb: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c0: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)driver == (Object)null || (Object)(object)driver.fullBar == (Object)null)
			{
				return;
			}
			try
			{
				RectTransform fullBar = driver.fullBar;
				GameObject val = new GameObject("PI_ExtraBar", new Type[1] { typeof(RectTransform) });
				val.transform.SetParent((Transform)(object)fullBar, false);
				RectTransform val2 = (RectTransform)val.transform;
				val2.anchorMin = new Vector2(1f, 0.5f);
				val2.anchorMax = new Vector2(1f, 0.5f);
				val2.pivot = new Vector2(0f, 0.5f);
				val2.anchoredPosition = new Vector2(6f, 0f);
				val2.sizeDelta = new Vector2(45f, 45f);
				val.SetActive(false);
				GameObject val3 = new GameObject("PI_ExtraStamina", new Type[2]
				{
					typeof(RectTransform),
					typeof(Image)
				});
				val3.transform.SetParent(val.transform, false);
				RectTransform val4 = (RectTransform)val3.transform;
				val4.anchorMin = new Vector2(0f, 0f);
				val4.anchorMax = new Vector2(0f, 1f);
				val4.pivot = new Vector2(0f, 0.5f);
				val4.anchoredPosition = new Vector2(0f, 0f);
				val4.sizeDelta = new Vector2(6f, 0f);
				Image component = val3.GetComponent<Image>();
				((Graphic)component).color = new Color(0.54f, 0.91f, 0.27f, 1f);
				((Graphic)component).raycastTarget = false;
				driver.extraBar = val2;
				driver.extraBarStamina = val4;
				driver.extraBarInitialSize = new Vector2(45f, 45f);
				PluginLogger.Debug("[ExtraBuild] PI_ExtraBar built under " + ((Object)fullBar).name);
			}
			catch (Exception ex)
			{
				PluginLogger.ThrottleWarn("extra_build", "BuildSimpleExtraBar failed: " + ex.Message);
			}
		}

		private TMP_Text AddAfflictionText(GameObject hostGo, string label)
		{
			//IL_002e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0033: Unknown result type (might be due to invalid IL or missing references)
			//IL_0045: Unknown result type (might be due to invalid IL or missing references)
			//IL_004c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0057: Unknown result type (might be due to invalid IL or missing references)
			//IL_0062: 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_00bf: Unknown result type (might be due to invalid IL or missing references)
			try
			{
				if ((Object)(object)hostGo == (Object)null)
				{
					return null;
				}
				GameObject val = new GameObject("PI_" + label, new Type[1] { typeof(RectTransform) });
				val.transform.SetParent(hostGo.transform, false);
				RectTransform component = val.GetComponent<RectTransform>();
				component.anchorMin = Vector2.zero;
				component.anchorMax = Vector2.one;
				component.offsetMin = Vector2.zero;
				component.offsetMax = Vector2.zero;
				TextMeshProUGUI obj = val.AddComponent<TextMeshProUGUI>();
				((TMP_Text)obj).font = FontHelper.GetChineseCapable();
				((TMP_Text)obj).fontSize = 16f;
				((TMP_Text)obj).fontStyle = (FontStyles)0;
				((TMP_Text)obj).alignment = (TextAlignmentOptions)514;
				((Graphic)obj).raycastTarget = false;
				((TMP_Text)obj).textWrappingMode = (TextWrappingModes)0;
				TmpOutlineHelper.Apply((TMP_Text)(object)obj, 0.08f, new Color32((byte)0, (byte)0, (byte)0, byte.MaxValue));
				((TMP_Text)obj).text = string.Empty;
				return (TMP_Text)(object)obj;
			}
			catch (Exception ex)
			{
				PluginLogger.ThrottleWarn("aff_text", "AddAfflictionText failed: " + ex.Message);
				return null;
			}
		}

		private TMP_Text AddValueText(GameObject hostGo, string label)
		{
			//IL_0037: Unknown result type (might be due to invalid IL or missing references)
			//IL_003c: Unknown result type (might be due to invalid IL or missing references)
			//IL_004e: 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_0060: 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_0075: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e3: Unknown result type (might be due to invalid IL or missing references)
			try
			{
				if ((Object)(object)hostGo == (Object)null)
				{
					return null;
				}
				hostGo.SetActive(true);
				GameObject val = new GameObject("PI_" + label, new Type[1] { typeof(RectTransform) });
				val.transform.SetParent(hostGo.transform, false);
				RectTransform component = val.GetComponent<RectTransform>();
				component.anchorMin = Vector2.zero;
				component.anchorMax = Vector2.one;
				component.offsetMin = Vector2.zero;
				component.offsetMax = Vector2.zero;
				TextMeshProUGUI obj = val.AddComponent<TextMeshProUGUI>();
				((TMP_Text)obj).font = FontHelper.GetChineseCapable();
				((TMP_Text)obj).fontSize = 20f;
				((TMP_Text)obj).fontStyle = (FontStyles)0;
				((TMP_Text)obj).alignment = (TextAlignmentOptions)514;
				((Graphic)obj).raycastTarget = false;
				((TMP_Text)obj).textWrappingMode = (TextWrappingModes)0;
				TmpOutlineHelper.Apply((TMP_Text)(object)obj, 0.08f, new Color32((byte)0, (byte)0, (byte)0, byte.MaxValue));
				((TMP_Text)obj).text = string.Empty;
				((TMP_Text)obj).transform.localScale = Vector3.one;
				return (TMP_Text)(object)obj;
			}
			catch (Exception ex)
			{
				PluginLogger.ThrottleWarn("value_text", "AddValueText failed: " + ex.Message);
				return null;
			}
		}

		public void ClearAll()
		{
			for (int i = 0; i < _pool.Count; i++)
			{
				TeammateBarDriver teammateBarDriver = _pool[i];
				if ((Object)(object)teammateBarDriver != (Object)null && (Object)(object)((Component)teammateBarDriver).gameObject != (Object)null)
				{
					Object.Destroy((Object)(object)((Component)teammateBarDriver).gameObject);
				}
			}
			_pool.Clear();
			_displayOrder.Clear();
			_pendingOrder.Clear();
			_pendingOrderSince = -1f;
			s_retainedById.Clear();
			s_viewIdToActor.Clear();
		}

		public void OnConfigChanged()
		{
			ClearAll();
			_nextRefreshTime = 0f;
		}

		private static int GetStableCharacterId(Character c)
		{
			if ((Object)(object)c == (Object)null || ((object)c).Equals((object?)null) || (Object)(object)((MonoBehaviourPun)c).photonView == (Object)null)
			{
				return int.MinValue;
			}
			int viewID = ((MonoBehaviourPun)c).photonView.ViewID;
			try
			{
				if (((MonoBehaviourPun)c).photonView.Owner != null)
				{
					int actorNumber = ((MonoBehaviourPun)c).photonView.Owner.ActorNumber;
					s_viewIdToActor[viewID] = actorNumber;
					return actorNumber;
				}
				if (s_viewIdToActor.TryGetValue(viewID, out var value))
				{
					return value;
				}
			}
			catch
			{
			}
			return viewID;
		}

		private void ResolveDisplayOrder(List<Character> desiredCharacters)
		{
			List<int> list = new List<int>(desiredCharacters.Count);
			for (int i = 0; i < desiredCharacters.Count; i++)
			{
				int stableCharacterId = GetStableCharacterId(desiredCharacters[i]);
				if (stableCharacterId != int.MinValue)
				{
					list.Add(stableCharacterId);
				}
			}
			if (!HasSameMembers(_displayOrder, list))
			{
				ApplyDisplayOrder(list);
			}
			else if (HasSameSequence(_displayOrder, list))
			{
				_pendingOrder.Clear();
				_pendingOrderSince = -1f;
			}
			else if (!HasSameSequence(_pendingOrder, list))
			{
				_pendingOrder.Clear();
				_pendingOrder.AddRange(list);
				_pendingOrderSince = Time.unscaledTime;
			}
			else if (_pendingOrderSince < 0f)
			{
				_pendingOrderSince = Time.unscaledTime;
			}
			else if (Time.unscaledTime - _pendingOrderSince >= 0.75f)
			{
				ApplyDisplayOrder(list);
			}
		}

		private void ApplyDisplayOrder(List<int> desiredIds)
		{
			_displayOrder.Clear();
			_displayOrder.AddRange(desiredIds);
			_pendingOrder.Clear();
			_pendingOrderSince = -1f;
		}

		private static bool HasSameMembers(List<int> left, List<int> right)
		{
			if (left.Count != right.Count)
			{
				return false;
			}
			for (int i = 0; i < left.Count; i++)
			{
				if (!right.Contains(left[i]))
				{
					return false;
				}
			}
			return true;
		}

		private static bool HasSameSequence(List<int> left, List<int> right)
		{
			if (left.Count != right.Count)
			{
				return false;
			}
			for (int i = 0; i < left.Count; i++)
			{
				if (left[i] != right[i])
				{
					return false;
				}
			}
			return true;
		}
	}
	internal class TeammateInventoryRow : MonoBehaviour
	{
		private struct SlotView
		{
			public GameObject root;

			public Image bg;

			public Image icon;

			public TextMeshProUGUI countText;

			public int lastPrefabId;

			public bool hidden;
		}

		public Character Target;

		private const int MainSlotCount = 3;

		private const int BackpackInnerCount = 4;

		private const int TotalSlots = 8;

		private readonly SlotView[] _slots = new SlotView[8];

		private float _nextRefreshTime;

		private const float RefreshInterval = 0.15f;

		private static readonly Color BgEmpty = new Color(0f, 0f, 0f, 0.45f);

		private static readonly Color BgFilled = new Color(0f, 0f, 0f, 0.6f);

		private static readonly Color BgBackpackInner = new Color(0.2f, 0.15f, 0.05f, 0.55f);

		public static TeammateInventoryRow Build(RectTransform parent, float totalWidth, float height, float spacing)
		{
			//IL_0018: 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_002a: Unknown result type (might be due to invalid IL or missing references)
			//IL_003c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0051: Unknown result type (might be due to invalid IL or missing references)
			//IL_0066: Unknown result type (might be due to invalid IL or missing references)
			//IL_0073: Unknown result type (might be due to invalid IL or missing references)
			GameObject val = new GameObject("InventoryRow", new Type[1] { typeof(RectTransform) });
			val.transform.SetParent((Transform)(object)parent, false);
			RectTransform component = val.GetComponent<RectTransform>();
			component.anchorMin = new Vector2(0f, 0.5f);
			component.anchorMax = new Vector2(0f, 0.5f);
			component.pivot = new Vector2(0f, 0.5f);
			component.sizeDelta = new Vector2(totalWidth, height);
			TeammateInventoryRow teammateInventoryRow = val.AddComponent<TeammateInventoryRow>();
			teammateInventoryRow.BuildSlots(component, totalWidth, height, spacing);
			return teammateInventoryRow;
		}

		private void BuildSlots(RectTransform root, float totalWidth, float height, float spacing)
		{
			//IL_0062: Unknown result type (might be due to invalid IL or missing references)
			//IL_0068: Expected O, but got Unknown
			//IL_0089: 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_00b5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c3: 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_00ff: 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_011b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0135: Unknown result type (might be due to invalid IL or missing references)
			//IL_0140: 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_0155: Unknown result type (might be due to invalid IL or missing references)
			//IL_0177: Unknown result type (might be due to invalid IL or missing references)
			//IL_017c: Unknown result type (might be due to invalid IL or missing references)
			//IL_01bb: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d0: 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_01e5: 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_020c: Unknown result type (might be due to invalid IL or missing references)
			//IL_021a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0221: Unknown result type (might be due to invalid IL or missing references)
			//IL_022c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0241: Unknown result type (might be due to invalid IL or missing references)
			//IL_0255: Unknown result type (might be due to invalid IL or missing references)
			//IL_0294: Unknown result type (might be due to invalid IL or missing references)
			float num = height;
			float num2 = 8f * num + 7f * spacing;
			float num3 = 0f;
			if (num2 > totalWidth)
			{
				num = (totalWidth - 7f * spacing) / 8f;
				num = Mathf.Max(num, 12f);
			}
			for (int i = 0; i < 8; i++)
			{
				GameObject val = new GameObject($"Slot{i}", new Type[1] { typeof(RectTransform) });
				val.transform.SetParent((Transform)(object)root, false);
				RectTransform component = val.GetComponent<RectTransform>();
				component.anchorMin = new Vector2(0f, 0.5f);
				component.anchorMax = new Vector2(0f, 0.5f);
				component.pivot = new Vector2(0f, 0.5f);
				component.sizeDelta = new Vector2(num, num);
				component.anchoredPosition = new Vector2(num3 + (float)i * (num + spacing), 0f);
				GameObject val2 = new GameObject("Bg", new Type[1] { typeof(RectTransform) });
				val2.transform.SetParent((Transform)(object)component, false);
				Image val3 = val2.AddComponent<Image>();
				((Graphic)val3).color = BgEmpty;
				((Graphic)val3).raycastTarget = false;
				RectTransform rectTransform = ((Graphic)val3).rectTransform;
				rectTransform.anchorMin = Vector2.zero;
				rectTransform.anchorMax = Vector2.one;
				rectTransform.offsetMin = Vector2.zero;
				rectTransform.offsetMax = Vector2.zero;
				GameObject val4 = new GameObject("Icon", new Type[1] { typeof(RectTransform) });
				val4.transform.SetParent((Transform)(object)component, false);
				Image val5 = val4.AddComponent<Image>();
				((Graphic)val5).raycastTarget = false;
				val5.preserveAspect = true;
				((Behaviour)val5).enabled = false;
				RectTransform rectTransform2 = ((Graphic)val5).rectTransform;
				rectTransform2.anchorMin = new Vector2(0.1f, 0.1f);
				rectTransform2.anchorMax = new Vector2(0.9f, 0.9f);
				rectTransform2.offsetMin = Vector2.zero;
				rectTransform2.offsetMax = Vector2.zero;
				GameObject val6 = new GameObject("Count", new Type[1] { typeof(RectTransform) });
				val6.transform.SetParent((Transform)(object)component, false);
				RectTransform component2 = val6.GetComponent<RectTransform>();
				component2.anchorMin = Vector2.zero;
				component2.anchorMax = Vector2.one;
				component2.offsetMin = new Vector2(0f, 0f);
				component2.offsetMax = new Vector2(-1f, 0f);
				TextMeshProUGUI val7 = val6.AddComponent<TextMeshProUGUI>();
				((TMP_Text)val7).alignment = (TextAlignmentOptions)1028;
				((TMP_Text)val7).fontSize = Mathf.Max(8f, num * 0.45f);
				((TMP_Text)val7).fontStyle = (FontStyles)1;
				((Graphic)val7).color = Color.white;
				((Graphic)val7).raycastTarget = false;
				((TMP_Text)val7).text = string.Empty;
				_slots[i] = new SlotView
				{
					root = val,
					bg = val3,
					icon = val5,
					countText = val7,
					lastPrefabId = 0,
					hidden = false
				};
			}
		}

		private void LateUpdate()
		{
			if (Time.unscaledTime < _nextRefreshTime)
			{
				return;
			}
			_nextRefreshTime = Time.unscaledTime + 0.15f;
			try
			{
				RefreshAll();
			}
			catch (Exception ex)
			{
				PluginLogger.ThrottleError("inv_refresh", "Inventory refresh failed: " + ex.Message);
			}
		}

		private void RefreshAll()
		{
			//IL_0076: 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_00a1: Unknown result type (might be due to inv