Decompiled source of FireworksShow v0.9.3
plugins/FireworksShow.dll
Decompiled a day ago
The result has been truncated due to the large size, download it to view full contents!
using System; using System.Collections; using System.Collections.Generic; using System.Diagnostics; using System.Globalization; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using System.Security; using System.Security.Permissions; using BepInEx; using BepInEx.Configuration; using BepInEx.Logging; using FireworksShow.UI; using Microsoft.CodeAnalysis; using Photon.Pun; using UnityEngine; using Zorro.Core; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: TargetFramework(".NETFramework,Version=v4.8.1", FrameworkDisplayName = ".NET Framework 4.8.1")] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("0.0.0.0")] [module: UnverifiableCode] [module: RefSafetyRules(11)] namespace Microsoft.CodeAnalysis { [CompilerGenerated] [Embedded] internal sealed class EmbeddedAttribute : Attribute { } } namespace System.Runtime.CompilerServices { [CompilerGenerated] [Embedded] [AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)] internal sealed class RefSafetyRulesAttribute : Attribute { public readonly int Version; public RefSafetyRulesAttribute(int P_0) { Version = P_0; } } } namespace FireworksShow { public class ContinuousRunner { private readonly FireworkLauncher _launcher; private readonly Queue<GameObject> _pacingQueue = new Queue<GameObject>(); private float _nextContinuousTime; private bool _pacingPumping; private bool _continuousRunning; public bool Running => _continuousRunning; public ContinuousRunner(FireworkLauncher launcher) { _launcher = launcher; } public void Toggle() { if (!ModConfig.ContinuousEnabled.Value) { _launcher.ShowNotice(Lang.L("连续烟花未启用", "Continuous fireworks disabled")); return; } _continuousRunning = !_continuousRunning; _nextContinuousTime = 0f; ResetPacing(); _launcher.ShowNotice(_continuousRunning ? Lang.L("连续烟花:开始", "Continuous: started") : Lang.L("连续烟花:停止", "Continuous: stopped")); } public void Stop() { _continuousRunning = false; } public void Update(bool handleToggle) { //IL_001c: Unknown result type (might be due to invalid IL or missing references) if (!ModConfig.ContinuousEnabled.Value) { _continuousRunning = false; return; } if (handleToggle && Pressed(ModConfig.ContinuousKey.Value)) { Toggle(); } if (_continuousRunning) { if (ModConfig.PacingEnabled.Value) { HandlePaced(); } else { HandleDirect(); } } } public void EnqueuePaced(GameObject go) { if ((Object)(object)go != (Object)null) { _pacingQueue.Enqueue(go); } } private void HandleDirect() { //IL_003a: 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) if (_pacingPumping) { ResetPacing(); } if (_launcher.CanSpawn() && !(Time.time < _nextContinuousTime)) { Character localCharacter = Character.localCharacter; if (!((Object)(object)localCharacter == (Object)null) && FireworkPointPicker.TryFindContinuousPoint(localCharacter.Center, _launcher.ActivePoints, out var point)) { TickRate(); _launcher.StartSpawn(point, ModConfig.LightDelay.Value, paced: false); } } } private void HandlePaced() { //IL_0046: 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) if (!_pacingPumping) { ((MonoBehaviour)_launcher).StartCoroutine(PacingPump()); } if (_launcher.CanSpawn() && !(Time.time < _nextContinuousTime)) { Character localCharacter = Character.localCharacter; if (!((Object)(object)localCharacter == (Object)null) && FireworkPointPicker.TryFindContinuousPoint(localCharacter.Center, _launcher.ActivePoints, out var point)) { TickRate(); _launcher.StartSpawn(point, -1f, paced: true); } } } private void TickRate() { float num = Mathf.Max(0.1f, ModConfig.ContinuousRate.Value); _nextContinuousTime = Time.time + 1f / num; } private IEnumerator PacingPump() { if (_pacingPumping) { yield break; } _pacingPumping = true; float interval = Mathf.Max(0.05f, ModConfig.BlossomInterval.Value); int groupSize = Mathf.Clamp(ModConfig.SimultaneousCount.Value, 1, 30); float num = Mathf.Max(0f, ModConfig.LightDelay.Value); if (num > 0f) { yield return (object)new WaitForSeconds(num); } while (_continuousRunning && ModConfig.Enabled.Value && ModConfig.ContinuousEnabled.Value) { for (int i = 0; i < groupSize; i++) { while (_pacingQueue.Count > 0 && (Object)(object)_pacingQueue.Peek() == (Object)null) { _pacingQueue.Dequeue(); } if (_pacingQueue.Count == 0) { break; } GameObject val = _pacingQueue.Dequeue(); if (!((Object)(object)val == (Object)null)) { Rocketpack component = val.GetComponent<Rocketpack>(); if (!((Object)(object)component == (Object)null) && !((Object)(object)component.view == (Object)null)) { component.Light(); } } } yield return (object)new WaitForSeconds(interval); } _pacingPumping = false; ResetPacing(); } private void ResetPacing() { _pacingPumping = false; while (_pacingQueue.Count > 0) { GameObject val = _pacingQueue.Dequeue(); if (!((Object)(object)val == (Object)null)) { Rocketpack component = val.GetComponent<Rocketpack>(); if (!((Object)(object)component == (Object)null) && !((Object)(object)component.view == (Object)null)) { component.Light(); } } } } private static bool Pressed(KeyCode key) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0003: Unknown result type (might be due to invalid IL or missing references) if ((int)key != 0) { return Input.GetKeyDown(key); } return false; } } public enum SpawnCategory { Normal, Heart, Pattern } public class FireworkLauncher : MonoBehaviour { private struct SpawnedItem { public GameObject go; public Vector3 point; public SpawnCategory category; public int spawnMode; } private readonly List<SpawnedItem> _items = new List<SpawnedItem>(); private readonly List<Vector3> _activePoints = new List<Vector3>(); private ShowScheduler _scheduler; private float _nextClickTime; private string _noticeText; private float _noticeUntil; private GUIStyle _noticeStyle; private const float KeepLitInterval = 2f; public static FireworkLauncher Instance { get; private set; } public ContinuousRunner Continuous { get; private set; } public int ActiveCount { get { int num = 0; for (int i = 0; i < _items.Count; i++) { if (_items[i].spawnMode == 0) { num++; } } return num; } } public bool ContinuousRunning { get { if (Continuous != null) { return Continuous.Running; } return false; } } public IList<Vector3> ActivePoints => _activePoints; public float SetupDelay => Mathf.Max(0f, ModConfig.LightDelay.Value); public int HeartCount => CountCategory(SpawnCategory.Heart); public int PatternCount => CountCategory(SpawnCategory.Pattern); private void Awake() { Instance = this; Continuous = new ContinuousRunner(this); _scheduler = new ShowScheduler(this); ((MonoBehaviour)this).StartCoroutine(KeepLitRoutine()); } private void Update() { //IL_0042: Unknown result type (might be due to invalid IL or missing references) //IL_0059: 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) PruneSpawned(); if (!ModConfig.Enabled.Value) { Continuous.Stop(); _noticeUntil = 0f; return; } if (FireworksPanel.IsOpen) { Continuous.Update(handleToggle: false); return; } if (Pressed(ModConfig.Hotkey.Value)) { TrySpawnBatch(); } if (Pressed(ModConfig.HeartKey.Value)) { TrySpawnHeart(); } if (Pressed(ModConfig.SquirtleKey.Value) && ModConfig.SquirtleEnabled.Value) { TrySpawnSquirtle(); } Continuous.Update(handleToggle: true); HandleMiddleClick(); } private void OnGUI() { //IL_008b: Unknown result type (might be due to invalid IL or missing references) //IL_0090: Unknown result type (might be due to invalid IL or missing references) //IL_0095: 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_00b4: 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_002e: 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_003a: 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_004e: Expected O, but got Unknown //IL_0059: Unknown result type (might be due to invalid IL or missing references) if (!(Time.time >= _noticeUntil) && !string.IsNullOrEmpty(_noticeText)) { if (_noticeStyle == null) { _noticeStyle = new GUIStyle(GUI.skin.label) { alignment = (TextAnchor)4, fontSize = 28, fontStyle = (FontStyle)1 }; _noticeStyle.normal.textColor = Color.white; } float num = 420f; float num2 = 60f; Rect val = new Rect(((float)Screen.width - num) * 0.5f, (float)Screen.height * 0.12f, num, num2); Color color = GUI.color; GUI.color = new Color(0f, 0f, 0f, 0.6f); GUI.DrawTexture(val, (Texture)(object)Texture2D.whiteTexture); GUI.color = color; GUI.Label(val, _noticeText, _noticeStyle); } } public void TrySpawnBatch() { //IL_0049: 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) if (!PhotonNetwork.InRoom) { Plugin.Log.LogInfo((object)"未进入房间,无法释放烟花。"); return; } Character localCharacter = Character.localCharacter; if ((Object)(object)localCharacter == (Object)null) { return; } int num = Mathf.Clamp(ModConfig.Count.Value, 1, 30); int num2 = 0; for (int i = 0; i < num; i++) { if (!HasBudget()) { break; } if (FireworkPointPicker.TryFindBatchPoint(localCharacter.Center, _activePoints, out var point)) { float startDelay = (float)i * Mathf.Max(0f, ModConfig.BatchInterval.Value); StartSpawn(point, startDelay, paced: false); num2++; } } if (num2 == 0) { Plugin.Log.LogInfo((object)"附近没有合适的露天位置,烟花未释放。"); } } public void TrySpawnHeart() { //IL_005e: Unknown result type (might be due to invalid IL or missing references) if (!PhotonNetwork.InRoom) { Plugin.Log.LogInfo((object)"未进入房间,无法释放烟花。"); return; } Character localCharacter = Character.localCharacter; if ((Object)(object)localCharacter == (Object)null) { return; } int count = Mathf.Clamp(Mathf.RoundToInt(24f * ((float)ModConfig.HeartDensity.Value / 45f) * (ModConfig.HeartSize.Value / 12f)), 8, 120); Vector3[] array = ShowcaseLayout.BuildHeartPoints(localCharacter.Center, ModConfig.HeartSize.Value, count); if (array.Length == 0) { return; } int num = Mathf.Clamp(ModConfig.PatternSpawnMode.Value, 0, 2); if (num == 0) { float interval = Mathf.Max(0f, ModConfig.HeartInterval.Value); float[] array2 = ShowcaseLayout.OrderHeartDelays(array, ModConfig.HeartOrder.Value, interval); float setupDelay = SetupDelay; for (int i = 0; i < array2.Length; i++) { array2[i] += setupDelay; } ((MonoBehaviour)this).StartCoroutine(_scheduler.RunSimultaneous(array, array2, 0, SpawnCategory.Heart)); ShowNotice(Lang.L("心形礼花:准备绽放", "Heart: blooming")); } else { ((MonoBehaviour)this).StartCoroutine(_scheduler.RunDisplay(array, num, SpawnCategory.Heart)); ShowNotice(Lang.L("心形礼花:已生成图案", "Heart: pattern placed")); } } public void TrySpawnSquirtle() { //IL_002a: Unknown result type (might be due to invalid IL or missing references) if (!PhotonNetwork.InRoom) { Plugin.Log.LogInfo((object)"未进入房间,无法释放烟花。"); return; } Character localCharacter = Character.localCharacter; if (!((Object)(object)localCharacter == (Object)null)) { ((MonoBehaviour)this).StartCoroutine(PatternRoutine(localCharacter.Center)); } } private IEnumerator PatternRoutine(Vector3 center) { //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) int pattern = Mathf.Clamp(ModConfig.SquirtlePattern.Value, 0, PatternCatalog.Names.Length - 1); float num = Mathf.Max(10f, ModConfig.SquirtleWidth.Value); int num2 = Mathf.Clamp(ModConfig.SquirtleDensity.Value, 10, 120); int num3 = Mathf.Clamp(Mathf.RoundToInt(213f * ((float)num2 / 45f) * (num / 45f)), 40, 400); List<Vector3>[] array = PatternCatalog.Build(pattern, num3); if (array == null || array.Length == 0) { ShowNotice(Lang.L("图案烟花点数太少", "Pattern has too few points")); yield break; } List<Vector3>[] array2 = ShowcaseLayout.BuildTextPointGroups(array, center, num, ModConfig.SquirtleDistance.Value, ModConfig.SquirtleHeightOffset.Value); if (array2 == null || array2.Length == 0) { ShowNotice(Lang.L("图案烟花点数太少", "Pattern has too few points")); yield break; } int num4 = Mathf.Clamp(ModConfig.PatternSpawnMode.Value, 0, 2); string text = PatternCatalog.LocalizedName(pattern); if (num4 != 0) { int num5 = 0; for (int i = 0; i < array2.Length; i++) { num5 += array2[i].Count; } Vector3[] array3 = (Vector3[])(object)new Vector3[num5]; int num6 = 0; foreach (List<Vector3> list in array2) { for (int k = 0; k < list.Count; k++) { array3[num6++] = list[k]; } } ((MonoBehaviour)this).StartCoroutine(_scheduler.RunDisplay(array3, num4, SpawnCategory.Pattern)); ShowNotice(Lang.L("图案烟花:", "Pattern: ") + text + Lang.L("(展示)", " (display)")); yield break; } float num7 = Mathf.Clamp(1f / (float)num2, 0.012f, 0.12f); float num8 = 0.6f; int num9 = 0; for (int l = 0; l < array2.Length; l++) { num9 += array2[l].Count; } Vector3[] array4 = (Vector3[])(object)new Vector3[num9]; float[] array5 = new float[num9]; int num10 = 0; float num11 = 0f; foreach (List<Vector3> list2 in array2) { for (int n = 0; n < list2.Count; n++) { array4[num10] = list2[n]; array5[num10] = num11 + (float)n * num7; num10++; } num11 += (float)Mathf.Max(1, list2.Count) * num7 + num8; } int concurrentCap = Mathf.Clamp(num3, 40, 300); ((MonoBehaviour)this).StartCoroutine(_scheduler.RunRolling(array4, array5, concurrentCap, 0, SpawnCategory.Pattern)); ShowNotice(Lang.L("图案烟花:", "Pattern: ") + text); } public void LaunchFirework(Vector3 point, float startDelay) { //IL_0011: Unknown result type (might be due to invalid IL or missing references) if (PhotonNetwork.InRoom && HasBudget()) { StartSpawn(point, startDelay, paced: false); } } public void ToggleContinuous() { Continuous.Toggle(); } public void ShowNotice(string text) { _noticeText = text; _noticeUntil = Time.time + 2f; } private void PruneSpawned() { for (int num = _items.Count - 1; num >= 0; num--) { if ((Object)(object)_items[num].go == (Object)null) { _items.RemoveAt(num); if (num < _activePoints.Count) { _activePoints.RemoveAt(num); } } } while (_activePoints.Count > _items.Count) { _activePoints.RemoveAt(_activePoints.Count - 1); } } private void RegisterSpawned(GameObject go, Vector3 point, bool paced, SpawnCategory category, int spawnMode) { //IL_0018: Unknown result type (might be due to invalid IL or missing references) //IL_0019: Unknown result type (might be due to invalid IL or missing references) //IL_003c: Unknown result type (might be due to invalid IL or missing references) _items.Add(new SpawnedItem { go = go, point = point, category = category, spawnMode = spawnMode }); _activePoints.Add(point); if (paced && (Object)(object)go != (Object)null && (Object)(object)go.GetComponent<Rocketpack>() != (Object)null && (Object)(object)go.GetComponent<PhotonView>() != (Object)null) { Continuous.EnqueuePaced(go); } } private bool HasBudget() { return ActiveCount < ModConfig.MaxConcurrent.Value; } public bool CanSpawn() { if (PhotonNetwork.InRoom) { return HasBudget(); } return false; } private static bool Pressed(KeyCode key) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0003: Unknown result type (might be due to invalid IL or missing references) if ((int)key != 0) { return Input.GetKeyDown(key); } return false; } private void HandleMiddleClick() { //IL_0056: Unknown result type (might be due to invalid IL or missing references) if (ModConfig.MiddleClickEnabled.Value && Input.GetMouseButton(2) && !(Time.time < _nextClickTime) && CanSpawn() && FireworkPointPicker.TryGetAimPoint(out var point)) { _nextClickTime = Time.time + Mathf.Max(0.02f, ModConfig.Interval.Value); StartSpawn(point, 0f, paced: false); } } public void StartSpawn(Vector3 point, float startDelay, bool paced, float lightDelayOverride = -1f, int spawnMode = 0, SpawnCategory category = SpawnCategory.Normal) { //IL_0002: Unknown result type (might be due to invalid IL or missing references) ((MonoBehaviour)this).StartCoroutine(SpawnRoutine(point, startDelay, paced, lightDelayOverride, spawnMode, category)); } private IEnumerator SpawnRoutine(Vector3 point, float startDelay, bool paced, float lightDelayOverride, int spawnMode, SpawnCategory category) { //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) if (startDelay > 0f) { yield return (object)new WaitForSeconds(startDelay); } if (!PhotonNetwork.InRoom) { yield break; } string text = FireworkPrefabRegistry.ResolvePrefabPath(); if (string.IsNullOrEmpty(text)) { yield break; } GameObject spawned; try { spawned = PhotonNetwork.Instantiate(text, point, Quaternion.identity, (byte)0, (object[])null); } catch (Exception ex) { Plugin.Log.LogWarning((object)("生成烟花失败:" + ex.Message)); yield break; } if ((Object)(object)spawned == (Object)null) { yield break; } Rocketpack rocket = spawned.GetComponent<Rocketpack>(); if ((Object)(object)rocket == (Object)null) { Plugin.Log.LogWarning((object)"生成物不包含 Rocketpack 组件,已销毁。"); PhotonNetwork.Destroy(spawned); yield break; } if ((Object)(object)rocket.backpack != (Object)null) { ((Item)rocket.backpack).blockInteraction = true; if ((Object)(object)((Item)rocket.backpack).rig != (Object)null) { ((Item)rocket.backpack).rig.isKinematic = true; } } RegisterSpawned(spawned, point, paced, category, spawnMode); if (paced) { yield break; } switch (spawnMode) { case 1: yield break; case 2: { float num = ((lightDelayOverride >= 0f) ? lightDelayOverride : Mathf.Max(0.15f, ModConfig.LightDelay.Value)); if (num > 0f) { yield return (object)new WaitForSeconds(num); } if (!((Object)(object)spawned == (Object)null)) { if ((Object)(object)rocket.view != (Object)null) { rocket.view.RPC("RPCLightRocket", (RpcTarget)0, Array.Empty<object>()); } if ((Object)(object)rocket.rocketFX != (Object)null) { rocket.rocketFX.RocketLight(0f); } } yield break; } } float num2 = ((lightDelayOverride >= 0f) ? lightDelayOverride : Mathf.Max(0f, ModConfig.LightDelay.Value)); if (num2 > 0f) { yield return (object)new WaitForSeconds(num2); } if (!((Object)(object)spawned == (Object)null)) { if ((Object)(object)rocket.view == (Object)null) { Plugin.Log.LogWarning((object)"火箭背包缺少 PhotonView,无法同步点燃。"); } else { rocket.Light(); } } } private int CountCategory(SpawnCategory cat) { int num = 0; for (int i = 0; i < _items.Count; i++) { if ((Object)(object)_items[i].go != (Object)null && _items[i].category == cat) { num++; } } return num; } public void LightCategory(SpawnCategory cat) { if (!PhotonNetwork.InRoom) { return; } int num = 0; for (int i = 0; i < _items.Count; i++) { SpawnedItem value = _items[i]; if (!((Object)(object)value.go == (Object)null) && value.category == cat) { Rocketpack component = value.go.GetComponent<Rocketpack>(); if (!((Object)(object)component == (Object)null) && !((Object)(object)component.view == (Object)null)) { value.spawnMode = 0; _items[i] = value; component.Light(); num++; } } } if (num > 0) { ShowNotice(Lang.L("已点燃 ", "Lit ") + num + Lang.L(" 枚", " items")); } } public void DeleteCategory(SpawnCategory cat) { int num = DestroyWhere((SpawnedItem it) => it.category == cat); if (num > 0) { ShowNotice(Lang.L("已删除 ", "Deleted ") + num + Lang.L(" 枚", " items")); } } public void DeleteAll() { int num = DestroyWhere((SpawnedItem _) => true); if (num > 0) { ShowNotice(Lang.L("已删除全部 ", "Deleted all ") + num + Lang.L(" 枚", " items")); } } private int DestroyWhere(Predicate<SpawnedItem> predicate) { int num = 0; for (int i = 0; i < _items.Count; i++) { if (predicate(_items[i]) && TryDestroy(_items[i].go)) { num++; } } PruneSpawned(); return num; } private static bool TryDestroy(GameObject go) { if ((Object)(object)go == (Object)null) { return false; } PhotonView component = go.GetComponent<PhotonView>(); if ((Object)(object)component == (Object)null) { return false; } if (!component.IsMine && !PhotonNetwork.IsMasterClient) { return false; } try { PhotonNetwork.Destroy(go); return true; } catch (Exception ex) { Plugin.Log.LogWarning((object)("删除火箭背包失败:" + ex.Message)); return false; } } private IEnumerator KeepLitRoutine() { WaitForSeconds wait = new WaitForSeconds(2f); while (true) { yield return wait; if (!PhotonNetwork.InRoom) { continue; } for (int i = 0; i < _items.Count; i++) { if ((Object)(object)_items[i].go == (Object)null || _items[i].spawnMode != 2) { continue; } Rocketpack component = _items[i].go.GetComponent<Rocketpack>(); if (!((Object)(object)component == (Object)null) && !((Object)(object)component.view == (Object)null)) { component.view.RPC("RPCLightRocket", (RpcTarget)0, Array.Empty<object>()); if ((Object)(object)component.rocketFX != (Object)null) { component.rocketFX.RocketLight(0f); } } } } } } internal static class FireworkPointPicker { private static int _cachedSegment = int.MinValue; private static Bounds _segmentBounds; private static bool _haveSegmentBounds; public static bool HasPointClearance(Vector3 point, IList<Vector3> activePoints) { //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_003c: Unknown result type (might be due to invalid IL or missing references) float value = ModConfig.MinSpawnDistance.Value; if (value <= 0f || activePoints == null || activePoints.Count == 0) { return true; } float num = value * value; int count = activePoints.Count; for (int i = 0; i < count; i++) { Vector3 val = activePoints[i] - point; if (((Vector3)(ref val)).sqrMagnitude < num) { return false; } } return true; } private static bool IsPointUsable(Vector3 candidate, Vector3 anchor, float clearance, bool needLos, bool needSky, float skyHeight) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0005: 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_0010: 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_0024: 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_003b: Unknown result type (might be due to invalid IL or missing references) LayerMask terrainMapMask = HelperFunctions.terrainMapMask; if (clearance > 0f && Physics.CheckSphere(candidate, clearance, LayerMask.op_Implicit(terrainMapMask), (QueryTriggerInteraction)1)) { return false; } RaycastHit val = default(RaycastHit); if (needLos && Physics.Linecast(anchor, candidate, ref val, LayerMask.op_Implicit(terrainMapMask), (QueryTriggerInteraction)1)) { return false; } if (needSky && !IsOpenSky(candidate, skyHeight)) { return false; } return true; } private static bool IsOpenSky(Vector3 point, float checkHeight) { //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_0013: Unknown result type (might be due to invalid IL or missing references) if (checkHeight <= 0f) { return true; } RaycastHit val = default(RaycastHit); return !Physics.Raycast(point, Vector3.up, ref val, checkHeight, LayerMask.op_Implicit(HelperFunctions.terrainMapMask), (QueryTriggerInteraction)1); } public static bool TryFindBatchPoint(Vector3 anchor, IList<Vector3> activePoints, out Vector3 point) { //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_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_0095: 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: 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_00b0: Unknown result type (might be due to invalid IL or missing references) //IL_00b5: Unknown result type (might be due to invalid IL or missing references) //IL_00ba: Unknown result type (might be due to invalid IL or missing references) //IL_00c0: Unknown result type (might be due to invalid IL or missing references) //IL_00c5: Unknown result type (might be due to invalid IL or missing references) //IL_00ca: Unknown result type (might be due to invalid IL or missing references) //IL_00cc: Unknown result type (might be due to invalid IL or missing references) //IL_00ce: Unknown result type (might be due to invalid IL or missing references) //IL_00dd: Unknown result type (might be due to invalid IL or missing references) //IL_00e8: Unknown result type (might be due to invalid IL or missing references) //IL_00ea: Unknown result type (might be due to invalid IL or missing references) point = Vector3.zero; int num = Mathf.Clamp(ModConfig.RingCount.Value, 1, 10); float num2 = Mathf.Max(1f, ModConfig.Radius.Value); float num3 = Mathf.Max(1f, ModConfig.Height.Value); float value = ModConfig.Clearance.Value; bool value2 = ModConfig.RequireLineOfSight.Value; bool value3 = ModConfig.RequireOpenSky.Value; float value4 = ModConfig.SkyCheckHeight.Value; for (int i = 0; i < 12; i++) { int num4 = Random.Range(0, num); float num5 = num2 * (float)(num4 + 1); Vector2 val = RandomDir(); Vector3 val2 = anchor + new Vector3(val.x, 0f, val.y) * num5 + Vector3.up * num3; if (IsPointUsable(val2, anchor, value, value2, value3, value4) && HasPointClearance(val2, activePoints)) { point = val2; return true; } } return false; } public static bool TryFindContinuousPoint(Vector3 anchor, IList<Vector3> activePoints, out Vector3 point) { //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_0083: Unknown result type (might be due to invalid IL or missing references) //IL_0088: 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_00a5: Unknown result type (might be due to invalid IL or missing references) //IL_00b1: 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_00bf: Unknown result type (might be due to invalid IL or missing references) //IL_00c4: 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_00cf: Unknown result type (might be due to invalid IL or missing references) //IL_00d4: Unknown result type (might be due to invalid IL or missing references) //IL_00d9: 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_00dd: Unknown result type (might be due to invalid IL or missing references) //IL_00ec: 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) //IL_00f9: Unknown result type (might be due to invalid IL or missing references) point = Vector3.zero; float num = Mathf.Max(0f, ModConfig.ContinuousInnerRadius.Value); float num2 = Mathf.Max(num + 0.1f, ModConfig.ContinuousOuterRadius.Value); float num3 = Mathf.Max(1f, ModConfig.Height.Value); float value = ModConfig.Clearance.Value; bool value2 = ModConfig.RequireLineOfSight.Value; bool value3 = ModConfig.RequireOpenSky.Value; float value4 = ModConfig.SkyCheckHeight.Value; for (int i = 0; i < 12; i++) { Vector2 val = RandomDir(); float num4 = Mathf.Sqrt(Random.Range(num * num / (num2 * num2), 1f)) * num2; Vector3 val2 = anchor + new Vector3(val.x, 0f, val.y) * num4 + Vector3.up * num3; if (IsPointUsable(val2, anchor, value, value2, value3, value4) && HasPointClearance(val2, activePoints)) { point = val2; return true; } } return false; } public static bool TryGetAimPoint(out Vector3 point) { //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_001c: Unknown result type (might be due to invalid IL or missing references) //IL_0022: Invalid comparison between Unknown and I4 //IL_0048: Unknown result type (might be due to invalid IL or missing references) //IL_0024: Unknown result type (might be due to invalid IL or missing references) //IL_004d: Unknown result type (might be due to invalid IL or missing references) //IL_004f: Unknown result type (might be due to invalid IL or missing references) //IL_0050: 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_006f: Unknown result type (might be due to invalid IL or missing references) //IL_0073: 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_009c: Unknown result type (might be due to invalid IL or missing references) //IL_00a1: Unknown result type (might be due to invalid IL or missing references) //IL_00a6: Unknown result type (might be due to invalid IL or missing references) point = Vector3.zero; Camera main = Camera.main; if ((Object)(object)main == (Object)null) { return false; } Vector3 val = (Vector3)(((int)Cursor.lockState == 1) ? new Vector3((float)Screen.width * 0.5f, (float)Screen.height * 0.5f, 0f) : Input.mousePosition); Ray val2 = main.ScreenPointToRay(val); float num = Mathf.Max(1f, ModConfig.RayDistance.Value); LayerMask terrainMapMask = HelperFunctions.terrainMapMask; RaycastHit val3 = default(RaycastHit); if (!Physics.Raycast(val2, ref val3, num, LayerMask.op_Implicit(terrainMapMask), (QueryTriggerInteraction)1)) { return false; } point = ((RaycastHit)(ref val3)).point + ((RaycastHit)(ref val3)).normal * ModConfig.SurfaceOffset.Value; return true; } public static bool TryFindFestivalPoint(Vector3 anchor, IList<Vector3> activePoints, out Vector3 point) { //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_0051: Unknown result type (might be due to invalid IL or missing references) //IL_010a: Unknown result type (might be due to invalid IL or missing references) //IL_010f: Unknown result type (might be due to invalid IL or missing references) //IL_0120: Unknown result type (might be due to invalid IL or missing references) //IL_0121: Unknown result type (might be due to invalid IL or missing references) //IL_012d: Unknown result type (might be due to invalid IL or missing references) //IL_0134: Unknown result type (might be due to invalid IL or missing references) //IL_013b: Unknown result type (might be due to invalid IL or missing references) //IL_0140: Unknown result type (might be due to invalid IL or missing references) //IL_0145: Unknown result type (might be due to invalid IL or missing references) //IL_007b: 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_00a8: Unknown result type (might be due to invalid IL or missing references) //IL_00ce: Unknown result type (might be due to invalid IL or missing references) //IL_0147: Unknown result type (might be due to invalid IL or missing references) //IL_0149: Unknown result type (might be due to invalid IL or missing references) //IL_0158: Unknown result type (might be due to invalid IL or missing references) //IL_0163: Unknown result type (might be due to invalid IL or missing references) //IL_016f: Unknown result type (might be due to invalid IL or missing references) //IL_0196: Unknown result type (might be due to invalid IL or missing references) //IL_0181: Unknown result type (might be due to invalid IL or missing references) //IL_0184: Unknown result type (might be due to invalid IL or missing references) //IL_01a1: Unknown result type (might be due to invalid IL or missing references) //IL_01a3: Unknown result type (might be due to invalid IL or missing references) point = Vector3.zero; float num = Mathf.Max(20f, ModConfig.FestivalAltitude.Value); float checkHeight = Mathf.Max(num * 1.2f, ModConfig.SkyCheckHeight.Value); float value = ModConfig.Clearance.Value; bool num2 = ModConfig.FestivalScope.Value == 1; Bounds bounds = default(Bounds); bool flag = num2 && TryGetSegmentBounds(out bounds); Vector3 val = default(Vector3); Vector3 val3 = default(Vector3); for (int i = 0; i < 20; i++) { if (flag) { float num3 = Mathf.Max(1f, ((Bounds)(ref bounds)).extents.x); float num4 = Mathf.Max(1f, ((Bounds)(ref bounds)).extents.z); ((Vector3)(ref val))..ctor(((Bounds)(ref bounds)).center.x + (Random.value - 0.5f) * 2f * num3, 0f, ((Bounds)(ref bounds)).center.z + (Random.value - 0.5f) * 2f * num4); } else { float num5 = Mathf.Max(5f, ModConfig.FestivalRadius.Value); Vector2 val2 = RandomDir(); float num6 = Mathf.Sqrt(Random.value) * num5; val = anchor + new Vector3(val2.x, 0f, val2.y) * num6; } float num7 = SampleGroundY(val, anchor.y); ((Vector3)(ref val3))..ctor(val.x, num7 + num, val.z); if (IsOpenSky(val3, checkHeight) && (!(value > 0f) || !Physics.CheckSphere(val3, value, LayerMask.op_Implicit(HelperFunctions.terrainMapMask), (QueryTriggerInteraction)1)) && HasPointClearance(val3, activePoints)) { point = val3; return true; } } return false; } private static float SampleGroundY(Vector3 ground, float fallback) { //IL_0000: 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_0013: 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_0024: 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) RaycastHit val = default(RaycastHit); if (Physics.Raycast(new Vector3(ground.x, fallback + 500f, ground.z), Vector3.down, ref val, 1000f, LayerMask.op_Implicit(HelperFunctions.terrainMapMask), (QueryTriggerInteraction)1)) { return ((RaycastHit)(ref val)).point.y; } return fallback; } public static bool TryGetSegmentBounds(out Bounds bounds) { //IL_0001: 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_001c: Expected I4, but got Unknown //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_00b4: Unknown result type (might be due to invalid IL or missing references) //IL_00b9: Unknown result type (might be due to invalid IL or missing references) //IL_00ea: Unknown result type (might be due to invalid IL or missing references) //IL_00ef: Unknown result type (might be due to invalid IL or missing references) //IL_00d1: Unknown result type (might be due to invalid IL or missing references) //IL_010a: Unknown result type (might be due to invalid IL or missing references) //IL_010b: Unknown result type (might be due to invalid IL or missing references) //IL_0117: Unknown result type (might be due to invalid IL or missing references) //IL_0118: Unknown result type (might be due to invalid IL or missing references) bounds = default(Bounds); try { if (!MapHandler.Exists) { return false; } int num = (int)MapHandler.CurrentSegmentNumber; if (_haveSegmentBounds && _cachedSegment == num) { bounds = _segmentBounds; return true; } if ((Object)(object)Singleton<MapHandler>.Instance == (Object)null || Singleton<MapHandler>.Instance.segments == null) { return false; } if (num < 0 || num >= Singleton<MapHandler>.Instance.segments.Length) { return false; } GameObject segmentParent = Singleton<MapHandler>.Instance.segments[num].segmentParent; if ((Object)(object)segmentParent == (Object)null) { return false; } Renderer[] componentsInChildren = segmentParent.GetComponentsInChildren<Renderer>(true); if (componentsInChildren == null || componentsInChildren.Length == 0) { return false; } Bounds bounds2 = componentsInChildren[0].bounds; for (int i = 1; i < componentsInChildren.Length; i++) { if ((Object)(object)componentsInChildren[i] != (Object)null) { ((Bounds)(ref bounds2)).Encapsulate(componentsInChildren[i].bounds); } } Vector3 size = ((Bounds)(ref bounds2)).size; if (((Vector3)(ref size)).sqrMagnitude < 1f) { return false; } _cachedSegment = num; _segmentBounds = bounds2; _haveSegmentBounds = true; bounds = bounds2; return true; } catch { return false; } } private static Vector2 RandomDir() { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0005: 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_0014: Unknown result type (might be due to invalid IL or missing references) //IL_0019: Unknown result type (might be due to invalid IL or missing references) Vector2 val = Random.insideUnitCircle; if (((Vector2)(ref val)).sqrMagnitude < 0.0001f) { val = Vector2.right; } return ((Vector2)(ref val)).normalized; } } internal static class FireworkPrefabRegistry { private const string RocketpackResourcePath = "0_Items/Rocketpack"; private static string _resolved; private static bool _searched; public static string ResolvePrefabPath() { string text = ModConfig.PrefabName?.Value; if (!string.IsNullOrWhiteSpace(text)) { text = text.Trim(); if (!text.Contains("/")) { return "0_Items/" + text; } return text; } if (!string.IsNullOrEmpty(_resolved)) { return _resolved; } if (_searched) { return null; } _searched = true; GameObject val = Resources.Load<GameObject>("0_Items/Rocketpack"); if ((Object)(object)val != (Object)null && (Object)(object)val.GetComponent<Rocketpack>() != (Object)null) { _resolved = "0_Items/Rocketpack"; return _resolved; } GameObject[] array = Resources.LoadAll<GameObject>("0_Items"); foreach (GameObject val2 in array) { if ((Object)(object)val2 != (Object)null && (Object)(object)val2.GetComponent<Rocketpack>() != (Object)null) { _resolved = "0_Items/" + ((Object)val2).name; return _resolved; } } Plugin.Log.LogError((object)"未能自动定位火箭背包预制体,请在配置文件中手动填写「预制体名」。"); return null; } public static void Reset() { _resolved = null; _searched = false; } } internal static class ModConfig { public static ConfigEntry<bool> Enabled; public static ConfigEntry<KeyCode> Hotkey; public static ConfigEntry<bool> MiddleClickEnabled; public static ConfigEntry<string> PrefabName; public static ConfigEntry<int> Count; public static ConfigEntry<float> Radius; public static ConfigEntry<int> RingCount; public static ConfigEntry<float> BatchInterval; public static ConfigEntry<float> Height; public static ConfigEntry<float> Interval; public static ConfigEntry<int> MaxConcurrent; public static ConfigEntry<float> MinSpawnDistance; public static ConfigEntry<bool> ContinuousEnabled; public static ConfigEntry<KeyCode> ContinuousKey; public static ConfigEntry<float> ContinuousRate; public static ConfigEntry<float> ContinuousInnerRadius; public static ConfigEntry<float> ContinuousOuterRadius; public static ConfigEntry<bool> PacingEnabled; public static ConfigEntry<float> BlossomInterval; public static ConfigEntry<int> SimultaneousCount; public static ConfigEntry<float> LightDelay; public static ConfigEntry<bool> RequireOpenSky; public static ConfigEntry<bool> RequireLineOfSight; public static ConfigEntry<float> Clearance; public static ConfigEntry<float> SkyCheckHeight; public static ConfigEntry<float> SurfaceOffset; public static ConfigEntry<float> RayDistance; public static ConfigEntry<bool> FestivalEnabled; public static ConfigEntry<KeyCode> FestivalKey; public static ConfigEntry<int> FestivalScope; public static ConfigEntry<float> FestivalRadius; public static ConfigEntry<float> FestivalAltitude; public static ConfigEntry<float> FestivalRate; public static ConfigEntry<KeyCode> HeartKey; public static ConfigEntry<int> HeartDensity; public static ConfigEntry<float> HeartSize; public static ConfigEntry<float> HeartInterval; public static ConfigEntry<float> HeartForward; public static ConfigEntry<int> HeartOrder; public static ConfigEntry<int> PatternSpawnMode; public static ConfigEntry<KeyCode> PanelKey; public static ConfigEntry<float> PanelScale; public static ConfigEntry<float> PanelX; public static ConfigEntry<float> PanelY; public static ConfigEntry<float> PanelWidth; public static ConfigEntry<float> PanelHeight; public static ConfigEntry<int> Language; public static ConfigEntry<bool> SquirtleEnabled; public static ConfigEntry<KeyCode> SquirtleKey; public static ConfigEntry<int> SquirtlePattern; public static ConfigEntry<int> SquirtleDensity; public static ConfigEntry<float> SquirtleWidth; public static ConfigEntry<float> SquirtleDistance; public static ConfigEntry<float> SquirtleHeightOffset; public static void Bind(ConfigFile config) { //IL_006f: Unknown result type (might be due to invalid IL or missing references) //IL_0079: Expected O, but got Unknown //IL_00a7: Unknown result type (might be due to invalid IL or missing references) //IL_00b1: Expected O, but got Unknown //IL_00d4: Unknown result type (might be due to invalid IL or missing references) //IL_00de: Expected O, but got Unknown //IL_010c: Unknown result type (might be due to invalid IL or missing references) //IL_0116: Expected O, but got Unknown //IL_0144: Unknown result type (might be due to invalid IL or missing references) //IL_014e: Expected O, but got Unknown //IL_017c: Unknown result type (might be due to invalid IL or missing references) //IL_0186: Expected O, but got Unknown //IL_01aa: Unknown result type (might be due to invalid IL or missing references) //IL_01b4: Expected O, but got Unknown //IL_01e2: Unknown result type (might be due to invalid IL or missing references) //IL_01ec: Expected O, but got Unknown //IL_0250: Unknown result type (might be due to invalid IL or missing references) //IL_025a: Expected O, but got Unknown //IL_0288: Unknown result type (might be due to invalid IL or missing references) //IL_0292: Expected O, but got Unknown //IL_02c0: Unknown result type (might be due to invalid IL or missing references) //IL_02ca: Expected O, but got Unknown //IL_0313: Unknown result type (might be due to invalid IL or missing references) //IL_031d: Expected O, but got Unknown //IL_0340: Unknown result type (might be due to invalid IL or missing references) //IL_034a: Expected O, but got Unknown //IL_0397: Unknown result type (might be due to invalid IL or missing references) //IL_03a1: Expected O, but got Unknown //IL_0405: Unknown result type (might be due to invalid IL or missing references) //IL_040f: Expected O, but got Unknown //IL_043d: Unknown result type (might be due to invalid IL or missing references) //IL_0447: Expected O, but got Unknown //IL_0475: Unknown result type (might be due to invalid IL or missing references) //IL_047f: Expected O, but got Unknown //IL_04ad: Unknown result type (might be due to invalid IL or missing references) //IL_04b7: Expected O, but got Unknown //IL_050f: Unknown result type (might be due to invalid IL or missing references) //IL_0519: Expected O, but got Unknown //IL_0547: Unknown result type (might be due to invalid IL or missing references) //IL_0551: Expected O, but got Unknown //IL_057f: Unknown result type (might be due to invalid IL or missing references) //IL_0589: Expected O, but got Unknown //IL_05b7: Unknown result type (might be due to invalid IL or missing references) //IL_05c1: Expected O, but got Unknown //IL_0601: Unknown result type (might be due to invalid IL or missing references) //IL_060b: Expected O, but got Unknown //IL_0639: Unknown result type (might be due to invalid IL or missing references) //IL_0643: Expected O, but got Unknown //IL_0671: Unknown result type (might be due to invalid IL or missing references) //IL_067b: Expected O, but got Unknown //IL_06a9: Unknown result type (might be due to invalid IL or missing references) //IL_06b3: Expected O, but got Unknown //IL_06d5: Unknown result type (might be due to invalid IL or missing references) //IL_06df: Expected O, but got Unknown //IL_0701: Unknown result type (might be due to invalid IL or missing references) //IL_070b: Expected O, but got Unknown //IL_0758: Unknown result type (might be due to invalid IL or missing references) //IL_0762: Expected O, but got Unknown //IL_0800: Unknown result type (might be due to invalid IL or missing references) //IL_080a: Expected O, but got Unknown //IL_0862: Unknown result type (might be due to invalid IL or missing references) //IL_086c: Expected O, but got Unknown //IL_0891: Unknown result type (might be due to invalid IL or missing references) //IL_089b: Expected O, but got Unknown //IL_08c9: Unknown result type (might be due to invalid IL or missing references) //IL_08d3: Expected O, but got Unknown //IL_0901: Unknown result type (might be due to invalid IL or missing references) //IL_090b: Expected O, but got Unknown //IL_0939: Unknown result type (might be due to invalid IL or missing references) //IL_0943: Expected O, but got Unknown Enabled = config.Bind<bool>("0-总开关", "启用", true, "烟花秀总开关。关闭后快捷键与中键点选均不再生成烟花(已在空中的烟花不受影响)。"); Hotkey = config.Bind<KeyCode>("1-按键", "快捷键", (KeyCode)0, "在附近空中释放烟花的按键。默认留空(未绑定),可在面板中设置。"); MiddleClickEnabled = config.Bind<bool>("1-按键", "中键点选", true, "是否启用鼠标中键点选生成烟花;按住中键可连续生成。"); Count = config.Bind<int>("2-烟花规模", "数量", 6, new ConfigDescription("按快捷键时单次释放的烟花(火箭背包)数量。", (AcceptableValueBase)(object)new AcceptableValueRange<int>(1, 30), Array.Empty<object>())); Radius = config.Bind<float>("2-烟花规模", "散布半径", 15f, new ConfigDescription("烟花围绕玩家水平散布的半径(米),同时也是多圈烟花的圈距。", (AcceptableValueBase)(object)new AcceptableValueRange<float>(1f, 40f), Array.Empty<object>())); RingCount = config.Bind<int>("2-烟花规模", "圈数", 1, new ConfigDescription("多圈烟花的圈数;设为 3、散布半径 15m 时,会在半径 15/30/45m 三个圆上生成烟花。", (AcceptableValueBase)(object)new AcceptableValueRange<int>(1, 10), Array.Empty<object>())); BatchInterval = config.Bind<float>("2-烟花规模", "每圈间隔", 0.15f, new ConfigDescription("按快捷键释放时,同批烟花每枚之间的生成间隔(秒),用于形成接连绽放的观感。", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 3f), Array.Empty<object>())); Height = config.Bind<float>("2-烟花规模", "高度", 12f, new ConfigDescription("烟花相对玩家位置抬升的高度(米)。", (AcceptableValueBase)(object)new AcceptableValueRange<float>(1f, 50f), Array.Empty<object>())); Interval = config.Bind<float>("2-烟花规模", "生成间隔", 0.15f, new ConfigDescription("中键连续点选时两次生成之间的最短间隔(秒)。", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0.02f, 2f), Array.Empty<object>())); MaxConcurrent = config.Bind<int>("2-烟花规模", "最大同时存在", 30, new ConfigDescription("同时存在的烟花数量上限,达到上限后停止生成,直到旧烟花消失。", (AcceptableValueBase)(object)new AcceptableValueRange<int>(1, 60), Array.Empty<object>())); MinSpawnDistance = config.Bind<float>("2-烟花规模", "最小间距", 8f, new ConfigDescription("任意两个尚未爆炸的烟花之间的最小水平距离(米),避免生成在同一位置后互相叠加爆炸。", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 30f), Array.Empty<object>())); ContinuousEnabled = config.Bind<bool>("5-连续烟花", "启用", true, "是否允许使用连续烟花功能(按 G 键开启/停止持续释放)。"); ContinuousKey = config.Bind<KeyCode>("5-连续烟花", "开关按键", (KeyCode)0, "开启/停止连续释放烟花的按键。默认留空(未绑定),可在面板中设置。"); ContinuousRate = config.Bind<float>("5-连续烟花", "每秒个数", 3f, new ConfigDescription("连续释放时每秒生成的烟花数量。", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0.2f, 20f), Array.Empty<object>())); ContinuousInnerRadius = config.Bind<float>("5-连续烟花", "内圈半径", 10f, new ConfigDescription("连续释放时生成区域的圆环内半径(米)。", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 60f), Array.Empty<object>())); ContinuousOuterRadius = config.Bind<float>("5-连续烟花", "外圈半径", 30f, new ConfigDescription("连续释放时生成区域的圆环外半径(米)。", (AcceptableValueBase)(object)new AcceptableValueRange<float>(1f, 80f), Array.Empty<object>())); PacingEnabled = config.Bind<bool>("5-连续烟花", "绽放节奏", false, "开启后按「每秒个数」「绽放间隔」「同期点火数」自动安排每个火箭背包的点火时间,使烟花持续在空中绽放而不是同时炸完。"); BlossomInterval = config.Bind<float>("5-连续烟花", "绽放间隔", 0.5f, new ConfigDescription("开启绽放节奏后,每组烟花点火之间相隔的时间(秒)。", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0.05f, 10f), Array.Empty<object>())); SimultaneousCount = config.Bind<int>("5-连续烟花", "同期点火数", 3, new ConfigDescription("开启绽放节奏后,每组同时点火的烟花个数;例如每秒 6 个、间隔 0.5 秒、同期 3 个时,每 3 个一组、每组间隔 0.5 秒点火。", (AcceptableValueBase)(object)new AcceptableValueRange<int>(1, 30), Array.Empty<object>())); PrefabName = config.Bind<string>("3-生成", "预制体名", "", "留空自动探测,一般无需修改。默认对应游戏资源 0_Items/Rocketpack。"); LightDelay = config.Bind<float>("3-生成", "点燃延迟", 0.3f, new ConfigDescription("生成后延迟多少秒再点燃,确保其他玩家已收到生成事件。", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 2f), Array.Empty<object>())); RequireOpenSky = config.Bind<bool>("4-位置校验", "仅露天", true, "按快捷键释放时,跳过上方被地形或建筑遮挡的位置,避免烟花卡在洞里。"); RequireLineOfSight = config.Bind<bool>("4-位置校验", "需要视线", true, "按快捷键释放时,跳过与玩家之间被地形遮挡的位置。"); Clearance = config.Bind<float>("4-位置校验", "空间检测半径", 0.6f, new ConfigDescription("生成点周围多大范围内不允许有地形(米)。", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 5f), Array.Empty<object>())); SkyCheckHeight = config.Bind<float>("4-位置校验", "露天检测高度", 60f, new ConfigDescription("向上探测多高以内有遮挡就视为不露天(米)。", (AcceptableValueBase)(object)new AcceptableValueRange<float>(5f, 200f), Array.Empty<object>())); SurfaceOffset = config.Bind<float>("4-位置校验", "点选表面偏移", 0.8f, new ConfigDescription("中键点选时,生成点沿命中表面法线外移的距离(米)。", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 5f), Array.Empty<object>())); RayDistance = config.Bind<float>("4-位置校验", "点选射线距离", 120f, new ConfigDescription("中键点选时的最大射线距离(米)。", (AcceptableValueBase)(object)new AcceptableValueRange<float>(5f, 500f), Array.Empty<object>())); FestivalEnabled = config.Bind<bool>("6-春节模式", "启用", true, "是否允许使用春节模式(按开关按键开始/停止在高空持续撒烟花)。"); FestivalKey = config.Bind<KeyCode>("6-春节模式", "开关按键", (KeyCode)0, "开启/停止春节模式的按键。默认留空(未绑定),可在面板中设置。"); FestivalScope = config.Bind<int>("6-春节模式", "范围", 0, new ConfigDescription("0=跟随玩家:以玩家为中心、按「范围半径」撒点;1=整个地图:覆盖当前区域全部地面。", (AcceptableValueBase)(object)new AcceptableValueRange<int>(0, 1), Array.Empty<object>())); FestivalRadius = config.Bind<float>("6-春节模式", "范围半径", 60f, new ConfigDescription("跟随玩家模式下撒点的半径(米)。", (AcceptableValueBase)(object)new AcceptableValueRange<float>(5f, 300f), Array.Empty<object>())); FestivalAltitude = config.Bind<float>("6-春节模式", "高空高度", 90f, new ConfigDescription("烟花至少抬升到地表以上多高(米),保证足够高、无遮挡。", (AcceptableValueBase)(object)new AcceptableValueRange<float>(20f, 300f), Array.Empty<object>())); FestivalRate = config.Bind<float>("6-春节模式", "每秒个数", 5f, new ConfigDescription("春节模式每秒生成的烟花数量。", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0.5f, 30f), Array.Empty<object>())); HeartKey = config.Bind<KeyCode>("7-心形礼花", "快捷键", (KeyCode)0, "在玩家正前方高空放一颗由烟花组成的爱心。默认留空(未绑定),可在面板中设置。"); HeartDensity = config.Bind<int>("7-心形礼花", "密度", 45, new ConfigDescription("爱心轮廓上烟花的疏密程度(与杰尼龟图案同一套密度含义)。越大越清晰,同时生成的烟花与网络压力也越大;烟花数量与点火节奏会按密度和爱心大小自动推算。", (AcceptableValueBase)(object)new AcceptableValueRange<int>(10, 120), Array.Empty<object>())); HeartSize = config.Bind<float>("7-心形礼花", "爱心大小", 12f, new ConfigDescription("爱心形状的大小(米)。", (AcceptableValueBase)(object)new AcceptableValueRange<float>(3f, 40f), Array.Empty<object>())); HeartInterval = config.Bind<float>("7-心形礼花", "绽放间隔", 0.06f, new ConfigDescription("爱心烟花逐朵点火的时间间隔(秒)。所有烟花先同时生成,再按间隔依次点燃。", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 0.5f), Array.Empty<object>())); HeartForward = config.Bind<float>("7-心形礼花", "爱心距离", 18f, new ConfigDescription("爱心中心相对玩家的水平距离(米)。", (AcceptableValueBase)(object)new AcceptableValueRange<float>(1f, 40f), Array.Empty<object>())); HeartOrder = config.Bind<int>("7-心形礼花", "点火顺序", 0, new ConfigDescription("爱心烟花的点火顺序:0=对称下落(从顶部中点左右对称逐行向下、最后到心尖),1=整圈描边(沿周长绕一圈),2=心尖向上(从下往上),3=随机。", (AcceptableValueBase)(object)new AcceptableValueRange<int>(0, 3), Array.Empty<object>())); PatternSpawnMode = config.Bind<int>("7-心形礼花", "生成模式", 0, new ConfigDescription("心形与图案烟花共用的生成模式:0=点燃绽放(生成后按时点燃、升空爆炸);1=生成不点燃(仅生成背包静置空中,配合「删除」按钮清理,不爆炸);2=点燃不发射(持续燃烧、永不升空爆炸,配合「删除」按钮清理)。1、2 模式无爆炸,适合低性能电脑展示图案,且可随时用「点燃」按钮把它们变为真实烟花。", (AcceptableValueBase)(object)new AcceptableValueRange<int>(0, 2), Array.Empty<object>())); PanelKey = config.Bind<KeyCode>("8-面板", "面板开关按键", (KeyCode)286, "打开/关闭本 Mod 控制面板的按键。"); PanelScale = config.Bind<float>("8-面板", "面板缩放", 1f, new ConfigDescription("面板整体缩放比例,可在面板底部用「+/-」调整。", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0.6f, 2.5f), Array.Empty<object>())); PanelX = config.Bind<float>("8-面板", "面板位置X", 28f, "面板左上角 X 坐标,拖动面板后自动保存。"); PanelY = config.Bind<float>("8-面板", "面板位置Y", 28f, "面板左上角 Y 坐标,拖动面板后自动保存。"); PanelWidth = config.Bind<float>("8-面板", "面板宽度", 680f, "面板宽度,拖拽右下角后自动保存。"); PanelHeight = config.Bind<float>("8-面板", "面板高度", 560f, "面板高度,拖拽右下角后自动保存。"); Language = config.Bind<int>("8-面板", "语言/Language", 0, new ConfigDescription("面板语言:0=中文,1=English。也可在面板底部的语言按钮中切换。", (AcceptableValueBase)(object)new AcceptableValueRange<int>(0, 1), Array.Empty<object>())); SquirtleEnabled = config.Bind<bool>("9-杰尼龟的烟花", "启用", true, "是否允许使用杰尼龟图案烟花(按快捷键在玩家前方用烟花组成预设图案)。"); SquirtleKey = config.Bind<KeyCode>("9-杰尼龟的烟花", "快捷键", (KeyCode)0, "在玩家正前方用烟花组成预设图案的按键。默认留空(未绑定),可在面板中设置。"); SquirtlePattern = config.Bind<int>("9-杰尼龟的烟花", "图案", 0, new ConfigDescription("杰尼龟烟花使用的预设图案:0=囍、1=笑脸、2=PEAK、3=杰尼龟(>ε< 颜文字)。", (AcceptableValueBase)(object)new AcceptableValueRange<int>(0, 3), Array.Empty<object>())); SquirtleDensity = config.Bind<int>("9-杰尼龟的烟花", "密度", 45, new ConfigDescription("图案的烟花疏密程度(每米图案轮廓上的烟花数)。越大越清晰,同时生成的烟花与网络压力也越大;数量与点火节奏会按密度和大小自动推算。", (AcceptableValueBase)(object)new AcceptableValueRange<int>(10, 120), Array.Empty<object>())); SquirtleWidth = config.Bind<float>("9-杰尼龟的烟花", "大小", 45f, new ConfigDescription("整个图案横向占据的总宽度(米)。同时决定图案的点数与点火节奏:越大图案越壮观、烟花越多。", (AcceptableValueBase)(object)new AcceptableValueRange<float>(10f, 200f), Array.Empty<object>())); SquirtleDistance = config.Bind<float>("9-杰尼龟的烟花", "放置距离", 25f, new ConfigDescription("图案相对玩家正前方的水平距离(米)。", (AcceptableValueBase)(object)new AcceptableValueRange<float>(5f, 100f), Array.Empty<object>())); SquirtleHeightOffset = config.Bind<float>("9-杰尼龟的烟花", "高度偏移", 0f, new ConfigDescription("图案相对玩家中心的垂直偏移(米),正值抬高、负值降低。", (AcceptableValueBase)(object)new AcceptableValueRange<float>(-20f, 20f), Array.Empty<object>())); } public static void Save() { Plugin instance = Plugin.Instance; if (instance != null) { ConfigFile config = ((BaseUnityPlugin)instance).Config; if (config != null) { config.Save(); } } } } internal static class PatternCatalog { public const int PatternXi = 0; public const int PatternSmile = 1; public const int PatternPeak = 2; public const int PatternSquirtle = 3; public static readonly string[] Names = new string[4] { "囍", "笑脸", "PEAK", "杰尼龟" }; public static readonly string[] NamesEn = new string[4] { "Double Happiness", "Smiley", "PEAK", "Squirtle" }; private static readonly string[] XiRows = new string[17] { "....#.......#....", "#################", "#################", "....#.......#....", ".#######.#######.", ".................", ".#######.#######.", ".#....##.##....#.", ".#######.#######.", "..#..#.....#..#..", "..#..#.....#..#..", "########.########", ".................", ".#######.#######.", ".#....##.##....#.", ".#######.#######.", ".#....##.##....#." }; private const string SquirtleHeart = "0.00,0.35 0.00,0.38 0.03,0.46 0.11,0.56 0.22,0.64 0.37,0.66 0.53,0.62 0.65,0.52 0.72,0.38 0.72,0.22 0.65,0.06 0.53,-0.09 0.37,-0.23 0.22,-0.36 0.11,-0.47 0.03,-0.57 0.00,-0.64 0.00,-0.66 -0.00,-0.64 -0.03,-0.57 -0.11,-0.47 -0.22,-0.36 -0.37,-0.23 -0.53,-0.09 -0.65,0.06 -0.72,0.22 -0.72,0.38 -0.65,0.52 -0.53,0.62 -0.37,0.66 -0.22,0.64 -0.11,0.56 -0.03,0.46 -0.00,0.38"; private const string SquirtleEyeSharp = "-2.76,4.32 -2.57,4.20 -2.37,4.08 -2.17,3.97 -1.97,3.85 -1.78,3.73 -1.58,3.61 -1.38,3.49 -1.19,3.37 -0.99,3.26 -0.79,3.14 -0.59,3.02 -0.40,2.90 -0.40,2.90 -0.64,2.86 -0.89,2.82 -1.14,2.78 -1.38,2.74 -1.63,2.70 -1.88,2.66 -2.12,2.62 -2.37,2.58 -2.62,2.54 -2.86,2.51 -3.11,2.47 -3.36,2.43"; private const string SquirtleEyeLess = "4.34,2.78 4.11,2.73 3.89,2.68 3.66,2.63 3.43,2.58 3.21,2.53 2.98,2.49 2.75,2.44 2.53,2.39 2.30,2.34 2.07,2.29 1.84,2.24 1.62,2.19 1.62,2.19 1.83,2.08 2.03,1.97 2.24,1.86 2.45,1.76 2.65,1.65 2.86,1.54 3.07,1.43 3.28,1.32 3.48,1.21 3.69,1.10 3.90,1.00 4.11,0.89"; private const string SquirtleMouth = "0.00,0.92 -0.25,0.91 -0.49,0.88 -0.71,0.83 -0.89,0.77 -1.04,0.69 -1.14,0.60 -1.19,0.51 -1.19,0.41 -1.14,0.32 -1.04,0.23 -0.89,0.15 -0.71,0.09 -0.49,0.04 -0.25,0.01 -0.00,0.00 0.00,0.00 -0.26,-0.01 -0.51,-0.04 -0.74,-0.09 -0.94,-0.16 -1.12,-0.24 -1.25,-0.33 -1.35,-0.44 -1.39,-0.54 -1.39,-0.66 -1.35,-0.76 -1.25,-0.87 -1.12,-0.96 -0.94,-1.04 -0.74,-1.11 -0.51,-1.16 -0.26,-1.19 -0.00,-1.20"; private const string SquirtleHandLeft = "-0.79,-2.08 -0.98,-2.01 -1.12,-1.87 -1.27,-1.72 -1.33,-1.54 -1.40,-1.36 -1.53,-1.20 -1.53,-0.99 -1.53,-0.78 -1.53,-0.57 -1.53,-0.36 -1.46,-0.18 -1.40,0.00 -1.34,0.18 -1.28,0.37 -1.13,0.52 -0.98,0.66 -0.92,0.84 -0.78,0.99 -0.63,1.14 -0.48,1.29 -0.33,1.44 -0.19,1.58 -0.03,1.71 0.14,1.79 0.29,1.94 0.48,2.00 0.65,2.08 0.86,2.08 1.07,2.08 1.28,2.08 1.28,1.87 1.40,1.71 1.53,1.55 1.53,1.34 1.53,1.14 1.53,0.93 1.53,0.72 1.46,0.54 1.40,0.35 1.33,0.17 1.27,-0.01 1.16,-0.17 1.15,-0.38 1.00,-0.52 0.92,-0.70"; private const string SquirtleHandRight = "2.92,-2.07 3.09,-2.07 3.22,-2.01 3.37,-1.96 3.53,-1.96 3.68,-1.91 3.81,-1.84 3.98,-1.84 4.03,-1.72 4.19,-1.72 4.36,-1.72 4.52,-1.72 4.65,-1.64 4.80,-1.60 4.97,-1.60 5.13,-1.60 5.30,-1.60 5.45,-1.64 5.58,-1.72 5.74,-1.72 5.87,-1.82 5.98,-1.94 6.00,-2.10 6.00,-2.26 6.00,-2.43 5.96,-2.55 5.88,-2.64 5.87,-2.80 5.75,-2.91 5.63,-3.03 5.52,-3.15 5.40,-3.27 5.28,-3.38 5.17,-3.50 5.05,-3.61 4.93,-3.66 4.84,-3.73 4.72,-3.83 4.60,-3.95 4.45,-3.98 4.33,-4.09 4.18,-4.13 4.06,-4.25 3.93,-4.32 3.76,-4.32 3.72,-4.44 3.55,-4.44 3.42,-4.53 3.27,-4.57 3.15,-4.68 2.99,-4.68 2.92,-4.78 2.78,-4.80 2.61,-4.80 2.45,-4.80"; private static readonly string[] SquirtleParts = new string[6] { "-5.10,4.20,0.78", "-1.90,3.40,1.00", "2.60,1.90,1.00", "-0.20,0.20,1.00", "-4.60,-1.30,1.02", "4.50,-2.60,1.02" }; public static string LocalizedName(int pattern) { int num = Mathf.Clamp(pattern, 0, Names.Length - 1); if (!Lang.English) { return Names[num]; } return NamesEn[num]; } public static List<Vector3>[] Build(int pattern, int count) { count = Mathf.Max(4, count); return pattern switch { 1 => new List<Vector3>[1] { BuildSmile(count) }, 2 => BuildPeak(count), 3 => new List<Vector3>[1] { BuildSquirtle(count) }, _ => new List<Vector3>[1] { BuildXi(count) }, }; } private static List<Vector3> BuildXi(int count) { return RowsToPoints(XiRows, '#'); } private static List<Vector3> BuildSmile(int count) { //IL_009e: 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_0065: Unknown result type (might be due to invalid IL or missing references) //IL_012b: Unknown result type (might be due to invalid IL or missing references) List<Vector3> list = new List<Vector3>(count + 16); int num = Mathf.Max(8, Mathf.RoundToInt((float)count * 0.6f)); for (int i = 0; i < num; i++) { float num2 = (float)Math.PI * 2f * (float)i / (float)num; float num3 = 5f - ((i % 3 == 0) ? 0.15f : 0f); list.Add(new Vector3(Mathf.Cos(num2) * num3, Mathf.Sin(num2) * num3, 0f)); } int n = Mathf.Max(3, Mathf.RoundToInt((float)count * 0.09f)); AddDot(list, new Vector3(-2f, 2f, 0f), 0.8f, n); AddDot(list, new Vector3(2f, 2f, 0f), 0.8f, n); float num4 = 3.2f; float num5 = 1.2f; float num6 = 1.8f; int num7 = Mathf.Max(6, count - list.Count); for (int j = 0; j < num7; j++) { float num8 = (float)Math.PI * (float)j / (float)Mathf.Max(1, num7 - 1); list.Add(new Vector3(num4 * Mathf.Cos(num8), 0f - num5 - num6 * Mathf.Sin(num8), 0f)); } return list; } private static void AddDot(List<Vector3> points, Vector3 center, float radius, int n) { //IL_002e: Unknown result type (might be due to invalid IL or missing references) //IL_0044: 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) int num = 0; for (int i = 0; i < n; i++) { float num2 = Random.Range(0f, (float)Math.PI * 2f); float num3 = radius * Mathf.Sqrt(Random.Range(0f, 1f)); points.Add(center + new Vector3(Mathf.Cos(num2) * num3, Mathf.Sin(num2) * num3, 0f)); num++; } } private static List<Vector3> BuildSquirtle(int count) { //IL_00ad: Unknown result type (might be due to invalid IL or missing references) //IL_00b2: Unknown result type (might be due to invalid IL or missing references) //IL_00b4: Unknown result type (might be due to invalid IL or missing references) //IL_00c8: Unknown result type (might be due to invalid IL or missing references) //IL_00bf: Unknown result type (might be due to invalid IL or missing references) //IL_00dc: Unknown result type (might be due to invalid IL or missing references) //IL_00d3: 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_0143: Unknown result type (might be due to invalid IL or missing references) //IL_014d: Unknown result type (might be due to invalid IL or missing references) //IL_015f: Unknown result type (might be due to invalid IL or missing references) //IL_0172: Unknown result type (might be due to invalid IL or missing references) //IL_00f0: Unknown result type (might be due to invalid IL or missing references) //IL_00e7: 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) string[] array = new string[6] { "0.00,0.35 0.00,0.38 0.03,0.46 0.11,0.56 0.22,0.64 0.37,0.66 0.53,0.62 0.65,0.52 0.72,0.38 0.72,0.22 0.65,0.06 0.53,-0.09 0.37,-0.23 0.22,-0.36 0.11,-0.47 0.03,-0.57 0.00,-0.64 0.00,-0.66 -0.00,-0.64 -0.03,-0.57 -0.11,-0.47 -0.22,-0.36 -0.37,-0.23 -0.53,-0.09 -0.65,0.06 -0.72,0.22 -0.72,0.38 -0.65,0.52 -0.53,0.62 -0.37,0.66 -0.22,0.64 -0.11,0.56 -0.03,0.46 -0.00,0.38", "-2.76,4.32 -2.57,4.20 -2.37,4.08 -2.17,3.97 -1.97,3.85 -1.78,3.73 -1.58,3.61 -1.38,3.49 -1.19,3.37 -0.99,3.26 -0.79,3.14 -0.59,3.02 -0.40,2.90 -0.40,2.90 -0.64,2.86 -0.89,2.82 -1.14,2.78 -1.38,2.74 -1.63,2.70 -1.88,2.66 -2.12,2.62 -2.37,2.58 -2.62,2.54 -2.86,2.51 -3.11,2.47 -3.36,2.43", "4.34,2.78 4.11,2.73 3.89,2.68 3.66,2.63 3.43,2.58 3.21,2.53 2.98,2.49 2.75,2.44 2.53,2.39 2.30,2.34 2.07,2.29 1.84,2.24 1.62,2.19 1.62,2.19 1.83,2.08 2.03,1.97 2.24,1.86 2.45,1.76 2.65,1.65 2.86,1.54 3.07,1.43 3.28,1.32 3.48,1.21 3.69,1.10 3.90,1.00 4.11,0.89", "0.00,0.92 -0.25,0.91 -0.49,0.88 -0.71,0.83 -0.89,0.77 -1.04,0.69 -1.14,0.60 -1.19,0.51 -1.19,0.41 -1.14,0.32 -1.04,0.23 -0.89,0.15 -0.71,0.09 -0.49,0.04 -0.25,0.01 -0.00,0.00 0.00,0.00 -0.26,-0.01 -0.51,-0.04 -0.74,-0.09 -0.94,-0.16 -1.12,-0.24 -1.25,-0.33 -1.35,-0.44 -1.39,-0.54 -1.39,-0.66 -1.35,-0.76 -1.25,-0.87 -1.12,-0.96 -0.94,-1.04 -0.74,-1.11 -0.51,-1.16 -0.26,-1.19 -0.00,-1.20", "-0.79,-2.08 -0.98,-2.01 -1.12,-1.87 -1.27,-1.72 -1.33,-1.54 -1.40,-1.36 -1.53,-1.20 -1.53,-0.99 -1.53,-0.78 -1.53,-0.57 -1.53,-0.36 -1.46,-0.18 -1.40,0.00 -1.34,0.18 -1.28,0.37 -1.13,0.52 -0.98,0.66 -0.92,0.84 -0.78,0.99 -0.63,1.14 -0.48,1.29 -0.33,1.44 -0.19,1.58 -0.03,1.71 0.14,1.79 0.29,1.94 0.48,2.00 0.65,2.08 0.86,2.08 1.07,2.08 1.28,2.08 1.28,1.87 1.40,1.71 1.53,1.55 1.53,1.34 1.53,1.14 1.53,0.93 1.53,0.72 1.46,0.54 1.40,0.35 1.33,0.17 1.27,-0.01 1.16,-0.17 1.15,-0.38 1.00,-0.52 0.92,-0.70", "2.92,-2.07 3.09,-2.07 3.22,-2.01 3.37,-1.96 3.53,-1.96 3.68,-1.91 3.81,-1.84 3.98,-1.84 4.03,-1.72 4.19,-1.72 4.36,-1.72 4.52,-1.72 4.65,-1.64 4.80,-1.60 4.97,-1.60 5.13,-1.60 5.30,-1.60 5.45,-1.64 5.58,-1.72 5.74,-1.72 5.87,-1.82 5.98,-1.94 6.00,-2.10 6.00,-2.26 6.00,-2.43 5.96,-2.55 5.88,-2.64 5.87,-2.80 5.75,-2.91 5.63,-3.03 5.52,-3.15 5.40,-3.27 5.28,-3.38 5.17,-3.50 5.05,-3.61 4.93,-3.66 4.84,-3.73 4.72,-3.83 4.60,-3.95 4.45,-3.98 4.33,-4.09 4.18,-4.13 4.06,-4.25 3.93,-4.32 3.76,-4.32 3.72,-4.44 3.55,-4.44 3.42,-4.53 3.27,-4.57 3.15,-4.68 2.99,-4.68 2.92,-4.78 2.78,-4.80 2.61,-4.80 2.45,-4.80" }; List<Vector3>[] array2 = new List<Vector3>[array.Length]; int num = 0; for (int i = 0; i < array.Length && i < SquirtleParts.Length; i++) { List<Vector3> list = new List<Vector3>(64); AppendEncoded(list, array[i]); if (list.Count == 0) { array2[i] = list; continue; } float[] array3 = ParseLayout(SquirtleParts[i]); if (array3 != null) { float num2 = float.MaxValue; float num3 = float.MinValue; float num4 = float.MaxValue; float num5 = float.MinValue; for (int j = 0; j < list.Count; j++) { Vector3 val = list[j]; if (val.x < num2) { num2 = val.x; } if (val.x > num3) { num3 = val.x; } if (val.y < num4) { num4 = val.y; } if (val.y > num5) { num5 = val.y; } } float num6 = (num2 + num3) * 0.5f; float num7 = (num4 + num5) * 0.5f; float num8 = array3[2]; for (int k = 0; k < list.Count; k++) { Vector3 val2 = list[k]; list[k] = new Vector3(array3[0] + (val2.x - num6) * num8, array3[1] + (val2.y - num7) * num8, 0f); } } array2[i] = list; num += list.Count; } List<Vector3> list2 = new List<Vector3>(count + 32); if (num <= 0) { return list2; } foreach (List<Vector3> list3 in array2) { if (list3 != null && list3.Count != 0) { int num9 = Mathf.RoundToInt((float)count * (float)list3.Count / (float)num); int num10 = Mathf.Min(8, list3.Count); num9 = Mathf.Clamp(num9, num10, 600); list2.AddRange(ResamplePath(list3, num9)); } } return list2; } private static List<Vector3> ResamplePath(List<Vector3> path, int target) { //IL_002c: Unknown result type (might be due to invalid IL or missing references) //IL_0034: 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_00c5: Unknown result type (might be due to invalid IL or missing references) //IL_00d1: Unknown result type (might be due to invalid IL or missing references) if (path.Count < 2 || target < 2) { return path; } float[] array = new float[path.Count]; float num = 0f; for (int i = 1; i < path.Count; i++) { num = (array[i] = num + Vector3.Distance(path[i - 1], path[i])); } if (num <= 0.0001f) { return path; } List<Vector3> list = new List<Vector3>(target); int j = 1; for (int k = 0; k < target; k++) { float num2; for (num2 = num * (float)k / (float)(target - 1); j < path.Count - 1 && array[j] < num2; j++) { } float num3 = array[j] - array[j - 1]; float num4 = ((num3 > 1E-06f) ? ((num2 - array[j - 1]) / num3) : 0f); list.Add(Vector3.Lerp(path[j - 1], path[j], Mathf.Clamp01(num4))); } return list; } private static float[] ParseLayout(string s) { string[] array = s.Split(new char[1] { ',' }); if (array.Length < 3) { return null; } float[] array2 = new float[3]; for (int i = 0; i < 3; i++) { if (!float.TryParse(array[i], NumberStyles.Float, CultureInfo.InvariantCulture, out array2[i])) { return null; } } return array2; } private static void AppendEncoded(List<Vector3> points, string encoded) { //IL_0076: Unknown result type (might be due to invalid IL or missing references) int i = 0; int length = encoded.Length; while (i < length) { for (; i < length && encoded[i] == ' '; i++) { } int num = encoded.IndexOf(',', i); if (num >= 0) { int num2 = encoded.IndexOf(' ', num); if (num2 < 0) { num2 = length; } float num3 = float.Parse(encoded.Substring(i, num - i), CultureInfo.InvariantCulture); float num4 = float.Parse(encoded.Substring(num + 1, num2 - num - 1), CultureInfo.InvariantCulture); points.Add(new Vector3(num3, num4, 0f)); i = num2 + 1; continue; } break; } } private static List<Vector3>[] BuildPeak(int count) { int count2 = Mathf.Max(4, count / 4); return new List<Vector3>[4] { LetterP(count2), LetterE(count2), LetterA(count2), LetterK(count2) }; } private static List<Vector3> LetterP(int count) { new List<Vector3>(16); return RowsToPoints(new string[7] { "11110", "10001", "10001", "11110", "10000", "10000", "10000" }, '1'); } private static List<Vector3> LetterE(int count) { return RowsToPoints(new string[7] { "11111", "10000", "10000", "11110", "10000", "10000", "11111" }, '1'); } private static List<Vector3> LetterA(int count) { return RowsToPoints(new string[7] { "01110", "10001", "10001", "11111", "10001", "10001", "10001" }, '1'); } private static List<Vector3> LetterK(int count) { return RowsToPoints(new string[7] { "10001", "10010", "10100", "11000", "10100", "10010", "10001" }, '1'); } private static List<Vector3> RowsToPoints(string[] rows, char marker) { //IL_004a: Unknown result type (might be due to invalid IL or missing references) int num = rows.Length; int length = rows[0].Length; List<Vector3> list = new List<Vector3>(num * length); for (int i = 0; i < num; i++) { string text = rows[i]; for (int j = 0; j < length; j++) { if (j < text.Length && text[j] == marker) { list.Add(new Vector3((float)j, (float)(num - 1 - i), 0f)); } } } return list; } } [BepInPlugin("peak.fireworksshow", "烟花秀", "0.9.3")] public class Plugin : BaseUnityPlugin { private GameObject _host; public static Plugin Instance { get; private set; } public static ManualLogSource Log { get; private set; } private void Awake() { //IL_0022: Unknown result type (might be due to invalid IL or missing references) //IL_002c: Expected O, but got Unknown Instance = this; Log = ((BaseUnityPlugin)this).Logger; ModConfig.Bind(((BaseUnityPlugin)this).Config); _host = new GameObject("FireworksShow_Host"); ((Object)_host).hideFlags = (HideFlags)61; Object.DontDestroyOnLoad((Object)(object)_host); FireworkLauncher launcher = _host.AddComponent<FireworkLauncher>(); _host.AddComponent<SpringFestivalMode>().Launcher = launcher; PanelTheme.Log = delegate(string msg) { Log.LogInfo((object)msg); }; PanelHost panelHost = _host.AddComponent<PanelHost>(); panelHost.Panel = new FireworksPanel(); panelHost.ToggleKey = () => ModConfig.PanelKey.Value; panelHost.LogError = delegate(string msg) { Log.LogError((object)msg); }; Log.LogInfo((object)"烟花秀 v0.9.3 已加载。"); } private void OnDestroy() { if ((Object)(object)_host != (Object)null) { Object.Destroy((Object)(object)_host); } } } internal static class PluginInfo { public const string Guid = "peak.fireworksshow"; public const string Name = "烟花秀"; public const string Version = "0.9.3"; } internal static class ShowcaseLayout { public static Vector3[] BuildHeartPoints(Vector3 anchor, float size, int count) { //IL_0034: 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_0039: Unknown result type (might be due to invalid IL or missing references) //IL_005c: Unknown result type (might be due to invalid IL or missing references) //IL_0061: 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_0059: 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_006b: 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_00a0: Unknown result type (might be due to invalid IL or missing references) //IL_00a5: Unknown result type (might be due to invalid IL or missing references) //IL_00a6: Unknown result type (might be due to invalid IL or missing references) //IL_00a7: Unknown result type (might be due to invalid IL or missing references) //IL_00bc: Unknown result type (might be due to invalid IL or missing references) //IL_00c1: 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_0098: Unknown result type (might be due to invalid IL or missing references) //IL_009d: Unknown result type (might be due to invalid IL or missing references) //IL_0183: Unknown result type (might be due to invalid IL or missing references) //IL_0188: Unknown result type (might be due to invalid IL or missing references) //IL_01d0: Unknown result type (might be due to invalid IL or missing references) //IL_01d1: Unknown result type (might be due to invalid IL or missing references) //IL_01e0: Unknown result type (might be due to invalid IL or missing references) //IL_01e5: Unknown result type (might be due to invalid IL or missing references) //IL_01ea: Unknown result type (might be due to invalid IL or missing references) //IL_0203: Unknown result type (might be due to invalid IL or missing references) //IL_0208: Unknown result type (might be due to invalid IL or missing references) //IL_020d: Unknown result type (might be due to invalid IL or missing references) count = Mathf.Clamp(count, 8, 100); size = Mathf.Max(2f, size); Camera main = Camera.main; Vector3 val = (((Object)(object)main != (Object)null) ? ((Component)main).transform.forward : Vector3.forward); val.y = 0f; if (((Vector3)(ref val)).sqrMagnitude < 0.0001f) { val = Vector3.forward; } val = ((Vector3)(ref val)).normalized; Vector3 val2 = (((Object)(object)main != (Object)null) ? ((Component)main).transform.right : Vector3.right); val2.y = 0f; if (((Vector3)(ref val2)).sqrMagnitude < 0.0001f) { val2 = Vector3.right; } val2 = ((Vector3)(ref val2)).normalized; Vector3 val3 = anchor + val * Mathf.Max(1f, ModConfig.HeartForward.Value); float num = Mathf.Max(2f, ModConfig.Height.Value); float num2 = size / 32f; Vector3[] array = (Vector3[])(object)new Vector3[count]; float num3 = float.MaxValue; float num4 = float.MinValue; for (int i = 0; i < count; i++) { float num5 = (float)Math.PI * 2f * (float)i / (float)count; float num6 = 16f * Mathf.Pow(Mathf.Sin(num5), 3f); float num7 = 13f * Mathf.Cos(num5) - 5f * Mathf.Cos(2f * num5) - 2f * Mathf.Cos(3f * num5) - Mathf.Cos(4f * num5); array[i] = new Vector3(num6 * num2, num7 * num2, 0f); if (num7 < num3) { num3 = num7; } if (num7 > num4) { num4 = num7; } } float num8 = (num3 + num4) * 0.5f * num2; Vector3[] array2 = (Vector3[])(object)new Vector3[count]; for (int j = 0; j < count; j++) { array2[j] = val3 + val2 * array[j].x + Vector3.up * (num + array[j].y - num8); } return array2; } public static float[] OrderHeartDelays(Vector3[] points, int order, float interval) { int num = points.Length; float[] array = new float[num]; if (num == 0) { return array; } switch (order) { case 1: { for (int num10 = 0; num10 < num; num10++) { array[num10] = (float)num10 * interval; } break; } case 2: { int[] array4 = new int[num]; for (int num11 = 0; num11 < num; num11++) { array4[num11] = num11; } Array.Sort(array4, (int a, int b) => points[a].y.CompareTo(points[b].y)); for (int num12 = 0; num12 < num; num12++) { array[array4[num12]] = (float)num12 * interval; } break; } case 3: { int[] array3 = new int[num]; for (int num5 = 0; num5 < num; num5++) { array3[num5] = num5; } for (int num6 = num - 1; num6 > 0; num6--) { int num7 = Random.Range(0, num6 + 1); int num8 = array3[num6]; array3[num6] = array3[num7]; array3[num7] = num8; } for (int num9 = 0; num9 < num; num9++) { array[array3[num9]] = (float)num9 * interval; } break; } default: { int[] array2 = new int[num]; for (int i = 0; i < num; i++) { array2[i] = i; } Array.Sort(array2, delegate(int a, int b) { int num13 = points[b].y.CompareTo(points[a].y); return (num13 == 0) ? points[a].x.CompareTo(points[b].x) : num13; }); float num2 = float.NaN; int num3 = -1; for (int num4 = 0; num4 < num; num4++) { if (float.IsNaN(num2) || Mathf.Abs(points[array2[num4]].y - num2) > 0.001f) { num2 = points[array2[num4]].y; num3++; } array[array2[num4]] = (float)num3 * interval; } break; } } return array; } public static Vector3[] BuildTextPoints(List<Vector3>[] chars, Vector3 anchor, float totalWidth, float distance, float heightOffset) { //IL_0001: 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_0050: Unknown result type (might be due to invalid IL or missing references) List<Vector3>[] array = BuildTextPointGroups(chars, anchor, totalWidth, distance, heightOffset); int num = 0; for (int i = 0; i < array.Length; i++) { num += array[i].Count; } Vector3[] array2 = (Vector3[])(object)new Vector3[num]; int num2 = 0; for (int j = 0; j < array.Length; j++) { for (int k = 0; k < array[j].Count; k++) { array2[num2++] = array[j][k]; } } return array2; } public static List<Vector3>[] BuildTextPointGroups(List<Vector3>[] chars, Vector3 anchor, float totalWidth, float distance, float heightOffset) { //IL_0121: Unknown result type (might be due to invalid IL or missing references) //IL_0113: 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_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_006e: Unknown result type (might be due to invalid IL or missing references) //IL_014b: Unknown result type (might be due to invalid IL or missing references) //IL_0150: Unknown result type (might be due to invalid IL or missing references) //IL_0142: Unknown result type (might be due to invalid IL or missing references) //IL_0147: Unknown result type (might be due to invalid IL or missing references) //IL_0082: Unknown result type (might be due to invalid IL or missing references) //IL_0079: Unknown result type (might be due to invalid IL or missing references) //IL_016a: Unknown result type (might be due to invalid IL or missing references) //IL_015c: 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_008d: Unknown result type (might be due to invalid IL or missing references) //IL_016f: 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_00a0: Unknown result type (might be due to invalid IL or missing references) //IL_0194: Unknown result type (might be due to invalid IL or missing references) //IL_0199: Unknown result type (might be due to invalid IL or missing references) //IL_01e8: Unknown result type (might be due to invalid IL or missing references) //IL_01e9: Unknown result type (might be due to invalid IL or missing references) //IL_01f6: Unknown result type (might be due to invalid IL or missing references) //IL_01fb: Unknown result type (might be due to invalid IL or missing references) //IL_0200: Unknown result type (might be due to invalid IL or missing references) //IL_018b: Unknown result type (might be due to invalid IL or missing references) //IL_0190: Unknown result type (might be due to invalid IL or missing references) //IL_00b2: Unknown result type (might be due to invalid IL or missing references) //IL_023a: Unknown result type (might be due to invalid IL or missing references) //IL_024c: Unknown result type (might be due to invalid IL or missing references) //IL_0280: Unknown result type (might be due to invalid IL or missing references) //IL_0285: 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_02a1: Unknown result type (might be due to invalid IL or missing references) //IL_02b7: 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_02bd: Unknown result type (might be due to invalid IL or missing references) //IL_02c2: Unknown result type (might be due to invalid IL or missing references) //IL_02c7: Unknown result type (might be due to invalid IL or missing references) //IL_02ce: Unknown result type (might be due to invalid IL or missing references) //IL_02d3: Unknown result type (might be due to invalid IL or missing references) int num = chars.Length; List<Vector3>[] array = new List<Vector3>[num]; float num2 = float.MaxValue; float num3 = float.MinValue; float[] array2 = new float[num]; float num4 = 0f; for (int i = 0; i < num; i++) { List<Vector3> list = chars[i]; if (list == null || list.Count == 0) { array[i] = new List<Vector3>(0); continue; } float num5 = float.MaxValue; float num6 = float.MinValue; for (int j = 0; j < list.Count; j++) { Vector3 val = list[j]; if (val.x < num5) { num5 = val.x; } if (val.x > num6) { num6 = val.x; } if (val.y < num2) { num2 = val.y; } if (val.y > num3) { num3 = val.y; } } array2[i] = Mathf.Max(0.5f, num6 - num5); num4 += array2[i]; } if (num4 <= 0f) { return array; } Camera main = Camera.main; Vector3 val2 = (((Object)(object)main != (Object)null) ? ((Component)main).transform.forward : Vector3.forward); val2.y = 0f; if (((Vector3)(ref val2)).sqrMagnitude < 0.0001f) { val2 = Vector3.forward; } val2 = ((Vector3)(ref val2)).normalized; Vector3 val3 = (((Object)(object)main != (Object)null) ? ((Component)main).transform.right : Vector3.right); val3.y = 0f; if (((Vector3)(ref val3)).sqrMagnitude < 0.0001f) { val3 = Vector3.right; } val3 = ((Vector3)(ref val3)).normalized; float num7 = totalWidth * 0.03f; float num8 = num4 + num7 * (float)Mathf.Max(0, num - 1); float num9 = Mathf.Max(0.05f, totalWidth / Mathf.Max(0.5f, num8)); float num10 = Mathf.Max(0.5f, num3 - num2) * num9 * 0.5f; Vector3 val4 = anchor + val2 * Mathf.Max(1f, distance); float num11 = 0f; for (int k = 0; k < num; k++) { List<Vector3> list2 = chars[k]; if (list2 == null || list2.Count == 0) { continue; } float num12 = float.MaxValue; for (int l = 0; l < list2.Count; l++) { if (list2[l].x < num12) { num12 = list2[l].x; } } List<Vector3> list3 = new List<Vector3>(list2.Count); for (int m = 0; m < list2.Count; m++) { Vector3 val5 = list2[m]; float num13 = (num11 + (val5.x - num12)) * num9 - totalWidth * 0.5f; float num14 = (val5.y - num2) * num9 - num10 + heightOffset; list3.Add(val4 + val3 * num13 + Vector3.up * num14); } array[k] = list3; num11 += array2[k] + num7; } return array; } } internal sealed class ShowScheduler { private const float FlightSeconds = 6f; private const int MaxSpawnPerFrame = 6; private readonly FireworkLauncher _launcher; public ShowScheduler(FireworkLauncher launcher) { _launcher = launcher; } public IEnumerator RunSimultaneous(Vector3[] points, float[] lightDelays, int spawnMode, SpawnCategory category) { int num = Mathf.Min(points.Length, lightDelays.Length); for (int i = 0; i < num; i++) { _launcher.StartSpawn(points[i], 0f, paced: false, Mathf.Max(0f, lightDelays[i]), spawnMode, category); } yield break; } public IEnumerator RunRolling(Vector3[] points, float[] lightDelays, int concurrentCap, int spawnMode, SpawnCategory category) { float setup = Mathf.Max(0.15f, _launcher.SetupDelay); float start = Time.time; int index = 0; int count = Mathf.Min(points.Length, lightDelays.Length); while (index < count) { float num = Time.time - start; int num2 = 0; while (index < count && num2 < 6) { float num3 = lightDelays[index] - 6f; if (num < num3 - setup || _launcher.ActiveCount >= concurrentCap) { break; } _launcher.StartSpawn(points[index], 0f, paced: false, setup, spawnMode, category); index++; num2++; } yield return null; } } public IEnumerator RunDisplay(Vector3[] points, int spawnMode, SpawnCategory category) { float setup = Mathf.Max(0.15f, _launcher.SetupDelay); int index = 0; while (index < points.Length) { int num = 0; while (index < points.Length && num < 6) { _launcher.StartSpawn(points[index], 0f, paced: false, setup, spawnMode, category); index++; num++; } yield return null; } } } public class SpringFestivalMode : MonoBehaviour { public FireworkLauncher Launcher; private bool _running; private float _nextSpawn; public static SpringFestivalMode Instance { get; private set; } public bool IsRunning => _running; private void Awake() { Instance = this; } private void Update() { //IL_002b: 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_00b4: Unknown result type (might be due to invalid IL or missing references) if (!ModConfig.Enabled.Value || !ModConfig.FestivalEnabled.Value) { Stop(); return; } if (!FireworksPanel.IsOpen && Pressed(ModConfig.FestivalKey.Value)) { Toggle(); } if (_running && PhotonNetwork.InRoom && !(Time.time < _nextSpawn)) { Character localCharacter = Character.localCharacter; if (!((Object)(object)localCharacter == (Object)null) && FireworkPointPicker.TryFindFestivalPoint(localCharacter.Center, Launcher.ActivePoints, out var point)) { float num = Mathf.Max(0.5f, ModConfig.FestivalRate.Value); _nextSpawn = Time.time + 1f / num; Launcher.LaunchFirework(point, ModConfig.LightDelay.Value); } } } public void Toggle() { _running = !_running; _nextSpawn = 0f; Launcher?.ShowNotice(_running ? Lang.L("春节烟花:已开启", "Spring Festival: started") : Lang.L("春节烟花:已停止", "Spring Festival: stopped")); } public void Stop() { if (_running) { _running = false; Launcher?.ShowNotice(Lang.L("春节烟花:已停止", "Spring Festival: stopped")); } } private static bool Pressed(KeyCode key) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0003: Unknown result type (might be due to invalid IL or missing references) if ((int)key != 0) { return Input.GetKeyDown(key); } return false; } } } namespace FireworksShow.UI { internal sealed class FireworksPanel : ModPanelBase { private readonly Dictionary<ConfigEntryBase, string> _buffers = new Dictionary<ConfigEntryBase, string>(); private float _nextSave; public static FireworksPanel Instance { get; private set; } public static bool IsOpen { get { if (Instance != null) { return Instance.Visible; } return false; } } protected override string Title => Lang.L("烟花秀 v", "Fireworks Show v") + "0.9.3"; protected override string TitleNote => Lang.L("全房可见 · 纯视觉", "Visible to everyone · Visual only"); protected override string[] TabLabels => new string[5] { Lang.L("概览", "Overview"), Lang.L("常规烟花", "Normal"), Lang.L("连续烟花", "Continuous"), Lang.L("春节模式", "Festival"), Lang.L("高级", "Advanced") }; protected override int WindowId => 61802; public FireworksPanel() { Instance = this; } protected override float LoadScale() { return ModConfig.PanelScale.Value; } protected override void SaveScale(float value) { ModConfig.PanelScale.Value = value; SaveSoon(); } protected override Rect LoadWindowRect() { //IL_0028: Unknown result type (might be due to invalid IL or missing references) return new Rect(ModConfig.PanelX.Value, ModConfig.PanelY.Value, ModConfig.PanelWidth.Value, ModConfig.PanelHeight.Value); } protected override void SaveWindowRect(Rect rect) { ModConfig.PanelX.Value = ((Rect)(ref rect)).x; ModConfig.PanelY.Value = ((Rect)(ref rect)).y; ModConfig.PanelWidth.Value = ((Rect)(ref rect)).width; ModConfig.PanelHeight.Value = ((Rect)(ref rect)).height; SaveSoon(); } protected override void OnOpen() { _buffers.Clear(); } protected override void DrawStatusStrip() { int num = FireworkLauncher.Instance?.ActiveCount ?? 0; GUILayout.BeginHorizontal(Array.Empty<GUILayoutOption>()); GUILayout.Label(Lang.L($"在场 {num}", $"In air {num}"), PanelTheme.Sub, Array.Empty<GUILayoutOption>()); GUILayout.Space(16f); GUILayout.Label(ContinuousState(), PanelTheme.Sub, Array.Empty<GUILayoutOption>()); GUILayout.Space(16f); GUILayout.Label(FestivalState(), PanelTheme.Sub, Array.Empty<GUILayoutOption>()); GUILayout.FlexibleSpace(); GUILayout.EndHorizontal(); GUILayout.Space(4f); } protected override void DrawFooterHint() { //IL_000a: 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) GUILayout.Label(Lang.L("按 " + KeyName(ModConfig.PanelKey.Value) + " 开关面板 · 改动即时生效", "Press " + KeyName(ModConfig.PanelKey.Value) + " to toggle · changes apply instantly"), PanelTheme.Hint, Array.Empty<GUILayoutOption>()); } protected override void DrawFooterExtras() { GUILayout.Space(8f); if (GUILayout.Button(Lang.L("English", "中文"), PanelTheme.Mini, (GUILayoutOption[])(object)new GUILayoutOption[2] { GUILayout.Width(58f), GUILayout.Height(18f) })) { Lang.Toggle(); _buffers.Clear(); Notify(Lang.L("已切换为中文。", "Switched to English.")); } } private unsafe static string KeyName(KeyCode key) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) if ((int)key != 0) { return ((object)(*(KeyCode*)(&key))/*cast due to .constrained prefix*/).ToString(); } return Lang.L("(未绑定)", "(unbound)"); } private string ContinuousState() { FireworkLauncher instance = FireworkLauncher.Instance; if (instance ==