Please disclose if your mod was created primarily 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 Custom Weapon Stats v0.7.0
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; } }