Decompiled source of DamageSparks v1.0.0

DamageSparks.dll

Decompiled 4 hours ago
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Globalization;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Runtime.Versioning;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using HarmonyLib;
using PerfectRandom.Sulfur.Core.Stats;
using PerfectRandom.Sulfur.Core.Units;
using TMPro;
using UnityEngine;
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: AssemblyTitle("SulfurDamageNumbersMod")]
[assembly: AssemblyDescription("SULFUR damage numbers mod for BepInEx 5")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("ryuka_labs")]
[assembly: AssemblyProduct("SulfurDamageNumbersMod")]
[assembly: AssemblyCopyright("")]
[assembly: AssemblyTrademark("")]
[assembly: ComVisible(false)]
[assembly: Guid("c9ebec31-296a-4d97-9959-9804ea595a74")]
[assembly: AssemblyFileVersion("1.0.6.0")]
[assembly: TargetFramework(".NETFramework,Version=v4.7.2", FrameworkDisplayName = ".NET Framework 4.7.2")]
[assembly: AssemblyVersion("1.0.6.0")]
namespace SulfurDamageNumbersMod;

internal static class DamageLogPatch
{
	private static bool _applied;

	public static void Apply(Harmony harmony)
	{
		//IL_0046: Unknown result type (might be due to invalid IL or missing references)
		//IL_0053: Expected O, but got Unknown
		if (!_applied)
		{
			MethodBase methodBase = TargetMethod();
			if (methodBase == null)
			{
				Plugin.Log.LogError((object)"SULFUR Damage Numbers failed: Unit.CreateDamageLog(float, float, DamageTypes, Data, DamageSourceData) was not found.");
				return;
			}
			harmony.Patch(methodBase, (HarmonyMethod)null, new HarmonyMethod(typeof(DamageLogPatch), "Postfix", (Type[])null), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
			_applied = true;
			Plugin.Log.LogInfo((object)("SULFUR Damage Numbers patched " + methodBase.DeclaringType.FullName + "." + methodBase.Name + "."));
		}
	}

	private static MethodBase TargetMethod()
	{
		return AccessTools.GetDeclaredMethods(typeof(Unit)).FirstOrDefault(delegate(MethodInfo m)
		{
			if (m.Name != "CreateDamageLog")
			{
				return false;
			}
			ParameterInfo[] parameters = m.GetParameters();
			return parameters.Length == 5 && parameters[0].ParameterType == typeof(float) && parameters[1].ParameterType == typeof(float) && parameters[2].ParameterType == typeof(DamageTypes) && parameters[4].ParameterType == typeof(DamageSourceData);
		});
	}

	private static void Postfix(Unit __instance, float __0, float __1, DamageTypes __2, object __3, DamageSourceData __4)
	{
		//IL_00bf: Unknown result type (might be due to invalid IL or missing references)
		//IL_01a2: Unknown result type (might be due to invalid IL or missing references)
		//IL_018e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0114: Unknown result type (might be due to invalid IL or missing references)
		if ((Object)(object)__instance == (Object)null || !Plugin.Enabled.Value)
		{
			return;
		}
		try
		{
			float num = __0;
			if (num < Plugin.MinDamageToShow.Value)
			{
				if (Plugin.DebugLog.Value)
				{
					Plugin.Log.LogInfo((object)("[DamageNumbers] reject low damage amount=" + num + " target=" + SafeName((Object)(object)__instance)));
				}
				return;
			}
			if (!IsAllowedTarget(__instance, out var reason))
			{
				if (Plugin.DebugLog.Value)
				{
					Plugin.Log.LogInfo((object)("[DamageNumbers] reject target: " + reason + " target=" + SafeName((Object)(object)__instance)));
				}
				return;
			}
			if (!IsPlayerExecutedAttack(__4, out reason))
			{
				if (Plugin.DebugLog.Value)
				{
					Plugin.Log.LogInfo((object)("[DamageNumbers] reject source: " + reason + " target=" + SafeName((Object)(object)__instance) + " source=" + DescribeSource(__4)));
				}
				return;
			}
			float hitMultiplier = DamageNumberColor.ResolveHitMultiplier(__3);
			if (Plugin.DebugLog.Value)
			{
				Plugin.Log.LogInfo((object)("[DamageNumbers] accept amount=" + num + " multiplier=" + hitMultiplier + " target=" + SafeName((Object)(object)__instance) + " source=" + DescribeSource(__4)));
			}
			DamageNumberManager.RegisterDamage(__instance, __4, num, hitMultiplier);
		}
		catch (Exception ex)
		{
			Plugin.Log.LogWarning((object)("[DamageNumbers] CreateDamageLog postfix failed: " + ex));
		}
	}

	private static bool IsAllowedTarget(Unit target, out string reason)
	{
		if (target.isPlayer)
		{
			reason = "target is player";
			return false;
		}
		if (Plugin.RequireNpcTarget.Value && !(target is Npc))
		{
			reason = "target is not Npc";
			return false;
		}
		reason = null;
		return true;
	}

	private static bool IsPlayerExecutedAttack(DamageSourceData sourceData, out string reason)
	{
		//IL_0001: Unknown result type (might be due to invalid IL or missing references)
		//IL_006c: Unknown result type (might be due to invalid IL or missing references)
		//IL_002c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0086: 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_00a6: Unknown result type (might be due to invalid IL or missing references)
		//IL_00a7: Unknown result type (might be due to invalid IL or missing references)
		if (!sourceData.isPlayer)
		{
			reason = "sourceData.isPlayer is false";
			return false;
		}
		if (Plugin.RequireSourceUnitPlayer.Value)
		{
			if ((Object)(object)sourceData.sourceUnit == (Object)null)
			{
				reason = "sourceUnit is null";
				return false;
			}
			if (!sourceData.sourceUnit.isPlayer)
			{
				reason = "sourceUnit is not player";
				return false;
			}
		}
		if ((Object)(object)sourceData.sourceWeapon != (Object)null)
		{
			reason = null;
			return true;
		}
		if (sourceData.melee)
		{
			reason = null;
			return true;
		}
		if (Plugin.ShowPlayerOwnedSecondaryEffects.Value && !sourceData.states.notCreatedByPlayer)
		{
			reason = null;
			return true;
		}
		reason = "no weapon/melee/player-owned secondary marker";
		return false;
	}

	private static string DescribeSource(DamageSourceData sourceData)
	{
		//IL_0001: Unknown result type (might be due to invalid IL or missing references)
		//IL_000f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0022: Unknown result type (might be due to invalid IL or missing references)
		//IL_0030: 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)
		string text = (((Object)(object)sourceData.sourceUnit == (Object)null) ? "null" : SafeName((Object)(object)sourceData.sourceUnit));
		string text2 = (((Object)(object)sourceData.sourceWeapon == (Object)null) ? "null" : ((Object)sourceData.sourceWeapon).name);
		return "isPlayer=" + sourceData.isPlayer + ", melee=" + sourceData.melee + ", weapon=" + text2 + ", unit=" + text + ", instanceId=" + sourceData.instanceId + ", name=" + sourceData.name;
	}

	private static string SafeName(Object obj)
	{
		return (obj == (Object)null) ? "null" : obj.name;
	}
}
internal sealed class DamageNumberManager : MonoBehaviour
{
	private struct AggregateEntry
	{
		public float Amount;

