Please disclose if any significant portion of your mod was created using AI tools by adding the 'AI Generated' category. Failing to do so may result in the mod being removed from Thunderstore.
Decompiled source of MobaModpack v1.4.0
BepInEx/plugins/Absolute-MobaModpack/satt-CustomArmorStats/CustomArmorStats.dll
Decompiled 2 years 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 2 years 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 2 years 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 2 years 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; } }