Please disclose if any significant portion of your mod was created using AI tools by adding the 'AI Generated' category. Failing to do so may result in the mod being removed from Thunderstore.
Decompiled source of GoosCombatOverhaul v2.0.2
BepInEx/plugins/GooCombatOverhaul/GooCombatOverhaul.dll
Decompiled a week ago
The result has been truncated due to the large size, download it to view full contents!
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 ConditionalConfigSync; using HarmonyLib; using Microsoft.CodeAnalysis; using UnityEngine; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)] [assembly: TargetFramework(".NETFramework,Version=v4.7.2", FrameworkDisplayName = ".NET Framework 4.7.2")] [assembly: AssemblyCompany("GooCombatOverhaul")] [assembly: AssemblyConfiguration("Debug")] [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 { [BepInDependency("_shudnal.ConditionalConfigSync", "1.0.8")] [BepInPlugin("goo.valheim.gooscombatoverhaul", "Goo's Combat Overhaul", "2.0.2")] public sealed class GooCombatOverhaulPlugin : BaseUnityPlugin { private enum DamageBonusKind { Backstab, StaggeredEnemy, Flanking, CounterDamage } private enum ModFeature { Damage, Staggering, HyperArmor, CounterDamage, HitStop, AttackMovement, Animation, AttackRotation, HitRay, StealthAttributes, MultiTargetPenalty, Pvp, Resources, Blocking } private enum IncomingParryStaggerSource { None, Ranged, Aoe } [Flags] private enum RuntimeRefreshFlags { None = 0, Attack = 1, Blocking = 2, Staff = 4, Character = 8, Player = 0x10, EquipmentVisual = 0x20 } private enum ArmorWeightClass { Light, Medium, Heavy } 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 = null; public Collider Collider = null; public Vector3 Point; public float Distance; } private static class DurabilityPatches { public static void AttackDurabilityPrefix(Attack __instance, ref DurabilityPatchState? __state) { if (AlternateEnvironmentHitRayPassDepth > 0) { __state = null; return; } __state = CaptureDurabilityState((__instance != null) ? __instance.GetWeapon() : null); } public static void SingleItemDurabilityPrefix(ItemData toolItem, ref DurabilityPatchState? __state) { __state = CaptureDurabilityState(toolItem); } public static void BlockDurabilityPrefix(Humanoid __instance, ref DurabilityPatchState? __state) { ItemData val = GetEquippedItem(__instance, "m_leftItem") ?? ((__instance != null) ? __instance.GetCurrentWeapon() : null); __state = CaptureDurabilityState(val); } public static void ArmorDurabilityPrefix(Player __instance, ref DurabilityPatchState? __state) { if ((Object)(object)__instance == (Object)null) { __state = null; return; } __state = CaptureDurabilityState(GetEquippedItem((Humanoid)(object)__instance, "m_chestItem"), GetEquippedItem((Humanoid)(object)__instance, "m_legItem"), GetEquippedItem((Humanoid)(object)__instance, "m_helmetItem"), GetEquippedItem((Humanoid)(object)__instance, "m_shoulderItem")); } public static void GetPlaceDurabilityPostfix(ItemData tool, ref float __result) { if (ModActive && tool != null && !(__result <= 0f)) { bool unbreakable; float durabilityConsumptionMultiplier = GetDurabilityConsumptionMultiplier(tool, out unbreakable); __result = (unbreakable ? 0f : (__result * durabilityConsumptionMultiplier)); } } public static Exception? DurabilityFinalizer(Exception? __exception, DurabilityPatchState? __state) { ApplyDurabilityState(__state); return __exception; } } 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 bool Restored { get; set; } } private sealed class WeaponVisualSuppressionState { private readonly List<WeaponParticleSystemState> _systems; private readonly List<WeaponTrailRendererState> _trailRenderers; private readonly List<WeaponMeleeTrailState> _meleeTrails; private readonly List<WeaponLightState> _lights; private WeaponVisualSuppressionState(GameObject root) { _systems = (from system in root.GetComponentsInChildren<ParticleSystem>(true) where (Object)(object)system != (Object)null select new WeaponParticleSystemState(system)).ToList(); _trailRenderers = (from trail in root.GetComponentsInChildren<TrailRenderer>(true) where (Object)(object)trail != (Object)null select new WeaponTrailRendererState(trail)).ToList(); _meleeTrails = (from trail in root.GetComponentsInChildren<MeleeWeaponTrail>(true) where (Object)(object)trail != (Object)null select new WeaponMeleeTrailState(trail)).ToList(); _lights = (from light in root.GetComponentsInChildren<Light>(true) where (Object)(object)light != (Object)null select new WeaponLightState(light)).ToList(); } public static WeaponVisualSuppressionState Capture(GameObject root) { return new WeaponVisualSuppressionState(root); } public void Disable() { foreach (WeaponParticleSystemState system in _systems) { system.Disable(); } foreach (WeaponTrailRendererState trailRenderer in _trailRenderers) { trailRenderer.Disable(); } foreach (WeaponMeleeTrailState meleeTrail in _meleeTrails) { meleeTrail.Disable(); } foreach (WeaponLightState light in _lights) { light.Disable(); } } public void Restore() { foreach (WeaponParticleSystemState system in _systems) { system.Restore(); } foreach (WeaponTrailRendererState trailRenderer in _trailRenderers) { trailRenderer.Restore(); } foreach (WeaponMeleeTrailState meleeTrail in _meleeTrails) { meleeTrail.Restore(); } foreach (WeaponLightState light in _lights) { light.Restore(); } } } private sealed class WeaponMeleeTrailState { private readonly MeleeWeaponTrail _trail; private readonly bool _emit; public WeaponMeleeTrailState(MeleeWeaponTrail trail) { _trail = trail; _emit = (Object)(object)trail != (Object)null && MeleeWeaponTrailEmitRef.Invoke(trail); } public void Disable() { if ((Object)(object)_trail != (Object)null) { _trail.Emit = false; } } public void Restore() { if ((Object)(object)_trail != (Object)null) { _trail.Emit = _emit; } } } private sealed class WeaponLightState { private readonly Light _light; private readonly bool _enabled; public WeaponLightState(Light light) { _light = light; _enabled = ((Behaviour)light).enabled; } public void Disable() { if ((Object)(object)_light != (Object)null) { ((Behaviour)_light).enabled = false; } } public void Restore() { if ((Object)(object)_light != (Object)null) { ((Behaviour)_light).enabled = _enabled; } } } private sealed class WeaponTrailRendererState { private readonly TrailRenderer _renderer; private readonly bool _enabled; public WeaponTrailRendererState(TrailRenderer renderer) { _renderer = renderer; _enabled = ((Renderer)renderer).enabled; } public void Disable() { if ((Object)(object)_renderer != (Object)null) { ((Renderer)_renderer).enabled = false; } } public void Restore() { if ((Object)(object)_renderer != (Object)null) { ((Renderer)_renderer).enabled = _enabled; } } } private sealed class WeaponParticleSystemState { private readonly ParticleSystem _system; private readonly ParticleSystemRenderer? _renderer; private readonly bool _emissionEnabled; private readonly bool _rendererEnabled; private readonly bool _wasPlaying; private readonly bool _wasPaused; public WeaponParticleSystemState(ParticleSystem system) { //IL_001d: Unknown result type (might be due to invalid IL or missing references) //IL_0022: Unknown result type (might be due to invalid IL or missing references) _system = system; _renderer = ((Component)system).GetComponent<ParticleSystemRenderer>(); EmissionModule emission = system.emission; _emissionEnabled = ((EmissionModule)(ref emission)).enabled; _rendererEnabled = (Object)(object)_renderer != (Object)null && ((Renderer)_renderer).enabled; _wasPlaying = system.isPlaying; _wasPaused = system.isPaused; } public void Disable() { //IL_0019: Unknown result type (might be due to invalid IL or missing references) //IL_001e: Unknown result type (might be due to invalid IL or missing references) if (!((Object)(object)_system == (Object)null)) { EmissionModule emission = _system.emission; ((EmissionModule)(ref emission)).enabled = false; _system.Stop(true, (ParticleSystemStopBehavior)0); if ((Object)(object)_renderer != (Object)null) { ((Renderer)_renderer).enabled = false; } } } public void Restore() { //IL_001c: Unknown result type (might be due to invalid IL or missing references) //IL_0021: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)_system == (Object)null) { return; } EmissionModule emission = _system.emission; ((EmissionModule)(ref emission)).enabled = _emissionEnabled; if ((Object)(object)_renderer != (Object)null) { ((Renderer)_renderer).enabled = _rendererEnabled; } if (((Component)_system).gameObject.activeInHierarchy) { if (_wasPaused) { _system.Pause(true); } else if (_wasPlaying) { _system.Play(true); } } } } private sealed class EquipmentMovementModifierCache { public float Total { get; } public EquipmentMovementModifierCache(float total) { Total = total; } } 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 StaffSummonConfig { public ConfigEntry<bool> AttackPlayersInPvp { get; } public ConfigEntry<float> SizeMultiplier { get; } public ConfigEntry<float> AttackSpeedMultiplier { get; } public ConfigEntry<int> Level { get; } public ConfigEntry<float>? HealthMultiplier { get; } public ConfigEntry<float> HealthConsumptionRate { get; } public ConfigEntry<int> BaseSpawnCapLevel1 { get; } public ConfigEntry<int> BaseSpawnCapLevel2 { get; } public ConfigEntry<int> BaseSpawnCapLevel3 { get; } public ConfigEntry<int> BaseSpawnCapLevel4 { get; } public StaffSummonConfig(ConfigEntry<bool> attackPlayersInPvp, ConfigEntry<float> sizeMultiplier, ConfigEntry<float> attackSpeedMultiplier, ConfigEntry<int> level, ConfigEntry<float>? healthMultiplier, ConfigEntry<float> healthConsumptionRate, ConfigEntry<int> baseSpawnCapLevel1, ConfigEntry<int> baseSpawnCapLevel2, ConfigEntry<int> baseSpawnCapLevel3, ConfigEntry<int> baseSpawnCapLevel4) { AttackPlayersInPvp = attackPlayersInPvp; SizeMultiplier = sizeMultiplier; AttackSpeedMultiplier = attackSpeedMultiplier; Level = level; HealthMultiplier = healthMultiplier; HealthConsumptionRate = healthConsumptionRate; BaseSpawnCapLevel1 = baseSpawnCapLevel1; BaseSpawnCapLevel2 = baseSpawnCapLevel2; BaseSpawnCapLevel3 = baseSpawnCapLevel3; BaseSpawnCapLevel4 = baseSpawnCapLevel4; } } 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 { return (_entry != null) ? _entry.Value : _value; } set { if (_entry != null) { _entry.Value = value; } else { _value = value; } } } public T DefaultValue => (_entry != null) ? ((T)((ConfigEntryBase)_entry).DefaultValue) : _value; public Setting(ConfigEntry<T> entry) { _entry = entry; _value = entry.Value; } public Setting(T value) { _entry = null; _value = value; } } internal sealed class RoleSettings<T> { public Setting<T> Primary1 { get; } public Setting<T> Primary2 { get; } public Setting<T> Primary3 { get; } public Setting<T> Primary4 { get; } public Setting<T> Secondary { get; } public RoleSettings(Setting<T> primary1, Setting<T> primary2, Setting<T> primary3, Setting<T> secondary, Setting<T>? primary4 = null) { Primary1 = primary1; Primary2 = primary2; Primary3 = primary3; Primary4 = primary4 ?? primary3; Secondary = secondary; } public Setting<T> Get(AttackRole role) { if (1 == 0) { } Setting<T> result = role switch { AttackRole.Primary2 => Primary2, AttackRole.Primary3 => Primary3, AttackRole.Primary4 => Primary4, AttackRole.Secondary => Secondary, _ => Primary1, }; if (1 == 0) { } return result; } 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); } return (_basicEntry != null) ? ToFullJumpAttackUsed(_basicEntry.Value) : DefaultJumpAttackUsed(_category); } 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<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<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) { 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; } public float GetBaseDamageMultiplier() { return IsFeatureApplied(Category, ModFeature.Damage) ? BaseDamageMultiplier.Value : 1f; } public float GetBlockStaminaConsumptionRate() { return IsFeatureApplied(Category, ModFeature.Blocking) ? BlockStaminaConsumptionRate.Value : 1f; } public float GetBlockingStaminaRegenMultiplier() { return IsFeatureApplied(Category, ModFeature.Blocking) ? BlockingStaminaRegenMultiplier.Value : 1f; } public float GetBlockBreakThresholdMultiplier() { return IsFeatureApplied(Category, ModFeature.Blocking) ? BlockBreakThresholdMultiplier.Value : 1f; } public StaggerApplicationMode GetStaggerMode(AttackRole role) { return IsFeatureApplied(Category, ModFeature.Staggering) ? StaggerMode.Get(role).Value : StaggerApplicationMode.MultiplyVanilla; } public float GetStaggerPowerValue(AttackRole role) { return IsFeatureApplied(Category, ModFeature.Staggering) ? StaggerPowerValue.Get(role).Value : 1f; } public float GetDamageToStaggeredEnemyMultiplier(AttackRole role) { return IsFeatureApplied(Category, ModFeature.Staggering) ? DamageToStaggeredEnemyMultiplier.Get(role).Value : 1f; } public HyperArmorMode GetHyperArmorMode(AttackRole role) { return IsFeatureApplied(Category, ModFeature.HyperArmor) ? HyperArmorMode.Get(role).Value : GooCombatOverhaul.HyperArmorMode.Off; } public float GetDamageTakenMultiplier(AttackRole role) { return IsFeatureApplied(Category, ModFeature.HyperArmor) ? DamageTakenMultiplier.Get(role).Value : 1f; } public float GetStaggerTakenMultiplier(AttackRole role) { return IsFeatureApplied(Category, ModFeature.HyperArmor) ? StaggerTakenMultiplier.Get(role).Value : 1f; } public float GetKnockbackTakenMultiplier(AttackRole role) { return IsFeatureApplied(Category, ModFeature.HyperArmor) ? KnockbackTakenMultiplier.Get(role).Value : 1f; } public float GetPvpDamageTakenMultiplierDuringHyperArmor(AttackRole role) { return IsFeatureApplied(Category, ModFeature.HyperArmor) ? PvpDamageTakenMultiplierDuringHyperArmor.Get(role).Value : 1f; } public float GetPvpStaggerTakenMultiplierDuringHyperArmor(AttackRole role) { return IsFeatureApplied(Category, ModFeature.HyperArmor) ? PvpStaggerTakenMultiplierDuringHyperArmor.Get(role).Value : 1f; } public float GetPvpKnockbackTakenMultiplierDuringHyperArmor(AttackRole role) { return IsFeatureApplied(Category, ModFeature.HyperArmor) ? PvpKnockbackTakenMultiplierDuringHyperArmor.Get(role).Value : 1f; } public bool GetHitStopOnHit(AttackRole role) { return IsFeatureApplied(Category, ModFeature.HitStop) && GetHitStopDurationMultiplier(role) > 0f; } public float GetHitStopDurationMultiplier(AttackRole role) { return IsFeatureApplied(Category, ModFeature.HitStop) ? HitStopDurationMultiplier.Get(role).Value : 1f; } public float GetPvpHitStopDurationMultiplier(AttackRole role) { return IsFeatureApplied(Category, ModFeature.HitStop) ? PvpHitStopDurationMultiplier.Get(role).Value : 1f; } public bool GetCounterDamageEnabled(AttackRole role) { return IsFeatureApplied(Category, ModFeature.CounterDamage) && CounterDamageEnabled.Get(role).Value; } public float GetCounterDamageMultiplier(AttackRole role) { return IsFeatureApplied(Category, ModFeature.CounterDamage) ? CounterDamageMultiplier.Get(role).Value : 1f; } public float GetPvpCounterDamageMultiplier(AttackRole role) { return IsFeatureApplied(Category, ModFeature.CounterDamage) ? PvpCounterDamageMultiplier.Get(role).Value : 1f; } public float GetDamageRateMultiplier(AttackRole role) { return IsFeatureApplied(Category, ModFeature.Damage) ? DamageRateMultiplier.Get(role).Value : 1f; } public float GetChopDamageMultiplier(AttackRole role) { return IsFeatureApplied(Category, ModFeature.Damage) ? ChopDamageMultiplier.Get(role).Value : DefaultChopDamageMultiplier(Category); } public float GetPickaxeDamageMultiplier(AttackRole role) { return IsFeatureApplied(Category, ModFeature.Damage) ? PickaxeDamageMultiplier.Get(role).Value : VanillaPickaxeDamageMultiplier(Category); } public float GetAirborneDamageMultiplier(AttackRole role) { return IsFeatureApplied(Category, ModFeature.Damage) ? AirborneDamageMultiplier.Get(role).Value : 1f; } public float GetAirborneStaggerMultiplier(AttackRole role) { return IsWeaponCategoryApplied(Category) ? AirborneStaggerMultiplier.Get(role).Value : 1f; } public float GetAirborneRotationFactor(AttackRole role) { return IsFeatureApplied(Category, ModFeature.AttackRotation) ? AirborneRotationFactor.Get(role).Value : 1f; } public float GetStaminaRateMultiplier(AttackRole role) { return IsFeatureApplied(Category, ModFeature.Resources) ? StaminaRateMultiplier.Get(role).Value : 1f; } public float GetEitrRateMultiplier(AttackRole role) { return IsFeatureApplied(Category, ModFeature.Resources) ? EitrRateMultiplier.Get(role).Value : 1f; } public float GetAttackMovementModifier(AttackRole role) { return IsFeatureApplied(Category, ModFeature.AttackMovement) ? AttackMovementModifier.Get(role).Value : 1f; } public AttackMovementApplicationMode GetAttackMovementApplicationMode(AttackRole role) { return IsFeatureApplied(Category, ModFeature.AttackMovement) ? AttackMovementApplicationMode.Get(role).Value : GooCombatOverhaul.AttackMovementApplicationMode.FullAnimation; } public float GetLungeDistanceMultiplier(AttackRole role) { return IsFeatureApplied(Category, ModFeature.AttackMovement) ? LungeDistanceMultiplier.Get(role).Value : 1f; } public LungeApplicationMode GetLungeApplicationMode(AttackRole role) { return IsFeatureApplied(Category, ModFeature.AttackMovement) ? LungeApplicationMode.Get(role).Value : GooCombatOverhaul.LungeApplicationMode.BeforeHitbox; } public float GetAttackAnimationSpeedMultiplier(AttackRole role) { return IsAnimationFeatureApplied(Category) ? AttackAnimationSpeedMultiplier.Get(role).Value : 1f; } public float GetRecoveryAnimationSpeedMultiplier(AttackRole role) { return IsAnimationFeatureApplied(Category) ? RecoveryAnimationSpeedMultiplier.Get(role).Value : 1f; } public float GetAttackRotationFactor(AttackRole role) { return IsFeatureApplied(Category, ModFeature.AttackRotation) ? Mathf.Max(0f, (AttackRotationFactor.Get(role).Value < 0f) ? 1f : AttackRotationFactor.Get(role).Value) : 1f; } public bool GetLockRotationAfterAttackTrigger(AttackRole role) { return IsFeatureApplied(Category, ModFeature.AttackRotation) && LockRotationAfterAttackTrigger.Get(role).Value; } public float GetAdrenalineMultiplier(AttackRole role) { return IsFeatureApplied(Category, ModFeature.Resources) ? AdrenalineMultiplier.Get(role).Value : 1f; } public float GetPvpDamageMultiplier(AttackRole role) { return IsFeatureApplied(Category, ModFeature.Pvp) ? PvpDamageMultiplier.Get(role).Value : 1f; } public float GetPvpStaggerMultiplier(AttackRole role) { return IsFeatureApplied(Category, ModFeature.Pvp) ? PvpStaggerMultiplier.Get(role).Value : 1f; } public float GetPvpStaggerDurationSeconds(AttackRole role) { return IsFeatureApplied(Category, ModFeature.Pvp) ? PvpStaggerDurationSeconds.Get(role).Value : DefaultPvpStaggerDuration(Category, role); } public float GetPvpKnockbackForceMultiplier(AttackRole role) { return IsFeatureApplied(Category, ModFeature.Pvp) ? PvpKnockbackForceMultiplier.Get(role).Value : 1f; } public float GetKnockbackForceMultiplier(AttackRole role) { return IsWeaponCategoryApplied(Category) ? KnockbackForceMultiplier.Get(role).Value : 1f; } public BlockCancelMode GetBlockCancelMode(AttackRole role) { return IsWeaponCategoryApplied(Category) ? BlockCancelMode.Get(role).Value : GooCombatOverhaul.BlockCancelMode.Disabled; } public float GetBlockCancelAnimationSpeedMultiplier(AttackRole role) { return IsWeaponCategoryApplied(Category) ? BlockCancelAnimationSpeedMultiplier.Get(role).Value : 1f; } } 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 object? AttackInstance { get; } public bool StartedAirborne { get; } public AttackRuntimeState(WeaponCategory category, AttackRole role, object? attackInstance, bool startedAirborne = false) { Category = category; Role = role; AttackInstance = attackInstance; StartedAirborne = startedAirborne; } } private readonly struct MeleeHitStopRuntimeState { public WeaponCategory Category { get; } public AttackRole Role { get; } public float EndTime { get; } public object? AttackInstance { get; } public bool IsPvpHitStop { get; } public MeleeHitStopRuntimeState(WeaponCategory category, AttackRole role, float endTime, object? attackInstance, bool isPvpHitStop = false) { Category = category; Role = role; EndTime = endTime; AttackInstance = attackInstance; 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 object? AttackInstance { get; } public HyperArmorRuntimeState(WeaponCategory category, AttackRole role, HyperArmorMode mode, object? attackInstance) { Category = category; Role = role; Mode = mode; AttackInstance = attackInstance; } } private sealed class OwnedFloatRuntimeValue { private float _original; private float _lastApplied; private bool _owns; public float Original => _original; public OwnedFloatRuntimeValue(float original) { _original = original; _lastApplied = original; } public float GetBase(float current) { ObserveExternal(current); return _original; } public void Apply(ref float field, float target) { ObserveExternal(field); if (Mathf.Approximately(target, _original)) { Restore(ref field); return; } if (!Mathf.Approximately(field, target)) { field = target; } _lastApplied = target; _owns = true; } public void Restore(ref float field) { if (!_owns) { _original = field; return; } if (Mathf.Approximately(field, _lastApplied)) { field = _original; } else { _original = field; } _owns = false; } private void ObserveExternal(float current) { if (_owns) { if (!Mathf.Approximately(current, _lastApplied)) { _original = current; _owns = false; } } else { _original = current; } } } private sealed class OwnedVector3RuntimeValue { private Vector3 _original; private Vector3 _lastApplied; private bool _owns; public OwnedVector3RuntimeValue(Vector3 original) { //IL_0009: Unknown result type (might be due to invalid IL or missing references) //IL_000a: Unknown result type (might be due to invalid IL or missing references) //IL_0010: Unknown result type (might be due to invalid IL or missing references) //IL_0011: Unknown result type (might be due to invalid IL or missing references) _original = original; _lastApplied = original; } public Vector3 GetBase(Vector3 current) { //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_000a: Unknown result type (might be due to invalid IL or missing references) //IL_000f: 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) ObserveExternal(current); return _original; } public void Apply(Transform transform, Vector3 target) { //IL_000f: Unknown result type (might be due to invalid IL or missing references) //IL_0014: Unknown result type (might be due to invalid IL or missing references) //IL_0016: Unknown result type (might be due to invalid IL or missing references) //IL_001d: Unknown result type (might be due to invalid IL or missing references) //IL_001f: Unknown result type (might be due to invalid IL or missing references) //IL_0024: Unknown result type (might be due to invalid IL or missing references) //IL_0029: Unknown result type (might be due to invalid IL or missing references) //IL_004a: Unknown result type (might be due to invalid IL or missing references) //IL_004b: Unknown result type (might be due to invalid IL or missing references) //IL_004c: Unknown result type (might be due to invalid IL or missing references) //IL_0051: Unknown result type (might be due to invalid IL or missing references) //IL_006f: Unknown result type (might be due to invalid IL or missing references) //IL_0070: Unknown result type (might be due to invalid IL or missing references) //IL_0067: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)transform == (Object)null) { return; } Vector3 localScale = transform.localScale; ObserveExternal(localScale); Vector3 val = target - _original; if (((Vector3)(ref val)).sqrMagnitude <= 1E-06f) { Restore(transform); return; } val = localScale - target; if (((Vector3)(ref val)).sqrMagnitude > 1E-06f) { transform.localScale = target; } _lastApplied = target; _owns = true; } public void Restore(Transform transform) { //IL_000f: Unknown result type (might be due to invalid IL or missing references) //IL_0014: Unknown result type (might be due to invalid IL or missing references) //IL_002c: Unknown result type (might be due to invalid IL or missing references) //IL_002e: Unknown result type (might be due to invalid IL or missing references) //IL_0033: Unknown result type (might be due to invalid IL or missing references) //IL_0038: Unknown result type (might be due to invalid IL or missing references) //IL_0024: Unknown result type (might be due to invalid IL or missing references) //IL_0025: Unknown result type (might be due to invalid IL or missing references) //IL_005f: Unknown result type (might be due to invalid IL or missing references) //IL_0060: Unknown result type (might be due to invalid IL or missing references) //IL_0051: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)transform == (Object)null) { return; } Vector3 localScale = transform.localScale; if (!_owns) { _original = localScale; return; } Vector3 val = localScale - _lastApplied; if (((Vector3)(ref val)).sqrMagnitude <= 1E-06f) { transform.localScale = _original; } else { _original = localScale; } _owns = false; } private void ObserveExternal(Vector3 current) { //IL_0040: Unknown result type (might be due to invalid IL or missing references) //IL_0041: Unknown result type (might be due to invalid IL or missing references) //IL_000c: Unknown result type (might be due to invalid IL or missing references) //IL_000e: Unknown result type (might be due to invalid IL or missing references) //IL_0013: Unknown result type (might be due to invalid IL or missing references) //IL_0018: Unknown result type (might be due to invalid IL or missing references) //IL_002d: Unknown result type (might be due to invalid IL or missing references) //IL_002e: Unknown result type (might be due to invalid IL or missing references) if (_owns) { Vector3 val = current - _lastApplied; if (((Vector3)(ref val)).sqrMagnitude > 1E-06f) { _original = current; _owns = false; } } else { _original = current; } } } private sealed class CharacterRuntimeDefaults { private readonly OwnedVector3RuntimeValue _localScale; private readonly OwnedFloatRuntimeValue _jogSpeed; private readonly OwnedFloatRuntimeValue _walkSpeed; private readonly OwnedFloatRuntimeValue _runSpeed; public CharacterRuntimeDefaults(Character character) { //IL_000f: Unknown result type (might be due to invalid IL or missing references) _localScale = new OwnedVector3RuntimeValue(((Component)character).transform.localScale); _jogSpeed = new OwnedFloatRuntimeValue(character.m_speed); _walkSpeed = new OwnedFloatRuntimeValue(character.m_walkSpeed); _runSpeed = new OwnedFloatRuntimeValue(character.m_runSpeed); } public void ApplyScale(Character character, float multiplier) { //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) //IL_0017: Unknown result type (might be due to invalid IL or missing references) //IL_0024: Unknown result type (might be due to invalid IL or missing references) //IL_0035: Unknown result type (might be due to invalid IL or missing references) Vector3 val = _localScale.GetBase(((Component)character).transform.localScale); _localScale.Apply(((Component)character).transform, val * Mathf.Clamp(multiplier, 0.2f, 5f)); } public void ApplyMovementSpeeds(Character character, float multiplier) { multiplier = Mathf.Clamp(multiplier, 0.05f, 10f); float num = _jogSpeed.GetBase(character.m_speed); float num2 = _walkSpeed.GetBase(character.m_walkSpeed); float num3 = _runSpeed.GetBase(character.m_runSpeed); _jogSpeed.Apply(ref character.m_speed, num * multiplier); _walkSpeed.Apply(ref character.m_walkSpeed, num2 * multiplier); _runSpeed.Apply(ref character.m_runSpeed, num3 * multiplier); } public void Restore(Character character) { _localScale.Restore(((Component)character).transform); _jogSpeed.Restore(ref character.m_speed); _walkSpeed.Restore(ref character.m_walkSpeed); _runSpeed.Restore(ref character.m_runSpeed); } } private sealed class PlayerRuntimeDefaults { private readonly OwnedFloatRuntimeValue _baseHealth; private readonly OwnedFloatRuntimeValue _baseStamina; private readonly OwnedFloatRuntimeValue _carryWeight; private readonly OwnedFloatRuntimeValue _eitrRegen; private readonly OwnedFloatRuntimeValue _jumpForce; private readonly OwnedFloatRuntimeValue _jumpStaminaUsage; private readonly OwnedFloatRuntimeValue _runStaminaDrain; private readonly OwnedFloatRuntimeValue _dodgeStaminaUsage; private readonly OwnedFloatRuntimeValue _sneakStaminaDrain; private readonly OwnedFloatRuntimeValue _runSpeed; private readonly OwnedFloatRuntimeValue _jogSpeed; private readonly OwnedFloatRuntimeValue _walkSpeed; private readonly OwnedFloatRuntimeValue _crouchSpeed; private readonly OwnedFloatRuntimeValue _staminaRegen; private readonly OwnedFloatRuntimeValue _staminaRegenTimeMultiplier; public float BaseHealth => _baseHealth.Original; public float BaseStamina => _baseStamina.Original; public float CarryWeight => _carryWeight.Original; public float EitrRegen => _eitrRegen.Original; public float JumpForce => _jumpForce.Original; public float JumpStaminaUsage => _jumpStaminaUsage.Original; public float RunStaminaDrain => _runStaminaDrain.Original; public float DodgeStaminaUsage => _dodgeStaminaUsage.Original; public float SneakStaminaDrain => _sneakStaminaDrain.Original; public float RunSpeed => _runSpeed.Original; public float JogSpeed => _jogSpeed.Original; public float WalkSpeed => _walkSpeed.Original; public float CrouchSpeed => _crouchSpeed.Original; public float StaminaRegen => _staminaRegen.Original; public PlayerRuntimeDefaults(Player player) { _baseHealth = new OwnedFloatRuntimeValue(player.m_baseHP); _baseStamina = new OwnedFloatRuntimeValue(player.m_baseStamina); _carryWeight = new OwnedFloatRuntimeValue(player.m_maxCarryWeight); _eitrRegen = new OwnedFloatRuntimeValue(player.m_eiterRegen); _jumpForce = new OwnedFloatRuntimeValue(((Character)player).m_jumpForce); _jumpStaminaUsage = new OwnedFloatRuntimeValue(((Character)player).m_jumpStaminaUsage); _runStaminaDrain = new OwnedFloatRuntimeValue(player.m_runStaminaDrain); _dodgeStaminaUsage = new OwnedFloatRuntimeValue(player.m_dodgeStaminaUsage); _sneakStaminaDrain = new OwnedFloatRuntimeValue(player.m_sneakStaminaDrain); _runSpeed = new OwnedFloatRuntimeValue(((Character)player).m_runSpeed); _jogSpeed = new OwnedFloatRuntimeValue(((Character)player).m_speed); _walkSpeed = new OwnedFloatRuntimeValue(((Character)player).m_walkSpeed); _crouchSpeed = new OwnedFloatRuntimeValue(((Character)player).m_crouchSpeed); _staminaRegen = new OwnedFloatRuntimeValue(player.m_staminaRegen); _staminaRegenTimeMultiplier = new OwnedFloatRuntimeValue(player.m_staminaRegenTimeMultiplier); } public void ApplyStatic(Player player) { _baseHealth.Apply(ref player.m_baseHP, Mathf.Max(1f, PlayerBaseHealth.Value)); _baseStamina.Apply(ref player.m_baseStamina, Mathf.Max(1f, PlayerBaseStamina.Value)); _carryWeight.Apply(ref player.m_maxCarryWeight, Mathf.Max(0f, PlayerBaseCarryWeight.Value)); float num = _eitrRegen.GetBase(player.m_eiterRegen); _eitrRegen.Apply(ref player.m_eiterRegen, num * Mathf.Clamp(PlayerBaseEitrRegenRate.Value, 0f, 10f)); float num2 = _jumpForce.GetBase(((Character)player).m_jumpForce); float num3 = _jumpStaminaUsage.GetBase(((Character)player).m_jumpStaminaUsage); float num4 = _runStaminaDrain.GetBase(player.m_runStaminaDrain); float num5 = _dodgeStaminaUsage.GetBase(player.m_dodgeStaminaUsage); float num6 = _sneakStaminaDrain.GetBase(player.m_sneakStaminaDrain); float num7 = _runSpeed.GetBase(((Character)player).m_runSpeed); float num8 = _jogSpeed.GetBase(((Character)player).m_speed); float num9 = _walkSpeed.GetBase(((Character)player).m_walkSpeed); float num10 = _crouchSpeed.GetBase(((Character)player).m_crouchSpeed); _jumpForce.Apply(ref ((Character)player).m_jumpForce, num2 * Mathf.Clamp(PlayerJumpForceMultiplier.Value, 0.05f, 10f)); _jumpStaminaUsage.Apply(ref ((Character)player).m_jumpStaminaUsage, num3 * Mathf.Clamp(JumpStaminaConsumptionRate.Value, 0f, 10f)); _runStaminaDrain.Apply(ref player.m_runStaminaDrain, num4 * Mathf.Clamp(RunStaminaConsumptionRate.Value, 0f, 10f)); _dodgeStaminaUsage.Apply(ref player.m_dodgeStaminaUsage, num5 * Mathf.Clamp(RollStaminaConsumptionRate.Value, 0f, 10f)); _sneakStaminaDrain.Apply(ref player.m_sneakStaminaDrain, num6 * Mathf.Clamp(CrouchStaminaConsumptionRate.Value, 0f, 10f)); _runSpeed.Apply(ref ((Character)player).m_runSpeed, num7 * Mathf.Clamp(PlayerRunSpeedMultiplier.Value, 0.05f, 10f)); _jogSpeed.Apply(ref ((Character)player).m_speed, num8 * Mathf.Clamp(PlayerJogSpeedMultiplier.Value, 0.05f, 10f)); _walkSpeed.Apply(ref ((Character)player).m_walkSpeed, num9 * Mathf.Clamp(PlayerWalkSpeedMultiplier.Value, 0.05f, 10f)); _crouchSpeed.Apply(ref ((Character)player).m_crouchSpeed, num10 * Mathf.Clamp(PlayerCrouchSpeedMultiplier.Value, 0.05f, 10f)); } public float GetStaminaRegenBase(Player player) { return _staminaRegen.GetBase(player.m_staminaRegen); } public float GetStaminaRegenTimeMultiplierBase(Player player) { return _staminaRegenTimeMultiplier.GetBase(player.m_staminaRegenTimeMultiplier); } public void ApplyStaminaRegen(Player player, float regen, float timeMultiplier) { _staminaRegen.Apply(ref player.m_staminaRegen, regen); _staminaRegenTimeMultiplier.Apply(ref player.m_staminaRegenTimeMultiplier, timeMultiplier); } public void RestoreStaminaRegen(Player player) { _staminaRegen.Restore(ref player.m_staminaRegen); _staminaRegenTimeMultiplier.Restore(ref player.m_staminaRegenTimeMultiplier); } public void Restore(Player player) { _baseHealth.Restore(ref player.m_baseHP); _baseStamina.Restore(ref player.m_baseStamina); _carryWeight.Restore(ref player.m_maxCarryWeight); _eitrRegen.Restore(ref player.m_eiterRegen); _jumpForce.Restore(ref ((Character)player).m_jumpForce); _jumpStaminaUsage.Restore(ref ((Character)player).m_jumpStaminaUsage); _runStaminaDrain.Restore(ref player.m_runStaminaDrain); _dodgeStaminaUsage.Restore(ref player.m_dodgeStaminaUsage); _sneakStaminaDrain.Restore(ref player.m_sneakStaminaDrain); _runSpeed.Restore(ref ((Character)player).m_runSpeed); _jogSpeed.Restore(ref ((Character)player).m_speed); _walkSpeed.Restore(ref ((Character)player).m_walkSpeed); _crouchSpeed.Restore(ref ((Character)player).m_crouchSpeed); RestoreStaminaRegen(player); } } private sealed class MeadStatusEffectClassification { public bool IsMead { get; } public MeadStatusEffectClassification(bool isMead) { IsMead = isMead; } } private sealed class AttackRuntimeContextHolder { public AttackRuntimeState State { get; } public AttackRuntimeContextHolder(AttackRuntimeState state) { State = state; } } private sealed class IncomingParryStaggerSourceHolder { public IncomingParryStaggerSource Source { get; } public IncomingParryStaggerSourceHolder(IncomingParryStaggerSource source) { Source = source; } } public sealed class BlockingMovementSpeedPatchState { private readonly Player _player; private readonly float _speed; private readonly float _walkSpeed; private readonly float _runSpeed; private readonly float _crouchSpeed; private readonly float _acceleration; private bool _restored; public bool PreservePhysicalAirborneMomentumBaseline { get; } public BlockingMovementSpeedPatchState(Player player, float speed, float walkSpeed, float runSpeed, float crouchSpeed, float acceleration, bool preservePhysicalAirborneMomentumBaseline) { _player = player; _speed = speed; _walkSpeed = walkSpeed; _runSpeed = runSpeed; _crouchSpeed = crouchSpeed; _acceleration = acceleration; PreservePhysicalAirborneMomentumBaseline = preservePhysicalAirborneMomentumBaseline; } public void Restore() { if (!_restored && !((Object)(object)_player == (Object)null)) { _restored = true; ((Character)_player).m_speed = _speed; ((Character)_player).m_walkSpeed = _walkSpeed; ((Character)_player).m_runSpeed = _runSpeed; ((Character)_player).m_crouchSpeed = _crouchSpeed; ((Character)_player).m_acceleration = _acceleration; } } } private sealed class AttackAnimatorSpeedState { private readonly Animator _animator; private float _nativeSpeed; private float _multiplier; private bool _pendingPostFreezeReapply; private float _lastAppliedSpeed; public AttackAnimatorSpeedState(Animator animator, float nativeSpeed, float multiplier) { _animator = animator; _nativeSpeed = Mathf.Clamp(nativeSpeed, 0.0001f, 20f); _multiplier = Mathf.Clamp(multiplier, 0.05f, 20f); _lastAppliedSpeed = _nativeSpeed; ApplyCurrentMultiplier(); } public bool IsFor(Animator animator) { return _animator == animator; } public float ApplyNativeSpeed(float nativeSpeed, float multiplier) { _nativeSpeed = Mathf.Clamp(nativeSpeed, 0.0001f, 20f); _multiplier = Mathf.Clamp(multiplier, 0.05f, 20f); _pendingPostFreezeReapply = false; _lastAppliedSpeed = Mathf.Clamp(_nativeSpeed * _multiplier, 0.0001f, 20f); return _lastAppliedSpeed; } public void SetMultiplier(float multiplier) { _multiplier = Mathf.Clamp(multiplier, 0.05f, 20f); if (!((Object)(object)_animator == (Object)null)) { if (_animator.speed <= 0.001f) { _pendingPostFreezeReapply = true; } else { ApplyCurrentMultiplier(); } } } public void EnsureApplied() { if (!((Object)(object)_animator == (Object)null) && !(_animator.speed <= 0.001f)) { if (_pendingPostFreezeReapply) { _pendingPostFreezeReapply = false; } if (!Mathf.Approximately(_animator.speed, _lastAppliedSpeed)) { _animator.speed = _lastAppliedSpeed; } } } public void Restore() { if (!((Object)(object)_animator == (Object)null) && !(_animator.speed <= 0.001f) && Mathf.Approximately(_animator.speed, _lastAppliedSpeed)) { _animator.speed = _nativeSpeed; } } private void ApplyCurrentMultiplier() { if (!((Object)(object)_animator == (Object)null)) { _lastAppliedSpeed = Mathf.Clamp(_nativeSpeed * _multiplier, 0.0001f, 20f); _animator.speed = _lastAppliedSpeed; } } } private readonly struct AnimatorSpeedValue { private readonly Animator _animator; private readonly float _originalSpeed; private readonly float _multiplier; public AnimatorSpeedValue(Animator animator, float originalSpeed, float multiplier) { _animator = animator; _originalSpeed = originalSpeed; _multiplier = multiplier; } public bool IsFor(Animator animator) { return _animator == animator; } public void Restore() { if ((Object)(object)_animator != (Object)null) { _animator.speed = _originalSpeed; } } public void Reapply() { if ((Object)(object)_animator != (Object)null && _animator.speed > 0.001f) { _animator.speed = _originalSpeed * _multiplier; } } } 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 StaffRuntimeTweakState { private Vector3 _originalScale; private Vector3 _lastAppliedScale; private bool _ownsScale; private float _lastAppliedMaxHealth; private bool _ownsMaxHealth; public StaffRuntimeTweakState(Vector3 originalScale) { //IL_0009: Unknown result type (might be due to invalid IL or missing references) //IL_000a: Unknown result type (might be due to invalid IL or missing references) //IL_0010: Unknown result type (might be due to invalid IL or missing references) //IL_0011: Unknown result type (might be due to invalid IL or missing references) _originalScale = originalScale; _lastAppliedScale = originalScale; } public void ApplyScale(Character character, float multiplier) { //IL_0017: Unknown result type (might be due to invalid IL or missing references) //IL_001c: Unknown result type (might be due to invalid IL or missing references) //IL_0025: Unknown result type (might be due to invalid IL or missing references) //IL_0027: Unknown result type (might be due to invalid IL or missing references) //IL_002c: Unknown result type (might be due to invalid IL or missing references) //IL_0031: Unknown result type (might be due to invalid IL or missing references) //IL_0059: Unknown result type (might be due to invalid IL or missing references) //IL_006e: Unknown result type (might be due to invalid IL or missing references) //IL_0073: Unknown result type (might be due to invalid IL or missing references) //IL_0074: Unknown result type (might be due to invalid IL or missing references) //IL_0075: Unknown result type (might be due to invalid IL or missing references) //IL_0076: Unknown result type (might be due to invalid IL or missing references) //IL_007b: Unknown result type (might be due to invalid IL or missing references) //IL_004a: Unknown result type (might be due to invalid IL or missing references) //IL_004b: Unknown result type (might be due to invalid IL or missing references) //IL_009f: Unknown result type (might be due to invalid IL or missing references) //IL_00a0: Unknown result type (might be due to invalid IL or missing references) //IL_0097: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)character == (Object)null) { return; } Vector3 localScale = ((Component)character).transform.localScale; Vector3 val; if (_ownsScale) { val = localScale - _lastAppliedScale; if (((Vector3)(ref val)).sqrMagnitude > 1E-06f) { _originalScale = localScale; _ownsScale = false; } } Vector3 val2 = _originalScale * Mathf.Clamp(multiplier, 0.05f, 10f); val = localScale - val2; if (((Vector3)(ref val)).sqrMagnitude > 1E-06f) { ((Component)character).transform.localScale = val2; } _lastAppliedScale = val2; _ownsScale = true; } public void ApplyMaxHealth(Character character, float multiplier) { if ((Object)(object)character == (Object)null) { return; } ZNetView component = ((Component)character).GetComponent<ZNetView>(); if (!((Object)(object)component != (Object)null) || !component.IsValid() || component.IsOwner()) { float num = Mathf.Max(0.01f, character.GetMaxHealthBase() * (float)Mathf.Max(1, character.GetLevel())); float num2 = num * Mathf.Clamp(multiplier, 0.01f, 20f); float maxHealth = character.GetMaxHealth(); if (!Mathf.Approximately(maxHealth, num2)) { float num3 = ((maxHealth > 0f) ? Mathf.Clamp01(character.GetHealth() / maxHealth) : 1f); character.SetMaxHealth(num2); character.SetHealth(Mathf.Clamp(num2 * num3, 0f, num2)); } _lastAppliedMaxHealth = num2; _ownsMaxHealth = true; } } public void Restore(Character character) { //IL_0022: Unknown result type (might be due to invalid IL or missing references) //IL_0027: Unknown result type (might be due to invalid IL or missing references) //IL_0028: Unknown result type (might be due to invalid IL or missing references) //IL_002a: Unknown result type (might be due to invalid IL or missing references) //IL_002f: Unknown result type (might be due to invalid IL or missing references) //IL_0034: Unknown result type (might be due to invalid IL or missing references) //IL_0052: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)character == (Object)null) { return; } if (_ownsScale) { Vector3 localScale = ((Component)character).transform.localScale; Vector3 val = localScale - _lastAppliedScale; if (((Vector3)(ref val)).sqrMagnitude <= 1E-06f) { ((Component)character).transform.localScale = _originalScale; } _ownsScale = false; } if (!_ownsMaxHealth) { return; } ZNetView component = ((Component)character).GetComponent<ZNetView>(); if ((Object)(object)component == (Object)null || !component.IsValid() || component.IsOwner()) { float maxHealth = character.GetMaxHealth(); if (Mathf.Approximately(maxHealth, _lastAppliedMaxHealth)) { float num = Mathf.Max(0.01f, character.GetMaxHealthBase() * (float)Mathf.Max(1, character.GetLevel())); float num2 = ((maxHealth > 0f) ? Mathf.Clamp01(character.GetHealth() / maxHealth) : 1f); character.SetMaxHealth(num); character.SetHealth(Mathf.Clamp(num * num2, 0f, num)); } } _ownsMaxHealth = false; } } private sealed class StaffSpawnOrigin { public Character? Owner { get; private set; } public long OwnerPlayerId { get; } public string StaffPrefabName { get; } public bool IsGreenRoots { get; } public bool IsSkeleton { get; } public bool IsSpiritCaller { 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); IsSpiritCaller = IsStaffSpiritCaller(staffConfig); CreatedTime = Time.time; } public StaffSpawnOrigin(long ownerPlayerId, string staffPrefabName) { OwnerPlayerId = ownerPlayerId; StaffPrefabName = staffPrefabName ?? string.Empty; IsGreenRoots = string.Equals(StaffPrefabName, "StaffGreenRoots", StringComparison.OrdinalIgnoreCase); IsSkeleton = string.Equals(StaffPrefabName, "StaffSkeleton", StringComparison.OrdinalIgnoreCase); IsSpiritCaller = string.Equals(StaffPrefabName, "StaffSpiritCaller", StringComparison.OrdinalIgnoreCase); Owner = (Character?)(object)((ownerPlayerId != 0L) ? Player.GetPlayer(ownerPlayerId) : null); CreatedTime = Time.time; } public Player? ResolveOwnerPlayer() { Character? owner = Owner; Player val = (Player)(object)((owner is Player) ? owner : null); if (val != null && (OwnerPlayerId == 0L || val.GetPlayerID() == OwnerPlayerId)) { return val; } if (OwnerPlayerId == 0) { return null; } Player player = Player.GetPlayer(OwnerPlayerId); if ((Object)(object)player != (Object)null) { Owner = (Character?)(object)player; } return player; } } private sealed class DamageBonusStackState { public static readonly DamageBonusStackState Empty = new DamageBonusStackState(1f, 1f, 1f, 1f); public float BackstabMultiplier { get; } public float StaggeredEnemyMultiplier { get; } public float FlankingMultiplier { get; } public float CounterDamageMultiplier { get; } public DamageBonusStackState(float backstabMultiplier, float staggeredEnemyMultiplier, float flankingMultiplier, float counterDamageMultiplier) { BackstabMultiplier = backstabMultiplier; StaggeredEnemyMultiplier = staggeredEnemyMultiplier; FlankingMultiplier = flankingMultiplier; CounterDamageMultiplier = counterDamageMultiplier; } public bool IsActive(DamageBonusKind kind) { return !Mathf.Approximately(Ge