Decompiled source of DamageAnalyzer v1.4.0

BepInEx/plugins/Hikaria.DamageAnalyzer/Hikaria.DamageAnalyzer.dll

Decompiled 2 months ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Runtime.Versioning;
using System.Text;
using Agents;
using BepInEx;
using BepInEx.Unity.IL2CPP;
using BepInEx.Unity.IL2CPP.Utils;
using Enemies;
using GTFO.API;
using GameData;
using Gear;
using Hikaria.DamageAnalyzer.Features;
using Hikaria.DamageAnalyzer.Handlers;
using Hikaria.DamageAnalyzer.Managers;
using Il2CppInterop.Runtime.InteropTypes;
using Il2CppInterop.Runtime.InteropTypes.Arrays;
using Microsoft.CodeAnalysis;
using Player;
using SNetwork;
using TMPro;
using TheArchive;
using TheArchive.Core;
using TheArchive.Core.Attributes;
using TheArchive.Core.Attributes.Feature.Settings;
using TheArchive.Core.FeaturesAPI;
using TheArchive.Core.Localization;
using TheArchive.Core.Models;
using TheArchive.Core.ModulesAPI;
using TheArchive.Interfaces;
using TheArchive.Loader;
using TheArchive.Utilities;
using UnityEngine;
using UnityEngine.UI;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: AssemblyTrademark("")]
[assembly: ComVisible(false)]
[assembly: Guid("b1fb651e-5d42-4e24-8688-33d2e80ebef4")]
[assembly: TargetFramework(".NETCoreApp,Version=v6.0", FrameworkDisplayName = ".NET 6.0")]
[assembly: AssemblyVersion("0.0.0.0")]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	[AttributeUsage(AttributeTargets.Class | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Parameter | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter, AllowMultiple = false, Inherited = false)]
	internal sealed class NullableAttribute : Attribute
	{
		public readonly byte[] NullableFlags;

		public NullableAttribute(byte P_0)
		{
			NullableFlags = new byte[1] { P_0 };
		}

		public NullableAttribute(byte[] P_0)
		{
			NullableFlags = P_0;
		}
	}
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	[AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Method | AttributeTargets.Interface | AttributeTargets.Delegate, AllowMultiple = false, Inherited = false)]
	internal sealed class NullableContextAttribute : Attribute
	{
		public readonly byte Flag;

		public NullableContextAttribute(byte P_0)
		{
			Flag = P_0;
		}
	}
}
namespace Hikaria.DamageAnalyzer
{
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[BepInPlugin("Hikaria.DamageAnalyzer", "DamageAnalyzer", "1.4.0")]
	public class EntryPoint : BasePlugin, IArchiveModule
	{
		public static EntryPoint Instance { get; private set; }

		public bool ApplyHarmonyPatches => false;

		public bool UsesLegacyPatches => false;

		public ArchiveLegacyPatcher Patcher { get; set; }

		public string ModuleGroup => "Damage Analyzer";

		public Dictionary<Language, string> ModuleGroupLanguages => new Dictionary<Language, string>
		{
			{
				(Language)1,
				"伤害分析器"
			},
			{
				(Language)0,
				"Damage Analyzer"
			}
		};

		public override void Load()
		{
			Instance = this;
			ArchiveMod.RegisterArchiveModule(typeof(EntryPoint));
			Logs.LogMessage("OK");
		}

		public void Init()
		{
		}

		public void OnSceneWasLoaded(int buildIndex, string sceneName)
		{
		}

		public void OnLateUpdate()
		{
		}

		public void OnExit()
		{
		}
	}
	internal static class Logs
	{
		private static IArchiveLogger _logger;

		private static IArchiveLogger Logger => _logger ?? (_logger = LoaderWrapper.CreateLoggerInstance("Hikaria.DamageAnalyzer", ConsoleColor.White));

		public static void LogDebug(object data)
		{
			Logger.Debug(data.ToString());
		}

		public static void LogError(object data)
		{
			Logger.Error(data.ToString());
		}

		public static void LogInfo(object data)
		{
			Logger.Info(data.ToString());
		}

		public static void LogMessage(object data)
		{
			Logger.Msg(ConsoleColor.White, data.ToString());
		}

		public static void LogWarning(object data)
		{
			Logger.Warning(data.ToString());
		}

		public static void LogNotice(object data)
		{
			Logger.Notice(data.ToString());
		}

		public static void LogSuccess(object data)
		{
			Logger.Success(data.ToString());
		}

		public static void LogException(Exception ex)
		{
			Logger.Exception(ex);
		}
	}
	public static class PluginInfo
	{
		public const string GUID = "Hikaria.DamageAnalyzer";

		public const string NAME = "DamageAnalyzer";

		public const string VERSION = "1.4.0";
	}
}
namespace Hikaria.DamageAnalyzer.Managers
{
	public static class DamageInfoManager
	{
		public struct pRegisterDamageInfoReceiver
		{
			public pPlayer player;

			public pRegisterDamageInfoReceiver(SNet_Player player)
			{
				//IL_0006: Unknown result type (might be due to invalid IL or missing references)
				this.player = default(pPlayer);
				((pPlayer)(ref this.player)).SetPlayer(player);
			}
		}

