Decompiled source of GoosCombatOverhaul v1.3.3

BepInEx/plugins/GooCombatOverhaul/GooCombatOverhaul.dll

Decompiled 4 days ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.Globalization;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Text;
using System.Text.RegularExpressions;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using HarmonyLib;
using Microsoft.CodeAnalysis;
using UnityEngine;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETFramework,Version=v4.7.2", FrameworkDisplayName = ".NET Framework 4.7.2")]
[assembly: AssemblyCompany("GooCombatOverhaul")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0")]
[assembly: AssemblyProduct("GooCombatOverhaul")]
[assembly: AssemblyTitle("GooCombatOverhaul")]
[assembly: AssemblyVersion("1.0.0.0")]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[Embedded]
	[AttributeUsage(AttributeTargets.Class | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Parameter | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter, AllowMultiple = false, Inherited = false)]
	internal sealed class NullableAttribute : Attribute
	{
		public readonly byte[] NullableFlags;

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

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

		public NullableContextAttribute(byte P_0)
		{
			Flag = P_0;
		}
	}
}
namespace GooCombatOverhaul
{
	[BepInPlugin("goo.valheim.gooscombatoverhaul", "Goo's Combat Overhaul", "1.3.3")]
	public sealed class GooCombatOverhaulPlugin : BaseUnityPlugin
	{
		private enum DamageBonusKind
		{
			Backstab,
			StaggeredEnemy,
			Flanking,
			CounterDamage
		}

		private enum ModFeature
		{
			Damage,
			Staggering,
			HyperArmor,
			CounterDamage,
			HitStop,
			AttackMovement,
			AttackRotation,
			HitRay,
			StealthAttributes,
			MultiTargetPenalty,
			Pvp,
			Resources,
			Blocking
		}

		private sealed class SoulsLikeBlockStaminaState
		{
			public readonly ItemData Blocker;

			public readonly float StaminaCost;

			public readonly float ValidUntil;

			public bool Consumed;

			public SoulsLikeBlockStaminaState(ItemData blocker, float staminaCost, float validUntil)
			{
				Blocker = blocker;
				StaminaCost = staminaCost;
				ValidUntil = validUntil;
			}
		}

		private sealed class SoulsLikeBlockBreakState
		{
			public readonly ItemData Blocker;

			public readonly float StaminaBefore;

			public readonly float StaminaCost;

			public readonly bool StaminaWillBeCleared;

			public readonly float ValidUntil;

			public SoulsLikeBlockBreakState(ItemData blocker, float staminaBefore, float staminaCost, bool staminaWillBeCleared, float validUntil)
			{
				Blocker = blocker;
				StaminaBefore = staminaBefore;
				StaminaCost = staminaCost;
				StaminaWillBeCleared = staminaWillBeCleared;
				ValidUntil = validUntil;
			}
		}

		internal sealed class GearDurabilityConfig
		{
			public ConfigEntry<bool> Unbreakable { get; }

			public ConfigEntry<float> DurabilityConsumptionMultiplier { get; }

			public ConfigEntry<float> BaseDurabilityMultiplier { get; }

			public ConfigEntry<float> DurabilityMultiplier { get; }

			public GearDurabilityConfig(ConfigEntry<bool> unbreakable, ConfigEntry<float> durabilityConsumptionMultiplier, ConfigEntry<float> baseDurabilityMultiplier, ConfigEntry<float> durabilityMultiplier)
			{
				Unbreakable = unbreakable;
				DurabilityConsumptionMultiplier = durabilityConsumptionMultiplier;
				BaseDurabilityMultiplier = baseDurabilityMultiplier;
				DurabilityMultiplier = durabilityMultiplier;
			}
		}

		public sealed class DurabilityPatchState
		{
			public readonly Dictionary<ItemData, float> Before = new Dictionary<ItemData, float>();

			public DurabilityPatchState(IEnumerable<ItemData> items)
			{
				foreach (ItemData item in items)
				{
					if (item != null && item.m_shared != null && ItemUsesDurability(item) && !Before.ContainsKey(item))
					{
						Before[item] = item.m_durability;
					}
				}
			}
		}

		public sealed class DurabilitySnapshotBox
		{
			public float Before { get; set; }

			public DurabilitySnapshotBox(float before)
			{
				Before = before;
			}
		}

		public sealed class FoodFreezePatchState
		{
			public readonly List<FoodSnapshot> FoodSnapshots = new List<FoodSnapshot>();

			public readonly Dictionary<SharedData, float> FoodRegenBefore = new Dictionary<SharedData, float>();

			public bool HasWork
			{
				get
				{
					if (FoodSnapshots.Count <= 0)
					{
						return FoodRegenBefore.Count > 0;
					}
					return true;
				}
			}
		}

		public sealed class FoodSnapshot
		{
			public readonly Food Food;

			private readonly float _time;

			public FoodSnapshot(Food food)
			{
				Food = food;
				_time = food.m_time;
			}

			public void RestoreTimeAndRecalculateValues()
			{
				Food.m_time = _time;
				SharedData val = Food.m_item?.m_shared;
				if (val != null)
				{
					float num = 1f;
					if (val.m_foodBurnTime > 0f)
					{
						num = Mathf.Pow(Mathf.Clamp01(Food.m_time / val.m_foodBurnTime), 0.3f);
					}
					Food.m_health = val.m_food * num;
					Food.m_stamina = val.m_foodStamina * num;
					Food.m_eitr = val.m_foodEitr * num;
				}
			}
		}

		internal sealed class BlockedHitDamageTakenConfig
		{
			public ConfigEntry<float> Generic { get; }

			public ConfigEntry<float> Blunt { get; }

			public ConfigEntry<float> Slash { get; }

			public ConfigEntry<float> Pierce { get; }

			public ConfigEntry<float> Chop { get; }

			public ConfigEntry<float> Pickaxe { get; }

			public ConfigEntry<float> Fire { get; }

			public ConfigEntry<float> Frost { get; }

			public ConfigEntry<float> Lightning { get; }

			public ConfigEntry<float> Poison { get; }

			public ConfigEntry<float> Spirit { get; }

			public BlockedHitDamageTakenConfig(ConfigEntry<float> generic, ConfigEntry<float> blunt, ConfigEntry<float> slash, ConfigEntry<float> pierce, ConfigEntry<float> chop, ConfigEntry<float> pickaxe, ConfigEntry<float> fire, ConfigEntry<float> frost, ConfigEntry<float> lightning, ConfigEntry<float> poison, ConfigEntry<float> spirit)
			{
				Generic = generic;
				Blunt = blunt;
				Slash = slash;
				Pierce = pierce;
				Chop = chop;
				Pickaxe = pickaxe;
				Fire = fire;
				Frost = frost;
				Lightning = lightning;
				Poison = poison;
				Spirit = spirit;
			}
		}

		internal sealed class WeaponBlockExtraConfig
		{
			public ConfigEntry<float> ParryBonusMultiplier { get; }

			public ConfigEntry<float> ParryWindowTimeMultiplier { get; }

			public ConfigEntry<float> PvpParryBonusMultiplier { get; }

			public ConfigEntry<float> PvpBlockForceMultiplier { get; }

			public ConfigEntry<float> PvpBlockBreakThresholdMultiplier { get; }

			public ConfigEntry<bool> SoulsLikeBlockBreak { get; }

			public ConfigEntry<bool> SoulsLikeBlockStaminaMode { get; }

			public ConfigEntry<float> SoulsLikeBlockStaminaBaseRate { get; }

			public ConfigEntry<float> KnockbackTakenWhileBlockingMultiplier { get; }

			public ConfigEntry<float> BlockingMovementSpeedMultiplier { get; }

			public ConfigEntry<bool> EnableRunningWhileBlocking { get; }

			public ConfigEntry<float> RunningWhileBlockingMovementSpeedMultiplier { get; }

			public WeaponBlockExtraConfig(ConfigEntry<float> parryBonusMultiplier, ConfigEntry<float> parryWindowTimeMultiplier, ConfigEntry<float> pvpParryBonusMultiplier, ConfigEntry<float> pvpBlockForceMultiplier, ConfigEntry<float> pvpBlockBreakThresholdMultiplier, ConfigEntry<bool> soulsLikeBlockBreak, ConfigEntry<bool> soulsLikeBlockStaminaMode, ConfigEntry<float> soulsLikeBlockStaminaBaseRate, ConfigEntry<float> knockbackTakenWhileBlockingMultiplier, ConfigEntry<float> blockingMovementSpeedMultiplier, ConfigEntry<bool> enableRunningWhileBlocking, ConfigEntry<float> runningWhileBlockingMovementSpeedMultiplier)
			{
				ParryBonusMultiplier = parryBonusMultiplier;
				ParryWindowTimeMultiplier = parryWindowTimeMultiplier;
				PvpParryBonusMultiplier = pvpParryBonusMultiplier;
				PvpBlockForceMultiplier = pvpBlockForceMultiplier;
				PvpBlockBreakThresholdMultiplier = pvpBlockBreakThresholdMultiplier;
				SoulsLikeBlockBreak = soulsLikeBlockBreak;
				SoulsLikeBlockStaminaMode = soulsLikeBlockStaminaMode;
				SoulsLikeBlockStaminaBaseRate = soulsLikeBlockStaminaBaseRate;
				KnockbackTakenWhileBlockingMultiplier = knockbackTakenWhileBlockingMultiplier;
				BlockingMovementSpeedMultiplier = blockingMovementSpeedMultiplier;
				EnableRunningWhileBlocking = enableRunningWhileBlocking;
				RunningWhileBlockingMovementSpeedMultiplier = runningWhileBlockingMovementSpeedMultiplier;
			}
		}

		internal sealed class ShieldTypeBlockConfig
		{
			public ConfigEntry<float> BlockArmorMultiplier { get; }

			public ConfigEntry<float> BlockForceMultiplier { get; }

			public ConfigEntry<float> ParryBonusMultiplier { get; }

			public ConfigEntry<float> ParryWindowTimeMultiplier { get; }

			public ConfigEntry<float> ParryAdrenalineMultiplier { get; }

			public ConfigEntry<float> BlockStaminaConsumptionRate { get; }

			public ConfigEntry<float> BlockingStaminaRegenMultiplier { get; }

			public ConfigEntry<float> BlockBreakThresholdMultiplier { get; }

			public ConfigEntry<float> PvpBlockArmorMultiplier { get; }

			public ConfigEntry<float> PvpBlockForceMultiplier { get; }

			public ConfigEntry<float> PvpParryBonusMultiplier { get; }

			public ConfigEntry<float> PvpBlockBreakThresholdMultiplier { get; }

			public ConfigEntry<bool> SoulsLikeBlockBreak { get; }

			public ConfigEntry<bool> SoulsLikeBlockStaminaMode { get; }

			public ConfigEntry<float> SoulsLikeBlockStaminaBaseRate { get; }

			public ConfigEntry<float> KnockbackTakenWhileBlockingMultiplier { get; }

			public ConfigEntry<float> MovementModifierPercent { get; }

			public ConfigEntry<float> BlockingMovementSpeedMultiplier { get; }

			public ConfigEntry<bool> EnableRunningWhileBlocking { get; }

			public ConfigEntry<float> RunningWhileBlockingMovementSpeedMultiplier { get; }

			public ShieldTypeBlockConfig(ConfigEntry<float> blockArmorMultiplier, ConfigEntry<float> blockForceMultiplier, ConfigEntry<float> parryBonusMultiplier, ConfigEntry<float> parryWindowTimeMultiplier, ConfigEntry<float> parryAdrenalineMultiplier, ConfigEntry<float> blockStaminaConsumptionRate, ConfigEntry<float> blockingStaminaRegenMultiplier, ConfigEntry<float> blockBreakThresholdMultiplier, ConfigEntry<float> pvpBlockArmorMultiplier, ConfigEntry<float> pvpBlockForceMultiplier, ConfigEntry<float> pvpParryBonusMultiplier, ConfigEntry<float> pvpBlockBreakThresholdMultiplier, ConfigEntry<bool> soulsLikeBlockBreak, ConfigEntry<bool> soulsLikeBlockStaminaMode, ConfigEntry<float> soulsLikeBlockStaminaBaseRate, ConfigEntry<float> knockbackTakenWhileBlockingMultiplier, ConfigEntry<float> movementModifierPercent, ConfigEntry<float> blockingMovementSpeedMultiplier, ConfigEntry<bool> enableRunningWhileBlocking, ConfigEntry<float> runningWhileBlockingMovementSpeedMultiplier)
			{
				BlockArmorMultiplier = blockArmorMultiplier;
				BlockForceMultiplier = blockForceMultiplier;
				ParryBonusMultiplier = parryBonusMultiplier;
				ParryWindowTimeMultiplier = parryWindowTimeMultiplier;
				ParryAdrenalineMultiplier = parryAdrenalineMultiplier;
				BlockStaminaConsumptionRate = blockStaminaConsumptionRate;
				BlockingStaminaRegenMultiplier = blockingStaminaRegenMultiplier;
				BlockBreakThresholdMultiplier = blockBreakThresholdMultiplier;
				PvpBlockArmorMultiplier = pvpBlockArmorMultiplier;
				PvpBlockForceMultiplier = pvpBlockForceMultiplier;
				PvpParryBonusMultiplier = pvpParryBonusMultiplier;
				PvpBlockBreakThresholdMultiplier = pvpBlockBreakThresholdMultiplier;
				SoulsLikeBlockBreak = soulsLikeBlockBreak;
				SoulsLikeBlockStaminaMode = soulsLikeBlockStaminaMode;
				SoulsLikeBlockStaminaBaseRate = soulsLikeBlockStaminaBaseRate;
				KnockbackTakenWhileBlockingMultiplier = knockbackTakenWhileBlockingMultiplier;
				MovementModifierPercent = movementModifierPercent;
				BlockingMovementSpeedMultiplier = blockingMovementSpeedMultiplier;
				EnableRunningWhileBlocking = enableRunningWhileBlocking;
				RunningWhileBlockingMovementSpeedMultiplier = runningWhileBlockingMovementSpeedMultiplier;
			}
		}

		internal sealed class StaffBlockConfig
		{
			public ConfigEntry<float> BlockArmorMultiplier { get; }

			public ConfigEntry<float> BlockForceMultiplier { get; }

			public ConfigEntry<float> ParryBonusMultiplier { get; }

			public ConfigEntry<float> ParryWindowTimeMultiplier { get; }

			public ConfigEntry<float> ParryAdrenalineMultiplier { get; }

			public ConfigEntry<float> BlockStaminaConsumptionRate { get; }