		public Vector3 Position;

		public int Frame;

		public float HighestMultiplier;

		public float LastMultiplier;

		public float WeightedMultiplierSum;
	}

	private struct PerHitSpreadOffset
	{
		public static readonly PerHitSpreadOffset Zero = new PerHitSpreadOffset
		{
			WorldOffset = Vector3.zero,
			ScreenOffset = Vector2.zero
		};

		public Vector3 WorldOffset;

		public Vector2 ScreenOffset;
	}

	private sealed class ScreenEntry
	{
		public string Text;

		public Vector3 WorldPosition;

		public Vector2 ScreenPosition;

		public Vector2 ScreenJitter;

		public float StartTime;

		public float Lifetime;

		public bool FixedScreen;

		public Color Color;
	}

	private static DamageNumberManager _instance;

	private readonly Dictionary<AggregateKey, AggregateEntry> _aggregates = new Dictionary<AggregateKey, AggregateEntry>();

	private readonly List<AggregateKey> _flushBuffer = new List<AggregateKey>();

	private readonly List<ScreenEntry> _screenEntries = new List<ScreenEntry>();

	private readonly Dictionary<PerHitSpreadKey, int> _perHitSpreadCounters = new Dictionary<PerHitSpreadKey, int>();

	private int _perHitSpreadFrame = -1;

	private GUIStyle _screenStyle;

	private GUIStyle _outlineStyle;

	public static void EnsureExists()
	{
		//IL_0017: Unknown result type (might be due to invalid IL or missing references)
		//IL_001d: Expected O, but got Unknown
		if (!((Object)(object)_instance != (Object)null))
		{
			GameObject val = new GameObject("SULFUR Damage Number Manager");
			Object.DontDestroyOnLoad((Object)(object)val);
			_instance = val.AddComponent<DamageNumberManager>();
		}
	}

	public static void RegisterDamage(Unit target, DamageSourceData sourceData, float amount, float hitMultiplier)
	{
		//IL_000d: Unknown result type (might be due to invalid IL or missing references)
		EnsureExists();
		_instance.RegisterDamageInternal(target, sourceData, amount, hitMultiplier);
	}

	public static void SpawnScreenTestNumber()
	{
		//IL_0029: Unknown result type (might be due to invalid IL or missing references)
		//IL_0033: Unknown result type (might be due to invalid IL or missing references)
		EnsureExists();
		_instance.SpawnScreenFixed("999", new Vector2((float)Screen.width * 0.5f, (float)Screen.height * 0.45f), DamageNumberColor.ForMultiplier(0f));
	}

	private void Update()
	{
		if (Plugin.DebugSpawnTestOnF8.Value && InputCompat.GetKeyDown((KeyCode)289))
		{
			SpawnScreenTestNumber();
			if (Plugin.DebugLog.Value)
			{
				Plugin.Log.LogInfo((object)"[DamageNumbers] F8 test number spawned.");
			}
		}
	}

	private void RegisterDamageInternal(Unit target, DamageSourceData sourceData, float amount, float hitMultiplier)
	{
		//IL_0002: Unknown result type (might be due to invalid IL or missing references)
		//IL_0007: Unknown result type (might be due to invalid IL or missing references)
		//IL_0043: Unknown result type (might be due to invalid IL or missing references)
		//IL_001c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0024: Unknown result type (might be due to invalid IL or missing references)
		//IL_002b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0032: Unknown result type (might be due to invalid IL or missing references)
		//IL_00c0: Unknown result type (might be due to invalid IL or missing references)
		//IL_00c1: 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)
		//IL_0079: Unknown result type (might be due to invalid IL or missing references)
		Vector3 damagePosition = GetDamagePosition(target);
		if (Plugin.Mode.Value == DisplayMode.PerHit)
		{
			PerHitSpreadOffset nextPerHitSpread = GetNextPerHitSpread(target, sourceData);
			SpawnNumber(damagePosition, amount, hitMultiplier, useJitter: true, nextPerHitSpread.WorldOffset, nextPerHitSpread.ScreenOffset);
			return;
		}
		AggregateKey key = AggregateKey.Create(target, sourceData);
		if (!_aggregates.TryGetValue(key, out var value))
		{
			AggregateEntry aggregateEntry = default(AggregateEntry);
			aggregateEntry.Amount = 0f;
			aggregateEntry.Position = damagePosition;
			aggregateEntry.Frame = Time.frameCount;
			aggregateEntry.HighestMultiplier = 0f;
			aggregateEntry.LastMultiplier = 0f;
			aggregateEntry.WeightedMultiplierSum = 0f;
			value = aggregateEntry;
		}
		value.Amount += amount;
		value.Position = damagePosition;
		value.Frame = Time.frameCount;
		value.LastMultiplier = hitMultiplier;
		value.WeightedMultiplierSum += Mathf.Max(0f, hitMultiplier) * Mathf.Max(0f, amount);
		if (hitMultiplier > value.HighestMultiplier)
		{
			value.HighestMultiplier = hitMultiplier;
		}
		_aggregates[key] = value;
	}