		public struct pDamageInfo
		{
			public pPlayer player;

			public BasicDamageInfo damageInfo;

			public pDamageInfo(SNet_Player player, BasicDamageInfo damageInfo)
			{
				//IL_0006: Unknown result type (might be due to invalid IL or missing references)
				this.player = default(pPlayer);
				((pPlayer)(ref this.player)).SetPlayer(player);
				this.damageInfo = damageInfo;
			}
		}

		public struct BasicDamageInfo
		{
			public pPlayer player;

			public pEnemyAgent enemy;

			public float rawDamage;

			public int limbID;

			public bool allowDirectionalBonus;

			public bool isSleepMulti;

			public float staggerMulti;

			public float precisionMulti;

			public float backstabberMulti;

			public float sleeperMulti;

			public DamageType damageType;

			public DamageSource damageSource;

			public Vector3 position;

			public Vector3 direction;

			public BasicDamageInfo(SNet_Player player, DamageType damageType, DamageSource damageSource, Dam_EnemyDamageLimb limb, Vector3 position, Vector3 direction, float rawDamage, bool allowDirectionalBonus = false, float staggerMulti = 1f, float precisionMulti = 1f, float backstabberMulti = 1f, float sleeperMulti = 1f, bool isSleepMulti = false)
			{
				//IL_0006: Unknown result type (might be due to invalid IL or missing references)
				//IL_002c: Unknown result type (might be due to invalid IL or missing references)
				//IL_0057: Unknown result type (might be due to invalid IL or missing references)
				//IL_0059: Unknown result type (might be due to invalid IL or missing references)
				//IL_005f: Unknown result type (might be due to invalid IL or missing references)
				//IL_0061: Unknown result type (might be due to invalid IL or missing references)
				this.player = default(pPlayer);
				((pPlayer)(ref this.player)).SetPlayer(player);
				this.damageType = damageType;
				this.damageSource = damageSource;
				enemy = default(pEnemyAgent);
				((pEnemyAgent)(ref enemy)).Set(limb.m_base.Owner);
				limbID = limb.m_limbID;
				this.position = position;
				this.direction = direction;
				this.rawDamage = rawDamage;
				this.allowDirectionalBonus = allowDirectionalBonus;
				this.staggerMulti = staggerMulti;
				this.precisionMulti = precisionMulti;
				this.backstabberMulti = backstabberMulti;
				this.sleeperMulti = sleeperMulti;
				this.isSleepMulti = isSleepMulti;
			}
		}

		public enum DamageType : byte
		{
			Bullet,
			Melee
		}

		public enum DamageSource : byte
		{
			SentryGun,
			Player
		}

		public static bool ShowSentryDamage = true;

		private static List<ulong> DamageInfoReceivers = new List<ulong>();

		public static uint LocalAgentGlobalID;

		public static bool IsSleepMulti;

		public static bool IsSentryGunFire;

		public static Dictionary<ulong, float> OriginalBulletDamage = new Dictionary<ulong, float>();

		public static bool DoBulletDamage;

		public static void Setup()
		{
			NetworkAPI.RegisterEvent<pDamageInfo>(typeof(pDamageInfo).FullName, (Action<ulong, pDamageInfo>)ReceiveDamageInfo);
			NetworkAPI.RegisterEvent<pRegisterDamageInfoReceiver>(typeof(pRegisterDamageInfoReceiver).FullName, (Action<ulong, pRegisterDamageInfoReceiver>)ReceiveRequestRegisterDamageInfoReceiver);
		}

		public static void OnPlayerEvent(SNet_Player player)
		{
			if (!((Object)(object)player == (Object)null) && player.PlayerSlotIndex() >= 0 && player.IsLocal && !SNet.IsMaster)
			{
				RequestRegisterDamageInfoReceiver();
			}
		}

		public static void OnMasterChanged()
		{
			if (!SNet.IsMaster)
			{
				RequestRegisterDamageInfoReceiver();
			}
		}

		public static void SendDamageInfo(BasicDamageInfo damageInfo, SNet_Player player)
		{
			pDamageInfo pDamageInfo = new pDamageInfo(player, damageInfo);
			NetworkAPI.InvokeEvent<pDamageInfo>(typeof(pDamageInfo).FullName, pDamageInfo, player, (SNet_ChannelType)4);
		}

		private static void ReceiveDamageInfo(ulong senderID, pDamageInfo data)
		{
			SNet_Player val = default(SNet_Player);
			SNet_Player val2 = default(SNet_Player);
			if (((pPlayer)(ref data.player)).TryGetPlayer(ref val) && val.IsLocal && SNet.TryGetPlayer(senderID, ref val2) && val2.IsMaster)
			{
				OriginalBulletDamage[val.Lookup] = data.damageInfo.rawDamage;
				ProcessDamageInfo(data.damageInfo);
			}
		}