			public ConfigEntry<float> BlockingStaminaRegenMultiplier { get; }

			public ConfigEntry<float> BlockBreakThresholdMultiplier { get; }

			public ConfigEntry<float> PvpBlockArmorMultiplier { get; }

			public ConfigEntry<float> PvpBlockForceMultiplier { get; }

			public ConfigEntry<float> PvpParryBonusMultiplier { get; }

			public ConfigEntry<float> PvpBlockBreakThresholdMultiplier { get; }

			public ConfigEntry<bool> SoulsLikeBlockBreak { get; }

			public ConfigEntry<bool> SoulsLikeBlockStaminaMode { get; }

			public ConfigEntry<float> SoulsLikeBlockStaminaBaseRate { get; }

			public ConfigEntry<float> KnockbackTakenWhileBlockingMultiplier { get; }

			public ConfigEntry<bool> EnableRunningWhileBlocking { get; }

			public ConfigEntry<float> RunningWhileBlockingMovementSpeedMultiplier { get; }

			public ConfigEntry<float> AttackMovementModifier { get; }

			public ConfigEntry<float> AttackRotationFactor { get; }

			public StaffBlockConfig(ConfigEntry<float> blockArmorMultiplier, ConfigEntry<float> blockForceMultiplier, ConfigEntry<float> parryBonusMultiplier, ConfigEntry<float> parryWindowTimeMultiplier, ConfigEntry<float> parryAdrenalineMultiplier, ConfigEntry<float> blockStaminaConsumptionRate, ConfigEntry<float> blockingStaminaRegenMultiplier, ConfigEntry<float> blockBreakThresholdMultiplier, ConfigEntry<float> pvpBlockArmorMultiplier, ConfigEntry<float> pvpBlockForceMultiplier, ConfigEntry<float> pvpParryBonusMultiplier, ConfigEntry<float> pvpBlockBreakThresholdMultiplier, ConfigEntry<bool> soulsLikeBlockBreak, ConfigEntry<bool> soulsLikeBlockStaminaMode, ConfigEntry<float> soulsLikeBlockStaminaBaseRate, ConfigEntry<float> knockbackTakenWhileBlockingMultiplier, ConfigEntry<bool> enableRunningWhileBlocking, ConfigEntry<float> runningWhileBlockingMovementSpeedMultiplier, ConfigEntry<float> attackMovementModifier, ConfigEntry<float> attackRotationFactor)
			{
				BlockArmorMultiplier = blockArmorMultiplier;
				BlockForceMultiplier = blockForceMultiplier;
				ParryBonusMultiplier = parryBonusMultiplier;
				ParryWindowTimeMultiplier = parryWindowTimeMultiplier;
				ParryAdrenalineMultiplier = parryAdrenalineMultiplier;
				BlockStaminaConsumptionRate = blockStaminaConsumptionRate;
				BlockingStaminaRegenMultiplier = blockingStaminaRegenMultiplier;
				BlockBreakThresholdMultiplier = blockBreakThresholdMultiplier;
				PvpBlockArmorMultiplier = pvpBlockArmorMultiplier;
				PvpBlockForceMultiplier = pvpBlockForceMultiplier;
				PvpParryBonusMultiplier = pvpParryBonusMultiplier;
				PvpBlockBreakThresholdMultiplier = pvpBlockBreakThresholdMultiplier;
				SoulsLikeBlockBreak = soulsLikeBlockBreak;
				SoulsLikeBlockStaminaMode = soulsLikeBlockStaminaMode;
				SoulsLikeBlockStaminaBaseRate = soulsLikeBlockStaminaBaseRate;
				KnockbackTakenWhileBlockingMultiplier = knockbackTakenWhileBlockingMultiplier;
				EnableRunningWhileBlocking = enableRunningWhileBlocking;
				RunningWhileBlockingMovementSpeedMultiplier = runningWhileBlockingMovementSpeedMultiplier;
				AttackMovementModifier = attackMovementModifier;
				AttackRotationFactor = attackRotationFactor;
			}
		}

		internal sealed class StaffShieldActiveConfig
		{
			public ConfigEntry<float> HealthConsumptionRate { get; }

			public ConfigEntry<float> StaggerMitigationMultiplier { get; }

			public ConfigEntry<float> PvpStaggerMitigationMultiplier { get; }

			public ConfigEntry<float> KnockbackMitigationMultiplier { get; }

			public ConfigEntry<float> PvpKnockbackMitigationMultiplier { get; }

			public ConfigEntry<float> ActiveParryBonusMultiplier { get; }

			public StaffShieldActiveConfig(ConfigEntry<float> healthConsumptionRate, ConfigEntry<float> staggerMitigationMultiplier, ConfigEntry<float> pvpStaggerMitigationMultiplier, ConfigEntry<float> knockbackMitigationMultiplier, ConfigEntry<float> pvpKnockbackMitigationMultiplier, ConfigEntry<float> activeParryBonusMultiplier)
			{
				HealthConsumptionRate = healthConsumptionRate;
				StaggerMitigationMultiplier = staggerMitigationMultiplier;
				PvpStaggerMitigationMultiplier = pvpStaggerMitigationMultiplier;
				KnockbackMitigationMultiplier = knockbackMitigationMultiplier;
				PvpKnockbackMitigationMultiplier = pvpKnockbackMitigationMultiplier;
				ActiveParryBonusMultiplier = activeParryBonusMultiplier;
			}
		}

		internal sealed class StaffConfig
		{
			public string PrefabName { get; }

			public bool DirectAttack { get; }

			public ConfigEntry<float>? DamageMultiplier { get; }

			public ConfigEntry<float>? StaggerMultiplier { get; }

			public ConfigEntry<float> AttackAnimationSpeedMultiplier { get; }

			public ConfigEntry<float> EitrRateMultiplier { get; }

			public ConfigEntry<float> AttackStartNoiseMultiplier { get; }

			public ConfigEntry<float> AttackHitNoiseMultiplier { get; }

			public ConfigEntry<float> BackstabDamageMultiplier { get; }

			public ConfigEntry<float>? PvpDamageMultiplier { get; }

			public ConfigEntry<float>? PvpStaggerMultiplier { get; }

			public ConfigEntry<float>? PvpKnockbackForceMultiplier { get; }

			public ConfigEntry<float>? SpreadMultiplier { get; }

			public ConfigEntry<float>? ShieldHealthMultiplier { get; }

			public ConfigEntry<float>? DamageTakenFromPlayersMultiplier { get; }

			public StaffConfig(string prefabName, bool directAttack, ConfigEntry<float>? damageMultiplier, ConfigEntry<float>? staggerMultiplier, ConfigEntry<float> attackAnimationSpeedMultiplier, ConfigEntry<float> eitrRateMultiplier, ConfigEntry<float> attackStartNoiseMultiplier, ConfigEntry<float> attackHitNoiseMultiplier, ConfigEntry<float> backstabDamageMultiplier, ConfigEntry<float>? pvpDamageMultiplier, ConfigEntry<float>? pvpStaggerMultiplier, ConfigEntry<float>? pvpKnockbackForceMultiplier, ConfigEntry<float>? spreadMultiplier, ConfigEntry<float>? shieldHealthMultiplier, ConfigEntry<float>? damageTakenFromPlayersMultiplier)
			{
				PrefabName = prefabName;
				DirectAttack = directAttack;
				DamageMultiplier = damageMultiplier;
				StaggerMultiplier = staggerMultiplier;
				AttackAnimationSpeedMultiplier = attackAnimationSpeedMultiplier;
				EitrRateMultiplier = eitrRateMultiplier;
				AttackStartNoiseMultiplier = attackStartNoiseMultiplier;
				AttackHitNoiseMultiplier = attackHitNoiseMultiplier;
				BackstabDamageMultiplier = backstabDamageMultiplier;
				PvpDamageMultiplier = pvpDamageMultiplier;
				PvpStaggerMultiplier = pvpStaggerMultiplier;
				PvpKnockbackForceMultiplier = pvpKnockbackForceMultiplier;
				SpreadMultiplier = spreadMultiplier;
				ShieldHealthMultiplier = shieldHealthMultiplier;
				DamageTakenFromPlayersMultiplier = damageTakenFromPlayersMultiplier;
			}
		}

		internal sealed class Setting<T>
		{
			private readonly ConfigEntry<T>? _entry;

			private T _value;

			public T Value
			{
				get
				{
					if (_entry == null)
					{
						return _value;
					}
					return _entry.Value;
				}
				set
				{
					if (_entry != null)
					{
						_entry.Value = value;
					}
					else
					{
						_value = value;
					}
				}
			}

			public Setting(ConfigEntry<T> entry)
			{
				_entry = entry;
				_value = entry.Value;
			}

			public Setting(T value)
			{
				_entry = null;
				_value = value;
			}
		}

		internal sealed class RoleSettings<T>
		{
			public Setting<T> Primary1 { get; }

			public Setting<T> Primary2 { get; }

			public Setting<T> Primary3 { get; }

			public Setting<T> Primary4 { get; }

			public Setting<T> Secondary { get; }

			public RoleSettings(Setting<T> primary1, Setting<T> primary2, Setting<T> primary3, Setting<T> secondary, Setting<T>? primary4 = null)
			{
				Primary1 = primary1;
				Primary2 = primary2;
				Primary3 = primary3;
				Primary4 = primary4 ?? primary3;
				Secondary = secondary;
			}

			public Setting<T> Get(AttackRole role)
			{
				return role switch
				{
					AttackRole.Primary2 => Primary2, 
					AttackRole.Primary3 => Primary3, 
					AttackRole.Primary4 => Primary4, 
					AttackRole.Secondary => Secondary, 
					_ => Primary1, 
				};
			}

			public void SetPrimary(T value)
			{
				Primary1.Value = value;
				Primary2.Value = value;
				Primary3.Value = value;
				Primary4.Value = value;
			}

			public void SetAll(T primary, T secondary)
			{
				SetPrimary(primary);
				Secondary.Value = secondary;
			}
		}

		internal sealed class RunningAttackConfig
		{
			public ConfigEntry<bool> Enabled { get; }

			public ConfigEntry<float> MinimumVelocity { get; }

			public ConfigEntry<RunningAttackUsed> UsedAttack { get; }

			public ConfigEntry<float> DamageMultiplier { get; }

			public ConfigEntry<float> StaggerMultiplier { get; }

			public ConfigEntry<float> StaminaRateMultiplier { get; }

			public ConfigEntry<float> AnimationSpeedMultiplier { get; }

			public ConfigEntry<float> RecoveryAnimationSpeedMultiplier { get; }

			public ConfigEntry<BlockCancelMode> BlockCancelMode { get; }

			public ConfigEntry<float> BlockCancelAnimationSpeedMultiplier { get; }

			public ConfigEntry<HyperArmorMode> HyperArmorMode { get; }

			public ConfigEntry<float> DamageTakenMultiplier { get; }

			public ConfigEntry<float> StaggerTakenMultiplier { get; }

			public ConfigEntry<float> KnockbackTakenMultiplier { get; }

			public ConfigEntry<float> PvpDamageTakenMultiplier { get; }

			public ConfigEntry<float> PvpStaggerTakenMultiplier { get; }

			public ConfigEntry<float> PvpKnockbackTakenMultiplier { get; }

			public ConfigEntry<bool> CounterDamageEnabled { get; }

			public ConfigEntry<float> CounterDamageMultiplier { get; }

			public ConfigEntry<float> PvpCounterDamageMultiplier { get; }

			public ConfigEntry<float> HitStopDurationMultiplier { get; }

			public ConfigEntry<float> PvpHitStopDurationMultiplier { get; }

			public ConfigEntry<float> ChopDamageMultiplier { get; }

			public ConfigEntry<float> PickaxeDamageMultiplier { get; }

			public ConfigEntry<float> BackstabDamageMultiplier { get; }

			public ConfigEntry<float> MovementSpeedMultiplier { get; }

			public ConfigEntry<AttackMovementApplicationMode> MovementApplicationMode { get; }

			public ConfigEntry<float> RotationFactor { get; }

			public ConfigEntry<bool> LockRotationAfterAttackTrigger { get; }

			public ConfigEntry<float> PvpDamageMultiplier { get; }

			public ConfigEntry<float> PvpStaggerMultiplier { get; }

			public ConfigEntry<float> PvpStaggerDurationSeconds { get; }

			public ConfigEntry<float> PvpKnockbackForceMultiplier { get; }

			public ConfigEntry<float> KnockbackForceMultiplier { get; }

			public ConfigEntry<float> AdrenalineMultiplier { get; }

			public ConfigEntry<float> LungeDistanceMultiplier { get; }

			public ConfigEntry<LungeApplicationMode> LungeApplicationMode { get; }

			public ConfigEntry<float> StartNoiseMultiplier { get; }

			public ConfigEntry<float> HitNoiseMultiplier { get; }

			public ConfigEntry<float> RangeMultiplier { get; }

			public ConfigEntry<float> RayWidthMultiplier { get; }

			public ConfigEntry<float> HitboxHeightMultiplier { get; }

			public ConfigEntry<float> OffsetMultiplier { get; }

			public ConfigEntry<AttackHitboxType> HitboxType { get; }

			public ConfigEntry<float> AngleMultiplier { get; }

			public ConfigEntry<AttackMultiTargetDamagePenaltyMode> MultiTargetDamagePenalty { get; }