	private void LateUpdate()
	{
		//IL_00b5: Unknown result type (might be due to invalid IL or missing references)
		//IL_00c9: Unknown result type (might be due to invalid IL or missing references)
		//IL_00ce: Unknown result type (might be due to invalid IL or missing references)
		if (_aggregates.Count == 0)
		{
			return;
		}
		_flushBuffer.Clear();
		foreach (KeyValuePair<AggregateKey, AggregateEntry> aggregate in _aggregates)
		{
			if (aggregate.Value.Frame <= Time.frameCount)
			{
				_flushBuffer.Add(aggregate.Key);
			}
		}
		for (int i = 0; i < _flushBuffer.Count; i++)
		{
			AggregateKey key = _flushBuffer[i];
			if (_aggregates.TryGetValue(key, out var value))
			{
				SpawnNumber(value.Position, value.Amount, ResolveAggregateMultiplier(value), useJitter: false, Vector3.zero, Vector2.zero);
				_aggregates.Remove(key);
			}
		}
	}

	private void OnGUI()
	{
		//IL_008f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0094: Unknown result type (might be due to invalid IL or missing references)
		//IL_00ae: Unknown result type (might be due to invalid IL or missing references)
		//IL_00b3: Unknown result type (might be due to invalid IL or missing references)
		//IL_00c0: Unknown result type (might be due to invalid IL or missing references)
		//IL_00c5: Unknown result type (might be due to invalid IL or missing references)
		//IL_00ca: Unknown result type (might be due to invalid IL or missing references)
		//IL_00cd: Unknown result type (might be due to invalid IL or missing references)
		//IL_00cf: Unknown result type (might be due to invalid IL or missing references)
		//IL_00d4: Unknown result type (might be due to invalid IL or missing references)
		//IL_00d6: Unknown result type (might be due to invalid IL or missing references)
		//IL_010f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0113: Unknown result type (might be due to invalid IL or missing references)
		//IL_0118: Unknown result type (might be due to invalid IL or missing references)
		//IL_011d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0150: Unknown result type (might be due to invalid IL or missing references)
		//IL_0155: Unknown result type (might be due to invalid IL or missing references)
		//IL_017a: Unknown result type (might be due to invalid IL or missing references)
		//IL_0187: Unknown result type (might be due to invalid IL or missing references)
		//IL_01ae: Unknown result type (might be due to invalid IL or missing references)
		//IL_01c1: Unknown result type (might be due to invalid IL or missing references)
		//IL_01ca: Unknown result type (might be due to invalid IL or missing references)
		//IL_00f4: Unknown result type (might be due to invalid IL or missing references)
		//IL_0101: Unknown result type (might be due to invalid IL or missing references)
		if (_screenEntries.Count == 0)
		{
			return;
		}
		EnsureGuiStyles();
		Camera main = Camera.main;
		float time = Time.time;
		Vector2 val = default(Vector2);
		Color textColor = default(Color);
		Rect r = default(Rect);
		for (int num = _screenEntries.Count - 1; num >= 0; num--)
		{
			ScreenEntry screenEntry = _screenEntries[num];
			float num2 = time - screenEntry.StartTime;
			if (num2 >= screenEntry.Lifetime)
			{
				_screenEntries.RemoveAt(num);
				continue;
			}
			if (screenEntry.FixedScreen)
			{
				val = screenEntry.ScreenPosition;
			}
			else
			{
				if ((Object)(object)main == (Object)null)
				{
					continue;
				}
				Vector3 val2 = screenEntry.WorldPosition + Vector3.up * (num2 * 0.25f);
				Vector3 val3 = main.WorldToScreenPoint(val2);
				if (val3.z <= 0f)
				{
					continue;
				}
				((Vector2)(ref val))..ctor(val3.x, (float)Screen.height - val3.y);
			}
			val += screenEntry.ScreenJitter;
			val.y -= num2 * Plugin.ScreenFloatSpeed.Value;
			float num3 = Mathf.Clamp01(1f - num2 / screenEntry.Lifetime);
			Color color = screenEntry.Color;
			color.a = num3;
			((Color)(ref textColor))..ctor(0f, 0f, 0f, num3);
			((Rect)(ref r))..ctor(val.x - 100f, val.y - 32f, 200f, 64f);
			_outlineStyle.normal.textColor = textColor;
			_screenStyle.normal.textColor = color;
			DrawOutlinedLabel(r, screenEntry.Text);
		}
	}

	private void DrawOutlinedLabel(Rect r, string text)
	{
		//IL_0001: Unknown result type (might be due to invalid IL or missing references)
		//IL_0002: Unknown result type (might be due to invalid IL or missing references)
		//IL_0017: Unknown result type (might be due to invalid IL or missing references)
		//IL_0025: Unknown result type (might be due to invalid IL or missing references)
		//IL_0026: Unknown result type (might be due to invalid IL or missing references)
		//IL_003b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0049: Unknown result type (might be due to invalid IL or missing references)
		//IL_004a: Unknown result type (might be due to invalid IL or missing references)
		//IL_005f: Unknown result type (might be due to invalid IL or missing references)
		//IL_006d: Unknown result type (might be due to invalid IL or missing references)
		//IL_006e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0083: Unknown result type (might be due to invalid IL or missing references)
		//IL_0091: Unknown result type (might be due to invalid IL or missing references)
		Rect val = r;
		((Rect)(ref val)).x = ((Rect)(ref val)).x - 2f;
		GUI.Label(val, text, _outlineStyle);
		val = r;
		((Rect)(ref val)).x = ((Rect)(ref val)).x + 2f;
		GUI.Label(val, text, _outlineStyle);
		val = r;
		((Rect)(ref val)).y = ((Rect)(ref val)).y - 2f;
		GUI.Label(val, text, _outlineStyle);
		val = r;
		((Rect)(ref val)).y = ((Rect)(ref val)).y + 2f;
		GUI.Label(val, text, _outlineStyle);
		GUI.Label(r, text, _screenStyle);
	}