		private static void ReceiveRequestRegisterDamageInfoReceiver(ulong senderID, pRegisterDamageInfoReceiver data)
		{
			SNet_Player val = default(SNet_Player);
			if (((pPlayer)(ref data.player)).TryGetPlayer(ref val) && val.Lookup == senderID && SNet.IsMaster && !DamageInfoReceivers.Contains(senderID))
			{
				DamageInfoReceivers.Add(senderID);
			}
		}

		public static void RequestRegisterDamageInfoReceiver()
		{
			if (!SNet.IsMaster)
			{
				pRegisterDamageInfoReceiver pRegisterDamageInfoReceiver = new pRegisterDamageInfoReceiver(SNet.LocalPlayer);
				NetworkAPI.InvokeEvent<pRegisterDamageInfoReceiver>(typeof(pRegisterDamageInfoReceiver).FullName, pRegisterDamageInfoReceiver, SNet.Master, (SNet_ChannelType)4);
			}
		}

		public static void ProcessDamageInfo(BasicDamageInfo damageInfo)
		{
			//IL_007f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0084: Unknown result type (might be due to invalid IL or missing references)
			//IL_0087: 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_00a6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ac: Invalid comparison between Unknown and I4
			//IL_00b4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ba: Invalid comparison between Unknown and I4
			//IL_013d: 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)
			SNet_Player val = default(SNet_Player);
			EnemyAgent val2 = default(EnemyAgent);
			if (!((pPlayer)(ref damageInfo.player)).TryGetPlayer(ref val) || !((pEnemyAgent)(ref damageInfo.enemy)).TryGet(ref val2))
			{
				return;
			}
			Dam_EnemyDamageLimb val3 = ((Il2CppArrayBase<Dam_EnemyDamageLimb>)(object)val2.Damage.DamageLimbs)[damageInfo.limbID];
			float rawDamage = damageInfo.rawDamage;
			bool isCrit = false;
			bool isArmor = false;
			bool isBackMulti = false;
			bool isSleepMulti = damageInfo.isSleepMulti;
			bool isImortal = val2.Damage.IsImortal;
			bool allowDirectionalBonus = damageInfo.allowDirectionalBonus;
			float precisionMulti = damageInfo.precisionMulti;
			float sleeperMulti = damageInfo.sleeperMulti;
			float backstabberMulti = damageInfo.backstabberMulti;
			Vector3 direction = damageInfo.direction;
			Vector3 position = damageInfo.position;
			DamageType damageType = damageInfo.damageType;
			DamageSource damageSource = damageInfo.damageSource;
			if ((Object)(object)val3 != (Object)null)
			{
				if ((int)val3.m_type == 1)
				{
					isCrit = true;
				}
				else if ((int)val3.m_type == 2)
				{
					isArmor = true;
				}
			}
			if (damageType == DamageType.Bullet)
			{
				if (damageSource == DamageSource.SentryGun)
				{
					if (!val.IsLocal)
					{
						if (SNet.IsMaster && DamageInfoReceivers.Contains(val.Lookup))
						{
							SendDamageInfo(damageInfo, val);
						}
						return;
					}
					if (val.IsLocal && !ShowSentryDamage)
					{
						return;
					}
				}
				rawDamage = AgentModifierManager.ApplyModifier((Agent)(object)val2, (AgentModifier)7, OriginalBulletDamage[val.Lookup]);
			}
			else
			{
				rawDamage = AgentModifierManager.ApplyModifier((Agent)(object)val2, (AgentModifier)6, rawDamage);
				if (isSleepMulti)
				{
					rawDamage *= sleeperMulti;
				}
			}
			rawDamage = val3.ApplyWeakspotAndArmorModifiers(rawDamage, precisionMulti);
			if (allowDirectionalBonus)
			{
				float num = rawDamage;
				rawDamage = val3.ApplyDamageFromBehindBonus(rawDamage, position, direction, backstabberMulti);
				if (rawDamage > num)
				{
					isBackMulti = true;
				}
			}
			DamageInfoDisplay.Instance.UpdateBasicDamageInfo(val3, isImortal, isArmor, isCrit, isBackMulti, IsSleepMulti, rawDamage);
		}
	}
	internal static class TranslateManager
	{
		public struct EnemyIDName
		{
			public List<uint> IDs;

			public string Name;
		}

		private struct EnemyLimbName
		{
			public string Contain;

			public string Name;
		}

		private static CustomSetting<List<EnemyIDName>> EnemyIDNameSettings = new CustomSetting<List<EnemyIDName>>("EnemyIDNames", new List<EnemyIDName>(), (Action<List<EnemyIDName>>)delegate(List<EnemyIDName> data)
		{
			EnemyID2NameLookup = new Dictionary<uint, string>();
			foreach (EnemyIDName datum in data)
			{
				foreach (uint iD in datum.IDs)
				{
					EnemyID2NameLookup[iD] = datum.Name;
				}
			}
		}, (LoadingTime)1, true);

		private static CustomSetting<List<EnemyLimbName>> EnemyLimbNameSettings = new CustomSetting<List<EnemyLimbName>>("EnemyLimbNames", new List<EnemyLimbName>(), (Action<List<EnemyLimbName>>)delegate(List<EnemyLimbName> data)
		{
			EnemyLimbNamesLookup = data.ToDictionary((EnemyLimbName x) => x.Contain.ToLower(), (EnemyLimbName x) => x.Name);
		}, (LoadingTime)1, true);