			public RunningAttackConfig(ConfigEntry<bool> enabled, ConfigEntry<float> minimumVelocity, ConfigEntry<RunningAttackUsed> usedAttack, ConfigEntry<float> damageMultiplier, ConfigEntry<float> staggerMultiplier, ConfigEntry<float> staminaRateMultiplier, ConfigEntry<float> animationSpeedMultiplier, ConfigEntry<float> recoveryAnimationSpeedMultiplier, ConfigEntry<BlockCancelMode> blockCancelMode, ConfigEntry<float> blockCancelAnimationSpeedMultiplier, ConfigEntry<HyperArmorMode> hyperArmorMode, ConfigEntry<float> damageTakenMultiplier, ConfigEntry<float> staggerTakenMultiplier, ConfigEntry<float> knockbackTakenMultiplier, ConfigEntry<float> pvpDamageTakenMultiplier, ConfigEntry<float> pvpStaggerTakenMultiplier, ConfigEntry<float> pvpKnockbackTakenMultiplier, ConfigEntry<bool> counterDamageEnabled, ConfigEntry<float> counterDamageMultiplier, ConfigEntry<float> pvpCounterDamageMultiplier, ConfigEntry<float> hitStopDurationMultiplier, ConfigEntry<float> pvpHitStopDurationMultiplier, ConfigEntry<float> chopDamageMultiplier, ConfigEntry<float> pickaxeDamageMultiplier, ConfigEntry<float> backstabDamageMultiplier, ConfigEntry<float> movementSpeedMultiplier, ConfigEntry<AttackMovementApplicationMode> movementApplicationMode, ConfigEntry<float> rotationFactor, ConfigEntry<bool> lockRotationAfterAttackTrigger, ConfigEntry<float> pvpDamageMultiplier, ConfigEntry<float> pvpStaggerMultiplier, ConfigEntry<float> pvpStaggerDurationSeconds, ConfigEntry<float> pvpKnockbackForceMultiplier, ConfigEntry<float> knockbackForceMultiplier, ConfigEntry<float> adrenalineMultiplier, ConfigEntry<float> lungeDistanceMultiplier, ConfigEntry<LungeApplicationMode> lungeApplicationMode, ConfigEntry<float> startNoiseMultiplier, ConfigEntry<float> hitNoiseMultiplier, ConfigEntry<float> rangeMultiplier, ConfigEntry<float> rayWidthMultiplier, ConfigEntry<float> hitboxHeightMultiplier, ConfigEntry<float> offsetMultiplier, ConfigEntry<AttackHitboxType> hitboxType, ConfigEntry<float> angleMultiplier, ConfigEntry<AttackMultiTargetDamagePenaltyMode> multiTargetDamagePenalty)
			{
				Enabled = enabled;
				MinimumVelocity = minimumVelocity;
				UsedAttack = usedAttack;
				DamageMultiplier = damageMultiplier;
				StaggerMultiplier = staggerMultiplier;
				StaminaRateMultiplier = staminaRateMultiplier;
				AnimationSpeedMultiplier = animationSpeedMultiplier;
				RecoveryAnimationSpeedMultiplier = recoveryAnimationSpeedMultiplier;
				BlockCancelMode = blockCancelMode;
				BlockCancelAnimationSpeedMultiplier = blockCancelAnimationSpeedMultiplier;
				HyperArmorMode = hyperArmorMode;
				DamageTakenMultiplier = damageTakenMultiplier;
				StaggerTakenMultiplier = staggerTakenMultiplier;
				KnockbackTakenMultiplier = knockbackTakenMultiplier;
				PvpDamageTakenMultiplier = pvpDamageTakenMultiplier;
				PvpStaggerTakenMultiplier = pvpStaggerTakenMultiplier;
				PvpKnockbackTakenMultiplier = pvpKnockbackTakenMultiplier;
				CounterDamageEnabled = counterDamageEnabled;
				CounterDamageMultiplier = counterDamageMultiplier;
				PvpCounterDamageMultiplier = pvpCounterDamageMultiplier;
				HitStopDurationMultiplier = hitStopDurationMultiplier;
				PvpHitStopDurationMultiplier = pvpHitStopDurationMultiplier;
				ChopDamageMultiplier = chopDamageMultiplier;
				PickaxeDamageMultiplier = pickaxeDamageMultiplier;
				BackstabDamageMultiplier = backstabDamageMultiplier;
				MovementSpeedMultiplier = movementSpeedMultiplier;
				MovementApplicationMode = movementApplicationMode;
				RotationFactor = rotationFactor;
				LockRotationAfterAttackTrigger = lockRotationAfterAttackTrigger;
				PvpDamageMultiplier = pvpDamageMultiplier;
				PvpStaggerMultiplier = pvpStaggerMultiplier;
				PvpStaggerDurationSeconds = pvpStaggerDurationSeconds;
				PvpKnockbackForceMultiplier = pvpKnockbackForceMultiplier;
				KnockbackForceMultiplier = knockbackForceMultiplier;
				AdrenalineMultiplier = adrenalineMultiplier;
				LungeDistanceMultiplier = lungeDistanceMultiplier;
				LungeApplicationMode = lungeApplicationMode;
				StartNoiseMultiplier = startNoiseMultiplier;
				HitNoiseMultiplier = hitNoiseMultiplier;
				RangeMultiplier = rangeMultiplier;
				RayWidthMultiplier = rayWidthMultiplier;
				HitboxHeightMultiplier = hitboxHeightMultiplier;
				OffsetMultiplier = offsetMultiplier;
				HitboxType = hitboxType;
				AngleMultiplier = angleMultiplier;
				MultiTargetDamagePenalty = multiTargetDamagePenalty;
			}
		}

		internal sealed class JumpAttackUsedSetting
		{
			private readonly WeaponCategory _category;

			private readonly ConfigEntry<JumpAttackUsed>? _fullEntry;

			private readonly ConfigEntry<JumpAttackUsedBasic>? _basicEntry;

			public JumpAttackUsed Value
			{
				get
				{
					if (_fullEntry != null)
					{
						return NormalizeJumpAttackUsed(_category, _fullEntry.Value);
					}
					if (_basicEntry == null)
					{
						return DefaultJumpAttackUsed(_category);
					}
					return ToFullJumpAttackUsed(_basicEntry.Value);
				}
				set
				{
					JumpAttackUsed jumpAttackUsed = NormalizeJumpAttackUsed(_category, value);
					if (_fullEntry != null)
					{
						_fullEntry.Value = jumpAttackUsed;
					}
					else if (_basicEntry != null)
					{
						_basicEntry.Value = ToBasicJumpAttackUsed(jumpAttackUsed);
					}
				}
			}

			public JumpAttackUsedSetting(WeaponCategory category, ConfigEntry<JumpAttackUsed> fullEntry)
			{
				_category = category;
				_fullEntry = fullEntry;
			}

			public JumpAttackUsedSetting(WeaponCategory category, ConfigEntry<JumpAttackUsedBasic> basicEntry)
			{
				_category = category;
				_basicEntry = basicEntry;
			}
		}

		internal sealed class JumpAttackConfig
		{
			public ConfigEntry<bool> Enabled { get; }

			public JumpAttackUsedSetting UsedAttack { get; }

			public ConfigEntry<float> DamageMultiplier { get; }

			public ConfigEntry<float> StaggerMultiplier { get; }

			public ConfigEntry<float> StaminaRateMultiplier { get; }

			public ConfigEntry<float> AnimationSpeedMultiplier { get; }

			public ConfigEntry<float> RecoveryAnimationSpeedMultiplier { get; }

			public ConfigEntry<BlockCancelMode> BlockCancelMode { get; }

			public ConfigEntry<float> BlockCancelAnimationSpeedMultiplier { get; }

			public ConfigEntry<HyperArmorMode> HyperArmorMode { get; }

			public ConfigEntry<float> DamageTakenMultiplier { get; }

			public ConfigEntry<float> StaggerTakenMultiplier { get; }

			public ConfigEntry<float> KnockbackTakenMultiplier { get; }

			public ConfigEntry<float> PvpDamageTakenMultiplier { get; }

			public ConfigEntry<float> PvpStaggerTakenMultiplier { get; }

			public ConfigEntry<float> PvpKnockbackTakenMultiplier { get; }

			public ConfigEntry<bool> CounterDamageEnabled { get; }

			public ConfigEntry<float> CounterDamageMultiplier { get; }

			public ConfigEntry<float> PvpCounterDamageMultiplier { get; }

			public ConfigEntry<float> HitStopDurationMultiplier { get; }

			public ConfigEntry<float> PvpHitStopDurationMultiplier { get; }

			public ConfigEntry<float> ChopDamageMultiplier { get; }

			public ConfigEntry<float> PickaxeDamageMultiplier { get; }

			public ConfigEntry<float> BackstabDamageMultiplier { get; }

			public ConfigEntry<float> MovementSpeedMultiplier { get; }

			public ConfigEntry<AttackMovementApplicationMode> MovementApplicationMode { get; }

			public ConfigEntry<float> RotationFactor { get; }

			public ConfigEntry<bool> LockRotationAfterAttackTrigger { get; }

			public ConfigEntry<float> PvpDamageMultiplier { get; }

			public ConfigEntry<float> PvpStaggerMultiplier { get; }

			public ConfigEntry<float> PvpStaggerDurationSeconds { get; }

			public ConfigEntry<float> PvpKnockbackForceMultiplier { get; }

			public ConfigEntry<float> KnockbackForceMultiplier { get; }

			public ConfigEntry<float> AdrenalineMultiplier { get; }

			public ConfigEntry<float> LungeDistanceMultiplier { get; }

			public ConfigEntry<LungeApplicationMode> LungeApplicationMode { get; }

			public ConfigEntry<float> StartNoiseMultiplier { get; }

			public ConfigEntry<float> HitNoiseMultiplier { get; }

			public ConfigEntry<float> RangeMultiplier { get; }

			public ConfigEntry<float> RayWidthMultiplier { get; }

			public ConfigEntry<float> HitboxHeightMultiplier { get; }

			public ConfigEntry<float> OffsetMultiplier { get; }

			public ConfigEntry<AttackHitboxType> HitboxType { get; }

			public ConfigEntry<float> AngleMultiplier { get; }

			public ConfigEntry<AttackMultiTargetDamagePenaltyMode> MultiTargetDamagePenalty { get; }

			public JumpAttackConfig(ConfigEntry<bool> enabled, JumpAttackUsedSetting usedAttack, ConfigEntry<float> damageMultiplier, ConfigEntry<float> staggerMultiplier, ConfigEntry<float> staminaRateMultiplier, ConfigEntry<float> animationSpeedMultiplier, ConfigEntry<float> recoveryAnimationSpeedMultiplier, ConfigEntry<BlockCancelMode> blockCancelMode, ConfigEntry<float> blockCancelAnimationSpeedMultiplier, ConfigEntry<HyperArmorMode> hyperArmorMode, ConfigEntry<float> damageTakenMultiplier, ConfigEntry<float> staggerTakenMultiplier, ConfigEntry<float> knockbackTakenMultiplier, ConfigEntry<float> pvpDamageTakenMultiplier, ConfigEntry<float> pvpStaggerTakenMultiplier, ConfigEntry<float> pvpKnockbackTakenMultiplier, ConfigEntry<bool> counterDamageEnabled, ConfigEntry<float> counterDamageMultiplier, ConfigEntry<float> pvpCounterDamageMultiplier, ConfigEntry<float> hitStopDurationMultiplier, ConfigEntry<float> pvpHitStopDurationMultiplier, ConfigEntry<float> chopDamageMultiplier, ConfigEntry<float> pickaxeDamageMultiplier, ConfigEntry<float> backstabDamageMultiplier, ConfigEntry<float> movementSpeedMultiplier, ConfigEntry<AttackMovementApplicationMode> movementApplicationMode, ConfigEntry<float> rotationFactor, ConfigEntry<bool> lockRotationAfterAttackTrigger, ConfigEntry<float> pvpDamageMultiplier, ConfigEntry<float> pvpStaggerMultiplier, ConfigEntry<float> pvpStaggerDurationSeconds, ConfigEntry<float> pvpKnockbackForceMultiplier, ConfigEntry<float> knockbackForceMultiplier, ConfigEntry<float> adrenalineMultiplier, ConfigEntry<float> lungeDistanceMultiplier, ConfigEntry<LungeApplicationMode> lungeApplicationMode, ConfigEntry<float> startNoiseMultiplier, ConfigEntry<float> hitNoiseMultiplier, ConfigEntry<float> rangeMultiplier, ConfigEntry<float> rayWidthMultiplier, ConfigEntry<float> hitboxHeightMultiplier, ConfigEntry<float> offsetMultiplier, ConfigEntry<AttackHitboxType> hitboxType, ConfigEntry<float> angleMultiplier, ConfigEntry<AttackMultiTargetDamagePenaltyMode> multiTargetDamagePenalty)
			{
				Enabled = enabled;
				UsedAttack = usedAttack;
				DamageMultiplier = damageMultiplier;
				StaggerMultiplier = staggerMultiplier;
				StaminaRateMultiplier = staminaRateMultiplier;
				AnimationSpeedMultiplier = animationSpeedMultiplier;
				RecoveryAnimationSpeedMultiplier = recoveryAnimationSpeedMultiplier;
				BlockCancelMode = blockCancelMode;
				BlockCancelAnimationSpeedMultiplier = blockCancelAnimationSpeedMultiplier;
				HyperArmorMode = hyperArmorMode;
				DamageTakenMultiplier = damageTakenMultiplier;
				StaggerTakenMultiplier = staggerTakenMultiplier;
				KnockbackTakenMultiplier = knockbackTakenMultiplier;
				PvpDamageTakenMultiplier = pvpDamageTakenMultiplier;
				PvpStaggerTakenMultiplier = pvpStaggerTakenMultiplier;
				PvpKnockbackTakenMultiplier = pvpKnockbackTakenMultiplier;
				CounterDamageEnabled = counterDamageEnabled;
				CounterDamageMultiplier = counterDamageMultiplier;
				PvpCounterDamageMultiplier = pvpCounterDamageMultiplier;
				HitStopDurationMultiplier = hitStopDurationMultiplier;
				PvpHitStopDurationMultiplier = pvpHitStopDurationMultiplier;
				ChopDamageMultiplier = chopDamageMultiplier;
				PickaxeDamageMultiplier = pickaxeDamageMultiplier;
				BackstabDamageMultiplier = backstabDamageMultiplier;
				MovementSpeedMultiplier = movementSpeedMultiplier;
				MovementApplicationMode = movementApplicationMode;
				RotationFactor = rotationFactor;
				LockRotationAfterAttackTrigger = lockRotationAfterAttackTrigger;
				PvpDamageMultiplier = pvpDamageMultiplier;
				PvpStaggerMultiplier = pvpStaggerMultiplier;
				PvpStaggerDurationSeconds = pvpStaggerDurationSeconds;
				PvpKnockbackForceMultiplier = pvpKnockbackForceMultiplier;
				KnockbackForceMultiplier = knockbackForceMultiplier;
				AdrenalineMultiplier = adrenalineMultiplier;
				LungeDistanceMultiplier = lungeDistanceMultiplier;
				LungeApplicationMode = lungeApplicationMode;
				StartNoiseMultiplier = startNoiseMultiplier;
				HitNoiseMultiplier = hitNoiseMultiplier;
				RangeMultiplier = rangeMultiplier;
				RayWidthMultiplier = rayWidthMultiplier;
				HitboxHeightMultiplier = hitboxHeightMultiplier;
				OffsetMultiplier = offsetMultiplier;
				HitboxType = hitboxType;
				AngleMultiplier = angleMultiplier;
				MultiTargetDamagePenalty = multiTargetDamagePenalty;
			}
		}

		internal sealed class CategoryConfig
		{
			public Setting<float> BaseDamageMultiplier { get; }