	private void EnsureGuiStyles()
	{
		//IL_003c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0046: Expected O, but got Unknown
		//IL_0081: Unknown result type (might be due to invalid IL or missing references)
		//IL_008b: Expected O, but got Unknown
		int num = Mathf.Max(8, Plugin.ScreenFontSize.Value);
		if (_screenStyle == null || _screenStyle.fontSize != num)
		{
			_screenStyle = new GUIStyle(GUI.skin.label);
			_screenStyle.alignment = (TextAnchor)4;
			_screenStyle.fontStyle = (FontStyle)1;
			_screenStyle.fontSize = num;
			_screenStyle.clipping = (TextClipping)0;
			_outlineStyle = new GUIStyle(_screenStyle);
		}
	}

	private static Vector3 GetDamagePosition(Unit target)
	{
		//IL_0038: Unknown result type (might be due to invalid IL or missing references)
		//IL_003d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0047: Unknown result type (might be due to invalid IL or missing references)
		//IL_004c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0051: Unknown result type (might be due to invalid IL or missing references)
		//IL_002a: Unknown result type (might be due to invalid IL or missing references)
		//IL_002f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0054: Unknown result type (might be due to invalid IL or missing references)
		Npc val = (Npc)(object)((target is Npc) ? target : null);
		if ((Object)(object)val != (Object)null && (Object)(object)val.overhead != (Object)null)
		{
			return val.overhead.position;
		}
		return ((Component)target).transform.position + Vector3.up * 2f;
	}

	private PerHitSpreadOffset GetNextPerHitSpread(Unit target, DamageSourceData sourceData)
	{
		//IL_0031: Unknown result type (might be due to invalid IL or missing references)
		//IL_00ef: Unknown result type (might be due to invalid IL or missing references)
		//IL_00f3: Unknown result type (might be due to invalid IL or missing references)
		//IL_00f8: Unknown result type (might be due to invalid IL or missing references)
		//IL_00ff: Unknown result type (might be due to invalid IL or missing references)
		//IL_010e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0118: Unknown result type (might be due to invalid IL or missing references)
		//IL_011d: Unknown result type (might be due to invalid IL or missing references)
		if (_perHitSpreadFrame != Time.frameCount)
		{
			_perHitSpreadFrame = Time.frameCount;
			_perHitSpreadCounters.Clear();
		}
		PerHitSpreadKey key = PerHitSpreadKey.Create(target, sourceData);
		if (!_perHitSpreadCounters.TryGetValue(key, out var value))
		{
			value = 0;
		}
		_perHitSpreadCounters[key] = value + 1;
		if (value <= 0)
		{
			return PerHitSpreadOffset.Zero;
		}
		float num = (float)value * 2.3999631f;
		float num2 = Mathf.Sqrt((float)value);
		Vector2 val = default(Vector2);
		((Vector2)(ref val))..ctor(Mathf.Cos(num), Mathf.Sin(num));
		float num3 = Mathf.Min(42f, Mathf.Max(0f, Plugin.PerHitStackScreenSpread.Value) * num2);
		float num4 = Mathf.Min(0.36f, Mathf.Max(0f, Plugin.PerHitStackWorldSpread.Value) * num2);
		PerHitSpreadOffset result = default(PerHitSpreadOffset);
		result.ScreenOffset = val * num3;
		result.WorldOffset = new Vector3(val.x * num4, 0f, val.y * num4);
		return result;
	}

	private static void SpawnNumber(Vector3 position, float amount, float hitMultiplier, bool useJitter, Vector3 extraWorldJitter, Vector2 extraScreenJitter)
	{
		//IL_0009: Unknown result type (might be due to invalid IL or missing references)
		//IL_000e: Unknown result type (might be due to invalid IL or missing references)
		//IL_000f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0011: Unknown result type (might be due to invalid IL or missing references)
		//IL_0012: Unknown result type (might be due to invalid IL or missing references)
		//IL_0014: Unknown result type (might be due to invalid IL or missing references)
		//IL_0038: Unknown result type (might be due to invalid IL or missing references)
		//IL_0047: 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_004e: 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)
		//IL_005b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0062: Unknown result type (might be due to invalid IL or missing references)
		//IL_0067: Unknown result type (might be due to invalid IL or missing references)
		//IL_006c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0085: Unknown result type (might be due to invalid IL or missing references)
		//IL_0086: Unknown result type (might be due to invalid IL or missing references)
		//IL_0095: Unknown result type (might be due to invalid IL or missing references)
		//IL_009a: Unknown result type (might be due to invalid IL or missing references)
		//IL_009f: Unknown result type (might be due to invalid IL or missing references)
		//IL_00ca: Unknown result type (might be due to invalid IL or missing references)
		//IL_00cb: Unknown result type (might be due to invalid IL or missing references)
		//IL_00cc: Unknown result type (might be due to invalid IL or missing references)
		//IL_00fc: Unknown result type (might be due to invalid IL or missing references)
		//IL_0103: Expected O, but got Unknown
		//IL_010f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0110: Unknown result type (might be due to invalid IL or missing references)
		//IL_0139: Unknown result type (might be due to invalid IL or missing references)
		string text = FormatDamage(amount);
		Color color = DamageNumberColor.ForMultiplier(hitMultiplier);
		Vector3 val = extraWorldJitter;
		Vector2 val2 = extraScreenJitter;
		if (useJitter)
		{
			if (Plugin.RandomJitter.Value > 0f)
			{
				Vector2 val3 = Random.insideUnitCircle * Plugin.RandomJitter.Value;
				val += new Vector3(val3.x, 0f, val3.y);
			}
			if (Plugin.ScreenJitter.Value > 0f)
			{
				val2 += Random.insideUnitCircle * Plugin.ScreenJitter.Value;
			}
		}
		if (Plugin.Renderer.Value == RenderMode.ScreenSpace || Plugin.Renderer.Value == RenderMode.Both)
		{
			_instance.SpawnScreenWorld(text, position, val2, color);
		}
		if (Plugin.Renderer.Value == RenderMode.WorldTextMeshPro || Plugin.Renderer.Value == RenderMode.Both)
		{
			GameObject val4 = new GameObject("SULFUR Damage Number");
			DamageNumberView damageNumberView = val4.AddComponent<DamageNumberView>();
			damageNumberView.Init(text, position, val, Plugin.Lifetime.Value, Plugin.FloatSpeed.Value, Plugin.WorldScale.Value, Plugin.FontSize.Value, color);
		}
	}