		private static Dictionary<string, string> EnemyLimbNamesLookup;

		private static Dictionary<uint, string> EnemyID2NameLookup;

		public static string KILL => ((Feature)Hikaria.DamageAnalyzer.Features.DamageAnalyzer.Instance).Localization.Get(1u);

		public static string IMMORTAL => ((Feature)Hikaria.DamageAnalyzer.Features.DamageAnalyzer.Instance).Localization.Get(2u);

		public static string UNKNOWN => ((Feature)Hikaria.DamageAnalyzer.Features.DamageAnalyzer.Instance).Localization.Get(3u);

		public static string ARMOR => ((Feature)Hikaria.DamageAnalyzer.Features.DamageAnalyzer.Instance).Localization.Get(4u);

		public static string CRIT => ((Feature)Hikaria.DamageAnalyzer.Features.DamageAnalyzer.Instance).Localization.Get(5u);

		public static string BACKMULTI => ((Feature)Hikaria.DamageAnalyzer.Features.DamageAnalyzer.Instance).Localization.Get(6u);

		public static string SLEEPMULTI => ((Feature)Hikaria.DamageAnalyzer.Features.DamageAnalyzer.Instance).Localization.Get(7u);

		public static string HITPOSITION_DESC => ((Feature)Hikaria.DamageAnalyzer.Features.DamageAnalyzer.Instance).Localization.Get(8u);

		public static string EnemyName(uint id)
		{
			if (!EnemyID2NameLookup.TryGetValue(id, out var value))
			{
				return $"{((GameDataBlockBase<EnemyDataBlock>)(object)GameDataBlockBase<EnemyDataBlock>.GetBlock(id)).name} [{id}]";
			}
			return value;
		}

		public static string EnemyLimb(string LimbName)
		{
			LimbName = LimbName.ToLower();
			if (EnemyLimbNamesLookup.Any(delegate(KeyValuePair<string, string> x)
			{
				if (LimbName.Contains(x.Key))
				{
					LimbName = x.Value;
					return true;
				}
				return false;
			}))
			{
				return LimbName;
			}
			return UNKNOWN;
		}
	}
}
namespace Hikaria.DamageAnalyzer.Handlers
{
	public class DamageInfoDisplay : MonoBehaviour
	{
		private bool Status;

		private float timer;

		private static StringBuilder sb = new StringBuilder(500);

		private Dam_EnemyDamageBase _dmgBase;

		private float _healthMax;

		private float _health;

		private bool _isImmortal;

		private string _limbName = string.Empty;

		private string _enemyName = string.Empty;

		private bool _isKill;

		private bool _isArmor;

		private bool _isCrit;

		private bool _isBackMulti;

		private bool _isSleepMulti;

		private float _damage;

		public static float LastingTime = 2.5f;

		public static int BarFontSize = 12;

		public static int HintFontSize = 12;

		public static int BarLength = 80;

		public static int OffsetX = 970;

		public static int OffsetY = 790;

		public static bool ShowHints = true;

		public static string BarFillChar_Remaining = "#";

		public static string BarFillChar_Losted = "-";

		public static bool ShowHPBar = true;

		public static bool ShowName = true;

		public static bool ShowLimb = true;

		public static bool ShowDamage = true;

		public static Color TextColor = new Color(1f, 1f, 0.8823f, 0.7059f);

		public static TextMeshPro TextMesh;

		public static DamageInfoDisplay Instance { get; private set; }

		public static TextMeshPro WatermarkTextPrefab => GuiManager.WatermarkLayer.m_watermark.m_watermarkText;

		private void Awake()
		{
			//IL_0049: 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_0076: Unknown result type (might be due to invalid IL or missing references)
			//IL_0085: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b8: Unknown result type (might be due to invalid IL or missing references)
			Instance = this;
			TextMesh = Object.Instantiate<TextMeshPro>(WatermarkTextPrefab);
			((Transform)((TMP_Text)TextMesh).rectTransform).SetParent(((Transform)((TMP_Text)WatermarkTextPrefab).rectTransform).parent);
			((Transform)((TMP_Text)TextMesh).rectTransform).localPosition = new Vector3((float)OffsetX, (float)OffsetY);
			((TMP_Text)TextMesh).rectTransform.sizeDelta = new Vector2(1920f, ((TMP_Text)TextMesh).rectTransform.sizeDelta.y);
			((Graphic)TextMesh).color = TextColor;
			((TMP_Text)TextMesh).alignment = (TextAlignmentOptions)257;
			((TMP_Text)TextMesh).SetText(string.Empty, true);
			((Transform)((TMP_Text)TextMesh).rectTransform).localScale = Vector3.zero;
			MonoBehaviourExtensions.StartCoroutine((MonoBehaviour)(object)this, UpdateTextCoroutine());
		}

		private void FixedUpdate()
		{
			//IL_0017: Unknown result type (might be due to invalid IL or missing references)
			if (timer >= LastingTime)
			{
				((Transform)((TMP_Text)TextMesh).rectTransform).localScale = Vector3.zero;
				Status = false;
			}
			if (Status)
			{
				timer += Time.fixedDeltaTime;
			}
		}

