Decompiled source of MobaModpack v1.4.0
BepInEx/plugins/Absolute-MobaModpack/satt-CustomArmorStats/CustomArmorStats.dll
Decompiled 6 months agousing System; using System.Collections.Generic; using System.Diagnostics; using System.IO; using System.Linq; using System.Reflection; using System.Reflection.Emit; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using System.Text.RegularExpressions; using BepInEx; using BepInEx.Configuration; using HarmonyLib; using TMPro; 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.8", FrameworkDisplayName = ".NET Framework 4.8")] [assembly: AssemblyConfiguration("Debug")] [assembly: AssemblyFileVersion("1.0.0.0")] [assembly: AssemblyInformationalVersion("1.0.0")] [assembly: AssemblyVersion("1.0.0.0")] namespace CustomArmorStats; internal class ArmorData { public string name; public float armor; public float armorPerLevel; public float movementModifier; public List<string> damageModifiers = new List<string>(); } [BepInPlugin("aedenthorn.CustomArmorStats", "Custom Armor Stats", "0.6.0")] public class BepInExPlugin : BaseUnityPlugin { private enum NewDamageTypes { Water = 0x400 } [HarmonyPatch(typeof(ZNetScene), "Awake")] private static class ZNetScene_Awake_Patch { private static void Postfix(ZNetScene __instance) { if (modEnabled.Value) { LoadAllArmorData(__instance); } } } [HarmonyPatch(typeof(ItemDrop), "Awake")] private static class ItemDrop_Awake_Patch { private static void Postfix(ItemDrop __instance) { if (modEnabled.Value) { CheckArmorData(ref __instance.m_itemData); } } } [HarmonyPatch(typeof(ItemDrop), "SlowUpdate")] private static class ItemDrop_SlowUpdate_Patch { private static void Postfix(ref ItemDrop __instance) { if (modEnabled.Value) { CheckArmorData(ref __instance.m_itemData); } } } [HarmonyPatch(typeof(Player), "DamageArmorDurability")] private static class Player_DamageArmorDurability_Patch { private static void Prefix(ref HitData hit) { if (modEnabled.Value) { hit.ApplyModifier(globalArmorDurabilityLossMult.Value); } } } [HarmonyPatch(typeof(Player), "GetEquipmentMovementModifier")] private static class GetEquipmentMovementModifier_Patch { private static void Postfix(ref float __result) { if (modEnabled.Value) { __result *= globalArmorMovementModMult.Value; } } } [HarmonyPatch(typeof(Player), "GetJogSpeedFactor")] private static class GetJogSpeedFactor_Patch { private static bool Prefix(ref float __result, float ___m_equipmentMovementModifier) { if (!modEnabled.Value) { return true; } __result = 1f + ___m_equipmentMovementModifier * globalArmorMovementModMult.Value; return false; } } [HarmonyPatch(typeof(Player), "GetRunSpeedFactor")] private static class GetRunSpeedFactor_Patch { private static bool Prefix(Skills ___m_skills, float ___m_equipmentMovementModifier, ref float __result) { if (!modEnabled.Value) { return true; } float skillFactor = ___m_skills.GetSkillFactor((SkillType)102); __result = (1f + skillFactor * 0.25f) * (1f + ___m_equipmentMovementModifier * 1.5f * globalArmorMovementModMult.Value); return false; } } [HarmonyPatch(typeof(SEMan), "AddStatusEffect", new Type[] { typeof(StatusEffect), typeof(bool), typeof(int), typeof(float) })] private static class SEMan_AddStatusEffect_Patch { private static bool Prefix(SEMan __instance, StatusEffect statusEffect, Character ___m_character, ref StatusEffect __result) { //IL_003c: 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_0042: Unknown result type (might be due to invalid IL or missing references) //IL_0044: Invalid comparison between Unknown and I4 //IL_0046: Unknown result type (might be due to invalid IL or missing references) //IL_0048: Invalid comparison between Unknown and I4 if (!modEnabled.Value || !___m_character.IsPlayer()) { return true; } if (statusEffect.m_name == "$se_wet_name") { DamageModifier newDamageTypeMod = GetNewDamageTypeMod(NewDamageTypes.Water, ___m_character); if ((int)newDamageTypeMod == 4 || (int)newDamageTypeMod == 3) { __result = null; return false; } } return true; } } [HarmonyPatch(typeof(SE_Stats), "GetDamageModifiersTooltipString")] private static class GetDamageModifiersTooltipString_Patch { private static void Postfix(ref string __result, List<DamageModPair> mods) { //IL_0039: Unknown result type (might be due to invalid IL or missing references) //IL_003e: 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_0063: Unknown result type (might be due to invalid IL or missing references) //IL_0064: Unknown result type (might be due to invalid IL or missing references) //IL_006a: Invalid comparison between Unknown and I4 //IL_006c: Unknown result type (might be due to invalid IL or missing references) //IL_006d: Unknown result type (might be due to invalid IL or missing references) //IL_0073: Invalid comparison between Unknown and I4 //IL_0082: Unknown result type (might be due to invalid IL or missing references) //IL_0083: Unknown result type (might be due to invalid IL or missing references) //IL_0088: Unknown result type (might be due to invalid IL or missing references) //IL_008a: Unknown result type (might be due to invalid IL or missing references) //IL_008c: Unknown result type (might be due to invalid IL or missing references) //IL_008e: Unknown result type (might be due to invalid IL or missing references) //IL_0091: Unknown result type (might be due to invalid IL or missing references) //IL_00af: Expected I4, but got Unknown //IL_0101: Unknown result type (might be due to invalid IL or missing references) //IL_0102: Unknown result type (might be due to invalid IL or missing references) //IL_010c: Invalid comparison between Unknown and I4 if (!modEnabled.Value) { return; } __result = Regex.Replace(__result, "\\n.*<color=orange></color>", ""); foreach (DamageModPair mod in mods) { if (!Enum.IsDefined(typeof(DamageType), mod.m_type) && (int)mod.m_modifier != 4 && (int)mod.m_modifier > 0) { DamageModifier modifier = mod.m_modifier; DamageModifier val = modifier; switch (val - 1) { case 0: __result += "\n$inventory_dmgmod: <color=orange>$inventory_resistant</color> VS "; break; case 1: __result += "\n$inventory_dmgmod: <color=orange>$inventory_weak</color> VS "; break; case 2: __result += "\n$inventory_dmgmod: <color=orange>$inventory_immune</color> VS "; break; case 4: __result += "\n$inventory_dmgmod: <color=orange>$inventory_veryresistant</color> VS "; break; case 5: __result += "\n$inventory_dmgmod: <color=orange>$inventory_veryweak</color> VS "; break; } if ((int)mod.m_type == 1024) { __result = __result + "<color=orange>" + waterModifierName.Value + "</color>"; } } } } } [HarmonyPatch(typeof(Player), "UpdateEnvStatusEffects")] private static class UpdateEnvStatusEffects_Patch { public static IEnumerable<CodeInstruction> Transpiler(IEnumerable<CodeInstruction> instructions) { //IL_00e8: Unknown result type (might be due to invalid IL or missing references) //IL_00f2: Expected O, but got Unknown //IL_00fa: Unknown result type (might be due to invalid IL or missing references) //IL_0104: Expected O, but got Unknown //IL_010f: Unknown result type (might be due to invalid IL or missing references) //IL_0119: Expected O, but got Unknown //IL_0122: Unknown result type (might be due to invalid IL or missing references) //IL_012c: Expected O, but got Unknown //IL_0134: Unknown result type (might be due to invalid IL or missing references) //IL_013e: Expected O, but got Unknown //IL_0149: Unknown result type (might be due to invalid IL or missing references) //IL_0153: Expected O, but got Unknown Dbgl("Transpiling UpdateEnvStatusEffects"); List<CodeInstruction> list = new List<CodeInstruction>(instructions); List<CodeInstruction> list2 = new List<CodeInstruction>(); bool flag = true; for (int i = 0; i < list.Count; i++) { if (flag && list[i].opcode == OpCodes.Ldloc_S && list[i + 1].opcode == OpCodes.Ldc_I4_1 && list[i + 2].opcode == OpCodes.Beq && list[i + 3].opcode == OpCodes.Ldloc_S && list[i + 3].operand == list[i].operand && list[i + 4].opcode == OpCodes.Ldc_I4_5) { Dbgl("Adding frost immune and ignore"); list2.Add(new CodeInstruction(list[i])); list2.Add(new CodeInstruction(OpCodes.Ldc_I4_3, (object)null)); list2.Add(new CodeInstruction(list[i + 2])); list2.Add(new CodeInstruction(list[i])); list2.Add(new CodeInstruction(OpCodes.Ldc_I4_4, (object)null)); list2.Add(new CodeInstruction(list[i + 2])); flag = false; } list2.Add(list[i]); } return list2.AsEnumerable(); } private static void Postfix(float dt, Player __instance, ItemData ___m_chestItem, ItemData ___m_legItem, ItemData ___m_helmetItem, ItemData ___m_shoulderItem, SEMan ___m_seman) { //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) //IL_005a: Unknown result type (might be due to invalid IL or missing references) //IL_005c: Invalid comparison between Unknown and I4 //IL_005e: Unknown result type (might be due to invalid IL or missing references) //IL_0060: Invalid comparison between Unknown and I4 //IL_007c: Unknown result type (might be due to invalid IL or missing references) //IL_007e: Invalid comparison between Unknown and I4 //IL_00c4: Unknown result type (might be due to invalid IL or missing references) //IL_00c6: Invalid comparison between Unknown and I4 //IL_011a: Unknown result type (might be due to invalid IL or missing references) //IL_011c: Invalid comparison between Unknown and I4 //IL_0173: Unknown result type (might be due to invalid IL or missing references) //IL_0175: Invalid comparison between Unknown and I4 if (modEnabled.Value && ___m_seman.HaveStatusEffect("Wet")) { int stableHashCode = StringExtensionMethods.GetStableHashCode("Wet"); DamageModifier newDamageTypeMod = GetNewDamageTypeMod(NewDamageTypes.Water, ___m_chestItem, ___m_legItem, ___m_helmetItem, ___m_shoulderItem); StatusEffect statusEffect = ___m_seman.GetStatusEffect(stableHashCode); Traverse val = Traverse.Create((object)statusEffect); if ((int)newDamageTypeMod == 4 || (int)newDamageTypeMod == 3) { ___m_seman.RemoveStatusEffect(stableHashCode, true); } else if ((int)newDamageTypeMod == 5 && !(bool)AccessTools.Method(typeof(Character), "InLiquidSwimDepth", (Type[])null, (Type[])null).Invoke(__instance, new object[0])) { ___m_seman.RemoveStatusEffect(stableHashCode, true); } else if ((int)newDamageTypeMod == 1) { val.Field("m_time").SetValue((object)(val.Field("m_time").GetValue<float>() + dt)); ___m_seman.RemoveStatusEffect(stableHashCode, true); ___m_seman.AddStatusEffect(statusEffect, false, 0, 0f); } else if ((int)newDamageTypeMod == 2) { val.Field("m_time").SetValue((object)(val.Field("m_time").GetValue<float>() - dt / 3f)); ___m_seman.RemoveStatusEffect(stableHashCode, true); ___m_seman.AddStatusEffect(statusEffect, false, 0, 0f); } else if ((int)newDamageTypeMod == 6) { val.Field("m_time").SetValue((object)(val.Field("m_time").GetValue<float>() - dt * 2f / 3f)); ___m_seman.RemoveStatusEffect(stableHashCode, true); ___m_seman.AddStatusEffect(statusEffect, false, 0, 0f); } } } } [HarmonyPatch(typeof(Terminal), "InputText")] private static class InputText_Patch { private static bool Prefix(Terminal __instance) { if (!modEnabled.Value) { return true; } string text = ((TMP_InputField)__instance.m_input).text; if (text.ToLower().Equals(typeof(BepInExPlugin).Namespace.ToLower() + " reset")) { ((BaseUnityPlugin)context).Config.Reload(); ((BaseUnityPlugin)context).Config.Save(); __instance.AddString(text); __instance.AddString(((BaseUnityPlugin)context).Info.Metadata.Name + " config reloaded"); return false; } if (text.ToLower().Equals(typeof(BepInExPlugin).Namespace.ToLower() + " reload")) { armorDatas = GetArmorDataFromFiles(); if (Object.op_Implicit((Object)(object)ZNetScene.instance)) { LoadAllArmorData(ZNetScene.instance); } __instance.AddString(text); __instance.AddString(((BaseUnityPlugin)context).Info.Metadata.Name + " reloaded armor stats from files"); return false; } if (text.ToLower().Equals(typeof(BepInExPlugin).Namespace.ToLower() + " damagetypes")) { __instance.AddString(text); Dbgl("\r\n" + string.Join("\r\n", Enum.GetNames(typeof(DamageType)))); __instance.AddString(((BaseUnityPlugin)context).Info.Metadata.Name + " dumped damage types"); return false; } if (text.ToLower().Equals(typeof(BepInExPlugin).Namespace.ToLower() + " damagemods")) { __instance.AddString(text); Dbgl("\r\n" + string.Join("\r\n", Enum.GetNames(typeof(DamageModifier)))); __instance.AddString(((BaseUnityPlugin)context).Info.Metadata.Name + " dumped damage modifiers"); return false; } if (text.ToLower().StartsWith(typeof(BepInExPlugin).Namespace.ToLower() + " save ")) { string text2 = text.Split(new char[1] { ' ' })[^1]; ArmorData armorDataByName = GetArmorDataByName(text2); if (armorDataByName == null) { return false; } CheckModFolder(); File.WriteAllText(Path.Combine(assetPath, armorDataByName.name + ".json"), JsonUtility.ToJson((object)armorDataByName, true)); __instance.AddString(text); __instance.AddString(((BaseUnityPlugin)context).Info.Metadata.Name + " saved armor data to " + text2 + ".json"); return false; } if (text.ToLower().StartsWith(typeof(BepInExPlugin).Namespace.ToLower() + " dump ")) { string text3 = text.Split(new char[1] { ' ' })[^1]; ArmorData armorDataByName2 = GetArmorDataByName(text3); if (armorDataByName2 == null) { return false; } Dbgl(JsonUtility.ToJson((object)armorDataByName2)); __instance.AddString(text); __instance.AddString(((BaseUnityPlugin)context).Info.Metadata.Name + " dumped " + text3); return false; } if (text.ToLower().StartsWith(typeof(BepInExPlugin).Namespace.ToLower() ?? "")) { string text4 = ((BaseUnityPlugin)context).Info.Metadata.Name + " reset\r\n" + ((BaseUnityPlugin)context).Info.Metadata.Name + " reload\r\n" + ((BaseUnityPlugin)context).Info.Metadata.Name + " dump <ArmorName>\r\n" + ((BaseUnityPlugin)context).Info.Metadata.Name + " save <ArmorName>\r\n" + ((BaseUnityPlugin)context).Info.Metadata.Name + " damagetypes\r\n" + ((BaseUnityPlugin)context).Info.Metadata.Name + " damagemods"; __instance.AddString(text); __instance.AddString(text4); return false; } return true; } } private static BepInExPlugin context; public static ConfigEntry<bool> modEnabled; public static ConfigEntry<bool> isDebug; public static ConfigEntry<int> nexusID; public static ConfigEntry<float> globalArmorDurabilityLossMult; public static ConfigEntry<float> globalArmorMovementModMult; public static ConfigEntry<string> waterModifierName; private static List<ArmorData> armorDatas; private static string assetPath; public static void Dbgl(string str = "", bool pref = true) { if (isDebug.Value) { Debug.Log((object)((pref ? (typeof(BepInExPlugin).Namespace + " ") : "") + str)); } } private void Awake() { context = this; modEnabled = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "Enabled", true, "Enable this mod"); isDebug = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "IsDebug", true, "Enable debug logs"); nexusID = ((BaseUnityPlugin)this).Config.Bind<int>("General", "NexusID", 1162, "Nexus mod ID for updates"); nexusID.Value = 1162; globalArmorDurabilityLossMult = ((BaseUnityPlugin)this).Config.Bind<float>("Stats", "GlobalArmorDurabilityLossMult", 1f, "Global armor durability loss multiplier"); globalArmorMovementModMult = ((BaseUnityPlugin)this).Config.Bind<float>("Stats", "GlobalArmorMovementModMult", 1f, "Global armor movement modifier multiplier"); waterModifierName = ((BaseUnityPlugin)this).Config.Bind<string>("Strings", "WaterModifierName", "Water", "Name of water damage modifier to show in tooltip"); assetPath = Path.Combine(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location), "CustomArmorStats"); Harmony.CreateAndPatchAll(Assembly.GetExecutingAssembly(), (string)null); } private static DamageModifier GetNewDamageTypeMod(NewDamageTypes type, Character character) { //IL_0049: Unknown result type (might be due to invalid IL or missing references) //IL_004e: 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) Traverse val = Traverse.Create((object)character); return GetNewDamageTypeMod(type, val.Field("m_chestItem").GetValue<ItemData>(), val.Field("m_legItem").GetValue<ItemData>(), val.Field("m_helmetItem").GetValue<ItemData>(), val.Field("m_shoulderItem").GetValue<ItemData>()); } private static DamageModifier GetNewDamageTypeMod(NewDamageTypes type, ItemData chestItem, ItemData legItem, ItemData helmetItem, ItemData shoulderItem) { //IL_0010: 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_003a: Unknown result type (might be due to invalid IL or missing references) //IL_005b: 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_0062: Unknown result type (might be due to invalid IL or missing references) //IL_0063: Unknown result type (might be due to invalid IL or missing references) //IL_0068: Unknown result type (might be due to invalid IL or missing references) //IL_006a: 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_00a5: Unknown result type (might be due to invalid IL or missing references) //IL_00a7: Unknown result type (might be due to invalid IL or missing references) //IL_00a8: Unknown result type (might be due to invalid IL or missing references) //IL_00ad: Unknown result type (might be due to invalid IL or missing references) //IL_00af: Unknown result type (might be due to invalid IL or missing references) //IL_007a: Unknown result type (might be due to invalid IL or missing references) //IL_007c: Unknown result type (might be due to invalid IL or missing references) //IL_010a: Unknown result type (might be due to invalid IL or missing references) //IL_010b: Unknown result type (might be due to invalid IL or missing references) //IL_0110: Unknown result type (might be due to invalid IL or missing references) //IL_00e7: Unknown result type (might be due to invalid IL or missing references) //IL_00ec: Unknown result type (might be due to invalid IL or missing references) //IL_00ee: Unknown result type (might be due to invalid IL or missing references) //IL_00ef: Unknown result type (might be due to invalid IL or missing references) //IL_00f4: Unknown result type (might be due to invalid IL or missing references) //IL_00f6: 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) //IL_00c1: Unknown result type (might be due to invalid IL or missing references) //IL_0114: Unknown result type (might be due to invalid IL or missing references) //IL_0106: Unknown result type (might be due to invalid IL or missing references) //IL_0108: Unknown result type (might be due to invalid IL or missing references) DamageModPair val = default(DamageModPair); if (chestItem != null) { val = ((IEnumerable<DamageModPair>)chestItem.m_shared.m_damageModifiers).FirstOrDefault((Func<DamageModPair, bool>)((DamageModPair s) => (int)s.m_type == (int)type)); } if (legItem != null) { DamageModPair val2 = ((IEnumerable<DamageModPair>)legItem.m_shared.m_damageModifiers).FirstOrDefault((Func<DamageModPair, bool>)((DamageModPair s) => (int)s.m_type == (int)type)); if (ShouldOverride(val.m_modifier, val2.m_modifier)) { val = val2; } } if (helmetItem != null) { DamageModPair val3 = ((IEnumerable<DamageModPair>)helmetItem.m_shared.m_damageModifiers).FirstOrDefault((Func<DamageModPair, bool>)((DamageModPair s) => (int)s.m_type == (int)type)); if (ShouldOverride(val.m_modifier, val3.m_modifier)) { val = val3; } } if (shoulderItem != null) { DamageModPair val4 = ((IEnumerable<DamageModPair>)shoulderItem.m_shared.m_damageModifiers).FirstOrDefault((Func<DamageModPair, bool>)((DamageModPair s) => (int)s.m_type == (int)type)); if (ShouldOverride(val.m_modifier, val4.m_modifier)) { val = val4; } } return val.m_modifier; } private static bool ShouldOverride(DamageModifier a, DamageModifier b) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0003: Invalid comparison between Unknown and I4 //IL_0005: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Invalid comparison between Unknown and I4 //IL_0009: Unknown result type (might be due to invalid IL or missing references) //IL_000b: Invalid comparison between Unknown and I4 //IL_0011: Unknown result type (might be due to invalid IL or missing references) //IL_0013: Invalid comparison between Unknown and I4 //IL_000d: Unknown result type (might be due to invalid IL or missing references) //IL_000f: Invalid comparison between Unknown and I4 //IL_0015: Unknown result type (might be due to invalid IL or missing references) //IL_0017: Invalid comparison between Unknown and I4 return (int)a != 4 && ((int)b == 3 || (((int)a != 5 || (int)b != 1) && ((int)a != 6 || (int)b != 2))); } private static void LoadAllArmorData(ZNetScene scene) { armorDatas = GetArmorDataFromFiles(); foreach (ArmorData armorData in armorDatas) { GameObject prefab = scene.GetPrefab(armorData.name); if (!((Object)(object)prefab == (Object)null)) { ItemData item = prefab.GetComponent<ItemDrop>().m_itemData; SetArmorData(ref item, armorData); prefab.GetComponent<ItemDrop>().m_itemData = item; } } } private static void CheckArmorData(ref ItemData instance) { try { string name = ((Object)instance.m_dropPrefab).name; ArmorData armor = armorDatas.First((ArmorData d) => d.name == name); SetArmorData(ref instance, armor); } catch { } } private static List<ArmorData> GetArmorDataFromFiles() { CheckModFolder(); List<ArmorData> list = new List<ArmorData>(); string[] files = Directory.GetFiles(assetPath, "*.json"); foreach (string path in files) { ArmorData item = JsonUtility.FromJson<ArmorData>(File.ReadAllText(path)); list.Add(item); } return list; } private static void CheckModFolder() { if (!Directory.Exists(assetPath)) { Dbgl("Creating mod folder"); Directory.CreateDirectory(assetPath); } } private static void SetArmorData(ref ItemData item, ArmorData armor) { //IL_00ac: Unknown result type (might be due to invalid IL or missing references) //IL_00b5: Unknown result type (might be due to invalid IL or missing references) //IL_00ce: Unknown result type (might be due to invalid IL or missing references) //IL_00d3: Unknown result type (might be due to invalid IL or missing references) //IL_00d8: Unknown result type (might be due to invalid IL or missing references) item.m_shared.m_armor = armor.armor; item.m_shared.m_armorPerLevel = armor.armorPerLevel; item.m_shared.m_movementModifier = armor.movementModifier; item.m_shared.m_damageModifiers.Clear(); foreach (string damageModifier in armor.damageModifiers) { string[] array = damageModifier.Split(new char[1] { ':' }); NewDamageTypes result; int num = (Enum.TryParse<NewDamageTypes>(array[0], out result) ? ((int)result) : ((int)Enum.Parse(typeof(DamageType), array[0]))); item.m_shared.m_damageModifiers.Add(new DamageModPair { m_type = (DamageType)num, m_modifier = (DamageModifier)Enum.Parse(typeof(DamageModifier), array[1]) }); } } private static ArmorData GetArmorDataByName(string armor) { GameObject itemPrefab = ObjectDB.instance.GetItemPrefab(armor); if (!Object.op_Implicit((Object)(object)itemPrefab)) { Dbgl("Armor not found!"); return null; } ItemData itemData = itemPrefab.GetComponent<ItemDrop>().m_itemData; return GetArmorDataFromItem(itemData, armor); } private static ArmorData GetArmorDataFromItem(ItemData item, string itemName) { return new ArmorData { name = itemName, armor = item.m_shared.m_armor, armorPerLevel = item.m_shared.m_armorPerLevel, movementModifier = item.m_shared.m_movementModifier, damageModifiers = item.m_shared.m_damageModifiers.Select((DamageModPair m) => ((object)(DamageType)(ref m.m_type)).ToString() + ":" + ((object)(DamageModifier)(ref m.m_modifier)).ToString()).ToList() }; } }
BepInEx/plugins/Absolute-MobaModpack/satt-Custom_Weapon_Stats/CustomWeaponStats.dll
Decompiled 6 months agousing System; using System.Collections.Generic; using System.Diagnostics; using System.IO; using System.Linq; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; using System.Runtime.Versioning; using BepInEx; using BepInEx.Configuration; using HarmonyLib; using TMPro; using UnityEngine; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)] [assembly: AssemblyTitle("CustomWeapons")] [assembly: AssemblyDescription("")] [assembly: AssemblyConfiguration("")] [assembly: AssemblyCompany("")] [assembly: AssemblyProduct("CustomWeapons")] [assembly: AssemblyCopyright("Copyright © 2021")] [assembly: AssemblyTrademark("")] [assembly: ComVisible(false)] [assembly: Guid("0efd1fbe-b627-4680-9a66-b95aa347eb48")] [assembly: AssemblyFileVersion("1.0.0.0")] [assembly: TargetFramework(".NETFramework,Version=v4.8", FrameworkDisplayName = ".NET Framework 4.8")] [assembly: AssemblyInformationalVersion("1.0.0")] [assembly: AssemblyVersion("1.0.0.0")] namespace CustomWeaponStats; [BepInPlugin("aedenthorn.CustomWeaponStats", "Custom Weapon Stats", "0.7.0")] public class BepInExPlugin : BaseUnityPlugin { [HarmonyPatch(typeof(ObjectDB), "CopyOtherDB")] private static class CopyOtherDB_Patch { private static void Postfix() { if (modEnabled.Value) { LoadAllWeaponData(reload: true); } } } [HarmonyPatch(typeof(InventoryGui), "Show")] [HarmonyPriority(0)] private static class InventoryGui_Show_Patch { private static void Postfix() { if (modEnabled.Value) { LoadAllWeaponData(reload: false); } } } [HarmonyPatch(typeof(ItemDrop), "Awake")] private static class ItemDrop_Awake_Patch { private static void Postfix(ItemDrop __instance) { if (modEnabled.Value) { CheckWeaponData(ref __instance.m_itemData); } } } [HarmonyPatch(typeof(ItemDrop), "SlowUpdate")] private static class ItemDrop_SlowUpdate_Patch { private static void Postfix(ref ItemDrop __instance) { if (modEnabled.Value) { CheckWeaponData(ref __instance.m_itemData); } } } [HarmonyPatch(typeof(Attack), "GetAttackStamina")] private static class GetAttackStamina_Patch { private static void Postfix(ref float __result) { if (modEnabled.Value) { __result *= globalAttackStaminaUseMultiplier.Value; } } } [HarmonyPatch(typeof(Attack), "Start")] private static class Attack_Start_Patch { private static void Prefix(ref ItemData weapon, ref WeaponState __state) { if (modEnabled.Value) { CheckWeaponData(ref weapon); Dbgl($"pre damage {weapon.m_shared.m_damages.m_slash}"); __state = new WeaponState(weapon); SharedData shared = weapon.m_shared; shared.m_useDurabilityDrain *= globalUseDurabilityMultiplier.Value; SharedData shared2 = weapon.m_shared; shared2.m_attackForce *= globalAttackForceMultiplier.Value; SharedData shared3 = weapon.m_shared; shared3.m_backstabBonus *= globalBackstabBonusMultiplier.Value; weapon.m_shared.m_damages.m_damage *= globalDamageMultiplier.Value; weapon.m_shared.m_damages.m_blunt *= globalDamageMultiplier.Value; weapon.m_shared.m_damages.m_slash *= globalDamageMultiplier.Value; weapon.m_shared.m_damages.m_pierce *= globalDamageMultiplier.Value; weapon.m_shared.m_damages.m_chop *= globalDamageMultiplier.Value; weapon.m_shared.m_damages.m_pickaxe *= globalDamageMultiplier.Value; weapon.m_shared.m_damages.m_fire *= globalDamageMultiplier.Value; weapon.m_shared.m_damages.m_frost *= globalDamageMultiplier.Value; weapon.m_shared.m_damages.m_lightning *= globalDamageMultiplier.Value; weapon.m_shared.m_damages.m_poison *= globalDamageMultiplier.Value; weapon.m_shared.m_damages.m_spirit *= globalDamageMultiplier.Value; Dbgl($"post damage {weapon.m_shared.m_damages.m_slash}"); } } private static void Postfix(ref ItemData weapon, WeaponState __state) { if (modEnabled.Value) { weapon.m_shared.m_useDurabilityDrain = __state.useDurabilityDrain; weapon.m_shared.m_attackForce = __state.attackForce; weapon.m_shared.m_backstabBonus = __state.backstabBonus; weapon.m_shared.m_damages.m_damage = __state.damage; weapon.m_shared.m_damages.m_blunt = __state.blunt; weapon.m_shared.m_damages.m_slash = __state.slash; weapon.m_shared.m_damages.m_pierce = __state.pierce; weapon.m_shared.m_damages.m_chop = __state.chop; weapon.m_shared.m_damages.m_pickaxe = __state.pickaxe; weapon.m_shared.m_damages.m_fire = __state.fire; weapon.m_shared.m_damages.m_frost = __state.frost; weapon.m_shared.m_damages.m_lightning = __state.lightning; weapon.m_shared.m_damages.m_poison = __state.poison; weapon.m_shared.m_damages.m_spirit = __state.spirit; } } } [HarmonyPatch(typeof(Terminal), "InputText")] private static class InputText_Patch { private static bool Prefix(Terminal __instance) { //IL_02d9: Unknown result type (might be due to invalid IL or missing references) //IL_02de: Unknown result type (might be due to invalid IL or missing references) //IL_02ed: Unknown result type (might be due to invalid IL or missing references) //IL_02fe: Unknown result type (might be due to invalid IL or missing references) //IL_0302: Expected I4, but got Unknown if (!modEnabled.Value) { return true; } string text = ((TMP_InputField)__instance.m_input).text; if (text.ToLower().Equals(typeof(BepInExPlugin).Namespace.ToLower() + " reset")) { ((BaseUnityPlugin)context).Config.Reload(); ((BaseUnityPlugin)context).Config.Save(); Traverse.Create((object)__instance).Method("AddString", new object[1] { text }).GetValue(); Traverse.Create((object)__instance).Method("AddString", new object[1] { ((BaseUnityPlugin)context).Info.Metadata.Name + " config reloaded" }).GetValue(); return false; } if (text.ToLower().Equals(typeof(BepInExPlugin).Namespace.ToLower() + " reload")) { weaponDatas = GetWeaponDataFromFiles(); LoadAllWeaponData(reload: true); Traverse.Create((object)__instance).Method("AddString", new object[1] { text }).GetValue(); Traverse.Create((object)__instance).Method("AddString", new object[1] { ((BaseUnityPlugin)context).Info.Metadata.Name + " reloaded weapon stats from files" }).GetValue(); return false; } if (text.ToLower().StartsWith(typeof(BepInExPlugin).Namespace.ToLower() + " dump ")) { string text2 = text.Split(new char[1] { ' ' })[^1]; WeaponData weaponDataByName = GetWeaponDataByName(text2); if (weaponDataByName == null) { return false; } Dbgl(JsonUtility.ToJson((object)weaponDataByName)); Traverse.Create((object)__instance).Method("AddString", new object[1] { text }).GetValue(); Traverse.Create((object)__instance).Method("AddString", new object[1] { ((BaseUnityPlugin)context).Info.Metadata.Name + " dumped " + text2 }).GetValue(); return false; } if (text.ToLower().Equals(typeof(BepInExPlugin).Namespace.ToLower() + " skills")) { Traverse.Create((object)__instance).Method("AddString", new object[1] { text }).GetValue(); List<string> list = new List<string>(); foreach (SkillType value in Enum.GetValues(typeof(SkillType))) { list.Add(Enum.GetName(typeof(SkillType), (object)value) + " " + (int)value); } Dbgl(string.Join("\r\n", list)); Traverse.Create((object)__instance).Method("AddString", new object[1] { ((BaseUnityPlugin)context).Info.Metadata.Name + " dumped skill types" }).GetValue(); return false; } if (text.ToLower().Equals(typeof(BepInExPlugin).Namespace.ToLower() + " se")) { Traverse.Create((object)__instance).Method("AddString", new object[1] { text }).GetValue(); Dbgl(string.Join("\r\n", ObjectDB.instance.m_StatusEffects.Select((StatusEffect se) => ((Object)se).name))); Traverse.Create((object)__instance).Method("AddString", new object[1] { ((BaseUnityPlugin)context).Info.Metadata.Name + " dumped status effects" }).GetValue(); return false; } if (text.ToLower().StartsWith(typeof(BepInExPlugin).Namespace.ToLower() + " save ")) { string text3 = text.Split(new char[1] { ' ' })[^1]; WeaponData weaponDataByName2 = GetWeaponDataByName(text3); if (weaponDataByName2 == null) { return false; } CheckModFolder(); File.WriteAllText(Path.Combine(assetPath, weaponDataByName2.name + ".json"), JsonUtility.ToJson((object)weaponDataByName2)); Traverse.Create((object)__instance).Method("AddString", new object[1] { text }).GetValue(); Traverse.Create((object)__instance).Method("AddString", new object[1] { ((BaseUnityPlugin)context).Info.Metadata.Name + " saved weapon data to " + text3 + ".json" }).GetValue(); return false; } if (text.ToLower().StartsWith(typeof(BepInExPlugin).Namespace.ToLower() ?? "")) { string text4 = ((BaseUnityPlugin)context).Info.Metadata.Name + " reset\r\n" + ((BaseUnityPlugin)context).Info.Metadata.Name + " reload\r\n" + ((BaseUnityPlugin)context).Info.Metadata.Name + " dump <WeaponName>\r\n" + ((BaseUnityPlugin)context).Info.Metadata.Name + " save <WeaponName>\r\n" + ((BaseUnityPlugin)context).Info.Metadata.Name + " skills" + ((BaseUnityPlugin)context).Info.Metadata.Name + " se"; Traverse.Create((object)__instance).Method("AddString", new object[1] { text }).GetValue(); Traverse.Create((object)__instance).Method("AddString", new object[1] { text4 }).GetValue(); return false; } return true; } } private static BepInExPlugin context; public static ConfigEntry<bool> modEnabled; public static ConfigEntry<bool> isDebug; public static ConfigEntry<int> nexusID; public static ConfigEntry<float> globalDamageMultiplier; public static ConfigEntry<float> globalUseDurabilityMultiplier; public static ConfigEntry<float> globalAttackForceMultiplier; public static ConfigEntry<float> globalBackstabBonusMultiplier; public static ConfigEntry<float> globalHoldDurationMinMultiplier; public static ConfigEntry<float> globalHoldStaminaDrainMultiplier; public static ConfigEntry<float> globalAttackStaminaUseMultiplier; private static List<WeaponData> weaponDatas; private static string assetPath; public static void Dbgl(string str = "", bool pref = true) { if (isDebug.Value) { Debug.Log((object)((pref ? (typeof(BepInExPlugin).Namespace + " ") : "") + str)); } } private void Awake() { context = this; modEnabled = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "Enabled", true, "Enable this mod"); isDebug = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "IsDebug", true, "Enable debug logs"); nexusID = ((BaseUnityPlugin)this).Config.Bind<int>("General", "NexusID", 1151, "Nexus mod ID for updates"); globalDamageMultiplier = ((BaseUnityPlugin)this).Config.Bind<float>("Global", "GlobalDamageMultiplier", 1f, "Global damage multiplier for all weapons"); globalUseDurabilityMultiplier = ((BaseUnityPlugin)this).Config.Bind<float>("Global", "GlobalUseDurabilityMultiplier", 1f, "Global use durability multiplier for all weapons"); globalAttackForceMultiplier = ((BaseUnityPlugin)this).Config.Bind<float>("Global", "GlobalAttackForceMultiplier", 1f, "Global attack force multiplier for all weapons"); globalBackstabBonusMultiplier = ((BaseUnityPlugin)this).Config.Bind<float>("Global", "GlobalBackstabBonusMultiplier", 1f, "Global backstab bonus multiplier for all weapons"); globalHoldDurationMinMultiplier = ((BaseUnityPlugin)this).Config.Bind<float>("Global", "GlobalHoldDurationMinMultiplier", 1f, "Global hold duration minimum multiplier for all weapons"); globalHoldStaminaDrainMultiplier = ((BaseUnityPlugin)this).Config.Bind<float>("Global", "GlobalHoldStaminaDrainMultiplier", 1f, "Global hold stamina drain multiplier for all weapons"); globalAttackStaminaUseMultiplier = ((BaseUnityPlugin)this).Config.Bind<float>("Global", "GlobalAttackStaminaUseMultiplier", 1f, "Global attack stamina use multiplier for all weapons"); assetPath = Path.Combine(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location), "CustomWeaponStats"); Harmony.CreateAndPatchAll(Assembly.GetExecutingAssembly(), (string)null); } private static void LoadAllWeaponData(bool reload) { if (reload) { weaponDatas = GetWeaponDataFromFiles(); } foreach (WeaponData weaponData in weaponDatas) { GameObject itemPrefab = ObjectDB.instance.GetItemPrefab(weaponData.name); if ((Object)(object)itemPrefab == (Object)null) { continue; } ItemData val = itemPrefab.GetComponent<ItemDrop>()?.m_itemData; if (itemPrefab.GetComponent<ItemDrop>()?.m_itemData == null) { continue; } SetWeaponData(ref itemPrefab.GetComponent<ItemDrop>().m_itemData, weaponData); for (int i = 0; i < ObjectDB.instance.m_recipes.Count; i++) { Recipe val2 = ObjectDB.instance.m_recipes[i]; if (!((Object)(object)val2.m_item == (Object)null) && val2.m_item.m_itemData.m_shared.m_name == val.m_shared.m_name) { SetWeaponData(ref val2.m_item.m_itemData, weaponData); ObjectDB.instance.m_recipes[i] = val2; } } if (!Object.op_Implicit((Object)(object)Player.m_localPlayer)) { continue; } List<ItemData> allItems = ((Humanoid)Player.m_localPlayer).GetInventory().GetAllItems(); for (int j = 0; j < allItems.Count; j++) { ItemData item = allItems[j]; if (item.m_shared.m_name == val.m_shared.m_name) { SetWeaponData(ref item, weaponData); } allItems[j] = item; } } } private static void CheckWeaponData(ref ItemData instance) { try { string name = ((Object)instance.m_dropPrefab).name; WeaponData weapon = weaponDatas.First((WeaponData d) => d.name == name); SetWeaponData(ref instance, weapon); } catch { } } private static List<WeaponData> GetWeaponDataFromFiles() { CheckModFolder(); List<WeaponData> list = new List<WeaponData>(); string[] files = Directory.GetFiles(assetPath, "*.json"); foreach (string path in files) { WeaponData item = JsonUtility.FromJson<WeaponData>(File.ReadAllText(path)); list.Add(item); } return list; } private static void SetWeaponData(ref ItemData item, WeaponData weapon) { //IL_0051: Unknown result type (might be due to invalid IL or missing references) //IL_0056: Unknown result type (might be due to invalid IL or missing references) item.m_shared.m_ammoType = weapon.ammoType; item.m_shared.m_useDurability = weapon.useDurability; item.m_shared.m_useDurabilityDrain = weapon.useDurabilityDrain; item.m_shared.m_durabilityPerLevel = weapon.durabilityPerLevel; item.m_shared.m_skillType = weapon.skillType; item.m_shared.m_toolTier = weapon.toolTier; item.m_shared.m_blockable = weapon.blockable; item.m_shared.m_dodgeable = weapon.dodgeable; item.m_shared.m_attackForce = weapon.attackForce; item.m_shared.m_backstabBonus = weapon.backStabBonus; item.m_shared.m_blockPower = weapon.blockPower; item.m_shared.m_blockPowerPerLevel = weapon.blockPowerPerLevel; item.m_shared.m_deflectionForce = weapon.deflectionForce; item.m_shared.m_deflectionForcePerLevel = weapon.deflectionForcePerLevel; item.m_shared.m_damages.m_damage = weapon.damage; item.m_shared.m_damages.m_blunt = weapon.blunt; item.m_shared.m_damages.m_slash = weapon.slash; item.m_shared.m_damages.m_pierce = weapon.pierce; item.m_shared.m_damages.m_chop = weapon.chop; item.m_shared.m_damages.m_pickaxe = weapon.pickaxe; item.m_shared.m_damages.m_fire = weapon.fire; item.m_shared.m_damages.m_frost = weapon.frost; item.m_shared.m_damages.m_lightning = weapon.lightning; item.m_shared.m_damages.m_poison = weapon.poison; item.m_shared.m_damages.m_spirit = weapon.spirit; item.m_shared.m_damagesPerLevel.m_damage = weapon.damagePerLevel; item.m_shared.m_damagesPerLevel.m_blunt = weapon.bluntPerLevel; item.m_shared.m_damagesPerLevel.m_slash = weapon.slashPerLevel; item.m_shared.m_damagesPerLevel.m_pierce = weapon.piercePerLevel; item.m_shared.m_damagesPerLevel.m_chop = weapon.chopPerLevel; item.m_shared.m_damagesPerLevel.m_pickaxe = weapon.pickaxePerLevel; item.m_shared.m_damagesPerLevel.m_fire = weapon.firePerLevel; item.m_shared.m_damagesPerLevel.m_frost = weapon.frostPerLevel; item.m_shared.m_damagesPerLevel.m_lightning = weapon.lightningPerLevel; item.m_shared.m_damagesPerLevel.m_poison = weapon.poisonPerLevel; item.m_shared.m_damagesPerLevel.m_spirit = weapon.spiritPerLevel; item.m_shared.m_attack.m_hitTerrain = weapon.hitTerrain; if (item.m_shared.m_secondaryAttack != null) { item.m_shared.m_secondaryAttack.m_hitTerrain = weapon.hitTerrainSecondary; } item.m_shared.m_attackStatusEffect = ObjectDB.instance.GetStatusEffect((!string.IsNullOrEmpty(weapon.statusEffect)) ? StringExtensionMethods.GetStableHashCode(weapon.statusEffect) : 0); } private static WeaponData GetWeaponDataByName(string weapon) { GameObject itemPrefab = ObjectDB.instance.GetItemPrefab(weapon); if (!Object.op_Implicit((Object)(object)itemPrefab)) { Dbgl("Weapon not found!"); return null; } ItemData itemData = itemPrefab.GetComponent<ItemDrop>().m_itemData; return GetWeaponDataFromItem(itemData, weapon); } private static WeaponData GetWeaponDataFromItem(ItemData item, string itemName) { //IL_0058: Unknown result type (might be due to invalid IL or missing references) //IL_005d: Unknown result type (might be due to invalid IL or missing references) WeaponData obj = new WeaponData { name = itemName, ammoType = item.m_shared.m_ammoType, useDurability = item.m_shared.m_useDurability, durabilityPerLevel = item.m_shared.m_durabilityPerLevel, useDurabilityDrain = item.m_shared.m_useDurabilityDrain, skillType = item.m_shared.m_skillType, toolTier = item.m_shared.m_toolTier, blockable = item.m_shared.m_blockable, dodgeable = item.m_shared.m_dodgeable, attackForce = item.m_shared.m_attackForce, backStabBonus = item.m_shared.m_backstabBonus, blockPower = item.m_shared.m_blockPower, blockPowerPerLevel = item.m_shared.m_blockPowerPerLevel, deflectionForce = item.m_shared.m_deflectionForce, deflectionForcePerLevel = item.m_shared.m_deflectionForcePerLevel, damage = item.m_shared.m_damages.m_damage, blunt = item.m_shared.m_damages.m_blunt, slash = item.m_shared.m_damages.m_slash, pierce = item.m_shared.m_damages.m_pierce, chop = item.m_shared.m_damages.m_chop, pickaxe = item.m_shared.m_damages.m_pickaxe, fire = item.m_shared.m_damages.m_fire, frost = item.m_shared.m_damages.m_frost, lightning = item.m_shared.m_damages.m_lightning, poison = item.m_shared.m_damages.m_poison, spirit = item.m_shared.m_damages.m_spirit, damagePerLevel = item.m_shared.m_damagesPerLevel.m_damage, bluntPerLevel = item.m_shared.m_damagesPerLevel.m_blunt, slashPerLevel = item.m_shared.m_damagesPerLevel.m_slash, piercePerLevel = item.m_shared.m_damagesPerLevel.m_pierce, chopPerLevel = item.m_shared.m_damagesPerLevel.m_chop, pickaxePerLevel = item.m_shared.m_damagesPerLevel.m_pickaxe, firePerLevel = item.m_shared.m_damagesPerLevel.m_fire, frostPerLevel = item.m_shared.m_damagesPerLevel.m_frost, lightningPerLevel = item.m_shared.m_damagesPerLevel.m_lightning, poisonPerLevel = item.m_shared.m_damagesPerLevel.m_poison, spiritPerLevel = item.m_shared.m_damagesPerLevel.m_spirit }; StatusEffect attackStatusEffect = item.m_shared.m_attackStatusEffect; obj.statusEffect = ((attackStatusEffect != null) ? ((Object)attackStatusEffect).name : null); obj.hitTerrain = item.m_shared.m_attack?.m_hitTerrain ?? false; obj.hitTerrainSecondary = item.m_shared.m_secondaryAttack?.m_hitTerrain ?? false; return obj; } private static void CheckModFolder() { if (!Directory.Exists(assetPath)) { Dbgl("Creating mod folder"); Directory.CreateDirectory(assetPath); } } } internal class WeaponData { public string name; public bool useDurability; public bool blockable; public bool dodgeable; public SkillType skillType; public float useDurabilityDrain; public float durabilityPerLevel; public float holdDurationMin; public float holdStaminaDrain; public int toolTier; public string ammoType; public string statusEffect; public float backStabBonus; public float blockPower; public float deflectionForce; public float attackForce; public float blunt; public float damage; public float pierce; public float slash; public float chop; public float pickaxe; public float fire; public float frost; public float lightning; public float poison; public float spirit; public float blockPowerPerLevel; public float deflectionForcePerLevel; public float bluntPerLevel; public float damagePerLevel; public float piercePerLevel; public float slashPerLevel; public float chopPerLevel; public float pickaxePerLevel; public float firePerLevel; public float frostPerLevel; public float lightningPerLevel; public float poisonPerLevel; public float spiritPerLevel; public bool hitTerrain; public bool hitTerrainSecondary; } public class WeaponState : SharedData { public float useDurabilityDrain; public float holdDurationMin; public float holdStaminaDrain; public float attackForce; public float backstabBonus; public float damage; public float blunt; public float slash; public float pierce; public float chop; public float pickaxe; public float fire; public float frost; public float lightning; public float poison; public float spirit; public bool hitTerrain; public bool hitTerrainSecondary; public WeaponState(ItemData weapon) { useDurabilityDrain = weapon.m_shared.m_useDurabilityDrain; attackForce = weapon.m_shared.m_attackForce; backstabBonus = weapon.m_shared.m_backstabBonus; damage = weapon.m_shared.m_damages.m_damage; blunt = weapon.m_shared.m_damages.m_blunt; slash = weapon.m_shared.m_damages.m_slash; pierce = weapon.m_shared.m_damages.m_pierce; chop = weapon.m_shared.m_damages.m_chop; pickaxe = weapon.m_shared.m_damages.m_pickaxe; fire = weapon.m_shared.m_damages.m_fire; frost = weapon.m_shared.m_damages.m_frost; lightning = weapon.m_shared.m_damages.m_lightning; poison = weapon.m_shared.m_damages.m_poison; spirit = weapon.m_shared.m_damages.m_spirit; hitTerrain = weapon.m_shared.m_attack?.m_hitTerrain ?? false; hitTerrainSecondary = weapon.m_shared.m_secondaryAttack?.m_hitTerrain ?? false; } }
BepInEx/plugins/satt-CustomArmorStats/CustomArmorStats.dll
Decompiled 6 months agousing System; using System.Collections.Generic; using System.Diagnostics; using System.IO; using System.Linq; using System.Reflection; using System.Reflection.Emit; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using System.Text.RegularExpressions; using BepInEx; using BepInEx.Configuration; using HarmonyLib; using TMPro; 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.8", FrameworkDisplayName = ".NET Framework 4.8")] [assembly: AssemblyConfiguration("Debug")] [assembly: AssemblyFileVersion("1.0.0.0")] [assembly: AssemblyInformationalVersion("1.0.0")] [assembly: AssemblyVersion("1.0.0.0")] namespace CustomArmorStats; internal class ArmorData { public string name; public float armor; public float armorPerLevel; public float movementModifier; public List<string> damageModifiers = new List<string>(); } [BepInPlugin("aedenthorn.CustomArmorStats", "Custom Armor Stats", "0.6.0")] public class BepInExPlugin : BaseUnityPlugin { private enum NewDamageTypes { Water = 0x400 } [HarmonyPatch(typeof(ZNetScene), "Awake")] private static class ZNetScene_Awake_Patch { private static void Postfix(ZNetScene __instance) { if (modEnabled.Value) { LoadAllArmorData(__instance); } } } [HarmonyPatch(typeof(ItemDrop), "Awake")] private static class ItemDrop_Awake_Patch { private static void Postfix(ItemDrop __instance) { if (modEnabled.Value) { CheckArmorData(ref __instance.m_itemData); } } } [HarmonyPatch(typeof(ItemDrop), "SlowUpdate")] private static class ItemDrop_SlowUpdate_Patch { private static void Postfix(ref ItemDrop __instance) { if (modEnabled.Value) { CheckArmorData(ref __instance.m_itemData); } } } [HarmonyPatch(typeof(Player), "DamageArmorDurability")] private static class Player_DamageArmorDurability_Patch { private static void Prefix(ref HitData hit) { if (modEnabled.Value) { hit.ApplyModifier(globalArmorDurabilityLossMult.Value); } } } [HarmonyPatch(typeof(Player), "GetEquipmentMovementModifier")] private static class GetEquipmentMovementModifier_Patch { private static void Postfix(ref float __result) { if (modEnabled.Value) { __result *= globalArmorMovementModMult.Value; } } } [HarmonyPatch(typeof(Player), "GetJogSpeedFactor")] private static class GetJogSpeedFactor_Patch { private static bool Prefix(ref float __result, float ___m_equipmentMovementModifier) { if (!modEnabled.Value) { return true; } __result = 1f + ___m_equipmentMovementModifier * globalArmorMovementModMult.Value; return false; } } [HarmonyPatch(typeof(Player), "GetRunSpeedFactor")] private static class GetRunSpeedFactor_Patch { private static bool Prefix(Skills ___m_skills, float ___m_equipmentMovementModifier, ref float __result) { if (!modEnabled.Value) { return true; } float skillFactor = ___m_skills.GetSkillFactor((SkillType)102); __result = (1f + skillFactor * 0.25f) * (1f + ___m_equipmentMovementModifier * 1.5f * globalArmorMovementModMult.Value); return false; } } [HarmonyPatch(typeof(SEMan), "AddStatusEffect", new Type[] { typeof(StatusEffect), typeof(bool), typeof(int), typeof(float) })] private static class SEMan_AddStatusEffect_Patch { private static bool Prefix(SEMan __instance, StatusEffect statusEffect, Character ___m_character, ref StatusEffect __result) { //IL_003c: 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_0042: Unknown result type (might be due to invalid IL or missing references) //IL_0044: Invalid comparison between Unknown and I4 //IL_0046: Unknown result type (might be due to invalid IL or missing references) //IL_0048: Invalid comparison between Unknown and I4 if (!modEnabled.Value || !___m_character.IsPlayer()) { return true; } if (statusEffect.m_name == "$se_wet_name") { DamageModifier newDamageTypeMod = GetNewDamageTypeMod(NewDamageTypes.Water, ___m_character); if ((int)newDamageTypeMod == 4 || (int)newDamageTypeMod == 3) { __result = null; return false; } } return true; } } [HarmonyPatch(typeof(SE_Stats), "GetDamageModifiersTooltipString")] private static class GetDamageModifiersTooltipString_Patch { private static void Postfix(ref string __result, List<DamageModPair> mods) { //IL_0039: Unknown result type (might be due to invalid IL or missing references) //IL_003e: 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_0063: Unknown result type (might be due to invalid IL or missing references) //IL_0064: Unknown result type (might be due to invalid IL or missing references) //IL_006a: Invalid comparison between Unknown and I4 //IL_006c: Unknown result type (might be due to invalid IL or missing references) //IL_006d: Unknown result type (might be due to invalid IL or missing references) //IL_0073: Invalid comparison between Unknown and I4 //IL_0082: Unknown result type (might be due to invalid IL or missing references) //IL_0083: Unknown result type (might be due to invalid IL or missing references) //IL_0088: Unknown result type (might be due to invalid IL or missing references) //IL_008a: Unknown result type (might be due to invalid IL or missing references) //IL_008c: Unknown result type (might be due to invalid IL or missing references) //IL_008e: Unknown result type (might be due to invalid IL or missing references) //IL_0091: Unknown result type (might be due to invalid IL or missing references) //IL_00af: Expected I4, but got Unknown //IL_0101: Unknown result type (might be due to invalid IL or missing references) //IL_0102: Unknown result type (might be due to invalid IL or missing references) //IL_010c: Invalid comparison between Unknown and I4 if (!modEnabled.Value) { return; } __result = Regex.Replace(__result, "\\n.*<color=orange></color>", ""); foreach (DamageModPair mod in mods) { if (!Enum.IsDefined(typeof(DamageType), mod.m_type) && (int)mod.m_modifier != 4 && (int)mod.m_modifier > 0) { DamageModifier modifier = mod.m_modifier; DamageModifier val = modifier; switch (val - 1) { case 0: __result += "\n$inventory_dmgmod: <color=orange>$inventory_resistant</color> VS "; break; case 1: __result += "\n$inventory_dmgmod: <color=orange>$inventory_weak</color> VS "; break; case 2: __result += "\n$inventory_dmgmod: <color=orange>$inventory_immune</color> VS "; break; case 4: __result += "\n$inventory_dmgmod: <color=orange>$inventory_veryresistant</color> VS "; break; case 5: __result += "\n$inventory_dmgmod: <color=orange>$inventory_veryweak</color> VS "; break; } if ((int)mod.m_type == 1024) { __result = __result + "<color=orange>" + waterModifierName.Value + "</color>"; } } } } } [HarmonyPatch(typeof(Player), "UpdateEnvStatusEffects")] private static class UpdateEnvStatusEffects_Patch { public static IEnumerable<CodeInstruction> Transpiler(IEnumerable<CodeInstruction> instructions) { //IL_00e8: Unknown result type (might be due to invalid IL or missing references) //IL_00f2: Expected O, but got Unknown //IL_00fa: Unknown result type (might be due to invalid IL or missing references) //IL_0104: Expected O, but got Unknown //IL_010f: Unknown result type (might be due to invalid IL or missing references) //IL_0119: Expected O, but got Unknown //IL_0122: Unknown result type (might be due to invalid IL or missing references) //IL_012c: Expected O, but got Unknown //IL_0134: Unknown result type (might be due to invalid IL or missing references) //IL_013e: Expected O, but got Unknown //IL_0149: Unknown result type (might be due to invalid IL or missing references) //IL_0153: Expected O, but got Unknown Dbgl("Transpiling UpdateEnvStatusEffects"); List<CodeInstruction> list = new List<CodeInstruction>(instructions); List<CodeInstruction> list2 = new List<CodeInstruction>(); bool flag = true; for (int i = 0; i < list.Count; i++) { if (flag && list[i].opcode == OpCodes.Ldloc_S && list[i + 1].opcode == OpCodes.Ldc_I4_1 && list[i + 2].opcode == OpCodes.Beq && list[i + 3].opcode == OpCodes.Ldloc_S && list[i + 3].operand == list[i].operand && list[i + 4].opcode == OpCodes.Ldc_I4_5) { Dbgl("Adding frost immune and ignore"); list2.Add(new CodeInstruction(list[i])); list2.Add(new CodeInstruction(OpCodes.Ldc_I4_3, (object)null)); list2.Add(new CodeInstruction(list[i + 2])); list2.Add(new CodeInstruction(list[i])); list2.Add(new CodeInstruction(OpCodes.Ldc_I4_4, (object)null)); list2.Add(new CodeInstruction(list[i + 2])); flag = false; } list2.Add(list[i]); } return list2.AsEnumerable(); } private static void Postfix(float dt, Player __instance, ItemData ___m_chestItem, ItemData ___m_legItem, ItemData ___m_helmetItem, ItemData ___m_shoulderItem, SEMan ___m_seman) { //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) //IL_005a: Unknown result type (might be due to invalid IL or missing references) //IL_005c: Invalid comparison between Unknown and I4 //IL_005e: Unknown result type (might be due to invalid IL or missing references) //IL_0060: Invalid comparison between Unknown and I4 //IL_007c: Unknown result type (might be due to invalid IL or missing references) //IL_007e: Invalid comparison between Unknown and I4 //IL_00c4: Unknown result type (might be due to invalid IL or missing references) //IL_00c6: Invalid comparison between Unknown and I4 //IL_011a: Unknown result type (might be due to invalid IL or missing references) //IL_011c: Invalid comparison between Unknown and I4 //IL_0173: Unknown result type (might be due to invalid IL or missing references) //IL_0175: Invalid comparison between Unknown and I4 if (modEnabled.Value && ___m_seman.HaveStatusEffect("Wet")) { int stableHashCode = StringExtensionMethods.GetStableHashCode("Wet"); DamageModifier newDamageTypeMod = GetNewDamageTypeMod(NewDamageTypes.Water, ___m_chestItem, ___m_legItem, ___m_helmetItem, ___m_shoulderItem); StatusEffect statusEffect = ___m_seman.GetStatusEffect(stableHashCode); Traverse val = Traverse.Create((object)statusEffect); if ((int)newDamageTypeMod == 4 || (int)newDamageTypeMod == 3) { ___m_seman.RemoveStatusEffect(stableHashCode, true); } else if ((int)newDamageTypeMod == 5 && !(bool)AccessTools.Method(typeof(Character), "InLiquidSwimDepth", (Type[])null, (Type[])null).Invoke(__instance, new object[0])) { ___m_seman.RemoveStatusEffect(stableHashCode, true); } else if ((int)newDamageTypeMod == 1) { val.Field("m_time").SetValue((object)(val.Field("m_time").GetValue<float>() + dt)); ___m_seman.RemoveStatusEffect(stableHashCode, true); ___m_seman.AddStatusEffect(statusEffect, false, 0, 0f); } else if ((int)newDamageTypeMod == 2) { val.Field("m_time").SetValue((object)(val.Field("m_time").GetValue<float>() - dt / 3f)); ___m_seman.RemoveStatusEffect(stableHashCode, true); ___m_seman.AddStatusEffect(statusEffect, false, 0, 0f); } else if ((int)newDamageTypeMod == 6) { val.Field("m_time").SetValue((object)(val.Field("m_time").GetValue<float>() - dt * 2f / 3f)); ___m_seman.RemoveStatusEffect(stableHashCode, true); ___m_seman.AddStatusEffect(statusEffect, false, 0, 0f); } } } } [HarmonyPatch(typeof(Terminal), "InputText")] private static class InputText_Patch { private static bool Prefix(Terminal __instance) { if (!modEnabled.Value) { return true; } string text = ((TMP_InputField)__instance.m_input).text; if (text.ToLower().Equals(typeof(BepInExPlugin).Namespace.ToLower() + " reset")) { ((BaseUnityPlugin)context).Config.Reload(); ((BaseUnityPlugin)context).Config.Save(); __instance.AddString(text); __instance.AddString(((BaseUnityPlugin)context).Info.Metadata.Name + " config reloaded"); return false; } if (text.ToLower().Equals(typeof(BepInExPlugin).Namespace.ToLower() + " reload")) { armorDatas = GetArmorDataFromFiles(); if (Object.op_Implicit((Object)(object)ZNetScene.instance)) { LoadAllArmorData(ZNetScene.instance); } __instance.AddString(text); __instance.AddString(((BaseUnityPlugin)context).Info.Metadata.Name + " reloaded armor stats from files"); return false; } if (text.ToLower().Equals(typeof(BepInExPlugin).Namespace.ToLower() + " damagetypes")) { __instance.AddString(text); Dbgl("\r\n" + string.Join("\r\n", Enum.GetNames(typeof(DamageType)))); __instance.AddString(((BaseUnityPlugin)context).Info.Metadata.Name + " dumped damage types"); return false; } if (text.ToLower().Equals(typeof(BepInExPlugin).Namespace.ToLower() + " damagemods")) { __instance.AddString(text); Dbgl("\r\n" + string.Join("\r\n", Enum.GetNames(typeof(DamageModifier)))); __instance.AddString(((BaseUnityPlugin)context).Info.Metadata.Name + " dumped damage modifiers"); return false; } if (text.ToLower().StartsWith(typeof(BepInExPlugin).Namespace.ToLower() + " save ")) { string text2 = text.Split(new char[1] { ' ' })[^1]; ArmorData armorDataByName = GetArmorDataByName(text2); if (armorDataByName == null) { return false; } CheckModFolder(); File.WriteAllText(Path.Combine(assetPath, armorDataByName.name + ".json"), JsonUtility.ToJson((object)armorDataByName, true)); __instance.AddString(text); __instance.AddString(((BaseUnityPlugin)context).Info.Metadata.Name + " saved armor data to " + text2 + ".json"); return false; } if (text.ToLower().StartsWith(typeof(BepInExPlugin).Namespace.ToLower() + " dump ")) { string text3 = text.Split(new char[1] { ' ' })[^1]; ArmorData armorDataByName2 = GetArmorDataByName(text3); if (armorDataByName2 == null) { return false; } Dbgl(JsonUtility.ToJson((object)armorDataByName2)); __instance.AddString(text); __instance.AddString(((BaseUnityPlugin)context).Info.Metadata.Name + " dumped " + text3); return false; } if (text.ToLower().StartsWith(typeof(BepInExPlugin).Namespace.ToLower() ?? "")) { string text4 = ((BaseUnityPlugin)context).Info.Metadata.Name + " reset\r\n" + ((BaseUnityPlugin)context).Info.Metadata.Name + " reload\r\n" + ((BaseUnityPlugin)context).Info.Metadata.Name + " dump <ArmorName>\r\n" + ((BaseUnityPlugin)context).Info.Metadata.Name + " save <ArmorName>\r\n" + ((BaseUnityPlugin)context).Info.Metadata.Name + " damagetypes\r\n" + ((BaseUnityPlugin)context).Info.Metadata.Name + " damagemods"; __instance.AddString(text); __instance.AddString(text4); return false; } return true; } } private static BepInExPlugin context; public static ConfigEntry<bool> modEnabled; public static ConfigEntry<bool> isDebug; public static ConfigEntry<int> nexusID; public static ConfigEntry<float> globalArmorDurabilityLossMult; public static ConfigEntry<float> globalArmorMovementModMult; public static ConfigEntry<string> waterModifierName; private static List<ArmorData> armorDatas; private static string assetPath; public static void Dbgl(string str = "", bool pref = true) { if (isDebug.Value) { Debug.Log((object)((pref ? (typeof(BepInExPlugin).Namespace + " ") : "") + str)); } } private void Awake() { context = this; modEnabled = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "Enabled", true, "Enable this mod"); isDebug = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "IsDebug", true, "Enable debug logs"); nexusID = ((BaseUnityPlugin)this).Config.Bind<int>("General", "NexusID", 1162, "Nexus mod ID for updates"); nexusID.Value = 1162; globalArmorDurabilityLossMult = ((BaseUnityPlugin)this).Config.Bind<float>("Stats", "GlobalArmorDurabilityLossMult", 1f, "Global armor durability loss multiplier"); globalArmorMovementModMult = ((BaseUnityPlugin)this).Config.Bind<float>("Stats", "GlobalArmorMovementModMult", 1f, "Global armor movement modifier multiplier"); waterModifierName = ((BaseUnityPlugin)this).Config.Bind<string>("Strings", "WaterModifierName", "Water", "Name of water damage modifier to show in tooltip"); assetPath = Path.Combine(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location), "CustomArmorStats"); Harmony.CreateAndPatchAll(Assembly.GetExecutingAssembly(), (string)null); } private static DamageModifier GetNewDamageTypeMod(NewDamageTypes type, Character character) { //IL_0049: Unknown result type (might be due to invalid IL or missing references) //IL_004e: 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) Traverse val = Traverse.Create((object)character); return GetNewDamageTypeMod(type, val.Field("m_chestItem").GetValue<ItemData>(), val.Field("m_legItem").GetValue<ItemData>(), val.Field("m_helmetItem").GetValue<ItemData>(), val.Field("m_shoulderItem").GetValue<ItemData>()); } private static DamageModifier GetNewDamageTypeMod(NewDamageTypes type, ItemData chestItem, ItemData legItem, ItemData helmetItem, ItemData shoulderItem) { //IL_0010: 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_003a: Unknown result type (might be due to invalid IL or missing references) //IL_005b: 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_0062: Unknown result type (might be due to invalid IL or missing references) //IL_0063: Unknown result type (might be due to invalid IL or missing references) //IL_0068: Unknown result type (might be due to invalid IL or missing references) //IL_006a: 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_00a5: Unknown result type (might be due to invalid IL or missing references) //IL_00a7: Unknown result type (might be due to invalid IL or missing references) //IL_00a8: Unknown result type (might be due to invalid IL or missing references) //IL_00ad: Unknown result type (might be due to invalid IL or missing references) //IL_00af: Unknown result type (might be due to invalid IL or missing references) //IL_007a: Unknown result type (might be due to invalid IL or missing references) //IL_007c: Unknown result type (might be due to invalid IL or missing references) //IL_010a: Unknown result type (might be due to invalid IL or missing references) //IL_010b: Unknown result type (might be due to invalid IL or missing references) //IL_0110: Unknown result type (might be due to invalid IL or missing references) //IL_00e7: Unknown result type (might be due to invalid IL or missing references) //IL_00ec: Unknown result type (might be due to invalid IL or missing references) //IL_00ee: Unknown result type (might be due to invalid IL or missing references) //IL_00ef: Unknown result type (might be due to invalid IL or missing references) //IL_00f4: Unknown result type (might be due to invalid IL or missing references) //IL_00f6: 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) //IL_00c1: Unknown result type (might be due to invalid IL or missing references) //IL_0114: Unknown result type (might be due to invalid IL or missing references) //IL_0106: Unknown result type (might be due to invalid IL or missing references) //IL_0108: Unknown result type (might be due to invalid IL or missing references) DamageModPair val = default(DamageModPair); if (chestItem != null) { val = ((IEnumerable<DamageModPair>)chestItem.m_shared.m_damageModifiers).FirstOrDefault((Func<DamageModPair, bool>)((DamageModPair s) => (int)s.m_type == (int)type)); } if (legItem != null) { DamageModPair val2 = ((IEnumerable<DamageModPair>)legItem.m_shared.m_damageModifiers).FirstOrDefault((Func<DamageModPair, bool>)((DamageModPair s) => (int)s.m_type == (int)type)); if (ShouldOverride(val.m_modifier, val2.m_modifier)) { val = val2; } } if (helmetItem != null) { DamageModPair val3 = ((IEnumerable<DamageModPair>)helmetItem.m_shared.m_damageModifiers).FirstOrDefault((Func<DamageModPair, bool>)((DamageModPair s) => (int)s.m_type == (int)type)); if (ShouldOverride(val.m_modifier, val3.m_modifier)) { val = val3; } } if (shoulderItem != null) { DamageModPair val4 = ((IEnumerable<DamageModPair>)shoulderItem.m_shared.m_damageModifiers).FirstOrDefault((Func<DamageModPair, bool>)((DamageModPair s) => (int)s.m_type == (int)type)); if (ShouldOverride(val.m_modifier, val4.m_modifier)) { val = val4; } } return val.m_modifier; } private static bool ShouldOverride(DamageModifier a, DamageModifier b) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0003: Invalid comparison between Unknown and I4 //IL_0005: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Invalid comparison between Unknown and I4 //IL_0009: Unknown result type (might be due to invalid IL or missing references) //IL_000b: Invalid comparison between Unknown and I4 //IL_0011: Unknown result type (might be due to invalid IL or missing references) //IL_0013: Invalid comparison between Unknown and I4 //IL_000d: Unknown result type (might be due to invalid IL or missing references) //IL_000f: Invalid comparison between Unknown and I4 //IL_0015: Unknown result type (might be due to invalid IL or missing references) //IL_0017: Invalid comparison between Unknown and I4 return (int)a != 4 && ((int)b == 3 || (((int)a != 5 || (int)b != 1) && ((int)a != 6 || (int)b != 2))); } private static void LoadAllArmorData(ZNetScene scene) { armorDatas = GetArmorDataFromFiles(); foreach (ArmorData armorData in armorDatas) { GameObject prefab = scene.GetPrefab(armorData.name); if (!((Object)(object)prefab == (Object)null)) { ItemData item = prefab.GetComponent<ItemDrop>().m_itemData; SetArmorData(ref item, armorData); prefab.GetComponent<ItemDrop>().m_itemData = item; } } } private static void CheckArmorData(ref ItemData instance) { try { string name = ((Object)instance.m_dropPrefab).name; ArmorData armor = armorDatas.First((ArmorData d) => d.name == name); SetArmorData(ref instance, armor); } catch { } } private static List<ArmorData> GetArmorDataFromFiles() { CheckModFolder(); List<ArmorData> list = new List<ArmorData>(); string[] files = Directory.GetFiles(assetPath, "*.json"); foreach (string path in files) { ArmorData item = JsonUtility.FromJson<ArmorData>(File.ReadAllText(path)); list.Add(item); } return list; } private static void CheckModFolder() { if (!Directory.Exists(assetPath)) { Dbgl("Creating mod folder"); Directory.CreateDirectory(assetPath); } } private static void SetArmorData(ref ItemData item, ArmorData armor) { //IL_00ac: Unknown result type (might be due to invalid IL or missing references) //IL_00b5: Unknown result type (might be due to invalid IL or missing references) //IL_00ce: Unknown result type (might be due to invalid IL or missing references) //IL_00d3: Unknown result type (might be due to invalid IL or missing references) //IL_00d8: Unknown result type (might be due to invalid IL or missing references) item.m_shared.m_armor = armor.armor; item.m_shared.m_armorPerLevel = armor.armorPerLevel; item.m_shared.m_movementModifier = armor.movementModifier; item.m_shared.m_damageModifiers.Clear(); foreach (string damageModifier in armor.damageModifiers) { string[] array = damageModifier.Split(new char[1] { ':' }); NewDamageTypes result; int num = (Enum.TryParse<NewDamageTypes>(array[0], out result) ? ((int)result) : ((int)Enum.Parse(typeof(DamageType), array[0]))); item.m_shared.m_damageModifiers.Add(new DamageModPair { m_type = (DamageType)num, m_modifier = (DamageModifier)Enum.Parse(typeof(DamageModifier), array[1]) }); } } private static ArmorData GetArmorDataByName(string armor) { GameObject itemPrefab = ObjectDB.instance.GetItemPrefab(armor); if (!Object.op_Implicit((Object)(object)itemPrefab)) { Dbgl("Armor not found!"); return null; } ItemData itemData = itemPrefab.GetComponent<ItemDrop>().m_itemData; return GetArmorDataFromItem(itemData, armor); } private static ArmorData GetArmorDataFromItem(ItemData item, string itemName) { return new ArmorData { name = itemName, armor = item.m_shared.m_armor, armorPerLevel = item.m_shared.m_armorPerLevel, movementModifier = item.m_shared.m_movementModifier, damageModifiers = item.m_shared.m_damageModifiers.Select((DamageModPair m) => ((object)(DamageType)(ref m.m_type)).ToString() + ":" + ((object)(DamageModifier)(ref m.m_modifier)).ToString()).ToList() }; } }
BepInEx/plugins/satt-Custom_Weapon_Stats/CustomWeaponStats.dll
Decompiled 6 months agousing System; using System.Collections.Generic; using System.Diagnostics; using System.IO; using System.Linq; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; using System.Runtime.Versioning; using BepInEx; using BepInEx.Configuration; using HarmonyLib; using TMPro; using UnityEngine; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)] [assembly: AssemblyTitle("CustomWeapons")] [assembly: AssemblyDescription("")] [assembly: AssemblyConfiguration("")] [assembly: AssemblyCompany("")] [assembly: AssemblyProduct("CustomWeapons")] [assembly: AssemblyCopyright("Copyright © 2021")] [assembly: AssemblyTrademark("")] [assembly: ComVisible(false)] [assembly: Guid("0efd1fbe-b627-4680-9a66-b95aa347eb48")] [assembly: AssemblyFileVersion("1.0.0.0")] [assembly: TargetFramework(".NETFramework,Version=v4.8", FrameworkDisplayName = ".NET Framework 4.8")] [assembly: AssemblyInformationalVersion("1.0.0")] [assembly: AssemblyVersion("1.0.0.0")] namespace CustomWeaponStats; [BepInPlugin("aedenthorn.CustomWeaponStats", "Custom Weapon Stats", "0.7.0")] public class BepInExPlugin : BaseUnityPlugin { [HarmonyPatch(typeof(ObjectDB), "CopyOtherDB")] private static class CopyOtherDB_Patch { private static void Postfix() { if (modEnabled.Value) { LoadAllWeaponData(reload: true); } } } [HarmonyPatch(typeof(InventoryGui), "Show")] [HarmonyPriority(0)] private static class InventoryGui_Show_Patch { private static void Postfix() { if (modEnabled.Value) { LoadAllWeaponData(reload: false); } } } [HarmonyPatch(typeof(ItemDrop), "Awake")] private static class ItemDrop_Awake_Patch { private static void Postfix(ItemDrop __instance) { if (modEnabled.Value) { CheckWeaponData(ref __instance.m_itemData); } } } [HarmonyPatch(typeof(ItemDrop), "SlowUpdate")] private static class ItemDrop_SlowUpdate_Patch { private static void Postfix(ref ItemDrop __instance) { if (modEnabled.Value) { CheckWeaponData(ref __instance.m_itemData); } } } [HarmonyPatch(typeof(Attack), "GetAttackStamina")] private static class GetAttackStamina_Patch { private static void Postfix(ref float __result) { if (modEnabled.Value) { __result *= globalAttackStaminaUseMultiplier.Value; } } } [HarmonyPatch(typeof(Attack), "Start")] private static class Attack_Start_Patch { private static void Prefix(ref ItemData weapon, ref WeaponState __state) { if (modEnabled.Value) { CheckWeaponData(ref weapon); Dbgl($"pre damage {weapon.m_shared.m_damages.m_slash}"); __state = new WeaponState(weapon); SharedData shared = weapon.m_shared; shared.m_useDurabilityDrain *= globalUseDurabilityMultiplier.Value; SharedData shared2 = weapon.m_shared; shared2.m_attackForce *= globalAttackForceMultiplier.Value; SharedData shared3 = weapon.m_shared; shared3.m_backstabBonus *= globalBackstabBonusMultiplier.Value; weapon.m_shared.m_damages.m_damage *= globalDamageMultiplier.Value; weapon.m_shared.m_damages.m_blunt *= globalDamageMultiplier.Value; weapon.m_shared.m_damages.m_slash *= globalDamageMultiplier.Value; weapon.m_shared.m_damages.m_pierce *= globalDamageMultiplier.Value; weapon.m_shared.m_damages.m_chop *= globalDamageMultiplier.Value; weapon.m_shared.m_damages.m_pickaxe *= globalDamageMultiplier.Value; weapon.m_shared.m_damages.m_fire *= globalDamageMultiplier.Value; weapon.m_shared.m_damages.m_frost *= globalDamageMultiplier.Value; weapon.m_shared.m_damages.m_lightning *= globalDamageMultiplier.Value; weapon.m_shared.m_damages.m_poison *= globalDamageMultiplier.Value; weapon.m_shared.m_damages.m_spirit *= globalDamageMultiplier.Value; Dbgl($"post damage {weapon.m_shared.m_damages.m_slash}"); } } private static void Postfix(ref ItemData weapon, WeaponState __state) { if (modEnabled.Value) { weapon.m_shared.m_useDurabilityDrain = __state.useDurabilityDrain; weapon.m_shared.m_attackForce = __state.attackForce; weapon.m_shared.m_backstabBonus = __state.backstabBonus; weapon.m_shared.m_damages.m_damage = __state.damage; weapon.m_shared.m_damages.m_blunt = __state.blunt; weapon.m_shared.m_damages.m_slash = __state.slash; weapon.m_shared.m_damages.m_pierce = __state.pierce; weapon.m_shared.m_damages.m_chop = __state.chop; weapon.m_shared.m_damages.m_pickaxe = __state.pickaxe; weapon.m_shared.m_damages.m_fire = __state.fire; weapon.m_shared.m_damages.m_frost = __state.frost; weapon.m_shared.m_damages.m_lightning = __state.lightning; weapon.m_shared.m_damages.m_poison = __state.poison; weapon.m_shared.m_damages.m_spirit = __state.spirit; } } } [HarmonyPatch(typeof(Terminal), "InputText")] private static class InputText_Patch { private static bool Prefix(Terminal __instance) { //IL_02d9: Unknown result type (might be due to invalid IL or missing references) //IL_02de: Unknown result type (might be due to invalid IL or missing references) //IL_02ed: Unknown result type (might be due to invalid IL or missing references) //IL_02fe: Unknown result type (might be due to invalid IL or missing references) //IL_0302: Expected I4, but got Unknown if (!modEnabled.Value) { return true; } string text = ((TMP_InputField)__instance.m_input).text; if (text.ToLower().Equals(typeof(BepInExPlugin).Namespace.ToLower() + " reset")) { ((BaseUnityPlugin)context).Config.Reload(); ((BaseUnityPlugin)context).Config.Save(); Traverse.Create((object)__instance).Method("AddString", new object[1] { text }).GetValue(); Traverse.Create((object)__instance).Method("AddString", new object[1] { ((BaseUnityPlugin)context).Info.Metadata.Name + " config reloaded" }).GetValue(); return false; } if (text.ToLower().Equals(typeof(BepInExPlugin).Namespace.ToLower() + " reload")) { weaponDatas = GetWeaponDataFromFiles(); LoadAllWeaponData(reload: true); Traverse.Create((object)__instance).Method("AddString", new object[1] { text }).GetValue(); Traverse.Create((object)__instance).Method("AddString", new object[1] { ((BaseUnityPlugin)context).Info.Metadata.Name + " reloaded weapon stats from files" }).GetValue(); return false; } if (text.ToLower().StartsWith(typeof(BepInExPlugin).Namespace.ToLower() + " dump ")) { string text2 = text.Split(new char[1] { ' ' })[^1]; WeaponData weaponDataByName = GetWeaponDataByName(text2); if (weaponDataByName == null) { return false; } Dbgl(JsonUtility.ToJson((object)weaponDataByName)); Traverse.Create((object)__instance).Method("AddString", new object[1] { text }).GetValue(); Traverse.Create((object)__instance).Method("AddString", new object[1] { ((BaseUnityPlugin)context).Info.Metadata.Name + " dumped " + text2 }).GetValue(); return false; } if (text.ToLower().Equals(typeof(BepInExPlugin).Namespace.ToLower() + " skills")) { Traverse.Create((object)__instance).Method("AddString", new object[1] { text }).GetValue(); List<string> list = new List<string>(); foreach (SkillType value in Enum.GetValues(typeof(SkillType))) { list.Add(Enum.GetName(typeof(SkillType), (object)value) + " " + (int)value); } Dbgl(string.Join("\r\n", list)); Traverse.Create((object)__instance).Method("AddString", new object[1] { ((BaseUnityPlugin)context).Info.Metadata.Name + " dumped skill types" }).GetValue(); return false; } if (text.ToLower().Equals(typeof(BepInExPlugin).Namespace.ToLower() + " se")) { Traverse.Create((object)__instance).Method("AddString", new object[1] { text }).GetValue(); Dbgl(string.Join("\r\n", ObjectDB.instance.m_StatusEffects.Select((StatusEffect se) => ((Object)se).name))); Traverse.Create((object)__instance).Method("AddString", new object[1] { ((BaseUnityPlugin)context).Info.Metadata.Name + " dumped status effects" }).GetValue(); return false; } if (text.ToLower().StartsWith(typeof(BepInExPlugin).Namespace.ToLower() + " save ")) { string text3 = text.Split(new char[1] { ' ' })[^1]; WeaponData weaponDataByName2 = GetWeaponDataByName(text3); if (weaponDataByName2 == null) { return false; } CheckModFolder(); File.WriteAllText(Path.Combine(assetPath, weaponDataByName2.name + ".json"), JsonUtility.ToJson((object)weaponDataByName2)); Traverse.Create((object)__instance).Method("AddString", new object[1] { text }).GetValue(); Traverse.Create((object)__instance).Method("AddString", new object[1] { ((BaseUnityPlugin)context).Info.Metadata.Name + " saved weapon data to " + text3 + ".json" }).GetValue(); return false; } if (text.ToLower().StartsWith(typeof(BepInExPlugin).Namespace.ToLower() ?? "")) { string text4 = ((BaseUnityPlugin)context).Info.Metadata.Name + " reset\r\n" + ((BaseUnityPlugin)context).Info.Metadata.Name + " reload\r\n" + ((BaseUnityPlugin)context).Info.Metadata.Name + " dump <WeaponName>\r\n" + ((BaseUnityPlugin)context).Info.Metadata.Name + " save <WeaponName>\r\n" + ((BaseUnityPlugin)context).Info.Metadata.Name + " skills" + ((BaseUnityPlugin)context).Info.Metadata.Name + " se"; Traverse.Create((object)__instance).Method("AddString", new object[1] { text }).GetValue(); Traverse.Create((object)__instance).Method("AddString", new object[1] { text4 }).GetValue(); return false; } return true; } } private static BepInExPlugin context; public static ConfigEntry<bool> modEnabled; public static ConfigEntry<bool> isDebug; public static ConfigEntry<int> nexusID; public static ConfigEntry<float> globalDamageMultiplier; public static ConfigEntry<float> globalUseDurabilityMultiplier; public static ConfigEntry<float> globalAttackForceMultiplier; public static ConfigEntry<float> globalBackstabBonusMultiplier; public static ConfigEntry<float> globalHoldDurationMinMultiplier; public static ConfigEntry<float> globalHoldStaminaDrainMultiplier; public static ConfigEntry<float> globalAttackStaminaUseMultiplier; private static List<WeaponData> weaponDatas; private static string assetPath; public static void Dbgl(string str = "", bool pref = true) { if (isDebug.Value) { Debug.Log((object)((pref ? (typeof(BepInExPlugin).Namespace + " ") : "") + str)); } } private void Awake() { context = this; modEnabled = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "Enabled", true, "Enable this mod"); isDebug = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "IsDebug", true, "Enable debug logs"); nexusID = ((BaseUnityPlugin)this).Config.Bind<int>("General", "NexusID", 1151, "Nexus mod ID for updates"); globalDamageMultiplier = ((BaseUnityPlugin)this).Config.Bind<float>("Global", "GlobalDamageMultiplier", 1f, "Global damage multiplier for all weapons"); globalUseDurabilityMultiplier = ((BaseUnityPlugin)this).Config.Bind<float>("Global", "GlobalUseDurabilityMultiplier", 1f, "Global use durability multiplier for all weapons"); globalAttackForceMultiplier = ((BaseUnityPlugin)this).Config.Bind<float>("Global", "GlobalAttackForceMultiplier", 1f, "Global attack force multiplier for all weapons"); globalBackstabBonusMultiplier = ((BaseUnityPlugin)this).Config.Bind<float>("Global", "GlobalBackstabBonusMultiplier", 1f, "Global backstab bonus multiplier for all weapons"); globalHoldDurationMinMultiplier = ((BaseUnityPlugin)this).Config.Bind<float>("Global", "GlobalHoldDurationMinMultiplier", 1f, "Global hold duration minimum multiplier for all weapons"); globalHoldStaminaDrainMultiplier = ((BaseUnityPlugin)this).Config.Bind<float>("Global", "GlobalHoldStaminaDrainMultiplier", 1f, "Global hold stamina drain multiplier for all weapons"); globalAttackStaminaUseMultiplier = ((BaseUnityPlugin)this).Config.Bind<float>("Global", "GlobalAttackStaminaUseMultiplier", 1f, "Global attack stamina use multiplier for all weapons"); assetPath = Path.Combine(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location), "CustomWeaponStats"); Harmony.CreateAndPatchAll(Assembly.GetExecutingAssembly(), (string)null); } private static void LoadAllWeaponData(bool reload) { if (reload) { weaponDatas = GetWeaponDataFromFiles(); } foreach (WeaponData weaponData in weaponDatas) { GameObject itemPrefab = ObjectDB.instance.GetItemPrefab(weaponData.name); if ((Object)(object)itemPrefab == (Object)null) { continue; } ItemData val = itemPrefab.GetComponent<ItemDrop>()?.m_itemData; if (itemPrefab.GetComponent<ItemDrop>()?.m_itemData == null) { continue; } SetWeaponData(ref itemPrefab.GetComponent<ItemDrop>().m_itemData, weaponData); for (int i = 0; i < ObjectDB.instance.m_recipes.Count; i++) { Recipe val2 = ObjectDB.instance.m_recipes[i]; if (!((Object)(object)val2.m_item == (Object)null) && val2.m_item.m_itemData.m_shared.m_name == val.m_shared.m_name) { SetWeaponData(ref val2.m_item.m_itemData, weaponData); ObjectDB.instance.m_recipes[i] = val2; } } if (!Object.op_Implicit((Object)(object)Player.m_localPlayer)) { continue; } List<ItemData> allItems = ((Humanoid)Player.m_localPlayer).GetInventory().GetAllItems(); for (int j = 0; j < allItems.Count; j++) { ItemData item = allItems[j]; if (item.m_shared.m_name == val.m_shared.m_name) { SetWeaponData(ref item, weaponData); } allItems[j] = item; } } } private static void CheckWeaponData(ref ItemData instance) { try { string name = ((Object)instance.m_dropPrefab).name; WeaponData weapon = weaponDatas.First((WeaponData d) => d.name == name); SetWeaponData(ref instance, weapon); } catch { } } private static List<WeaponData> GetWeaponDataFromFiles() { CheckModFolder(); List<WeaponData> list = new List<WeaponData>(); string[] files = Directory.GetFiles(assetPath, "*.json"); foreach (string path in files) { WeaponData item = JsonUtility.FromJson<WeaponData>(File.ReadAllText(path)); list.Add(item); } return list; } private static void SetWeaponData(ref ItemData item, WeaponData weapon) { //IL_0051: Unknown result type (might be due to invalid IL or missing references) //IL_0056: Unknown result type (might be due to invalid IL or missing references) item.m_shared.m_ammoType = weapon.ammoType; item.m_shared.m_useDurability = weapon.useDurability; item.m_shared.m_useDurabilityDrain = weapon.useDurabilityDrain; item.m_shared.m_durabilityPerLevel = weapon.durabilityPerLevel; item.m_shared.m_skillType = weapon.skillType; item.m_shared.m_toolTier = weapon.toolTier; item.m_shared.m_blockable = weapon.blockable; item.m_shared.m_dodgeable = weapon.dodgeable; item.m_shared.m_attackForce = weapon.attackForce; item.m_shared.m_backstabBonus = weapon.backStabBonus; item.m_shared.m_blockPower = weapon.blockPower; item.m_shared.m_blockPowerPerLevel = weapon.blockPowerPerLevel; item.m_shared.m_deflectionForce = weapon.deflectionForce; item.m_shared.m_deflectionForcePerLevel = weapon.deflectionForcePerLevel; item.m_shared.m_damages.m_damage = weapon.damage; item.m_shared.m_damages.m_blunt = weapon.blunt; item.m_shared.m_damages.m_slash = weapon.slash; item.m_shared.m_damages.m_pierce = weapon.pierce; item.m_shared.m_damages.m_chop = weapon.chop; item.m_shared.m_damages.m_pickaxe = weapon.pickaxe; item.m_shared.m_damages.m_fire = weapon.fire; item.m_shared.m_damages.m_frost = weapon.frost; item.m_shared.m_damages.m_lightning = weapon.lightning; item.m_shared.m_damages.m_poison = weapon.poison; item.m_shared.m_damages.m_spirit = weapon.spirit; item.m_shared.m_damagesPerLevel.m_damage = weapon.damagePerLevel; item.m_shared.m_damagesPerLevel.m_blunt = weapon.bluntPerLevel; item.m_shared.m_damagesPerLevel.m_slash = weapon.slashPerLevel; item.m_shared.m_damagesPerLevel.m_pierce = weapon.piercePerLevel; item.m_shared.m_damagesPerLevel.m_chop = weapon.chopPerLevel; item.m_shared.m_damagesPerLevel.m_pickaxe = weapon.pickaxePerLevel; item.m_shared.m_damagesPerLevel.m_fire = weapon.firePerLevel; item.m_shared.m_damagesPerLevel.m_frost = weapon.frostPerLevel; item.m_shared.m_damagesPerLevel.m_lightning = weapon.lightningPerLevel; item.m_shared.m_damagesPerLevel.m_poison = weapon.poisonPerLevel; item.m_shared.m_damagesPerLevel.m_spirit = weapon.spiritPerLevel; item.m_shared.m_attack.m_hitTerrain = weapon.hitTerrain; if (item.m_shared.m_secondaryAttack != null) { item.m_shared.m_secondaryAttack.m_hitTerrain = weapon.hitTerrainSecondary; } item.m_shared.m_attackStatusEffect = ObjectDB.instance.GetStatusEffect((!string.IsNullOrEmpty(weapon.statusEffect)) ? StringExtensionMethods.GetStableHashCode(weapon.statusEffect) : 0); } private static WeaponData GetWeaponDataByName(string weapon) { GameObject itemPrefab = ObjectDB.instance.GetItemPrefab(weapon); if (!Object.op_Implicit((Object)(object)itemPrefab)) { Dbgl("Weapon not found!"); return null; } ItemData itemData = itemPrefab.GetComponent<ItemDrop>().m_itemData; return GetWeaponDataFromItem(itemData, weapon); } private static WeaponData GetWeaponDataFromItem(ItemData item, string itemName) { //IL_0058: Unknown result type (might be due to invalid IL or missing references) //IL_005d: Unknown result type (might be due to invalid IL or missing references) WeaponData obj = new WeaponData { name = itemName, ammoType = item.m_shared.m_ammoType, useDurability = item.m_shared.m_useDurability, durabilityPerLevel = item.m_shared.m_durabilityPerLevel, useDurabilityDrain = item.m_shared.m_useDurabilityDrain, skillType = item.m_shared.m_skillType, toolTier = item.m_shared.m_toolTier, blockable = item.m_shared.m_blockable, dodgeable = item.m_shared.m_dodgeable, attackForce = item.m_shared.m_attackForce, backStabBonus = item.m_shared.m_backstabBonus, blockPower = item.m_shared.m_blockPower, blockPowerPerLevel = item.m_shared.m_blockPowerPerLevel, deflectionForce = item.m_shared.m_deflectionForce, deflectionForcePerLevel = item.m_shared.m_deflectionForcePerLevel, damage = item.m_shared.m_damages.m_damage, blunt = item.m_shared.m_damages.m_blunt, slash = item.m_shared.m_damages.m_slash, pierce = item.m_shared.m_damages.m_pierce, chop = item.m_shared.m_damages.m_chop, pickaxe = item.m_shared.m_damages.m_pickaxe, fire = item.m_shared.m_damages.m_fire, frost = item.m_shared.m_damages.m_frost, lightning = item.m_shared.m_damages.m_lightning, poison = item.m_shared.m_damages.m_poison, spirit = item.m_shared.m_damages.m_spirit, damagePerLevel = item.m_shared.m_damagesPerLevel.m_damage, bluntPerLevel = item.m_shared.m_damagesPerLevel.m_blunt, slashPerLevel = item.m_shared.m_damagesPerLevel.m_slash, piercePerLevel = item.m_shared.m_damagesPerLevel.m_pierce, chopPerLevel = item.m_shared.m_damagesPerLevel.m_chop, pickaxePerLevel = item.m_shared.m_damagesPerLevel.m_pickaxe, firePerLevel = item.m_shared.m_damagesPerLevel.m_fire, frostPerLevel = item.m_shared.m_damagesPerLevel.m_frost, lightningPerLevel = item.m_shared.m_damagesPerLevel.m_lightning, poisonPerLevel = item.m_shared.m_damagesPerLevel.m_poison, spiritPerLevel = item.m_shared.m_damagesPerLevel.m_spirit }; StatusEffect attackStatusEffect = item.m_shared.m_attackStatusEffect; obj.statusEffect = ((attackStatusEffect != null) ? ((Object)attackStatusEffect).name : null); obj.hitTerrain = item.m_shared.m_attack?.m_hitTerrain ?? false; obj.hitTerrainSecondary = item.m_shared.m_secondaryAttack?.m_hitTerrain ?? false; return obj; } private static void CheckModFolder() { if (!Directory.Exists(assetPath)) { Dbgl("Creating mod folder"); Directory.CreateDirectory(assetPath); } } } internal class WeaponData { public string name; public bool useDurability; public bool blockable; public bool dodgeable; public SkillType skillType; public float useDurabilityDrain; public float durabilityPerLevel; public float holdDurationMin; public float holdStaminaDrain; public int toolTier; public string ammoType; public string statusEffect; public float backStabBonus; public float blockPower; public float deflectionForce; public float attackForce; public float blunt; public float damage; public float pierce; public float slash; public float chop; public float pickaxe; public float fire; public float frost; public float lightning; public float poison; public float spirit; public float blockPowerPerLevel; public float deflectionForcePerLevel; public float bluntPerLevel; public float damagePerLevel; public float piercePerLevel; public float slashPerLevel; public float chopPerLevel; public float pickaxePerLevel; public float firePerLevel; public float frostPerLevel; public float lightningPerLevel; public float poisonPerLevel; public float spiritPerLevel; public bool hitTerrain; public bool hitTerrainSecondary; } public class WeaponState : SharedData { public float useDurabilityDrain; public float holdDurationMin; public float holdStaminaDrain; public float attackForce; public float backstabBonus; public float damage; public float blunt; public float slash; public float pierce; public float chop; public float pickaxe; public float fire; public float frost; public float lightning; public float poison; public float spirit; public bool hitTerrain; public bool hitTerrainSecondary; public WeaponState(ItemData weapon) { useDurabilityDrain = weapon.m_shared.m_useDurabilityDrain; attackForce = weapon.m_shared.m_attackForce; backstabBonus = weapon.m_shared.m_backstabBonus; damage = weapon.m_shared.m_damages.m_damage; blunt = weapon.m_shared.m_damages.m_blunt; slash = weapon.m_shared.m_damages.m_slash; pierce = weapon.m_shared.m_damages.m_pierce; chop = weapon.m_shared.m_damages.m_chop; pickaxe = weapon.m_shared.m_damages.m_pickaxe; fire = weapon.m_shared.m_damages.m_fire; frost = weapon.m_shared.m_damages.m_frost; lightning = weapon.m_shared.m_damages.m_lightning; poison = weapon.m_shared.m_damages.m_poison; spirit = weapon.m_shared.m_damages.m_spirit; hitTerrain = weapon.m_shared.m_attack?.m_hitTerrain ?? false; hitTerrainSecondary = weapon.m_shared.m_secondaryAttack?.m_hitTerrain ?? false; } }