	private void SpawnScreenWorld(string text, Vector3 worldPosition, Vector2 jitter, Color color)
	{
		//IL_001b: Unknown result type (might be due to invalid IL or missing references)
		//IL_001c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0022: Unknown result type (might be due to invalid IL or missing references)
		//IL_0023: Unknown result type (might be due to invalid IL or missing references)
		//IL_0055: Unknown result type (might be due to invalid IL or missing references)
		//IL_0057: Unknown result type (might be due to invalid IL or missing references)
		TrimOldScreenEntriesIfNeeded();
		_screenEntries.Add(new ScreenEntry
		{
			Text = text,
			WorldPosition = worldPosition,
			ScreenJitter = jitter,
			StartTime = Time.time,
			Lifetime = Mathf.Max(0.05f, Plugin.Lifetime.Value),
			FixedScreen = false,
			Color = color
		});
	}

	private void SpawnScreenFixed(string text, Vector2 screenPosition, Color color)
	{
		//IL_001b: Unknown result type (might be due to invalid IL or missing references)
		//IL_001c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0022: Unknown result type (might be due to invalid IL or missing references)
		//IL_0027: Unknown result type (might be due to invalid IL or missing references)
		//IL_0059: Unknown result type (might be due to invalid IL or missing references)
		//IL_005a: Unknown result type (might be due to invalid IL or missing references)
		TrimOldScreenEntriesIfNeeded();
		_screenEntries.Add(new ScreenEntry
		{
			Text = text,
			ScreenPosition = screenPosition,
			ScreenJitter = Vector2.zero,
			StartTime = Time.time,
			Lifetime = Mathf.Max(0.05f, Plugin.Lifetime.Value),
			FixedScreen = true,
			Color = color
		});
	}

	private void TrimOldScreenEntriesIfNeeded()
	{
		int num = Mathf.Max(1, Plugin.MaxActiveNumbers.Value);
		while (_screenEntries.Count >= num)
		{
			_screenEntries.RemoveAt(0);
		}
	}

	private static string FormatDamage(float amount)
	{
		if (Plugin.ShowDecimals.Value)
		{
			float num = Mathf.Round(amount * 10f) / 10f;
			float num2 = Mathf.Round(num);
			if (Mathf.Abs(num - num2) <= 0.0001f)
			{
				int num3 = Mathf.RoundToInt(num2);
				if (num3 <= 0 && amount > 0f)
				{
					num3 = 1;
				}
				return num3.ToString(CultureInfo.InvariantCulture);
			}
			return num.ToString("0.0", CultureInfo.InvariantCulture);
		}
		int num4 = Mathf.RoundToInt(amount);
		if (num4 <= 0)
		{
			num4 = 1;
		}
		return num4.ToString(CultureInfo.InvariantCulture);
	}

	private static float ResolveAggregateMultiplier(AggregateEntry entry)
	{
		switch (Plugin.AggregateColorMode.Value)
		{
		case MergedColorMode.LastHit:
			return entry.LastMultiplier;
		case MergedColorMode.DamageWeightedAverage:
			if (entry.Amount > 0.0001f)
			{
				return entry.WeightedMultiplierSum / entry.Amount;
			}
			return entry.HighestMultiplier;
		default:
			return entry.HighestMultiplier;
		}
	}
}
internal struct PerHitSpreadKey : IEquatable<PerHitSpreadKey>
{
	private int _targetId;

	private int _frame;

	private int _sourceId;

	public static PerHitSpreadKey Create(Unit target, DamageSourceData sourceData)
	{
		//IL_0003: Unknown result type (might be due to invalid IL or missing references)
		//IL_0021: Unknown result type (might be due to invalid IL or missing references)
		//IL_0013: Unknown result type (might be due to invalid IL or missing references)
		//IL_0037: Unknown result type (might be due to invalid IL or missing references)
		//IL_002e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0047: Unknown result type (might be due to invalid IL or missing references)
		int sourceId = 0;
		if ((Object)(object)sourceData.sourceWeapon != (Object)null)
		{
			sourceId = ((Object)sourceData.sourceWeapon).GetInstanceID();
		}
		else if (sourceData.instanceId != 0)
		{
			sourceId = sourceData.instanceId;
		}
		else if ((Object)(object)sourceData.sourceUnit != (Object)null)
		{
			sourceId = ((Object)sourceData.sourceUnit).GetInstanceID();
		}
		PerHitSpreadKey result = default(PerHitSpreadKey);
		result._targetId = ((Object)target).GetInstanceID();
		result._frame = Time.frameCount;
		result._sourceId = sourceId;
		return result;
	}

	public bool Equals(PerHitSpreadKey other)
	{
		return _targetId == other._targetId && _frame == other._frame && _sourceId == other._sourceId;
	}

	public override bool Equals(object obj)
	{
		return obj is PerHitSpreadKey && Equals((PerHitSpreadKey)obj);
	}

	public override int GetHashCode()
	{
		int targetId = _targetId;
		targetId = (targetId * 397) ^ _frame;
		return (targetId * 397) ^ _sourceId;
	}
}
internal struct AggregateKey : IEquatable<AggregateKey>
{
	private int _targetId;

	private int _frame;

	private int _sourceId;

	private int _damageType;

	private bool _melee;

