Decompiled source of Autopsy Report and Live Combat Log v0.9.0

AutopsyReport.dll

Decompiled 4 days ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Text.RegularExpressions;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using HarmonyLib;
using Jotunn.GUI;
using Jotunn.Managers;
using Microsoft.CodeAnalysis;
using UnityEngine;
using UnityEngine.EventSystems;
using UnityEngine.Events;
using UnityEngine.UI;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)]
[assembly: AssemblyVersion("0.0.0.0")]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[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 AutopsyReport
{
	[BepInPlugin("zeeCameLsnake.AutopsyReport", "Autopsy Report", "0.9.0")]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	public class AutopsyReportPlugin : BaseUnityPlugin
	{
		public enum LogScrollDirection
		{
			NewestAtTop,
			NewestAtBottom
		}

		public enum CombatEventType
		{
			IncomingDamage,
			OutgoingDamage,
			IncomingHeal,
			Blocked
		}

		public class CombatEvent
		{
			public float timestamp;

			public CombatEventType eventType;

			public float amount;

			public string damageType;

			public string entityName;

			public string sourceName;

			public float healthAfter;

			public float blockedAmount;

			public bool isParry;

			public bool isCritOrWeakness;

			public bool isResisted;

			public string healSource;

			public int tickCount = 1;

			public bool isDoT = false;

			public bool isFatal = false;
		}

		public class DeathReportData
		{
			public string killerName = "Unknown";

			public string damageType = "0 damage";

			public float overkillAmount = 0f;

			public float fatalBlockedDamage = 0f;

			public List<string> skillLosses = new List<string>();

			public List<string> activeStatusEffects = new List<string>();

			public bool hadNoSkillDrainBuff = false;

			public List<CombatEvent> timeline = new List<CombatEvent>();
		}

		[Serializable]
		[CompilerGenerated]
		private sealed class <>c
		{
			public static readonly <>c <>9 = new <>c();

			public static UnityAction <>9__75_0;

			public static UnityAction <>9__75_1;

			internal void <CreateUI>b__75_0()
			{
				showReport = false;
			}

			internal void <CreateUI>b__75_1()
			{
				showReport = false;
			}
		}

		public const string PluginId = "zeeCameLsnake.AutopsyReport";

		public const string PluginName = "Autopsy Report";

		public const string PluginVersion = "0.9.0";

		private readonly Harmony _harmony = new Harmony("zeeCameLsnake.AutopsyReport");

		public static ConfigEntry<KeyboardShortcut> toggleHotkey;

		public static ConfigEntry<bool> autoSaveEnabled;

		public static ConfigEntry<bool> autoOpenOnRevive;

		public static ConfigEntry<bool> enableLiveCombatLog;

		public static ConfigEntry<KeyboardShortcut> toggleCombatLogHotkey;

		public static ConfigEntry<bool> showContentBorder;

		public static ConfigEntry<float> boxPositionX;

		public static ConfigEntry<float> boxPositionY;

		public static ConfigEntry<float> boxWidth;

		public static ConfigEntry<int> combatLogFontSize;

		public static ConfigEntry<bool> wordWrapCombatLog;

		public static ConfigEntry<string> damageIndicatorSymbol;

		public static ConfigEntry<LogScrollDirection> scrollDirection;

		public static ConfigEntry<int> maxLogLines;

		public static ConfigEntry<float> fadeoutDelay;

		public static ConfigEntry<float> backgroundAlpha;

		public static ConfigEntry<bool> isPinned;

		public static ConfigEntry<bool> isMinimized;

		public static ConfigEntry<bool> showIncomingDamage;

		public static ConfigEntry<bool> showOutgoingDamage;

		public static ConfigEntry<bool> showMinionDamage;

		public static ConfigEntry<bool> showActiveHeals;

		public static ConfigEntry<bool> showBlockedDamage;

		public static ConfigEntry<bool> logPassiveFoodRegen;

		public static ConfigEntry<bool> useWoodpanelStyle;

		public static ConfigEntry<bool> showOutgoingFireDoT;

		public static ConfigEntry<bool> showOutgoingPoisonDoT;

		public static ConfigEntry<bool> showOutgoingSpiritDoT;

		public static bool showReport = false;

		public static bool hasNewAutopsyData = false;

		public static DeathReportData currentDeathReport = null;

		public static List<CombatEvent> recentCombatEvents = new List<CombatEvent>();

		public static bool clearHitsOnNextDamage = false;

		public static float lastDamageTime = 0f;

		public static float lastCombatActionTime = -999f;

		public static Dictionary<Character, float> playerBurningTargets = new Dictionary<Character, float>();

		public static Dictionary<Character, float> playerPoisonTargets = new Dictionary<Character, float>();

		public static Dictionary<Character, float> playerSpiritTargets = new Dictionary<Character, float>();

		private static readonly Vector2 DefaultReportPos = new Vector2(0f, -20f);

		private static readonly Vector2 DefaultHistoryPos = new Vector2(130f, -326f);

		private GameObject reportPanel;

		private GameObject damageHistoryPanel;

		private Text damageHistoryText;

		private Text reportText;

		private Button closeButton;

		private Button saveButton;

		private Button xButton;

		private Text combatLogToggleText;

		private Dropdown historyDropdown;

		private List<string> savedFilePaths = new List<string>();

		private Text hintText;

		private Texture2D bgTexture;

		private Texture2D titleTexture;

		private Texture2D borderTexture;

		private Sprite woodSprite;

		private GUIStyle titleStyle;

		private GUIStyle textStyle;

		private GUIStyle btnStyle;

		private bool isDraggingLog = false;

		private Vector2 dragStartMousePos;

		private Vector2 dragStartBoxPos;

		private bool isResizingLog = false;

		private Vector2 resizeStartMousePos;

		private float resizeStartWidth;

		private float resizeStartHeight;

		public static AutopsyReportPlugin Instance { get; private set; }

		public static ManualLogSource Log { get; private set; }

		public static void AddCombatEvent(CombatEvent ev)
		{
			if (clearHitsOnNextDamage)
			{
				recentCombatEvents.Clear();
				clearHitsOnNextDamage = false;
				CharacterDamagePatch.lastPoisonAttackerName = null;
				CharacterDamagePatch.lastFireAttackerName = null;
			}
			if (ev.eventType == CombatEventType.IncomingHeal && recentCombatEvents.Count > 0)
			{
				CombatEvent combatEvent = recentCombatEvents[0];
				if (combatEvent.eventType == CombatEventType.IncomingHeal && combatEvent.entityName == ev.entityName)
				{
					combatEvent.amount += ev.amount;
					combatEvent.healthAfter = ev.healthAfter;
					combatEvent.timestamp = ev.timestamp;
					combatEvent.tickCount++;
					lastCombatActionTime = Time.time;
					return;
				}
			}
			if (ev.eventType == CombatEventType.IncomingDamage && ev.isDoT)
			{
				int num = Mathf.Min(6, recentCombatEvents.Count);
				for (int i = 0; i < num; i++)
				{
					CombatEvent combatEvent2 = recentCombatEvents[i];
					if (combatEvent2.eventType == CombatEventType.IncomingDamage && combatEvent2.isDoT && combatEvent2.entityName == ev.entityName && combatEvent2.damageType == ev.damageType && Time.time - combatEvent2.timestamp < 3.5f)
					{
						combatEvent2.amount += ev.amount;
						combatEvent2.healthAfter = ev.healthAfter;
						combatEvent2.timestamp = Time.time;
						combatEvent2.tickCount++;
						lastCombatActionTime = Time.time;
						return;
					}
				}
			}
			if (ev.eventType == CombatEventType.OutgoingDamage && ev.isDoT)
			{
				int num2 = Mathf.Min(6, recentCombatEvents.Count);
				for (int j = 0; j < num2; j++)
				{
					CombatEvent combatEvent3 = recentCombatEvents[j];
					if (combatEvent3.eventType == CombatEventType.OutgoingDamage && combatEvent3.isDoT && combatEvent3.entityName == ev.entityName && combatEvent3.damageType == ev.damageType && combatEvent3.sourceName == ev.sourceName && Time.time - combatEvent3.timestamp < 3.5f)
					{
						combatEvent3.amount += ev.amount;
						combatEvent3.timestamp = Time.time;
						combatEvent3.tickCount++;
						lastCombatActionTime = Time.time;
						return;
					}
				}
			}
			recentCombatEvents.Insert(0, ev);
			if (recentCombatEvents.Count > 50)
			{
				recentCombatEvents.RemoveAt(recentCombatEvents.Count - 1);
			}
			lastCombatActionTime = Time.time;
		}

		public static string GetDamageTypeSummary(HitData hit)
		{
			//IL_0015: Unknown result type (might be due to invalid IL or missing references)
			//IL_001b: Invalid comparison between Unknown and I4
			//IL_002f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0035: Invalid comparison between Unknown and I4
			//IL_0049: Unknown result type (might be due to invalid IL or missing references)
			//IL_0050: Invalid comparison between Unknown and I4
			//IL_0064: Unknown result type (might be due to invalid IL or missing references)
			//IL_006b: Invalid comparison between Unknown and I4
			//IL_006e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0075: Invalid comparison between Unknown and I4
			//IL_0092: Unknown result type (might be due to invalid IL or missing references)
			//IL_0097: 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_00b7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f5: Unknown result type (might be due to invalid IL or missing references)
			//IL_0114: Unknown result type (might be due to invalid IL or missing references)
			//IL_0133: Unknown result type (might be due to invalid IL or missing references)
			//IL_0141: Unknown result type (might be due to invalid IL or missing references)
			//IL_0147: Invalid comparison between Unknown and I4
			//IL_015e: Unknown result type (might be due to invalid IL or missing references)
			//IL_016c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0172: Invalid comparison between Unknown and I4
			//IL_0189: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a8: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b6: Unknown result type (might be due to invalid IL or missing references)
			//IL_01bc: Invalid comparison between Unknown and I4
			//IL_01d3: Unknown result type (might be due to invalid IL or missing references)
			//IL_0202: Unknown result type (might be due to invalid IL or missing references)
			if (hit == null)
			{
				return "";
			}
			if ((int)hit.m_hitType == 3)
			{
				return "Fall";
			}
			if ((int)hit.m_hitType == 4)
			{
				return "Drowning";
			}
			if ((int)hit.m_hitType == 9)
			{
				return "Smoke";
			}
			if ((int)hit.m_hitType == 22 || (int)hit.m_hitType == 21)
			{
				return "Lava";
			}
			List<string> list = new List<string>();
			DamageTypes damage = hit.m_damage;
			if (damage.m_blunt > 0.05f)
			{
				list.Add("Blunt");
			}
			if (damage.m_slash > 0.05f)
			{
				list.Add("Slash");
			}
			if (damage.m_pierce > 0.05f)
			{
				list.Add("Pierce");
			}
			if (damage.m_chop > 0.05f)
			{
				list.Add("Chop");
			}
			if (damage.m_pickaxe > 0.05f)
			{
				list.Add("Pickaxe");
			}
			if (damage.m_fire > 0.05f || (int)hit.m_hitType == 5)
			{
				list.Add("Fire");
			}
			if (damage.m_frost > 0.05f || (int)hit.m_hitType == 6)
			{
				list.Add("Frost");
			}
			if (damage.m_lightning > 0.05f)
			{
				list.Add("Lightning");
			}
			if (damage.m_poison > 0.05f || (int)hit.m_hitType == 7)
			{
				list.Add("Poison");
			}
			if (damage.m_spirit > 0.05f)
			{
				list.Add("Spirit");
			}
			if (list.Count == 0)
			{
				if (damage.m_damage > 0.05f)
				{
					return "Physical";
				}
				return "";
			}
			return string.Join("/", list);
		}

		private static bool IsBow(ItemData item)
		{
			//IL_001e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0024: Invalid comparison between Unknown and I4
			//IL_002c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0032: Invalid comparison between Unknown and I4
			if (item == null || item.m_shared == null)
			{
				return false;
			}
			return (int)item.m_shared.m_itemType == 4 || (int)item.m_shared.m_skillType == 8;
		}

		private static bool IsCrossbow(ItemData item)
		{
			//IL_001e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0025: Invalid comparison between Unknown and I4
			if (item == null || item.m_shared == null)
			{
				return false;
			}
			return (int)item.m_shared.m_skillType == 14;
		}

		public static string FormatAttackerName(Character attacker, HitData hit = null)
		{
			//IL_0056: Unknown result type (might be due to invalid IL or missing references)
			//IL_005c: Invalid comparison between Unknown and I4
			//IL_006f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0076: Invalid comparison between Unknown and I4
			if ((Object)(object)attacker == (Object)null)
			{
				return "Unknown";
			}
			string text = attacker.GetHoverName();
			string prefabName = Utils.GetPrefabName(((Component)attacker).gameObject);
			string text2 = null;
			if (!attacker.IsPlayer())
			{
				if (hit != null && hit.m_ranged)
				{
					if ((int)hit.m_skill == 8)
					{
						text2 = "Archer";
					}
					else if ((int)hit.m_skill == 14)
					{
						text2 = "Crossbow";
					}
				}
				if (string.IsNullOrEmpty(text2))
				{
					Humanoid val = (Humanoid)(object)((attacker is Humanoid) ? attacker : null);
					if (val != null)
					{
						if (IsBow(val.LeftItem) || IsBow(val.RightItem) || IsBow(val.GetCurrentWeapon()))
						{
							text2 = "Archer";
						}
						else if (IsCrossbow(val.LeftItem) || IsCrossbow(val.RightItem) || IsCrossbow(val.GetCurrentWeapon()))
						{
							text2 = "Crossbow";
						}
						else if (val.GetInventory() != null)
						{
							foreach (ItemData allItem in val.GetInventory().GetAllItems())
							{
								if (IsBow(allItem))
								{
									text2 = "Archer";
									break;
								}
								if (IsCrossbow(allItem))
								{
									text2 = "Crossbow";
									break;
								}
							}
						}
					}
				}
				if (string.IsNullOrEmpty(text2))
				{
					if (prefabName.EndsWith("_Ranged") || prefabName.EndsWith("_Bow") || prefabName.Contains("Archer"))
					{
						text2 = "Archer";
					}
					else if (prefabName.EndsWith("_Elite"))
					{
						text2 = "Elite";
					}
				}
				if (!string.IsNullOrEmpty(text2))
				{
					string text3 = (attacker.m_name + "_" + prefabName).ToLower();
					if (text2 == "Archer" && (text3.Contains("archer") || text3.Contains("bow")))
					{
						text2 = null;
					}
					else if (text2 == "Crossbow" && text3.Contains("crossbow"))
					{
						text2 = null;
					}
					else if (text2 == "Elite" && (text3.Contains("elite") || text3.Contains("brute")))
					{
						text2 = null;
					}
				}
			}
			if (!string.IsNullOrEmpty(text2))
			{
				text = text + " (" + text2 + ")";
			}
			int level = attacker.GetLevel();
			if (level == 2)
			{
				text += " <color=yellow>★</color>";
			}
			else if (level == 3)
			{
				text += " <color=yellow>★★</color>";
			}
			else if (level > 3)
			{
				text += $" <color=yellow>({level - 1}★)</color>";
			}
			return text;
		}

		public static bool IsPlayerMinionOrPet(Character attacker, out string minionName)
		{
			minionName = null;
			if ((Object)(object)attacker == (Object)null || (Object)(object)attacker == (Object)(object)Player.m_localPlayer)
			{
				return false;
			}
			if (!attacker.IsTamed())
			{
				return false;
			}
			BaseAI baseAI = attacker.GetBaseAI();
			MonsterAI val = (MonsterAI)(object)((baseAI is MonsterAI) ? baseAI : null);
			bool flag = (Object)(object)val != (Object)null && (Object)(object)val.GetFollowTarget() == (Object)(object)((Component)Player.m_localPlayer).gameObject;
			bool flag2 = false;
			ZNetView component = ((Component)attacker).GetComponent<ZNetView>();
			if ((Object)(object)component != (Object)null && component.IsValid())
			{
				string text = component.GetZDO().GetString(ZDOVars.s_follow, "");
				if (!string.IsNullOrEmpty(text) && (Object)(object)Player.m_localPlayer != (Object)null && text == Player.m_localPlayer.GetPlayerName())
				{
					flag2 = true;
				}
			}
			bool flag3 = (Object)(object)ZNet.instance != (Object)null && (!ZNet.instance.IsServer() || ZNet.instance.GetNrOfPlayers() <= 1);
			if (flag || flag2 || flag3)
			{
				minionName = FormatAttackerName(attacker);
				return true;
			}
			return false;
		}

		private void Awake()
		{
			//IL_002e: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bc: Unknown result type (might be due to invalid IL or missing references)
			//IL_0181: Unknown result type (might be due to invalid IL or missing references)
			//IL_018b: Expected O, but got Unknown
			//IL_021a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0224: Expected O, but got Unknown
			Instance = this;
			Log = ((BaseUnityPlugin)this).Logger;
			toggleHotkey = ((BaseUnityPlugin)this).Config.Bind<KeyboardShortcut>("General", "ToggleHotkey", new KeyboardShortcut((KeyCode)289, Array.Empty<KeyCode>()), "Hotkey to show/hide the Autopsy Report");
			autoSaveEnabled = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "AutoSave", false, "Automatically save all autopsy reports to file");
			autoOpenOnRevive = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "AutoOpenOnRevive", true, "Automatically open the Autopsy Report window after respawning/reviving.");
			enableLiveCombatLog = ((BaseUnityPlugin)this).Config.Bind<bool>("LiveCombatLog", "EnableLiveCombatLog", true, "Show on-screen live combat log box during combat.");
			toggleCombatLogHotkey = ((BaseUnityPlugin)this).Config.Bind<KeyboardShortcut>("LiveCombatLog", "ToggleCombatLogHotkey", new KeyboardShortcut((KeyCode)290, Array.Empty<KeyCode>()), "Hotkey to toggle the Live Combat Log on/off.");
			showContentBorder = ((BaseUnityPlugin)this).Config.Bind<bool>("LiveCombatLog", "ShowContentBorder", true, "Draw border frame around the log content area. Disable for a frameless look below the title bar.");
			boxPositionX = ((BaseUnityPlugin)this).Config.Bind<float>("LiveCombatLog", "BoxPositionX", 20f, "X position of the combat log on screen (pixels from left).");
			boxPositionY = ((BaseUnityPlugin)this).Config.Bind<float>("LiveCombatLog", "BoxPositionY", 650f, "Y position of the combat log on screen (pixels from top).");
			boxWidth = ((BaseUnityPlugin)this).Config.Bind<float>("LiveCombatLog", "BoxWidth", 460f, "Width of the combat log window in pixels.");
			combatLogFontSize = ((BaseUnityPlugin)this).Config.Bind<int>("LiveCombatLog", "FontSize", 13, new ConfigDescription("Font size of the combat log text entries (10-22).", (AcceptableValueBase)(object)new AcceptableValueRange<int>(10, 22), Array.Empty<object>()));
			wordWrapCombatLog = ((BaseUnityPlugin)this).Config.Bind<bool>("LiveCombatLog", "WordWrap", false, "Whether combat log lines wrap if the window is too narrow. When false, overflowing text is clipped.");
			damageIndicatorSymbol = ((BaseUnityPlugin)this).Config.Bind<string>("LiveCombatLog", "DamageIndicatorSymbol", "✦", new ConfigDescription("Symbol displayed for weakness/critical hits.", (AcceptableValueBase)(object)new AcceptableValueList<string>(new string[8] { "✦", "★", "♦", "▲", "!", "*", "#", "None" }), Array.Empty<object>()));
			scrollDirection = ((BaseUnityPlugin)this).Config.Bind<LogScrollDirection>("LiveCombatLog", "ScrollDirection", LogScrollDirection.NewestAtTop, "Order of events in the box: NewestAtTop or NewestAtBottom.");
			maxLogLines = ((BaseUnityPlugin)this).Config.Bind<int>("LiveCombatLog", "MaxLogLines", 8, "Maximum number of visible lines in the combat log (5-15).");
			fadeoutDelay = ((BaseUnityPlugin)this).Config.Bind<float>("LiveCombatLog", "FadeoutDelay", 8f, "Seconds of inactivity before combat log fades out (0 = never fade).");
			backgroundAlpha = ((BaseUnityPlugin)this).Config.Bind<float>("LiveCombatLog", "BackgroundAlpha", 0.72f, "Background box opacity (0.0 = transparent, 1.0 = solid).");
			isPinned = ((BaseUnityPlugin)this).Config.Bind<bool>("LiveCombatLog", "IsPinned", false, "Pin combat log to screen: true = Always visible, false = Auto-hide after fadeout delay.");
			isMinimized = ((BaseUnityPlugin)this).Config.Bind<bool>("LiveCombatLog", "IsMinimized", false, "Whether the log is collapsed to only its title bar.");
			showIncomingDamage = ((BaseUnityPlugin)this).Config.Bind<bool>("LiveCombatLog", "ShowIncomingDamage", true, "Log incoming damage taken by player.");
			showOutgoingDamage = ((BaseUnityPlugin)this).Config.Bind<bool>("LiveCombatLog", "ShowOutgoingDamage", true, "Log outgoing attacks dealt by player.");
			showMinionDamage = ((BaseUnityPlugin)this).Config.Bind<bool>("LiveCombatLog", "ShowMinionDamage", true, "Log outgoing attacks dealt by summoned creatures (skeletons) and tamed pets.");
			showActiveHeals = ((BaseUnityPlugin)this).Config.Bind<bool>("LiveCombatLog", "ShowActiveHeals", true, "Log active heals (potions, meads, leech).");
			showBlockedDamage = ((BaseUnityPlugin)this).Config.Bind<bool>("LiveCombatLog", "ShowBlockedDamage", true, "Log blocked and parried attacks.");
			logPassiveFoodRegen = ((BaseUnityPlugin)this).Config.Bind<bool>("LiveCombatLog", "LogPassiveFoodRegen", false, "Whether to log passive 10s food regen ticks (disabled to prevent spam).");
			useWoodpanelStyle = ((BaseUnityPlugin)this).Config.Bind<bool>("LiveCombatLog", "UseWoodpanelStyle", false, "Use Valheim's classic solid wooden board style instead of the translucent dark HUD box.");
			showOutgoingFireDoT = ((BaseUnityPlugin)this).Config.Bind<bool>("LiveCombatLog", "ShowOutgoingFireDoT", true, "Log outgoing fire burning DoT ticks on enemies.");
			showOutgoingPoisonDoT = ((BaseUnityPlugin)this).Config.Bind<bool>("LiveCombatLog", "ShowOutgoingPoisonDoT", true, "Log outgoing poison DoT ticks on enemies.");
			showOutgoingSpiritDoT = ((BaseUnityPlugin)this).Config.Bind<bool>("LiveCombatLog", "ShowOutgoingSpiritDoT", true, "Log outgoing spirit DoT ticks on enemies.");
			_harmony.PatchAll();
			Log.LogInfo((object)"Autopsy Report v0.9.0 loaded!");
			GUIManager.OnCustomGUIAvailable += CreateUI;
		}

		private void OnDestroy()
		{
			_harmony.UnpatchSelf();
		}

		private void CreateUI()
		{
			//IL_003f: Unknown result type (might be due to invalid IL or missing references)
			//IL_004e: Unknown result type (might be due to invalid IL or missing references)
			//IL_005d: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fb: Unknown result type (might be due to invalid IL or missing references)
			//IL_013b: Unknown result type (might be due to invalid IL or missing references)
			//IL_014a: 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_01c9: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d8: Unknown result type (might be due to invalid IL or missing references)
			//IL_01e7: Unknown result type (might be due to invalid IL or missing references)
			//IL_01f8: Unknown result type (might be due to invalid IL or missing references)
			//IL_01fe: Unknown result type (might be due to invalid IL or missing references)
			//IL_0259: Unknown result type (might be due to invalid IL or missing references)
			//IL_0268: Unknown result type (might be due to invalid IL or missing references)
			//IL_0277: Unknown result type (might be due to invalid IL or missing references)
			//IL_0199: Unknown result type (might be due to invalid IL or missing references)
			//IL_019e: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a4: Expected O, but got Unknown
			//IL_02b7: Unknown result type (might be due to invalid IL or missing references)
			//IL_02bc: Unknown result type (might be due to invalid IL or missing references)
			//IL_02c2: Expected O, but got Unknown
			//IL_02fa: Unknown result type (might be due to invalid IL or missing references)
			//IL_0309: Unknown result type (might be due to invalid IL or missing references)
			//IL_0318: Unknown result type (might be due to invalid IL or missing references)
			//IL_035d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0356: Unknown result type (might be due to invalid IL or missing references)
			//IL_0376: Unknown result type (might be due to invalid IL or missing references)
			//IL_0380: Expected O, but got Unknown
			//IL_03a0: Unknown result type (might be due to invalid IL or missing references)
			//IL_03af: Unknown result type (might be due to invalid IL or missing references)
			//IL_03be: Unknown result type (might be due to invalid IL or missing references)
			//IL_0404: Unknown result type (might be due to invalid IL or missing references)
			//IL_040e: Expected O, but got Unknown
			//IL_042e: Unknown result type (might be due to invalid IL or missing references)
			//IL_043d: Unknown result type (might be due to invalid IL or missing references)
			//IL_044c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0479: Unknown result type (might be due to invalid IL or missing references)
			//IL_0483: Expected O, but got Unknown
			//IL_04b6: Unknown result type (might be due to invalid IL or missing references)
			//IL_04c5: Unknown result type (might be due to invalid IL or missing references)
			//IL_04d4: Unknown result type (might be due to invalid IL or missing references)
			//IL_0519: Unknown result type (might be due to invalid IL or missing references)
			//IL_0512: Unknown result type (might be due to invalid IL or missing references)
			//IL_0532: Unknown result type (might be due to invalid IL or missing references)
			//IL_053c: Expected O, but got Unknown
			//IL_055c: Unknown result type (might be due to invalid IL or missing references)
			//IL_056b: Unknown result type (might be due to invalid IL or missing references)
			//IL_057a: Unknown result type (might be due to invalid IL or missing references)
			//IL_05b4: Unknown result type (might be due to invalid IL or missing references)
			//IL_05be: Expected O, but got Unknown
			//IL_05da: Unknown result type (might be due to invalid IL or missing references)
			//IL_05e9: Unknown result type (might be due to invalid IL or missing references)
			//IL_05f8: Unknown result type (might be due to invalid IL or missing references)
			//IL_063d: Unknown result type (might be due to invalid IL or missing references)
			//IL_064c: Unknown result type (might be due to invalid IL or missing references)
			//IL_065b: Unknown result type (might be due to invalid IL or missing references)
			//IL_066c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0672: Unknown result type (might be due to invalid IL or missing references)
			//IL_06a5: Unknown result type (might be due to invalid IL or missing references)
			//IL_06aa: Unknown result type (might be due to invalid IL or missing references)
			//IL_06ac: Unknown result type (might be due to invalid IL or missing references)
			//IL_06b3: Expected O, but got Unknown
			//IL_06db: Unknown result type (might be due to invalid IL or missing references)
			//IL_06e0: Unknown result type (might be due to invalid IL or missing references)
			//IL_06e2: Unknown result type (might be due to invalid IL or missing references)
			//IL_06e9: Expected O, but got Unknown
			//IL_0730: Unknown result type (might be due to invalid IL or missing references)
			//IL_073f: Unknown result type (might be due to invalid IL or missing references)
			//IL_074e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0788: Unknown result type (might be due to invalid IL or missing references)
			//IL_0797: Unknown result type (might be due to invalid IL or missing references)
			//IL_07a6: Unknown result type (might be due to invalid IL or missing references)
			//IL_07eb: Unknown result type (might be due to invalid IL or missing references)
			//IL_07fa: Unknown result type (might be due to invalid IL or missing references)
			//IL_0809: Unknown result type (might be due to invalid IL or missing references)
			//IL_081a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0820: Unknown result type (might be due to invalid IL or missing references)
			//IL_0852: Unknown result type (might be due to invalid IL or missing references)
			//IL_085c: Expected O, but got Unknown
			//IL_087c: Unknown result type (might be due to invalid IL or missing references)
			//IL_088b: Unknown result type (might be due to invalid IL or missing references)
			//IL_089a: Unknown result type (might be due to invalid IL or missing references)
			//IL_08ba: Unknown result type (might be due to invalid IL or missing references)
			//IL_08c0: Unknown result type (might be due to invalid IL or missing references)
			//IL_08ff: Unknown result type (might be due to invalid IL or missing references)
			//IL_090e: Unknown result type (might be due to invalid IL or missing references)
			//IL_091d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0985: Unknown result type (might be due to invalid IL or missing references)
			//IL_0994: Unknown result type (might be due to invalid IL or missing references)
			//IL_09a3: Unknown result type (might be due to invalid IL or missing references)
			//IL_09b4: Unknown result type (might be due to invalid IL or missing references)
			//IL_09ba: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)reportPanel != (Object)null)
			{
				return;
			}
			reportPanel = GUIManager.Instance.CreateWoodpanel(GUIManager.CustomGUIFront.transform, new Vector2(0.5f, 0.5f), new Vector2(0.5f, 0.5f), new Vector2(0f, -20f), 500f, 950f);
			reportPanel.SetActive(false);
			try
			{
				reportPanel.AddComponent<DragWindowCntrl>();
			}
			catch (Exception)
			{
			}
			GUIManager.Instance.CreateText("Autopsy Report", reportPanel.transform, new Vector2(0.5f, 1f), new Vector2(0.5f, 1f), new Vector2(0f, -70f), GUIManager.Instance.AveriaSerifBold, 28, new Color(1f, 0.647f, 0f), true, Color.black, 450f, 40f, false).GetComponent<Text>().alignment = (TextAnchor)4;
			GameObject val = GUIManager.Instance.CreateButton("X", reportPanel.transform, new Vector2(1f, 1f), new Vector2(1f, 1f), new Vector2(-30f, -30f), 40f, 40f);
			xButton = val.GetComponent<Button>();
			ButtonClickedEvent onClick = xButton.onClick;
			object obj = <>c.<>9__75_0;
			if (obj == null)
			{
				UnityAction val2 = delegate
				{
					showReport = false;
				};
				<>c.<>9__75_0 = val2;
				obj = (object)val2;
			}
			((UnityEvent)onClick).AddListener((UnityAction)obj);
			GameObject val3 = GUIManager.Instance.CreateText("Loading...", reportPanel.transform, new Vector2(0.5f, 1f), new Vector2(0.5f, 1f), new Vector2(0f, -500f), GUIManager.Instance.AveriaSerifBold, 16, Color.white, true, Color.black, 450f, 760f, false);
			reportText = val3.GetComponent<Text>();
			reportText.alignment = (TextAnchor)0;
			reportText.supportRichText = true;
			GameObject val4 = GUIManager.Instance.CreateButton("Close", reportPanel.transform, new Vector2(0.5f, 0.05f), new Vector2(0.5f, 0.05f), new Vector2(-150f, 65f), 130f, 35f);
			closeButton = val4.GetComponent<Button>();
			ButtonClickedEvent onClick2 = closeButton.onClick;
			object obj2 = <>c.<>9__75_1;
			if (obj2 == null)
			{
				UnityAction val5 = delegate
				{
					showReport = false;
				};
				<>c.<>9__75_1 = val5;
				obj2 = (object)val5;
			}
			((UnityEvent)onClick2).AddListener((UnityAction)obj2);
			GameObject val6 = GUIManager.Instance.CreateButton(autoSaveEnabled.Value ? "Auto Save: ON" : "Auto Save: OFF", reportPanel.transform, new Vector2(0.5f, 0.05f), new Vector2(0.5f, 0.05f), new Vector2(0f, 65f), 150f, 35f);
			Button component = val6.GetComponent<Button>();
			Text autoSaveText = val6.GetComponentInChildren<Text>();
			((Graphic)autoSaveText).color = (autoSaveEnabled.Value ? Color.green : Color.white);
			((UnityEvent)component.onClick).AddListener((UnityAction)delegate
			{
				//IL_0056: Unknown result type (might be due to invalid IL or missing references)
				//IL_004f: Unknown result type (might be due to invalid IL or missing references)
				autoSaveEnabled.Value = !autoSaveEnabled.Value;
				autoSaveText.text = (autoSaveEnabled.Value ? "Auto Save: ON" : "Auto Save: OFF");
				((Graphic)autoSaveText).color = (autoSaveEnabled.Value ? Color.green : Color.white);
				if (autoSaveEnabled.Value && currentDeathReport != null)
				{
					SaveCurrentReport();
					((MonoBehaviour)Instance).StartCoroutine(ShowSavedFeedback(autoSaveText));
				}
			});
			GameObject val7 = GUIManager.Instance.CreateButton("Save to File", reportPanel.transform, new Vector2(0.5f, 0.05f), new Vector2(0.5f, 0.05f), new Vector2(150f, 65f), 130f, 35f);
			saveButton = val7.GetComponent<Button>();
			Text saveButtonText = ((Component)saveButton).GetComponentInChildren<Text>();
			((UnityEvent)saveButton.onClick).AddListener((UnityAction)delegate
			{
				SaveCurrentReport();
				((MonoBehaviour)Instance).StartCoroutine(ShowSavedFeedback(saveButtonText));
			});
			GameObject val8 = GUIManager.Instance.CreateButton("Reset Layout", reportPanel.transform, new Vector2(0.5f, 0.05f), new Vector2(0.5f, 0.05f), new Vector2(-145f, 22f), 130f, 35f);
			Button component2 = val8.GetComponent<Button>();
			((UnityEvent)component2.onClick).AddListener((UnityAction)delegate
			{
				//IL_0034: Unknown result type (might be due to invalid IL or missing references)
				//IL_0078: Unknown result type (might be due to invalid IL or missing references)
				if ((Object)(object)reportPanel != (Object)null)
				{
					RectTransform component7 = reportPanel.GetComponent<RectTransform>();
					if ((Object)(object)component7 != (Object)null)
					{
						component7.anchoredPosition = DefaultReportPos;
					}
				}
				if ((Object)(object)damageHistoryPanel != (Object)null)
				{
					RectTransform component8 = damageHistoryPanel.GetComponent<RectTransform>();
					if ((Object)(object)component8 != (Object)null)
					{
						component8.anchoredPosition = DefaultHistoryPos;
					}
				}
			});
			GameObject val9 = GUIManager.Instance.CreateButton(enableLiveCombatLog.Value ? "Combat Log: ON" : "Combat Log: OFF", reportPanel.transform, new Vector2(0.5f, 0.05f), new Vector2(0.5f, 0.05f), new Vector2(0f, 22f), 140f, 35f);
			Button component3 = val9.GetComponent<Button>();
			combatLogToggleText = val9.GetComponentInChildren<Text>();
			((Graphic)combatLogToggleText).color = (enableLiveCombatLog.Value ? Color.green : Color.white);
			((UnityEvent)component3.onClick).AddListener((UnityAction)delegate
			{
				enableLiveCombatLog.Value = !enableLiveCombatLog.Value;
				if (enableLiveCombatLog.Value)
				{
					lastCombatActionTime = Time.time;
				}
				UpdateCombatLogButtonUI();
				((BaseUnityPlugin)this).Config.Save();
			});
			GameObject val10 = GUIManager.Instance.CreateButton("Clear Old Reports", reportPanel.transform, new Vector2(0.5f, 0.05f), new Vector2(0.5f, 0.05f), new Vector2(145f, 22f), 130f, 35f);
			Button component4 = val10.GetComponent<Button>();
			Text clearText = val10.GetComponentInChildren<Text>();
			((UnityEvent)component4.onClick).AddListener((UnityAction)delegate
			{
				ClearOldReports();
				((MonoBehaviour)Instance).StartCoroutine(ShowSavedFeedback(clearText, "<color=#00ff00>Old Cleared!</color>"));
			});
			GameObject tooltipObj = GUIManager.Instance.CreateWoodpanel(reportPanel.transform, new Vector2(0.5f, 0.05f), new Vector2(0.5f, 0.05f), new Vector2(145f, 75f), 260f, 45f);
			tooltipObj.SetActive(false);
			Text component5 = GUIManager.Instance.CreateText("Deletes all saved reports except the most recent one.", tooltipObj.transform, new Vector2(0.5f, 0.5f), new Vector2(0.5f, 0.5f), new Vector2(0f, 0f), GUIManager.Instance.AveriaSerif, 11, Color.yellow, true, Color.black, 240f, 35f, false).GetComponent<Text>();
			component5.alignment = (TextAnchor)4;
			EventTrigger val11 = val10.gameObject.AddComponent<EventTrigger>();
			Entry val12 = new Entry
			{
				eventID = (EventTriggerType)0
			};
			((UnityEvent<BaseEventData>)(object)val12.callback).AddListener((UnityAction<BaseEventData>)delegate
			{
				tooltipObj.SetActive(true);
			});
			val11.triggers.Add(val12);
			Entry val13 = new Entry
			{
				eventID = (EventTriggerType)1
			};
			((UnityEvent<BaseEventData>)(object)val13.callback).AddListener((UnityAction<BaseEventData>)delegate
			{
				tooltipObj.SetActive(false);
			});
			val11.triggers.Add(val13);
			GameObject val14 = GUIManager.Instance.CreateButton("Damage History", reportPanel.transform, new Vector2(0.5f, 1f), new Vector2(0.5f, 1f), new Vector2(130f, -176f), 140f, 30f);
			Button component6 = val14.GetComponent<Button>();
			damageHistoryPanel = GUIManager.Instance.CreateWoodpanel(reportPanel.transform, new Vector2(0.5f, 1f), new Vector2(0.5f, 1f), new Vector2(130f, -326f), 450f, 275f);
			damageHistoryPanel.SetActive(false);
			GameObject val15 = GUIManager.Instance.CreateText("", damageHistoryPanel.transform, new Vector2(0.5f, 0.5f), new Vector2(0.5f, 0.5f), new Vector2(0f, 0f), GUIManager.Instance.AveriaSerif, 14, Color.white, true, Color.black, 430f, 255f, false);
			damageHistoryText = val15.GetComponent<Text>();
			((UnityEvent)component6.onClick).AddListener((UnityAction)delegate
			{
				damageHistoryPanel.SetActive(!damageHistoryPanel.activeSelf);
				if (damageHistoryPanel.activeSelf && ((Object)(object)historyDropdown == (Object)null || historyDropdown.value == 0))
				{
					UpdateDamageHistoryText();
				}
			});
			GameObject val16 = GUIManager.Instance.CreateText("Wall of Shame (History)", reportPanel.transform, new Vector2(0.5f, 0.12f), new Vector2(0.5f, 0.12f), new Vector2(0f, 75f), GUIManager.Instance.AveriaSerifBold, 20, new Color(1f, 0.647f, 0f), true, Color.black, 250f, 30f, false);
			val16.GetComponent<Text>().alignment = (TextAnchor)4;
			GameObject val17 = GUIManager.Instance.CreateDropDown(reportPanel.transform, new Vector2(0.5f, 0.12f), new Vector2(0.5f, 0.12f), new Vector2(0f, 45f), 16, 250f, 35f);
			historyDropdown = val17.GetComponent<Dropdown>();
			((UnityEvent<int>)(object)historyDropdown.onValueChanged).AddListener((UnityAction<int>)OnDropdownChanged);
			RefreshHistoryDropdown();
			GameObject val18 = GUIManager.Instance.CreateText("Press [TAB] for mouse (window is draggable).\nPress [F8] to toggle.", reportPanel.transform, new Vector2(0.5f, 1f), new Vector2(0.5f, 1f), new Vector2(0f, -25f), GUIManager.Instance.AveriaSerif, 12, Color.green, true, Color.black, 480f, 40f, false);
			hintText = val18.GetComponent<Text>();
			hintText.alignment = (TextAnchor)4;
			hintText.horizontalOverflow = (HorizontalWrapMode)0;
			((Graphic)hintText).raycastTarget = false;
		}

		public static void SaveCurrentReport()
		{
			if ((Object)(object)Instance == (Object)null)
			{
				return;
			}
			try
			{
				string input = GenerateReportContent(forSaveFile: true);
				string arg = Regex.Replace(input, "<.*?>", string.Empty);
				string text = Path.Combine(Paths.ConfigPath, "AutopsyReportLogs");
				if (!Directory.Exists(text))
				{
					Directory.CreateDirectory(text);
				}
				string path = $"AutopsyReport_{DateTime.Now:yyyy-MM-dd_HH-mm-ss}.txt";
				string path2 = Path.Combine(text, path);
				File.WriteAllText(path2, $"--- AUTOPSY REPORT [{DateTime.Now:yyyy-MM-dd HH:mm:ss}] ---\n{arg}\n");
				Instance.RefreshHistoryDropdown();
			}
			catch (Exception ex)
			{
				Log.LogError((object)("Failed to save report: " + ex.Message));
			}
		}

		private IEnumerator ShowSavedFeedback(Text btnText, string msg = "<color=#00ff00>Saved!</color>")
		{
			string originalText = btnText.text;
			btnText.text = msg;
			yield return (object)new WaitForSeconds(2f);
			btnText.text = originalText;
		}

		private void ClearOldReports()
		{
			try
			{
				string path = Path.Combine(Paths.ConfigPath, "AutopsyReportLogs");
				if (Directory.Exists(path))
				{
					string[] files = Directory.GetFiles(path, "AutopsyReport_*.txt");
					Array.Sort(files);
					Array.Reverse(files);
					for (int i = 1; i < files.Length; i++)
					{
						try
						{
							File.Delete(files[i]);
						}
						catch
						{
						}
					}
				}
				RefreshHistoryDropdown();
				if ((Object)(object)historyDropdown != (Object)null)
				{
					historyDropdown.value = 0;
				}
				UpdateReportText();
				UpdateDamageHistoryText();
			}
			catch (Exception ex)
			{
				Log.LogError((object)("Failed to clear old reports: " + ex.Message));
			}
		}

		private void RefreshHistoryDropdown()
		{
			if ((Object)(object)historyDropdown == (Object)null)
			{
				return;
			}
			historyDropdown.ClearOptions();
			savedFilePaths.Clear();
			List<string> list = new List<string>();
			list.Add("Current Death (Live)");
			savedFilePaths.Add("");
			string path = Path.Combine(Paths.ConfigPath, "AutopsyReportLogs");
			if (Directory.Exists(path))
			{
				string[] files = Directory.GetFiles(path, "AutopsyReport_*.txt");
				Array.Sort(files);
				Array.Reverse(files);
				string[] array = files;
				foreach (string text in array)
				{
					string fileNameWithoutExtension = Path.GetFileNameWithoutExtension(text);
					string item = fileNameWithoutExtension.Replace("AutopsyReport_", "").Replace("_", " ");
					list.Add(item);
					savedFilePaths.Add(text);
				}
			}
			historyDropdown.AddOptions(list);
		}

		private void OnDropdownChanged(int index)
		{
			if (index == 0 || savedFilePaths.Count <= index || string.IsNullOrEmpty(savedFilePaths[index]))
			{
				UpdateReportText();
				UpdateDamageHistoryText();
				return;
			}
			try
			{
				string text = File.ReadAllText(savedFilePaths[index]);
				string text2 = text;
				string text3 = "";
				int num = text.IndexOf("Last 10 Hits Timeline:");
				if (num < 0)
				{
					num = text.IndexOf("Last 10 Hits (Reverse Chronological):");
				}
				if (num < 0)
				{
					num = text.IndexOf("Last 10 Hits:");
				}
				if (num < 0)
				{
					num = text.IndexOf("Last 10 Hits");
				}
				if (num >= 0)
				{
					text2 = text.Substring(0, num).TrimEnd();
					text3 = text.Substring(num).Trim();
				}
				if (text2.StartsWith("--- AUTOPSY REPORT"))
				{
					int num2 = text2.IndexOf('\n');
					if (num2 >= 0)
					{
						text2 = text2.Substring(num2 + 1).TrimStart('\r', '\n');
					}
				}
				text2 = text2.Replace("Killer:", "<color=#87CEFA><b>Killer:</b></color>");
				text2 = text2.Replace("Fatal hit:", "<color=#87CEFA><b>Fatal hit:</b></color>");
				text2 = text2.Replace("Skills Lost:", "<color=#87CEFA><b>Skills Lost:</b></color>");
				text2 = text2.Replace("Active Buffs at time of death:", "<color=#87CEFA><b>Active Buffs at time of death:</b></color>");
				text2 = Regex.Replace(text2, "\\(([0-9,.]+\\s+Overkill)\\)", "(<color=red>$1</color>)");
				text2 = Regex.Replace(text2, "\\((Blocked:\\s+[0-9,.]+)\\)", "(<color=yellow>$1</color>)");
				text2 = Regex.Replace(text2, "\\[([A-Za-z/]+)\\]", "<color=#B0C4DE>[$1]</color>");
				text2 = text2.Replace("★", "<color=yellow>★</color>");
				reportText.text = "<color=white>" + text2 + "</color>";
				if (!string.IsNullOrEmpty(text3))
				{
					int num3 = text3.IndexOf('\n');
					string text4 = ((num3 >= 0) ? text3.Substring(num3 + 1).Trim() : "");
					string text5 = "<color=#87CEFA><b>Last 10 Hits Timeline (Reverse Chronological):</b></color>\n";
					if (!string.IsNullOrEmpty(text4))
					{
						text4 = Regex.Replace(text4, "\\((Blocked:\\s+[0-9,.]+)\\)", "(<color=yellow>$1</color>)");
						text4 = Regex.Replace(text4, "\\[([A-Za-z/]+)\\]", "<color=#B0C4DE>[$1]</color>");
						text4 = Regex.Replace(text4, "\\[FATAL\\]", "<color=#ff3333><b>[FATAL]</b></color>");
						text4 = text4.Replace("★", "<color=yellow>★</color>");
						SetDamageHistoryText(text5 + "<color=white>" + text4 + "</color>");
					}
					else
					{
						SetDamageHistoryText(text5 + "<color=white>No hit history in this report.</color>");
					}
				}
				else
				{
					SetDamageHistoryText("<color=#87CEFA><b>Last 10 Hits Timeline (Reverse Chronological):</b></color>\n<color=white>No hit history in this report.</color>");
				}
			}
			catch (Exception ex)
			{
				Log.LogError((object)("Failed to load report: " + ex.Message));
				reportText.text = "Failed to load report: " + ex.Message;
			}
		}

		private unsafe void Update()
		{
			//IL_01f1: Unknown result type (might be due to invalid IL or missing references)
			//IL_01f6: Unknown result type (might be due to invalid IL or missing references)
			//IL_027e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0283: Unknown result type (might be due to invalid IL or missing references)
			//IL_019c: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a1: Unknown result type (might be due to invalid IL or missing references)
			if (showReport && Input.GetKeyDown((KeyCode)27))
			{
				showReport = false;
			}
			if ((Object)(object)reportPanel != (Object)null)
			{
				if (showReport && !reportPanel.activeSelf)
				{
					reportPanel.SetActive(true);
					if ((Object)(object)damageHistoryPanel != (Object)null)
					{
						damageHistoryPanel.SetActive(false);
					}
					RefreshHistoryDropdown();
					if ((Object)(object)historyDropdown != (Object)null)
					{
						historyDropdown.value = 0;
					}
					UpdateReportText();
					UpdateDamageHistoryText();
				}
				else if (!showReport && reportPanel.activeSelf)
				{
					reportPanel.SetActive(false);
					if ((Object)(object)damageHistoryPanel != (Object)null)
					{
						damageHistoryPanel.SetActive(false);
					}
				}
			}
			KeyboardShortcut value;
			if ((Object)(object)hintText != (Object)null)
			{
				string text = "TAB";
				if (ZInput.instance != null)
				{
					string boundKeyString = ZInput.instance.GetBoundKeyString("inventory", false);
					if (!string.IsNullOrEmpty(boundKeyString) && !boundKeyString.Contains("MISSING"))
					{
						text = boundKeyString;
					}
					else
					{
						boundKeyString = ZInput.instance.GetBoundKeyString("Inventory", false);
						if (!string.IsNullOrEmpty(boundKeyString) && !boundKeyString.Contains("MISSING"))
						{
							text = boundKeyString;
						}
					}
				}
				value = toggleHotkey.Value;
				string text2 = ((object)(*(KeyboardShortcut*)(&value))/*cast due to .constrained prefix*/).ToString();
				hintText.text = "Press [" + text + "] for mouse (window is draggable).\nPress [" + text2 + "] to toggle.";
			}
			value = toggleHotkey.Value;
			if (((KeyboardShortcut)(ref value)).IsDown())
			{
				if (currentDeathReport != null || savedFilePaths.Count > 1)
				{
					showReport = !showReport;
					if (showReport)
					{
						Player localPlayer = Player.m_localPlayer;
						if (localPlayer != null)
						{
							((Character)localPlayer).Message((MessageType)1, "Autopsy Report Opened.", 0, (Sprite)null, false);
						}
					}
				}
				else
				{
					Player localPlayer2 = Player.m_localPlayer;
					if (localPlayer2 != null)
					{
						((Character)localPlayer2).Message((MessageType)1, "No Autopsy Data available yet!", 0, (Sprite)null, false);
					}
				}
			}
			value = toggleCombatLogHotkey.Value;
			if (((KeyboardShortcut)(ref value)).IsDown())
			{
				enableLiveCombatLog.Value = !enableLiveCombatLog.Value;
				if (enableLiveCombatLog.Value)
				{
					lastCombatActionTime = Time.time;
				}
				((BaseUnityPlugin)this).Config.Save();
				UpdateCombatLogButtonUI();
				Player localPlayer3 = Player.m_localPlayer;
				if (localPlayer3 != null)
				{
					((Character)localPlayer3).Message((MessageType)1, enableLiveCombatLog.Value ? "Combat Log: Enabled" : "Combat Log: Disabled", 0, (Sprite)null, false);
				}
			}
		}

		public static void UpdateCombatLogButtonUI()
		{
			//IL_006b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0064: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)Instance != (Object)null && (Object)(object)Instance.combatLogToggleText != (Object)null)
			{
				Instance.combatLogToggleText.text = (enableLiveCombatLog.Value ? "Combat Log: ON" : "Combat Log: OFF");
				((Graphic)Instance.combatLogToggleText).color = (enableLiveCombatLog.Value ? Color.green : Color.white);
			}
		}

		public static void SetDamageHistoryText(string txt)
		{
			//IL_0097: 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_00d4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00de: Unknown result type (might be due to invalid IL or missing references)
			if (!((Object)(object)Instance == (Object)null) && !((Object)(object)Instance.damageHistoryText == (Object)null) && !((Object)(object)Instance.damageHistoryPanel == (Object)null))
			{
				Instance.damageHistoryText.text = txt;
				float num = Instance.damageHistoryText.preferredWidth + 40f;
				float num2 = Mathf.Clamp(num, 430f, 560f);
				RectTransform component = Instance.damageHistoryPanel.GetComponent<RectTransform>();
				if ((Object)(object)component != (Object)null)
				{
					component.sizeDelta = new Vector2(num2, component.sizeDelta.y);
				}
				RectTransform component2 = ((Component)Instance.damageHistoryText).GetComponent<RectTransform>();
				if ((Object)(object)component2 != (Object)null)
				{
					component2.sizeDelta = new Vector2(num2 - 20f, component2.sizeDelta.y);
				}
			}
		}

		private static void DrawSlicedSprite(Rect position, Sprite sp)
		{
			//IL_0025: 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_0046: Unknown result type (might be due to invalid IL or missing references)
			//IL_004b: Unknown result type (might be due to invalid IL or missing references)
			//IL_004c: 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_0068: Unknown result type (might be due to invalid IL or missing references)
			//IL_007c: 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_0098: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b4: Unknown result type (might be due to invalid IL or missing references)
			//IL_01bc: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d5: Unknown result type (might be due to invalid IL or missing references)
			//IL_01eb: Unknown result type (might be due to invalid IL or missing references)
			//IL_0204: Unknown result type (might be due to invalid IL or missing references)
			//IL_0217: Unknown result type (might be due to invalid IL or missing references)
			//IL_0230: Unknown result type (might be due to invalid IL or missing references)
			//IL_0246: Unknown result type (might be due to invalid IL or missing references)
			//IL_025f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0278: Unknown result type (might be due to invalid IL or missing references)
			//IL_0291: Unknown result type (might be due to invalid IL or missing references)
			//IL_02a7: Unknown result type (might be due to invalid IL or missing references)
			//IL_02c0: 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_02ec: Unknown result type (might be due to invalid IL or missing references)
			//IL_0302: Unknown result type (might be due to invalid IL or missing references)
			//IL_031b: Unknown result type (might be due to invalid IL or missing references)
			//IL_032e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0347: Unknown result type (might be due to invalid IL or missing references)
			if (!((Object)(object)sp == (Object)null) && !((Object)(object)sp.texture == (Object)null))
			{
				Rect textureRect = sp.textureRect;
				float num = ((Texture)sp.texture).width;
				float num2 = ((Texture)sp.texture).height;
				Vector4 border = sp.border;
				float num3 = ((border.x > 0f) ? border.x : 16f);
				float num4 = ((border.y > 0f) ? border.y : 16f);
				float num5 = ((border.z > 0f) ? border.z : 16f);
				float num6 = ((border.w > 0f) ? border.w : 16f);
				float num7 = ((Rect)(ref textureRect)).x / num;
				float num8 = (((Rect)(ref textureRect)).x + num3) / num;
				float num9 = (((Rect)(ref textureRect)).x + ((Rect)(ref textureRect)).width - num5) / num;
				float num10 = (((Rect)(ref textureRect)).x + ((Rect)(ref textureRect)).width) / num;
				float num11 = ((Rect)(ref textureRect)).y / num2;
				float num12 = (((Rect)(ref textureRect)).y + num4) / num2;
				float num13 = (((Rect)(ref textureRect)).y + ((Rect)(ref textureRect)).height - num6) / num2;
				float num14 = (((Rect)(ref textureRect)).y + ((Rect)(ref textureRect)).height) / num2;
				float x = ((Rect)(ref position)).x;
				float num15 = ((Rect)(ref position)).x + num3;
				float num16 = ((Rect)(ref position)).x + ((Rect)(ref position)).width - num5;
				float num17 = ((Rect)(ref position)).x + ((Rect)(ref position)).width;
				float y = ((Rect)(ref position)).y;
				float num18 = ((Rect)(ref position)).y + num6;
				float num19 = ((Rect)(ref position)).y + ((Rect)(ref position)).height - num4;
				float num20 = ((Rect)(ref position)).y + ((Rect)(ref position)).height;
				GUI.DrawTextureWithTexCoords(new Rect(x, y, num3, num6), (Texture)(object)sp.texture, new Rect(num7, num13, num8 - num7, num14 - num13));
				GUI.DrawTextureWithTexCoords(new Rect(num15, y, num16 - num15, num6), (Texture)(object)sp.texture, new Rect(num8, num13, num9 - num8, num14 - num13));
				GUI.DrawTextureWithTexCoords(new Rect(num16, y, num5, num6), (Texture)(object)sp.texture, new Rect(num9, num13, num10 - num9, num14 - num13));
				GUI.DrawTextureWithTexCoords(new Rect(x, num18, num3, num19 - num18), (Texture)(object)sp.texture, new Rect(num7, num12, num8 - num7, num13 - num12));
				GUI.DrawTextureWithTexCoords(new Rect(num15, num18, num16 - num15, num19 - num18), (Texture)(object)sp.texture, new Rect(num8, num12, num9 - num8, num13 - num12));
				GUI.DrawTextureWithTexCoords(new Rect(num16, num18, num5, num19 - num18), (Texture)(object)sp.texture, new Rect(num9, num12, num10 - num9, num13 - num12));
				GUI.DrawTextureWithTexCoords(new Rect(x, num19, num3, num4), (Texture)(object)sp.texture, new Rect(num7, num11, num8 - num7, num12 - num11));
				GUI.DrawTextureWithTexCoords(new Rect(num15, num19, num16 - num15, num4), (Texture)(object)sp.texture, new Rect(num8, num11, num9 - num8, num12 - num11));
				GUI.DrawTextureWithTexCoords(new Rect(num16, num19, num5, num4), (Texture)(object)sp.texture, new Rect(num9, num11, num10 - num9, num12 - num11));
			}
		}

		private void OnGUI()
		{
			//IL_012b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0135: Expected O, but got Unknown
			//IL_013d: Unknown result type (might be due to invalid IL or missing references)
			//IL_016b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0175: Expected O, but got Unknown
			//IL_0191: Unknown result type (might be due to invalid IL or missing references)
			//IL_01bf: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c9: Expected O, but got Unknown
			//IL_01e5: Unknown result type (might be due to invalid IL or missing references)
			//IL_023f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0244: Unknown result type (might be due to invalid IL or missing references)
			//IL_024c: 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_025d: Unknown result type (might be due to invalid IL or missing references)
			//IL_026a: Expected O, but got Unknown
			//IL_02ca: Unknown result type (might be due to invalid IL or missing references)
			//IL_02cf: Unknown result type (might be due to invalid IL or missing references)
			//IL_02d7: Unknown result type (might be due to invalid IL or missing references)
			//IL_02e4: Expected O, but got Unknown
			//IL_02a3: Unknown result type (might be due to invalid IL or missing references)
			//IL_036c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0371: Unknown result type (might be due to invalid IL or missing references)
			//IL_0379: Unknown result type (might be due to invalid IL or missing references)
			//IL_0382: Unknown result type (might be due to invalid IL or missing references)
			//IL_038a: Unknown result type (might be due to invalid IL or missing references)
			//IL_038f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0399: Expected O, but got Unknown
			//IL_039f: Expected O, but got Unknown
			//IL_03f4: Unknown result type (might be due to invalid IL or missing references)
			//IL_040a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0434: Unknown result type (might be due to invalid IL or missing references)
			//IL_0309: Unknown result type (might be due to invalid IL or missing references)
			//IL_06d9: Unknown result type (might be due to invalid IL or missing references)
			//IL_06de: Unknown result type (might be due to invalid IL or missing references)
			//IL_0794: Unknown result type (might be due to invalid IL or missing references)
			//IL_07a6: Unknown result type (might be due to invalid IL or missing references)
			//IL_07cd: Unknown result type (might be due to invalid IL or missing references)
			//IL_07df: Unknown result type (might be due to invalid IL or missing references)
			//IL_07f0: Unknown result type (might be due to invalid IL or missing references)
			//IL_080e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0823: Unknown result type (might be due to invalid IL or missing references)
			//IL_0841: Unknown result type (might be due to invalid IL or missing references)
			//IL_08d4: Unknown result type (might be due to invalid IL or missing references)
			//IL_08f8: Unknown result type (might be due to invalid IL or missing references)
			//IL_0876: Unknown result type (might be due to invalid IL or missing references)
			//IL_0891: Unknown result type (might be due to invalid IL or missing references)
			//IL_08b5: Unknown result type (might be due to invalid IL or missing references)
			//IL_0676: Unknown result type (might be due to invalid IL or missing references)
			//IL_0682: Expected O, but got Unknown
			//IL_090a: Unknown result type (might be due to invalid IL or missing references)
			//IL_092d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0760: Unknown result type (might be due to invalid IL or missing references)
			//IL_0744: Unknown result type (might be due to invalid IL or missing references)
			//IL_0a03: Unknown result type (might be due to invalid IL or missing references)
			//IL_0a08: Unknown result type (might be due to invalid IL or missing references)
			//IL_0a0f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0a20: Unknown result type (might be due to invalid IL or missing references)
			//IL_0a31: Unknown result type (might be due to invalid IL or missing references)
			//IL_0e04: Unknown result type (might be due to invalid IL or missing references)
			//IL_0e14: Unknown result type (might be due to invalid IL or missing references)
			//IL_0e24: Unknown result type (might be due to invalid IL or missing references)
			//IL_0ac6: Unknown result type (might be due to invalid IL or missing references)
			//IL_0b01: Unknown result type (might be due to invalid IL or missing references)
			//IL_0b3c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0e7d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0b88: Unknown result type (might be due to invalid IL or missing references)
			//IL_0eb5: Unknown result type (might be due to invalid IL or missing references)
			//IL_0ef7: Unknown result type (might be due to invalid IL or missing references)
			//IL_0b9f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0be7: Unknown result type (might be due to invalid IL or missing references)
			//IL_0bed: Invalid comparison between Unknown and I4
			//IL_0bbd: Unknown result type (might be due to invalid IL or missing references)
			//IL_0bc2: Unknown result type (might be due to invalid IL or missing references)
			//IL_0c91: Unknown result type (might be due to invalid IL or missing references)
			//IL_0c97: Invalid comparison between Unknown and I4
			//IL_0c04: Unknown result type (might be due to invalid IL or missing references)
			//IL_0c0a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0c0f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0c14: Unknown result type (might be due to invalid IL or missing references)
			//IL_0c21: Unknown result type (might be due to invalid IL or missing references)
			//IL_0c4d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0ccc: Unknown result type (might be due to invalid IL or missing references)
			//IL_0cd7: Unknown result type (might be due to invalid IL or missing references)
			//IL_0d2e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0d34: Invalid comparison between Unknown and I4
			//IL_0cf5: Unknown result type (might be due to invalid IL or missing references)
			//IL_0cfa: Unknown result type (might be due to invalid IL or missing references)
			//IL_0d14: Unknown result type (might be due to invalid IL or missing references)
			//IL_0d19: Unknown result type (might be due to invalid IL or missing references)
			//IL_0dcc: Unknown result type (might be due to invalid IL or missing references)
			//IL_0dd2: Invalid comparison between Unknown and I4
			//IL_0d4b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0d51: Unknown result type (might be due to invalid IL or missing references)
			//IL_0d56: Unknown result type (might be due to invalid IL or missing references)
			//IL_0d5b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0d6d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0d9e: Unknown result type (might be due to invalid IL or missing references)
			if (!enableLiveCombatLog.Value || (Object)(object)Player.m_localPlayer == (Object)null || ((Object)(object)Hud.instance != (Object)null && Hud.IsUserHidden()))
			{
				return;
			}
			bool flag = Cursor.visible || InventoryGui.IsVisible() || Menu.IsVisible() || showReport;
			float num = 1f;
			if (!isPinned.Value && !flag && fadeoutDelay.Value > 0f)
			{
				float num2 = Time.time - lastCombatActionTime;
				if (num2 > fadeoutDelay.Value + 1.5f)
				{
					return;
				}
				if (num2 > fadeoutDelay.Value)
				{
					num = Mathf.Clamp01(1f - (num2 - fadeoutDelay.Value) / 1.5f);
				}
			}
			if (num <= 0.01f)
			{
				return;
			}
			if ((Object)(object)bgTexture == (Object)null)
			{
				bgTexture = new Texture2D(1, 1);
				bgTexture.SetPixel(0, 0, Color.white);
				bgTexture.Apply();
			}
			if ((Object)(object)titleTexture == (Object)null)
			{
				titleTexture = new Texture2D(1, 1);
				titleTexture.SetPixel(0, 0, new Color(0.18f, 0.15f, 0.12f, 0.95f));
				titleTexture.Apply();
			}
			if ((Object)(object)borderTexture == (Object)null)
			{
				borderTexture = new Texture2D(1, 1);
				borderTexture.SetPixel(0, 0, new Color(0.48f, 0.38f, 0.24f, 0.9f));
				borderTexture.Apply();
			}
			Font val = ((GUIManager.Instance != null && (Object)(object)GUIManager.Instance.AveriaSerifBold != (Object)null) ? GUIManager.Instance.AveriaSerifBold : null);
			if (titleStyle == null)
			{
				titleStyle = new GUIStyle(GUI.skin.label)
				{
					alignment = (TextAnchor)3,
					fontSize = 14,
					fontStyle = (FontStyle)1,
					richText = true
				};
				if ((Object)(object)val != (Object)null)
				{
					titleStyle.font = val;
				}
				titleStyle.normal.textColor = new Color(1f, 0.8f, 0.4f, 1f);
			}
			if (textStyle == null)
			{
				textStyle = new GUIStyle(GUI.skin.label)
				{
					alignment = (TextAnchor)3,
					richText = true
				};
				if ((Object)(object)val != (Object)null)
				{
					textStyle.font = val;
				}
				textStyle.normal.textColor = Color.white;
			}
			textStyle.fontSize = combatLogFontSize.Value;
			textStyle.wordWrap = wordWrapCombatLog.Value;
			textStyle.clipping = (TextClipping)1;
			if (btnStyle == null)
			{
				btnStyle = new GUIStyle(GUI.skin.label)
				{
					alignment = (TextAnchor)4,
					fontSize = 12,
					fontStyle = (FontStyle)1,
					padding = new RectOffset(0, 0, 0, 0)
				};
				btnStyle.normal.background = null;
				btnStyle.hover.background = null;
				btnStyle.active.background = null;
				btnStyle.normal.textColor = new Color(1f, 0.8f, 0.4f, 0.9f);
				btnStyle.hover.textColor = Color.white;
				btnStyle.active.textColor = new Color(1f, 0.6f, 0.2f, 1f);
			}
			float value = boxPositionX.Value;
			float value2 = boxPositionY.Value;
			float num3 = Mathf.Clamp(boxWidth.Value, 260f, (float)Screen.width - 20f);
			float num4 = 24f;
			List<CombatEvent> list = new List<CombatEvent>();
			foreach (CombatEvent recentCombatEvent in recentCombatEvents)
			{
				if (recentCombatEvent.eventType == CombatEventType.IncomingDamage && !showIncomingDamage.Value)
				{
					continue;
				}
				if (recentCombatEvent.eventType == CombatEventType.OutgoingDamage)
				{
					if (!string.IsNullOrEmpty(recentCombatEvent.sourceName))
					{
						if (!showMinionDamage.Value)
						{
							continue;
						}
					}
					else if (!showOutgoingDamage.Value)
					{
						continue;
					}
				}
				if ((recentCombatEvent.eventType != CombatEventType.IncomingHeal || showActiveHeals.Value) && (recentCombatEvent.eventType != CombatEventType.Blocked || showBlockedDamage.Value))
				{
					list.Add(recentCombatEvent);
					if (list.Count >= maxLogLines.Value)
					{
						break;
					}
				}
			}
			if (scrollDirection.Value == LogScrollDirection.NewestAtBottom)
			{
				list.Reverse();
			}
			float num5 = (float)combatLogFontSize.Value + 7f;
			List<string> list2 = new List<string>(list.Count);
			List<float> list3 = new List<float>(list.Count);
			float num6 = 0f;
			float num7 = num3 - 20f;
			if (!isMinimized.Value)
			{
				if (list.Count == 0)
				{
					num6 = num5;
				}
				else
				{
					for (int i = 0; i < list.Count; i++)
					{
						string text = FormatCombatEventLine(list[i]);
						list2.Add(text);
						float num8 = num5;
						if (wordWrapCombatLog.Value)
						{
							num8 = Mathf.Max(num5, textStyle.CalcHeight(new GUIContent(text), num7));
						}
						list3.Add(num8);
						num6 += num8;
					}
				}
			}
			float num9 = (isMinimized.Value ? 0f : (num6 + 8f));
			float num10 = num4 + num9;
			Color color = GUI.color;
			if (useWoodpanelStyle.Value)
			{
				if ((Object)(object)woodSprite == (Object)null && GUIManager.Instance != null)
				{
					woodSprite = GUIManager.Instance.GetSprite("woodpanel_settings");
				}
				if ((Object)(object)woodSprite != (Object)null)
				{
					DrawSlicedSprite(new Rect(value, value2, num3, num10), woodSprite);
				}
				else
				{
					GUI.DrawTexture(new Rect(value, value2, num3, num10), (Texture)(object)bgTexture);
				}
			}
			else
			{
				GUI.color = new Color(0.04f, 0.04f, 0.05f, backgroundAlpha.Value * num);
				GUI.DrawTexture(new Rect(value, value2, num3, num10), (Texture)(object)bgTexture);
				GUI.color = new Color(0.2f, 0.16f, 0.12f, 0.85f * num);
				GUI.DrawTexture(new Rect(value, value2, num3, num4), (Texture)(object)titleTexture);
				GUI.color = color;
				GUI.color = new Color(0.55f, 0.42f, 0.26f, 0.95f * num);
				GUI.DrawTexture(new Rect(value, value2, num3, 2f), (Texture)(object)borderTexture);
				GUI.DrawTexture(new Rect(value, value2 + num4, num3, 1f), (Texture)(object)borderTexture);
				if (showContentBorder.Value)
				{
					GUI.DrawTexture(new Rect(value, value2 + num10 - 2f, num3, 2f), (Texture)(object)borderTexture);
					GUI.DrawTexture(new Rect(value, value2, 2f, num10), (Texture)(object)borderTexture);
					GUI.DrawTexture(new Rect(value + num3 - 2f, value2, 2f, num10), (Texture)(object)borderTexture);
				}
				else
				{
					GUI.DrawTexture(new Rect(value, value2, 2f, num4), (Texture)(object)borderTexture);
					GUI.DrawTexture(new Rect(value + num3 - 2f, value2, 2f, num4), (Texture)(object)borderTexture);
				}
				GUI.color = color;
			}
			Rect val2 = default(Rect);
			((Rect)(ref val2))..ctor(value + 8f, value2, num3 - 90f, num4);
			GUI.Label(val2, "<color=#ff9900><b>Combat Log</b></color>", titleStyle);
			float num11 = 20f;
			float num12 = 18f;
			float num13 = value2 + 2f;
			string text2 = (isPinned.Value ? "P" : "A");
			string text3 = (isMinimized.Value ? "▲" : "—");
			string text4 = "✕";
			Rect val3 = default(Rect);
			((Rect)(ref val3))..ctor(value + num3 - 70f, num13, num11, num12);
			Rect val4 = default(Rect);
			((Rect)(ref val4))..ctor(value + num3 - 46f, num13, num11, num12);
			Rect val5 = default(Rect);
			((Rect)(ref val5))..ctor(value + num3 - 22f, num13, num11, num12);
			Rect val6 = default(Rect);
			((Rect)(ref val6))..ctor(value + num3 - 16f, value2 + num10 - 16f, 16f, 16f);
			Vector2 mousePosition = Event.current.mousePosition;
			bool flag2 = flag && ((Rect)(ref val3)).Contains(mousePosition);
			bool flag3 = flag && ((Rect)(ref val4)).Contains(mousePosition);
			bool flag4 = flag && ((Rect)(ref val5)).Contains(mousePosition);
			string text5 = (flag2 ? ("<color=#ffffff><b>" + text2 + "</b></color>") : ("<color=#ffcc66>" + text2 + "</color>"));
			string text6 = (flag3 ? ("<color=#ffffff><b>" + text3 + "</b></color>") : ("<color=#ffcc66>" + text3 + "</color>"));
			string text7 = (flag4 ? ("<color=#ff4d4d><b>" + text4 + "</b></color>") : ("<color=#ffcc66>" + text4 + "</color>"));
			if (flag)
			{
				if (GUI.Button(val3, text5, btnStyle))
				{
					isPinned.Value = !isPinned.Value;
					((BaseUnityPlugin)this).Config.Save();
				}
				if (GUI.Button(val4, text6, btnStyle))
				{
					isMinimized.Value = !isMinimized.Value;
					((BaseUnityPlugin)this).Config.Save();
				}
				if (GUI.Button(val5, text7, btnStyle))
				{
					enableLiveCombatLog.Value = false;
					((BaseUnityPlugin)this).Config.Save();
				}
				Event current2 = Event.current;
				Rect val7 = default(Rect);
				((Rect)(ref val7))..ctor(value, value2, num3 - 75f, num4);
				if ((int)current2.type == 0 && !isMinimized.Value && ((Rect)(ref val6)).Contains(current2.mousePosition))
				{
					isResizingLog = true;
					resizeStartMousePos = current2.mousePosition;
					resizeStartWidth = num3;
					resizeStartHeight = num10;
					current2.Use();
				}
				else if ((int)current2.type == 3 && isResizingLog)
				{
					Vector2 val8 = current2.mousePosition - resizeStartMousePos;
					boxWidth.Value = Mathf.Clamp(resizeStartWidth + val8.x, 280f, (float)Screen.width - value - 10f);
					float num14 = resizeStartHeight + val8.y;
					int value3 = Mathf.Clamp(Mathf.RoundToInt((num14 - num4 - 8f) / num5), 3, 25);
					maxLogLines.Value = value3;
					current2.Use();
				}
				else if ((int)current2.type == 1 && isResizingLog)
				{
					isResizingLog = false;
					((BaseUnityPlugin)this).Config.Save();
					current2.Use();
				}
				else if ((int)current2.type == 0 && ((Rect)(ref val7)).Contains(current2.mousePosition))
				{
					isDraggingLog = true;
					dragStartMousePos = current2.mousePosition;
					dragStartBoxPos = new Vector2(boxPositionX.Value, boxPositionY.Value);
					current2.Use();
				}
				else if ((int)current2.type == 3 && isDraggingLog)
				{
					Vector2 val9 = current2.mousePosition - dragStartMousePos;
					boxPositionX.Value = Mathf.Clamp(dragStartBoxPos.x + val9.x, 0f, (float)Screen.width - num3);
					boxPositionY.Value = Mathf.Clamp(dragStartBoxPos.y + val9.y, 0f, (float)Screen.height - num10);
					current2.Use();
				}
				else if ((int)current2.type == 1 && isDraggingLog)
				{
					isDraggingLog = false;
					((BaseUnityPlugin)this).Config.Save();
					current2.Use();
				}
			}
			else
			{
				GUI.Label(val3, text5, btnStyle);
				GUI.Label(val4, text6, btnStyle);
				GUI.Label(val5, text7, btnStyle);
			}
			if (isMinimized.Value)
			{
				return;
			}
			float num15 = value2 + num4 + 4f;
			if (list.Count == 0)
			{
				GUI.Label(new Rect(value + 8f, num15, num3 - 16f, num5), "<color=#888888><i>No recent combat events</i></color>", textStyle);
			}
			else
			{
				for (int j = 0; j < list2.Count; j++)
				{
					float num16 = list3[j];
					GUI.Label(new Rect(value + 8f, num15, num7, num16), list2[j], textStyle);
					num15 += num16;
				}
			}
			if (flag)
			{
				GUI.Label(val6, "<color=#8b7355>◢</color>", btnStyle);
			}
		}

		private static string FormatCombatEventLine(CombatEvent ev)
		{
			switch (ev.eventType)
			{
			case CombatEventType.IncomingDamage:
			{
				string text8 = ((!string.IsNullOrEmpty(ev.damageType) && !string.Equals(ev.entityName, ev.damageType, StringComparison.OrdinalIgnoreCase)) ? (" (" + ev.damageType + ")") : "");
				string text9 = ((ev.blockedAmount > 0f) ? $" [<color=#ffd700>Blocked {ev.blockedAmount:0.0}</color>]" : "");
				string text10 = ((ev.tickCount > 1) ? $" ({ev.tickCount} ticks)" : "");
				return $"<color=#ff4d4d><b>-{ev.amount:0.0}</b></color> [{ev.entityName}{text8}{text10}]{text9} <color=#e0e0e0>(HP: {ev.healthAfter:0.0})</color>";
			}
			case CombatEventType.OutgoingDamage:
			{
				string text2 = damageIndicatorSymbol.Value;
				if (string.IsNullOrEmpty(text2) || text2 == "None")
				{
					text2 = "";
				}
				string text3 = ((ev.isCritOrWeakness && !string.IsNullOrEmpty(text2)) ? (" <color=#00ff88>" + text2 + "</color>") : "");
				string text4 = ((!string.IsNullOrEmpty(ev.damageType)) ? (" (" + ev.damageType + ")") : "");
				string text5 = ((ev.tickCount > 1) ? $" ({ev.tickCount} ticks)" : "");
				string text6 = ((!string.IsNullOrEmpty(ev.sourceName)) ? ("<color=#c4b5fd>[" + ev.sourceName + "]</color> ") : "");
				string text7 = (ev.isResisted ? "#aaaaaa" : "#ffcc00");
				return $"{text6}<color={text7}><b>+{ev.amount:0.0}</b></color>{text3} -> {ev.entityName}{text4}{text5}";
			}
			case CombatEventType.IncomingHeal:
			{
				string text11 = ((ev.tickCount > 1) ? $" ({ev.tickCount} ticks)" : "");
				return $"<color=#00ff88><b>+{ev.amount:0.0} HP</b></color> [{ev.entityName}{text11}] <color=#e0e0e0>(HP: {ev.healthAfter:0.0})</color>";
			}
			case CombatEventType.Blocked:
			{
				string text = (ev.isParry ? " [<color=#ffd700>Parry!</color>]" : "");
				return $"<color=#33ccff><b>Blocked {ev.amount:0.0}</b></color> from {ev.entityName}{text} <color=#e0e0e0>(HP: {ev.healthAfter:0.0})</color>";
			}
			default:
				return "";
			}
		}

		public static void UpdateDamageHistoryText()
		{
			if ((Object)(object)Instance == (Object)null || (Object)(object)Instance.damageHistoryText == (Object)null)
			{
				return;
			}
			string text = "<color=#87CEFA><b>Last 10 Hits Timeline (Reverse Chronological):</b></color>\n";
			List<CombatEvent> list = currentDeathReport?.timeline;
			if (list == null || list.Count == 0)
			{
				text += "<color=white>No hit history in this report.</color>";
			}
			else
			{
				foreach (CombatEvent item in list)
				{
					if (item.eventType == CombatEventType.IncomingHeal)
					{
						string text2 = ((item.tickCount > 1) ? $" ({item.tickCount} ticks)" : "");
						text += $"+ <color=#00ff88><b>{item.entityName}</b>: +{item.amount:0.0} HP{text2}</color> (HP left: {item.healthAfter:0.0})\n";
						continue;
					}
					if (item.eventType == CombatEventType.Blocked)
					{
						text += $"o <color=#33ccff><b>Blocked {item.amount:0.0} dmg</b></color> from {item.entityName} (HP left: {item.healthAfter:0.0})\n";
						continue;
					}
					string text3 = (item.isFatal ? "<color=#ff3333><b>[FATAL]</b></color> " : "");
					string text4 = ((!string.IsNullOrEmpty(item.damageType) && !string.Equals(item.entityName, item.damageType, StringComparison.OrdinalIgnoreCase)) ? (" <color=#B0C4DE>[" + item.damageType + "]</color>") : "");
					string text5 = ((item.blockedAmount > 0f) ? $" (<color=yellow>Blocked: {item.blockedAmount:0.0}</color>)" : "");
					string text6 = ((item.tickCount > 1) ? $" ({item.tickCount} ticks)" : "");
					text += $"- {text3}<b>{item.entityName}</b>: {item.amount:0.0} dmg{text4}{text5}{text6} (HP left: {item.healthAfter:0.0})\n";
				}
			}
			SetDamageHistoryText(text);
		}

		public static string GenerateReportContent(bool forSaveFile = false)
		{
			DeathReportData deathReportData = currentDeathReport;
			if (deathReportData == null)
			{
				return "<color=#87CEFA><b>Autopsy Report:</b></color>\nNo autopsy report available yet.";
			}
			string text = deathReportData.damageType;
			if (deathReportData.overkillAmount > 0f)
			{
				text += $" (<color=red>{deathReportData.overkillAmount:0.0} Overkill</color>)";
			}
			if (deathReportData.fatalBlockedDamage > 0f)
			{
				text += $" (<color=yellow>Blocked: {deathReportData.fatalBlockedDamage:0.0}</color>)";
			}
			string text2 = "<color=#87CEFA><b>Killer:</b></color> " + deathReportData.killerName + "\n<color=#87CEFA><b>Fatal hit:</b></color> " + text + "\n\n<color=#87CEFA><b>Skills Lost:</b></color>\n";
			if (deathReportData.skillLosses.Count == 0)
			{
				text2 = ((!deathReportData.hadNoSkillDrainBuff) ? (text2 + "No skill loss (Prevented by World Modifier or Mod?)\n") : (text2 + "No skill loss (Prevented by 'No skill drain' buff)\n"));
			}
			else
			{
				foreach (string skillLoss in deathReportData.skillLosses)
				{
					text2 = text2 + skillLoss + "\n";
				}
			}
			text2 += "\n<color=#87CEFA><b>Active Status Effects at time of death:</b></color>\n";
			if (deathReportData.activeStatusEffects.Count == 0)
			{
				text2 += "- None\n";
			}
			else
			{
				foreach (string activeStatusEffect in deathReportData.activeStatusEffects)
				{
					text2 = text2 + "- " + activeStatusEffect + "\n";
				}
			}
			if (forSaveFile && deathReportData.timeline.Count > 0)
			{
				text2 += "\n<color=#87CEFA><b>Last 10 Hits Timeline:</b></color>\n";
				foreach (CombatEvent item in deathReportData.timeline)
				{
					if (item.eventType == CombatEventType.IncomingHeal)
					{
						string text3 = ((item.tickCount > 1) ? $" ({item.tickCount} ticks)" : "");
						text2 += $"+ {item.entityName}: +{item.amount:0.0} HP{text3} (HP left: {item.healthAfter:0.0})\n";
					}
					else if (item.eventType == CombatEventType.Blocked)
					{
						text2 += $"o Blocked {item.amount:0.0} dmg from {item.entityName} (HP left: {item.healthAfter:0.0})\n";
					}
					else if (item.eventType == CombatEventType.IncomingDamage)
					{
						string text4 = (item.isFatal ? "[FATAL] " : "");
						string text5 = ((item.blockedAmount > 0f) ? $" (Blocked: {item.blockedAmount:0.0})" : "");
						string text6 = ((!string.IsNullOrEmpty(item.damageType) && !string.Equals(item.entityName, item.damageType, StringComparison.OrdinalIgnoreCase)) ? (" [" + item.damageType + "]") : "");
						text2 += $"- {text4}{item.entityName}: {item.amount:0.0} dmg{text6}{text5} (HP left: {item.healthAfter:0.0})\n";
					}
				}
			}
			return text2;
		}

		public static void UpdateReportText()
		{
			if (!((Object)(object)Instance == (Object)null) && !((Object)(object)Instance.reportText == (Object)null))
			{
				Instance.reportText.text = GenerateReportContent();
			}
		}
	}
	[HarmonyPatch(typeof(Humanoid), "BlockAttack")]
	public static class HumanoidBlockAttackPatch
	{
		public static bool isPlayerBlocking;

		public static float currentBlockedDamage;

		[HarmonyPrefix]
		public static void Prefix(Humanoid __instance)
		{
			if ((Object)(object)__instance == (Object)(object)Player.m_localPlayer)
			{
				isPlayerBlocking = true;
			}
		}

		[HarmonyPostfix]
		public static void Postfix(Humanoid __instance)
		{
			if ((Object)(object)__instance == (Object)(object)Player.m_localPlayer)
			{
				isPlayerBlocking = false;
			}
		}
	}
	[HarmonyPatch(typeof(HitData), "BlockDamage")]
	public static class HitDataBlockDamagePatch
	{
		[HarmonyPrefix]
		public static void Prefix(float damage)
		{
			if (HumanoidBlockAttackPatch.isPlayerBlocking)
			{
				HumanoidBlockAttackPatch.currentBlockedDamage = damage;
			}
		}
	}
	[HarmonyPatch(typeof(Character), "Damage")]
	public static class CharacterDamagePatch
	{
		public static HitData lastHit;

		public static string lastAttackerName;

		public static string lastPoisonAttackerName;

		public static string lastFireAttackerName;

		public static float lastMitigatedDamage;

		public static float lastBlockedDamage;

		public static float lastOverkill;

		[HarmonyPrefix]
		public static void Prefix(Character __instance, HitData hit)
		{
			string minionName;
			if ((Object)(object)__instance == (Object)(object)Player.m_localPlayer)
			{
				lastHit = hit;
				if ((Object)(object)hit.GetAttacker() != (Object)null)
				{
					lastAttackerName = AutopsyReportPlugin.FormatAttackerName(hit.GetAttacker(), hit);
					if (hit.m_damage.m_poison > 0f)
					{
						lastPoisonAttackerName = lastAttackerName;
					}
					if (hit.m_damage.m_fire > 0f)
					{
						lastFireAttackerName = lastAttackerName;
					}
				}
				HumanoidBlockAttackPatch.currentBlockedDamage = 0f;
			}
			else if (hit != null && ((Object)(object)hit.GetAttacker() == (Object)(object)Player.m_localPlayer || ((Object)(object)hit.GetAttacker() != (Object)null && AutopsyReportPlugin.IsPlayerMinionOrPet(hit.GetAttacker(), out minionName))))
			{
				if (hit.m_damage.m_fire > 0f)
				{
					AutopsyReportPlugin.playerBurningTargets[__instance] = Time.time + 15f;
				}
				if (hit.m_damage.m_poison > 0f)
				{
					AutopsyReportPlugin.playerPoisonTargets[__instance] = Time.time + 30f;
				}
				if (hit.m_damage.m_spirit > 0f)
				{
					AutopsyReportPlugin.playerSpiritTargets[__instance] = Time.time + 15f;
				}
			}
		}
	}
	[HarmonyPatch(typeof(Player), "OnDeath")]
	public static class PlayerDeathPatch
	{
		private static Dictionary<SkillType, float> preDeathSkills = new Dictionary<SkillType, float>();

		private static List<string> activeStatusEffects = new List<string>();

		[HarmonyPrefix]
		public static void Prefix(Player __instance)
		{
			//IL_0058: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)__instance != (Object)(object)Player.m_localPlayer)
			{
				return;
			}
			AutopsyReportPlugin.Log.LogInfo((object)"Player died. Gathering autopsy data...");
			preDeathSkills.Clear();
			foreach (Skill skill in ((Character)__instance).GetSkills().GetSkillList())
			{
				preDeathSkills[skill.m_info.m_skill] = skill.m_level + skill.GetLevelPercentage();
			}
			activeStatusEffects.Clear();
			foreach (StatusEffect statusEffect in ((Character)__instance).GetSEMan().GetStatusEffects())
			{
				activeStatusEffects.Add(statusEffect.m_name);
			}
			foreach (Food food in __instance.GetFoods())
			{
				activeStatusEffects.Add(food.m_item.m_shared.m_name);
			}
		}

		[HarmonyPostfix]
		public static void Postfix(Player __instance)
		{
			//IL_0077: Unknown result type (might be due to invalid IL or missing references)
			//IL_007d: Invalid comparison between Unknown and I4
			//IL_02ab: 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_00c9: Invalid comparison between Unknown and I4
			//IL_010f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0116: Invalid comparison between Unknown and I4
			//IL_0130: Unknown result type (might be due to invalid IL or missing references)
			//IL_0136: Invalid comparison between Unknown and I4
			//IL_0150: Unknown result type (might be due to invalid IL or missing references)
			//IL_0156: Invalid comparison between Unknown and I4
			//IL_0170: Unknown result type (might be due to invalid IL or missing references)
			//IL_0177: Invalid comparison between Unknown and I4
			//IL_018e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0195: Invalid comparison between Unknown and I4
			//IL_01ac: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b3: Invalid comparison between Unknown and I4
			//IL_01e0: Unknown result type (might be due to invalid IL or missing references)
			//IL_01e7: Invalid comparison between Unknown and I4
			if ((Object)(object)__instance != (Object)(object)Player.m_localPlayer)
			{
				return;
			}
			string text = "Unknown";
			string damageType = "Unknown damage";
			string damageTypeSummary = AutopsyReportPlugin.GetDamageTypeSummary(CharacterDamagePatch.lastHit);
			if (CharacterDamagePatch.lastHit != null)
			{
				text = (((Object)(object)CharacterDamagePatch.lastHit.GetAttacker() != (Object)null) ? AutopsyReportPlugin.FormatAttackerName(CharacterDamagePatch.lastHit.GetAttacker(), CharacterDamagePatch.lastHit) : (((int)CharacterDamagePatch.lastHit.m_hitType != 7 && !(CharacterDamagePatch.lastHit.m_damage.m_poison > 0f)) ? (((int)CharacterDamagePatch.lastHit.m_hitType != 5 && !(CharacterDamagePatch.lastHit.m_damage.m_fire > 0f)) ? (((int)CharacterDamagePatch.lastHit.m_hitType == 9) ? "Smoke" : (((int)CharacterDamagePatch.lastHit.m_hitType == 3) ? "Fall Damage" : (((int)CharacterDamagePatch.lastHit.m_hitType == 4) ? "Drowning" : (((int)CharacterDamagePatch.lastHit.m_hitType == 13) ? "Falling Tree" : (((int)CharacterDamagePatch.lastHit.m_hitType == 18) ? "Falling Stalactite" : (((int)CharacterDamagePatch.lastHit.m_hitType == 12) ? "Rolling Cart" : ((!(CharacterDamagePatch.lastHit.m_damage.m_blunt > 0.05f) && (int)CharacterDamagePatch.lastHit.m_hitType != 11) ? "Environment" : "Object Collision"))))))) : ((!string.IsNullOrEmpty(CharacterDamagePatch.lastFireAttackerName)) ? CharacterDamagePatch.lastFireAttackerName : "Fire")) : ((!string.IsNullOrEmpty(CharacterDamagePatch.lastPoisonAttackerName)) ? CharacterDamagePatch.lastPoisonAttackerName : "Poison")));
				string text2 = ((!string.IsNullOrEmpty(damageTypeSummary)) ? (" <color=#B0C4DE>[" + damageTypeSummary + "]</color>") : "");
				damageType = CharacterDamagePatch.lastMitigatedDamage.ToString("0.0") + " damage" + text2;
			}
			AutopsyReportPlugin.DeathReportData deathReportData = new AutopsyReportPlugin.DeathReportData();
			deathReportData.killerName = text;
			deathReportData.damageType = damageType;
			deathReportData.overkillAmount = CharacterDamagePatch.lastOverkill;
			deathReportData.fatalBlockedDamage = CharacterDamagePatch.lastBlockedDamage;
			foreach (Skill skill in ((Character)__instance).GetSkills().GetSkillList())
			{
				float num = skill.m_level + skill.GetLevelPercentage();
				if (preDeathSkills.TryGetValue(skill.m_info.m_skill, out var value))
				{
					float num2 = value - num;
					if (num2 > 0.001f)
					{
						string arg = Localization.instance.Localize("$skill_" + ((object)Unsafe.As<SkillType, SkillType>(ref skill.m_info.m_skill)/*cast due to .constrained prefix*/).ToString().ToLower());
						deathReportData.skillLosses.Add($"- {arg}: -{num2:0.00} levels");
					}
				}
			}
			foreach (string activeStatusEffect in activeStatusEffects)
			{
				string item = Localization.instance.Localize(activeStatusEffect);
				deathReportData.activeStatusEffects.Add(item);
				string text3 = activeStatusEffect.ToLower().Replace(" ", "");
				if (text3.Contains("noskilldrain") || text3.Contains("harddeath") || text3.Contains("softdeath"))
				{
					deathReportData.hadNoSkillDrainBuff = true;
				}
			}
			if (CharacterDamagePatch.lastHit != null)
			{
				deathReportData.timeline.Add(new AutopsyReportPlugin.CombatEvent
				{
					timestamp = Time.time,
					eventType = AutopsyReportPlugin.CombatEventType.IncomingDamage,
					amount = CharacterDamagePatch.lastMitigatedDamage,
					damageType = damageTypeSummary,
					entityName = text,
					healthAfter = 0f,
					blockedAmount = CharacterDamagePatch.lastBlockedDamage,
					isFatal = true
				});
			}
			int num3 = 0;
			foreach (AutopsyReportPlugin.CombatEvent recentCombatEvent in AutopsyReportPlugin.recentCombatEvents)
			{
				if (recentCombatEvent.eventType == AutopsyReportPlugin.CombatEventType.IncomingDamage || recentCombatEvent.eventType == AutopsyReportPlugin.CombatEventType.Blocked)
				{
					deathReportData.timeline.Add(recentCombatEvent);
					num3++;
					if (num3 >= 9)
					{
						break;
					}
				}
				else if (recentCombatEvent.eventType == AutopsyReportPlugin.CombatEventType.IncomingHeal)
				{
					deathReportData.timeline.Add(recentCombatEvent);
				}
			}
			AutopsyReportPlugin.currentDeathReport = deathReportData;
			AutopsyReportPlugin.hasNewAutopsyData = true;
			AutopsyReportPlugin.Log.LogInfo((object)"Autopsy data compiled and snapshot frozen successfully.");
			AutopsyReportPlugin.UpdateReportText();
			AutopsyReportPlugin.UpdateDamageHistoryText();
			if (AutopsyReportPlugin.autoSaveEnabled.Value)
			{
				AutopsyReportPlugin.SaveCurrentReport();
			}
		}
	}
	[HarmonyPatch(typeof(Player), "UpdateFood")]
	public static class PlayerUpdateFoodPatch
	{
		public static bool isFoodRegen;

		[HarmonyPrefix]
		public static void Prefix()
		{
			isFoodRegen = true;
		}

		[HarmonyPostfix]
		public static void Postfix()
		{
			isFoodRegen = false;
		}
	}
	[HarmonyPatch(typeof(SE_Stats), "UpdateStatusEffect")]
	public static class SE_StatsUpdateStatusEffectPatch
	{
		public static SE_Stats currentTickingEffect;

		[HarmonyPrefix]
		public static void Prefix(SE_Stats __instance)
		{
			currentTickingEffect = __instance;
		}

		[HarmonyPostfix]
		public static void Postfix()
		{
			currentTickingEffect = null;
		}
	}
	[HarmonyPatch(typeof(Character), "RPC_Heal")]
	public static class CharacterRPC_HealPatch
	{
		[HarmonyPostfix]
		public static void Postfix(Character __instance, float hp)
		{
			if ((Object)(object)__instance != (Object)(object)Player.m_localPlayer || hp <= 0.05f)
			{
				return;
			}
			bool isFoodRegen = PlayerUpdateFoodPatch.isFoodRegen;
			if (isFoodRegen && !AutopsyReportPlugin.logPassiveFoodRegen.Value)
			{
				return;
			}
			SE_Stats currentTickingEffect = SE_StatsUpdateStatusEffectPatch.currentTickingEffect;
			if ((Object)(object)currentTickingEffect != (Object)null)
			{
				string text = (((Object)currentTickingEffect).name ?? "").ToLower() + "_" + (((StatusEffect)currentTickingEffect).m_name ?? "").ToLower();
				if (text.Contains("corpse") || text.Contains("tombstone"))
				{
					return;
				}
			}
			string text2 = (isFoodRegen ? "Food Regen" : "Healing");
			if (!isFoodRegen)
			{
				if ((Object)(object)currentTickingEffect != (Object)null)
				{
					text2 = (((StatusEffect)currentTickingEffect).m_name.StartsWith("$") ? Localization.instance.Localize(((StatusEffect)currentTickingEffect).m_name) : ((StatusEffect)currentTickingEffect).m_name);
				}
				else
				{
					SEMan sEMan = __instance.GetSEMan();
					if (sEMan != null)
					{
						foreach (StatusEffect statusEffect in sEMan.GetStatusEffects())
						{
							string text3 = (((Object)statusEffect).name ?? "").ToLower() + "_" + (statusEffect.m_name ?? "").ToLower();
							if (!text3.Contains("corpse") && !text3.Contains("tombstone"))
							{
								SE_Stats val = (SE_Stats)(object)((statusEffect is SE_Stats) ? statusEffect : null);
								if (val != null && (val.m_healthOverTime > 0f || val.m_healthPerTick > 0f || val.m_healthUpFront > 0f))
								{
									text2 = (statusEffect.m_name.StartsWith("$") ? Localization.instance.Localize(statusEffect.m_name) : statusEffect.m_name);
									break;
								}
							}
						}
					}
				}
			}
			float health = __instance.GetHealth();
			AutopsyReportPlugin.AddCombatEvent(new AutopsyReportPlugin.CombatEvent
			{
				timestamp = Time.time,
				eventType = AutopsyReportPlugin.CombatEventType.IncomingHeal,
				amount = hp,
				entityName = text2,
				healthAfter = health,
				healSource = text2
			});
		}
	}
	[HarmonyPatch(typeof(Character), "ApplyDamage")]
	public static class CharacterApplyDamagePatch
	{
		public static float hpBefore;

		public static float currentMitigatedDamage;

		[HarmonyPrefix]
		public static void Prefix(Character __instance, HitData hit)
		{
			if ((Object)(object)__instance == (Object)(object)Player.m_localPlayer)
			{
				hpBefore = __instance.GetHealth();
				currentMitigatedDamage = ((DamageTypes)(ref hit.m_damage)).GetTotalDamage();
				CharacterDamagePatch.lastMitigatedDamage = currentMitigatedDamage;
				CharacterDamagePatch.lastHit = hit;
				CharacterDamagePatch.lastBlockedDamage = HumanoidBlockAttackPatch.currentBlockedDamage;
				float num = currentMitigatedDamage - hpBefore;
				CharacterDamagePatch.lastOverkill = Mathf.Max(0f, num);
			}
		}

		[HarmonyPostfix]
		public static void Postfix(Character __instance, HitData hit, DamageModifier mod)
		{
			//IL_04ae: Unknown result type (might be due to invalid IL or missing references)
			//IL_04b0: Invalid comparison between Unknown and I4
			//IL_04b2: Unknown result type (might be due to invalid IL or missing references)
			//IL_04b4: Invalid comparison between Unknown and I4
			//IL_00e5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00eb: Invalid comparison between Unknown and I4
			//IL_04bf: Unknown result type (might be due to invalid IL or missing references)
			//IL_04c1: Invalid comparison between Unknown and I4
			//IL_04b6: Unknown result type (might be due to invalid IL or missing references)
			//IL_04b8: Invalid comparison between Unknown and I4
			//IL_0116: Unknown result type (might be due to invalid IL or missing references)
			//IL_011c: Invalid comparison between Unknown and I4
			//IL_0617: Unknown result type (might be due to invalid IL or missing references)
			//IL_0619: Invalid comparison between Unknown and I4
			//IL_04c3: Unknown result type (might be due to invalid IL or missing references)
			//IL_04c5: Invalid comparison between Unknown and I4
			//IL_061b: Unknown result type (might be due to invalid IL or missing references)
			//IL_061d: Invalid comparison between Unknown and I4
			//IL_04c7: Unknown result type (might be due to invalid IL or missing references)
			//IL_04c9: Invalid comparison between Unknown and I4
			//IL_0159: Unknown result type (might be due to invalid IL or missing references)
			//IL_015f: Invalid comparison between Unknown and I4
			//IL_0343: Unknown result type (might be due to invalid IL or missing references)
			//IL_0349: Invalid comparison between Unknown and I4
			//IL_0759: Unknown result type (might be due to invalid IL or missing references)
			//IL_075f: Invalid comparison between Unknown and I4
			//IL_0628: Unknown result type (might be due to invalid IL or missing references)
			//IL_062a: Invalid comparison between Unknown and I4
			//IL_061f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0621: Invalid comparison between Unknown and I4
			//IL_034f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0355: Invalid comparison between Unknown and I4
			//IL_062c: Unknown result type (might be due to invalid IL or missing references)
			//IL_062e: Invalid comparison between Unknown and I4
			//IL_035b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0361: Invalid comparison between Unknown and I4
			//IL_0630: Unknown result type (might be due to invalid IL or missing references)
			//IL_0632: Invalid comparison between Unknown and I4
			//IL_01b2: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b8: Invalid comparison between Unknown and I4
			//IL_0364: Unknown result type (might be due to invalid IL or missing references)
			//IL_036a: Invalid comparison between Unknown and I4
			//IL_036d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0374: Invalid comparison between Unknown and I4
			//IL_07b6: Unknown result type (might be due to invalid IL or missing references)
			//IL_07bc: Invalid comparison between Unknown and I4
			//IL_020b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0211: Invalid comparison between Unknown and I4
			//IL_023f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0246: Invalid comparison between Unknown and I4
			//IL_0271: Unknown result type (might be due to invalid IL or missing references)
			//IL_0278: Invalid comparison between Unknown and I4
			//IL_02a3: Unknown result type (might be due to invalid IL or missing references)
			//IL_02aa: Invalid comparison between Unknown and I4
			//IL_02d2: Unknown result type (might be due to invalid IL or missing references)
			//IL_02d9: Invalid comparison between Unknown and I4
			//IL_0313: Unknown result type (might be due to invalid IL or missing references)
			//IL_031a: Invalid comparison between Unknown and I4
			float health;
			float num;
			float currentBlockedDamage;
			string text;
			string text2;
			int num2;
			if ((Object)(object)__instance == (Object)(object)Player.m_localPlayer)
			{
				health = __instance.GetHealth();
				num = Mathf.Max(0f, hpBefore - health);
				currentBlockedDamage = HumanoidBlockAttackPatch.currentBlockedDamage;
				HumanoidBlockAttackPatch.currentBlockedDamage = 0f;
				if (health > 0f && (num > 0.05f || currentBlockedDamage > 0f))
				{
					text = AutopsyReportPlugin.GetDamageTypeSummary(hit);
					text2 = "Environment";
					if ((Object)(object)hit.GetAttacker() != (Object)null)
					{
						text2 = (CharacterDamagePatch.lastAttackerName = AutopsyReportPlugin.FormatAttackerName(hit.GetAttacker(), hit));
						if (hit.m_damage.m_poison > 0f)
						{
							CharacterDamagePatch.lastPoisonAttackerName = text2;
						}
						if (hit.m_damage.m_fire > 0f)
						{
							CharacterDamagePatch.lastFireAttackerName = text2;
						}
					}
					else if ((int)hit.m_hitType == 3)
					{
						text2 = "Fall Damage";
						if (string.IsNullOrEmpty(text))
						{
							text = "Fall";
						}
					}
					else if ((int)hit.m_hitType == 4)
					{
						text2 = "Drowning";
						if (string.IsNullOrEmpty(text))
						{
							text = "Water";
						}
					}
					else if (hit.m_damage.m_poison > 0f || (int)hit.m_hitType == 7)
					{
						text2 = ((!string.IsNullOrEmpty(CharacterDamagePatch.lastPoisonAttackerName)) ? CharacterDamagePatch.lastPoisonAttackerName : "Poison");
						if (string.IsNullOrEmpty(text))
						{
							text = "Poison";
						}
					}
					else if (hit.m_damage.m_fire > 0f || (int)hit.m_hitType == 5)
					{
						text2 = ((!string.IsNullOrEmpty(CharacterDamagePatch.lastFireAttackerName)) ? CharacterDamagePatch.lastFireAttackerName : "Fire");
						if (string.IsNullOrEmpty(text))
						{
							text = "Fire";
						}
					}
					else if (hit.m_damage.m_frost > 0f || (int)hit.m_hitType == 6)
					{
						text2 = "Freezing";
						if (string.IsNullOrEmpty(text))
						{
							text = "Frost";
						}
					}
					else if ((int)hit.m_hitType == 9)
					{
						text2 = "Smoke";
						if (string.IsNullOrEmpty(text))
						{
							text = "Smoke";
						}
					}
					else if ((int)hit.m_hitType == 13)
					{
						text2 = "Falling Tree";
						if (string.IsNullOrEmpty(text))
						{
							text = "Blunt";
						}
					}
					else if ((int)hit.m_hitType == 18)
					{
						text2 = "Falling Stalactite";
						if (string.IsNullOrEmpty(text))
						{
							text = "Pierce";
						}
					}
					else if ((int)hit.m_hitType == 12)
					{
						text2 = "Rolling Cart";
						if (string.IsNullOrEmpty(text))
						{
							text = "Blunt";
						}
					}
					else if (hit.m_damage.m_blunt > 0.05f || (int)hit.m_hitType == 11)
					{
						text2 = "Object Collision";
						if (string.IsNullOrEmpty(text))
						{
							text = "Blunt";
						}
					}
					if ((int)hit.m_hitType == 5 || (int)hit.m_hitType == 7 || (int)hit.m_hitType == 6 || (int)hit.m_hitType == 4 || (int)hit.m_hitType == 9)
					{
						goto IL_03db;
					}
					switch (text2)
					{
					case "Fire":
						if (!((Object)(object)hit.GetAttacker() == (Object)null))
						{
							break;
						}
						goto IL_03db;
					case "Drowning":
					case "Smoke":
					case "Freezing":
						goto IL_03db;
					}
					num2 = ((text2 == "