		private IEnumerator UpdateTextCoroutine()
		{
			WaitForSecondsRealtime yielder = new WaitForSecondsRealtime(0.05f);
			while (true)
			{
				if (Status)
				{
					UpdateDamageInfo();
				}
				yield return yielder;
			}
		}

		private void RestartTimer()
		{
			//IL_001c: Unknown result type (might be due to invalid IL or missing references)
			timer = 0f;
			Status = true;
			((Transform)((TMP_Text)TextMesh).rectTransform).localScale = Vector3.one;
		}

		public void UpdateBasicDamageInfo(Dam_EnemyDamageLimb dam_EnemyDamageLimb, bool isImmortal, bool isArmor, bool isCrit, bool isBackMulti, bool isSleepMulti, float damage)
		{
			_dmgBase = dam_EnemyDamageLimb.m_base;
			_limbName = TranslateManager.EnemyLimb(((Object)dam_EnemyDamageLimb).name);
			_enemyName = TranslateManager.EnemyName(_dmgBase.Owner.EnemyDataID);
			_isImmortal = isImmortal;
			_isArmor = isArmor;
			_isCrit = isCrit;
			_isBackMulti = isBackMulti;
			_isSleepMulti = isSleepMulti;
			_damage = damage;
			RestartTimer();
		}

		private void UpdateDamageInfo()
		{
			bool flag = (Object)(object)_dmgBase != (Object)null;
			if (flag)
			{
				_health = ((Dam_SyncedDamageBase)_dmgBase).Health;
				_healthMax = ((Dam_SyncedDamageBase)_dmgBase).HealthMax;
			}
			else
			{
				_health = 0f;
			}
			_health = Math.Max(_health, 0f);
			_health = (float)Math.Round(_health, 1);
			if (flag)
			{
				_isKill = !flag || ((Dam_SyncedDamageBase)_dmgBase).Health <= 0f;
			}
			else
			{
				_isKill = true;
			}
			StringBuilder stringBuilder = sb;
			StringBuilder stringBuilder2 = stringBuilder;
			StringBuilder.AppendInterpolatedStringHandler handler = new StringBuilder.AppendInterpolatedStringHandler(7, 1, stringBuilder);
			handler.AppendLiteral("<size=");
			handler.AppendFormatted(HintFontSize);
			handler.AppendLiteral(">");
			stringBuilder2.Append(ref handler);
			if (ShowName)
			{
				sb.Append(_enemyName);
			}
			if (ShowLimb)
			{
				if (ShowName)
				{
					stringBuilder = sb;
					StringBuilder stringBuilder3 = stringBuilder;
					handler = new StringBuilder.AppendInterpolatedStringHandler(3, 1, stringBuilder);
					handler.AppendLiteral(" (");
					handler.AppendFormatted(_limbName);
					handler.AppendLiteral(")");
					stringBuilder3.Append(ref handler);
				}
				else
				{
					stringBuilder = sb;
					StringBuilder stringBuilder4 = stringBuilder;
					handler = new StringBuilder.AppendInterpolatedStringHandler(2, 2, stringBuilder);
					handler.AppendFormatted(TranslateManager.HITPOSITION_DESC);
					handler.AppendLiteral(": ");
					handler.AppendFormatted(_limbName);
					stringBuilder4.Append(ref handler);
				}
			}
			sb.Append("</size>\n");
			if (ShowHPBar)
			{
				stringBuilder = sb;
				StringBuilder stringBuilder5 = stringBuilder;
				handler = new StringBuilder.AppendInterpolatedStringHandler(13, 1, stringBuilder);
				handler.AppendLiteral("<size=");
				handler.AppendFormatted(BarFontSize);
				handler.AppendLiteral(">HP: |-");
				stringBuilder5.Append(ref handler);
				int num = (int)(_health / _healthMax * (float)BarLength);
				if (num == 0 && !_isKill)
				{
					num = 1;
				}
				sb.Append(BarFillChar_Remaining[0], num);
				sb.Append(BarFillChar_Losted[0], BarLength - num);
				sb.Append("-| </size>");
			}
			else
			{
				stringBuilder = sb;
				StringBuilder stringBuilder6 = stringBuilder;
				handler = new StringBuilder.AppendInterpolatedStringHandler(18, 1, stringBuilder);
				handler.AppendLiteral("<size=");
				handler.AppendFormatted(BarFontSize);
				handler.AppendLiteral(">HP: </size>");
				stringBuilder6.Append(ref handler);
			}
			stringBuilder = sb;
			StringBuilder stringBuilder7 = stringBuilder;
			handler = new StringBuilder.AppendInterpolatedStringHandler(19, 3, stringBuilder);
			handler.AppendLiteral("<size=");
			handler.AppendFormatted(BarFontSize);
			handler.AppendLiteral(">[");
			handler.AppendFormatted(_health);
			handler.AppendLiteral(" / ");
			handler.AppendFormatted(_healthMax);
			handler.AppendLiteral("]</size>");
			stringBuilder7.AppendLine(ref handler);
			if (ShowHints)
			{
				stringBuilder = sb;
				StringBuilder stringBuilder8 = stringBuilder;
				handler = new StringBuilder.AppendInterpolatedStringHandler(7, 1, stringBuilder);
				handler.AppendLiteral("<size=");
				handler.AppendFormatted(HintFontSize);
				handler.AppendLiteral(">");
				stringBuilder8.Append(ref handler);
				if (ShowDamage)
				{
					stringBuilder = sb;
					StringBuilder stringBuilder9 = stringBuilder;
					handler = new StringBuilder.AppendInterpolatedStringHandler(4, 1, stringBuilder);
					handler.AppendLiteral("HP -");
					handler.AppendFormatted(_damage.ToString("0.00"));
					stringBuilder9.AppendLine(ref handler);
				}
				if (_isCrit)
				{
					sb.AppendLine(TranslateManager.CRIT);
				}
				if (_isBackMulti)
				{
					sb.AppendLine(TranslateManager.BACKMULTI);
				}
				if (_isSleepMulti)
				{
					sb.AppendLine(TranslateManager.SLEEPMULTI);
				}
				if (_isImmortal)
				{
					sb.AppendLine(TranslateManager.IMMORTAL);
				}
				if (_isArmor)
				{
					sb.AppendLine(TranslateManager.ARMOR);
				}
				if (_isKill)
				{
					sb.AppendLine(TranslateManager.KILL);
				}
				sb.Append("</size>");
			}
			((TMP_Text)TextMesh).SetText(sb.ToString(), true);
			sb.Clear();
		}
	}
}
namespace Hikaria.DamageAnalyzer.Features
{
	[DisallowInGameToggle]
	[EnableFeatureByDefault]
	public class DamageAnalyzer : Feature
	{
		public class DamageAnalyzerSetting
		{
			[FSDisplayName("持续时间")]
			public float LastingTime
			{
				get
				{
					return DamageInfoDisplay.LastingTime;
				}
				set
				{
					DamageInfoDisplay.LastingTime = value;
				}
			}