	public static AggregateKey Create(Unit target, DamageSourceData sourceData)
	{
		//IL_0003: Unknown result type (might be due to invalid IL or missing references)
		//IL_0021: Unknown result type (might be due to invalid IL or missing references)
		//IL_0013: Unknown result type (might be due to invalid IL or missing references)
		//IL_0037: Unknown result type (might be due to invalid IL or missing references)
		//IL_002e: Unknown result type (might be due to invalid IL or missing references)
		//IL_007e: Unknown result type (might be due to invalid IL or missing references)
		//IL_007f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0095: Unknown result type (might be due to invalid IL or missing references)
		//IL_0047: Unknown result type (might be due to invalid IL or missing references)
		int sourceId = 0;
		if ((Object)(object)sourceData.sourceWeapon != (Object)null)
		{
			sourceId = ((Object)sourceData.sourceWeapon).GetInstanceID();
		}
		else if (sourceData.instanceId != 0)
		{
			sourceId = sourceData.instanceId;
		}
		else if ((Object)(object)sourceData.sourceUnit != (Object)null)
		{
			sourceId = ((Object)sourceData.sourceUnit).GetInstanceID();
		}
		AggregateKey result = default(AggregateKey);
		result._targetId = ((Object)target).GetInstanceID();
		result._frame = Time.frameCount;
		result._sourceId = sourceId;
		result._damageType = Convert.ToInt32(sourceData.damageType);
		result._melee = sourceData.melee;
		return result;
	}

	public bool Equals(AggregateKey other)
	{
		return _targetId == other._targetId && _frame == other._frame && _sourceId == other._sourceId && _damageType == other._damageType && _melee == other._melee;
	}

	public override bool Equals(object obj)
	{
		return obj is AggregateKey && Equals((AggregateKey)obj);
	}

	public override int GetHashCode()
	{
		int targetId = _targetId;
		targetId = (targetId * 397) ^ _frame;
		targetId = (targetId * 397) ^ _sourceId;
		targetId = (targetId * 397) ^ _damageType;
		return (targetId * 397) ^ (_melee ? 1 : 0);
	}
}
internal static class DamageNumberColor
{
	private static readonly Color NormalDamageColor = Color.white;

	private static readonly Color OrangeDamageColor = new Color(1f, 0.5f, 0f, 1f);

	private static MethodInfo _getShapeMultiplierMethod;

	private static Type _cachedHitDataType;

	public static float ResolveHitMultiplier(object hitData)
	{
		if (hitData == null)
		{
			return 0f;
		}
		try
		{
			Type type = hitData.GetType();
			MethodInfo shapeMultiplierMethod = GetShapeMultiplierMethod(type);
			if (shapeMultiplierMethod == null)
			{
				return 0f;
			}
			object obj = shapeMultiplierMethod.Invoke(hitData, null);
			if (obj is float)
			{
				return Mathf.Max(0f, (float)obj);
			}
			if (obj is double)
			{
				return Mathf.Max(0f, (float)(double)obj);
			}
		}
		catch
		{
			return 0f;
		}
		return 0f;
	}

	public static Color ForMultiplier(float multiplier)
	{
		//IL_0013: Unknown result type (might be due to invalid IL or missing references)
		//IL_0018: Unknown result type (might be due to invalid IL or missing references)
		//IL_002e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0033: Unknown result type (might be due to invalid IL or missing references)
		//IL_00c1: Unknown result type (might be due to invalid IL or missing references)
		//IL_0063: 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_007d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0082: 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_009c: Unknown result type (might be due to invalid IL or missing references)
		//IL_00b9: Unknown result type (might be due to invalid IL or missing references)
		//IL_00be: Unknown result type (might be due to invalid IL or missing references)
		//IL_00b1: Unknown result type (might be due to invalid IL or missing references)
		//IL_00b6: Unknown result type (might be due to invalid IL or missing references)
		if (!Plugin.UseWeakspotColors.Value)
		{
			return NormalDamageColor;
		}
		if (multiplier <= 0f)
		{
			return NormalDamageColor;
		}
		if (Plugin.TreatOneMultiplierAsNormal.Value && Mathf.Abs(multiplier - 1f) <= 0.0001f)
		{
			return NormalDamageColor;
		}
		if (multiplier >= 1.5f)
		{
			return Color.red;
		}
		if (multiplier >= 1f)
		{
			return OrangeDamageColor;
		}
		if (multiplier >= 0.75f)
		{
			return Color.yellow;
		}
		return NormalDamageColor;
	}

	private static MethodInfo GetShapeMultiplierMethod(Type type)
	{
		if (type == null)
		{
			return null;
		}
		if (_cachedHitDataType == type)
		{
			return _getShapeMultiplierMethod;
		}
		_cachedHitDataType = type;
		_getShapeMultiplierMethod = type.GetMethod("GetShapeMultiplier", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic, null, Type.EmptyTypes, null);
		return _getShapeMultiplierMethod;
	}
}
internal static class InputCompat
{
	private static readonly MethodInfo GetKeyDownMethod = FindGetKeyDownMethod();

	public static bool GetKeyDown(KeyCode key)
	{
		//IL_0024: Unknown result type (might be due to invalid IL or missing references)
		if (GetKeyDownMethod == null)
		{
			return false;
		}
		try
		{
			object obj = GetKeyDownMethod.Invoke(null, new object[1] { key });
			return obj is bool && (bool)obj;
		}
		catch
		{
			return false;
		}
	}

	private static MethodInfo FindGetKeyDownMethod()
	{
		Assembly[] assemblies = AppDomain.CurrentDomain.GetAssemblies();
		for (int i = 0; i < assemblies.Length; i++)
		{
			Type type = assemblies[i].GetType("UnityEngine.Input", throwOnError: false);
			if (!(type == null))
			{
				MethodInfo method = type.GetMethod("GetKeyDown", BindingFlags.Static | BindingFlags.Public, null, new Type[1] { typeof(KeyCode) }, null);
				if (method != null)
				{
					return method;
				}
			}
		}
		return null;
	}
}
internal sealed class DamageNumberView : MonoBehaviour
{
	private TextMeshPro _text;

	private Vector3 _basePosition;

	private Vector3 _jitter;

	private float _startTime;

	private float _lifetime;

	private float _floatSpeed;

	private Color _baseColor;

