Decompiled source of GoosCombatOverhaul v1.4.0

BepInEx/plugins/GooCombatOverhaul/GooCombatOverhaul.dll

Decompiled a month 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.Reflection.Emit;
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.4.0")]
	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 enum IncomingParryStaggerSource
		{
			None,
			Ranged,
			Aoe
		}

		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;
			}
		}

		private sealed class DirectSledgeHitPoint
		{
			public GameObject Go;

			public Collider Collider;

			public Vector3 Point;

			public float Distance;
		}

		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 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<bool> CanParry { get; }

			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<bool> canParry, 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)
			{
				CanParry = canParry;
				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<bool> CanParry { get; }

			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<bool> canParry, 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)
			{
				CanParry = canParry;
				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<bool> CanParry { get; }

			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<bool> canParry, 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)
			{
				CanParry = canParry;
				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>? ProjectileSpeedMultiplier { get; }

			public ConfigEntry<float>? AoeRadiusMultiplier { 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>? projectileSpeedMultiplier, ConfigEntry<float>? aoeRadiusMultiplier, 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;
				ProjectileSpeedMultiplier = projectileSpeedMultiplier;
				AoeRadiusMultiplier = aoeRadiusMultiplier;
				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 T DefaultValue
			{
				get
				{
					if (_entry == null)
					{
						return _value;
					}
					return (T)((ConfigEntryBase)_entry).DefaultValue;
				}
			}

			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 sealed class ParryStaggerSuppressionState
		{
			private Character? _attacker;

			private bool _originalStaggerWhenBlocked;

			public void Suppress(Character attacker)
			{
				if (!((Object)(object)attacker == (Object)null) && !((Object)(object)_attacker != (Object)null))
				{
					_attacker = attacker;
					_originalStaggerWhenBlocked = attacker.m_staggerWhenBlocked;
				}
			}

			public void Restore()
			{
				if (!((Object)(object)_attacker == (Object)null))
				{
					_attacker.m_staggerWhenBlocked = _originalStaggerWhenBlocked;
					_attacker = null;
				}
			}
		}

		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);
				}
			}

			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);
			}
		}

		private sealed class StaffGreenRootSpawnRecord
		{
			public Character Character { get; }

			public long SpawnTicks { get; }

			public StaffGreenRootSpawnRecord(Character character, long spawnTicks)
			{
				Character = character;
				SpawnTicks = spawnTicks;
			}
		}

		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 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);
				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 PvpStaggerDurationState
		{
			public float DurationSeconds { get; }

			public PvpStaggerDurationState(float durationSeconds)
			{
				DurationSeconds = durationSeconds;
			}
		}

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

			public float StaggerBefore { get; }

			public float HealthAfterDamage { get; set; } = -1f;

			public float StaggerAfterDamage { get; set; } = -1f;

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

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

		private sealed class LightningAttackSpawnState
		{
			public GameObject? SpawnOnHit { get; }

			public float SpawnOnHitChance { get; }

			public LightningAttackSpawnState(GameObject? spawnOnHit, float spawnOnHitChance)
			{
				SpawnOnHit = spawnOnHit;
				SpawnOnHitChance = spawnOnHitChance;
			}
		}

		public sealed class ConfigSyncSaveState
		{
			public bool EnteredLocalReadScope { get; }

			public bool ExitedLocalReadScope { get; set; }

			public ConfigSyncSaveState(bool enteredLocalReadScope)
			{
				EnteredLocalReadScope = enteredLocalReadScope;
			}
		}

		public sealed class RpcDamageFlankSoundState
		{
			public EffectList? PreviousEffectList { get; }

			public int PreviousDepth { get; }

			public bool Restored { get; set; }

			public RpcDamageFlankSoundState(EffectList? previousEffectList, int previousDepth)
			{
				PreviousEffectList = previousEffectList;
				PreviousDepth = previousDepth;
			}
		}

		public sealed class SledgeAreaAttackScaleState
		{
			private readonly object _attackInstance;

			private readonly float _originalRadius;

			private readonly float _originalCharacterExtraRadius;

			private bool _restored;

			public SledgeAreaAttackScaleState(object attackInstance, float originalRadius, float originalCharacterExtraRadius)
			{
				_attackInstance = attackInstance;
				_originalRadius = originalRadius;
				_originalCharacterExtraRadius = originalCharacterExtraRadius;
			}

			public void Restore()
			{
				if (_restored)
				{
					return;
				}
				_restored = true;
				try
				{
					SetFieldValueRaw(_attackInstance, "m_attackRayWidth", _originalRadius);
					SetFieldValueRaw(_attackInstance, "m_attackRayWidthCharExtra", _originalCharacterExtraRadius);
				}
				catch
				{
				}
			}
		}

		public sealed class AlternateSledgeSecondarySwapState
		{
			private readonly Character _character;

			private readonly ItemData _weapon;

			private readonly Attack? _originalSecondary;

			private readonly Attack _temporarySecondary;

			private bool _restored;

			private bool _requestCleaned;

			public AlternateSledgeSecondarySwapState(Character character, ItemData weapon, Attack? originalSecondary, Attack temporarySecondary)
			{
				_character = character;
				_weapon = weapon;
				_originalSecondary = originalSecondary;
				_temporarySecondary = temporarySecondary;
			}

			public void Restore(bool cleanRequestState = false)
			{
				if (!_restored)
				{
					_restored = true;
					try
					{
						if (_weapon?.m_shared != null && _weapon.m_shared.m_secondaryAttack == _temporarySecondary)
						{
							_weapon.m_shared.m_secondaryAttack = _originalSecondary;
						}
					}
					catch
					{
					}
				}
				if (cleanRequestState && !_requestCleaned)
				{
					_requestCleaned = true;
					PendingAttackRoles.Remove(_character);
					AlternateSledgeSecondaryRequests.Remove(_character);
				}
			}
		}

		public sealed class ParryCapabilityPatchState
		{
			private readonly ItemData _blocker;

			private readonly float _originalTimedBlockBonus;

			private bool _restored;

			public ParryCapabilityPatchState(ItemData blocker, float originalTimedBlockBonus)
			{
				_blocker = blocker;
				_originalTimedBlockBonus = originalTimedBlockBonus;
			}

			public void Restore()
			{
				if (_restored)
				{
					return;
				}
				_restored = true;
				try
				{
					if (_blocker?.m_shared != null)
					{
						_blocker.m_shared.m_timedBlockBonus = _originalTimedBlockBonus;
					}
				}
				catch
				{
				}
			}
		}

		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<ConfigEntryBase, Type> <>9__564_0;

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

			public static Func<ConfigEntryBase, string> <>9__577_0;

			public static Func<ConfigEntryBase, string> <>9__577_1;

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

			public static Predicate<string> <>9__614_0;

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

			public static Func<FieldInfo, bool> <>9__668_0;

			public static Func<ConfigEntryBase, bool> <>9__668_1;

			public static Func<ConfigEntryBase, string> <>9__668_2;

			public static Func<ConfigEntryBase, string> <>9__668_4;

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

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

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

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

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

			public static Func<ConfigEntryBase, bool> <>9__691_0;

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

			public static ConsoleOptionsFetcher <>9__694_0;

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

			public static Comparison<RaycastHit> <>9__1036_0;

			public static Func<DirectSledgeHitPoint, float> <>9__1036_1;

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

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

			public static Predicate<StaffGreenRootSpawnRecord> <>9__1331_0;

			public static Predicate<StaffGreenRootSpawnRecord> <>9__1333_0;

			public static Comparison<StaffGreenRootSpawnRecord> <>9__1333_1;

			public static Func<StaffGreenRootSpawnRecord, bool> <>9__1333_2;

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

			internal Type <PatchConfigEntryEffectiveValueGetters>b__564_0(ConfigEntryBase entry)
			{
				return entry.SettingType;
			}

			internal bool <PatchConfigurationManagerLocalDisplayScope>b__566_0(Type type)
			{
				return type != null;
			}

			internal string <BuildConfigSyncEnvelope>b__577_0(ConfigEntryBase entry)
			{
				return entry.Definition.Section;
			}

			internal string <BuildConfigSyncEnvelope>b__577_1(ConfigEntryBase entry)
			{
				return entry.Definition.Key;
			}

			internal bool <TryGetStartupRawConfigValue>b__599_0(string k)
			{
				return !string.IsNullOrWhiteSpace(k);
			}

			internal bool <GetConfigWeaponSectionIndex>b__614_0(string value)
			{
				return value.Equals("Sledges", StringComparison.OrdinalIgnoreCase);
			}

			internal bool <RegisterAllGcoCommandEntry>b__666_0(string token)
			{
				return !string.IsNullOrWhiteSpace(token);
			}

			internal bool <EnsureConsoleCommandCoverage>b__668_0(FieldInfo field)
			{
				return typeof(IDictionary).IsAssignableFrom(field.FieldType);
			}

			internal bool <EnsureConsoleCommandCoverage>b__668_1(ConfigEntryBase entry)
			{
				if (IsRunnableCommandEntry(entry) && GcoPrimaryCommandRegisteredEntries.Contains(entry))
				{
					return !GcoAllCommandRegisteredEntries.Contains(entry);
				}
				return true;
			}

			internal string <EnsureConsoleCommandCoverage>b__668_2(ConfigEntryBase entry)
			{
				return "[" + entry.Definition.Section + "] " + entry.Definition.Key;
			}

			internal string <EnsureConsoleCommandCoverage>b__668_4(ConfigEntryBase entry)
			{
				return "[" + entry.Definition.Section + "] " + entry.Definition.Key;
			}

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

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

			internal string <BuildCompactCommandPath>b__674_0(string token)
			{
				return ReplaceOrdinalIgnoreCase(token, "Backstab", "Flank");
			}

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

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

			internal bool <GetExpectedRunnableCommandEntries>b__691_0(ConfigEntryBase entry)
			{
				return entry != null;
			}

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

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

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

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

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

			internal bool <PatchCoreDamageAndStagger>b__792_0(MethodInfo method)
			{
				return method.Name == "Create";
			}

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

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

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

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

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

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

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

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

			internal bool <PatchAttackAreaMethods>b__940_0(MethodInfo m)
			{
				return m.Name == "DoAreaAttack";
			}

			internal bool <PatchHumanoidBlockAttack>b__945_0(MethodInfo method)
			{
				if (method.Name == "BlockAttack" && method.ReturnType == typeof(bool) && method.GetParameters().Length == 2 && method.GetParameters()[0].ParameterType == typeof(HitData))
				{
					return typeof(Character).IsAssignableFrom(method.GetParameters()[1].ParameterType);
				}
				return false;
			}

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

			internal int <TryRunAlternateSledgeDirectHitRay>b__1036_0(RaycastHit x, RaycastHit y)
			{
				return ((RaycastHit)(ref x)).distance.CompareTo(((RaycastHit)(ref y)).distance);
			}

			internal float <TryRunAlternateSledgeDirectHitRay>b__1036_1(DirectSledgeHitPoint h)
			{
				return h.Distance;
			}

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

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

			internal bool <RegisterStaffGreenRoot>b__1331_0(StaffGreenRootSpawnRecord record)
			{
				if (!((Object)(object)record.Character == (Object)null))
				{
					return (Object)(object)((Component)record.Character).gameObject == (Object)null;
				}
				return true;
			}

			internal bool <EnforceStaffGreenRootCap>b__1333_0(StaffGreenRootSpawnRecord record)
			{
				if (!((Object)(object)record.Character == (Object)null))
				{
					return (Object)(object)((Component)record.Character).gameObject == (Object)null;
				}
				return true;
			}

			internal int <EnforceStaffGreenRootCap>b__1333_1(StaffGreenRootSpawnRecord a, StaffGreenRootSpawnRecord b)
			{
				return a.SpawnTicks.CompareTo(b.SpawnTicks);
			}

			internal bool <EnforceStaffGreenRootCap>b__1333_2(StaffGreenRootSpawnRecord candidate)
			{
				return CanAuthoritativelyDestroyStaffGreenRoot(candidate.Character);
			}

			internal string <GetCachedMethod>b__1528_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.4.0";

		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 _startupConfigVersionNeedsBump;

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

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

		private readonly List<string> _startupConfigInheritanceFailures = new List<string>();

		private bool _startupRawConfigSnapshotLoaded;

		private bool _startupHadExistingConfigFile;

		private static bool _clientMultiplayerConfigSyncActive;

		private static bool _clientGuestDebugAuthorityLimited;

		private static bool _applyingGuestDebugAuthorityRestriction;

		private static bool _configSyncBroadcastPending;

		private static bool _configRuntimeRefreshBatchActive;

		private static bool _configRuntimeRefreshBatchPending;

		[ThreadStatic]
		private static int _readClientLocalConfigDepth;

		[ThreadStatic]
		private static int _configurationManagerLocalDisplayDepth;

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

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

		private static readonly Dictionary<ConfigEntryBase, object> ClientSyncedTypedValues = new Dictionary<ConfigEntryBase, object>();

		private static readonly HashSet<MethodBase> PatchedConfigEntryValueGetters = new HashSet<MethodBase>();

		private const string ConfigSyncRpcName = "GCO_ConfigSync";

		private const string ConfigSyncRequestRpcName = "GCO_ConfigSyncRequest";

		private const int ConfigSyncProtocolVersion = 3;

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

		private static readonly HashSet<ConfigEntryBase> GcoPrimaryCommandRegisteredEntries = new HashSet<ConfigEntryBase>();

		private static readonly HashSet<ConfigEntryBase> GcoAllCommandRegisteredEntries = new HashSet<ConfigEntryBase>();

		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 bool _gcoFlatConsoleCommandsRegistered;

		private static int GcoConsoleFeatureCollisionCount;

		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<bool> SyncConfigInMultiplayer = null;

		internal static ConfigEntry<bool> LimitGuestsAuthority = 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> DebugSledgeAlternateMoveset = 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> MobMaintainDirectionWhenStaggered = null;

		internal static ConfigEntry<bool> PlayerMaintainDirectionWhenStaggered = 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<bool> UseDamageCurveInPve = null;

		internal static ConfigEntry<float> PveAlternateDamageCurveBaseRawDamage = null;

		internal static ConfigEntry<float> PveAlternateDamageCurveExponent = null;

		internal static ConfigEntry<float> PveAlternateDamageCurveMinimumMultiplier = null;

		internal static ConfigEntry<float> PveAlternateDamageCurveMaximumMultiplier = null;

		internal static ConfigEntry<bool> UseDamageCurveInPvp = null;

		internal static ConfigEntry<float> PvpAlternateDamageCurveBaseRawDamage = null;

		internal static ConfigEntry<float> PvpAlternateDamageCurveExponent = null;

		internal static ConfigEntry<float> PvpAlternateDamageCurveMinimumMultiplier = null;

		internal static ConfigEntry<float> PvpAlternateDamageCurveMaximumMultiplier = 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> GlobalBackstabDamageMultiplier = null;

		internal static ConfigEntry<float> GlobalPvpBackstabDamageMultiplier = 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<bool> CanStaggerRangedAttacksWithParryPve = null;

		internal static ConfigEntry<bool> CanStaggerRangedAttacksWithParryPvp = null;

		internal static ConfigEntry<bool> CanStaggerAoeAttacksWithParryPve = null;

		internal static ConfigEntry<bool> CanStaggerAoeAttacksWithParryPvp = 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> GlobalSneakDamageMultiplier = null;

		internal static ConfigEntry<bool> SneakDamageScalesWithSneakLevel = null;

		internal static ConfigEntry<float> SneakDamageScaleBaseMultiplier = null;

		internal static ConfigEntry<float> SneakDamageMultiplierPerSneakLevel = null;

		internal static ConfigEntry<bool> SneakXpOnSuccessfulSneakAttack = null;

		internal static ConfigEntry<float> SneakXpOnSuccessfulSneakAttackBaseAmount = null;

		internal static ConfigEntry<bool> SneakXpScalesWithSneakDamageMultiplier = null;

		internal static ConfigEntry<float> SneakXpRangedAttackMultiplier = 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<bool> BetterLightningEffects = null;

		internal static ConfigEntry<float> HimminAflLightningChainChance = null;

		internal static ConfigEntry<float> DundrLightningChainChancePerPellet = null;

		internal static ConfigEntry<float> StaffLightningRecoilStrengthMultiplier = 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<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;

		p