			public RoleSettings<StaggerApplicationMode> StaggerMode { get; }

			public RoleSettings<float> StaggerPowerValue { get; }

			public RoleSettings<float> DamageToStaggeredEnemyMultiplier { get; }

			public RoleSettings<HyperArmorMode> HyperArmorMode { get; }

			public RoleSettings<float> DamageTakenMultiplier { get; }

			public RoleSettings<float> StaggerTakenMultiplier { get; }

			public RoleSettings<float> KnockbackTakenMultiplier { get; }

			public RoleSettings<float> PvpDamageTakenMultiplierDuringHyperArmor { get; }

			public RoleSettings<float> PvpStaggerTakenMultiplierDuringHyperArmor { get; }

			public RoleSettings<float> PvpKnockbackTakenMultiplierDuringHyperArmor { get; }

			public RoleSettings<float> HitStopDurationMultiplier { get; }

			public RoleSettings<float> PvpHitStopDurationMultiplier { get; }

			public RoleSettings<bool> CounterDamageEnabled { get; }

			public RoleSettings<float> CounterDamageMultiplier { get; }

			public RoleSettings<float> PvpCounterDamageMultiplier { get; }

			public RoleSettings<float> DamageRateMultiplier { get; }

			public RoleSettings<float> ChopDamageMultiplier { get; }

			public RoleSettings<float> PickaxeDamageMultiplier { get; }

			public RoleSettings<float> AirborneDamageMultiplier { get; }

			public RoleSettings<float> AirborneStaggerMultiplier { get; }

			public RoleSettings<float> AirborneRotationFactor { get; }

			public RoleSettings<float> StaminaRateMultiplier { get; }

			public RoleSettings<float> EitrRateMultiplier { get; }

			public RoleSettings<float> AttackMovementModifier { get; }

			public RoleSettings<AttackMovementApplicationMode> AttackMovementApplicationMode { get; }

			public RoleSettings<float> LungeDistanceMultiplier { get; }

			public RoleSettings<LungeApplicationMode> LungeApplicationMode { get; }

			public RoleSettings<float> AttackAnimationSpeedMultiplier { get; }

			public RoleSettings<float> RecoveryAnimationSpeedMultiplier { get; }

			public RoleSettings<float> AttackRotationFactor { get; }

			public RoleSettings<bool> LockRotationAfterAttackTrigger { get; }

			public RoleSettings<float> AdrenalineMultiplier { get; }

			public RoleSettings<float> PvpDamageMultiplier { get; }

			public RoleSettings<float> PvpStaggerMultiplier { get; }

			public RoleSettings<float> PvpStaggerDurationSeconds { get; }

			public RoleSettings<float> PvpKnockbackForceMultiplier { get; }

			public RoleSettings<float> KnockbackForceMultiplier { get; }

			public Setting<float> PvpBlockArmorMultiplier { get; }

			public Setting<float> BlockArmorMultiplier { get; }

			public Setting<float> BlockForceMultiplier { get; }

			public Setting<float> BlockStaminaConsumptionRate { get; }

			public Setting<float> BlockingStaminaRegenMultiplier { get; }

			public Setting<float> BlockBreakThresholdMultiplier { get; }

			public RoleSettings<float> FullAttackDuration { get; }

			public RoleSettings<BlockCancelMode> BlockCancelMode { get; }

			public RoleSettings<float> BlockCancelAnimationSpeedMultiplier { get; }

			public WeaponCategory Category { get; }

			public Setting<StaggerApplicationMode> PrimaryStaggerMode => StaggerMode.Primary1;

			public Setting<float> PrimaryStaggerPowerValue => StaggerPowerValue.Primary1;

			public Setting<StaggerApplicationMode> SecondaryStaggerMode => StaggerMode.Secondary;

			public Setting<float> SecondaryStaggerPowerValue => StaggerPowerValue.Secondary;

			public Setting<HyperArmorMode> PrimaryHyperArmorMode => HyperArmorMode.Primary1;

			public Setting<HyperArmorMode> SecondaryHyperArmorMode => HyperArmorMode.Secondary;

			public Setting<float> PrimaryDamageTakenMultiplier => DamageTakenMultiplier.Primary1;

			public Setting<float> SecondaryDamageTakenMultiplier => DamageTakenMultiplier.Secondary;

			public Setting<float> PrimaryStaggerTakenMultiplier => StaggerTakenMultiplier.Primary1;

			public Setting<float> SecondaryStaggerTakenMultiplier => StaggerTakenMultiplier.Secondary;

			public Setting<float> PrimaryKnockbackTakenMultiplier => KnockbackTakenMultiplier.Primary1;

			public Setting<float> SecondaryKnockbackTakenMultiplier => KnockbackTakenMultiplier.Secondary;

			public Setting<float> PrimaryPvpDamageTakenMultiplierDuringHyperArmor => PvpDamageTakenMultiplierDuringHyperArmor.Primary1;

			public Setting<float> SecondaryPvpDamageTakenMultiplierDuringHyperArmor => PvpDamageTakenMultiplierDuringHyperArmor.Secondary;

			public Setting<float> PrimaryPvpStaggerTakenMultiplierDuringHyperArmor => PvpStaggerTakenMultiplierDuringHyperArmor.Primary1;

			public Setting<float> SecondaryPvpStaggerTakenMultiplierDuringHyperArmor => PvpStaggerTakenMultiplierDuringHyperArmor.Secondary;

			public Setting<float> PrimaryPvpKnockbackTakenMultiplierDuringHyperArmor => PvpKnockbackTakenMultiplierDuringHyperArmor.Primary1;

			public Setting<float> SecondaryPvpKnockbackTakenMultiplierDuringHyperArmor => PvpKnockbackTakenMultiplierDuringHyperArmor.Secondary;

			public Setting<bool> PrimaryCounterDamageEnabled => CounterDamageEnabled.Primary1;

			public Setting<float> PrimaryCounterDamageMultiplier => CounterDamageMultiplier.Primary1;

			public Setting<bool> SecondaryCounterDamageEnabled => CounterDamageEnabled.Secondary;

			public Setting<float> SecondaryCounterDamageMultiplier => CounterDamageMultiplier.Secondary;

			public Setting<float> PrimaryPvpCounterDamageMultiplier => PvpCounterDamageMultiplier.Primary1;

			public Setting<float> SecondaryPvpCounterDamageMultiplier => PvpCounterDamageMultiplier.Secondary;

			public Setting<float> PrimaryDamageRateMultiplier => DamageRateMultiplier.Primary1;

			public Setting<float> SecondaryDamageRateMultiplier => DamageRateMultiplier.Secondary;

			public Setting<float> PrimaryChopDamageMultiplier => ChopDamageMultiplier.Primary1;

			public Setting<float> SecondaryChopDamageMultiplier => ChopDamageMultiplier.Secondary;

			public Setting<float> PrimaryPickaxeDamageMultiplier => PickaxeDamageMultiplier.Primary1;

			public Setting<float> SecondaryPickaxeDamageMultiplier => PickaxeDamageMultiplier.Secondary;

			public Setting<float> PrimaryAirborneDamageMultiplier => AirborneDamageMultiplier.Primary1;

			public Setting<float> SecondaryAirborneDamageMultiplier => AirborneDamageMultiplier.Secondary;

			public Setting<float> PrimaryAirborneStaggerMultiplier => AirborneStaggerMultiplier.Primary1;

			public Setting<float> SecondaryAirborneStaggerMultiplier => AirborneStaggerMultiplier.Secondary;

			public Setting<float> PrimaryAirborneRotationFactor => AirborneRotationFactor.Primary1;

			public Setting<float> SecondaryAirborneRotationFactor => AirborneRotationFactor.Secondary;

			public Setting<float> PrimaryStaminaRateMultiplier => StaminaRateMultiplier.Primary1;

			public Setting<float> SecondaryStaminaRateMultiplier => StaminaRateMultiplier.Secondary;

			public Setting<float> PrimaryEitrRateMultiplier => EitrRateMultiplier.Primary1;

			public Setting<float> SecondaryEitrRateMultiplier => EitrRateMultiplier.Secondary;

			public Setting<float> PrimaryAttackMovementModifier => AttackMovementModifier.Primary1;

			public Setting<float> SecondaryAttackMovementModifier => AttackMovementModifier.Secondary;

			public Setting<float> PrimaryLungeDistanceMultiplier => LungeDistanceMultiplier.Primary1;

			public Setting<float> SecondaryLungeDistanceMultiplier => LungeDistanceMultiplier.Secondary;

			public Setting<float> PrimaryAttackAnimationSpeedMultiplier => AttackAnimationSpeedMultiplier.Primary1;

			public Setting<float> SecondaryAttackAnimationSpeedMultiplier => AttackAnimationSpeedMultiplier.Secondary;

			public Setting<float> PrimaryRecoveryAnimationSpeedMultiplier => RecoveryAnimationSpeedMultiplier.Primary1;

			public Setting<float> SecondaryRecoveryAnimationSpeedMultiplier => RecoveryAnimationSpeedMultiplier.Secondary;

			public Setting<float> PrimaryAttackRotationFactor => AttackRotationFactor.Primary1;

			public Setting<float> SecondaryAttackRotationFactor => AttackRotationFactor.Secondary;

			public Setting<bool> PrimaryLockRotationAfterAttackTrigger => LockRotationAfterAttackTrigger.Primary1;

			public Setting<bool> SecondaryLockRotationAfterAttackTrigger => LockRotationAfterAttackTrigger.Secondary;

			public Setting<float> PrimaryAdrenalineMultiplier => AdrenalineMultiplier.Primary1;

			public Setting<float> SecondaryAdrenalineMultiplier => AdrenalineMultiplier.Secondary;

			public Setting<float> PrimaryPvpDamageMultiplier => PvpDamageMultiplier.Primary1;

			public Setting<float> SecondaryPvpDamageMultiplier => PvpDamageMultiplier.Secondary;

			public Setting<float> PrimaryPvpStaggerMultiplier => PvpStaggerMultiplier.Primary1;

			public Setting<float> SecondaryPvpStaggerMultiplier => PvpStaggerMultiplier.Secondary;

			public Setting<float> PrimaryPvpStaggerDurationSeconds => PvpStaggerDurationSeconds.Primary1;

			public Setting<float> SecondaryPvpStaggerDurationSeconds => PvpStaggerDurationSeconds.Secondary;

			public Setting<float> PrimaryPvpKnockbackForceMultiplier => PvpKnockbackForceMultiplier.Primary1;

			public Setting<float> SecondaryPvpKnockbackForceMultiplier => PvpKnockbackForceMultiplier.Secondary;

			public Setting<float> PrimaryKnockbackForceMultiplier => KnockbackForceMultiplier.Primary1;

			public Setting<float> SecondaryKnockbackForceMultiplier => KnockbackForceMultiplier.Secondary;

			public Setting<float> PrimaryFullAttackDuration => FullAttackDuration.Primary1;

			public Setting<float> SecondaryFullAttackDuration => FullAttackDuration.Secondary;

			public Setting<BlockCancelMode> PrimaryBlockCancelMode => BlockCancelMode.Primary1;

			public Setting<BlockCancelMode> SecondaryBlockCancelMode => BlockCancelMode.Secondary;

			public CategoryConfig(WeaponCategory category, Setting<float> baseDamageMultiplier, RoleSettings<StaggerApplicationMode> staggerMode, RoleSettings<float> staggerPowerValue, RoleSettings<float> damageToStaggeredEnemyMultiplier, RoleSettings<HyperArmorMode> hyperArmorMode, RoleSettings<float> damageTakenMultiplier, RoleSettings<float> staggerTakenMultiplier, RoleSettings<float> knockbackTakenMultiplier, RoleSettings<float> pvpDamageTakenMultiplierDuringHyperArmor, RoleSettings<float> pvpStaggerTakenMultiplierDuringHyperArmor, RoleSettings<float> pvpKnockbackTakenMultiplierDuringHyperArmor, RoleSettings<float> hitStopDurationMultiplier, RoleSettings<float> pvpHitStopDurationMultiplier, RoleSettings<bool> counterDamageEnabled, RoleSettings<float> counterDamageMultiplier, RoleSettings<float> pvpCounterDamageMultiplier, RoleSettings<float> damageRateMultiplier, RoleSettings<float> chopDamageMultiplier, RoleSettings<float> pickaxeDamageMultiplier, RoleSettings<float> airborneDamageMultiplier, RoleSettings<float> airborneStaggerMultiplier, RoleSettings<float> airborneRotationFactor, RoleSettings<float> staminaRateMultiplier, RoleSettings<float> eitrRateMultiplier, RoleSettings<float> attackMovementSpeedMultiplier, RoleSettings<AttackMovementApplicationMode> attackMovementApplicationMode, RoleSettings<float> lungeDistanceMultiplier, RoleSettings<LungeApplicationMode> lungeApplicationMode, RoleSettings<float> attackAnimationSpeedMultiplier, RoleSettings<float> recoveryAnimationSpeedMultiplier, RoleSettings<float> attackRotationFactor, RoleSettings<bool> lockRotationAfterAttackTrigger, RoleSettings<float> adrenalineMultiplier, RoleSettings<float> pvpDamageMultiplier, RoleSettings<float> pvpStaggerMultiplier, RoleSettings<float> pvpStaggerDurationSeconds, RoleSettings<float> pvpKnockbackForceMultiplier, RoleSettings<float> knockbackForceMultiplier, Setting<float> pvpBlockArmorMultiplier, Setting<float> blockPowerMultiplier, Setting<float> deflectionForceMultiplier, Setting<float> blockStaminaConsumptionRate, Setting<float> blockingStaminaRegenMultiplier, Setting<float> blockBreakThresholdMultiplier, RoleSettings<BlockCancelMode> blockCancelMode, RoleSettings<float> blockCancelAnimationSpeedMultiplier, RoleSettings<float> fullAttackDuration)
			{
				Category = category;
				BaseDamageMultiplier = baseDamageMultiplier;
				StaggerMode = staggerMode;
				StaggerPowerValue = staggerPowerValue;
				DamageToStaggeredEnemyMultiplier = damageToStaggeredEnemyMultiplier;
				HyperArmorMode = hyperArmorMode;
				DamageTakenMultiplier = damageTakenMultiplier;
				StaggerTakenMultiplier = staggerTakenMultiplier;
				KnockbackTakenMultiplier = knockbackTakenMultiplier;
				PvpDamageTakenMultiplierDuringHyperArmor = pvpDamageTakenMultiplierDuringHyperArmor;
				PvpStaggerTakenMultiplierDuringHyperArmor = pvpStaggerTakenMultiplierDuringHyperArmor;
				PvpKnockbackTakenMultiplierDuringHyperArmor = pvpKnockbackTakenMultiplierDuringHyperArmor;
				HitStopDurationMultiplier = hitStopDurationMultiplier;
				PvpHitStopDurationMultiplier = pvpHitStopDurationMultiplier;
				CounterDamageEnabled = counterDamageEnabled;
				CounterDamageMultiplier = counterDamageMultiplier;
				PvpCounterDamageMultiplier = pvpCounterDamageMultiplier;
				DamageRateMultiplier = damageRateMultiplier;
				ChopDamageMultiplier = chopDamageMultiplier;
				PickaxeDamageMultiplier = pickaxeDamageMultiplier;
				AirborneDamageMultiplier = airborneDamageMultiplier;
				AirborneStaggerMultiplier = airborneStaggerMultiplier;
				AirborneRotationFactor = airborneRotationFactor;
				StaminaRateMultiplier = staminaRateMultiplier;
				EitrRateMultiplier = eitrRateMultiplier;
				AttackMovementModifier = attackMovementSpeedMultiplier;
				AttackMovementApplicationMode = attackMovementApplicationMode;
				LungeDistanceMultiplier = lungeDistanceMultiplier;
				LungeApplicationMode = lungeApplicationMode;
				AttackAnimationSpeedMultiplier = attackAnimationSpeedMultiplier;
				RecoveryAnimationSpeedMultiplier = recoveryAnimationSpeedMultiplier;
				AttackRotationFactor = attackRotationFactor;
				LockRotationAfterAttackTrigger = lockRotationAfterAttackTrigger;
				AdrenalineMultiplier = adrenalineMultiplier;
				PvpDamageMultiplier = pvpDamageMultiplier;
				PvpStaggerMultiplier = pvpStaggerMultiplier;
				PvpStaggerDurationSeconds = pvpStaggerDurationSeconds;
				PvpKnockbackForceMultiplier = pvpKnockbackForceMultiplier;
				KnockbackForceMultiplier = knockbackForceMultiplier;
				PvpBlockArmorMultiplier = pvpBlockArmorMultiplier;
				BlockArmorMultiplier = blockPowerMultiplier;
				BlockForceMultiplier = deflectionForceMultiplier;
				BlockStaminaConsumptionRate = blockStaminaConsumptionRate;
				BlockingStaminaRegenMultiplier = blockingStaminaRegenMultiplier;
				BlockBreakThresholdMultiplier = blockBreakThresholdMultiplier;
				BlockCancelMode = blockCancelMode;
				BlockCancelAnimationSpeedMultiplier = blockCancelAnimationSpeedMultiplier;
				FullAttackDuration = fullAttackDuration;
			}