	public void Init(string value, Vector3 position, Vector3 jitter, float lifetime, float floatSpeed, float worldScale, float fontSize, Color color)
	{
		//IL_0002: Unknown result type (might be due to invalid IL or missing references)
		//IL_0003: Unknown result type (might be due to invalid IL or missing references)
		//IL_0009: Unknown result type (might be due to invalid IL or missing references)
		//IL_000a: Unknown result type (might be due to invalid IL or missing references)
		//IL_0035: Unknown result type (might be due to invalid IL or missing references)
		//IL_0037: Unknown result type (might be due to invalid IL or missing references)
		//IL_0042: Unknown result type (might be due to invalid IL or missing references)
		//IL_0043: Unknown result type (might be due to invalid IL or missing references)
		//IL_0044: Unknown result type (might be due to invalid IL or missing references)
		//IL_0055: Unknown result type (might be due to invalid IL or missing references)
		//IL_005c: Unknown result type (might be due to invalid IL or missing references)
		//IL_00b8: Unknown result type (might be due to invalid IL or missing references)
		_basePosition = position;
		_jitter = jitter;
		_startTime = Time.time;
		_lifetime = Mathf.Max(0.05f, lifetime);
		_floatSpeed = floatSpeed;
		_baseColor = color;
		((Component)this).transform.position = position + jitter;
		((Component)this).transform.localScale = Vector3.one * worldScale;
		_text = ((Component)this).gameObject.AddComponent<TextMeshPro>();
		((TMP_Text)_text).text = value;
		((TMP_Text)_text).fontSize = fontSize;
		((TMP_Text)_text).alignment = (TextAlignmentOptions)514;
		((TMP_Text)_text).textWrappingMode = (TextWrappingModes)0;
		((Graphic)_text).color = _baseColor;
	}

	private void LateUpdate()
	{
		//IL_0039: Unknown result type (might be due to invalid IL or missing references)
		//IL_003f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0044: Unknown result type (might be due to invalid IL or missing references)
		//IL_0049: Unknown result type (might be due to invalid IL or missing references)
		//IL_0056: Unknown result type (might be due to invalid IL or missing references)
		//IL_005b: Unknown result type (might be due to invalid IL or missing references)
		//IL_00df: Unknown result type (might be due to invalid IL or missing references)
		//IL_00e4: Unknown result type (might be due to invalid IL or missing references)
		//IL_00f3: Unknown result type (might be due to invalid IL or missing references)
		//IL_0080: Unknown result type (might be due to invalid IL or missing references)
		//IL_008b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0090: Unknown result type (might be due to invalid IL or missing references)
		//IL_0095: Unknown result type (might be due to invalid IL or missing references)
		//IL_00b1: Unknown result type (might be due to invalid IL or missing references)
		//IL_00b9: Unknown result type (might be due to invalid IL or missing references)
		//IL_00be: Unknown result type (might be due to invalid IL or missing references)
		float num = Time.time - _startTime;
		if (num >= _lifetime)
		{
			Object.Destroy((Object)(object)((Component)this).gameObject);
			return;
		}
		((Component)this).transform.position = _basePosition + _jitter + Vector3.up * (num * _floatSpeed);
		Camera main = Camera.main;
		if ((Object)(object)main != (Object)null)
		{
			Vector3 val = ((Component)this).transform.position - ((Component)main).transform.position;
			if (((Vector3)(ref val)).sqrMagnitude > 0.0001f)
			{
				((Component)this).transform.rotation = Quaternion.LookRotation(val, ((Component)main).transform.up);
			}
		}
		float a = Mathf.Clamp01(1f - num / _lifetime);
		Color baseColor = _baseColor;
		baseColor.a = a;
		((Graphic)_text).color = baseColor;
	}
}
internal static class DamageReceivePatch
{
	public static void Apply(Harmony harmony)
	{
		DamageLogPatch.Apply(harmony);
	}
}
[BepInPlugin("ryuka.sulfur.damagenumbers", "SULFUR Damage Numbers", "1.0.7")]
public sealed class Plugin : BaseUnityPlugin
{
	public const string PluginGuid = "ryuka.sulfur.damagenumbers";

	public const string PluginName = "SULFUR Damage Numbers";

	public const string PluginVersion = "1.0.7";

	internal static ConfigEntry<bool> Enabled;

	internal static ConfigEntry<DisplayMode> Mode;

	internal static ConfigEntry<RenderMode> Renderer;

	internal static ConfigEntry<MergedColorMode> AggregateColorMode;

	internal static ConfigEntry<bool> UseWeakspotColors;

	internal static ConfigEntry<bool> TreatOneMultiplierAsNormal;

	internal static ConfigEntry<bool> RequireNpcTarget;

	internal static ConfigEntry<bool> RequireSourceUnitPlayer;

	internal static ConfigEntry<bool> ShowPlayerOwnedSecondaryEffects;

	internal static ConfigEntry<float> MinDamageToShow;

	internal static ConfigEntry<bool> ShowDecimals;

	internal static ConfigEntry<float> Lifetime;

	internal static ConfigEntry<float> FloatSpeed;

	internal static ConfigEntry<float> WorldScale;

	internal static ConfigEntry<float> RandomJitter;

	internal static ConfigEntry<float> FontSize;

	internal static ConfigEntry<int> ScreenFontSize;

	internal static ConfigEntry<float> ScreenFloatSpeed;

	internal static ConfigEntry<float> ScreenJitter;

	internal static ConfigEntry<float> PerHitStackScreenSpread;

	internal static ConfigEntry<float> PerHitStackWorldSpread;

	internal static ConfigEntry<int> MaxActiveNumbers;

	internal static ConfigEntry<bool> DebugLog;

	internal static ConfigEntry<bool> DebugSpawnTestOnF8;

	internal static ManualLogSource Log;

	private Harmony _harmony;