			[FSDisplayName("生命值条文本大小")]
			public int BarFontSize
			{
				get
				{
					return DamageInfoDisplay.BarFontSize;
				}
				set
				{
					DamageInfoDisplay.BarFontSize = value;
				}
			}

			[FSDisplayName("提示文本大小")]
			public int HintFontSize
			{
				get
				{
					return DamageInfoDisplay.HintFontSize;
				}
				set
				{
					DamageInfoDisplay.HintFontSize = value;
				}
			}

			[FSDisplayName("生命值条文本长度")]
			public int BarLength
			{
				get
				{
					return DamageInfoDisplay.BarLength;
				}
				set
				{
					DamageInfoDisplay.BarLength = value;
				}
			}

			[FSDisplayName("显示位置横向偏移量")]
			public int OffsetX
			{
				get
				{
					//IL_001d: Unknown result type (might be due to invalid IL or missing references)
					if ((Object)(object)DamageInfoDisplay.TextMesh == (Object)null)
					{
						return DamageInfoDisplay.OffsetX;
					}
					return (int)DamageInfoDisplay.TextMesh.transform.localPosition.x;
				}
				set
				{
					//IL_002c: Unknown result type (might be due to invalid IL or missing references)
					DamageInfoDisplay.OffsetX = value;
					if (!((Object)(object)DamageInfoDisplay.TextMesh == (Object)null))
					{
						DamageInfoDisplay.TextMesh.transform.localPosition = new Vector3((float)value, (float)OffsetY, 0f);
					}
				}
			}

			[FSDisplayName("显示位置纵向偏移量")]
			public int OffsetY
			{
				get
				{
					//IL_001d: Unknown result type (might be due to invalid IL or missing references)
					if ((Object)(object)DamageInfoDisplay.TextMesh == (Object)null)
					{
						return DamageInfoDisplay.OffsetY;
					}
					return (int)DamageInfoDisplay.TextMesh.transform.localPosition.y;
				}
				set
				{
					//IL_002c: Unknown result type (might be due to invalid IL or missing references)
					DamageInfoDisplay.OffsetY = value;
					if (!((Object)(object)DamageInfoDisplay.TextMesh == (Object)null))
					{
						DamageInfoDisplay.TextMesh.transform.localPosition = new Vector3((float)OffsetX, (float)value, 0f);
					}
				}
			}

			[FSDisplayName("显示提示")]
			public bool ShowHints
			{
				get
				{
					return DamageInfoDisplay.ShowHints;
				}
				set
				{
					DamageInfoDisplay.ShowHints = value;
				}
			}

			[FSDisplayName("显示生命值条")]
			public bool ShowHPBar
			{
				get
				{
					return DamageInfoDisplay.ShowHPBar;
				}
				set
				{
					DamageInfoDisplay.ShowHPBar = value;
				}
			}

			[FSDisplayName("显示敌人名称")]
			public bool ShowName
			{
				get
				{
					return DamageInfoDisplay.ShowName;
				}
				set
				{
					DamageInfoDisplay.ShowName = value;
				}
			}