			public float GetBaseDamageMultiplier()
			{
				if (!IsFeatureApplied(Category, ModFeature.Damage))
				{
					return 1f;
				}
				return BaseDamageMultiplier.Value;
			}

			public float GetBlockStaminaConsumptionRate()
			{
				if (!IsFeatureApplied(Category, ModFeature.Blocking))
				{
					return 1f;
				}
				return BlockStaminaConsumptionRate.Value;
			}

			public float GetBlockingStaminaRegenMultiplier()
			{
				if (!IsFeatureApplied(Category, ModFeature.Blocking))
				{
					return 1f;
				}
				return BlockingStaminaRegenMultiplier.Value;
			}

			public float GetBlockBreakThresholdMultiplier()
			{
				if (!IsFeatureApplied(Category, ModFeature.Blocking))
				{
					return 1f;
				}
				return BlockBreakThresholdMultiplier.Value;
			}

			public StaggerApplicationMode GetStaggerMode(AttackRole role)
			{
				if (!IsFeatureApplied(Category, ModFeature.Staggering))
				{
					return StaggerApplicationMode.MultiplyVanilla;
				}
				return StaggerMode.Get(role).Value;
			}

			public float GetStaggerPowerValue(AttackRole role)
			{
				if (!IsFeatureApplied(Category, ModFeature.Staggering))
				{
					return 1f;
				}
				return StaggerPowerValue.Get(role).Value;
			}

			public float GetDamageToStaggeredEnemyMultiplier(AttackRole role)
			{
				if (!IsFeatureApplied(Category, ModFeature.Staggering))
				{
					return 1f;
				}
				return DamageToStaggeredEnemyMultiplier.Get(role).Value;
			}

			public HyperArmorMode GetHyperArmorMode(AttackRole role)
			{
				if (!IsFeatureApplied(Category, ModFeature.HyperArmor))
				{
					return GooCombatOverhaul.HyperArmorMode.Off;
				}
				return HyperArmorMode.Get(role).Value;
			}

			public float GetDamageTakenMultiplier(AttackRole role)
			{
				if (!IsFeatureApplied(Category, ModFeature.HyperArmor))
				{
					return 1f;
				}
				return DamageTakenMultiplier.Get(role).Value;
			}

			public float GetStaggerTakenMultiplier(AttackRole role)
			{
				if (!IsFeatureApplied(Category, ModFeature.HyperArmor))
				{
					return 1f;
				}
				return StaggerTakenMultiplier.Get(role).Value;
			}

			public float GetKnockbackTakenMultiplier(AttackRole role)
			{
				if (!IsFeatureApplied(Category, ModFeature.HyperArmor))
				{
					return 1f;
				}
				return KnockbackTakenMultiplier.Get(role).Value;
			}

			public float GetPvpDamageTakenMultiplierDuringHyperArmor(AttackRole role)
			{
				if (!IsFeatureApplied(Category, ModFeature.HyperArmor))
				{
					return 1f;
				}
				return PvpDamageTakenMultiplierDuringHyperArmor.Get(role).Value;
			}

			public float GetPvpStaggerTakenMultiplierDuringHyperArmor(AttackRole role)
			{
				if (!IsFeatureApplied(Category, ModFeature.HyperArmor))
				{
					return 1f;
				}
				return PvpStaggerTakenMultiplierDuringHyperArmor.Get(role).Value;
			}

			public float GetPvpKnockbackTakenMultiplierDuringHyperArmor(AttackRole role)
			{
				if (!IsFeatureApplied(Category, ModFeature.HyperArmor))
				{
					return 1f;
				}
				return PvpKnockbackTakenMultiplierDuringHyperArmor.Get(role).Value;
			}

			public bool GetHitStopOnHit(AttackRole role)
			{
				if (IsFeatureApplied(Category, ModFeature.HitStop))
				{
					return GetHitStopDurationMultiplier(role) > 0f;
				}
				return false;
			}

			public float GetHitStopDurationMultiplier(AttackRole role)
			{
				if (!IsFeatureApplied(Category, ModFeature.HitStop))
				{
					return 1f;
				}
				return HitStopDurationMultiplier.Get(role).Value;
			}

			public float GetPvpHitStopDurationMultiplier(AttackRole role)
			{
				if (!IsFeatureApplied(Category, ModFeature.HitStop))
				{
					return 1f;
				}
				return PvpHitStopDurationMultiplier.Get(role).Value;
			}

			public bool GetCounterDamageEnabled(AttackRole role)
			{
				if (IsFeatureApplied(Category, ModFeature.CounterDamage))
				{
					return CounterDamageEnabled.Get(role).Value;
				}
				return false;
			}

			public float GetCounterDamageMultiplier(AttackRole role)
			{
				if (!IsFeatureApplied(Category, ModFeature.CounterDamage))
				{
					return 1f;
				}
				return CounterDamageMultiplier.Get(role).Value;
			}

			public float GetPvpCounterDamageMultiplier(AttackRole role)
			{
				if (!IsFeatureApplied(Category, ModFeature.CounterDamage))
				{
					return 1f;
				}
				return PvpCounterDamageMultiplier.Get(role).Value;
			}

			public float GetDamageRateMultiplier(AttackRole role)
			{
				if (!IsFeatureApplied(Category, ModFeature.Damage))
				{
					return 1f;
				}
				return DamageRateMultiplier.Get(role).Value;
			}

			public float GetChopDamageMultiplier(AttackRole role)
			{
				if (!IsFeatureApplied(Category, ModFeature.Damage))
				{
					return DefaultChopDamageMultiplier(Category);
				}
				return ChopDamageMultiplier.Get(role).Value;
			}

			public float GetPickaxeDamageMultiplier(AttackRole role)
			{
				if (!IsFeatureApplied(Category, ModFeature.Damage))
				{
					return VanillaPickaxeDamageMultiplier(Category);
				}
				return PickaxeDamageMultiplier.Get(role).Value;
			}

			public float GetAirborneDamageMultiplier(AttackRole role)
			{
				if (!IsFeatureApplied(Category, ModFeature.Damage))
				{
					return 1f;
				}
				return AirborneDamageMultiplier.Get(role).Value;
			}

			public float GetAirborneStaggerMultiplier(AttackRole role)
			{
				if (!IsWeaponCategoryApplied(Category))
				{
					return 1f;
				}
				return AirborneStaggerMultiplier.Get(role).Value;
			}

			public float GetAirborneRotationFactor(AttackRole role)
			{
				if (!IsFeatureApplied(Category, ModFeature.AttackRotation))
				{
					return 1f;
				}
				return AirborneRotationFactor.Get(role).Value;
			}

			public float GetStaminaRateMultiplier(AttackRole role)
			{
				if (!IsFeatureApplied(Category, ModFeature.Resources))
				{
					return 1f;
				}
				return StaminaRateMultiplier.Get(role).Value;
			}

			public float GetEitrRateMultiplier(AttackRole role)
			{
				if (!IsFeatureApplied(Category, ModFeature.Resources))
				{
					return 1f;
				}
				return EitrRateMultiplier.Get(role).Value;
			}

			public float GetAttackMovementModifier(AttackRole role)
			{
				if (!IsFeatureApplied(Category, ModFeature.AttackMovement))
				{
					return 1f;
				}
				return AttackMovementModifier.Get(role).Value;
			}

			public AttackMovementApplicationMode GetAttackMovementApplicationMode(AttackRole role)
			{
				if (!IsFeatureApplied(Category, ModFeature.AttackMovement))
				{
					return GooCombatOverhaul.AttackMovementApplicationMode.FullAnimation;
				}
				return AttackMovementApplicationMode.Get(role).Value;
			}

			public float GetLungeDistanceMultiplier(AttackRole role)
			{
				if (!IsFeatureApplied(Category, ModFeature.AttackMovement))
				{
					return 1f;
				}
				return LungeDistanceMultiplier.Get(role).Value;
			}

			public LungeApplicationMode GetLungeApplicationMode(AttackRole role)
			{
				if (!IsFeatureApplied(Category, ModFeature.AttackMovement))
				{
					return GooCombatOverhaul.LungeApplicationMode.BeforeHitbox;
				}
				return LungeApplicationMode.Get(role).Value;
			}

			public float GetAttackAnimationSpeedMultiplier(AttackRole role)
			{
				if (!IsWeaponCategoryApplied(Category))
				{
					return 1f;
				}
				return AttackAnimationSpeedMultiplier.Get(role).Value;
			}

			public float GetRecoveryAnimationSpeedMultiplier(AttackRole role)
			{
				if (!IsWeaponCategoryApplied(Category))
				{
					return 1f;
				}
				return RecoveryAnimationSpeedMultiplier.Get(role).Value;
			}

			public float GetAttackRotationFactor(AttackRole role)
			{
				if (!IsFeatureApplied(Category, ModFeature.AttackRotation))
				{
					return 1f;
				}
				return AttackRotationFactor.Get(role).Value;
			}

			public bool GetLockRotationAfterAttackTrigger(AttackRole role)
			{
				if (IsFeatureApplied(Category, ModFeature.AttackRotation))
				{
					return LockRotationAfterAttackTrigger.Get(role).Value;
				}
				return false;
			}

			public float GetAdrenalineMultiplier(AttackRole role)
			{
				if (!IsFeatureApplied(Category, ModFeature.Resources))
				{
					return 1f;
				}
				return AdrenalineMultiplier.Get(role).Value;
			}

			public float GetPvpDamageMultiplier(AttackRole role)
			{
				if (!IsFeatureApplied(Category, ModFeature.Pvp))
				{
					return 1f;
				}
				return PvpDamageMultiplier.Get(role).Value;
			}

			public float GetPvpStaggerMultiplier(AttackRole role)
			{
				if (!IsFeatureApplied(Category, ModFeature.Pvp))
				{
					return 1f;
				}
				return PvpStaggerMultiplier.Get(role).Value;
			}

			public float GetPvpStaggerDurationSeconds(AttackRole role)
			{
				if (!IsFeatureApplied(Category, ModFeature.Pvp))
				{
					return DefaultPvpStaggerDuration(Category, role);
				}
				return PvpStaggerDurationSeconds.Get(role).Value;
			}

			public float GetPvpKnockbackForceMultiplier(AttackRole role)
			{
				if (!IsFeatureApplied(Category, ModFeature.Pvp))
				{
					return 1f;
				}
				return PvpKnockbackForceMultiplier.Get(role).Value;
			}

			public float GetKnockbackForceMultiplier(AttackRole role)
			{
				if (!IsWeaponCategoryApplied(Category))
				{
					return 1f;
				}
				return KnockbackForceMultiplier.Get(role).Value;
			}

			public float GetFullAttackDuration(AttackRole role)
			{
				if (!IsWeaponCategoryApplied(Category))
				{
					return 0f;
				}
				return FullAttackDuration.Get(role).Value;
			}

			public BlockCancelMode GetBlockCancelMode(AttackRole role)
			{
				if (!IsWeaponCategoryApplied(Category))
				{
					return GooCombatOverhaul.BlockCancelMode.Disabled;
				}
				return BlockCancelMode.Get(role).Value;
			}

			public float GetBlockCancelAnimationSpeedMultiplier(AttackRole role)
			{
				if (!IsWeaponCategoryApplied(Category))
				{
					return 1f;
				}
				return BlockCancelAnimationSpeedMultiplier.Get(role).Value;
			}
		}

		private readonly struct SuppressedFieldValue
		{
			public object Target { get; }

			public FieldInfo Field { get; }

			public object? OriginalValue { get; }

			public SuppressedFieldValue(object target, FieldInfo field, object? originalValue)
			{
				Target = target;
				Field = field;
				OriginalValue = originalValue;
			}
		}

		private readonly struct CounterVulnerableState
		{
			public object? AttackInstance { get; }

			public CounterVulnerableState(object? attackInstance)
			{
				AttackInstance = attackInstance;
			}
		}