	private void Awake()
	{
		//IL_0345: Unknown result type (might be due to invalid IL or missing references)
		//IL_034f: Expected O, but got Unknown
		Log = ((BaseUnityPlugin)this).Logger;
		Enabled = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "Enabled", true, "Enable damage number display.");
		Mode = ((BaseUnityPlugin)this).Config.Bind<DisplayMode>("General", "DamageDisplayMode", DisplayMode.PerTargetTotal, "PerTargetTotal = same frame, same player attack source, same target damage is merged. PerHit = every real damage log call creates one number.");
		Renderer = ((BaseUnityPlugin)this).Config.Bind<RenderMode>("Visual", "Renderer", RenderMode.ScreenSpace, "ScreenSpace is the most reliable renderer. WorldTextMeshPro uses 3D TextMeshPro objects. Both renders both at the same time for debugging.");
		UseWeakspotColors = ((BaseUnityPlugin)this).Config.Bind<bool>("Visual", "UseWeakspotColors", true, "Use weakspot/body-part multiplier colors. The color thresholds match the PositiveShapes debug overlay style: red >= 1.5, orange >= 1.0, yellow >= 0.75, white when no multiplier is available.");
		TreatOneMultiplierAsNormal = ((BaseUnityPlugin)this).Config.Bind<bool>("Visual", "TreatOneMultiplierAsNormal", false, "If true, multiplier 1.0 is shown as white instead of orange. Enable this if the game reports ordinary body hits as multiplier 1.0 and you want only special weakpoints colored.");
		AggregateColorMode = ((BaseUnityPlugin)this).Config.Bind<MergedColorMode>("Visual", "AggregateColorMode", MergedColorMode.HighestMultiplier, "Color rule for PerTargetTotal. HighestMultiplier = use the strongest pellet/hit color. DamageWeightedAverage = average multipliers by damage. LastHit = use the last hit color.");
		RequireNpcTarget = ((BaseUnityPlugin)this).Config.Bind<bool>("Filter", "RequireNpcTarget", true, "Only show damage numbers on Npc targets. Keep true to avoid barrels/objects if they also use Unit damage code.");
		RequireSourceUnitPlayer = ((BaseUnityPlugin)this).Config.Bind<bool>("Filter", "RequireSourceUnitPlayer", false, "If true, sourceData.sourceUnit must exist and be the player. Default false because some projectiles/explosions keep only the game's isPlayer flag.");
		ShowPlayerOwnedSecondaryEffects = ((BaseUnityPlugin)this).Config.Bind<bool>("Filter", "ShowPlayerOwnedSecondaryEffects", true, "Show player-owned secondary damage such as projectile explosions if the game reports them as created by the player. Turn off if poison/fire DoT becomes noisy.");
		MinDamageToShow = ((BaseUnityPlugin)this).Config.Bind<float>("Filter", "MinDamageToShow", 0.01f, "Final damage below this value will not be shown.");
		ShowDecimals = ((BaseUnityPlugin)this).Config.Bind<bool>("Visual", "ShowDecimals", false, "Show one decimal place for non-integer damage. Integer values such as 5.0 are still shown as 5.");
		Lifetime = ((BaseUnityPlugin)this).Config.Bind<float>("Visual", "Lifetime", 0.85f, "Damage number lifetime in seconds.");
		FloatSpeed = ((BaseUnityPlugin)this).Config.Bind<float>("Visual", "FloatSpeed", 1.25f, "World-space upward speed for WorldTextMeshPro renderer.");
		WorldScale = ((BaseUnityPlugin)this).Config.Bind<float>("Visual", "WorldScale", 0.045f, "World-space scale of each TextMeshPro damage number.");
		RandomJitter = ((BaseUnityPlugin)this).Config.Bind<float>("Visual", "RandomJitter", 0.18f, "Random horizontal world-space offset. Useful for PerHit shotgun pellets.");
		FontSize = ((BaseUnityPlugin)this).Config.Bind<float>("Visual", "FontSize", 6f, "TextMeshPro font size for WorldTextMeshPro renderer.");
		ScreenFontSize = ((BaseUnityPlugin)this).Config.Bind<int>("Visual", "ScreenFontSize", 28, "Screen-space GUI font size.");
		ScreenFloatSpeed = ((BaseUnityPlugin)this).Config.Bind<float>("Visual", "ScreenFloatSpeed", 70f, "Screen-space upward speed in pixels per second.");
		ScreenJitter = ((BaseUnityPlugin)this).Config.Bind<float>("Visual", "ScreenJitter", 26f, "Random screen-space offset in pixels. Useful for PerHit shotgun pellets.");
		PerHitStackScreenSpread = ((BaseUnityPlugin)this).Config.Bind<float>("Visual", "PerHitStackScreenSpread", 12.8f, "Extra deterministic screen-space spread in pixels for multiple PerHit numbers created on the same target in the same frame. This makes shotgun pellets easier to read without delaying or merging damage.");
		PerHitStackWorldSpread = ((BaseUnityPlugin)this).Config.Bind<float>("Visual", "PerHitStackWorldSpread", 0.06f, "Extra deterministic world-space spread for multiple PerHit numbers created on the same target in the same frame. Used by WorldTextMeshPro and Both renderers.");
		MaxActiveNumbers = ((BaseUnityPlugin)this).Config.Bind<int>("Performance", "MaxActiveNumbers", 160, "Maximum active screen-space damage numbers. When exceeded, the oldest entries are discarded first to prevent UI spam during extreme PerHit cases.");
		DebugLog = ((BaseUnityPlugin)this).Config.Bind<bool>("Debug", "DebugLog", false, "Print accepted/rejected damage events to LogOutput.log.");
		DebugSpawnTestOnF8 = ((BaseUnityPlugin)this).Config.Bind<bool>("Debug", "DebugSpawnTestOnF8", true, "Press F8 in-game to spawn a test number at the screen center. This verifies the renderer even without hitting enemies.");
		DamageNumberManager.EnsureExists();
		_harmony = new Harmony("ryuka.sulfur.damagenumbers");
		DamageLogPatch.Apply(_harmony);
		((BaseUnityPlugin)this).Logger.LogInfo((object)("SULFUR Damage Numbers 1.0.7 loaded. Renderer=" + Renderer.Value.ToString() + ", Mode=" + Mode.Value.ToString() + "."));
	}

	private void OnDestroy()
	{
		if (_harmony != null)
		{
			_harmony.UnpatchSelf();
			_harmony = null;
		}
	}
}
public enum DisplayMode
{
	PerTargetTotal = 1,
	PerHit
}
public enum RenderMode
{
	ScreenSpace = 1,
	WorldTextMeshPro,
	Both
}
public enum MergedColorMode
{
	HighestMultiplier = 1,
	DamageWeightedAverage,
	LastHit
}