Decompiled source of MTMCore v0.2.0

plugins\MTMCore.dll

Decompiled a month ago
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Runtime.Versioning;
using System.Security.Permissions;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using HarmonyLib;
using Jotunn.Managers;
using Jotunn.Utils;
using More_World_Locations_AIO.Traders;
using TMPro;
using UnityEngine;
using UnityEngine.Events;
using UnityEngine.UI;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: AssemblyTitle("MTMCore")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("MTMCore")]
[assembly: AssemblyCopyright("Copyright ©  2021")]
[assembly: AssemblyTrademark("")]
[assembly: ComVisible(false)]
[assembly: Guid("e3243d22-4307-4008-ba36-9f326008cde5")]
[assembly: AssemblyFileVersion("0.2.0")]
[assembly: TargetFramework(".NETFramework,Version=v4.8", FrameworkDisplayName = ".NET Framework 4.8")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("0.2.0.0")]
namespace MTMCore
{
	[BepInPlugin("mightytightymods.mtm-core", "MTMCore", "0.2.0")]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[NetworkCompatibility(/*Could not decode attribute arguments.*/)]
	internal class Plugin : BaseUnityPlugin
	{
		public const string PluginGUID = "mightytightymods.mtm-core";

		public const string PluginName = "MTMCore";

		public const string PluginVersion = "0.2.0";

		public static ConfigEntry<float> CreatureHealthMult;

		public static ConfigEntry<float> CreatureDamageMult;

		public static ConfigEntry<float> BossHealthMult;

		public static ConfigEntry<float> BossDamageMult;

		public static ConfigEntry<float> PerStarHealthMult;

		public static ConfigEntry<float> PerStarDamageMult;

		public static ConfigEntry<float> AdrenalineMultiplier;

		public static ConfigEntry<float> AdrenalineDecayMultiplier;

		public static ConfigEntry<float> AdrenalineDecayDelayMultiplier;

		public static ConfigEntry<bool> AdrenalineEnableTrinketExtension;

		public static ConfigEntry<int> UpperLeftSplitAmount;

		public static ConfigEntry<int> UpperRightSplitAmount;

		public static ConfigEntry<int> LowerLeftSplitAmount;

		public static ConfigEntry<int> LowerRightSplitAmount;

		public static ConfigEntry<int> SkillBookBreakpoint;

		public static ConfigEntry<int> SkillBookCap;

		public static ConfigEntry<float> WispTorchRadiusMult;

		public static ConfigEntry<bool> VerboseLogging;

		private readonly Harmony harmony = new Harmony("mightytightymods.mtm-core");

		public static ManualLogSource Log;