		private readonly struct AttackRuntimeState
		{
			public WeaponCategory Category { get; }

			public AttackRole Role { get; }

			public float EndTime { get; }

			public object? AttackInstance { get; }

			public bool StartedAirborne { get; }

			public bool IsPvpHitStop { get; }

			public AttackRuntimeState(WeaponCategory category, AttackRole role, float endTime, object? attackInstance, bool startedAirborne = false, bool isPvpHitStop = false)
			{
				Category = category;
				Role = role;
				EndTime = endTime;
				AttackInstance = attackInstance;
				StartedAirborne = startedAirborne;
				IsPvpHitStop = isPvpHitStop;
			}
		}

		private readonly struct PendingAttackRoleState
		{
			public AttackRole Role { get; }

			public float EndTime { get; }

			public PendingAttackRoleState(AttackRole role, float endTime)
			{
				Role = role;
				EndTime = endTime;
			}
		}

		private readonly struct HyperArmorRuntimeState
		{
			public WeaponCategory Category { get; }

			public AttackRole Role { get; }

			public HyperArmorMode Mode { get; }

			public float EndTime { get; }

			public object? AttackInstance { get; }

			public HyperArmorRuntimeState(WeaponCategory category, AttackRole role, HyperArmorMode mode, float endTime, object? attackInstance)
			{
				Category = category;
				Role = role;
				Mode = mode;
				EndTime = endTime;
				AttackInstance = attackInstance;
			}
		}

		private sealed class CharacterRuntimeDefaults
		{
			public readonly Vector3 LocalScale;

			public readonly float JogSpeed;

			public readonly float WalkSpeed;

			public readonly float RunSpeed;

			public readonly float TurnSpeed;

			public readonly float RunTurnSpeed;

			public CharacterRuntimeDefaults(Character character)
			{
				//IL_000d: Unknown result type (might be due to invalid IL or missing references)
				//IL_0012: Unknown result type (might be due to invalid IL or missing references)
				LocalScale = ((Component)character).transform.localScale;
				JogSpeed = character.m_speed;
				WalkSpeed = character.m_walkSpeed;
				RunSpeed = character.m_runSpeed;
				TurnSpeed = character.m_turnSpeed;
				RunTurnSpeed = character.m_runTurnSpeed;
			}
		}

		private sealed class PlayerRuntimeDefaults
		{
			public readonly float JumpForce;

			public readonly float JumpStaminaUsage;

			public readonly float RunStaminaDrain;

			public readonly float DodgeStaminaUsage;

			public readonly float SneakStaminaDrain;

			public readonly float RunSpeed;

			public readonly float JogSpeed;

			public readonly float WalkSpeed;

			public readonly float CrouchSpeed;

			public readonly float StaminaRegen;

			public readonly float StaminaRegenTimeMultiplier;

			public PlayerRuntimeDefaults(Player player)
			{
				JumpForce = ((Character)player).m_jumpForce;
				JumpStaminaUsage = ((Character)player).m_jumpStaminaUsage;
				RunStaminaDrain = player.m_runStaminaDrain;
				DodgeStaminaUsage = player.m_dodgeStaminaUsage;
				SneakStaminaDrain = player.m_sneakStaminaDrain;
				RunSpeed = ((Character)player).m_runSpeed;
				JogSpeed = ((Character)player).m_speed;
				WalkSpeed = ((Character)player).m_walkSpeed;
				CrouchSpeed = ((Character)player).m_crouchSpeed;
				StaminaRegen = player.m_staminaRegen;
				StaminaRegenTimeMultiplier = player.m_staminaRegenTimeMultiplier;
			}
		}

		public sealed class BlockingMovementSpeedPatchState
		{
			private readonly Player _player;

			private readonly float _speed;

			private readonly float _walkSpeed;

			private readonly float _runSpeed;

			private readonly float _crouchSpeed;

			public BlockingMovementSpeedPatchState(Player player, float speed, float walkSpeed, float runSpeed, float crouchSpeed)
			{
				_player = player;
				_speed = speed;
				_walkSpeed = walkSpeed;
				_runSpeed = runSpeed;
				_crouchSpeed = crouchSpeed;
			}

			public void Restore()
			{
				if (!((Object)(object)_player == (Object)null))
				{
					((Character)_player).m_speed = _speed;
					((Character)_player).m_walkSpeed = _walkSpeed;
					((Character)_player).m_runSpeed = _runSpeed;
					((Character)_player).m_crouchSpeed = _crouchSpeed;
				}
			}
		}

		private readonly struct AnimatorSpeedValue
		{
			private readonly Animator? _animator;

			private readonly object? _target;

			private readonly FieldInfo? _field;

			private readonly float _originalSpeed;

			private readonly float _multiplier;

			public AnimatorSpeedValue(Animator animator, float originalSpeed, float multiplier)
			{
				_animator = animator;
				_target = null;
				_field = null;
				_originalSpeed = originalSpeed;
				_multiplier = multiplier;
			}

			public AnimatorSpeedValue(object target, FieldInfo field, float originalSpeed, float multiplier)
			{
				_animator = null;
				_target = target;
				_field = field;
				_originalSpeed = originalSpeed;
				_multiplier = multiplier;
			}

			public void Restore()
			{
				if ((Object)(object)_animator != (Object)null)
				{
					_animator.speed = _originalSpeed;
				}
				else if (_target != null && _field != null)
				{
					_field.SetValue(_target, _originalSpeed);
				}
			}

			public void Reapply()
			{
				float num = _originalSpeed * _multiplier;
				if ((Object)(object)_animator != (Object)null)
				{
					if (!(_animator.speed <= 0.001f))
					{
						_animator.speed = num;
					}
				}
				else if (_target != null && _field != null)
				{
					_field.SetValue(_target, num);
				}
			}
		}

		private sealed class GcoPvpTestDummyBehaviour : MonoBehaviour
		{
			private Character _character;

			private void Awake()
			{
				_character = ((Component)this).GetComponent<Character>();
				if ((Object)(object)_character != (Object)null)
				{
					DisableDummyAI(_character);
					ApplyPvpTestDummyConfigToInstance(_character, restoreHealth: true);
					SetPrivateFloat(_character, "m_staggerDamage", 0f);
					if (TryGetZdo(_character, out ZDO zdo))
					{
						zdo.Set("GCO_TestDummyWasAttacked", false);
						zdo.Set("GCO_TestDummyNextHealTime", 0f);
					}
				}
			}

			private void FixedUpdate()
			{
				if ((Object)(object)_character == (Object)null)
				{
					_character = ((Component)this).GetComponent<Character>();
				}
				if ((Object)(object)_character == (Object)null || !IsPvpTestDummy(_character))
				{
					return;
				}
				DisableDummyAI(_character);
				ZDO val = null;
				ZNetView component = ((Component)_character).GetComponent<ZNetView>();
				if ((Object)(object)component != (Object)null && component.IsValid())
				{
					val = component.GetZDO();
					if (val != null)
					{
						val.Persistent = true;
					}
					if (!component.IsOwner())
					{
						return;
					}
				}
				float pvpTestDummyMaxHealth = GetPvpTestDummyMaxHealth(_character);
				_character.SetMaxHealth(pvpTestDummyMaxHealth);
				if (_character.GetHealth() <= 0.5f)
				{
					_character.SetHealth(Mathf.Max(1f, pvpTestDummyMaxHealth));
				}
				if (val != null && val.GetBool("GCO_TestDummyWasAttacked", false))
				{
					float num = val.GetFloat("GCO_TestDummyNextHealTime", 0f);
					if (num <= 0f)
					{
						val.Set("GCO_TestDummyNextHealTime", Time.time + Mathf.Max(0.25f, PvpTestDummyFullHealIntervalSeconds.Value));
					}
					else if (Time.time >= num)
					{
						_character.SetHealth(pvpTestDummyMaxHealth);
						SetPrivateFloat(_character, "m_staggerDamage", 0f);
						val.Set("GCO_TestDummyWasAttacked", false);
						val.Set("GCO_TestDummyNextHealTime", 0f);
					}
				}
			}
		}

		private sealed class StaffSpawnOrigin
		{
			public Character Owner { get; }

			public long OwnerPlayerId { get; }

			public string StaffPrefabName { get; }

			public bool IsGreenRoots { get; }

			public bool IsSkeleton { get; }

			public int SkeletonItemQuality { get; }

			public int SkeletonResolvedSpawnCap { get; }

			public float CreatedTime { get; }

			public StaffSpawnOrigin(Character owner, StaffConfig staffConfig, ItemData? item = null)
			{
				Owner = owner;
				Player val = (Player)(object)((owner is Player) ? owner : null);
				OwnerPlayerId = ((val != null) ? val.GetPlayerID() : 0);
				StaffPrefabName = staffConfig.PrefabName;
				IsGreenRoots = IsStaffGreenRoots(staffConfig);
				IsSkeleton = IsStaffSkeleton(staffConfig);
				SkeletonItemQuality = ((item == null) ? 1 : Mathf.Clamp(item.m_quality, 1, 4));
				SkeletonResolvedSpawnCap = ((IsSkeleton && item != null) ? GetStaffSkeletonConfiguredSpawnCapForItem(item) : 0);
				CreatedTime = Time.time;
			}
		}

		private sealed class DamageBonusStackState
		{
			public static readonly DamageBonusStackState Empty = new DamageBonusStackState(backstab: false, staggeredEnemy: false, flanking: false, counterDamage: false);

			public bool Backstab { get; }

			public bool StaggeredEnemy { get; }

			public bool Flanking { get; }

			public bool CounterDamage { get; }

			public int ActiveCount => (Backstab ? 1 : 0) + (StaggeredEnemy ? 1 : 0) + (Flanking ? 1 : 0) + (CounterDamage ? 1 : 0);

			public DamageBonusStackState(bool backstab, bool staggeredEnemy, bool flanking, bool counterDamage)
			{
				Backstab = backstab;
				StaggeredEnemy = staggeredEnemy;
				Flanking = flanking;
				CounterDamage = counterDamage;
			}

			public bool IsActive(DamageBonusKind kind)
			{
				return kind switch
				{
					DamageBonusKind.Backstab => Backstab, 
					DamageBonusKind.StaggeredEnemy => StaggeredEnemy, 
					DamageBonusKind.Flanking => Flanking, 
					DamageBonusKind.CounterDamage => CounterDamage, 
					_ => false, 
				};
			}
		}

		private sealed class CombatDingState
		{
			public bool CounterDamageDingPlayed;

			public bool FlankingDingPlayed;
		}

		private sealed class SkillDamageFactorState
		{
			public float SkillDamageFactor { get; }

			public SkillDamageFactorState(float skillDamageFactor)
			{
				SkillDamageFactor = skillDamageFactor;
			}
		}

		private sealed class PvpDummyDebugState
		{
			public float HealthBefore { get; }

			public float StaggerBefore { get; }

			public PvpDummyDebugState(float healthBefore, float staggerBefore)
			{
				HealthBefore = healthBefore;
				StaggerBefore = staggerBefore;
			}
		}

		private sealed class ProcessedHitMarker
		{
			public static readonly ProcessedHitMarker Instance = new ProcessedHitMarker();
		}

		public sealed class DamagePatchState
		{
			public Character Victim { get; }

			public float HealthBefore { get; }

			public float DamageMultiplier { get; }

			public DurabilityPatchState? DurabilityState { get; set; }

			public float TargetHealthAfterMitigation { get; set; }

			public DamagePatchState(Character victim, float healthBefore, float damageMultiplier)
			{
				Victim = victim;
				HealthBefore = healthBefore;
				DamageMultiplier = damageMultiplier;
				TargetHealthAfterMitigation = -1f;
			}
		}

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

			public static Func<string, bool> <>9__508_0;

			public static Func<string, bool> <>9__508_1;

			public static Func<string, bool> <>9__513_0;

			public static Func<string, string> <>9__513_1;

			public static Func<string, string> <>9__533_1;

			public static ConsoleOptionsFetcher <>9__533_0;

			public static Func<KeyValuePair<string, ConfigEntryBase>, ConfigEntryBase> <>9__537_1;

			public static Func<IGrouping<ConfigEntryBase, KeyValuePair<string, ConfigEntryBase>>, KeyValuePair<string, ConfigEntryBase>> <>9__537_2;

			public static Func<string, bool> <>9__553_0;

			public static Func<MethodInfo, bool> <>9__625_0;

			public static Func<Type, bool> <>9__627_0;

			public static Func<Type, string> <>9__633_0;

			public static Func<Food, bool> <>9__680_0;

			public static Func<Food, bool> <>9__685_0;

			public static Func<Food, float> <>9__685_1;

			public static Func<MethodInfo, bool> <>9__757_0;

			public static Func<MethodInfo, bool> <>9__757_1;

			public static Func<MethodInfo, bool> <>9__761_0;

			public static Func<KeyValuePair<object, Character>, object> <>9__817_1;

			public static ConditionalWeakTable<HitData, CombatDingState>.CreateValueCallback <>9__943_0;

			public static Func<Type, string> <>9__1237_0;

			internal bool <TryBuildFlatGcoBranchAndFeature>b__508_0(string part)
			{
				return !string.IsNullOrWhiteSpace(part);
			}

			internal bool <TryBuildFlatGcoBranchAndFeature>b__508_1(string part)
			{
				return !string.IsNullOrWhiteSpace(part);
			}

			internal bool <BuildCompactCommandPath>b__513_0(string t)
			{
				return !string.IsNullOrWhiteSpace(t);
			}

			internal string <BuildCompactCommandPath>b__513_1(string t)
			{
				return t.Trim();
			}

			internal string <RegisterGcoFlatConsoleCommands>b__533_1(string key)
			{
				if (!GcoFlatBranchDisplayNames.TryGetValue(key, out string value))
				{
					return key;
				}
				return value;
			}

			internal List<string> <RegisterGcoFlatConsoleCommands>b__533_0()
			{
				return new List<string> { "goo", "vanilla" };
			}

			internal ConfigEntryBase <TryResolveGcoFlatEntry>b__537_1(KeyValuePair<string, ConfigEntryBase> pair)
			{
				return pair.Value;
			}

			internal KeyValuePair<string, ConfigEntryBase> <TryResolveGcoFlatEntry>b__537_2(IGrouping<ConfigEntryBase, KeyValuePair<string, ConfigEntryBase>> group)
			{
				return group.First();
			}

			internal bool <ToFriendlyGcoCommandPath>b__553_0(string x)
			{
				return !string.IsNullOrWhiteSpace(x);
			}

			internal bool <PatchCoreDamageAndStagger>b__625_0(MethodInfo m)
			{
				return m.Name == "Stagger";
			}

			internal bool <GetSafeAssemblyTypes>b__627_0(Type t)
			{
				return t != null;
			}

