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 Bogus Valheim v1.0.17
plugins/BogusFreeBossSummons.dll
Decompiled 5 days agousing System; using System.Collections.Generic; using System.Diagnostics; 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: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: AssemblyVersion("0.0.0.0")] namespace BogusFreeBossSummons; [BepInDependency(/*Could not decode attribute arguments.*/)] [BepInPlugin("bogus.freebosssummons", "Bogus Free Boss Summons", "1.3.1")] public class Plugin : BaseUnityPlugin { [HarmonyPatch(typeof(OfferingBowl), "Interact")] private static class BowlInteract { private static bool Prefix(OfferingBowl __instance, Humanoid user, bool hold, ref bool __result) { if (!IsFree(__instance)) { return true; } __result = false; if (hold) { return false; } if ((bool)miQueued.Invoke(__instance, null)) { return false; } fiUser.SetValue(__instance, user); object obj = miSpawnPos.Invoke(__instance, null); miInitiate.Invoke(__instance, new object[2] { obj, false }); __result = true; return false; } } [HarmonyPatch(typeof(OfferingBowl), "GetHoverText")] private static class BowlHover { private static void Postfix(OfferingBowl __instance, ref string __result) { if (IsFree(__instance)) { int num = ((__result == null) ? (-1) : __result.IndexOf('\n')); string text = ((num > 0) ? __result.Substring(0, num) : (__result ?? "")); __result = text + "\n[<color=yellow><b>E</b></color>] Summon (free)"; } } } [HarmonyPatch(typeof(Tameable), "Awake")] private static class SummonAwake { private static void Postfix(Tameable __instance) { //IL_003f: Unknown result type (might be due to invalid IL or missing references) //IL_0049: Unknown result type (might be due to invalid IL or missing references) if (!SummonXP.Value || (!(__instance.m_unsummonDistance > 0f) && !(__instance.m_unsummonOnOwnerLogoutSeconds > 0f))) { return; } string text = Clean(((Object)((Component)__instance).gameObject).name); if ((int)__instance.m_levelUpOwnerSkill == 0) { __instance.m_levelUpOwnerSkill = (SkillType)10; __instance.m_levelUpFactor = SummonXPFactor.Value; if (summonLogged.Add(text)) { Log.LogInfo((object)("Summon " + text + " now gives its owner Blood Magic XP x" + SummonXPFactor.Value)); } } else if (summonLogged.Add(text)) { Log.LogInfo((object)("Summon " + text + " already gives owner XP in " + ((object)Unsafe.As<SkillType, SkillType>(ref __instance.m_levelUpOwnerSkill)/*cast due to .constrained prefix*/).ToString() + " x" + __instance.m_levelUpFactor)); } } } [HarmonyPatch(typeof(Door), "HaveKey")] private static class DoorKey { private static bool Prefix(Door __instance, ref bool __result) { if (Object.op_Implicit((Object)(object)__instance.m_keyItem) && InList(FreeDoorKeys.Value, Clean(((Object)__instance.m_keyItem).name))) { __result = true; return false; } return true; } } internal static ConfigEntry<string> FreeBosses; internal static ConfigEntry<string> FreeDoorKeys; internal static ConfigEntry<string> NoLootChestBosses; internal static ConfigEntry<bool> SummonXP; internal static ConfigEntry<float> SummonXPFactor; internal static ManualLogSource Log; private static Harmony _harmony; private static readonly HashSet<string> logged = new HashSet<string>(); private static readonly MethodInfo miQueued = AccessTools.Method(typeof(OfferingBowl), "IsBossSpawnQueued", (Type[])null, (Type[])null); private static readonly MethodInfo miSpawnPos = AccessTools.Method(typeof(OfferingBowl), "GetSpawnPosition", (Type[])null, (Type[])null); private static readonly MethodInfo miInitiate = AccessTools.Method(typeof(OfferingBowl), "InitiateSpawnBoss", (Type[])null, (Type[])null); private static readonly FieldInfo fiUser = AccessTools.Field(typeof(OfferingBowl), "m_interactUser"); private static readonly HashSet<string> summonLogged = new HashSet<string>(); private void Awake() { //IL_00c0: Unknown result type (might be due to invalid IL or missing references) //IL_00c5: Unknown result type (might be due to invalid IL or missing references) //IL_00d0: Expected O, but got Unknown //IL_00e1: Unknown result type (might be due to invalid IL or missing references) //IL_00f5: Expected O, but got Unknown //IL_00f0: Unknown result type (might be due to invalid IL or missing references) Log = ((BaseUnityPlugin)this).Logger; FreeBosses = ((BaseUnityPlugin)this).Config.Bind<string>("General", "FreeBosses", "Eikthyr,gd_king,Bonemass,Dragon,GoblinKing,SeekerQueen,Fader", "Boss prefab names whose altar summons for free (no offering). Bosses not listed keep their vanilla cost."); FreeDoorKeys = ((BaseUnityPlugin)this).Config.Bind<string>("General", "FreeDoorKeys", "DvergrKey", "Key item prefab names that are no longer needed to open their door (DvergrKey = Sealbreaker, the Queen's sealed tower)."); NoLootChestBosses = ((BaseUnityPlugin)this).Config.Bind<string>("General", "NoLootChestBosses", "SeekerQueen", "Boss prefab names whose loot drops normally instead of going into a BossLootChests chest (the Queen's sky arena makes the chest fall to the ground below)."); SummonXP = ((BaseUnityPlugin)this).Config.Bind<bool>("SummonXP", "Enabled", true, "Summoned creatures (Spirit Caller, Dead Raiser, Trollstav...) give the player they follow Blood Magic XP every time they hit something."); SummonXPFactor = ((BaseUnityPlugin)this).Config.Bind<float>("SummonXP", "XPFactor", 1f, "Blood Magic XP per summon hit, relative to the XP a player weapon hit gives. 1 = same as your own hit, 0.5 = half."); Harmony val = new Harmony("bogus.freebosssummons"); val.PatchAll(); _harmony = val; new ConsoleCommand("bogus_pullloot", "[radius] [pull] Lists containers with items nearby (any height). 'pull' drops boss loot chest contents at your feet.", new ConsoleEvent(PullLoot), false, false, false, false, false, false, (ConsoleOptionsFetcher)null, false, false, false); Log.LogInfo((object)("Bogus Free Boss Summons loaded. Free bosses: " + FreeBosses.Value + " | Free door keys: " + FreeDoorKeys.Value)); } private void Start() { //IL_0047: Unknown result type (might be due to invalid IL or missing references) //IL_0054: Expected O, but got Unknown Harmony harmony = _harmony; try { Type type = AccessTools.TypeByName("Cjayride.BossLootChests.BountyTargets"); MethodInfo methodInfo = ((type == null) ? null : AccessTools.Method(type, "SkipChestCapture", (Type[])null, (Type[])null)); if (methodInfo != null) { harmony.Patch((MethodBase)methodInfo, (HarmonyMethod)null, new HarmonyMethod(typeof(Plugin), "SkipChestPostfix", (Type[])null), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null); Log.LogInfo((object)("BossLootChests hooked. No loot chest for: " + NoLootChestBosses.Value)); } else { Log.LogInfo((object)"BossLootChests not found; loot chest skip not active."); } } catch (Exception ex) { Log.LogWarning((object)("Could not hook BossLootChests: " + ex.Message)); } } private static void PullLoot(ConsoleEventArgs args) { //IL_0073: Unknown result type (might be due to invalid IL or missing references) //IL_0078: Unknown result type (might be due to invalid IL or missing references) //IL_009d: Unknown result type (might be due to invalid IL or missing references) //IL_00a2: Unknown result type (might be due to invalid IL or missing references) //IL_00a4: Unknown result type (might be due to invalid IL or missing references) //IL_00ab: Unknown result type (might be due to invalid IL or missing references) //IL_00b2: Unknown result type (might be due to invalid IL or missing references) //IL_00b9: Unknown result type (might be due to invalid IL or missing references) //IL_00c0: Unknown result type (might be due to invalid IL or missing references) //IL_00c5: Unknown result type (might be due to invalid IL or missing references) //IL_01a0: Unknown result type (might be due to invalid IL or missing references) //IL_01af: Unknown result type (might be due to invalid IL or missing references) //IL_0229: Unknown result type (might be due to invalid IL or missing references) //IL_022a: Unknown result type (might be due to invalid IL or missing references) //IL_022f: Unknown result type (might be due to invalid IL or missing references) //IL_023a: Unknown result type (might be due to invalid IL or missing references) //IL_023f: Unknown result type (might be due to invalid IL or missing references) //IL_0244: Unknown result type (might be due to invalid IL or missing references) Player localPlayer = Player.m_localPlayer; if (!Object.op_Implicit((Object)(object)localPlayer)) { args.Context.AddString("No player."); return; } bool flag = false; float num = 300f; for (int i = 1; i < args.Length; i++) { float result; if (args[i].ToLower() == "pull") { flag = true; } else if (float.TryParse(args[i], out result)) { num = result; } } Vector3 position = ((Component)localPlayer).transform.position; int num2 = 0; int num3 = 0; Container[] array = Object.FindObjectsByType<Container>((FindObjectsSortMode)0); foreach (Container val in array) { Vector3 position2 = ((Component)val).transform.position; Vector2 val2 = new Vector2(position2.x - position.x, position2.z - position.z); float magnitude = ((Vector2)(ref val2)).magnitude; if (magnitude > num) { continue; } ZNetView component = ((Component)val).GetComponent<ZNetView>(); if (!Object.op_Implicit((Object)(object)component) || !component.IsValid()) { continue; } Inventory inventory = val.GetInventory(); if (inventory == null) { continue; } List<ItemData> list = new List<ItemData>(inventory.GetAllItems()); Piece component2 = ((Component)val).GetComponent<Piece>(); long num4 = (Object.op_Implicit((Object)(object)component2) ? component2.GetCreator() : 0); bool flag2 = ((Object)val).name.StartsWith("piece_chest_blackmetal") && num4 == 0; if (list.Count == 0 && !flag2) { continue; } num2++; args.Context.AddString(string.Format("#{0} {1}: {2:0} m away sideways, height {3:0} (you {4:0}), {5} stacks{6}", num2, Clean(((Object)val).name), magnitude, position2.y, position.y, list.Count, flag2 ? " <- boss loot chest" : ((num4 != 0L) ? " (player-built)" : ""))); if (!flag || !flag2 || list.Count == 0) { continue; } component.ClaimOwnership(); foreach (ItemData item in list) { ItemDrop.DropItem(item, item.m_stack, position + Vector3.up + ((Component)localPlayer).transform.forward, Quaternion.identity); inventory.RemoveItem(item); num3++; } } if (num2 == 0) { args.Context.AddString("No containers with items within " + num + " m."); } else if (flag) { args.Context.AddString("Dropped " + num3 + " stacks from boss loot chests at your feet."); } else { args.Context.AddString("Run 'bogus_pullloot pull' (optionally with a radius, e.g. 'bogus_pullloot 500 pull') to drop boss loot chest contents at your feet."); } } private static void SkipChestPostfix(Character character, ref bool __result) { if (!__result && Object.op_Implicit((Object)(object)character) && InList(NoLootChestBosses.Value, Clean(((Object)((Component)character).gameObject).name))) { __result = true; } } internal static bool InList(string csv, string name) { if (string.IsNullOrEmpty(name)) { return false; } string[] array = csv.Split(','); for (int i = 0; i < array.Length; i++) { if (string.Equals(array[i].Trim(), name, StringComparison.OrdinalIgnoreCase)) { return true; } } return false; } internal static string Clean(string n) { if (n != null) { return n.Replace("(Clone)", "").Trim(); } return ""; } internal static bool IsFree(OfferingBowl bowl) { string text = (Object.op_Implicit((Object)(object)bowl.m_bossPrefab) ? Clean(((Object)bowl.m_bossPrefab).name) : ""); string text2 = (Object.op_Implicit((Object)(object)bowl.m_bossItem) ? Clean(((Object)bowl.m_bossItem).name) : ""); string item = text + "|" + text2; bool result = text != "" && InList(FreeBosses.Value, text); if (logged.Add(item)) { Log.LogInfo((object)("Altar boss=" + text + " offering=" + text2 + "x" + bowl.m_bossItems + " itemStands=" + bowl.m_useItemStands + " free=" + result)); } return result; } }