		private void Awake()
		{
			//IL_000b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0010: Unknown result type (might be due to invalid IL or missing references)
			//IL_0018: Expected O, but got Unknown
			//IL_004d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0057: 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
			//IL_00b5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bf: Expected O, but got Unknown
			//IL_00e9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f3: Expected O, but got Unknown
			//IL_011d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0127: Expected O, but got Unknown
			//IL_0151: Unknown result type (might be due to invalid IL or missing references)
			//IL_015b: Expected O, but got Unknown
			//IL_0185: Unknown result type (might be due to invalid IL or missing references)
			//IL_018f: Expected O, but got Unknown
			//IL_01b9: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c3: Expected O, but got Unknown
			//IL_01ed: Unknown result type (might be due to invalid IL or missing references)
			//IL_01f7: Expected O, but got Unknown
			//IL_021d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0227: Expected O, but got Unknown
			//IL_0251: Unknown result type (might be due to invalid IL or missing references)
			//IL_025b: Expected O, but got Unknown
			//IL_027c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0286: Expected O, but got Unknown
			//IL_02a8: Unknown result type (might be due to invalid IL or missing references)
			//IL_02b2: Expected O, but got Unknown
			//IL_02d4: Unknown result type (might be due to invalid IL or missing references)
			//IL_02de: Expected O, but got Unknown
			//IL_030e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0318: Expected O, but got Unknown
			//IL_033f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0349: Expected O, but got Unknown
			//IL_0381: Unknown result type (might be due to invalid IL or missing references)
			//IL_038b: Expected O, but got Unknown
			//IL_03ac: Unknown result type (might be due to invalid IL or missing references)
			//IL_03b6: Expected O, but got Unknown
			Log = ((BaseUnityPlugin)this).Logger;
			ConfigurationManagerAttributes val = new ConfigurationManagerAttributes
			{
				IsAdminOnly = true
			};
			AcceptableValueRange<float> val2 = new AcceptableValueRange<float>(0.1f, 5f);
			CreatureHealthMult = ((BaseUnityPlugin)this).Config.Bind<float>("Creatures", "HealthMultiplier", 1f, new ConfigDescription("Multiplier applied to all non-boss creature hitpoints. 1.0 = vanilla.", (AcceptableValueBase)(object)val2, new object[1] { val }));
			CreatureDamageMult = ((BaseUnityPlugin)this).Config.Bind<float>("Creatures", "DamageMultiplier", 1f, new ConfigDescription("Multiplier applied to all non-boss creature damage output. 1.0 = vanilla.", (AcceptableValueBase)(object)val2, new object[1] { val }));
			PerStarHealthMult = ((BaseUnityPlugin)this).Config.Bind<float>("Creatures", "PerStarHealthMultiplier", 1f, new ConfigDescription("Multiplier to creature health added per star level. 1.0 = vanilla star health scaling -> +100% health per star.NOTE: This is multiplicative with HealthMultiplier.", (AcceptableValueBase)(object)val2, new object[1] { val }));
			PerStarDamageMult = ((BaseUnityPlugin)this).Config.Bind<float>("Creatures", "PerStarDamageMultiplier", 1f, new ConfigDescription("Multiplier to creature damage added per star level. 1.0 = vanilla star damage scaling -> +50% damage per star.NOTE: This is multiplicative with DamageMultiplier.", (AcceptableValueBase)(object)val2, new object[1] { val }));
			BossHealthMult = ((BaseUnityPlugin)this).Config.Bind<float>("Bosses", "BossHealthMultiplier", 1f, new ConfigDescription("Multiplier applied to boss health. 1.0 = vanilla.", (AcceptableValueBase)(object)val2, new object[1] { val }));
			BossDamageMult = ((BaseUnityPlugin)this).Config.Bind<float>("Bosses", "BossDamageMultiplier", 1f, new ConfigDescription("Multiplier applied to all boss damage output. 1.0 = vanilla.", (AcceptableValueBase)(object)val2, new object[1] { val }));
			AdrenalineMultiplier = ((BaseUnityPlugin)this).Config.Bind<float>("Adrenaline", "AdrenalineMultiplier", 1f, new ConfigDescription("Multiplier applied to adrenaline gained. Lower = harder (e.g. 0.5), higher = easier (e.g. 1.5). 1.0 = vanilla.", (AcceptableValueBase)(object)val2, new object[1] { val }));
			AdrenalineDecayMultiplier = ((BaseUnityPlugin)this).Config.Bind<float>("Adrenaline", "AdrenalineDecayMultiplier", 1f, new ConfigDescription("Multiplier applied to adrenaline lost. Higher = harder (e.g. 1.5), lower = easier (e.g. 0.5). 1.0 = vanilla.", (AcceptableValueBase)(object)val2, new object[1] { val }));
			AdrenalineDecayDelayMultiplier = ((BaseUnityPlugin)this).Config.Bind<float>("Adrenaline", "AdrenalineDecayDelayMultiplier", 1f, new ConfigDescription("Multiplier applied to the delay before adrenaline starts decaying. Lower = harder (e.g. 0.5), higher = easier (e.g. 1.5). 1.0 = vanilla.", (AcceptableValueBase)(object)val2, new object[1] { val }));
			AdrenalineEnableTrinketExtension = ((BaseUnityPlugin)this).Config.Bind<bool>("Adrenaline", "EnableTrinketExtensionAndCooldown", true, new ConfigDescription("If true: adrenaline earned while a full-adrenaline trinket effect is active extends its duration (up to 2x base), and the trinket cannot re-proc for one base-duration after the effect ends. If false: vanilla trinket proc behavior.", (AcceptableValueBase)null, new object[1] { val }));
			AcceptableValueRange<int> val3 = new AcceptableValueRange<int>(1, 50);
			UpperLeftSplitAmount = ((BaseUnityPlugin)this).Config.Bind<int>("Split Buttons", "UpperLeftAmount", 1, new ConfigDescription("Split Amount", (AcceptableValueBase)(object)val3, Array.Empty<object>()));
			UpperRightSplitAmount = ((BaseUnityPlugin)this).Config.Bind<int>("Split Buttons", "UpperRightAmount", 2, new ConfigDescription("Split Amount", (AcceptableValueBase)(object)val3, Array.Empty<object>()));
			LowerLeftSplitAmount = ((BaseUnityPlugin)this).Config.Bind<int>("Split Buttons", "LowerLeftAmount", 10, new ConfigDescription("Split Amount", (AcceptableValueBase)(object)val3, Array.Empty<object>()));
			LowerRightSplitAmount = ((BaseUnityPlugin)this).Config.Bind<int>("Split Buttons", "LowerRightAmount", 20, new ConfigDescription("Split Amount", (AcceptableValueBase)(object)val3, Array.Empty<object>()));
			AcceptableValueRange<int> val4 = new AcceptableValueRange<int>(1, 100);
			SkillBookBreakpoint = ((BaseUnityPlugin)this).Config.Bind<int>("Skill Book Limits", "SkillBookBreakpoint", 100, new ConfigDescription("Skill level past which costs double", (AcceptableValueBase)(object)val4, new object[1] { val }));
			SkillBookCap = ((BaseUnityPlugin)this).Config.Bind<int>("Skill Book Limits", "SkillBookCap", 100, new ConfigDescription("Max skill level trained with a skill book", (AcceptableValueBase)(object)val4, new object[1] { val }));
			WispTorchRadiusMult = ((BaseUnityPlugin)this).Config.Bind<float>("Wisp Torch", "RadiusMultiplier", 1f, new ConfigDescription("Multiplier applied to the placed wisp torch's demisting radius. 1.0 = vanilla. Does not affect the Wisplight.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0.5f, 5f), new object[1] { val }));
			VerboseLogging = ((BaseUnityPlugin)this).Config.Bind<bool>("Diagnostics", "VerboseLogging", false, new ConfigDescription("Logs detailed per-hit and per-creature scaling information.", (AcceptableValueBase)null, Array.Empty<object>()));
			harmony.PatchAll();
			((BaseUnityPlugin)this).Logger.LogInfo((object)"MTM Difficulty initialized.");
		}
	}
}
namespace MTMCore.Patches
{
	internal class AdrenalineTrinketState
	{
		public bool Active;