			internal string <PatchSpecificMethod>b__633_0(Type p)
			{
				return p.Name;
			}

			internal bool <PlayerCanEatPrefix>b__680_0(Food food)
			{
				if (food != null)
				{
					return food.CanEatAgain();
				}
				return false;
			}

			internal bool <PlayerEatFoodPrefix>b__685_0(Food food)
			{
				if (food != null)
				{
					return food.CanEatAgain();
				}
				return false;
			}

			internal float <PlayerEatFoodPrefix>b__685_1(Food food)
			{
				return food.m_time;
			}

			internal bool <PatchAttackStartMethods>b__757_0(MethodInfo m)
			{
				if (m.Name == "Start")
				{
					return m.ReturnType == typeof(bool);
				}
				return false;
			}

			internal bool <PatchAttackStartMethods>b__757_1(MethodInfo m)
			{
				return m.Name == "Start";
			}

			internal bool <PatchHumanoidStartAttack>b__761_0(MethodInfo m)
			{
				if (m.Name == "StartAttack")
				{
					return m.ReturnType == typeof(bool);
				}
				return false;
			}

			internal object <CleanupPreviousAttackContextsForCharacter>b__817_1(KeyValuePair<object, Character> kvp)
			{
				return kvp.Key;
			}

			internal CombatDingState <PlayConditionalDamageDing>b__943_0(HitData _)
			{
				return new CombatDingState();
			}

			internal string <GetCachedMethod>b__1237_0(Type t)
			{
				return t.FullName;
			}
		}

		public const string ModGuid = "goo.valheim.gooscombatoverhaul";

		public const string ModName = "Goo's Combat Overhaul";

		public const string ModVersion = "1.3.3";

		private readonly Harmony _harmony = new Harmony("goo.valheim.gooscombatoverhaul");

		private bool _bindPrimary3ForCurrentCategory = true;

		private bool _bindPrimary4ForCurrentCategory;

		private WeaponCategory _bindCategoryForCurrentCategory;

		private bool _processingGlobalRulesetButton;

		private static bool _suppressGcoChatBroadcast;

		private bool _startupConfigVersionDecisionInitialized;

		private bool _startupLegacyConfigNeedsGooRewrite;

		private bool _startupConfigVersionNeedsBump;

		private static readonly Dictionary<ConfigEntryBase, string> GcoCommandPrimaryPaths = new Dictionary<ConfigEntryBase, string>();

		private static readonly Dictionary<string, Dictionary<string, ConfigEntryBase>> GcoFlatCommandEntries = new Dictionary<string, Dictionary<string, ConfigEntryBase>>(StringComparer.OrdinalIgnoreCase);

		private static readonly Dictionary<string, SortedSet<string>> GcoFlatCommandOptions = new Dictionary<string, SortedSet<string>>(StringComparer.OrdinalIgnoreCase);