			[FSDisplayName("显示命中部位")]
			public bool ShowLimb
			{
				get
				{
					return DamageInfoDisplay.ShowLimb;
				}
				set
				{
					DamageInfoDisplay.ShowLimb = value;
				}
			}

			[FSDisplayName("显示造成的伤害")]
			public bool ShowDamage
			{
				get
				{
					return DamageInfoDisplay.ShowDamage;
				}
				set
				{
					DamageInfoDisplay.ShowDamage = value;
				}
			}

			[FSDisplayName("显示哨戒炮造成的伤害")]
			[FSDescription("显示哨戒炮的命中信息, 仅当房主也安装了本插件才能显示")]
			public bool ShowSentryDamage
			{
				get
				{
					return DamageInfoManager.ShowSentryDamage;
				}
				set
				{
					DamageInfoManager.ShowSentryDamage = value;
				}
			}

			[FSDisplayName("生命值剩余表示字符")]
			public string BarFillChar_Remaining
			{
				get
				{
					return DamageInfoDisplay.BarFillChar_Remaining;
				}
				set
				{
					DamageInfoDisplay.BarFillChar_Remaining = value;
				}
			}

			[FSDisplayName("生命值失去表示字符")]
			public string BarFillChar_Losted
			{
				get
				{
					return DamageInfoDisplay.BarFillChar_Losted;
				}
				set
				{
					DamageInfoDisplay.BarFillChar_Losted = value;
				}
			}

			[FSDisplayName("文本颜色")]
			public SColor TextColor
			{
				get
				{
					//IL_001d: Unknown result type (might be due to invalid IL or missing references)
					//IL_0022: Unknown result type (might be due to invalid IL or missing references)
					//IL_000d: Unknown result type (might be due to invalid IL or missing references)
					//IL_0012: Unknown result type (might be due to invalid IL or missing references)
					if ((Object)(object)DamageInfoDisplay.TextMesh == (Object)null)
					{
						return SColorExtensions.ToSColor(DamageInfoDisplay.TextColor);
					}
					return SColorExtensions.ToSColor(((Graphic)DamageInfoDisplay.TextMesh).color);
				}
				set
				{
					//IL_0000: Unknown result type (might be due to invalid IL or missing references)
					//IL_0001: Unknown result type (might be due to invalid IL or missing references)
					//IL_0006: Unknown result type (might be due to invalid IL or missing references)
					//IL_001e: Unknown result type (might be due to invalid IL or missing references)
					//IL_001f: Unknown result type (might be due to invalid IL or missing references)
					DamageInfoDisplay.TextColor = SColorExtensions.ToUnityColor(value);
					if (!((Object)(object)DamageInfoDisplay.TextMesh == (Object)null))
					{
						((Graphic)DamageInfoDisplay.TextMesh).color = SColorExtensions.ToUnityColor(value);
					}
				}
			}
		}

		[ArchivePatch(/*Could not decode attribute arguments.*/)]
		private class PUI_Watermark__UpdateWatermark__Patch
		{
			private static bool IsSetup;

			private static void Postfix()
			{
				//IL_000c: Unknown result type (might be due to invalid IL or missing references)
				//IL_0011: Unknown result type (might be due to invalid IL or missing references)
				//IL_002f: Unknown result type (might be due to invalid IL or missing references)
				//IL_0039: Unknown result type (might be due to invalid IL or missing references)
				//IL_003f: Expected O, but got Unknown
				if (!IsSetup)
				{
					GameObject val = new GameObject("DamageAnalyzer");
					val.transform.position = new Vector3((float)Screen.width / 2f, (float)Screen.height / 2f);
					Object.DontDestroyOnLoad((Object)val);
					val.AddComponent<DamageInfoDisplay>();
					IsSetup = true;
				}
			}
		}

		[ArchivePatch(/*Could not decode attribute arguments.*/)]
		private class BulletWeapon__BulletHit__Patch
		{
			private static void Prefix(WeaponHitData weaponRayData, bool doDamage, float additionalDis)
			{
				//IL_0041: Unknown result type (might be due to invalid IL or missing references)
				//IL_0046: Unknown result type (might be due to invalid IL or missing references)
				//IL_0053: 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_008b: Unknown result type (might be due to invalid IL or missing references)
				//IL_0096: Unknown result type (might be due to invalid IL or missing references)
				DamageInfoManager.DoBulletDamage = doDamage;
				SNet_Player owner = weaponRayData.owner.Owner;
				if (!DamageInfoManager.OriginalBulletDamage.TryAdd(owner.Lookup, weaponRayData.damage))
				{
					DamageInfoManager.OriginalBulletDamage[owner.Lookup] = weaponRayData.damage;
				}
				RaycastHit rayHit = weaponRayData.rayHit;
				float num = ((RaycastHit)(ref rayHit)).distance + additionalDis;
				if (num > weaponRayData.damageFalloff.x)
				{
					DamageInfoManager.OriginalBulletDamage[owner.Lookup] *= Mathf.Max(1f - (num - weaponRayData.damageFalloff.x) / (weaponRayData.damageFalloff.y - weaponRayData.damageFalloff.x), BulletWeapon.s_falloffMin);
				}
			}
		}