		public StatusEffect ActiveEffect;

		public float BaseDuration;

		public float CooldownEndsAt = -1f;

		public float ExtensionBudgetRemaining;

		public bool OnCooldown
		{
			get
			{
				if (CooldownEndsAt > 0f)
				{
					return Time.time < CooldownEndsAt;
				}
				return false;
			}
		}
	}
	internal struct AdrenalineCallState
	{
		public float RawV;

		public bool WasActive;
	}
	internal static class AdrenalinePatches
	{
		[HarmonyPatch(typeof(Player), "AddAdrenaline")]
		private static class Patch_AddAdrenaline
		{
			private static void Prefix(Player __instance, ref float v, out AdrenalineCallState __state)
			{
				bool value = Plugin.AdrenalineEnableTrinketExtension.Value;
				AdrenalineTrinketState adrenalineTrinketState = (value ? GetState(__instance) : null);
				__state = new AdrenalineCallState
				{
					RawV = v,
					WasActive = (adrenalineTrinketState?.Active ?? false)
				};
				if (v > 0f)
				{
					if (adrenalineTrinketState != null && (adrenalineTrinketState.Active || adrenalineTrinketState.OnCooldown))
					{
						v = 0f;
					}
					else
					{
						v *= Plugin.AdrenalineMultiplier.Value;
					}
				}
				else
				{
					v *= Plugin.AdrenalineDecayMultiplier.Value;
				}
				if (value)
				{
					s_pendingProcPlayer = __instance;
				}
			}

			private static void Postfix(Player __instance, ref float ___m_adrenalineDegenTimer, ref float v, AdrenalineCallState __state)
			{
				s_pendingProcPlayer = null;
				float maxAdrenaline = ((Character)__instance).GetMaxAdrenaline();
				if (v > 0f && maxAdrenaline > 0f)
				{
					___m_adrenalineDegenTimer *= Plugin.AdrenalineDecayDelayMultiplier.Value;
				}
				if (!Plugin.AdrenalineEnableTrinketExtension.Value)
				{
					return;
				}
				AdrenalineTrinketState state = GetState(__instance);
				if (!__state.WasActive || !state.Active || (Object)(object)state.ActiveEffect == (Object)null || __state.RawV <= 0f)
				{
					return;
				}
				float num = Mathf.Min(__state.RawV, state.ExtensionBudgetRemaining);
				if (!(num <= 0f))
				{
					float num2 = (float)StatusEffectTimeField.GetValue(state.ActiveEffect);
					StatusEffectTimeField.SetValue(state.ActiveEffect, num2 - num);
					state.ExtensionBudgetRemaining -= num;
					if (Plugin.VerboseLogging.Value)
					{
						Plugin.Log.LogInfo((object)$"[Adrenaline] Trinket extended by {num}, budget remaining {state.ExtensionBudgetRemaining:0.0}s");
					}
				}
			}
		}

