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 SingleBerserkir v0.1.1
BepInEx/plugins/SingleBerserkir/SingleBerserkir.dll
Decompiled a week agousing System; using System.Collections; using System.Collections.Generic; using System.Linq; using System.Reflection; using System.Runtime.CompilerServices; using BepInEx; using BepInEx.Configuration; using BepInEx.Logging; using HarmonyLib; using UnityEngine; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: AssemblyMetadata("AI_Assisted_Creation", "Coded with the assistance of ChatGPT 6.0; packaged with OpenAI Codex.")] [assembly: AssemblyMetadata("AI_Model_Vendor", "OpenAI")] [assembly: AssemblyVersion("0.0.0.0")] namespace SingleBerserkir; [BepInPlugin("au.tyvalheim.singleberserkir", "Single Berserkir", "0.1.1")] public sealed class Plugin : BaseUnityPlugin { [HarmonyPatch(typeof(ObjectDB), "Awake")] private static class DB { private static void Prefix(ObjectDB __instance) { Instance.Register(__instance); } private static void Postfix() { Instance.Network(ZNetScene.instance); } } [HarmonyPatch(typeof(ObjectDB), "CopyOtherDB")] private static class CopyDB { private static void Postfix(ObjectDB __instance) { Instance.Register(__instance); AccessTools.Method(typeof(ObjectDB), "UpdateRegisters", (Type[])null, (Type[])null).Invoke(__instance, null); Instance.Network(ZNetScene.instance); } } [HarmonyPatch(typeof(ZNetScene), "Awake")] private static class Scene { private static void Prefix(ZNetScene __instance) { Instance.Register(ObjectDB.instance); if (Instance.failed) { return; } foreach (GameObject value in Instance.prefabs.Values) { if (!__instance.m_prefabs.Contains(value)) { __instance.m_prefabs.Add(value); } } } private static void Postfix(ZNetScene __instance) { Instance.Network(__instance); } } [HarmonyPatch(typeof(Attack), "Start")] private static class StartAttack { private static void Postfix(bool __result, ItemData ___m_weapon, ZSyncAnimation ___m_zanim) { if (__result && IsSingle(___m_weapon) && Object.op_Implicit((Object)(object)___m_zanim)) { ___m_zanim.SetSpeed(Instance.SwingSpeed.Value); } } } [HarmonyPatch(typeof(CharacterAnimEvent), "Speed")] private static class AnimationSpeed { private static void Prefix(ref float __0, Character ___m_character) { Humanoid val = (Humanoid)(object)((___m_character is Humanoid) ? ___m_character : null); if (Object.op_Implicit((Object)(object)val) && ((Character)val).InAttack() && IsSingle(val.GetCurrentWeapon())) { __0 *= Instance.SwingSpeed.Value; } } } public const string Id = "au.tyvalheim.singleberserkir"; public const string Version = "0.1.1"; public const string PrefabName = "SB_AxeBerserkir"; internal static Plugin Instance; internal static readonly MethodInfo CloneObject = AccessTools.Method(typeof(object), "MemberwiseClone", (Type[])null, (Type[])null); internal ConfigEntry<float> SwingSpeed; internal static readonly string[] Sources = new string[4] { "AxeBerzerkr", "AxeBerzerkrBlood", "AxeBerzerkrNature", "AxeBerzerkrLightning" }; internal static readonly string[] Names = new string[4] { "SB_AxeBerserkir", "SB_AxeBerserkirBlood", "SB_AxeBerserkirNature", "SB_AxeBerserkirLightning" }; internal static readonly string[] Titles = new string[4] { "Berserkir axe", "Bleeding Berserkir axe", "Primal Berserkir axe", "Thundering Berserkir axe" }; private GameObject root; private readonly Dictionary<string, GameObject> prefabs = new Dictionary<string, GameObject>(); private readonly Dictionary<string, Recipe> recipes = new Dictionary<string, Recipe>(); private bool failed; private void Awake() { //IL_0036: Unknown result type (might be due to invalid IL or missing references) //IL_0040: Expected O, but got Unknown //IL_004b: Unknown result type (might be due to invalid IL or missing references) //IL_0055: Expected O, but got Unknown //IL_0071: Unknown result type (might be due to invalid IL or missing references) Instance = this; SwingSpeed = ((BaseUnityPlugin)this).Config.Bind<float>("Combat", "AttackSpeed", 1.25f, new ConfigDescription("One-handed axe animation speed multiplier. 1 = normal; 1.25 = 25% faster. Use matching settings on all peers.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(1f, 2f), new object[0])); root = new GameObject("SingleBerserkir_Prefabs"); root.SetActive(false); Object.DontDestroyOnLoad((Object)(object)root); new Harmony("au.tyvalheim.singleberserkir").PatchAll(); ((BaseUnityPlugin)this).Logger.LogInfo((object)"Single Berserkir 0.1.1 loaded."); } internal static T Copy<T>(T value) where T : class { return (T)CloneObject.Invoke(value, null); } internal static GameObject CreateItem(GameObject source, GameObject axe, Transform parent) { //IL_00b6: Unknown result type (might be due to invalid IL or missing references) //IL_00bb: Unknown result type (might be due to invalid IL or missing references) //IL_00c3: Unknown result type (might be due to invalid IL or missing references) //IL_00c8: Unknown result type (might be due to invalid IL or missing references) //IL_00d0: Unknown result type (might be due to invalid IL or missing references) //IL_00d5: Unknown result type (might be due to invalid IL or missing references) GameObject val = Object.Instantiate<GameObject>(source, parent, false); try { int num = Array.IndexOf(Sources, ((Object)source).name); if (num < 0) { throw new InvalidOperationException("Unknown Berserkir variant."); } ((Object)val).name = Names[num]; ItemDrop component = val.GetComponent<ItemDrop>(); component.m_itemData = source.GetComponent<ItemDrop>().m_itemData.Clone(); SharedData val2 = (component.m_itemData.m_shared = Copy<SharedData>(component.m_itemData.m_shared)); SharedData shared = axe.GetComponent<ItemDrop>().m_itemData.m_shared; val2.m_name = Titles[num]; val2.m_description = component.m_itemData.m_shared.m_description + "\nForged for a single hand. Leaves your other hand free for a shield."; val2.m_itemType = shared.m_itemType; val2.m_animationState = shared.m_animationState; val2.m_attachOverride = shared.m_attachOverride; val2.m_attack = Copy<Attack>(val2.m_attack); val2.m_secondaryAttack = Copy<Attack>(val2.m_secondaryAttack); AdaptAnimation(val2.m_attack, shared.m_attack); AdaptAnimation(val2.m_secondaryAttack, shared.m_secondaryAttack); component.m_itemData.m_dropPrefab = val; BuildVisual(val, axe); val.SetActive(true); return val; } catch { Object.DestroyImmediate((Object)(object)val); throw; } } private static void AdaptAnimation(Attack target, Attack template) { //IL_0026: Unknown result type (might be due to invalid IL or missing references) //IL_002b: Unknown result type (might be due to invalid IL or missing references) target.m_attackAnimation = template.m_attackAnimation; target.m_attackChainLevels = template.m_attackChainLevels; target.m_attackRandomAnimations = template.m_attackRandomAnimations; target.m_attackType = template.m_attackType; } private static void BuildVisual(GameObject item, GameObject axe) { //IL_007f: Unknown result type (might be due to invalid IL or missing references) //IL_00c3: Unknown result type (might be due to invalid IL or missing references) //IL_00c8: Unknown result type (might be due to invalid IL or missing references) //IL_00da: Unknown result type (might be due to invalid IL or missing references) //IL_00df: Unknown result type (might be due to invalid IL or missing references) //IL_00ea: 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_0106: Unknown result type (might be due to invalid IL or missing references) //IL_0124: Unknown result type (might be due to invalid IL or missing references) //IL_012b: Expected O, but got Unknown //IL_0141: Unknown result type (might be due to invalid IL or missing references) //IL_0146: Unknown result type (might be due to invalid IL or missing references) //IL_014b: Unknown result type (might be due to invalid IL or missing references) //IL_0153: Unknown result type (might be due to invalid IL or missing references) //IL_0158: Unknown result type (might be due to invalid IL or missing references) //IL_015f: Unknown result type (might be due to invalid IL or missing references) //IL_0164: Unknown result type (might be due to invalid IL or missing references) //IL_0169: Unknown result type (might be due to invalid IL or missing references) //IL_0188: Unknown result type (might be due to invalid IL or missing references) //IL_0196: Unknown result type (might be due to invalid IL or missing references) Transform val = item.transform.Find("attach"); MeshFilter val2 = (Object.op_Implicit((Object)(object)val) ? ((Component)val).GetComponentsInChildren<MeshFilter>(true).FirstOrDefault() : null); Transform val3 = axe.transform.Find("attach"); MeshFilter val4 = (Object.op_Implicit((Object)(object)val3) ? ((Component)val3).GetComponentsInChildren<MeshFilter>(true).FirstOrDefault() : null); if (!Object.op_Implicit((Object)(object)val2) || !Object.op_Implicit((Object)(object)val4) || !Object.op_Implicit((Object)(object)val2.sharedMesh)) { throw new InvalidOperationException("Native axe visual layout changed."); } Transform transform = new GameObject("single_attach").transform; transform.SetParent(item.transform, false); GameObject val5 = Object.Instantiate<GameObject>(((Component)val2).gameObject, transform, false); ((Object)val5).name = "BerserkirModel"; val5.transform.localPosition = val3.InverseTransformPoint(((Component)val4).transform.position); val5.transform.localRotation = Quaternion.Inverse(val3.rotation) * ((Component)val4).transform.rotation; val5.transform.localScale = ((Component)val4).transform.localScale; foreach (Transform item2 in val) { Transform val6 = item2; if (!Object.op_Implicit((Object)(object)((Component)val6).GetComponent<MeshFilter>())) { Vector3 localPosition = ((Component)val2).transform.InverseTransformPoint(val6.position); Quaternion localRotation = Quaternion.Inverse(((Component)val2).transform.rotation) * val6.rotation; GameObject val7 = Object.Instantiate<GameObject>(((Component)val6).gameObject, val5.transform, false); val7.transform.localPosition = localPosition; val7.transform.localRotation = localRotation; } } Transform val8 = ((IEnumerable<Transform>)((Component)val3).GetComponentsInChildren<Transform>(true)).FirstOrDefault((Func<Transform, bool>)((Transform t) => ((Object)t).name == "equiped")); if (Object.op_Implicit((Object)(object)val8)) { ((Object)Object.Instantiate<GameObject>(((Component)val8).gameObject, transform, false)).name = "equiped"; } Transform[] array = ((IEnumerable)item.transform).Cast<Transform>().ToArray(); foreach (Transform val9 in array) { if ((Object)(object)val9 != (Object)(object)transform && (((Object)val9).name == "attach" || ((Object)val9).name == "attach_skin" || ((Object)val9).name == "attach_back")) { Object.DestroyImmediate((Object)(object)((Component)val9).gameObject); } } ((Object)transform).name = "attach"; } internal static Recipe CreateRecipe(Recipe source, GameObject item) { Recipe val = Object.Instantiate<Recipe>(source); ((Object)val).name = "Recipe_" + ((Object)item).name; val.m_item = item.GetComponent<ItemDrop>(); val.m_resources = source.m_resources.Select(Copy<Requirement>).ToArray(); return val; } internal void Register(ObjectDB db) { if (failed || !Object.op_Implicit((Object)(object)db)) { return; } try { GameObject val = ((IEnumerable<GameObject>)db.m_items).FirstOrDefault((Func<GameObject, bool>)((GameObject x) => Object.op_Implicit((Object)(object)x) && ((Object)x).name == "AxeBlackMetal")); if (!Object.op_Implicit((Object)(object)val)) { return; } int i; for (i = 0; i < Sources.Length; i++) { GameObject val2 = ((IEnumerable<GameObject>)db.m_items).FirstOrDefault((Func<GameObject, bool>)((GameObject x) => Object.op_Implicit((Object)(object)x) && ((Object)x).name == Sources[i])); if (Object.op_Implicit((Object)(object)val2) && !prefabs.ContainsKey(Sources[i])) { if (db.m_items.Any((GameObject x) => Object.op_Implicit((Object)(object)x) && ((Object)x).name == Names[i])) { throw new InvalidOperationException("Duplicate Single Berserkir prefab name."); } prefabs.Add(Sources[i], CreateItem(val2, val, root.transform)); } } foreach (KeyValuePair<string, GameObject> pair in prefabs) { List<GameObject> items = db.m_items; KeyValuePair<string, GameObject> keyValuePair = pair; if (!items.Contains(keyValuePair.Value)) { List<GameObject> items2 = db.m_items; KeyValuePair<string, GameObject> keyValuePair2 = pair; items2.Add(keyValuePair2.Value); } Recipe val3 = ((IEnumerable<Recipe>)db.m_recipes).FirstOrDefault((Func<Recipe, bool>)delegate(Recipe x) { if (Object.op_Implicit((Object)(object)x) && Object.op_Implicit((Object)(object)x.m_item)) { string name = ((Object)x.m_item).name; KeyValuePair<string, GameObject> keyValuePair7 = pair; return name == keyValuePair7.Key; } return false; }); if (!Object.op_Implicit((Object)(object)val3) || !prefabs.ContainsKey(Sources[0])) { continue; } Dictionary<string, Recipe> dictionary = recipes; KeyValuePair<string, GameObject> keyValuePair3 = pair; if (!dictionary.TryGetValue(keyValuePair3.Key, out var value)) { KeyValuePair<string, GameObject> keyValuePair4 = pair; value = CreateRecipe(val3, keyValuePair4.Value); Requirement[] resources = value.m_resources; foreach (Requirement val4 in resources) { if (Object.op_Implicit((Object)(object)val4.m_resItem) && prefabs.TryGetValue(((Object)val4.m_resItem).name, out var value2)) { val4.m_resItem = value2.GetComponent<ItemDrop>(); } } Dictionary<string, Recipe> dictionary2 = recipes; KeyValuePair<string, GameObject> keyValuePair5 = pair; dictionary2.Add(keyValuePair5.Key, value); ManualLogSource logger = ((BaseUnityPlugin)this).Logger; object[] array = new object[6] { "Registered ", null, null, null, null, null }; KeyValuePair<string, GameObject> keyValuePair6 = pair; array[1] = ((Object)keyValuePair6.Value).name; array[2] = " with native recipe at "; array[3] = ((Object)val3.m_craftingStation).name; array[4] = ", level "; array[5] = val3.m_minStationLevel; logger.LogInfo((object)string.Concat(array)); } if (!db.m_recipes.Contains(value)) { db.m_recipes.Add(value); } } } catch (Exception ex) { failed = true; ((BaseUnityPlugin)this).Logger.LogError((object)("Single Berserkir registration failed: " + ex)); } } internal void Network(ZNetScene scene) { if (!Object.op_Implicit((Object)(object)scene) || failed) { return; } Dictionary<int, GameObject> dictionary = (Dictionary<int, GameObject>)AccessTools.Field(typeof(ZNetScene), "m_namedPrefabs").GetValue(scene); foreach (GameObject value2 in prefabs.Values) { int stableHashCode = StringExtensionMethods.GetStableHashCode(((Object)value2).name); if (dictionary.TryGetValue(stableHashCode, out var value) && (Object)(object)value != (Object)(object)value2) { throw new InvalidOperationException("Single Berserkir prefab hash collision."); } if (!scene.m_prefabs.Contains(value2)) { scene.m_prefabs.Add(value2); } dictionary[stableHashCode] = value2; } } internal static bool IsSingle(ItemData item) { if (item != null && Object.op_Implicit((Object)(object)item.m_dropPrefab)) { return Array.IndexOf(Names, ((Object)item.m_dropPrefab).name) >= 0; } return false; } } internal static class VanillaVisuals { [HarmonyPatch(typeof(VisEquipment), "SetRightItemVisual")] private static class PublishHand { private static void Postfix(int __0, ZNetView ___m_nview, bool ___m_isPlayer) { if (___m_isPlayer && Object.op_Implicit((Object)(object)___m_nview)) { Publish(___m_nview.GetZDO(), ___m_nview.IsOwner(), ZDOVars.s_rightItem, HandKey, __0); } } } [HarmonyPatch(typeof(VisEquipment), "SetRightBackItem")] private static class PublishBack { private static void Postfix(int __0, ZNetView ___m_nview, bool ___m_isPlayer) { if (___m_isPlayer && Object.op_Implicit((Object)(object)___m_nview)) { Publish(___m_nview.GetZDO(), ___m_nview.IsOwner(), ZDOVars.s_rightBackItem, BackKey, __0); } } } [HarmonyPatch(typeof(VisEquipment), "SetRightHandEquipped")] private static class ResolveHand { private static void Prefix(ref int __0, ZNetView ___m_nview, bool ___m_isPlayer) { if (___m_isPlayer && Object.op_Implicit((Object)(object)___m_nview)) { __0 = Resolve(___m_nview.GetZDO(), HandKey, __0); } } } [HarmonyPatch(typeof(VisEquipment), "SetBackEquipped")] private static class ResolveBack { private static void Prefix(ref int __1, ZNetView ___m_nview, bool ___m_isPlayer) { if (___m_isPlayer && Object.op_Implicit((Object)(object)___m_nview)) { __1 = Resolve(___m_nview.GetZDO(), BackKey, __1); } } } internal static readonly int Fallback = StringExtensionMethods.GetStableHashCode("AxeBlackMetal"); internal static readonly int HandKey = StringExtensionMethods.GetStableHashCode("au.tyvalheim.singleberserkir.rightHand"); internal static readonly int BackKey = StringExtensionMethods.GetStableHashCode("au.tyvalheim.singleberserkir.rightBack"); private static readonly int[] Custom = Array.ConvertAll(Plugin.Names, (string n) => StringExtensionMethods.GetStableHashCode(n)); internal static bool IsCustom(int hash) { return Array.IndexOf(Custom, hash) >= 0; } internal static void Publish(ZDO data, bool owner, int slot, int marker, int actual) { if (data != null && owner) { bool flag = IsCustom(actual); data.Set(marker, flag ? actual : 0, false); data.Set(slot, flag ? Fallback : actual, false); } } internal static int Resolve(ZDO data, int marker, int publicHash) { if (data == null || publicHash != Fallback) { return publicHash; } int num = data.GetInt(marker, 0); if (!IsCustom(num) || !Object.op_Implicit((Object)(object)ObjectDB.instance) || !Object.op_Implicit((Object)(object)ObjectDB.instance.GetItemPrefab(num))) { return publicHash; } return num; } }