		[ArchivePatch(/*Could not decode attribute arguments.*/)]
		private class Dam_EnemyDamageLimb__MeleeDamage__Patch
		{
			private static void Prefix(Dam_EnemyDamageLimb __instance, float dam, Agent sourceAgent, Vector3 position, Vector3 direction, float staggerMulti = 1f, float precisionMulti = 1f, float backstabberMulti = 1f, float sleeperMulti = 1f)
			{
				//IL_003a: Unknown result type (might be due to invalid IL or missing references)
				//IL_0041: Invalid comparison between Unknown and I4
				if (!((Object)(object)sourceAgent == (Object)null) && DamageInfoManager.LocalAgentGlobalID == sourceAgent.GlobalID && !((Il2CppObjectBase)sourceAgent).TryCast<PlayerAgent>().Owner.IsBot && (int)__instance.m_base.Owner.Locomotion.CurrentStateEnum == 14)
				{
					DamageInfoManager.IsSleepMulti = true;
				}
			}

			private static void Postfix(Dam_EnemyDamageLimb __instance, float dam, Agent sourceAgent, Vector3 position, Vector3 direction, float staggerMulti = 1f, float precisionMulti = 1f, float backstabberMulti = 1f, float sleeperMulti = 1f)
			{
				//IL_0035: Unknown result type (might be due to invalid IL or missing references)
				//IL_0036: Unknown result type (might be due to invalid IL or missing references)
				if (!((Object)(object)sourceAgent == (Object)null) && DamageInfoManager.LocalAgentGlobalID == sourceAgent.GlobalID)
				{
					PlayerAgent val = ((Il2CppObjectBase)sourceAgent).TryCast<PlayerAgent>();
					if (!val.Owner.IsBot)
					{
						DamageInfoManager.ProcessDamageInfo(new DamageInfoManager.BasicDamageInfo(val.Owner, DamageInfoManager.DamageType.Melee, DamageInfoManager.DamageSource.Player, __instance, position, direction, dam, allowDirectionalBonus: true, staggerMulti, precisionMulti, backstabberMulti, sleeperMulti, DamageInfoManager.IsSleepMulti));
						DamageInfoManager.IsSleepMulti = false;
					}
				}
			}
		}

		[ArchivePatch(/*Could not decode attribute arguments.*/)]
		private class Dam_EnemyDamageLimb__BulletDamage__Patch
		{
			private static void Postfix(Dam_EnemyDamageLimb __instance, float dam, Agent sourceAgent, Vector3 position, Vector3 direction, bool allowDirectionalBonus, float staggerMulti = 1f, float precisionMulti = 1f)
			{
				//IL_0046: Unknown result type (might be due to invalid IL or missing references)
				//IL_0047: Unknown result type (might be due to invalid IL or missing references)
				if (!((Object)(object)sourceAgent == (Object)null) && (SNet.IsMaster || DamageInfoManager.LocalAgentGlobalID == sourceAgent.GlobalID))
				{
					PlayerAgent val = ((Il2CppObjectBase)sourceAgent).TryCast<PlayerAgent>();
					if (!val.Owner.IsBot)
					{
						DamageInfoManager.ProcessDamageInfo(new DamageInfoManager.BasicDamageInfo(val.Owner, DamageInfoManager.DamageType.Bullet, (!DamageInfoManager.IsSentryGunFire) ? DamageInfoManager.DamageSource.Player : DamageInfoManager.DamageSource.SentryGun, __instance, position, direction, dam, allowDirectionalBonus, staggerMulti, precisionMulti));
					}
				}
			}
		}

		[ArchivePatch(/*Could not decode attribute arguments.*/)]
		private class SentryGunInstance_Firing_Bullets__FireBullet__Patch
		{
			private static void Prefix()
			{
				DamageInfoManager.IsSentryGunFire = true;
			}

			private static void Postfix()
			{
				DamageInfoManager.IsSentryGunFire = false;
			}
		}

		[ArchivePatch(/*Could not decode attribute arguments.*/)]
		private class SentryGunInstance_Firing_Bullets__UpdateFireShotgunSemi__Patch
		{
			private static void Prefix()
			{
				DamageInfoManager.IsSentryGunFire = true;
			}

			private static void Postfix()
			{
				DamageInfoManager.IsSentryGunFire = false;
			}
		}

		[ArchivePatch(/*Could not decode attribute arguments.*/)]
		private class LocalPlayerAgent__Setup__Patch
		{
			private static void Postfix(LocalPlayerAgent __instance)
			{
				DamageInfoManager.LocalAgentGlobalID = ((Agent)__instance).GlobalID;
			}
		}

		public override string Name => "Damage Analyzer";

		public override bool InlineSettingsIntoParentMenu => true;

		public static DamageAnalyzer Instance { get; private set; }

		[FeatureConfig]
		public static DamageAnalyzerSetting Settings { get; set; }

		public override void Init()
		{
			Instance = this;
			ClassInjector.RegisterTypeInIl2Cpp<DamageInfoDisplay>(false);
			DamageInfoManager.Setup();
		}
	}
}