		[HarmonyPatch(typeof(SEMan), "AddStatusEffect", new Type[]
		{
			typeof(StatusEffect),
			typeof(bool),
			typeof(int),
			typeof(float),
			typeof(short)
		})]
		private static class Patch_SEMan_AddStatusEffect
		{
			private static void Postfix(StatusEffect __result)
			{
				if (!Plugin.AdrenalineEnableTrinketExtension.Value || (Object)(object)s_pendingProcPlayer == (Object)null || (Object)(object)__result == (Object)null)
				{
					return;
				}
				if (__result.m_ttl <= 0f)
				{
					if (Plugin.VerboseLogging.Value)
					{
						Plugin.Log.LogInfo((object)$"[Adrenaline] Trinket proc'd: {((Object)__result).name} has no duration (m_ttl={__result.m_ttl}), exempt from extension/cooldown.");
					}
					return;
				}
				AdrenalineTrinketState state = GetState(s_pendingProcPlayer);
				state.Active = true;
				state.ActiveEffect = __result;
				state.BaseDuration = __result.m_ttl;
				state.ExtensionBudgetRemaining = __result.m_ttl;
				state.CooldownEndsAt = -1f;
				if (Plugin.VerboseLogging.Value)
				{
					Plugin.Log.LogInfo((object)$"[Adrenaline] Trinket proc'd: {((Object)__result).name}, base duration {__result.m_ttl}s");
				}
			}
		}

		[HarmonyPatch(typeof(StatusEffect), "Stop")]
		private static class Patch_StatusEffect_Stop
		{
			private static void Prefix(StatusEffect __instance)
			{
				if (!Plugin.AdrenalineEnableTrinketExtension.Value)
				{
					return;
				}
				Character character = __instance.m_character;
				Player val = (Player)(object)((character is Player) ? character : null);
				if (val == null)
				{
					return;
				}
				AdrenalineTrinketState state = GetState(val);
				if (state.Active && state.ActiveEffect == __instance)
				{
					state.Active = false;
					state.ActiveEffect = null;
					state.CooldownEndsAt = Time.time + state.BaseDuration;
					if (Plugin.VerboseLogging.Value)
					{
						Plugin.Log.LogInfo((object)$"[Adrenaline] Trinket ended, cooldown for {state.BaseDuration}s");
					}
				}
			}
		}

		private static readonly ConditionalWeakTable<Player, AdrenalineTrinketState> States = new ConditionalWeakTable<Player, AdrenalineTrinketState>();

		private static readonly FieldInfo StatusEffectTimeField = AccessTools.Field(typeof(StatusEffect), "m_time");

		private static Player s_pendingProcPlayer;

		private static AdrenalineTrinketState GetState(Player player)
		{
			return States.GetOrCreateValue(player);
		}
	}
	[HarmonyPatch(typeof(Minimap), "Start")]
	public static class Minimap_Start_TextClockPatch
	{
		private class TimeOfDayLabelUpdater : MonoBehaviour
		{
			private Text _label;

			private float _timer;

			private string _lastText = string.Empty;

			public void Bind(Text label)
			{
				_label = label;
			}

			private void Update()
			{
				_timer -= Time.deltaTime;
				if (!(_timer > 0f))
				{
					_timer = 2f;
					string label = TimeOfDay.GetLabel(EnvMan.instance.GetDayFraction());
					if (label != _lastText)
					{
						_label.text = label;
						_lastText = label;
					}
				}
			}
		}

		private const float OffsetX = -5f;

		private const float OffsetY = 0f;

		private const int FontSize = 16;

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

		private const float UpdateIntervalSeconds = 2f;

		private static void Postfix(Minimap __instance)
		{
			//IL_004d: 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_006b: 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_0082: 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)
			Transform transform = __instance.m_smallRoot.transform;
			object obj;
			if (__instance == null)
			{
				obj = null;
			}
			else
			{
				TMP_Text biomeNameLarge = __instance.m_biomeNameLarge;
				obj = ((biomeNameLarge != null) ? biomeNameLarge.font : null);
			}
			TMP_FontAsset val = (TMP_FontAsset)obj;
			if (val != null)
			{
				Plugin.Log.LogDebug((object)((Object)val).name);
			}
			GameObject obj2 = GUIManager.Instance.CreateText("", transform, new Vector2(1f, 0f), new Vector2(1f, 0f), new Vector2(-5f, 0f), GUIManager.Instance.AveriaSerifBold, 16, TextColor, true, Color.black, 200f, 30f, true);
			obj2.GetComponent<RectTransform>().pivot = new Vector2(1f, 1f);
			Text component = obj2.GetComponent<Text>();
			component.alignment = (TextAnchor)8;
			obj2.AddComponent<TimeOfDayLabelUpdater>().Bind(component);
		}
	}
	public static class TimeOfDay
	{
		private const float WeeHoursStart = 0.15f;

