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 LoreAccurateLightningStrike v1.0.0
LoreAccurateLightningStrike.dll
Decompiled 2 months agousing System; using System.Collections; using System.Diagnostics; using System.Reflection; using System.Runtime.CompilerServices; using BepInEx; using BepInEx.Configuration; using HarmonyLib; using Microsoft.CodeAnalysis; using UnityEngine; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: AssemblyVersion("0.0.0.0")] [module: RefSafetyRules(11)] namespace Microsoft.CodeAnalysis { [CompilerGenerated] [Embedded] internal sealed class EmbeddedAttribute : Attribute { } } namespace System.Runtime.CompilerServices { [CompilerGenerated] [Embedded] [AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)] internal sealed class RefSafetyRulesAttribute : Attribute { public readonly int Version; public RefSafetyRulesAttribute(int P_0) { Version = P_0; } } } namespace LoreAccurateLightningStrike { [BepInPlugin("rook.valheim.loreaccuratelightningstrike", "Lore Accurate Lightning Strike", "1.0.0")] public sealed class LightningStrikePlugin : BaseUnityPlugin { [HarmonyPatch(typeof(Attack), "FireProjectileBurst")] private static class FireProjectileBurstPatch { private static void Prefix(Attack __instance) { if (_instance != null && _baselineReady && __instance != null && IsLightningStrikeAttack(__instance)) { ApplyProjectileTuning(__instance); if (!_loggedLiveAttack) { _loggedLiveAttack = true; ((BaseUnityPlugin)_instance).Logger.LogInfo((object)("Live Lightning Strike attack intercepted: velocity=" + __instance.m_projectileVelMin.ToString("0.##") + "-" + __instance.m_projectileVel.ToString("0.##") + ", accuracy=" + __instance.m_projectileAccuracy.ToString("0.##") + ".")); } } } } [HarmonyPatch(typeof(Projectile), "Setup")] private static class ProjectileSetupPatch { private static void Prefix(ref Vector3 velocity, ItemData item) { //IL_0047: Unknown result type (might be due to invalid IL or missing references) //IL_004d: Unknown result type (might be due to invalid IL or missing references) //IL_0052: Unknown result type (might be due to invalid IL or missing references) if (_instance != null && _baselineReady && IsLightningStrikeItem(item)) { float num = _baseMaxVelocity * Mathf.Max(0.01f, _instance._speedMultiplier.Value); if (((Vector3)(ref velocity)).sqrMagnitude > 0.0001f) { velocity = ((Vector3)(ref velocity)).normalized * num; } if (!_loggedProjectileSetup) { _loggedProjectileSetup = true; ((BaseUnityPlugin)_instance).Logger.LogInfo((object)("Lightning Strike Projectile.Setup intercepted: final speed=" + ((Vector3)(ref velocity)).magnitude.ToString("0.##") + ".")); } } } } public const string PluginGuid = "rook.valheim.loreaccuratelightningstrike"; public const string PluginName = "Lore Accurate Lightning Strike"; public const string PluginVersion = "1.0.0"; private static LightningStrikePlugin _instance; private static bool _baselineReady; private static float _baseMinVelocity; private static float _baseMaxVelocity; private static GameObject _lightningStrikeProjectile; private static bool _loggedLiveAttack; private static bool _loggedProjectileSetup; private ConfigEntry<string> _prefabName; private ConfigEntry<string> _itemName; private ConfigEntry<float> _speedMultiplier; private ConfigEntry<float> _scatterDegrees; private ConfigEntry<bool> _disableCircularScatter; private ConfigEntry<bool> _removeLaunchArc; private IEnumerator Start() { _instance = this; new Harmony("rook.valheim.loreaccuratelightningstrike").PatchAll(); _prefabName = ((BaseUnityPlugin)this).Config.Bind<string>("General", "PrefabName", "StaffThunderBlood", "Internal prefab name for Lightning Strike in Valheim 1.0."); if (string.Equals(_prefabName.Value, "StaffLightning", StringComparison.OrdinalIgnoreCase)) { _prefabName.Value = "StaffThunderBlood"; ((BaseUnityPlugin)this).Logger.LogWarning((object)"Migrated obsolete PrefabName StaffLightning to StaffThunderBlood."); } _itemName = ((BaseUnityPlugin)this).Config.Bind<string>("General", "ItemName", "Lightning Strike", "Displayed item name, raw localization key, or prefab name to patch."); _speedMultiplier = ((BaseUnityPlugin)this).Config.Bind<float>("Projectile", "SpeedMultiplier", 3f, "Multiplier applied to both minimum and maximum projectile velocity."); _scatterDegrees = ((BaseUnityPlugin)this).Config.Bind<float>("Projectile", "ScatterDegrees", 0f, "Projectile spread in degrees. Zero removes normal random scatter."); _disableCircularScatter = ((BaseUnityPlugin)this).Config.Bind<bool>("Projectile", "DisableCircularScatter", true, "Also disables circular distribution of multi-projectile attacks."); _removeLaunchArc = ((BaseUnityPlugin)this).Config.Bind<bool>("Projectile", "RemoveLaunchArc", true, "Removes Lightning Strike's built-in upward launch angle so faster bolts track the crosshair."); while ((Object)(object)ObjectDB.instance == (Object)null || ObjectDB.instance.m_items == null) { yield return null; } PatchItem(); } private void PatchItem() { string text = (_prefabName.Value ?? "StaffThunderBlood").Trim(); GameObject val = ObjectDB.instance.GetItemPrefab(text); string text2 = (_itemName.Value ?? "Lightning Strike").Trim(); if ((Object)(object)val != (Object)null) { ((BaseUnityPlugin)this).Logger.LogInfo((object)("Located Lightning Strike using prefab '" + text + "'.")); } foreach (GameObject item in ObjectDB.instance.m_items) { if ((Object)(object)val != (Object)null) { break; } if ((Object)(object)item == (Object)null) { continue; } ItemDrop component = item.GetComponent<ItemDrop>(); if (!((Object)(object)component == (Object)null) && component.m_itemData != null && component.m_itemData.m_shared != null) { string text3 = component.m_itemData.m_shared.m_name ?? string.Empty; if (Matches(((Object)item).name, text2) || Matches(text3, text2)) { val = item; ((BaseUnityPlugin)this).Logger.LogInfo((object)("Matched item: prefab='" + ((Object)item).name + "', key='" + text3 + "'.")); break; } } } if ((Object)(object)val == (Object)null) { ((BaseUnityPlugin)this).Logger.LogError((object)("Could not find prefab '" + text + "' or an ObjectDB item matching '" + text2 + "'.")); return; } Attack attack = val.GetComponent<ItemDrop>().m_itemData.m_shared.m_attack; if (attack == null) { ((BaseUnityPlugin)this).Logger.LogError((object)"Matched item has no primary attack data."); return; } _baseMinVelocity = attack.m_projectileVelMin; _baseMaxVelocity = attack.m_projectileVel; _lightningStrikeProjectile = attack.m_attackProjectile; _baselineReady = true; float baseMinVelocity = _baseMinVelocity; float baseMaxVelocity = _baseMaxVelocity; ApplyProjectileTuning(attack); ((BaseUnityPlugin)this).Logger.LogInfo((object)("Lightning Strike patched: velocity " + baseMinVelocity.ToString("0.##") + "-" + baseMaxVelocity.ToString("0.##") + " -> " + attack.m_projectileVelMin.ToString("0.##") + "-" + attack.m_projectileVel.ToString("0.##") + "; scatter=" + Mathf.Max(0f, _scatterDegrees.Value).ToString("0.##") + " degrees. Runtime firing patch active.")); } private static void ApplyProjectileTuning(Attack attack) { if (_instance != null && _baselineReady && attack != null) { float num = Mathf.Max(0.01f, _instance._speedMultiplier.Value); float num2 = Mathf.Max(0f, _instance._scatterDegrees.Value); attack.m_projectileVelMin = _baseMinVelocity * num; attack.m_projectileVel = _baseMaxVelocity * num; attack.m_projectileAccuracyMin = num2; attack.m_projectileAccuracy = num2; attack.m_randomVelocity = false; if (_instance._removeLaunchArc.Value) { attack.m_launchAngle = 0f; } if (_instance._disableCircularScatter.Value) { attack.m_circularProjectileLaunch = false; attack.m_distributeProjectilesAroundCircle = false; } } } private static bool IsLightningStrikeAttack(Attack attack) { if (attack == null) { return false; } if ((Object)(object)_lightningStrikeProjectile != (Object)null && (Object)(object)attack.m_attackProjectile == (Object)(object)_lightningStrikeProjectile) { return true; } return IsLightningStrikeItem(attack.GetWeapon()); } private static bool IsLightningStrikeItem(ItemData item) { if (_instance == null || item == null) { return false; } string b = (_instance._prefabName.Value ?? "StaffThunderBlood").Trim(); if ((Object)(object)item.m_dropPrefab != (Object)null && string.Equals(((Object)item.m_dropPrefab).name, b, StringComparison.OrdinalIgnoreCase)) { return true; } string candidate = ((item.m_shared != null) ? item.m_shared.m_name : string.Empty); if (!Matches(candidate, "Lightning Strike") && !Matches(candidate, "StaffThunderBlood")) { return Matches(candidate, "staff_thunderblood"); } return true; } private static bool Matches(string candidate, string wanted) { if (string.IsNullOrEmpty(candidate) || string.IsNullOrEmpty(wanted)) { return false; } if (candidate.IndexOf(wanted, StringComparison.OrdinalIgnoreCase) < 0) { return candidate.Replace("$", string.Empty).Replace("_", string.Empty).IndexOf(wanted.Replace(" ", string.Empty), StringComparison.OrdinalIgnoreCase) >= 0; } return true; } } }