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 VikingWeapons v0.2.0
VikingWeapons.dll
Decompiled 3 days agousing System; using System.Collections.Generic; using System.Diagnostics; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using System.Security; using System.Security.Permissions; using BepInEx; using BepInEx.Configuration; using BepInEx.Logging; using HarmonyLib; using Microsoft.CodeAnalysis; using UnityEngine; using VikingLib.Combat; using VikingLib.Combat.Attacks; using VikingWeapons.Configuration; using VikingWeapons.Profiles; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")] [assembly: AssemblyCompany("DigitalVikings")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyDescription("Weapon archetype overhauls, custom cleave calibrations, animation refinements, and tactical secondary attacks for Valheim and VikingLib.")] [assembly: AssemblyFileVersion("0.2.0.0")] [assembly: AssemblyInformationalVersion("0.2.0+05bd3cc3f72b83b1bf613c555a27acf4af44f355")] [assembly: AssemblyProduct("VikingWeapons")] [assembly: AssemblyTitle("VikingWeapons")] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("0.2.0.0")] [module: UnverifiableCode] [module: RefSafetyRules(11)] 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; } } [CompilerGenerated] [Embedded] [AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)] internal sealed class RefSafetyRulesAttribute : Attribute { public readonly int Version; public RefSafetyRulesAttribute(int P_0) { Version = P_0; } } } namespace VikingWeapons { [BepInPlugin("com.digitalvikings.vikingweapons", "VikingWeapons", "0.2.0")] [BepInDependency(/*Could not decode attribute arguments.*/)] public class VikingWeaponsPlugin : BaseUnityPlugin { public const string ModGUID = "com.digitalvikings.vikingweapons"; public const string ModName = "VikingWeapons"; public const string ModVersion = "0.2.0"; private Harmony _harmony; public static VikingWeaponsPlugin Instance { get; private set; } public static ManualLogSource Log { get; private set; } private void Awake() { //IL_0022: Unknown result type (might be due to invalid IL or missing references) //IL_002c: Expected O, but got Unknown Instance = this; Log = ((BaseUnityPlugin)this).Logger; ModConfig.Init(((BaseUnityPlugin)this).Config); _harmony = new Harmony("com.digitalvikings.vikingweapons"); _harmony.PatchAll(); WeaponProfiles.RegisterAll(); Log.LogInfo((object)"VikingWeapons v0.2.0 initialized successfully."); } private void OnDestroy() { _harmony.UnpatchSelf(); } } } namespace VikingWeapons.Profiles { public static class WeaponProfiles { public static void RegisterAll() { //IL_001c: Unknown result type (might be due to invalid IL or missing references) //IL_0022: Expected O, but got Unknown //IL_0085: Unknown result type (might be due to invalid IL or missing references) //IL_008b: Expected O, but got Unknown //IL_00ce: Unknown result type (might be due to invalid IL or missing references) //IL_00d5: Expected O, but got Unknown //IL_0138: Unknown result type (might be due to invalid IL or missing references) //IL_013f: Expected O, but got Unknown //IL_0186: Unknown result type (might be due to invalid IL or missing references) //IL_018d: Expected O, but got Unknown //IL_01de: Unknown result type (might be due to invalid IL or missing references) //IL_01e5: Expected O, but got Unknown //IL_022c: Unknown result type (might be due to invalid IL or missing references) //IL_0233: Expected O, but got Unknown //IL_0253: Unknown result type (might be due to invalid IL or missing references) //IL_025a: Expected O, but got Unknown //IL_02c2: Unknown result type (might be due to invalid IL or missing references) //IL_02c9: Expected O, but got Unknown //IL_02e1: Unknown result type (might be due to invalid IL or missing references) //IL_02e8: Expected O, but got Unknown //IL_0320: Unknown result type (might be due to invalid IL or missing references) //IL_0327: Expected O, but got Unknown //IL_035f: Unknown result type (might be due to invalid IL or missing references) //IL_0366: Expected O, but got Unknown //IL_03aa: Unknown result type (might be due to invalid IL or missing references) //IL_03b1: Expected O, but got Unknown if (!ModConfig.ModEnabled.Value) { return; } if (ModConfig.SwordOverhaulEnabled.Value) { WeaponAttackProfile val = new WeaponAttackProfile(); float value = ModConfig.SwordPrimaryCleave.Value; val.AddStep("primary_1", ModConfig.SwordDamageMultiplier.Value, value); val.AddStep("primary_2", ModConfig.SwordDamageMultiplier.Value, value); val.AddStep("primary_3", ModConfig.SwordFinisherMultiplier.Value, value); float value2 = ModConfig.SwordSecondaryCleave.Value; AttackStepModifiers val2 = new AttackStepModifiers(ModConfig.SwordSecondaryDamageMultiplier.Value, value2); if (ModConfig.SwordSecondaryPierce.Value) { val2.OverrideDamageType = (DamageType)2; } val.Steps["secondary"] = val2; WeaponAttackRegistry.Register("category_sword", val); } if (ModConfig.BattleaxeOverhaulEnabled.Value) { WeaponAttackProfile val3 = new WeaponAttackProfile(); float value3 = ModConfig.BattleaxePrimaryCleave.Value; val3.AddStep("primary_1", ModConfig.BattleaxeDamageMultiplier.Value, value3); val3.AddStep("primary_2", ModConfig.BattleaxeDamageMultiplier.Value, value3); val3.AddStep("primary_3", ModConfig.BattleaxeFinisherMultiplier.Value, value3); AttackStepModifiers val4 = new AttackStepModifiers(ModConfig.BattleaxeSecondaryDamageMultiplier.Value, 0.375f); if (ModConfig.BattleaxeSecondaryDamageTypeBlunt.Value) { val4.OverrideDamageType = (DamageType)0; } val3.Steps["secondary"] = val4; WeaponAttackRegistry.Register("category_battleaxe", val3); } if (ModConfig.PolearmOverhaulEnabled.Value) { WeaponAttackProfile val5 = new WeaponAttackProfile(); val5.AddStep("primary_1", 1f, 0.375f); val5.AddStep("primary_2", 1f, 0.375f); val5.AddStep("primary_3", 2f, 0.375f); AttackStepModifiers val6 = new AttackStepModifiers(1f, ModConfig.PolearmSecondaryCleave.Value); if (ModConfig.PolearmSecondarySlashDamage.Value) { val6.OverrideDamageType = (DamageType)1; } val5.Steps["secondary"] = val6; WeaponAttackRegistry.Register("category_atgeir", val5); } if (ModConfig.SpearOverhaulEnabled.Value) { WeaponAttackProfile val7 = new WeaponAttackProfile(); val7.AddStep("primary_1", 1f, 0.375f); AttackStepModifiers val8 = new AttackStepModifiers(1.5f, 0f); if (ModConfig.SpearSecondaryHamstringEnabled.Value) { val8.OnHitStatusEffect = "SE_Cripple"; val8.StatusEffectDuration = ModConfig.SpearSecondaryHamstringDuration.Value; val8.StatusEffectValue = ModConfig.SpearSecondaryHamstringPotency.Value; } val7.Steps["secondary"] = val8; WeaponAttackRegistry.Register("category_spear", val7); } if (ModConfig.KnifeOverhaulEnabled.Value) { WeaponAttackProfile val9 = new WeaponAttackProfile(); float value4 = ModConfig.KnifePrimaryCleave.Value; AttackStepModifiers val10 = new AttackStepModifiers(ModConfig.KnifeDamageMultiplier.Value, value4); if (ModConfig.KnifePrimarySlashDamage.Value) { val10.OverrideDamageType = (DamageType)1; } val9.Steps["primary_1"] = val10; AttackStepModifiers val11 = new AttackStepModifiers(ModConfig.KnifeDamageMultiplier.Value, value4); if (ModConfig.KnifePrimarySlashDamage.Value) { val11.OverrideDamageType = (DamageType)1; } val9.Steps["primary_2"] = val11; AttackStepModifiers val12 = new AttackStepModifiers(ModConfig.KnifeFinisherMultiplier.Value, value4); if (ModConfig.KnifeFinisherPierceDamage.Value) { val12.OverrideDamageType = (DamageType)2; } val9.Steps["primary_3"] = val12; float value5 = ModConfig.KnifeSecondaryCleave.Value; AttackStepModifiers val13 = new AttackStepModifiers(ModConfig.KnifeSecondaryDamageMultiplier.Value, value5); if (ModConfig.KnifeSecondaryPierceDamage.Value) { val13.OverrideDamageType = (DamageType)2; } val9.Steps["secondary"] = val13; WeaponAttackRegistry.Register("category_knife", val9); } } } } namespace VikingWeapons.Patches { public class SpearVisualController : MonoBehaviour { private Quaternion _nativeRotation; private Quaternion _flippedRotation; private Vector3 _nativePosition; private Vector3 _flippedPosition; private bool _isFlipped; public bool IsFlipped => _isFlipped; public void Initialize(Vector3 rotEulerOffset, Vector3 posOffset) { //IL_0007: 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_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_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) //IL_0023: 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_003b: Unknown result type (might be due to invalid IL or missing references) //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_0046: Unknown result type (might be due to invalid IL or missing references) _nativeRotation = ((Component)this).transform.localRotation; _flippedRotation = _nativeRotation * Quaternion.Euler(rotEulerOffset); _nativePosition = ((Component)this).transform.localPosition; _flippedPosition = _nativePosition + posOffset; SetFlipped(flipped: true); } public void SetFlipped(bool flipped) { //IL_0019: Unknown result type (might be due to invalid IL or missing references) //IL_0011: Unknown result type (might be due to invalid IL or missing references) //IL_0035: 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) _isFlipped = flipped; ((Component)this).transform.localRotation = (flipped ? _flippedRotation : _nativeRotation); ((Component)this).transform.localPosition = (flipped ? _flippedPosition : _nativePosition); } } [HarmonyPatch] public static class SpearModelPatch { private static readonly FieldRef<VisEquipment, GameObject> RightItemInstanceRef = AccessTools.FieldRefAccess<VisEquipment, GameObject>("m_rightItemInstance"); private static readonly Dictionary<int, bool> SpearHashCache = new Dictionary<int, bool>(); [HarmonyPatch(typeof(VisEquipment), "SetRightHandEquipped")] [HarmonyPostfix] public static void PostfixSetRightHandEquipped(VisEquipment __instance, int hash, bool __result) { //IL_00be: Unknown result type (might be due to invalid IL or missing references) //IL_00bf: Unknown result type (might be due to invalid IL or missing references) if (!ModConfig.ModEnabled.Value || !ModConfig.SpearModelFlipEnabled.Value || !__result || hash == 0 || (Object)(object)__instance == (Object)null || (__instance.m_isArmorStand && !ModConfig.SpearModelFlipArmorStand.Value) || !IsSpear(hash)) { return; } GameObject val = RightItemInstanceRef.Invoke(__instance); if ((Object)(object)val != (Object)null) { SpearVisualController spearVisualController = val.GetComponent<SpearVisualController>(); if ((Object)(object)spearVisualController == (Object)null) { spearVisualController = val.AddComponent<SpearVisualController>(); } Vector3 rotEulerOffset = default(Vector3); ((Vector3)(ref rotEulerOffset))..ctor(ModConfig.SpearModelFlipAngleX.Value, ModConfig.SpearModelFlipAngleY.Value, ModConfig.SpearModelFlipAngleZ.Value); Vector3 posOffset = default(Vector3); ((Vector3)(ref posOffset))..ctor(ModConfig.SpearModelPositionOffsetX.Value, ModConfig.SpearModelPositionOffsetY.Value, ModConfig.SpearModelPositionOffsetZ.Value); spearVisualController.Initialize(rotEulerOffset, posOffset); } } [HarmonyPatch(typeof(Attack), "Start")] [HarmonyPrefix] public static void PrefixAttackStart(Attack __instance, Humanoid character) { if (ModConfig.ModEnabled.Value && ModConfig.SpearModelFlipEnabled.Value && __instance != null && !((Object)(object)character == (Object)null) && __instance.m_attackAnimation == "spear_throw") { SetSpearFlipped(character, flipped: false); } } [HarmonyPatch(typeof(Attack), "Stop")] [HarmonyPostfix] public static void PostfixAttackStop(Attack __instance) { if (ModConfig.ModEnabled.Value && ModConfig.SpearModelFlipEnabled.Value && __instance != null && __instance.m_attackAnimation == "spear_throw") { Humanoid character = HumanoidAttackHelper.GetCharacter(__instance); if ((Object)(object)character != (Object)null) { SetSpearFlipped(character, flipped: true); } } } private static void SetSpearFlipped(Humanoid character, bool flipped) { VisEquipment visEquipment = character.GetVisEquipment(); if ((Object)(object)visEquipment == (Object)null) { return; } GameObject val = RightItemInstanceRef.Invoke(visEquipment); if ((Object)(object)val != (Object)null) { SpearVisualController component = val.GetComponent<SpearVisualController>(); if ((Object)(object)component != (Object)null) { component.SetFlipped(flipped); } } } public static bool IsSpear(int hash) { //IL_0063: Unknown result type (might be due to invalid IL or missing references) //IL_0069: Invalid comparison between Unknown and I4 //IL_0076: Unknown result type (might be due to invalid IL or missing references) //IL_007c: Invalid comparison between Unknown and I4 if (SpearHashCache.TryGetValue(hash, out var value)) { return value; } if ((Object)(object)ObjectDB.instance == (Object)null) { return false; } GameObject itemPrefab = ObjectDB.instance.GetItemPrefab(hash); if ((Object)(object)itemPrefab == (Object)null) { return false; } ItemDrop component = itemPrefab.GetComponent<ItemDrop>(); bool flag = component?.m_itemData?.m_shared != null && (int)component.m_itemData.m_shared.m_skillType == 5 && (int)component.m_itemData.m_shared.m_itemType == 3; SpearHashCache[hash] = flag; return flag; } } [HarmonyPatch] public static class WeaponAttackSpeedPatch { private static readonly FieldRef<ZSyncAnimation, Animator> AnimatorRef = AccessTools.FieldRefAccess<ZSyncAnimation, Animator>("m_animator"); private static readonly FieldRef<CharacterAnimEvent, Character> CharacterAnimRef = AccessTools.FieldRefAccess<CharacterAnimEvent, Character>("m_character"); [HarmonyPatch(typeof(Attack), "Start")] [HarmonyPostfix] [HarmonyPriority(200)] public static void PostfixAttackStart(Attack __instance, bool __result, Humanoid character, ZSyncAnimation zanim) { //IL_00d1: Unknown result type (might be due to invalid IL or missing references) //IL_00d7: Invalid comparison between Unknown and I4 //IL_0075: Unknown result type (might be due to invalid IL or missing references) //IL_007b: Invalid comparison between Unknown and I4 //IL_00fc: Unknown result type (might be due to invalid IL or missing references) //IL_0102: Invalid comparison between Unknown and I4 //IL_00a0: Unknown result type (might be due to invalid IL or missing references) //IL_00a6: Invalid comparison between Unknown and I4 if (!ModConfig.ModEnabled.Value || !__result || (Object)(object)character == (Object)null || (Object)(object)zanim == (Object)null) { return; } ItemData val = __instance.GetWeapon() ?? character.GetCurrentWeapon(); if (val?.m_shared == null) { return; } if (val.m_shared.m_secondaryAttack != null && __instance.m_attackAnimation == val.m_shared.m_secondaryAttack.m_attackAnimation) { if ((int)val.m_shared.m_skillType == 7 && ModConfig.AxeSecondarySpeedEnabled.Value) { MultiplyAnimSpeed(zanim, ModConfig.AxeSecondarySpeedMultiplier.Value); } else if ((int)val.m_shared.m_skillType == 3 && ModConfig.ClubSecondarySpeedEnabled.Value) { MultiplyAnimSpeed(zanim, ModConfig.ClubSecondarySpeedMultiplier.Value); } } else if ((int)val.m_shared.m_skillType == 1 && ModConfig.SwordOverhaulEnabled.Value) { MultiplyAnimSpeed(zanim, ModConfig.SwordAttackSpeedMultiplier.Value); } else if ((int)val.m_shared.m_skillType == 5 && ModConfig.SpearOverhaulEnabled.Value && ModConfig.SpearPrimaryAnimation.Value == "sword_secondary" && ModConfig.SpearPokeSpeedMultiplier.Value > 0f) { MultiplyAnimSpeed(zanim, ModConfig.SpearPokeSpeedMultiplier.Value); } } [HarmonyPatch(typeof(CharacterAnimEvent), "Speed")] [HarmonyPrefix] public static void PrefixCharacterAnimEventSpeed(CharacterAnimEvent __instance, ref float speedScale) { //IL_0055: Unknown result type (might be due to invalid IL or missing references) //IL_005b: Invalid comparison between Unknown and I4 //IL_00d0: Unknown result type (might be due to invalid IL or missing references) //IL_00d6: Invalid comparison between Unknown and I4 //IL_0136: Unknown result type (might be due to invalid IL or missing references) //IL_013c: Invalid comparison between Unknown and I4 //IL_019c: Unknown result type (might be due to invalid IL or missing references) //IL_01a2: Invalid comparison between Unknown and I4 if (!ModConfig.ModEnabled.Value || (Object)(object)__instance == (Object)null) { return; } Character obj = CharacterAnimRef.Invoke(__instance); Humanoid val = (Humanoid)(object)((obj is Humanoid) ? obj : null); if ((Object)(object)val == (Object)null) { return; } ItemData currentWeapon = val.GetCurrentWeapon(); if (currentWeapon?.m_shared != null) { Attack currentAttack = HumanoidAttackHelper.GetCurrentAttack(val); if ((int)currentWeapon.m_shared.m_skillType == 5 && ModConfig.SpearOverhaulEnabled.Value && (currentAttack?.m_attackAnimation ?? currentWeapon.m_shared.m_attack?.m_attackAnimation ?? "") == "sword_secondary") { float num = ((speedScale <= 0.25f) ? 1f : 1.5f); speedScale = num * ModConfig.SpearPokeSpeedMultiplier.Value; } else if ((int)currentWeapon.m_shared.m_skillType == 7 && ModConfig.AxeSecondarySpeedEnabled.Value && (currentAttack?.m_attackAnimation ?? currentWeapon.m_shared.m_secondaryAttack?.m_attackAnimation ?? "") == "axe_secondary") { speedScale *= ModConfig.AxeSecondarySpeedMultiplier.Value; } else if ((int)currentWeapon.m_shared.m_skillType == 3 && ModConfig.ClubSecondarySpeedEnabled.Value && (currentAttack?.m_attackAnimation ?? currentWeapon.m_shared.m_secondaryAttack?.m_attackAnimation ?? "") == "club_secondary") { speedScale *= ModConfig.ClubSecondarySpeedMultiplier.Value; } else if ((int)currentWeapon.m_shared.m_skillType == 1 && ModConfig.SwordOverhaulEnabled.Value) { speedScale *= ModConfig.SwordAttackSpeedMultiplier.Value; } } } private static void MultiplyAnimSpeed(ZSyncAnimation zanim, float factor) { if (!((Object)(object)zanim == (Object)null) && !Mathf.Approximately(factor, 1f)) { Animator val = AnimatorRef.Invoke(zanim); if (!((Object)(object)val == (Object)null)) { float speed = val.speed; zanim.SetSpeed(speed * factor); } } } } [HarmonyPatch] public static class WeaponPrefabPatch { [HarmonyPatch(typeof(ObjectDB), "Awake")] [HarmonyPostfix] public static void PostfixObjectDBAwake(ObjectDB __instance) { ApplyPrefabModifications(__instance); } [HarmonyPatch(typeof(ObjectDB), "CopyOtherDB")] [HarmonyPostfix] public static void PostfixObjectDBCopyOtherDB(ObjectDB __instance) { ApplyPrefabModifications(__instance); } public static void ApplyPrefabModifications(ObjectDB? db) { //IL_0090: Unknown result type (might be due to invalid IL or missing references) //IL_0096: Invalid comparison between Unknown and I4 //IL_0124: Unknown result type (might be due to invalid IL or missing references) //IL_012a: Invalid comparison between Unknown and I4 //IL_0099: Unknown result type (might be due to invalid IL or missing references) //IL_009f: Invalid comparison between Unknown and I4 if (!ModConfig.ModEnabled.Value || (Object)(object)db == (Object)null || db.m_items == null || db.m_items.Count == 0) { return; } foreach (GameObject item in db.m_items) { if ((Object)(object)item == (Object)null) { continue; } ItemDrop component = item.GetComponent<ItemDrop>(); if (component?.m_itemData?.m_shared == null) { continue; } SharedData shared = component.m_itemData.m_shared; if (ModConfig.SpearOverhaulEnabled.Value && (int)shared.m_skillType == 5 && (int)shared.m_itemType == 3 && shared.m_attack != null) { string value = ModConfig.SpearPrimaryAnimation.Value; if (!string.IsNullOrEmpty(value)) { shared.m_attack.m_attackAnimation = value; } if (ModConfig.SpearPrimaryReach.Value > 0f) { shared.m_attack.m_attackRange = ModConfig.SpearPrimaryReach.Value; } if (ModConfig.SpearPrimaryHeight.Value > 0f) { shared.m_attack.m_attackHeight = ModConfig.SpearPrimaryHeight.Value; } } if (ModConfig.PolearmOverhaulEnabled.Value && (int)shared.m_skillType == 4 && shared.m_secondaryAttack != null) { shared.m_secondaryAttack.m_staggerMultiplier = ModConfig.PolearmSecondaryStaggerMultiplier.Value; } } } } } namespace VikingWeapons.Configuration { public static class ModConfig { public static ConfigEntry<bool> ModEnabled; public static ConfigEntry<bool> AxeSecondarySpeedEnabled; public static ConfigEntry<float> AxeSecondarySpeedMultiplier; public static ConfigEntry<bool> BattleaxeOverhaulEnabled; public static ConfigEntry<float> BattleaxePrimaryCleave; public static ConfigEntry<float> BattleaxeDamageMultiplier; public static ConfigEntry<float> BattleaxeFinisherMultiplier; public static ConfigEntry<bool> BattleaxeSecondaryDamageTypeBlunt; public static ConfigEntry<float> BattleaxeSecondaryDamageMultiplier; public static ConfigEntry<bool> SwordOverhaulEnabled; public static ConfigEntry<float> SwordPrimaryCleave; public static ConfigEntry<float> SwordDamageMultiplier; public static ConfigEntry<float> SwordFinisherMultiplier; public static ConfigEntry<bool> SwordSecondaryPierce; public static ConfigEntry<float> SwordSecondaryDamageMultiplier; public static ConfigEntry<float> SwordSecondaryCleave; public static ConfigEntry<float> SwordAttackSpeedMultiplier; public static ConfigEntry<bool> ClubSecondarySpeedEnabled; public static ConfigEntry<float> ClubSecondarySpeedMultiplier; public static ConfigEntry<bool> SpearOverhaulEnabled; public static ConfigEntry<string> SpearPrimaryAnimation; public static ConfigEntry<float> SpearPokeSpeedMultiplier; public static ConfigEntry<float> SpearPrimaryReach; public static ConfigEntry<float> SpearPrimaryHeight; public static ConfigEntry<bool> SpearModelFlipEnabled; public static ConfigEntry<float> SpearModelFlipAngleX; public static ConfigEntry<float> SpearModelFlipAngleY; public static ConfigEntry<float> SpearModelFlipAngleZ; public static ConfigEntry<float> SpearModelPositionOffsetX; public static ConfigEntry<float> SpearModelPositionOffsetY; public static ConfigEntry<float> SpearModelPositionOffsetZ; public static ConfigEntry<bool> SpearModelFlipArmorStand; public static ConfigEntry<bool> SpearSecondaryHamstringEnabled; public static ConfigEntry<float> SpearSecondaryHamstringDuration; public static ConfigEntry<float> SpearSecondaryHamstringPotency; public static ConfigEntry<bool> PolearmOverhaulEnabled; public static ConfigEntry<float> PolearmSecondaryCleave; public static ConfigEntry<bool> PolearmSecondarySlashDamage; public static ConfigEntry<float> PolearmSecondaryStaggerMultiplier; public static ConfigEntry<bool> KnifeOverhaulEnabled; public static ConfigEntry<float> KnifePrimaryCleave; public static ConfigEntry<float> KnifeDamageMultiplier; public static ConfigEntry<float> KnifeFinisherMultiplier; public static ConfigEntry<float> KnifeSecondaryDamageMultiplier; public static ConfigEntry<float> KnifeSecondaryCleave; public static ConfigEntry<bool> KnifePrimarySlashDamage; public static ConfigEntry<bool> KnifeFinisherPierceDamage; public static ConfigEntry<bool> KnifeSecondaryPierceDamage; public static void Init(ConfigFile config) { ModEnabled = config.Bind<bool>("0. General", "ModEnabled", true, "Master toggle for VikingWeapons."); AxeSecondarySpeedEnabled = config.Bind<bool>("1. Axes", "AxeSecondarySpeedEnabled", true, "Speeds up the 1H Axe secondary uppercut attack."); AxeSecondarySpeedMultiplier = config.Bind<float>("1. Axes", "AxeSecondarySpeedMultiplier", 1.3f, "Playback speed multiplier for Axe secondary attack."); BattleaxeOverhaulEnabled = config.Bind<bool>("2. Battleaxes", "BattleaxeOverhaulEnabled", true, "Enables the Battleaxe archetype overhaul."); BattleaxePrimaryCleave = config.Bind<float>("2. Battleaxes", "BattleaxePrimaryCleave", 0.4f, "Cleave efficiency factor for Battleaxe primary attacks (default 40%)."); BattleaxeDamageMultiplier = config.Bind<float>("2. Battleaxes", "BattleaxeDamageMultiplier", 1.1f, "Base damage step multiplier for Battleaxe primary swings (1.10x)."); BattleaxeFinisherMultiplier = config.Bind<float>("2. Battleaxes", "BattleaxeFinisherMultiplier", 2.2f, "Base damage step multiplier for Battleaxe combo finisher (2.20x)."); BattleaxeSecondaryDamageTypeBlunt = config.Bind<bool>("2. Battleaxes", "BattleaxeSecondaryDamageTypeBlunt", true, "Converts Battleaxe secondary attack damage to Blunt."); BattleaxeSecondaryDamageMultiplier = config.Bind<float>("2. Battleaxes", "BattleaxeSecondaryDamageMultiplier", 0.6f, "Damage multiplier for Battleaxe secondary attack poke."); SwordOverhaulEnabled = config.Bind<bool>("3. Swords", "SwordOverhaulEnabled", true, "Enables the Sword archetype overhaul."); SwordPrimaryCleave = config.Bind<float>("3. Swords", "SwordPrimaryCleave", 0.25f, "Cleave efficiency factor for Sword primary attacks (reduced from native 100% to 25%)."); SwordDamageMultiplier = config.Bind<float>("3. Swords", "SwordDamageMultiplier", 1.1f, "Compensatory base damage step multiplier for Sword primary swings (1.10x)."); SwordFinisherMultiplier = config.Bind<float>("3. Swords", "SwordFinisherMultiplier", 2.2f, "Compensatory base damage step multiplier for Sword combo finisher (2.20x)."); SwordSecondaryPierce = config.Bind<bool>("3. Swords", "SwordSecondaryPierce", true, "Converts Sword secondary thrust attack damage to Pierce."); SwordSecondaryDamageMultiplier = config.Bind<float>("3. Swords", "SwordSecondaryDamageMultiplier", 3f, "Damage multiplier for Sword secondary thrust attack (3.0x)."); SwordSecondaryCleave = config.Bind<float>("3. Swords", "SwordSecondaryCleave", 0.25f, "Cleave efficiency factor for Sword secondary thrust attack."); SwordAttackSpeedMultiplier = config.Bind<float>("3. Swords", "SwordAttackSpeedMultiplier", 1.1f, "Compensatory attack animation speed multiplier for swords."); ClubSecondarySpeedEnabled = config.Bind<bool>("4. Clubs", "ClubSecondarySpeedEnabled", true, "Speeds up Club/Mace secondary attack to reduce enemy interruption."); ClubSecondarySpeedMultiplier = config.Bind<float>("4. Clubs", "ClubSecondarySpeedMultiplier", 1.3f, "Playback speed multiplier for Club/Mace secondary attack."); SpearOverhaulEnabled = config.Bind<bool>("5. Spears", "SpearOverhaulEnabled", true, "Enables the Spear archetype overhaul."); SpearPrimaryAnimation = config.Bind<string>("5. Spears", "SpearPrimaryAnimation", "sword_secondary", "Primary attack animation trigger ('sword_secondary' for forward poke, 'knife_stab', or 'spear_poke')."); SpearPokeSpeedMultiplier = config.Bind<float>("5. Spears", "SpearPokeSpeedMultiplier", 0.45f, "Playback speed multiplier for the forward spear poke animation (default 0.45x provides a balanced, natural thrust cadence)."); SpearPrimaryReach = config.Bind<float>("5. Spears", "SpearPrimaryReach", 1.9f, "Attack range (reach in meters) for spear primary poke (native spear reach is 1.9m)."); SpearPrimaryHeight = config.Bind<float>("5. Spears", "SpearPrimaryHeight", 1f, "Vertical attack height in meters for spear primary poke (1.0m matches waist/chest underhand thrust; native overhand was 1.5m)."); SpearModelFlipEnabled = config.Bind<bool>("5. Spears", "SpearModelFlipEnabled", true, "Flips equipped 1H spears 180 degrees in the hand so the spearhead points forward during thrusts."); SpearModelFlipAngleX = config.Bind<float>("5. Spears", "SpearModelFlipAngleX", 180f, "Euler X rotation offset applied to equipped spears."); SpearModelFlipAngleY = config.Bind<float>("5. Spears", "SpearModelFlipAngleY", 0f, "Euler Y rotation offset applied to equipped spears."); SpearModelFlipAngleZ = config.Bind<float>("5. Spears", "SpearModelFlipAngleZ", 0f, "Euler Z rotation offset applied to equipped spears."); SpearModelPositionOffsetX = config.Bind<float>("5. Spears", "SpearModelPositionOffsetX", 0f, "Local X position offset applied to equipped spears."); SpearModelPositionOffsetY = config.Bind<float>("5. Spears", "SpearModelPositionOffsetY", 0f, "Local Y position offset applied to equipped spears."); SpearModelPositionOffsetZ = config.Bind<float>("5. Spears", "SpearModelPositionOffsetZ", 0f, "Local Z position offset applied to equipped spears."); SpearModelFlipArmorStand = config.Bind<bool>("5. Spears", "SpearModelFlipArmorStand", false, "Whether to apply the spear flip to armor stands (default false keeps spears upright on stands)."); SpearSecondaryHamstringEnabled = config.Bind<bool>("5. Spears", "SpearSecondaryHamstringEnabled", true, "Thrown spears inflict Hamstring/Cripple on struck targets."); SpearSecondaryHamstringDuration = config.Bind<float>("5. Spears", "SpearSecondaryHamstringDuration", 6f, "Duration in seconds for the spear hamstring/cripple effect."); SpearSecondaryHamstringPotency = config.Bind<float>("5. Spears", "SpearSecondaryHamstringPotency", 0.5f, "Potency slice value for the cripple slow (0.50 = 33% slow)."); PolearmOverhaulEnabled = config.Bind<bool>("6. Polearms", "PolearmOverhaulEnabled", true, "Enables the Polearm (Atgeir) archetype overhaul."); PolearmSecondaryCleave = config.Bind<float>("6. Polearms", "PolearmSecondaryCleave", 0.4f, "Cleave efficiency factor for Atgeir secondary 360-spin (reduced from native 100% to 40%)."); PolearmSecondarySlashDamage = config.Bind<bool>("6. Polearms", "PolearmSecondarySlashDamage", true, "Converts Atgeir secondary spin attack damage to Slash."); PolearmSecondaryStaggerMultiplier = config.Bind<float>("6. Polearms", "PolearmSecondaryStaggerMultiplier", 1f, "Secondary spin stagger multiplier (down from native 6.0x, relies on 5.0x knockback)."); KnifeOverhaulEnabled = config.Bind<bool>("7. Knives", "KnifeOverhaulEnabled", true, "Enables the Knife archetype overhaul."); KnifePrimaryCleave = config.Bind<float>("7. Knives", "KnifePrimaryCleave", 0.375f, "Cleave efficiency factor for Knife primary attacks (default 37.5%)."); KnifeDamageMultiplier = config.Bind<float>("7. Knives", "KnifeDamageMultiplier", 1f, "Base damage step multiplier for Knife primary swings 1 and 2 (1.0x)."); KnifeFinisherMultiplier = config.Bind<float>("7. Knives", "KnifeFinisherMultiplier", 2f, "Base damage step multiplier for Knife combo finisher thrust 3 (2.0x)."); KnifeSecondaryDamageMultiplier = config.Bind<float>("7. Knives", "KnifeSecondaryDamageMultiplier", 3f, "Damage multiplier for Knife secondary leap attack (3.0x)."); KnifeSecondaryCleave = config.Bind<float>("7. Knives", "KnifeSecondaryCleave", 0.375f, "Cleave efficiency factor for Knife secondary leap attack."); KnifePrimarySlashDamage = config.Bind<bool>("7. Knives", "KnifePrimarySlashDamage", true, "Converts Knife primary swings 1 and 2 entirely to Slash damage to match slashing animations."); KnifeFinisherPierceDamage = config.Bind<bool>("7. Knives", "KnifeFinisherPierceDamage", true, "Converts Knife combo finisher 3 entirely to Pierce damage to match thrust animation."); KnifeSecondaryPierceDamage = config.Bind<bool>("7. Knives", "KnifeSecondaryPierceDamage", true, "Converts Knife secondary leap attack entirely to Pierce damage to match downward stab animation."); config.SettingChanged += delegate { WeaponProfiles.RegisterAll(); }; } } }