		private const float DawnStart = 0.2f;

		private const float MorningStart = 0.25f;

		private const float MidDayStart = 0.35f;

		private const float EveningStart = 0.6f;

		private const float DuskStart = 0.7f;

		private const float NightfallStart = 0.75f;

		private const float MidnightStart = 0.85f;

		public static string GetLabel(float dayFraction)
		{
			if (!(dayFraction >= 0.85f))
			{
				if (!(dayFraction >= 0.75f))
				{
					if (!(dayFraction >= 0.7f))
					{
						if (!(dayFraction >= 0.6f))
						{
							if (!(dayFraction >= 0.35f))
							{
								if (!(dayFraction >= 0.25f))
								{
									if (!(dayFraction >= 0.2f))
									{
										if (dayFraction >= 0.15f)
										{
											return "Jiig O'Clock";
										}
										return "Midnight";
									}
									return "Dawn";
								}
								return "Morning";
							}
							return "Mid-day";
						}
						return "Evening";
					}
					return "Dusk";
				}
				return "Nightfall";
			}
			return "Midnight";
		}
	}
	[HarmonyPatch(typeof(Character), "SetupMaxHealth")]
	public static class CharacterSetupMaxHealthPatch
	{
		private static void Postfix(Character __instance)
		{
			if (!__instance.IsPlayer())
			{
				float maxHealthBase = __instance.GetMaxHealthBase();
				int num = __instance.GetLevel() - 1;
				bool boss = __instance.m_boss;
				float num2 = (boss ? Plugin.BossHealthMult.Value : Plugin.CreatureHealthMult.Value);
				float num3 = 1f + (float)num * 1f * Plugin.PerStarHealthMult.Value;
				float num4 = maxHealthBase * num2 * num3;
				__instance.SetMaxHealth(num4);
				if (Plugin.VerboseLogging.Value)
				{
					Plugin.Log.LogInfo((object)($"[HEALTH PATCHED] {((Object)__instance).name} | stars={num} isBoss={boss} " + $"baseHealth={maxHealthBase:F1} mult={num2:F2} starBonus={num3:F2} => final={num4:F1}"));
				}
			}
		}
	}
	[HarmonyPatch(typeof(Character), "Damage")]
	public static class CharacterDamagePatch
	{
		private struct DamageComponentLog
		{
			public string Name { get; init; }

			public float Before { get; init; }

			public float After { get; init; }
		}

