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 Deathsquito Lightning Tower v0.3.7
BepInEx/plugins/LightningTower/LightningTower.dll
Decompiled 20 hours ago
The result has been truncated due to the large size, download it to view full contents!
using System; using System.Collections.Generic; using System.Diagnostics; using System.IO; using System.Linq; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using System.Text; using BepInEx; using BepInEx.Configuration; using BepInEx.Logging; using HarmonyLib; using Jotunn.Configs; using Jotunn.Entities; using Jotunn.Managers; using Jotunn.Utils; using Microsoft.CodeAnalysis; using UnityEngine; using UnityEngine.Audio; using UnityEngine.Rendering; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: TargetFramework(".NETFramework,Version=v4.8", FrameworkDisplayName = ".NET Framework 4.8")] [assembly: AssemblyCompany("LightningTower")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyDescription("A storm-powered lightning tower for Valheim.")] [assembly: AssemblyFileVersion("0.3.7.0")] [assembly: AssemblyInformationalVersion("0.3.7")] [assembly: AssemblyProduct("LightningTower")] [assembly: AssemblyTitle("LightningTower")] [assembly: AssemblyVersion("0.3.7.0")] [module: RefSafetyRules(11)] namespace Microsoft.CodeAnalysis { [CompilerGenerated] [Embedded] internal sealed class EmbeddedAttribute : Attribute { } } namespace System.Runtime.CompilerServices { [CompilerGenerated] [Embedded] [AttributeUsage(AttributeTargets.Class | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Parameter | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter, AllowMultiple = false, Inherited = false)] internal sealed class NullableAttribute : Attribute { public readonly byte[] NullableFlags; public NullableAttribute(byte P_0) { NullableFlags = new byte[1] { P_0 }; } public NullableAttribute(byte[] P_0) { NullableFlags = P_0; } } [CompilerGenerated] [Embedded] [AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Method | AttributeTargets.Interface | AttributeTargets.Delegate, AllowMultiple = false, Inherited = false)] internal sealed class NullableContextAttribute : Attribute { public readonly byte Flag; public NullableContextAttribute(byte P_0) { Flag = P_0; } } [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 LightningTower { public sealed class ChargedHum : MonoBehaviour { private readonly AudioSource[] voices = (AudioSource[])(object)new AudioSource[2]; private readonly double[] starts = new double[2] { -100.0, -100.0 }; private float sectionDuration; private float gain; private static AudioClip? humLoop; private AudioSource drone; private double nextVoice; private int voiceIndex; private bool charged; private const float Crossfade = 0.35f; private const float Pitch = 0.75f; internal bool Active { get { if (Object.op_Implicit((Object)(object)drone)) { if (!drone.isPlaying && !voices[0].isPlaying) { return voices[1].isPlaying; } return true; } return false; } } internal AudioSource[] Voices => voices; internal AudioSource Drone => drone; internal void Initialize(AudioClip clip, AudioMixerGroup mixer) { sectionDuration = clip.length / 0.75f; if (!Object.op_Implicit((Object)(object)humLoop)) { float[] array = HumSignal.CreateLoop(); humLoop = AudioClip.Create("LightningTower_ElectricalHum", array.Length, 1, 22050, false); if (!(bool)typeof(AudioClip).GetMethod("SetData", new Type[2] { typeof(float[]), typeof(int) }).Invoke(humLoop, new object[2] { array, 0 })) { throw new InvalidOperationException("Could not initialize the electrical hum audio."); } } drone = CreateSource("ElectricalHum", humLoop, mixer); drone.loop = true; for (int i = 0; i < voices.Length; i++) { voices[i] = CreateSource("ObliteratorCrackle_" + i, clip, mixer); AudioSource obj = voices[i]; obj.pitch = 0.75f; ((Component)obj).gameObject.AddComponent<AudioLowPassFilter>().cutoffFrequency = 2800f; } } private AudioSource CreateSource(string name, AudioClip clip, AudioMixerGroup mixer) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0006: Unknown result type (might be due to invalid IL or missing references) GameObject val = new GameObject(name); val.transform.SetParent(((Component)this).transform, false); AudioSource obj = val.AddComponent<AudioSource>(); obj.clip = clip; obj.outputAudioMixerGroup = mixer; obj.playOnAwake = false; obj.volume = 0f; obj.spatialBlend = 0f; obj.dopplerLevel = 0f; obj.reverbZoneMix = 0f; obj.bypassReverbZones = true; return obj; } internal void SetCharged(bool value) { charged = value; } internal static float DistanceGain(float distance, float range) { return HumSignal.DistanceGain(distance, range); } private void Update() { //IL_0028: Unknown result type (might be due to invalid IL or missing references) //IL_0033: 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_00c6: 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) //IL_00da: Unknown result type (might be due to invalid IL or missing references) //IL_00de: Unknown result type (might be due to invalid IL or missing references) if (!Object.op_Implicit((Object)(object)voices[0])) { return; } float num = DistanceGain(Object.op_Implicit((Object)(object)Player.m_localPlayer) ? Vector3.Distance(((Character)Player.m_localPlayer).GetCenterPoint(), ((Component)this).transform.position) : float.PositiveInfinity, Plugin.Settings.HumRange.Value); gain = Mathf.MoveTowards(gain, (float)(charged ? 1 : 0), Time.unscaledDeltaTime * 4f); if (num <= 0f || gain <= 0f) { StopVoices(); return; } Camera mainCamera = Utils.GetMainCamera(); float num2; if (!Object.op_Implicit((Object)(object)mainCamera) || !Object.op_Implicit((Object)(object)Player.m_localPlayer)) { num2 = 0f; } else { Vector3 right = ((Component)mainCamera).transform.right; Vector3 val = ((Component)this).transform.position - ((Character)Player.m_localPlayer).GetCenterPoint(); num2 = Mathf.Clamp(Vector3.Dot(right, ((Vector3)(ref val)).normalized), -0.75f, 0.75f); } float panStereo = num2; float num3 = gain * num * Plugin.Settings.HumVolume.Value; drone.volume = num3; drone.panStereo = panStereo; if (!drone.isPlaying) { drone.Play(); } double dspTime = AudioSettings.dspTime; if (dspTime >= nextVoice) { AudioSource obj = voices[voiceIndex]; obj.Stop(); obj.timeSamples = 0; starts[voiceIndex] = dspTime + 0.02; obj.PlayScheduled(starts[voiceIndex]); nextVoice = starts[voiceIndex] + (double)sectionDuration - 0.3499999940395355; voiceIndex = 1 - voiceIndex; } for (int i = 0; i < voices.Length; i++) { float num4 = (float)(dspTime - starts[i]); float num5 = Mathf.Clamp01(num4 / 0.35f) * Mathf.Clamp01((sectionDuration - num4) / 0.35f); voices[i].volume = Mathf.Sqrt(num5) * num3 * 0.35f; voices[i].panStereo = panStereo; if (num4 >= sectionDuration) { voices[i].Stop(); } } } private void StopVoices() { if (Object.op_Implicit((Object)(object)drone)) { drone.volume = 0f; drone.Stop(); } AudioSource[] array = voices; foreach (AudioSource val in array) { if (Object.op_Implicit((Object)(object)val)) { val.volume = 0f; val.Stop(); } } starts[0] = (starts[1] = -100.0); nextVoice = 0.0; voiceIndex = 0; } private void OnDisable() { StopVoices(); } } internal static class ChargeRules { internal static int Clamp(int charge, int capacity) { return Math.Max(0, Math.Min(Math.Max(1, capacity), charge)); } internal static int Add(int charge, int amount, int capacity) { return (int)Math.Min(Math.Max(1, capacity), (long)Clamp(charge, capacity) + (long)Math.Max(0, amount)); } internal static bool InRange(float distanceSquared, float range) { if (distanceSquared >= 0f) { return distanceSquared <= range * range; } return false; } internal static long NextTick(long now, float seconds) { return now + (long)(seconds * 10000000f); } internal static bool IsDue(long now, long deadline) { if (deadline > 0) { return now >= deadline; } return false; } } internal static class ConfiguredTargets { private static string? previous; private static ZNetScene? scene; private static TargetList? targets; internal static bool Contains(int prefab) { if (!Object.op_Implicit((Object)(object)ZNetScene.instance)) { return false; } string value = Plugin.Settings.TargetPrefabs.Value; if (targets == null || previous != value || (Object)(object)scene != (Object)(object)ZNetScene.instance) { previous = value; scene = ZNetScene.instance; targets = new TargetList(value, delegate(string name) { GameObject prefab2 = ZNetScene.instance.GetPrefab(name); return (!Object.op_Implicit((Object)(object)prefab2) || !Object.op_Implicit((Object)(object)prefab2.GetComponent<Character>()) || Object.op_Implicit((Object)(object)prefab2.GetComponent<Player>())) ? ((int?)null) : new int?(StringExtensionMethods.GetStableHashCode(name)); }, delegate(string name) { Plugin.Log.LogWarning((object)("TargetPrefabs: ignoring '" + name + "'; use the exact prefab name of a non-player creature.")); }); } return targets.Contains(prefab); } } public sealed class CrownLightning : MonoBehaviour { private Transform[] tips = Array.Empty<Transform>(); private Transform orb; private readonly LineRenderer[] lines = (LineRenderer[])(object)new LineRenderer[2]; private readonly LineRenderer[] glows = (LineRenderer[])(object)new LineRenderer[2]; private readonly int[] selected = new int[2] { -1, -1 }; private readonly Vector3[] points = (Vector3[])(object)new Vector3[13]; private Random random; private bool charged; private float nextPulse; private float endPulse; private float nextShape; private float started; private int pulsesUntilDouble; internal int PulseCount { get; private set; } internal int ActiveBoltCount { get; private set; } internal bool Flashing => ActiveBoltCount > 0; internal LineRenderer Line => lines[0]; internal Transform? SelectedTip => TipAt(0); internal LineRenderer LineAt(int index) { return lines[index]; } internal Transform? TipAt(int index) { if (selected[index] < 0) { return null; } return tips[selected[index]]; } internal void Initialize(Transform orbTransform, Material material) { orb = orbTransform; tips = (from t in ((Component)((Component)this).transform).GetComponentsInChildren<Transform>(true) where ((Object)t).name.StartsWith("LightningTower_BranchTip_") select t).ToArray(); random = new Random(((Object)this).GetInstanceID()); pulsesUntilDouble = random.Next(2, 5); for (int num = 0; num < lines.Length; num++) { glows[num] = CreateLine("LightningTower_CrownGlow_" + num, material, 0.12f); lines[num] = CreateLine("LightningTower_CrownArc_" + num, material, 0.05f); } } private LineRenderer CreateLine(string name, Material material, float width) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0006: 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_0067: 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_007d: 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_0093: 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_00a9: Unknown result type (might be due to invalid IL or missing references) //IL_00ae: Unknown result type (might be due to invalid IL or missing references) //IL_00b8: Expected O, but got Unknown GameObject val = new GameObject(name); val.transform.SetParent(((Component)this).transform, false); LineRenderer val2 = val.AddComponent<LineRenderer>(); ((Renderer)val2).sharedMaterial = material; val2.useWorldSpace = false; val2.positionCount = points.Length; val2.alignment = (LineAlignment)0; val2.textureMode = (LineTextureMode)0; val2.widthMultiplier = width; val2.widthCurve = new AnimationCurve((Keyframe[])(object)new Keyframe[4] { new Keyframe(0f, 0.5f), new Keyframe(0.15f, 1f), new Keyframe(0.8f, 1f), new Keyframe(1f, 0.4f) }); val2.numCapVertices = 2; ((Renderer)val2).shadowCastingMode = (ShadowCastingMode)0; ((Renderer)val2).receiveShadows = false; ((Renderer)val2).enabled = false; return val2; } internal void SetCharged(bool value) { if (charged != value) { charged = value; if (value) { nextPulse = Time.time + 0.35f + (float)random.NextDouble() * 0.3f; } else { HidePulse(); } } } private void Update() { //IL_01f8: Unknown result type (might be due to invalid IL or missing references) //IL_01ff: Unknown result type (might be due to invalid IL or missing references) //IL_0235: Unknown result type (might be due to invalid IL or missing references) //IL_023c: Unknown result type (might be due to invalid IL or missing references) if (!charged || tips.Length == 0 || !Object.op_Implicit((Object)(object)lines[0])) { return; } float time = Time.time; if (Flashing && time >= endPulse) { HidePulse(); } if (!Flashing && time >= nextPulse) { selected[0] = PickTip(selected[0]); bool flag = --pulsesUntilDouble == 0 && tips.Length > 1; ActiveBoltCount = ((!flag) ? 1 : 2); if (flag) { selected[1] = PickTip(selected[0]); pulsesUntilDouble = random.Next(2, 5); } started = time; endPulse = time + 0.32f + (float)random.NextDouble() * 0.13f; nextPulse = time + 2f + (float)random.NextDouble(); nextShape = time; for (int i = 0; i < ActiveBoltCount; i++) { LineRenderer obj = lines[i]; bool enabled = (((Renderer)glows[i]).enabled = true); ((Renderer)obj).enabled = enabled; } PulseCount++; } if (!Flashing) { return; } if (time >= nextShape) { for (int j = 0; j < ActiveBoltCount; j++) { Reshape(j); } nextShape = time + 0.055f; } float num = Mathf.Clamp01((endPulse - time) / 0.08f) * ((Mathf.FloorToInt((time - started) / 0.055f) % 3 == 1) ? 0.75f : 1f); Color val = default(Color); for (int k = 0; k < ActiveBoltCount; k++) { LineRenderer obj2 = lines[k]; LineRenderer obj3 = lines[k]; ((Color)(ref val))..ctor(1f, 1f, 1f, num); obj3.endColor = val; obj2.startColor = val; LineRenderer obj4 = glows[k]; LineRenderer obj5 = glows[k]; ((Color)(ref val))..ctor(0.35f, 0.7f, 1f, num * 0.22f); obj5.endColor = val; obj4.startColor = val; } } private int PickTip(int excluded) { if (tips.Length < 2) { return 0; } int num = random.Next(tips.Length - ((excluded >= 0) ? 1 : 0)); if (excluded < 0 || num < excluded) { return num; } return num + 1; } private void Reshape(int index) { //IL_0015: Unknown result type (might be due to invalid IL or missing references) //IL_001a: Unknown result type (might be due to invalid IL or missing references) //IL_001f: Unknown result type (might be due to invalid IL or missing references) //IL_002c: Unknown result type (might be due to invalid IL or missing references) //IL_0031: Unknown result type (might be due to invalid IL or missing references) //IL_0036: Unknown result type (might be due to invalid IL or missing references) //IL_0037: Unknown result type (might be due to invalid IL or missing references) //IL_0038: Unknown result type (might be due to invalid IL or missing references) //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_0042: Unknown result type (might be due to invalid IL or missing references) //IL_0047: Unknown result type (might be due to invalid IL or missing references) //IL_0048: 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) //IL_0062: 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_0067: Unknown result type (might be due to invalid IL or missing references) //IL_006c: Unknown result type (might be due to invalid IL or missing references) //IL_0070: Unknown result type (might be due to invalid IL or missing references) //IL_0075: Unknown result type (might be due to invalid IL or missing references) //IL_0076: Unknown result type (might be due to invalid IL or missing references) //IL_0077: 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_007d: Unknown result type (might be due to invalid IL or missing references) //IL_0081: Unknown result type (might be due to invalid IL or missing references) //IL_0086: Unknown result type (might be due to invalid IL or missing references) //IL_008d: 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_00a8: Unknown result type (might be due to invalid IL or missing references) //IL_00a9: Unknown result type (might be due to invalid IL or missing references) //IL_00be: 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_0125: Unknown result type (might be due to invalid IL or missing references) //IL_0126: Unknown result type (might be due to invalid IL or missing references) //IL_0129: Unknown result type (might be due to invalid IL or missing references) //IL_012e: Unknown result type (might be due to invalid IL or missing references) //IL_0131: Unknown result type (might be due to invalid IL or missing references) //IL_0136: Unknown result type (might be due to invalid IL or missing references) //IL_013a: Unknown result type (might be due to invalid IL or missing references) //IL_013f: Unknown result type (might be due to invalid IL or missing references) //IL_0154: Unknown result type (might be due to invalid IL or missing references) //IL_0159: Unknown result type (might be due to invalid IL or missing references) //IL_015e: Unknown result type (might be due to invalid IL or missing references) Vector3 val = ((Component)this).transform.InverseTransformPoint(tips[selected[index]].position); Vector3 val2 = ((Component)this).transform.InverseTransformPoint(orb.position); Vector3 val3 = val2 - val; Vector3 normalized = ((Vector3)(ref val3)).normalized; val3 = Vector3.Cross(normalized, (Math.Abs(normalized.y) > 0.9f) ? Vector3.forward : Vector3.up); Vector3 normalized2 = ((Vector3)(ref val3)).normalized; val3 = Vector3.Cross(normalized2, normalized); Vector3 normalized3 = ((Vector3)(ref val3)).normalized; float num = Mathf.Min(0.18f, Vector3.Distance(val, val2) * 0.14f); points[0] = val; points[points.Length - 1] = val2; for (int i = 1; i < points.Length - 1; i++) { float num2 = (float)i / (float)(points.Length - 1); float num3 = (float)((i % 2 == 0) ? 1 : (-1)) * (0.4f + (float)random.NextDouble() * 0.6f); float num4 = ((float)random.NextDouble() - 0.5f) * 0.6f; points[i] = Vector3.Lerp(val, val2, num2) + (normalized2 * num3 + normalized3 * num4) * (num * Mathf.Sin(num2 * (float)Math.PI)); } lines[index].SetPositions(points); glows[index].SetPositions(points); } private void HidePulse() { ActiveBoltCount = 0; for (int i = 0; i < lines.Length; i++) { if (Object.op_Implicit((Object)(object)lines[i])) { ((Renderer)lines[i]).enabled = false; } if (Object.op_Implicit((Object)(object)glows[i])) { ((Renderer)glows[i]).enabled = false; } } } private void OnDisable() { HidePulse(); } private void OnDestroy() { foreach (LineRenderer item in lines.Concat(glows)) { if (Object.op_Implicit((Object)(object)item)) { Object.Destroy((Object)(object)((Component)item).gameObject); } } } } internal static class HumSignal { internal const int SampleRate = 22050; internal static float DistanceGain(float distance, float range) { if (range <= 0f || distance >= range || float.IsNaN(distance)) { return 0f; } float num = Math.Min(1f, range * 0.4f); if (distance <= num) { return 1f; } float num2 = (distance - num) / (range - num); return 1f - num2 * num2 * (3f - 2f * num2); } internal static float[] CreateLoop() { float[] array = new float[44100]; for (int i = 0; i < array.Length; i++) { double num = (double)i / 22050.0; double num2 = Math.PI * 2.0 * num; array[i] = (float)((0.45 * Math.Sin(100.0 * num2) + 0.2 * Math.Sin(150.0 * num2) + 0.12 * Math.Sin(200.0 * num2) + 0.08 * Math.Sin(300.0 * num2)) * (0.9 + 0.1 * Math.Sin(3.0 * num2))); } return array; } } public sealed class JaggedBolt : MonoBehaviour { private LineRenderer line; private Vector3 origin; private Vector3 target; private Vector3 side; private Vector3 up; private Vector3[] points = Array.Empty<Vector3>(); private Random random; private float started; private float nextShape; private float amplitude; internal LineRenderer Line => line; internal void Initialize(Vector3 from, Vector3 to, Material material) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_0008: Unknown result type (might be due to invalid IL or missing references) //IL_0009: Unknown result type (might be due to invalid IL or missing references) //IL_000e: Unknown result type (might be due to invalid IL or missing references) //IL_000f: Unknown result type (might be due to invalid IL or missing references) //IL_0010: Unknown result type (might be due to invalid IL or missing references) //IL_0015: Unknown result type (might be due to invalid IL or missing references) //IL_0018: Unknown result type (might be due to invalid IL or missing references) //IL_001d: Unknown result type (might be due to invalid IL or missing references) //IL_001f: Unknown result type (might be due to invalid IL or missing references) //IL_0020: Unknown result type (might be due to invalid IL or missing references) //IL_0039: Unknown result type (might be due to invalid IL or missing references) //IL_0032: 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_0043: 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_004b: 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) //IL_0057: Unknown result type (might be due to invalid IL or missing references) //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) //IL_0060: Unknown result type (might be due to invalid IL or missing references) //IL_0065: 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_006b: Unknown result type (might be due to invalid IL or missing references) //IL_00ca: Unknown result type (might be due to invalid IL or missing references) //IL_00d0: Expected O, but got Unknown //IL_0181: Unknown result type (might be due to invalid IL or missing references) //IL_0186: Unknown result type (might be due to invalid IL or missing references) //IL_0197: Unknown result type (might be due to invalid IL or missing references) //IL_019c: Unknown result type (might be due to invalid IL or missing references) //IL_01ad: Unknown result type (might be due to invalid IL or missing references) //IL_01b2: Unknown result type (might be due to invalid IL or missing references) //IL_01c3: Unknown result type (might be due to invalid IL or missing references) //IL_01c8: Unknown result type (might be due to invalid IL or missing references) //IL_01cd: Unknown result type (might be due to invalid IL or missing references) //IL_01d7: Expected O, but got Unknown origin = from; target = to; Vector3 val = to - from; Vector3 normalized = ((Vector3)(ref val)).normalized; val = Vector3.Cross(normalized, (Math.Abs(normalized.y) > 0.9f) ? Vector3.forward : Vector3.up); side = ((Vector3)(ref val)).normalized; val = Vector3.Cross(side, normalized); up = ((Vector3)(ref val)).normalized; float num = Vector3.Distance(from, to); points = (Vector3[])(object)new Vector3[Mathf.Clamp(Mathf.CeilToInt(num / 0.6f), 8, 64) + 1]; amplitude = Mathf.Min(Plugin.Settings.BoltJaggedness.Value, num * 0.12f); random = new Random(((Object)this).GetInstanceID()); GameObject val2 = new GameObject("LightningTower_JaggedPath"); line = val2.AddComponent<LineRenderer>(); ((Renderer)line).sharedMaterial = material; line.useWorldSpace = true; line.positionCount = points.Length; line.textureMode = (LineTextureMode)0; line.alignment = (LineAlignment)0; line.numCapVertices = 2; line.numCornerVertices = 0; ((Renderer)line).shadowCastingMode = (ShadowCastingMode)0; ((Renderer)line).receiveShadows = false; line.widthMultiplier = Plugin.Settings.BoltWidth.Value; line.widthCurve = new AnimationCurve((Keyframe[])(object)new Keyframe[4] { new Keyframe(0f, 0.55f), new Keyframe(0.18f, 1f), new Keyframe(0.8f, 0.8f), new Keyframe(1f, 0.3f) }); started = Time.time; Reshape(); } private void Update() { //IL_0092: Unknown result type (might be due to invalid IL or missing references) //IL_0098: Unknown result type (might be due to invalid IL or missing references) if (!Object.op_Implicit((Object)(object)line)) { return; } float num = Time.time - started; if (num >= 0.4f) { ((Renderer)line).enabled = false; return; } if (Time.time >= nextShape) { Reshape(); } float num2 = (1f - num / 0.4f) * ((Mathf.FloorToInt(num / 0.045f) % 3 == 1) ? 0.65f : 1f); LineRenderer obj = line; LineRenderer obj2 = line; Color val = default(Color); ((Color)(ref val))..ctor(1f, 1f, 1f, num2); obj2.endColor = val; obj.startColor = val; } private void Reshape() { //IL_0008: Unknown result type (might be due to invalid IL or missing references) //IL_000d: Unknown result type (might be due to invalid IL or missing references) //IL_0023: Unknown result type (might be due to invalid IL or missing references) //IL_0028: Unknown result type (might be due to invalid IL or missing references) //IL_0096: Unknown result type (might be due to invalid IL or missing references) //IL_009c: 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_00a8: Unknown result type (might be due to invalid IL or missing references) //IL_00ae: Unknown result type (might be due to invalid IL or missing references) //IL_00b4: 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_00c0: Unknown result type (might be due to invalid IL or missing references) //IL_00cd: Unknown result type (might be due to invalid IL or missing references) //IL_00d2: Unknown result type (might be due to invalid IL or missing references) //IL_00d7: Unknown result type (might be due to invalid IL or missing references) points[0] = origin; points[points.Length - 1] = target; for (int i = 1; i < points.Length - 1; i++) { float num = (float)i / (float)(points.Length - 1); float num2 = Mathf.Sin(num * (float)Math.PI); float num3 = (float)((i % 2 == 0) ? 1 : (-1)) * (0.35f + (float)random.NextDouble() * 0.65f); float num4 = ((float)random.NextDouble() - 0.5f) * 0.7f; points[i] = Vector3.Lerp(origin, target, num) + (side * num3 + up * num4) * (amplitude * num2); } line.SetPositions(points); nextShape = Time.time + 0.065f; } private void OnDestroy() { if (Object.op_Implicit((Object)(object)line)) { Object.Destroy((Object)(object)((Component)line).gameObject); } } } internal static class LightningEffects { private static GameObject? storage; private static GameObject? bolt; private static GameObject? halo; private static GameObject? sound; private static Material jaggedMaterial; private static Material crownMaterial; private static AudioClip humClip; private static AudioMixerGroup humMixer; private static float soundLifetime; private static Bounds boltBounds; private static bool ready; internal static bool Ready => ready; internal static void Discover() { //IL_000d: Unknown result type (might be due to invalid IL or missing references) //IL_0017: Expected O, but got Unknown //IL_00ec: Unknown result type (might be due to invalid IL or missing references) //IL_00f1: Unknown result type (might be due to invalid IL or missing references) //IL_00fb: Unknown result type (might be due to invalid IL or missing references) //IL_011e: Unknown result type (might be due to invalid IL or missing references) //IL_0123: Unknown result type (might be due to invalid IL or missing references) //IL_0133: Unknown result type (might be due to invalid IL or missing references) //IL_0144: Unknown result type (might be due to invalid IL or missing references) //IL_015d: Unknown result type (might be due to invalid IL or missing references) //IL_017d: Unknown result type (might be due to invalid IL or missing references) //IL_0182: Unknown result type (might be due to invalid IL or missing references) //IL_019f: Unknown result type (might be due to invalid IL or missing references) //IL_01a4: Unknown result type (might be due to invalid IL or missing references) //IL_01a5: Unknown result type (might be due to invalid IL or missing references) //IL_01ac: Unknown result type (might be due to invalid IL or missing references) //IL_01ae: 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_01b6: Unknown result type (might be due to invalid IL or missing references) //IL_01d6: Unknown result type (might be due to invalid IL or missing references) //IL_01db: Unknown result type (might be due to invalid IL or missing references) //IL_01e3: Unknown result type (might be due to invalid IL or missing references) //IL_01f4: Unknown result type (might be due to invalid IL or missing references) //IL_020e: Unknown result type (might be due to invalid IL or missing references) //IL_0213: Unknown result type (might be due to invalid IL or missing references) //IL_021e: Unknown result type (might be due to invalid IL or missing references) //IL_0223: Unknown result type (might be due to invalid IL or missing references) //IL_022e: Unknown result type (might be due to invalid IL or missing references) //IL_0233: Unknown result type (might be due to invalid IL or missing references) //IL_023e: Unknown result type (might be due to invalid IL or missing references) //IL_0243: Unknown result type (might be due to invalid IL or missing references) //IL_024e: Unknown result type (might be due to invalid IL or missing references) //IL_0253: Unknown result type (might be due to invalid IL or missing references) //IL_0476: Unknown result type (might be due to invalid IL or missing references) //IL_0480: Expected O, but got Unknown //IL_061b: Unknown result type (might be due to invalid IL or missing references) //IL_062a: Unknown result type (might be due to invalid IL or missing references) if (Ready) { return; } storage = new GameObject("LightningTower_EffectTemplates"); storage.SetActive(false); Object.DontDestroyOnLoad((Object)(object)storage); GameObject prefab = PrefabManager.Instance.GetPrefab("fx_chainlightning_spread"); Transform obj = (Object.op_Implicit((Object)(object)prefab) ? prefab.transform.Find("Lightning") : null); if (!Object.op_Implicit((Object)(object)obj)) { throw new InvalidOperationException("Missing fx_chainlightning_spread/Lightning."); } bolt = CopyVisual(((Component)obj).gameObject, "LightningTower_Bolt"); for (int num = bolt.transform.childCount - 1; num >= 0; num--) { Object.DestroyImmediate((Object)(object)((Component)bolt.transform.GetChild(num)).gameObject); } ParticleSystem component = bolt.GetComponent<ParticleSystem>(); ParticleSystemRenderer component2 = bolt.GetComponent<ParticleSystemRenderer>(); if (!Object.op_Implicit((Object)(object)component2.mesh)) { throw new InvalidOperationException("The chain-lightning effect has no bolt mesh."); } boltBounds = component2.mesh.bounds; if (((Bounds)(ref boltBounds)).size.x < 0.001f) { throw new InvalidOperationException("The lightning mesh has no length along its firing axis."); } component2.alignment = (ParticleSystemRenderSpace)2; MainModule main = component.main; ((MainModule)(ref main)).loop = false; ((MainModule)(ref main)).startLifetime = MinMaxCurve.op_Implicit(0.4f); ((MainModule)(ref main)).startSpeed = MinMaxCurve.op_Implicit(0f); ((MainModule)(ref main)).startSize3D = false; ((MainModule)(ref main)).startSize = MinMaxCurve.op_Implicit(1f); ((MainModule)(ref main)).startColor = MinMaxGradient.op_Implicit(new Color(0.5f, 0.65f, 0.8f, 0.25f)); ((MainModule)(ref main)).startRotation3D = true; MinMaxCurve val = (((MainModule)(ref main)).startRotationZ = MinMaxCurve.op_Implicit(0f)); MinMaxCurve startRotationX = (((MainModule)(ref main)).startRotationY = val); ((MainModule)(ref main)).startRotationX = startRotationX; ((MainModule)(ref main)).maxParticles = 1; ((MainModule)(ref main)).simulationSpace = (ParticleSystemSimulationSpace)0; ((MainModule)(ref main)).scalingMode = (ParticleSystemScalingMode)0; EmissionModule emission = component.emission; ((EmissionModule)(ref emission)).rateOverTime = MinMaxCurve.op_Implicit(0f); ((EmissionModule)(ref emission)).rateOverDistance = MinMaxCurve.op_Implicit(0f); ((EmissionModule)(ref emission)).SetBursts((Burst[])(object)new Burst[1] { new Burst(0f, (short)1) }); ShapeModule shape = component.shape; ((ShapeModule)(ref shape)).enabled = false; VelocityOverLifetimeModule velocityOverLifetime = component.velocityOverLifetime; ((VelocityOverLifetimeModule)(ref velocityOverLifetime)).enabled = false; NoiseModule noise = component.noise; ((NoiseModule)(ref noise)).enabled = false; SubEmittersModule subEmitters = component.subEmitters; ((SubEmittersModule)(ref subEmitters)).enabled = false; GameObject prefab2 = PrefabManager.Instance.GetPrefab("StaffLightning"); Transform val4 = (Object.op_Implicit((Object)(object)prefab2) ? prefab2.transform.Find("attach/Loaded/Lightning") : null); if (!Object.op_Implicit((Object)(object)val4)) { throw new InvalidOperationException("Missing StaffLightning loaded lightning effect."); } Incinerator component3 = PrefabManager.Instance.GetPrefab("incinerator").GetComponent<Incinerator>(); GameObject lightingAOEs = component3.m_lightingAOEs; sound = CopyVisual(((Component)lightingAOEs.GetComponentsInChildren<ZSFX>(true).First((ZSFX sfx) => sfx.m_audioClips.Any((AudioClip clip) => Object.op_Implicit((Object)(object)clip) && ((Object)clip).name.StartsWith("Obliterator_Lightning_")))).gameObject, "LightningTower_ObliteratorThunder"); ZSFX component4 = sound.GetComponent<ZSFX>(); component4.m_minDelay = (component4.m_maxDelay = 0f); component4.m_minVol *= Plugin.Settings.StrikeVolume.Value; component4.m_maxVol *= Plugin.Settings.StrikeVolume.Value; component4.m_maxConcurrentSources = 3; soundLifetime = component4.m_audioClips.Max((AudioClip clip) => clip.length) / Mathf.Max(0.1f, Mathf.Min(component4.m_minPitch, component4.m_maxPitch)) + 0.5f; ZSFX obj2 = component3.m_leverEffects.m_effectPrefabs.Where((EffectData effect) => Object.op_Implicit((Object)(object)effect.m_prefab)).SelectMany((EffectData effect) => effect.m_prefab.GetComponentsInChildren<ZSFX>(true)).First((ZSFX effect) => effect.m_audioClips.Any((AudioClip clip) => Object.op_Implicit((Object)(object)clip) && ((Object)clip).name.StartsWith("Obliterator_Electricity_Start_"))); humClip = obj2.m_audioClips.OrderByDescending((AudioClip clip) => clip.length).First(); humMixer = ((Component)obj2).GetComponent<AudioSource>().outputAudioMixerGroup; halo = new GameObject("LightningTower_ChargedHalo"); halo.transform.SetParent(storage.transform, false); GameObject obj3 = CopyVisual(((Component)val4).gameObject, "WhiteElectricalArcs"); obj3.transform.SetParent(halo.transform, false); ConfigureHaloParticles(obj3.GetComponent<ParticleSystem>(), stars: false); ParticleSystem val5 = component3.m_leverEffects.m_effectPrefabs.Where((EffectData effect) => Object.op_Implicit((Object)(object)effect.m_prefab)).SelectMany((EffectData effect) => effect.m_prefab.GetComponentsInChildren<ParticleSystem>(true)).FirstOrDefault((Func<ParticleSystem, bool>)((ParticleSystem effect) => ((Object)effect).name.IndexOf("spar", StringComparison.OrdinalIgnoreCase) >= 0 && ((Renderer)((Component)effect).GetComponent<ParticleSystemRenderer>()).sharedMaterials.Any((Material material) => Object.op_Implicit((Object)(object)material) && Object.op_Implicit((Object)(object)material.mainTexture) && ((Object)material.mainTexture).name == "spark"))); Transform val6 = (Object.op_Implicit((Object)(object)val5) ? ((Component)val5).transform : lightingAOEs.transform.Find("Sparcs")); if (!Object.op_Implicit((Object)(object)val6)) { throw new InvalidOperationException("Missing Obliterator star particles."); } GameObject obj4 = CopyVisual(((Component)val6).gameObject, "ObliteratorStars"); obj4.transform.SetParent(halo.transform, false); ConfigureHaloParticles(obj4.GetComponent<ParticleSystem>(), stars: true); jaggedMaterial = WhiteMaterial(((Renderer)((Component)val4).GetComponent<ParticleSystemRenderer>()).sharedMaterials.First((Material material) => Object.op_Implicit((Object)(object)material))); crownMaterial = WhiteMaterial(jaggedMaterial); ((Object)crownMaterial).name = "LightningTower_CrownArcWhite"; crownMaterial.mainTexture = (Texture)(object)Texture2D.whiteTexture; crownMaterial.mainTextureScale = Vector2.one; crownMaterial.mainTextureOffset = Vector2.zero; ready = true; Plugin.Log.LogInfo((object)string.Format("Visuals: jagged overlay + chain-lightning core; white halo radius={0}m; stars={1}/{2}.", Plugin.Settings.HaloRadius.Value, Object.op_Implicit((Object)(object)val5) ? "Obliterator charging" : "Obliterator lightning", ((Object)val6).name)); Plugin.Log.LogInfo((object)$"Audio: Obliterator_Lightning_01/02/03; electrical hum + {((Object)humClip).name}, pitch=0.75, crossfade=0.35s, radius={Plugin.Settings.HumRange.Value}m."); } private static Material WhiteMaterial(Material original) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_001d: Expected O, but got Unknown //IL_004f: Unknown result type (might be due to invalid IL or missing references) Material val = new Material(original) { name = ((Object)original).name + "_LightningTowerWhite" }; string[] array = new string[3] { "_Color", "_TintColor", "_EmissionColor" }; foreach (string text in array) { if (val.HasProperty(text)) { val.SetColor(text, Color.white); } } return val; } private static void ConfigureHaloParticles(ParticleSystem particles, bool stars) { //IL_0025: Unknown result type (might be due to invalid IL or missing references) //IL_002a: Unknown result type (might be due to invalid IL or missing references) //IL_0087: Unknown result type (might be due to invalid IL or missing references) //IL_0098: Unknown result type (might be due to invalid IL or missing references) //IL_00c2: Unknown result type (might be due to invalid IL or missing references) //IL_00d6: Unknown result type (might be due to invalid IL or missing references) //IL_00db: 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_00fb: Unknown result type (might be due to invalid IL or missing references) //IL_0132: Unknown result type (might be due to invalid IL or missing references) //IL_013e: Unknown result type (might be due to invalid IL or missing references) //IL_014a: Unknown result type (might be due to invalid IL or missing references) //IL_0155: Unknown result type (might be due to invalid IL or missing references) //IL_015a: Unknown result type (might be due to invalid IL or missing references) //IL_0170: Unknown result type (might be due to invalid IL or missing references) //IL_0181: Unknown result type (might be due to invalid IL or missing references) //IL_0198: Unknown result type (might be due to invalid IL or missing references) //IL_019d: Unknown result type (might be due to invalid IL or missing references) //IL_01bd: Unknown result type (might be due to invalid IL or missing references) //IL_01c2: Unknown result type (might be due to invalid IL or missing references) //IL_01c3: Unknown result type (might be due to invalid IL or missing references) //IL_01ca: Unknown result type (might be due to invalid IL or missing references) //IL_01cc: Unknown result type (might be due to invalid IL or missing references) //IL_01cd: Unknown result type (might be due to invalid IL or missing references) //IL_01d4: Unknown result type (might be due to invalid IL or missing references) //IL_01e7: Unknown result type (might be due to invalid IL or missing references) //IL_01fd: Unknown result type (might be due to invalid IL or missing references) //IL_0213: Unknown result type (might be due to invalid IL or missing references) //IL_0228: Unknown result type (might be due to invalid IL or missing references) //IL_022d: Unknown result type (might be due to invalid IL or missing references) //IL_022e: Unknown result type (might be due to invalid IL or missing references) //IL_0235: Unknown result type (might be due to invalid IL or missing references) //IL_0237: Unknown result type (might be due to invalid IL or missing references) //IL_0238: 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_024d: Unknown result type (might be due to invalid IL or missing references) //IL_025e: Unknown result type (might be due to invalid IL or missing references) //IL_0269: Unknown result type (might be due to invalid IL or missing references) //IL_026e: Unknown result type (might be due to invalid IL or missing references) //IL_0279: Unknown result type (might be due to invalid IL or missing references) //IL_027e: Unknown result type (might be due to invalid IL or missing references) //IL_0289: Unknown result type (might be due to invalid IL or missing references) //IL_028e: Unknown result type (might be due to invalid IL or missing references) //IL_0299: Unknown result type (might be due to invalid IL or missing references) //IL_029e: Unknown result type (might be due to invalid IL or missing references) //IL_02a9: Unknown result type (might be due to invalid IL or missing references) //IL_02ae: Unknown result type (might be due to invalid IL or missing references) //IL_02b9: Unknown result type (might be due to invalid IL or missing references) //IL_02be: Unknown result type (might be due to invalid IL or missing references) //IL_02d4: Unknown result type (might be due to invalid IL or missing references) //IL_02f1: Unknown result type (might be due to invalid IL or missing references) //IL_02fc: Unknown result type (might be due to invalid IL or missing references) //IL_0301: Unknown result type (might be due to invalid IL or missing references) //IL_030b: Unknown result type (might be due to invalid IL or missing references) //IL_0312: Expected O, but got Unknown //IL_031c: Unknown result type (might be due to invalid IL or missing references) //IL_0326: Unknown result type (might be due to invalid IL or missing references) //IL_032b: Unknown result type (might be due to invalid IL or missing references) //IL_0332: Unknown result type (might be due to invalid IL or missing references) //IL_033c: Unknown result type (might be due to invalid IL or missing references) //IL_0341: Unknown result type (might be due to invalid IL or missing references) //IL_0358: Unknown result type (might be due to invalid IL or missing references) //IL_035d: Unknown result type (might be due to invalid IL or missing references) //IL_036e: Unknown result type (might be due to invalid IL or missing references) //IL_0373: Unknown result type (might be due to invalid IL or missing references) //IL_0384: Unknown result type (might be due to invalid IL or missing references) //IL_0389: Unknown result type (might be due to invalid IL or missing references) //IL_039a: Unknown result type (might be due to invalid IL or missing references) //IL_039f: Unknown result type (might be due to invalid IL or missing references) //IL_03ad: Unknown result type (might be due to invalid IL or missing references) //IL_03b8: Unknown result type (might be due to invalid IL or missing references) //IL_03bd: Unknown result type (might be due to invalid IL or missing references) //IL_03e5: Unknown result type (might be due to invalid IL or missing references) //IL_0417: Unknown result type (might be due to invalid IL or missing references) //IL_0423: Unknown result type (might be due to invalid IL or missing references) //IL_0428: Unknown result type (might be due to invalid IL or missing references) //IL_04c6: Unknown result type (might be due to invalid IL or missing references) //IL_04cb: Unknown result type (might be due to invalid IL or missing references) //IL_04dd: Unknown result type (might be due to invalid IL or missing references) //IL_04e2: Unknown result type (might be due to invalid IL or missing references) particles.Stop(true, (ParticleSystemStopBehavior)0); float num = Plugin.Settings.HaloRadius.Value / 3f; MainModule main = particles.main; ((MainModule)(ref main)).loop = true; ((MainModule)(ref main)).duration = 3f; ((MainModule)(ref main)).prewarm = true; ((MainModule)(ref main)).playOnAwake = true; ((MainModule)(ref main)).cullingMode = (ParticleSystemCullingMode)3; ((MainModule)(ref main)).simulationSpace = (ParticleSystemSimulationSpace)0; ((MainModule)(ref main)).scalingMode = (ParticleSystemScalingMode)0; ((MainModule)(ref main)).startLifetime = new MinMaxCurve(stars ? 0.35f : 0.65f, stars ? 0.8f : 1.15f); ((MainModule)(ref main)).startSpeed = MinMaxCurve.op_Implicit(0f); ((MainModule)(ref main)).startSize = new MinMaxCurve(stars ? 0.03f : 0.007f, stars ? 0.07f : 0.015f); ((MainModule)(ref main)).startSize3D = false; ((MainModule)(ref main)).startColor = MinMaxGradient.op_Implicit(Color.white); ((MainModule)(ref main)).maxParticles = (stars ? 48 : 120); ShapeModule shape = particles.shape; ((ShapeModule)(ref shape)).enabled = true; ((ShapeModule)(ref shape)).shapeType = (ParticleSystemShapeType)0; ((ShapeModule)(ref shape)).radius = num * (stars ? 1.15f : 1f); ((ShapeModule)(ref shape)).radiusThickness = 0f; ((ShapeModule)(ref shape)).position = Vector3.zero; ((ShapeModule)(ref shape)).rotation = Vector3.zero; ((ShapeModule)(ref shape)).scale = Vector3.one; EmissionModule emission = particles.emission; ((EmissionModule)(ref emission)).enabled = true; ((EmissionModule)(ref emission)).rateOverTime = MinMaxCurve.op_Implicit((float)(stars ? 18 : 70)); ((EmissionModule)(ref emission)).rateOverDistance = MinMaxCurve.op_Implicit(0f); ((EmissionModule)(ref emission)).SetBursts(Array.Empty<Burst>()); VelocityOverLifetimeModule velocityOverLifetime = particles.velocityOverLifetime; ((VelocityOverLifetimeModule)(ref velocityOverLifetime)).enabled = !stars; ((VelocityOverLifetimeModule)(ref velocityOverLifetime)).space = (ParticleSystemSimulationSpace)0; MinMaxCurve val = (((VelocityOverLifetimeModule)(ref velocityOverLifetime)).z = MinMaxCurve.op_Implicit(0f)); MinMaxCurve x = (((VelocityOverLifetimeModule)(ref velocityOverLifetime)).y = val); ((VelocityOverLifetimeModule)(ref velocityOverLifetime)).x = x; ((VelocityOverLifetimeModule)(ref velocityOverLifetime)).orbitalX = new MinMaxCurve(1f, 2f); ((VelocityOverLifetimeModule)(ref velocityOverLifetime)).orbitalY = new MinMaxCurve(2f, 4f); ((VelocityOverLifetimeModule)(ref velocityOverLifetime)).orbitalZ = new MinMaxCurve(0f, 0f); val = (((VelocityOverLifetimeModule)(ref velocityOverLifetime)).orbitalOffsetZ = MinMaxCurve.op_Implicit(0f)); x = (((VelocityOverLifetimeModule)(ref velocityOverLifetime)).orbitalOffsetY = val); ((VelocityOverLifetimeModule)(ref velocityOverLifetime)).orbitalOffsetX = x; ((VelocityOverLifetimeModule)(ref velocityOverLifetime)).radial = MinMaxCurve.op_Implicit(0f); ((VelocityOverLifetimeModule)(ref velocityOverLifetime)).speedModifier = MinMaxCurve.op_Implicit(1f); ForceOverLifetimeModule forceOverLifetime = particles.forceOverLifetime; ((ForceOverLifetimeModule)(ref forceOverLifetime)).enabled = false; ExternalForcesModule externalForces = particles.externalForces; ((ExternalForcesModule)(ref externalForces)).enabled = false; CollisionModule collision = particles.collision; ((CollisionModule)(ref collision)).enabled = false; ColorBySpeedModule colorBySpeed = particles.colorBySpeed; ((ColorBySpeedModule)(ref colorBySpeed)).enabled = false; SizeOverLifetimeModule sizeOverLifetime = particles.sizeOverLifetime; ((SizeOverLifetimeModule)(ref sizeOverLifetime)).enabled = false; NoiseModule noise = particles.noise; ((NoiseModule)(ref noise)).enabled = !stars; ((NoiseModule)(ref noise)).strength = MinMaxCurve.op_Implicit(num * 0.06f); ((NoiseModule)(ref noise)).frequency = 4f; ((NoiseModule)(ref noise)).scrollSpeed = MinMaxCurve.op_Implicit(0.7f); ColorOverLifetimeModule colorOverLifetime = particles.colorOverLifetime; ((ColorOverLifetimeModule)(ref colorOverLifetime)).enabled = true; Gradient val6 = new Gradient(); val6.SetKeys((GradientColorKey[])(object)new GradientColorKey[2] { new GradientColorKey(Color.white, 0f), new GradientColorKey(Color.white, 1f) }, (GradientAlphaKey[])(object)new GradientAlphaKey[4] { new GradientAlphaKey(0f, 0f), new GradientAlphaKey(1f, 0.15f), new GradientAlphaKey(0.85f, 0.7f), new GradientAlphaKey(0f, 1f) }); ((ColorOverLifetimeModule)(ref colorOverLifetime)).color = MinMaxGradient.op_Implicit(val6); TrailModule trails = particles.trails; if (!stars) { ((TrailModule)(ref trails)).enabled = true; ((TrailModule)(ref trails)).mode = (ParticleSystemTrailMode)0; ((TrailModule)(ref trails)).ratio = 1f; ((TrailModule)(ref trails)).lifetime = MinMaxCurve.op_Implicit(0.25f); ((TrailModule)(ref trails)).minVertexDistance = 0.006f; ((TrailModule)(ref trails)).worldSpace = false; ((TrailModule)(ref trails)).dieWithParticles = true; ((TrailModule)(ref trails)).inheritParticleColor = true; ((TrailModule)(ref trails)).colorOverLifetime = MinMaxGradient.op_Implicit(val6); ((TrailModule)(ref trails)).colorOverTrail = new MinMaxGradient(Color.white); } else { ((TrailModule)(ref trails)).enabled = false; } ParticleSystemRenderer component = ((Component)particles).GetComponent<ParticleSystemRenderer>(); if (stars) { component.renderMode = (ParticleSystemRenderMode)0; component.alignment = (ParticleSystemRenderSpace)0; component.lengthScale = 0f; component.velocityScale = 0f; } Material fallback = ((Renderer)component).sharedMaterials.First((Material material) => Object.op_Implicit((Object)(object)material)); ((Renderer)component).sharedMaterials = ((Renderer)component).sharedMaterials.Select((Material material) => WhiteMaterial(Object.op_Implicit((Object)(object)material) ? material : fallback)).ToArray(); ((Renderer)component).localBounds = new Bounds(Vector3.zero, Vector3.one * (num * 2f + 1f)); particles.Play(); } private static GameObject CopyVisual(GameObject source, string name) { //IL_0088: Unknown result type (might be due to invalid IL or missing references) //IL_0098: 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) GameObject val = Object.Instantiate<GameObject>(source, storage.transform); ((Object)val).name = name; MonoBehaviour[] componentsInChildren = val.GetComponentsInChildren<MonoBehaviour>(true); foreach (MonoBehaviour val2 in componentsInChildren) { if (!(val2 is ZSFX)) { Object.DestroyImmediate((Object)(object)val2); } } Collider[] componentsInChildren2 = val.GetComponentsInChildren<Collider>(true); for (int i = 0; i < componentsInChildren2.Length; i++) { Object.DestroyImmediate((Object)(object)componentsInChildren2[i]); } Rigidbody[] componentsInChildren3 = val.GetComponentsInChildren<Rigidbody>(true); for (int i = 0; i < componentsInChildren3.Length; i++) { Object.DestroyImmediate((Object)(object)componentsInChildren3[i]); } val.transform.localPosition = Vector3.zero; val.transform.localRotation = Quaternion.identity; val.transform.localScale = Vector3.one; val.SetActive(true); return val; } internal static GameObject AttachHalo(Transform tip) { //IL_0012: Unknown result type (might be due to invalid IL or missing references) //IL_0022: Unknown result type (might be due to invalid IL or missing references) //IL_0032: 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) GameObject obj = Object.Instantiate<GameObject>(halo, tip, false); obj.transform.localPosition = Vector3.zero; obj.transform.localRotation = Quaternion.identity; obj.transform.localScale = Vector3.one * (3f / TowerGeometry.Scale); obj.SetActive(false); return obj; } internal static ChargedHum AttachHum(Transform tower) { //IL_0005: Unknown result type (might be due to invalid IL or missing references) //IL_000a: Unknown result type (might be due to invalid IL or missing references) //IL_0017: Unknown result type (might be due to invalid IL or missing references) //IL_001d: Unknown result type (might be due to invalid IL or missing references) //IL_002d: Unknown result type (might be due to invalid IL or missing references) GameObject val = new GameObject("LightningTower_ChargedHum"); val.transform.SetParent(tower, false); val.transform.localPosition = Vector3.up * (1.2f / TowerGeometry.Scale); ChargedHum chargedHum = val.AddComponent<ChargedHum>(); chargedHum.Initialize(humClip, humMixer); return chargedHum; } internal static CrownLightning AttachCrownLightning(Transform tower, Transform tip) { CrownLightning crownLightning = ((Component)tower).gameObject.AddComponent<CrownLightning>(); crownLightning.Initialize(tip, crownMaterial); return crownLightning; } internal static GameObject? Play(Vector3 origin, Vector3 target) { //IL_0009: Unknown result type (might be due to invalid IL or missing references) //IL_000a: Unknown result type (might be due to invalid IL or missing references) //IL_000b: Unknown result type (might be due to invalid IL or missing references) //IL_0010: Unknown result type (might be due to invalid IL or missing references) //IL_0021: Unknown result type (might be due to invalid IL or missing references) //IL_0026: Unknown result type (might be due to invalid IL or missing references) //IL_0027: Unknown result type (might be due to invalid IL or missing references) //IL_002c: Unknown result type (might be due to invalid IL or missing references) //IL_0039: Unknown result type (might be due to invalid IL or missing references) //IL_0054: 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_008a: 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_00a9: Unknown result type (might be due to invalid IL or missing references) //IL_00aa: Unknown result type (might be due to invalid IL or missing references) //IL_00ac: Unknown result type (might be due to invalid IL or missing references) //IL_00ae: Unknown result type (might be due to invalid IL or missing references) //IL_00b3: Unknown result type (might be due to invalid IL or missing references) //IL_00b8: Unknown result type (might be due to invalid IL or missing references) //IL_00bd: Unknown result type (might be due to invalid IL or missing references) //IL_00c9: Unknown result type (might be due to invalid IL or missing references) //IL_00d6: Unknown result type (might be due to invalid IL or missing references) //IL_00d7: Unknown result type (might be due to invalid IL or missing references) //IL_00fe: Unknown result type (might be due to invalid IL or missing references) //IL_00ff: Unknown result type (might be due to invalid IL or missing references) if (!Ready) { return null; } Vector3 val = target - origin; if (((Vector3)(ref val)).sqrMagnitude < 0.0001f) { return null; } Quaternion val2 = Quaternion.FromToRotation(Vector3.right, val); float num = ((Vector3)(ref val)).magnitude / ((Bounds)(ref boltBounds)).size.x; float num2 = 0.09f / Mathf.Max(0.01f, Mathf.Max(((Bounds)(ref boltBounds)).size.y, ((Bounds)(ref boltBounds)).size.z)); Vector3 val3 = default(Vector3); ((Vector3)(ref val3))..ctor(num, num2, num2); Vector3 val4 = default(Vector3); ((Vector3)(ref val4))..ctor(((Bounds)(ref boltBounds)).min.x, 0f, 0f); GameObject obj = Object.Instantiate<GameObject>(bolt, origin - val2 * Vector3.Scale(val4, val3), val2); obj.transform.localScale = val3; obj.AddComponent<JaggedBolt>().Initialize(origin, target, jaggedMaterial); Object.Destroy((Object)(object)obj, 0.6f); if (Object.op_Implicit((Object)(object)sound)) { Object.Destroy((Object)(object)Object.Instantiate<GameObject>(sound, origin, Quaternion.identity), soundLifetime); } return obj; } } internal static class NorseTowerModel { internal const float Height = 6f; internal const float BurialDepth = 0.45f; internal const float OrbRadius = 0.34f; internal const float TipHeight = 5.28f; internal const string ModelName = "LightningTower_NorseModel"; internal const string MetalworkName = "CopperPillar"; internal const string RunePrefix = "RuneFace"; internal const string BranchTipPrefix = "LightningTower_BranchTip_"; internal static readonly Color RuneGlow = new Color(0.21f, 1.95f, 3f); internal static GameObject Build(Transform parent) { //IL_0005: Unknown result type (might be due to invalid IL or missing references) //IL_000b: Expected O, but got Unknown //IL_005d: 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_006e: Expected O, but got Unknown //IL_0091: Unknown result type (might be due to invalid IL or missing references) //IL_0096: Unknown result type (might be due to invalid IL or missing references) //IL_00a2: Expected O, but got Unknown //IL_00a5: Unknown result type (might be due to invalid IL or missing references) //IL_00aa: Unknown result type (might be due to invalid IL or missing references) //IL_00b6: Expected O, but got Unknown //IL_00b9: Unknown result type (might be due to invalid IL or missing references) //IL_00be: Unknown result type (might be due to invalid IL or missing references) //IL_00ca: Expected O, but got Unknown //IL_00e1: Unknown result type (might be due to invalid IL or missing references) //IL_010d: Unknown result type (might be due to invalid IL or missing references) //IL_0143: Unknown result type (might be due to invalid IL or missing references) //IL_0181: Unknown result type (might be due to invalid IL or missing references) //IL_0186: Unknown result type (might be due to invalid IL or missing references) //IL_0191: Unknown result type (might be due to invalid IL or missing references) //IL_019a: Expected O, but got Unknown //IL_047b: Unknown result type (might be due to invalid IL or missing references) //IL_0480: Unknown result type (might be due to invalid IL or missing references) //IL_0484: Unknown result type (might be due to invalid IL or missing references) //IL_0489: Unknown result type (might be due to invalid IL or missing references) //IL_0499: Unknown result type (might be due to invalid IL or missing references) //IL_049e: Unknown result type (might be due to invalid IL or missing references) //IL_04aa: Unknown result type (might be due to invalid IL or missing references) //IL_04bc: Unknown result type (might be due to invalid IL or missing references) //IL_04c2: Unknown result type (might be due to invalid IL or missing references) //IL_04c4: Unknown result type (might be due to invalid IL or missing references) //IL_04c6: Unknown result type (might be due to invalid IL or missing references) //IL_04d0: Unknown result type (might be due to invalid IL or missing references) //IL_04da: Unknown result type (might be due to invalid IL or missing references) //IL_04e0: Unknown result type (might be due to invalid IL or missing references) //IL_04e5: Unknown result type (might be due to invalid IL or missing references) //IL_04e7: Unknown result type (might be due to invalid IL or missing references) //IL_04e9: Unknown result type (might be due to invalid IL or missing references) //IL_04ee: Unknown result type (might be due to invalid IL or missing references) //IL_0505: Unknown result type (might be due to invalid IL or missing references) //IL_0507: Unknown result type (might be due to invalid IL or missing references) //IL_0532: Unknown result type (might be due to invalid IL or missing references) //IL_053c: Unknown result type (might be due to invalid IL or missing references) //IL_038f: Unknown result type (might be due to invalid IL or missing references) //IL_0394: Unknown result type (might be due to invalid IL or missing references) //IL_03a6: Unknown result type (might be due to invalid IL or missing references) //IL_03ae: Unknown result type (might be due to invalid IL or missing references) //IL_03b6: Unknown result type (might be due to invalid IL or missing references) //IL_03c2: Expected O, but got Unknown //IL_057a: Unknown result type (might be due to invalid IL or missing references) //IL_0593: Unknown result type (might be due to invalid IL or missing references) //IL_05b0: Unknown result type (might be due to invalid IL or missing references) //IL_05ba: Unknown result type (might be due to invalid IL or missing references) //IL_0346: Unknown result type (might be due to invalid IL or missing references) //IL_034b: Unknown result type (might be due to invalid IL or missing references) //IL_0362: Unknown result type (might be due to invalid IL or missing references) //IL_0367: Unknown result type (might be due to invalid IL or missing references) //IL_03f3: Unknown result type (might be due to invalid IL or missing references) //IL_03fa: Expected O, but got Unknown GameObject val = new GameObject("LightningTower_NorseModel"); val.transform.SetParent(parent, false); val.layer = LayerMask.NameToLayer("piece"); Material sharedMaterial = ((Renderer)PrefabManager.Instance.GetPrefab("Copper").GetComponentInChildren<MeshRenderer>(true)).sharedMaterial; Material val2 = new Material(((Renderer)PrefabManager.Instance.GetPrefab("BlackMetal").GetComponentInChildren<MeshRenderer>(true)).sharedMaterial) { name = "LightningTower_BlackMetal" }; Shader shader = sharedMaterial.shader; if (!Object.op_Implicit((Object)(object)shader)) { throw new InvalidOperationException("Standard copper shader is unavailable."); } Material[] array = (Material[])(object)new Material[7] { new Material(sharedMaterial) { name = "LightningTower_Copper" }, new Material(sharedMaterial) { name = "LightningTower_CopperWeathered" }, new Material(sharedMaterial) { name = "LightningTower_CopperBright" }, Metal(shader, "RuneInlay", new Color(0.12f, 0.55f, 0.67f), 0.35f, 0.48f), Metal(shader, "OrbPreviewSlot", new Color(0.22f, 0.73f, 0.9f), 0.15f, 0.68f), val2, val2 }; array[3].EnableKeyword("_EMISSION"); array[3].SetColor("_EmissionColor", Color.black); using (Stream stream = Assembly.GetExecutingAssembly().GetManifestResourceStream("LightningTower.CopperSurface") ?? throw new InvalidOperationException("Embedded copper texture is missing.")) { using MemoryStream memoryStream = new MemoryStream(); stream.CopyTo(memoryStream); Texture2D val3 = new Texture2D(2, 2, (TextureFormat)4, true) { name = "LightningTower_AuthoredCopper", wrapMode = (TextureWrapMode)0 }; if (!(bool)(typeof(ImageConversion).GetMethod("LoadImage", new Type[3] { typeof(Texture2D), typeof(byte[]), typeof(bool) }) ?? throw new MissingMethodException("Unity's byte-array image loader is unavailable.")).Invoke(null, new object[3] { val3, memoryStream.ToArray(), true })) { throw new InvalidDataException("Copper texture could not be loaded."); } for (int i = 0; i < 3; i++) { array[i].mainTexture = (Texture)(object)val3; } } using Stream input = Assembly.GetExecutingAssembly().GetManifestResourceStream("LightningTower.CopperTowerMesh") ?? throw new InvalidOperationException("Embedded copper tower mesh is missing."); using BinaryReader binaryReader = new BinaryReader(input); if (Encoding.ASCII.GetString(binaryReader.ReadBytes(4)) != "LT08") { throw new InvalidDataException("Unsupported tower mesh format."); } int num = binaryReader.ReadInt32(); int num2 = 0; for (int j = 0; j < num; j++) { string text = Encoding.UTF8.GetString(binaryReader.ReadBytes(binaryReader.ReadInt32())); int num3 = binaryReader.ReadInt32(); num2 += num3; Vector3[] array2 = (Vector3[])(object)new Vector3[num3 * 3]; Vector2[] array3 = (Vector2[])(object)new Vector2[array2.Length]; List<int>[] array4 = new List<int>[array.Length]; for (int k = 0; k < array4.Length; k++) { array4[k] = new List<int>(); } for (int l = 0; l < num3; l++) { int num4 = binaryReader.ReadInt32(); for (int m = 0; m < 3; m++) { int num5 = l * 3 + m; array2[num5] = ReadVector(binaryReader); array3[num5] = new Vector2(binaryReader.ReadSingle(), binaryReader.ReadSingle()); array4[num4].Add(num5); } } Mesh val4 = new Mesh { name = "LightningTower_" + text, vertices = array2, uv = array3, subMeshCount = array.Length }; for (int n = 0; n < array4.Length; n++) { val4.SetTriangles(array4[n], n); } val4.RecalculateNormals(); val4.RecalculateBounds(); GameObject val5 = new GameObject(text); val5.layer = val.layer; val5.transform.SetParent(val.transform, false); val5.AddComponent<MeshFilter>().sharedMesh = val4; ((Renderer)val5.AddComponent<MeshRenderer>()).sharedMaterials = array; if (text == "CopperPillar") { MeshCollider obj = val5.AddComponent<MeshCollider>(); obj.sharedMesh = val4; obj.convex = true; } } int num6 = binaryReader.ReadInt32(); for (int num7 = 0; num7 < num6; num7++) { Vector3 val6 = ReadVector(binaryReader); Vector3 val7 = ReadVector(binaryReader); float num8 = binaryReader.ReadSingle(); GameObject val8 = new GameObject("ConductorCollision") { layer = val.layer }; val8.transform.SetParent(val.transform, false); val8.transform.localPosition = (val6 + val7) * 0.5f; val8.transform.localRotation = Quaternion.FromToRotation(Vector3.up, val7 - val6); CapsuleCollider obj2 = val8.AddComponent<CapsuleCollider>(); obj2.radius = num8; obj2.height = Vector3.Distance(val6, val7) + num8 * 2f; } CapsuleCollider obj3 = val.AddComponent<CapsuleCollider>(); obj3.center = Vector3.up * 4.68f; obj3.height = 1.12f; obj3.radius = 0.13f; int num9 = binaryReader.ReadInt32(); for (int num10 = 0; num10 < num9; num10++) { Transform transform = new GameObject("LightningTower_BranchTip_" + num10).transform; transform.SetParent(val.transform, false); transform.localPosition = ReadVector(binaryReader); } SphereCollider obj4 = val.AddComponent<SphereCollider>(); obj4.center = Vector3.up * 5.28f; obj4.radius = 0.34f; Plugin.Log.LogInfo((object)$"Copper concept model: {num} authored parts, {num2} authored triangles, 3 rune faces, 2 raised-rim riveted bands, {num9} crown tips, height={6f}m above / {0.45f}m below ground, orb centre={5.28f}m."); return val; } private static Vector3 ReadVector(BinaryReader reader) { //IL_0012: Unknown result type (might be due to invalid IL or missing references) return new Vector3(reader.ReadSingle(), reader.ReadSingle(), reader.ReadSingle()); } private static Material Metal(Shader shader, string name, Color color, float metallic, float smoothness) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_0017: Unknown result type (might be due to invalid IL or missing references) //IL_0018: Unknown result type (might be due to invalid IL or missing references) //IL_001e: Unknown result type (might be due to invalid IL or missing references) //IL_002a: Unknown result type (might be due to invalid IL or missing references) //IL_0038: Expected O, but got Unknown Material val = new Material(shader) { name = "LightningTower_" + name, color = color }; val.SetFloat("_Metallic", metallic); val.SetFloat("_Glossiness", smoothness); return val; } } [BepInPlugin("valheim.lightningtower", "Lightning Tower", "0.3.7")] [BepInDependency(/*Could not decode attribute arguments.*/)] [NetworkCompatibility(/*Could not decode attribute arguments.*/)] public sealed class Plugin : BaseUnityPlugin { public const string Guid = "valheim.lightningtower"; public const string Version = "0.3.7"; public const string PrefabName = "piece_lightningtower"; internal static TowerSettings Settings { get; private set; } internal static ManualLogSource Log { get; private set; } private void Awake() { Log = ((BaseUnityPlugin)this).Logger; Settings = new TowerSettings(((BaseUnityPlugin)this).Config); PrefabManager.OnVanillaPrefabsAvailable += RegisterTower; SynchronizationManager.OnConfigurationSynchronized += ConfigurationSynchronized; ((Component)this).gameObject.AddComponent<RefillClient>(); ((Component)this).gameObject.AddComponent<TargetCoordinator>(); CommandManager.Instance.AddConsoleCommand((ConsoleCommand)(object)new TowerCommand()); ((BaseUnityPlugin)this).Logger.LogInfo((object)string.Format("Lightning Tower {0} loaded. Range={1}m; capacity={2}.", "0.3.7", Settings.Range.Value, Settings.Capacity.Value)); } private void RegisterTower() { try { TowerPrefab.Register(); PrefabManager.OnVanillaPrefabsAvailable -= RegisterTower; } catch (Exception arg) { ((BaseUnityPlugin)this).Logger.LogError((object)$"Tower registration failed: {arg}"); } } private void ConfigurationSynchronized(object sender, ConfigurationSynchronizationEventArgs args) { TowerPrefab.RefreshConfiguration(); } private void OnDestroy() { PrefabManager.OnVanillaPrefabsAvailable -= RegisterTower; SynchronizationManager.OnConfigurationSynchronized -= ConfigurationSynchronized; } } internal sealed class RefillClient : MonoBehaviour { [Serializable] private sealed class Journal { public long World; public long TowerUser; public uint TowerId; public string Token = ""; public bool StoneRemoved; } private const string JournalKey = "lightningtower.pendingRefill"; private static float retryAt; internal static bool Begin(TowerBehaviour tower, Humanoid user) { //IL_0057: Unknown result type (might be due to invalid IL or missing references) //IL_00b8: Unknown result type (might be due to invalid IL or missing references) //IL_00bd: Unknown result type (might be due to invalid IL or missing references) Player val = (Player)(object)((user is Player) ? user : null); if (!Object.op_Implicit((Object)(object)val) || (Object)(object)val != (Object)(object)Player.m_localPlayer || !Object.op_Implicit((Object)(object)tower.View) || !tower.View.IsValid()) { return false; } if (Read(val) != null) { ((Character)val).Message((MessageType)2, "A refill is pending. Stay near that tower until it finishes.", 0, (Sprite)null, false); return false; } if (!PrivateArea.CheckAccess(((Component)tower).transform.position, 0f, true, false)) { return false; } if (tower.Charge >= Plugin.Settings.Capacity.Value) { ((Character)val).Message((MessageType)2, "The tower is already full.", 0, (Sprite)null, false); return false; } if (FindStone(val) == null) { ((Character)val).Message((MessageType)2, "You need one Thunder Stone.", 0, (Sprite)null, false); return false; } ZDOID uid = tower.View.GetZDO().m_uid; Journal journal = new Journal { World = ZNet.World.m_uid, TowerUser = ((ZDOID)(ref uid)).UserID, TowerId = ((ZDOID)(ref uid)).ID, Token = Guid.NewGuid().ToString("N") }; Write(val, journal); Send(tower, val, journal); return true; } private void Update() { //IL_006c: Unknown result type (might be due to invalid IL or missing references) Player localPlayer = Player.m_localPlayer; if (!Object.op_Implicit((Object)(object)localPlayer) || !Object.op_Implicit((Object)(object)ZNet.instance) || Time.unscaledTime < retryAt) { return; } retryAt = Time.unscaledTime + 1f; Journal journal = Read(localPlayer); if (journal != null && journal.World == ZNet.World.m_uid) { ZNetScene instance = ZNetScene.instance; GameObject obj = ((instance != null) ? instance.FindInstance(new ZDOID(journal.TowerUser, journal.TowerId)) : null); TowerBehaviour towerBehaviour = ((obj != null) ? obj.GetComponent<TowerBehaviour>() : null); if (Object.op_Implicit((Object)(object)towerBehaviour) && Object.op_Implicit((Object)(object)towerBehaviour.View) && towerBehaviour.View.IsValid()) { Send(towerBehaviour, localPlayer, journal); } } } private static void Send(TowerBehaviour tower, Player player, Journal journal) { //IL_0033: Unknown result type (might be due to invalid IL or missing references) retryAt = Time.unscaledTime + 1f; tower.View.InvokeRPC(journal.StoneRemoved ? "LT_Commit" : "LT_Request", new object[2] { ((Character)player).GetZDOID(), journal.Token }); } internal static void Grant(TowerBehaviour tower, long peer, string token) { //IL_004c: Unknown result type (might be due to invalid IL or missing references) Player localPlayer = Player.m_localPlayer; if (!Object.op_Implicit((Object)(object)localPlayer) || peer != tower.View.GetZDO().GetOwner()) { return; } Journal journal = Read(localPlayer); if (!Matches(tower, journal, token)) { return; } if (!journal.StoneRemoved) { ItemData val = FindStone(localPlayer); if (val == null || !PrivateArea.CheckAccess(((Component)tower).transform.position, 0f, true, false)) { localPlayer.m_customData.Remove("lightningtower.pendingRefill"); ((Character)localPlayer).Message((MessageType)2, "Refill cancelled. The tower will unlock shortly.", 0, (Sprite)null, false); return; } if (!((Humanoid)localPlayer).GetInventory().RemoveItem(val, 1)) { return; } journal.StoneRemoved = true; Write(localPlayer, journal); } Send(tower, localPlayer, journal); } internal static void Result(TowerBehaviour tower, long peer, string token, bool accepted, string message) { //IL_007b: Unknown result type (might be due to invalid IL or missing references) //IL_0080: Unknown result type (might be due to invalid IL or missing references) //IL_0085: 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) Player localPlayer = Player.m_localPlayer; if (!Object.op_Implicit((Object)(object)localPlayer) || peer != tower.View.GetZDO().GetOwner()) { return; } Journal journal = Read(localPlayer); if (!Matches(tower, journal, token)) { return; } if (!accepted && journal.StoneRemoved) { ItemData val = ObjectDB.instance.GetItemPrefab("Thunderstone").GetComponent<ItemDrop>().m_itemData.Clone(); val.m_stack = 1; if (!((Humanoid)localPlayer).GetInventory().AddItem(val)) { ItemDrop.DropItem(val, 1, ((Component)localPlayer).transform.position + Vector3.up, Quaternion.identity); } } localPlayer.m_customData.Remove("lightningtower.pendingRefill"); ((Character)localPlayer).Message((MessageType)2, message, 0, (Sprite)null, false); } private static ItemData? FindStone(Player player) { return ((IEnumerable<ItemData>)((Humanoid)player).GetInventory().GetAllItems()).FirstOrDefault((Func<ItemData, bool>)((ItemData item) => item.m_stack > 0 && Object.op_Implicit((Object)(object)item.m_dropPrefab) && ((Object)item.m_dropPrefab).name == "Thunderstone")); } private static bool Matches(TowerBehaviour tower, Journal? journal, string token) { //IL_002e: Unknown result type (might be due to invalid IL or missing references) //IL_003f: Unknown result type (might be due to invalid IL or missing references) if (journal != null && journal.Token == token && journal.World == ZNet.World.m_uid) { return tower.View.GetZDO().m_uid == new ZDOID(journal.TowerUser, journal.TowerId); } return false; } private static void Write(Player player, Journal journal) { player.m_customData["lightningtower.pendingRefill"] = JsonUtility.ToJson((object)journal); } private static Journal? Read(Player player) { if (!player.m_customData.TryGetValue("lightningtower.pendingRefill", out var value)) { return null; } try { return JsonUtility.FromJson<Journal>(value); } catch (Exception ex) { Plugin.Log.LogError((object)("Could not read pending refill. Preserve character data for recovery: " + ex.Message)); return null; } } } internal static class StormWeather { private static readonly MethodInfo SelectWeather = AccessTools.Method(typeof(EnvMan), "SelectWeightedEnvironment", (Type[])null, (Type[])null); internal static bool IsThunderstorm(Vector3 position) { //IL_01ce: Unknown result type (might be due to invalid IL or missing references) //IL_0067: Unknown result type (might be due to invalid IL or missing references) //IL_00ff: Unknown result type (might be due to invalid IL or missing references) //IL_0104: Unknown result type (might be due to invalid IL or missing references) //IL_013a: Unknown result type (might be due to invalid IL or missing references) //IL_0141: Expected O, but got Unknown //IL_015d: Unknown result type (might be due to invalid IL or missing references) //IL_0163: Unknown result type (might be due to invalid IL or missing references) //IL_0182: 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) EnvMan instance = EnvMan.instance; if ((Object)(object)instance == (Object)null || WorldGenerator.instance == null || (Object)(object)ZNet.instance == (Object)null) { return false; } if (!ZNet.instance.IsDedicated() && ZNet.instance.IsServer() && ZNet.instance.GetPeerConnections() == 0 && !string.IsNullOrEmpty(instance.m_debugEnv)) { return IsStormName(instance.m_debugEnv); } BiomeSector biomeSector = WorldGenerator.instance.GetBiomeSector(position, false); foreach (AltBiome altBiome in biomeSector.AltBiomes) { if (!string.IsNullOrEmpty(altBiome.m_forceEnvironment)) { return IsStormName(altBiome.m_forceEnvironment); } } string text = (Object.op_Implicit((Object)(object)PersistentEventSystem.instance) ? PersistentEventSystem.instance.GetEnvironmentOverride() : null); if (!string.IsNullOrEmpty(text)) { return IsStormName(text); } List<EnvEntry> availableEnvironments = instance.GetAvailableEnvironments(biomeSector); if (availableEnvironments == null || availableEnvironments.Count == 0) { return false; } State state = Random.state; try { Random.InitState((int)((long)ZNet.instance.GetTimeSeconds() / Math.Max(1L, instance.m_environmentDuration))); EnvSetup val = (EnvSetup)SelectWeather.Invoke(instance, new object[1] { availableEnvironments }); foreach (EnvEntry item in availableEnvironments) { if (item.m_ashlandsOverride && WorldGenerator.IsAshlands(position.x, position.z)) { val = item.m_env; } if (item.m_deepnorthOverride && WorldGenerator.IsDeepnorth(position.x, position.z)) { val = item.m_env; } } return val != null && IsStormName(val.m_name); } finally { Random.state = state; } } private static bool IsStormName(string? name) { return string.Equals(name, "ThunderStorm", StringComparison.OrdinalIgnoreCase); } } internal static class TargetAssignment { internal static int[] Match(double[,] distances) { int length = distances.GetLength(0); int length2 = distances.GetLength(1); int num = length2 + length; int[] array = new int[length]; for (int i = 0; i < length; i++) { array[i] = -1; } if (length == 0 || length2 == 0) { return array; } double num2 = 0.0; foreach (double num3 in distances) { if (Valid(num3)) { num2 = Math.Max(num2, num3); } } double num4 = (num2 + 1.0) * (double)(length + 1); double[] array2 = new double[length + 1]; double[] array3 = new double[num + 1]; int[] array4 = new int[num + 1]; int[] array5 = new int[num + 1]; for (int l = 1; l <= length; l++) { array4[0] = l; double[] array6 = new double[num + 1]; bool[] array7 = new bool[num + 1]; for (int m = 1; m <= num; m++) { array6[m] = double.PositiveInfinity; } int num5 = 0; do { array7[num5] = true; int num6 = array4[num5]; int num7 = 0; double num8 = double.PositiveInfinity; for (int n = 1; n <= num; n++) { if (!array7[n]) { double num9 = ((n <= length2) ? distances[num6 - 1, n - 1] : num4); if (!Valid(num9)) { num9 = num4 * 2.0; } double num10 = num9 - array2[num6] - array3[n]; if (num10 < array6[n]) { array6[n] = num10; array5[n] = num5; } if (array6[n] < num8) { num8 = array6[n]; num7 = n; } } } for (int num11 = 0; num11 <= num; num11++) { if (array7[num11]) { array2[array4[num11]] += num8; array3[num11] -= num8; } else { array6[num11] -= num8; } } num5 = num7; } while (array4[num5] != 0); do { int num12 = array5[num5]; array4[num5] = array4[num12]; num5 = num12; } while (num5 != 0); } for (int num13 = 1; num13 <= length2; num13++) { if (array4[num13] != 0 && Valid(distances[array4[num13] - 1, num13 - 1])) { array[array4[num13] - 1] = num13 - 1; } } return array; } private static bool Valid(double cost) { if (cost >= 0.0 && !double.IsNaN(cost)) { return !double.IsInfinity(cost); } return false; } } internal sealed class TargetCoordinator : MonoBehaviour { private sealed class Report { internal ZDOID Tower; internal long Owner; internal float Received; internal readonly Dictionary<ZDOID, float> Distances = new Dictionary<ZDOID, float>(); } private const string ReportRpc = "LightningTower_TargetReport"; private const string GrantRpc = "LightningTower_TargetGrant"; private const string ResultRpc = "LightningTower_TargetResult"; private readonly Dictionary<ZDOID, Report> reports = new Dictionary<ZDOID, Report>(); private TargetReservations<ZDOID> reservations = new TargetReservations<ZDOID>(); private ZRoutedRpc? rpc; private float nextReport; private float nextRound; private readonly Dictionary<ZDOID, long> lastGrants = new Dictionary<ZDOID, long>(); private static readonly HashSet<TowerBehaviour> towers = new HashSet<TowerBehaviour>(); private static double Now => (double)ZNet.instance.GetTime().Ticks / 10000000.0; private static long Server { get { if (!ZNet.instance.IsServer()) { return ZNet.instance.GetServerPeer()?.m_uid ?? 0; } return ZNet.GetUID(); } } internal static void Add(TowerBehaviour tower) { towers.Add(tower); } internal static void Remove(TowerBehaviour tower) { towers.Remove(tower); } private void Update() { if (rpc != ZRoutedRpc.instance) { rpc = ZRoutedRpc.instance; reports.Clear(); reservations = new TargetReservations<ZDOID>(); lastGrants.Clear(); nextReport = 0f; nextRound = Time.time + Plugin.Settings.ScanInterval.Value; if (rpc != null) { rpc.Register<ZDOID, ZPackage>("LightningTower_TargetReport", (Action<long, ZDOID, ZPackage>)ReceiveReport); rpc.Register<ZPackage>("LightningTower_TargetGrant", (Action<long, ZPackage>)ReceiveGrant); rpc.Register<long, bool>("LightningTower_TargetResult", (Action<long, long, bool>)ReceiveResult); } } } private void LateUpdate() { if (rpc != null && Object.op_Implicit((Object)(object)ZNet.instance) && Object.op_Implicit((Object)(object)ZNetScene.instance) && Server != 0L) { if (Time.time >= nextReport) { nextReport = Time.time + Plugin.Settings.ScanInterval.Value; SendReports(); } if (ZNet.instance.IsServer() && !(Time.time < nextRound)) { nextRound = Time.time + Plugin.Settings.ScanInterval.Value; AssignRound(); } } } private void SendReports() { //IL_0078: Unknown result type (might be due to invalid IL or missing references) //IL_007f: Expected O, but got Unknown //IL_009e: Unknown result type (might be due to invalid IL or missing references) //IL_00b0: Unknown result type (might be due to invalid IL or missing references) //IL_00b7: Unknown result type (might be due to invalid IL or missing references) //IL_00f7: Unknown result type (might be due to invalid IL or missing references) Character[] source = Character.GetAllCharacters().Where(TowerBehaviour.Eligible).ToArray(); TowerBehaviour[] array = towers.ToArray(); foreach (TowerBehaviour towerBehaviour in array) { if (!Object.op_Implicit((Object)(object)towerBehaviour) || !towerBehaviour.CanFire()) { continue; } Character[] array2 = source.Where(towerBehaviour.CanHit).ToArray(); if (array2.Length != 0) { ZPackage val = new ZPackage(); val.Write(array2.Length); Character[] array3 = array2; foreach (Character val2 in array3) { val.Write(val2.GetZDOID()); val.Write(Vector3.Distance(((Component)towerBehaviour).transform.position, val2.GetCenterPoint())); } rpc.InvokeRoutedRPC(Server, "LightningTower_TargetReport", new object[2] { towerBehaviour.View.GetZDO().m_uid, val }); } } } private void ReceiveReport(long sender, ZDOID tower, ZPackage package) { //IL_000c: Unknown result type (might be due to invalid IL or missing references) //IL_001c: Unknown result type (might be due to invalid IL or missing references) //IL_001d: 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_0053: Unknown result type (might be due to invalid IL or missing references) //IL_009c: 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_0086: Unknown result type (might be due to invalid IL or missing references) if (!ZNet.instance.IsServer() || !ValidTower(tower, sender)) { return; } Report report = new Report { Tower = tower, Owner = sender, Received = Time.time }; int num = package.ReadInt(); if (num < 0 || num > 4096) { return; } for (int i = 0; i < num; i++) { ZDOID val = package.ReadZDOID(); float num2 = package.ReadSingle(); if (num2 >= 0f && num2 <= Plugin.Settings.Range.Value && ValidTarget(val)) { report.Distances[val] = num2; } } reports[tower] = report; } private void AssignRound() { //IL_0090: Unknown result type (might be due to invalid IL or missing references) //IL_01c5: Unknown result type (might be due to invalid IL or missing references) //IL_0227: Unknown result type (might be due to invalid IL or missing references) //IL_0232: Unknown result type (might be due to invalid IL or missing references) //IL_0254: Unknown result type (might be due to invalid IL or missing references) //IL_0289: Unknown result type (might be due to invalid IL or missing references) //IL_0290: Expected O, but got Unknown //IL_02a2: Unknown result type (might be due to invalid IL or missing references) //IL_02b0: Unknown result type (might be due to invalid IL or missing references) double now = Now; reservations.Expire(now); float maxAge = Mathf.Max(1f, Plugin.Settings.ScanInterval.Value * 2f); Report[] array = reports.Values.Where((Report report2) => Time.time - report2.Received > maxAge || !ValidTower(report2.Tower, report2.Owner)).ToArray(); foreach (Report report in array) { reports.Remove(report.Tower); } Report[] array2 = (from report2 in reports.Values where !reservations.TowerBusy(report2.Tower) orderby ((ZDOID)(ref report2.Tower)).UserID, ((ZDOID)(ref report2.Tower)).ID select report2).ToArray(); ZDOID[] array3 = (from target in array2.SelectMany((Report report2) => report2.Distances.Keys).Distinct() where !reservations.TargetBusy(target) && ValidTarget(target) orderby ((ZDOID)(ref target)).UserID, ((ZDOID)(ref target)).ID select target).ToArray(); double[,] array4 = new double[array2.Length, array3.Length]; for (int num2 = 0; num2 < array2.Length; num2++) { for (int num3 = 0; num3 < array3.Length; num3++) { array4[num2, num3] = (array2[num2].Distances.TryGetValue(array3[num3], out var value) ? ((double)value) : double.PositiveInfinity); } } int[] array5 = TargetAssignment.Match(array4); List<TargetReservations<ZDOID>.Lease> list = new List<TargetReservations<ZDOID>.Lease>(); for (int num4 = 0; num4 < array2.Length; num4++) { if (array5[num4] >= 0) { TargetReservations<ZDOID>.Lease lease = reservations.Reserve(array2[num4].Tower, array3[array5[num4]], array2[num4].Owner, now); if (lease != null) { reports.Remove(lease.Tower); list.Add(lease); } } } foreach (TargetReservations<ZDOID>.Lease item in list) { ZPackage val = new ZPackage(); val.Write(item.Id); val.Write(item.Tower); val.Write(item.Target); val.Write(item.Deadline); rpc.InvokeRoutedRPC(item.Owner, "LightningTower_TargetGrant", new object[1] { val }); } } private void ReceiveGrant(long sender, ZPackage package) { //IL_0011: Unknown result type (might be due to invalid IL or missing references) //IL_0016: Unknown result type (might be due to invalid IL or missing references) //IL_0018: Unknown result type (might be due to invalid IL or missing references) //IL_001d: 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) //IL_0049: Unknown result type (might be due to invalid IL or missing references) //IL_0055: Unknown result type (might be due to invalid IL or missing references) //IL_006e: Unknown result type (might be due to invalid IL or missing references) if (sender == Server) { long num = package.ReadLong(); ZDOID val = package.ReadZDOID(); ZDOID val2 = package.ReadZDOID(); double num2 = package.ReadDouble(); if ((!lastGrants.TryGetValue(val, out var value) || num > value) && !(Now >= num2)) { lastGrants[val] = num; GameObject obj = ZNetScene.instance.FindInstance(val); TowerBehaviour towerBehaviour = ((obj != null) ? obj.GetComponent<TowerBehaviour>() : null); GameObject obj2 = ZNetScene.instance.FindInstance(val2); Character val3 = ((obj2 != null) ? obj2.GetComponent<Character>() : null); bool flag = Object.op_Implicit((Object)(object)towerBehaviour) && Object.op_Implicit((Object)(object)val3) && towerBehaviour.TryFire(val3); rpc.InvokeRoutedRPC(Server, "LightningTower_TargetResult", new object[2] { num, flag }); } } } private void ReceiveResult(long sender, long id, bool fired) { if (ZNet.instance.IsServer()) { reservations.Complete(id, sender, fired, Now, Plugin.Settings.Cooldown.Value); } } private static bool ValidTower(ZDOID id, long owner) { //IL_0005: Unknown result type (might be due to invalid IL or missing references) ZDO zDO = ZDOMan.instance.GetZDO(id); if (zDO != null && zDO.GetPrefab() == StringExtensionMethods.GetStableHashCode("piece_lightningtower")) { return zDO.GetOwner() == owner; } return false; } internal static bool ValidTarget(ZDOID id) { //IL_0005: Unknown result type (might be due to invalid IL or missing references) ZDO zDO = ZDOMan.instance.GetZDO(id); if (zDO != null && ConfiguredTargets.Contains(zDO.GetPrefab()) && zDO.GetFloat(ZDOVars.s_health, 1f) > 0f) { return !zDO.GetBool(ZDOVars.s_tamed, false); } return false; } } internal sealed class TargetList { private readonly HashSet<int> prefabs = new HashSet<int>(); internal TargetList(string csv, Func<string, int?> resolve, Action<string> rejected) { HashSet<string> hashSet = new HashSet<string>(StringComparer.Ordinal); string[] array = csv.Split(new char[1] { ',' }); for (int i = 0; i < array.Length; i++) { string text = array[i].Trim(); if (text.Length != 0 && hashSet.Add(text)) { int? num = resolve(text); if (num.HasValue) { prefabs.Add(num.Value); } else { rejected(text); } } } } internal bool Contains(int prefab) { return prefabs.Contains(prefab); } } internal sealed class TargetReservations<TKey> where TKey : notnull { internal sealed class Lease { internal long Id; internal long Owner; internal TKey Tower; internal TKey Target; internal double Deadline; internal double Expires; internal bool Completed; } private readonly Dictionary<long, Lease> leases = new Dictionary<long, Lease>(); private readonly Dictionary<TKey, long> towers = new Dictionary<TKey, long>(); private readonly Dictionary<TKey, long> targets = new Dictionary<TKey, long>(); private long sequence; internal bool TowerBusy(TKey tower) { return towers.ContainsKey(tower); } internal bool TargetBusy(TKey target) { return targets.ContainsKey(target); } internal Lease? Reserve(TKey tower, TKey target, long owner, double now) { Expire(now); if (TowerBusy(tower) || TargetBusy(target)) { return null; } Lease lease = new Lease { Id = ++sequence, Tower = tower, Target = target, Owner = owner, Deadline = now + 2.0, Expires = now + 2.0 }; leases.Add(lease.Id, lease); towers.Add(tower, lease.Id); targets.Add(target, lease.Id); return lease; } internal bool Complete(long id, long owner, bool fired, double now, double cooldown) { Expire(now); if (!leases.TryGetValue(id, out Lease value) || value.Owner != owner || value.Completed) { return false; } if (!fired) { Remove(value); } else { value.Completed = true; value.Expires = now + Math.Max(0.1, cooldown); } return true; } internal void Expire(double now) { Lease[] array = leases.Values.Where((Lease lease2) => now >= lease2.Expires).ToArray(); foreach (Lease lease in array) { Remove(lease); } } private void Remove(Lease lease) { leases.Remove(lease.Id); towers.Remove(lease.Tower); targets.Remove(lease.Target); } } public sealed class TowerBehaviour : MonoBehaviour, Hoverable, Interactable { internal const string ChargeKey = "lightningtower.charge"; private const string ShotKey = "lightningtower.nextShot"; private const string StormKey = "lightningtower.nextStorm"; private float nextScan; private float nextWeatherCheck; private bool storm; private bool owned; private TowerVisuals visuals; private static readonly int OcclusionMask = LayerMask.GetMask(new string[6] { "Default", "static_solid", "Default_small", "piece", "terrain", "vehicle" }); internal ZNetView View { get; private set; } internal int Charge { get { if (!Object.op_Implicit((Object)(object)View) || !View.IsValid()) { return 0; } return ChargeRules.Clamp(View.GetZDO().GetInt("lightningtower.charge", 0), Plugin.Settings.Capacity.Value); } } internal Vector3 Tip => visuals.Tip; private void Awake() { //IL_0042: Unknown result type (might be due to invalid IL or missing references) //IL_0067: Unknown result type (might be due to invalid IL or missing references) //IL_0071: Unknown result type (might be due to invalid IL or missing references) View = ((Component)this).GetComponent<ZNetView>(); if (!Object.op_Implicit((Object)(object)View) || !View.IsValid() || !Object.op_Implicit((Object)(object)ZNetScene.instance) || (Object)(object)ZNetScene.instance.FindInstance(View.GetZDO().m_uid) != (Object)(object)((Component)this).gameObject) { ((Behaviour)this).enabled = false; return; } ((Component)this).transform.localScale = Vector3.one * TowerGeometry.Scale; visuals = ((Component)this).GetComponent<TowerVisuals>(); View.Register<Vector3, Vector3>("LT_Fire", (Action<long, Vector3, Vector3>)ReceiveFire); TowerRefill.Register(this);