		private static readonly Dictionary<string, string> GcoFlatBranchDisplayNames = new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase);

		private static readonly Dictionary<string, GearDurabilityConfig> GearDurabilityConfigs = new Dictionary<string, GearDurabilityConfig>(StringComparer.OrdinalIgnoreCase);

		private static readonly ConditionalWeakTable<ItemData, DurabilitySnapshotBox> DurabilitySnapshots = new ConditionalWeakTable<ItemData, DurabilitySnapshotBox>();

		private static bool _gcoFlatConsoleCommandsRegistered;

		private static bool _gcoDebugFlyDesired;

		private static bool _gcoNoPlacementCostDesired;

		private static bool _gcoGhostModeDesired;

		private static readonly Dictionary<string, float> DebugShortcutDebounceUntil = new Dictionary<string, float>();

		private static readonly HashSet<string> SuppressedButtonDownNamesThisFrame = new HashSet<string>(StringComparer.OrdinalIgnoreCase);

		private static int SuppressedButtonDownFrame = -1;

		private static bool _lastGooCombatDebugModeActive;

		internal static ConfigEntry<bool> Enabled = null;

		internal static ConfigEntry<string> ConfigVersion = null;

		internal static ConfigEntry<bool> SetToGoosRuleset = null;

		internal static ConfigEntry<bool> SetToVanillaRuleset = null;

		internal static ConfigEntry<bool> BroadcastConfigChanges = null;

		internal static ConfigEntry<KeyCode> Roll = null;

		internal static ConfigEntry<bool> DebugLogging = null;

		internal static ConfigEntry<bool> VerboseDebugLogging = null;

		internal static ConfigEntry<bool> DebugAttackLifecycle = null;

		internal static ConfigEntry<bool> DebugCounterDamage = null;

		internal static ConfigEntry<bool> CounterDamageDing = null;

		internal static ConfigEntry<bool> DebugHitStop = null;

		internal static ConfigEntry<bool> DebugMovement = null;

		internal static ConfigEntry<bool> DebugHyperArmorLifecycle = null;

		internal static ConfigEntry<bool> EnableCounterDamage = null;

		internal static ConfigEntry<bool> OnlyPlayersCanDealCounterDamage = null;

		internal static ConfigEntry<HyperArmorDamageMitigationMode> HyperArmorMitigationMode = null;

		internal static ConfigEntry<bool> MitigateUnknownAttackerDamageDuringHyperArmor = null;

		internal static ConfigEntry<bool> DebugHyperArmorDamageMitigation = null;

		internal static ConfigEntry<bool> EnablePvpDamageModifiers = null;

		internal static ConfigEntry<bool> ClearStaggerMeterWhenStaggered = null;

		internal static ConfigEntry<bool> ClearEnemyStaggerMeterWhenStaggered = null;

		internal static ConfigEntry<bool> AlwaysDoMaxDamage = null;

		internal static ConfigEntry<bool> AlwaysDoMaxDamageInPvp = null;

		internal static ConfigEntry<float> GlobalDamageMultiplier = null;

		internal static ConfigEntry<float> GlobalHyperArmorDamageTakenMultiplier = null;

		internal static ConfigEntry<float> GlobalHyperArmorKnockbackTakenMultiplier = null;

		internal static ConfigEntry<float> GlobalPvpDamageMultiplier = null;

		internal static ConfigEntry<float> GlobalPvpDamageTakenMultiplier = null;

		internal static ConfigEntry<float> GlobalPlayerKnockbackMultiplier = null;

		internal static ConfigEntry<float> GlobalPvpKnockbackMultiplier = null;

		internal static ConfigEntry<float> GlobalPlayerStaggerPowerMultiplier = null;

		internal static ConfigEntry<float> GlobalDamageToStaggeredEnemiesMultiplier = null;

		internal static ConfigEntry<bool> StaggeredEnemyDamageStackableWithOtherBonuses = null;

		internal static ConfigEntry<bool> BackstabDamageStackableWithOtherBonuses = null;

		internal static ConfigEntry<bool> CounterDamageStackableWithOtherBonuses = null;

		internal static ConfigEntry<bool> EnableFlankingDamage = null;

		internal static ConfigEntry<bool> FlankingDamageStackableWithOtherBonuses = null;

		internal static ConfigEntry<bool> SuccessfulFlankDing = null;

		internal static ConfigEntry<float> FlankingPveRearAngleDegrees = null;

		internal static ConfigEntry<float> FlankingPvpRearAngleDegrees = null;

		internal static ConfigEntry<float> GlobalFlankingDamageMultiplier = null;

		internal static ConfigEntry<float> GlobalPvpFlankingDamageMultiplier = null;

		internal static ConfigEntry<float> GlobalPlayerDamageTakenMultiplier = null;

		internal static ConfigEntry<float> PlayerDamageToBuildingsMultiplier = null;

		internal static ConfigEntry<float> EnemyDamageToBuildingsMultiplier = null;

		internal static ConfigEntry<float> GlobalCounterDamageMultiplier = null;

		internal static ConfigEntry<bool> GlobalHitStopEnabled = null;

		internal static ConfigEntry<float> GlobalBlockingStaminaRegenMultiplier = null;

		internal static ConfigEntry<float> GlobalBlockArmorMultiplier = null;

		internal static ConfigEntry<float> GlobalBlockForceMultiplier = null;

		internal static ConfigEntry<float> GlobalParryBonusMultiplier = null;

		internal static ConfigEntry<float> GlobalParryWindowTimeMultiplier = null;

		internal static ConfigEntry<float> GlobalEffectiveBlockAngleMultiplier = null;

		internal static ConfigEntry<float> GlobalParryAdrenalineMultiplier = null;

		internal static ConfigEntry<float> GlobalBlockStaminaConsumptionRate = null;

		internal static ConfigEntry<float> GlobalBlockBreakThresholdMultiplier = null;

		internal static ConfigEntry<float> GlobalPvpBlockArmorMultiplier = null;

		internal static ConfigEntry<float> GlobalPvpBlockForceMultiplier = null;

		internal static ConfigEntry<float> GlobalPvpParryBonusMultiplier = null;

		internal static ConfigEntry<float> GlobalPvpBlockBreakThresholdMultiplier = null;

		internal static ConfigEntry<float> GlobalBlockingMovementSpeedMultiplier = null;

		internal static ConfigEntry<float> GlobalKnockbackTakenWhileBlockingMultiplier = null;

		internal static ConfigEntry<float> GlobalSoulsLikeBlockStaminaBaseRateMultiplier = null;

		internal static BlockedHitDamageTakenConfig GlobalDamageTakenOnBlockedHit = null;

		internal static BlockedHitDamageTakenConfig ShieldBucklerDamageTakenOnBlockedHit = null;

		internal static BlockedHitDamageTakenConfig ShieldMediumDamageTakenOnBlockedHit = null;

		internal static BlockedHitDamageTakenConfig ShieldTowerDamageTakenOnBlockedHit = null;

		private static readonly Dictionary<WeaponCategory, BlockedHitDamageTakenConfig> WeaponDamageTakenOnBlockedHitConfigs = new Dictionary<WeaponCategory, BlockedHitDamageTakenConfig>();

		private static readonly Dictionary<string, BlockedHitDamageTakenConfig> StaffDamageTakenOnBlockedHitConfigs = new Dictionary<string, BlockedHitDamageTakenConfig>(StringComparer.OrdinalIgnoreCase);

		internal static ConfigEntry<float> GlobalHitRayRangeMultiplier = null;

		internal static ConfigEntry<float> GlobalHitRayThicknessMultiplier = null;

		internal static ConfigEntry<float> GlobalHitRayStartHeightMultiplier = null;

		internal static ConfigEntry<float> GlobalHitRayOffsetMultiplier = null;

		internal static ConfigEntry<float> GlobalHitRayAngleMultiplier = null;

		internal static ConfigEntry<float> OneHandedAxeSecondaryHitRayAddedThicknessMeters = null;

		internal static ConfigEntry<float> OneHandedAxeJumpAttackHitRayAddedThicknessMeters = null;

		internal static ConfigEntry<float> GlobalAttackStartNoiseMultiplier = null;

		internal static ConfigEntry<float> GlobalAttackHitNoiseMultiplier = null;

		internal static ConfigEntry<float> GlobalBackstabDamageMultiplier = null;

		internal static ConfigEntry<float> GlobalAttackMovementMultiplier = null;

		internal static ConfigEntry<float> GlobalLungeDistanceMultiplier = null;

		internal static ConfigEntry<float> GlobalRunningAttackLungeDistanceMultiplier = null;

		internal static ConfigEntry<float> GlobalJumpAttackLungeDistanceMultiplier = null;

		internal static ConfigEntry<float> GlobalAttackRotationMultiplier = null;

		internal static ConfigEntry<float> GlobalPvpHitStopDurationMultiplier = null;

		internal static ConfigEntry<float> GlobalAttackAnimationSpeedMultiplier = null;

		internal static ConfigEntry<float> GlobalRecoveryAnimationSpeedMultiplier = null;

		internal static ConfigEntry<float> GlobalAdrenalineRate = null;

		internal static ConfigEntry<bool> MustEatUniqueFood = null;

		internal static ConfigEntry<float> FoodHealthMultiplier = null;

		internal static ConfigEntry<float> FoodStaminaMultiplier = null;

		internal static ConfigEntry<float> FoodEitrMultiplier = null;

		internal static ConfigEntry<float> FoodHealingRateMultiplier = null;

		internal static ConfigEntry<bool> PermanentFoodBuffs = null;

		internal static ConfigEntry<bool> PermanentMeadBuffs = null;

		internal static ConfigEntry<bool> PermanentRestedBuff = null;

		internal static ConfigEntry<bool> NoConsumption = null;

		internal static ConfigEntry<float> MeadStaminaRecoveryBonusMultiplier = null;

		internal static ConfigEntry<float> MeadEitrRecoveryBonusMultiplier = null;

		internal static ConfigEntry<float> MeadHealthRegenBonusMultiplier = null;

		internal static ConfigEntry<bool> GlobalUnbreakableGear = null;

		internal static ConfigEntry<float> GlobalDurabilityConsumptionMultiplier = null;

		internal static ConfigEntry<float> GlobalBaseDurabilityMultiplier = null;

		internal static ConfigEntry<float> GlobalDurabilityMultiplier = null;

		internal static ConfigEntry<bool> SpawnPvpTestDummy = null;

		internal static ConfigEntry<bool> RemovePvpTestDummies = null;

		internal static ConfigEntry<float> PvpTestDummyHealth = null;

		internal static ConfigEntry<float> PvpTestDummyArmor = null;

		internal static ConfigEntry<float> PvpTestDummyStaggerThresholdMultiplier = null;

		internal static ConfigEntry<float> PvpTestDummyFullHealIntervalSeconds = null;

		internal static ConfigEntry<bool> DebugPvpTestDummyOutput = null;

		internal static ConfigEntry<float> HitStopDurationMultiplier = null;

		internal static ConfigEntry<float> HitStopDurationOverrideSeconds = null;

		internal static ConfigEntry<AttackMovementGroundingMode> AttackMovementGroundingModeConfig = null;

		internal static ConfigEntry<bool> BetterFreeAim = null;

		private const float VanillaPlayerBaseHealth = 25f;

		private const float VanillaPlayerBaseStamina = 75f;

		private const float VanillaPlayerBaseArmor = 0f;

		private const float VanillaPlayerBaseCarryWeight = 300f;

		private const float VanillaJumpForce = 10f;

		private const float VanillaJumpStaminaUsage = 10f;

		private const float VanillaRunStaminaDrain = 10f;

		private const float VanillaDodgeStaminaUsage = 10f;

		private const float VanillaStaminaRegen = 5f;

		private const float VanillaFallDamageStartHeight = 4f;

		private const float VanillaFallDamagePerMeter = 6.25f;

		private const float VanillaFallDamageCap = 100f;

		internal static ConfigEntry<bool> EnableNegativeStamina = null;

		internal static ConfigEntry<float> NegativeStaminaFloor = null;

		internal static ConfigEntry<NegativeStaminaActionGateMode> NegativeStaminaActionGate = null;

		internal static ConfigEntry<float> PlayerBaseHealth = null;

		internal static ConfigEntry<float> PlayerBaseStamina = null;

		internal static ConfigEntry<float> PlayerBaseEitr = null;

		internal static ConfigEntry<float> PlayerBaseEitrRegenRate = null;

		internal static ConfigEntry<float> PlayerBaseArmor = null;

		internal static ConfigEntry<float> PlayerBaseCarryWeight = null;

		internal static ConfigEntry<float> PlayerJumpForceMultiplier = null;

		internal static ConfigEntry<float> PlayerRunSpeedMultiplier = null;

		internal static ConfigEntry<float> PlayerJogSpeedMultiplier = null;

		internal static ConfigEntry<float> PlayerWalkSpeedMultiplier = null;

		internal static ConfigEntry<float> PlayerCrouchSpeedMultiplier = null;

		internal static ConfigEntry<float> PlayerBaseRotationFactor = null;

		internal static ConfigEntry<float> PlayerSizeMultiplier = null;

		internal static ConfigEntry<float> PlayerPoiseMultiplier = null;

		internal static ConfigEntry<float> PlayerStaggerDecaySpeedMultiplier = null;

		internal static ConfigEntry<float> PlayerStaggerDecayCooldownSeconds = null;

		internal static ConfigEntry<float> AirborneAttackMinimumAirTimeSeconds = null;

		internal static ConfigEntry<float> JumpStaminaConsumptionRate = null;

		internal static ConfigEntry<float> RunStaminaConsumptionRate = null;

		internal static ConfigEntry<bool> DrainRunStaminaDuringAttacksAndAirborne = null;

		internal static ConfigEntry<float> RollStaminaConsumptionRate = null;

		internal static ConfigEntry<float> CrouchStaminaConsumptionRate = null;

		internal static ConfigEntry<float> RollAnimationSpeed = null;

		internal static ConfigEntry<float> StaminaRecoveryRate = null;

		internal static ConfigEntry<StaminaRegenCurveMode> StaminaRegenCurve = null;

		internal static ConfigEntry<float> PlayerHealingRate = null;

		internal static ConfigEntry<float> FallDamageStartHeight = null;

		internal static ConfigEntry<float> FallDamagePerMeter = null;

		internal static ConfigEntry<float> FallDamageCap = null;

		internal static ConfigEntry<float> BowDrawSpeedMultiplier = null;

		internal static ConfigEntry<float> BowSpreadMultiplier = null;

		internal static ConfigEntry<float> BowProjectileSpeedMultiplier = null;

		internal static ConfigEntry<float> BowBaseSpreadMultiplier = null;

		internal static ConfigEntry<float> CrossbowReloadTimeMultiplier = null;

		internal static ConfigEntry<float> CrossbowProjectileSpeedMultiplier = null;

		internal static ConfigEntry<float> SpearProjectileSpeedMultiplier = null;

		internal static ConfigEntry<bool> SpearLoyaltyMode = null;

		internal static ConfigEntry<float> HarpoonRopeStrengthMultiplier = null;

		internal static ConfigEntry<float> CrossbowBaseSpreadMultiplier = null;

		internal static ConfigEntry<float> LightArmorBaseArmorMultiplier = null;

		internal static ConfigEntry<float> MediumArmorBaseArmorMultiplier = null;

		internal static ConfigEntry<float> HeavyArmorBaseArmorMultiplier = null;

		internal static ConfigEntry<bool> DebugPlayerSystems = null;

		internal static ConfigEntry<bool> DebugNegativeStamina = null;

		internal static ConfigEntry<bool> DebugRanged = null;

		internal static ConfigEntry<bool> DebugBlocking = null;

		internal static ConfigEntry<bool> GooCombatDebugMode = null;

		internal static ConfigEntry<bool> EnableDebugFlyToggle = null;

		internal static ConfigEntry<bool> EnableNoPlacementCostToggle = null;

		internal static ConfigEntry<bool> EnableGhostModeToggle = null;

		internal static ConfigEntry<bool> ToggleNoPlacementCost = null;

		internal static ConfigEntry<bool> ToggleDebugFly = null;

		internal static ConfigEntry<bool> ToggleGhostMode = null;

		internal static ConfigEntry<bool> DebugModeHeal = null;

		internal static ConfigEntry<bool> DebugModeAddRested = null;

		internal static ConfigEntry<KeyCode> ToggleNoPlacementCostKeybind = null;

		internal static ConfigEntry<KeyCode> ToggleDebugFlyKeybind = null;

		internal static ConfigEntry<KeyCode> ToggleGhostModeKeybind = null;

		internal static ConfigEntry<KeyCode> DebugModeHealKeybind = null;

		internal static ConfigEntry<KeyCode> DebugModeAddRestedKeybind = null;

		internal static ConfigEntry<float> EnemyStaggerDamageDealtMultiplier = null;

		internal static ConfigEntry<float> EnemyKnockbackDealtMultiplier = null;

		internal static ConfigEntry<float> EnemySpeedMultiplier = null;

		internal static ConfigEntry<float> EnemyAttackAnimationSpeedMultiplier = null;

		internal static ConfigEntry<float> EnemyMovementAnimationSpeedMultiplier = null;

		internal static ConfigEntry<float> EnemySizeMultiplier = null;

		internal static ConfigEntry<float> EnemyAttackHitRayRangeMultiplier = null;

		internal static ConfigEntry<float> EnemyAttackHitRaySizeMultiplier = null;

		internal static ConfigEntry<float> EnemyAttackHitRayHeightMultiplier = null;

		internal static ConfigEntry<float> EnemyAttackHitRayOffsetMultiplier = null;

		internal static ConfigEntry<float> EnemyBaseRotationFactor = null;

		internal static ConfigEntry<float> EnemyAttackRotationFactor = null;

		internal static ConfigEntry<bool> EnemyLockRotationAfterHitRay = null;

		internal static ConfigEntry<float> EnemyPoiseMultiplier = null;

		internal static ConfigEntry<float> EnemyStaggerDecaySpeedMultiplier = null;

		internal static ConfigEntry<float> EnemyStaggerDecayCooldownSeconds = null;

		internal static ConfigEntry<bool> UseCustomLightArmorMovementModifier = null;

		internal static ConfigEntry<bool> UseCustomMediumArmorMovementModifier = null;

		internal static ConfigEntry<bool> UseCustomHeavyArmorMovementModifier = null;

		internal static ConfigEntry<bool> UseCustomOneHandedSwordMovementModifier = null;

		internal static ConfigEntry<bool> UseCustomOneHandedAxeMovementModifier = null;

		internal static ConfigEntry<bool> UseCustomClubMovementModifier = null;

		internal static ConfigEntry<bool> UseCustomKnifeMovementModifier = null;

		internal static ConfigEntry<bool> UseCustomDualKnivesMovementModifier = null;

		internal static ConfigEntry<bool> UseCustomSpearMovementModifier = null;

		internal static ConfigEntry<bool> UseCustomAtgeirMovementModifier = null;

		internal static ConfigEntry<bool> UseCustomTwoHandedSwordMovementModifier = null;

		internal static ConfigEntry<bool> UseCustomTwoHandedAxeMovementModifier = null;

		internal static ConfigEntry<bool> UseCustomSledgeMovementModifier = null;

		internal static ConfigEntry<bool> UseCustomDualAxesMovementModifier = null;

		internal static ConfigEntry<bool> UseCustomBowMovementModifier = null;

		internal static ConfigEntry<bool> UseCustomCrossbowMovementModifier = null;

		internal static ConfigEntry<bool> UseCustomToolMovementModifier = null;

		internal static ConfigEntry<bool> UseCustomOtherEquipmentMovementModifier = null;

		internal static ConfigEntry<float> LightArmorMovementModifierPercent = null;

		internal static ConfigEntry<float> MediumArmorMovementModifierPercent = null;

		internal static ConfigEntry<float> HeavyArmorMovementModifierPercent = null;

		internal static ConfigEntry<float> OneHandedSwordMovementModifierPercent = null;

		internal static ConfigEntry<float> OneHandedAxeMovementModifierPercent = null;

		internal static ConfigEntry<float> ClubMovementModifierPercent = null;

		internal static ConfigEntry<float> KnifeMovementModifierPercent = null;

		internal static ConfigEntry<float> DualKnivesMovementModifierPercent = null;

		internal static ConfigEntry<float> SpearMovementModifierPercent = null;

		internal static ConfigEntry<float> AtgeirMovementModifierPercent = null;

		internal static ConfigEntry<float> TwoHandedSwordMovementModifierPercent = null;

		internal static ConfigEntry<float> TwoHandedAxeMovementModifierPercent = null;

		internal static ConfigEntry<float> SledgeMovementModifierPercent = null;

		internal static ConfigEntry<float> DualAxesMovementModifierPercent = null;

		internal static ConfigEntry<float> BowMovementModifierPercent = null;

		internal static ConfigEntry<float> CrossbowMovementModifierPercent = null;

		internal static ConfigEntry<float> ToolMovementModifierPercent = null;

		internal static ConfigEntry<float> OtherEquipmentMovementModifierPercent = null;

		internal static readonly Dictionary<WeaponCategory, CategoryConfig> CategoryConfigs = new Dictionary<WeaponCategory, CategoryConfig>();

		internal static readonly Dictionary<WeaponCategory, RoleSettings<float>> AttackStartNoiseMultipliers = new Dictionary<WeaponCategory, RoleSettings<float>>();

		internal static readonly Dictionary<WeaponCategory, RoleSettings<float>> AttackHitNoiseMultipliers = new Dictionary<WeaponCategory, RoleSettings<float>>();

		internal static readonly Dictionary<WeaponCategory, RoleSettings<float>> AttackRangeMultipliers = new Dictionary<WeaponCategory, RoleSettings<float>>();

		internal static readonly Dictionary<string, ConfigEntry<float>> OneHandedSwordPrefabHitRayRangeMultipliers = new Dictionary<string, ConfigEntry<float>>(StringComparer.OrdinalIgnoreCase);

		internal static readonly Dictionary<string, ConfigEntry<float>> SpearPrefabHitRayRangeMultipliers = new Dictionary<string, ConfigEntry<float>>(StringComparer.OrdinalIgnoreCase);

		internal static readonly Dictionary<WeaponCategory, RoleSettings<float>> AttackRayWidthMultipliers = new Dictionary<WeaponCategory, RoleSettings<float>>();

		internal static readonly Dictionary<WeaponCategory, RoleSettings<float>> AttackHitboxHeightMultipliers = new Dictionary<WeaponCategory, RoleSettings<float>>();

		internal static readonly Dictionary<WeaponCategory, RoleSettings<float>> AttackOffsetMultipliers = new Dictionary<WeaponCategory, RoleSettings<float>>();

		internal static readonly Dictionary<WeaponCategory, RoleSettings<float>> AttackAngleMultipliers = new Dictionary<WeaponCategory, RoleSettings<float>>();

		internal static readonly Dictionary<WeaponCategory, RoleSettings<AttackHitboxType>> AttackHitboxTypes = new Dictionary<WeaponCategory, RoleSettings<AttackHitboxType>>();

		internal static readonly Dictionary<WeaponCategory, RoleSettings<AttackMultiTargetDamagePenaltyMode>> AttackMultiTargetDamagePenaltyModes = new Dictionary<WeaponCategory, RoleSettings<AttackMultiTargetDamagePenaltyMode>>();

		internal static readonly Dictionary<WeaponCategory, RoleSettings<float>> AttackBuildingDamageMultipliers = new Dictionary<WeaponCategory, RoleSettings<float>>();

		internal static readonly Dictionary<WeaponCategory, RoleSettings<float>> AttackStaggeredEnemyDamageMultipliers = new Dictionary<WeaponCategory, RoleSettings<float>>();

		internal static readonly Dictionary<WeaponCategory, RoleSettings<float>> BackstabDamageMultipliers = new Dictionary<WeaponCategory, RoleSettings<float>>();

		internal static readonly Dictionary<WeaponCategory, ConfigEntry<float>> WeaponFlankingDamageMultipliers = new Dictionary<WeaponCategory, ConfigEntry<float>>();

		internal static readonly Dictionary<WeaponCategory, ConfigEntry<float>> WeaponPvpFlankingDamageMultipliers = new Dictionary<WeaponCategory, ConfigEntry<float>>();

		internal static readonly Dictionary<WeaponCategory, ConfigEntry<float>> WeaponEffectiveBlockAngleMultipliers = new Dictionary<WeaponCategory, ConfigEntry<float>>();

		internal static readonly HashSet<object> EnemyRotationLockedAfterHitRayAttacks = new HashSet<object>();

		internal static readonly Dictionary<WeaponCategory, ConfigEntry<float>> RunningAttackBuildingDamageMultipliers = new Dictionary<WeaponCategory, ConfigEntry<float>>();

		internal static readonly Dictionary<WeaponCategory, ConfigEntry<float>> JumpAttackBuildingDamageMultipliers = new Dictionary<WeaponCategory, ConfigEntry<float>>();

		internal static readonly Dictionary<WeaponCategory, ConfigEntry<float>> RunningAttackStaggeredEnemyDamageMultipliers = new Dictionary<WeaponCategory, ConfigEntry<float>>();

		internal static readonly Dictionary<WeaponCategory, ConfigEntry<float>> JumpAttackStaggeredEnemyDamageMultipliers = new Dictionary<WeaponCategory, ConfigEntry<float>>();

		internal static readonly Dictionary<WeaponCategory, RunningAttackConfig> RunningAttackConfigs = new Dictionary<WeaponCategory, RunningAttackConfig>();

		internal static readonly Dictionary<WeaponCategory, JumpAttackConfig> JumpAttackConfigs = new Dictionary<WeaponCategory, JumpAttackConfig>();

		internal static readonly Dictionary<WeaponCategory, RoleSettings<BlockCancelMode>> BlockCancelModes = new Dictionary<WeaponCategory, RoleSettings<BlockCancelMode>>();

		internal static readonly Dictionary<WeaponCategory, WeaponBlockExtraConfig> WeaponBlockExtras = new Dictionary<WeaponCategory, WeaponBlockExtraConfig>();

		internal static readonly Dictionary<string, StaffConfig> StaffConfigs = new Dictionary<string, StaffConfig>(StringCompare