		private static void Prefix(Character __instance, ref HitData hit)
		{
			//IL_007a: 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_008c: 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)
			//IL_00c1: 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_00fa: Unknown result type (might be due to invalid IL or missing references)
			//IL_0108: 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_016c: 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_01a5: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b3: Unknown result type (might be due to invalid IL or missing references)
			//IL_01de: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ec: 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_0225: Unknown result type (might be due to invalid IL or missing references)
			//IL_0250: Unknown result type (might be due to invalid IL or missing references)
			//IL_025e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0289: Unknown result type (might be due to invalid IL or missing references)
			//IL_0297: Unknown result type (might be due to invalid IL or missing references)
			//IL_02c3: Unknown result type (might be due to invalid IL or missing references)
			//IL_02d1: Unknown result type (might be due to invalid IL or missing references)
			Character attacker = hit.GetAttacker();
			if ((Object)(object)attacker == (Object)null || attacker.IsPlayer())
			{
				return;
			}
			int num = attacker.GetLevel() - 1;
			bool boss = attacker.m_boss;
			float num2 = (boss ? Plugin.BossDamageMult.Value : Plugin.CreatureDamageMult.Value);
			float num3 = 1f + (float)num * 0.5f;
			float num4 = 1f + (float)num * 0.5f * Plugin.PerStarDamageMult.Value;
			float num5 = num2 * (num4 / num3);
			DamageTypes damage = hit.m_damage;
			hit.ApplyModifier(num5);
			DamageTypes damage2 = hit.m_damage;
			if (!Plugin.VerboseLogging.Value)
			{
				return;
			}
			DamageComponentLog[] obj = new DamageComponentLog[10]
			{
				new DamageComponentLog
				{
					Name = "blunt",
					Before = damage.m_blunt,
					After = damage2.m_blunt
				},
				new DamageComponentLog
				{
					Name = "slash",
					Before = damage.m_slash,
					After = damage2.m_slash
				},
				new DamageComponentLog
				{
					Name = "pierce",
					Before = damage.m_pierce,
					After = damage2.m_pierce
				},
				new DamageComponentLog
				{
					Name = "chop",
					Before = damage.m_chop,
					After = damage2.m_chop
				},
				new DamageComponentLog
				{
					Name = "pickaxe",
					Before = damage.m_pickaxe,
					After = damage2.m_pickaxe
				},
				new DamageComponentLog
				{
					Name = "fire",
					Before = damage.m_fire,
					After = damage2.m_fire
				},
				new DamageComponentLog
				{
					Name = "frost",
					Before = damage.m_frost,
					After = damage2.m_frost
				},
				new DamageComponentLog
				{
					Name = "lightning",
					Before = damage.m_lightning,
					After = damage2.m_lightning
				},
				new DamageComponentLog
				{
					Name = "poison",
					Before = damage.m_poison,
					After = damage2.m_poison
				},
				new DamageComponentLog
				{
					Name = "spirit",
					Before = damage.m_spirit,
					After = damage2.m_spirit
				}
			};
			List<string> list = new List<string>();
			DamageComponentLog[] array = obj;
			for (int i = 0; i < array.Length; i++)
			{
				DamageComponentLog damageComponentLog = array[i];
				if (damageComponentLog.Before != 0f || damageComponentLog.After != 0f)
				{
					list.Add($"  {damageComponentLog.Name}: {damageComponentLog.Before:F1} => {damageComponentLog.After:F1}");
				}
			}
			string text = string.Join("\n", list);
			Plugin.Log.LogInfo((object)($"[DMG PATCHED] attacker={((Object)attacker).name} stars={num} isBoss={boss} " + $"mult={num2:F2} starBonus={num4:F2} totalMult={num5:F2}\n" + text));
		}
	}
	[HarmonyPatch(typeof(Player), "CanConsumeItem")]
	internal static class SkillBookConsumeGatePatch
	{
		private static void Postfix(Player __instance, ItemData item, ref bool __result)
		{
			//IL_002e: Unknown result type (might be due to invalid IL or missing references)
			if (__result)
			{
				StatusEffect obj = item?.m_shared?.m_consumeStatusEffect;
				SkillBook_SE val = (SkillBook_SE)(object)((obj is SkillBook_SE) ? obj : null);
				if (val != null && ((Character)__instance).GetSkills().GetSkill(val.skillType).m_level >= (float)Plugin.SkillBookCap.Value)
				{
					((Character)__instance).Message((MessageType)2, "$skill_" + ((object)Unsafe.As<SkillType, SkillType>(ref val.skillType)/*cast due to .constrained prefix*/).ToString().ToLower() + " is already capped at " + Plugin.SkillBookCap.Value, 0, (Sprite)null, false);
					__result = false;
				}
			}
		}
	}
	[HarmonyPatch(typeof(SkillBook_SE), "ApplySkillBook")]
	internal static class SkillBookCapPatch
	{
		private const float FullRateCredit = 1f;

		private const float HalfRateCredit = 0.5f;

		private static bool Prefix(SkillBook_SE __instance, Player ___player, ref bool ___shouldRemove)
		{
			//IL_0015: 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)
			if ((Object)(object)___player == (Object)null)
			{
				___shouldRemove = true;
				return false;
			}
			Skill skill = ((Character)___player).GetSkills().GetSkill(__instance.skillType);
			if (skill.m_level >= (float)Plugin.SkillBookCap.Value)
			{
				((Character)___player).Message((MessageType)2, "$skill_" + ((object)Unsafe.As<SkillType, SkillType>(ref __instance.skillType)/*cast due to .constrained prefix*/).ToString().ToLower() + " is capped at " + Plugin.SkillBookCap.Value, 0, (Sprite)null, false);
				___shouldRemove = true;
				return false;
			}
			int num = __instance.bookTier switch
			{
				1 => 1, 
				2 => 3, 
				3 => 5, 
				_ => 1, 
			};
			bool flag = false;
			bool flag2 = false;
			for (int i = 0; i < num; i++)
			{
				if (!(skill.m_level < (float)Plugin.SkillBookCap.Value))
				{
					break;
				}
				bool flag3 = skill.m_level >= (float)Plugin.SkillBookBreakpoint.Value;
				float credit = (flag3 ? 0.5f : 1f);
				if (ApplyCredit(skill, ___player, __instance.skillType, credit))
				{
					if (flag3)
					{
						flag2 = true;
					}
					else
					{
						flag = true;
					}
				}
			}
			string text = "$skill_" + ((object)Unsafe.As<SkillType, SkillType>(ref __instance.skillType)/*cast due to .constrained prefix*/).ToString().ToLower();
			if (flag2)
			{
				((Character)___player).Message((MessageType)2, text + " increased to " + (int)skill.m_level + " — advanced training yields less", 0, skill.m_info?.m_icon, false);
			}
			else if (flag)
			{
				((Character)___player).Message((MessageType)2, text + " increased to " + (int)skill.m_level, 0, skill.m_info?.m_icon, false);
			}
			else
			{
				((Character)___player).Message((MessageType)2, text + " training progress recorded", 0, (Sprite)null, false);
			}
			___shouldRemove = true;
			return false;
		}

		private static bool ApplyCredit(Skill skill, Player player, SkillType skillType, float credit)
		{
			//IL_006c: Unknown result type (might be due to invalid IL or missing references)
			if (skill.m_level >= (float)Plugin.SkillBookCap.Value)
			{
				return false;
			}
			float nextLevelRequirement = skill.GetNextLevelRequirement();
			float num = ((nextLevelRequirement > 0f) ? (skill.m_accumulator / nextLevelRequirement) : 0f);
			num += credit;
			bool result = false;
			while (num >= 1f && skill.m_level < (float)Plugin.SkillBookCap.Value)
			{
				num -= 1f;
				skill.m_level = Mathf.Clamp(skill.m_level + 1f, 0f, (float)Plugin.SkillBookCap.Value);
				player.OnSkillLevelup(skillType, skill.m_level);
				result = true;
			}
			float nextLevelRequirement2 = skill.GetNextLevelRequirement();
			skill.m_accumulator = num * nextLevelRequirement2;
			return result;
		}
	}
	[HarmonyPatch(typeof(InventoryGui), "RepairOneItem")]
	internal static class RepairAll
	{
		private static readonly List<ItemData> WornItems = new List<ItemData>();

		[HarmonyPrefix]
		private static bool Prefix(InventoryGui __instance)
		{
			//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_00e2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e8: Unknown result type (might be due to invalid IL or missing references)
			Plugin.Log.LogDebug((object)"RepairAllPatch Prefix");
			Player localPlayer = Player.m_localPlayer;
			if ((Object)(object)localPlayer == (Object)null)
			{
				return false;
			}
			CraftingStation currentCraftingStation = localPlayer.GetCurrentCraftingStation();
			if ((Object)(object)currentCraftingStation == (Object)null)
			{
				return false;
			}
			Inventory inventory = ((Humanoid)localPlayer).GetInventory();
			WornItems.Clear();
			inventory.GetWornItems(WornItems);
			int num = 0;
			string text = null;
			foreach (ItemData wornItem in WornItems)
			{
				if (__instance.CanRepair(wornItem))
				{
					wornItem.m_durability = wornItem.GetMaxDurability();
					text = wornItem.m_shared.m_name;
					num++;
				}
			}
			WornItems.Clear();
			if (num > 0)
			{
				inventory.Changed(false, false);
				currentCraftingStation.m_repairItemDoneEffects.Create(((Component)currentCraftingStation).transform.position, Quaternion.identity, (Transform)null, 1f, -1, default(ZDOID));
				string text2 = ((num == 1) ? Localization.instance.Localize("$msg_repaired", new string[1] { text }) : $"Repaired {num} items");
				((Character)localPlayer).Message((MessageType)2, text2, 0, (Sprite)null, false);
				__instance.UpdateRepair();
			}
			return false;
		}
	}
	[HarmonyPatch(typeof(Ship), "Awake")]
	public static class Ship_Awake_AllowDeconstruct
	{
		private static void Postfix(Ship __instance)
		{
			Piece componentInParent = ((Component)__instance).GetComponentInParent<Piece>();
			if (!((Object)(object)componentInParent == (Object)null))
			{
				componentInParent.m_canBeRemoved = true;
				if ((Object)(object)componentInParent.m_destroyedLootPrefab == (Object)null && (Object)(object)ZNetScene.instance != (Object)null)
				{
					componentInParent.m_destroyedLootPrefab = ZNetScene.instance.GetPrefab("CargoCrate");
				}
			}
		}
	}
	[HarmonyPatch(typeof(Piece), "CanBeRemoved")]
	public static class Piece_CanBeRemoved_ShipPatch
	{
		private static void Postfix(Piece __instance, ref bool __result)
		{
			if (__result)
			{
				Ship componentInChildren = ((Component)__instance).GetComponentInChildren<Ship>();
				if ((Object)(object)componentInChildren != (Object)null && !componentInChildren.CanBeRemoved())
				{
					__result = false;
				}
			}
		}
	}
	[HarmonyPatch(typeof(SplitDialog), "OnEnable")]
	internal static class SplitDialogOnEnablePatch
	{
		private static void Postfix(SplitDialog __instance)
		{
			StackSplitButtons.Setup(__instance);
		}
	}
	internal static class StackSplitButtons
	{
		internal static void Setup(SplitDialog splitDialog)
		{
			//IL_0043: Unknown result type (might be due to invalid IL or missing references)
			//IL_0049: Expected O, but got Unknown
			//IL_009a: 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_00b6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e0: Unknown result type (might be due to invalid IL or missing references)
			//IL_0104: Unknown result type (might be due to invalid IL or missing references)
			//IL_0139: Unknown result type (might be due to invalid IL or missing references)
			//IL_016e: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a3: Unknown result type (might be due to invalid IL or missing references)
			RectTransform groupRect;
			if (!((Object)(object)((Transform)splitDialog.m_panel).Find("StackSplitButtonGroup") != (Object)null))
			{
				GameObject val = new GameObject("StackSplitButtonGroup", new Type[1] { typeof(RectTransform) });
				groupRect = val.GetComponent<RectTransform>();
				((Transform)groupRect).SetParent((Transform)(object)splitDialog.m_panel, false);
				Vector2 anchoredPosition = default(Vector2);
				((Vector2)(ref anchoredPosition))..ctor(10f, -63f);
				RectTransform obj = groupRect;
				RectTransform obj2 = groupRect;
				Vector2 val2 = default(Vector2);
				((Vector2)(ref val2))..ctor(1f, 1f);
				obj2.anchorMax = val2;
				obj.anchorMin = val2;
				groupRect.pivot = new Vector2(1f, 1f);
				groupRect.sizeDelta = new Vector2(124f, 64f);
				groupRect.anchoredPosition = anchoredPosition;
				MakeButton(Plugin.UpperLeftSplitAmount.Value.ToString(), new Vector2(0f, 0f), delegate
				{
					splitDialog.SliderValue = Plugin.UpperLeftSplitAmount.Value;
					splitDialog.SplitOk();
				});
				MakeButton(Plugin.UpperRightSplitAmount.Value.ToString(), new Vector2(64f, 0f), delegate
				{
					splitDialog.SliderValue = Plugin.UpperRightSplitAmount.Value;
					splitDialog.SplitOk();
				});
				MakeButton(Plugin.LowerLeftSplitAmount.Value.ToString(), new Vector2(0f, -34f), delegate
				{
					splitDialog.SliderValue = Plugin.LowerLeftSplitAmount.Value;
					splitDialog.SplitOk();
				});
				MakeButton(Plugin.LowerRightSplitAmount.Value.ToString(), new Vector2(64f, -34f), delegate
				{
					splitDialog.SliderValue = Plugin.LowerRightSplitAmount.Value;
					splitDialog.SplitOk();
				});
			}
			GameObject MakeButton(string label, Vector2 position, Action onClick)
			{
				//IL_0023: 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_0037: 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_0063: Expected O, but got Unknown
				GameObject obj3 = GUIManager.Instance.CreateButton(label, (Transform)(object)groupRect, new Vector2(0f, 1f), new Vector2(0f, 1f), position, 60f, 30f);
				((UnityEvent)obj3.GetComponent<Button>().onClick).AddListener((UnityAction)delegate
				{
					onClick();
				});
				return obj3;
			}
		}
	}
	[HarmonyPatch(typeof(Demister))]
	internal static class WispTorchPatches
	{
		[HarmonyPostfix]
		[HarmonyPatch("Awake")]
		private static void Awake_Postfix(Demister __instance)
		{
			if (!((Object)(object)__instance.m_forceField == (Object)null))
			{
				bool flag = (Object)(object)((Component)__instance).GetComponentInParent<Piece>() != (Object)null;
				if (Plugin.VerboseLogging.Value)
				{
					Plugin.Log.LogInfo((object)("Demister Awake: root=" + Utils.GetPrefabName(((Component)((Component)__instance).transform.root).gameObject) + ", " + $"isPiece={flag}, endRange={__instance.m_forceField.endRange}"));
				}
				if (flag)
				{
					ParticleSystemForceField forceField = __instance.m_forceField;
					forceField.endRange *= Plugin.WispTorchRadiusMult.Value;
				}
			}
		}
	}
}