Decompiled source of PocketExpedition v0.0.3
BepInEx/plugins/PocketExpedition/PocketExpedition.dll
Decompiled a month ago
The result has been truncated due to the large size, download it to view full contents!
using System; using System.Collections.Concurrent; using System.Collections.Generic; using System.ComponentModel; using System.Diagnostics; using System.Globalization; using System.IO; using System.IO.Compression; using System.Linq; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; using System.Runtime.Serialization; using System.Runtime.Serialization.Json; using System.Runtime.Versioning; using System.Security.Cryptography; using System.Text; using System.Text.RegularExpressions; using BepInEx; using HarmonyLib; using Microsoft.CodeAnalysis; using Newtonsoft.Json; using Newtonsoft.Json.Linq; using PocketExpedition.Core; using PocketExpedition.Runtime; using UnityEngine; using UnityEngine.EventSystems; using UnityEngine.Events; using UnityEngine.InputSystem; using UnityEngine.InputSystem.Controls; using UnityEngine.InputSystem.Utilities; using UnityEngine.Networking; using UnityEngine.UI; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")] [assembly: AssemblyCompany("PocketExpedition")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyFileVersion("0.0.3.0")] [assembly: AssemblyInformationalVersion("0.0.3")] [assembly: AssemblyProduct("PocketExpedition")] [assembly: AssemblyTitle("PocketExpedition")] [assembly: AssemblyVersion("0.0.3.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 PocketExpedition { [BepInPlugin("com.pocketexpedition.idlegame", "Pocket Expedition", "0.0.3")] [DefaultExecutionOrder(-32000)] public sealed class PocketExpeditionPlugin : BaseUnityPlugin { public const string PluginGuid = "com.pocketexpedition.idlegame"; public const string PluginName = "Pocket Expedition"; public const string PluginVersion = "0.0.3"; private SaveRepository? saveRepository; private IdleGame? game; private PixelAssetLoader? assetLoader; private BundleAssetStore? assetBundle; private PocketAudio? audio; private PocketExpeditionView? view; private InputFocusController? inputFocus; private float refreshAccumulator; private float saveAccumulator; private bool f8WasHeld; private bool primaryPointerWasHeld; private bool applicationFocused = true; private bool applicationQuitting; private readonly OverlayInteractionState overlayInteraction = new OverlayInteractionState(); private bool runtimeProbeLogged; private int inputProcessedFrame = -1; private string rankingServerUrl = "https://pocketexpedition.lotus030106.workers.dev"; private void Awake() { rankingServerUrl = ((BaseUnityPlugin)this).Config.Bind<string>("Ranking", "ServerUrl", "https://pocketexpedition.lotus030106.workers.dev", "Pocket Expedition 온라인 랭킹 서버의 HTTPS 주소").Value.Trim(); ((BaseUnityPlugin)this).Logger.LogInfo((object)"Pocket Expedition 등록 완료 · Unity Start에서 에셋 초기화 예정"); } private void Start() { ((BaseUnityPlugin)this).Logger.LogInfo((object)"Pocket Expedition Start 확인"); try { string pluginDirectory = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location) ?? Paths.PluginPath; saveRepository = new SaveRepository(Path.Combine(Paths.ConfigPath)); bool recoveredFromBackup; GameState gameState = saveRepository.Load(out recoveredFromBackup); game = new IdleGame(gameState); OfflineReward reward = game.PrepareOfflineProgress(DateTimeOffset.UtcNow.ToUnixTimeSeconds()); game.PersistState = saveRepository.Save; assetBundle = new BundleAssetStore(pluginDirectory, delegate(string message) { ((BaseUnityPlugin)this).Logger.LogInfo((object)message); }); assetLoader = new PixelAssetLoader(assetBundle); assetLoader.Load(pluginDirectory, delegate(string message) { ((BaseUnityPlugin)this).Logger.LogInfo((object)message); }); if (!assetLoader.IsComplete) { throw new InvalidDataException("AssetBundle is incomplete. Install the matching release files."); } audio = new PocketAudio(pluginDirectory, assetBundle, delegate(string message) { ((BaseUnityPlugin)this).Logger.LogInfo((object)message); }); audio.SetVolume((float)gameState.SoundVolumePercent / 100f); audio.SetOverlayActive(active: false, gameState.SoundEnabled); inputFocus = new InputFocusController(); inputFocus.BeforeHostInput = ProcessOverlayInput; view = new PocketExpeditionView(game, assetLoader, audio, CloseOverlay, saveRepository, RestoreSave, rankingServerUrl); view.PassiveInteractionRequested += EnterPassiveMode; if (reward.Seconds > 0 && reward.Gold > 0.0) { view.ShowOfflineReward(reward); } ((BaseUnityPlugin)this).Logger.LogInfo((object)"Pocket Expedition 0.0.3 준비 완료 · F8로 열기"); if (recoveredFromBackup) { ((BaseUnityPlugin)this).Logger.LogWarning((object)"기본 저장이 손상되어 백업 저장을 불러옴"); } } catch (Exception ex) { ((BaseUnityPlugin)this).Logger.LogError((object)("초기화 실패: " + ex)); DisposeRuntime(); } } private void OnEnable() { ((BaseUnityPlugin)this).Logger.LogInfo((object)"Pocket Expedition OnEnable 확인"); } private void Update() { if (!runtimeProbeLogged) { runtimeProbeLogged = true; ((BaseUnityPlugin)this).Logger.LogInfo((object)("런타임 Update 루프 확인 · game=" + (game != null) + " view=" + (view != null) + " inputFocus=" + (inputFocus != null) + " · InputSystem Keyboard=" + (Keyboard.current != null) + " · F8 대체 입력 활성화")); } if (game == null || view == null || inputFocus == null) { return; } audio?.SetExpeditionActive(game.SessionActive, game.State.ProfileId); audio?.Tick(); ProcessOverlayInput(); game.Tick(Time.unscaledDeltaTime); inputFocus.Tick(); view.TickVisuals(Time.unscaledTime); view.ApplyModGraphics(); refreshAccumulator += Time.unscaledDeltaTime; if (refreshAccumulator >= 0.1f) { refreshAccumulator = 0f; if (view.IsVisible) { view.Refresh(); } } if (game.State.HasStarted && game.SessionActive) { saveAccumulator += Time.unscaledDeltaTime; if (saveAccumulator >= (float)game.State.AutoSaveIntervalSeconds) { saveAccumulator = 0f; SafeSave(snapshot: true); } } } private void ProcessOverlayInput() { //IL_00a4: Unknown result type (might be due to invalid IL or missing references) if (view == null || inputFocus == null || !applicationFocused || inputProcessedFrame == Time.frameCount) { return; } inputProcessedFrame = Time.frameCount; if (ReadF8Pressed()) { ((BaseUnityPlugin)this).Logger.LogInfo((object)"F8 입력 감지 · 방치형 오버레이 전환"); ToggleOverlay(); } if (overlayInteraction.IsInteractive) { view.ProcessConfiguredKeys(); } if (overlayInteraction.IsVisible && applicationFocused && ReadPrimaryPointerPressed()) { OverlayInteractionMode mode = overlayInteraction.Mode; if (overlayInteraction.IsInteractive || (Cursor.visible && (int)Cursor.lockState == 0)) { overlayInteraction.PointerPressed(view.IsPointerInsideWindow()); } if (mode != overlayInteraction.Mode) { ApplyOverlayInteraction(mode == OverlayInteractionMode.Interactive); } } } private void LateUpdate() { inputFocus?.Tick(); if (inputFocus != null && overlayInteraction.IsInteractive && applicationFocused) { inputFocus.EnsureOverlayCursor(); } } private void OnApplicationQuit() { applicationQuitting = true; SafeSave(); } private void OnDisable() { overlayInteraction.Hide(); ApplyOverlayInteraction(deferGameplayRelease: false); } private void OnDestroy() { SafeSave(); DisposeRuntime(); } private bool ReadF8Pressed() { bool flag = false; try { flag = Keyboard.current != null && ((ButtonControl)Keyboard.current.f8Key).wasPressedThisFrame; } catch { } try { bool key = Input.GetKey((KeyCode)289); flag |= key && !f8WasHeld; f8WasHeld = key; } catch { } return flag; } private void OnApplicationFocus(bool focused) { applicationFocused = focused; overlayInteraction.SetApplicationFocus(focused); ApplyOverlayInteraction(deferGameplayRelease: false); } private bool ReadPrimaryPointerPressed() { bool flag = false; try { flag = Mouse.current != null && Mouse.current.leftButton.wasPressedThisFrame; } catch { } try { bool mouseButton = Input.GetMouseButton(0); flag |= mouseButton && !primaryPointerWasHeld; primaryPointerWasHeld = mouseButton; } catch { } return flag; } private bool ReadSkillPressed(int index) { bool flag = false; if (Keyboard.current != null) { try { switch (index) { case 0: flag = ((ButtonControl)Keyboard.current.digit1Key).wasPressedThisFrame || ((ButtonControl)Keyboard.current.numpad1Key).wasPressedThisFrame; break; case 1: flag = ((ButtonControl)Keyboard.current.digit2Key).wasPressedThisFrame || ((ButtonControl)Keyboard.current.numpad2Key).wasPressedThisFrame; break; case 2: flag = ((ButtonControl)Keyboard.current.digit3Key).wasPressedThisFrame || ((ButtonControl)Keyboard.current.numpad3Key).wasPressedThisFrame; break; case 3: flag = ((ButtonControl)Keyboard.current.digit4Key).wasPressedThisFrame || ((ButtonControl)Keyboard.current.numpad4Key).wasPressedThisFrame; break; } } catch { } } try { bool flag2 = flag; flag = (byte)((flag2 ? 1u : 0u) | (uint)(index switch { 0 => (Input.GetKeyDown((KeyCode)49) || Input.GetKeyDown((KeyCode)257)) ? 1 : 0, 1 => (Input.GetKeyDown((KeyCode)50) || Input.GetKeyDown((KeyCode)258)) ? 1 : 0, 2 => (Input.GetKeyDown((KeyCode)51) || Input.GetKeyDown((KeyCode)259)) ? 1 : 0, 3 => (Input.GetKeyDown((KeyCode)52) || Input.GetKeyDown((KeyCode)260)) ? 1 : 0, _ => 0, })) != 0; } catch { } return flag; } private void ToggleOverlay() { if (view != null && inputFocus != null) { bool isVisible = overlayInteraction.IsVisible; overlayInteraction.ToggleF8(); if (overlayInteraction.IsInteractive) { view.RestoreFromMinimized(); } ApplyOverlayInteraction(deferGameplayRelease: false); if (!overlayInteraction.IsVisible) { SafeSave(); } if (!isVisible && overlayInteraction.IsInteractive) { audio?.PlayPortal(); } } } private void CloseOverlay() { overlayInteraction.Hide(); ApplyOverlayInteraction(deferGameplayRelease: false); SafeSave(); } private void EnterPassiveMode() { OverlayInteractionMode mode = overlayInteraction.Mode; overlayInteraction.RequestPassive(); if (mode != overlayInteraction.Mode) { ApplyOverlayInteraction(deferGameplayRelease: false); } } private void ApplyOverlayInteraction(bool deferGameplayRelease) { if (view == null || inputFocus == null) { return; } if (applicationQuitting || !view.IsAlive) { inputFocus.ReleaseToGame(); return; } view.SetVisible(overlayInteraction.IsVisible); audio?.SetOverlayActive(overlayInteraction.IsVisible, game?.State.SoundEnabled ?? true); if (overlayInteraction.IsInteractive && applicationFocused) { inputFocus.CaptureForOverlay(); view.SetWindowInteraction(enabled: true); inputFocus.EnsureOverlayCursor(); return; } view.SetWindowInteraction(enabled: false); if (deferGameplayRelease) { inputFocus.ReleaseAfterPointerFrame(); } else { inputFocus.ReleaseToGame(); } } private void RestoreSave(string key) { if (saveRepository != null && game != null && assetLoader != null && audio != null) { if (game.RewardSettlementPending || game.ActiveSpecial != SpecialDungeon.None) { throw new InvalidOperationException("먼저 특수 던전과 보상 정산을 완료해 주세요."); } GameState gameState = saveRepository.ReadSnapshot(key); GameState state = game.State; gameState.LanguageCode = state.LanguageCode; gameState.EnglishUi = state.EnglishUi; gameState.SoundEnabled = state.SoundEnabled; gameState.SoundVolumePercent = state.SoundVolumePercent; gameState.UiScalePercent = state.UiScalePercent; gameState.ReduceMotion = state.ReduceMotion; gameState.AutoSaveIntervalSeconds = state.AutoSaveIntervalSeconds; gameState.RankingOrigin = new RankingOrigin { SourceProfileId = gameState.ProfileId, SourceRevision = gameState.SaveRevision }; gameState.ProfileId = Guid.NewGuid().ToString("N"); gameState.SaveRevision = 0L; gameState.RankingPreferences = new RankingPreferences { OptIn = state.RankingPreferences.OptIn }; IdleGame idleGame = new IdleGame(gameState); idleGame.Continue(); idleGame.PersistState = saveRepository.Save; if (game.State.HasStarted && game.SessionActive) { saveRepository.CreateSnapshot(game.State, SaveKind.BeforeRestore); } PocketExpeditionView pocketExpeditionView = new PocketExpeditionView(idleGame, assetLoader, audio, CloseOverlay, saveRepository, RestoreSave, rankingServerUrl); pocketExpeditionView.PassiveInteractionRequested += EnterPassiveMode; try { saveRepository.Save(gameState); } catch { pocketExpeditionView.Dispose(); throw; } view?.Dispose(); game = idleGame; view = pocketExpeditionView; saveAccumulator = 0f; audio.SetVolume((float)gameState.SoundVolumePercent / 100f); audio.SetOverlayActive(active: true, gameState.SoundEnabled); if (!overlayInteraction.IsVisible) { overlayInteraction.ToggleF8(); } ApplyOverlayInteraction(deferGameplayRelease: false); ((BaseUnityPlugin)this).Logger.LogInfo((object)("저장파일 복구 완료: " + key)); } } private void SafeSave(bool snapshot = false) { if (saveRepository == null || game == null || !game.State.HasStarted || !game.SessionActive) { return; } try { saveRepository.Save(game.State); if (snapshot) { saveRepository.CreateSnapshot(game.State, SaveKind.Auto); } } catch (Exception ex) { ((BaseUnityPlugin)this).Logger.LogError((object)("저장 실패: " + ex)); } } private void DisposeRuntime() { inputFocus?.Dispose(); view?.Dispose(); audio?.Dispose(); assetLoader?.Dispose(); assetBundle?.Dispose(); assetBundle = null; inputFocus = null; view = null; assetLoader = null; audio = null; game = null; saveRepository = null; } } } namespace PocketExpedition.Runtime { internal static class AssetLifetime { public static void Destroy(Object value) { Object.Destroy(value); } } public sealed class BundleAssetStore : IDisposable { public const string FileName = "PocketExpedition.assetbundle"; private readonly AssetBundle bundle; private readonly string root; private readonly HashSet<string> names; private readonly HashSet<AudioClip> audio = new HashSet<AudioClip>(); private bool disposed; public int Count => names.Count - 1; public BundleAssetStore(string pluginDirectory, Action<string> log) { root = Path.GetFullPath(pluginDirectory).TrimEnd(Path.DirectorySeparatorChar) + Path.DirectorySeparatorChar; string text = Path.Combine(root, "PocketExpedition.assetbundle"); bundle = AssetBundle.LoadFromFile(text); if ((Object)(object)bundle == (Object)null) { throw new InvalidDataException("Cannot load PocketExpedition.assetbundle. Install the matching DLL and assetbundle together."); } try { names = new HashSet<string>(bundle.GetAllAssetNames(), StringComparer.Ordinal); TextAsset val = bundle.LoadAsset<TextAsset>("__pocket_manifest"); if ((Object)(object)val == (Object)null || !val.text.StartsWith("PEAB1\n", StringComparison.Ordinal)) { throw new InvalidDataException("Unsupported Pocket Expedition asset bundle"); } Resources.UnloadAsset((Object)(object)val); log("AssetBundle loaded: PocketExpedition.assetbundle · " + Count + " assets · Unity " + Application.unityVersion); } catch { bundle.Unload(true); throw; } } private string Key(string path) { string text = path; if (Path.IsPathRooted(path)) { string fullPath = Path.GetFullPath(path); if (!fullPath.StartsWith(root, StringComparison.OrdinalIgnoreCase)) { throw new InvalidDataException("Asset path outside plugin: " + path); } text = fullPath.Substring(root.Length); } text = text.Replace('\\', '/'); if (text.StartsWith("Assets/", StringComparison.OrdinalIgnoreCase)) { text = text.Substring(7); } if (text.Contains("../") || text.StartsWith("/", StringComparison.Ordinal)) { throw new InvalidDataException("Invalid bundle path"); } return text.ToLowerInvariant(); } public bool Exists(string path) { if (!disposed) { return names.Contains(Key(path)); } return false; } public byte[] ReadBytes(string path) { if (disposed) { throw new ObjectDisposedException("BundleAssetStore"); } string text = Key(path); TextAsset val = bundle.LoadAsset<TextAsset>(text); if ((Object)(object)val == (Object)null) { throw new FileNotFoundException("Asset missing in bundle", text); } try { return val.bytes; } finally { Resources.UnloadAsset((Object)(object)val); } } public Stream OpenRead(string path) { return new MemoryStream(ReadBytes(path), writable: false); } public AudioClip LoadAudio(string path) { if (disposed) { throw new ObjectDisposedException("BundleAssetStore"); } AudioClip val = bundle.LoadAsset<AudioClip>(Key(path)); if ((Object)(object)val == (Object)null || val.samples <= 0) { throw new InvalidDataException("Audio missing in bundle: " + path); } audio.Add(val); return val; } public bool ReleaseAudio(AudioClip clip) { if ((Object)(object)clip == (Object)null || !audio.Remove(clip)) { return false; } Resources.UnloadAsset((Object)(object)clip); return true; } public void Dispose() { if (!disposed) { disposed = true; audio.Clear(); bundle.Unload(true); } } } public sealed class ButtonHoverFeedback : MonoBehaviour, IPointerEnterHandler, IEventSystemHandler, IPointerExitHandler { public Action? OnHover; public float HoverScale = 1.045f; private Button button; private Vector3 restingScale; private bool hovered; private float emphasis; private void Awake() { //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) button = ((Component)this).GetComponent<Button>(); restingScale = ((Component)this).transform.localScale; } public void OnPointerEnter(PointerEventData eventData) { if (!hovered && ((Selectable)button).IsInteractable()) { OnHover?.Invoke(); } hovered = true; } public void OnPointerExit(PointerEventData eventData) { hovered = false; } private void Update() { //IL_0058: 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) float num = ((hovered && ((Selectable)button).IsInteractable()) ? 1f : 0f); if (!Mathf.Approximately(emphasis, num)) { emphasis = Mathf.MoveTowards(emphasis, num, Time.unscaledDeltaTime / 0.12f); ((Component)this).transform.localScale = restingScale * Mathf.Lerp(1f, HoverScale, emphasis); } } private void OnDisable() { //IL_0019: Unknown result type (might be due to invalid IL or missing references) hovered = false; emphasis = 0f; ((Component)this).transform.localScale = restingScale; } } internal sealed class CombatDamagePopup { private readonly List<DamagePopupNumber> numbers = new List<DamagePopupNumber>(); private readonly Font numericFont; private readonly bool incoming; public RectTransform Rect { get; } public CombatDamagePopup(Transform parent, Font numericFont, bool incoming) { //IL_0041: Unknown result type (might be due to invalid IL or missing references) //IL_0047: Expected O, but got Unknown //IL_005b: Unknown result type (might be due to invalid IL or missing references) //IL_0065: Expected O, but got Unknown this.numericFont = numericFont; this.incoming = incoming; GameObject val = new GameObject(incoming ? "IncomingDamagePopups" : "AttackDamagePopups", new Type[1] { typeof(RectTransform) }); val.transform.SetParent(parent, false); Rect = (RectTransform)val.transform; } public void Show(string value, bool critical, bool heavy, float now) { //IL_0060: 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_0086: Unknown result type (might be due to invalid IL or missing references) //IL_008b: Unknown result type (might be due to invalid IL or missing references) //IL_008c: Unknown result type (might be due to invalid IL or missing references) //IL_0092: Unknown result type (might be due to invalid IL or missing references) DamagePopupNumber damagePopupNumber = null; foreach (DamagePopupNumber number in numbers) { if (number.IsAvailable(now)) { damagePopupNumber = number; break; } } if (damagePopupNumber == null) { damagePopupNumber = new DamagePopupNumber((Transform)(object)Rect, numericFont, incoming); damagePopupNumber.Rect.anchorMin = Vector2.zero; damagePopupNumber.Rect.anchorMax = Vector2.one; RectTransform rect = damagePopupNumber.Rect; Vector2 offsetMin = (damagePopupNumber.Rect.offsetMax = Vector2.zero); rect.offsetMin = offsetMin; numbers.Add(damagePopupNumber); } damagePopupNumber.Show(value, critical, heavy, now); ((Transform)Rect).SetAsLastSibling(); } public void Tick(float now, bool reducedMotion) { foreach (DamagePopupNumber number in numbers) { number.Tick(now, reducedMotion); } } } internal sealed class DamagePopupNumber { private readonly Text number; private readonly CanvasGroup group; private readonly DamageNumberGradient gradient; private readonly Outline outline; private readonly Shadow shadow; private readonly bool incoming; private float startedAt = -10f; private bool critical; public RectTransform Rect => ((Graphic)number).rectTransform; public DamagePopupNumber(Transform parent, Font numericFont, bool incoming) { //IL_0054: Unknown result type (might be due to invalid IL or missing references) //IL_005a: Expected O, but got Unknown //IL_011d: Unknown result type (might be due to invalid IL or missing references) //IL_0137: Unknown result type (might be due to invalid IL or missing references) //IL_0167: 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) this.incoming = incoming; GameObject val = new GameObject(incoming ? "IncomingDamage" : "AttackDamage", new Type[3] { typeof(RectTransform), typeof(CanvasGroup), typeof(Text) }); val.transform.SetParent(parent, false); group = val.GetComponent<CanvasGroup>(); group.blocksRaycasts = false; group.interactable = false; number = val.GetComponent<Text>(); number.font = numericFont; number.fontStyle = (FontStyle)0; number.alignment = (TextAnchor)4; number.horizontalOverflow = (HorizontalWrapMode)1; number.verticalOverflow = (VerticalWrapMode)1; number.supportRichText = false; ((Graphic)number).raycastTarget = false; gradient = val.AddComponent<DamageNumberGradient>(); shadow = val.AddComponent<Shadow>(); shadow.effectColor = new Color(0.12f, 0.025f, 0.018f, 0.95f); shadow.effectDistance = new Vector2(4f, -5f); outline = val.AddComponent<Outline>(); ((Shadow)outline).effectColor = new Color(0.065f, 0.035f, 0.028f, 1f); ((Shadow)outline).effectDistance = new Vector2(2f, -2f); val.SetActive(false); } public bool IsAvailable(float now) { if (((Component)number).gameObject.activeSelf) { return now - startedAt >= 0.75f; } return true; } public void Show(string value, bool isCritical, bool heavy, float now) { //IL_00a6: Unknown result type (might be due to invalid IL or missing references) //IL_00ab: Unknown result type (might be due to invalid IL or missing references) //IL_0090: Unknown result type (might be due to invalid IL or missing references) //IL_007a: Unknown result type (might be due to invalid IL or missing references) //IL_0101: Unknown result type (might be due to invalid IL or missing references) //IL_0106: Unknown result type (might be due to invalid IL or missing references) //IL_00eb: 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_0148: 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_0194: 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_0172: Unknown result type (might be due to invalid IL or missing references) //IL_01c7: 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) startedAt = now; critical = isCritical && !incoming; number.text = value; number.fontSize = ((!incoming) ? (critical ? 64 : 40) : (heavy ? 43 : 36)); gradient.Top = (incoming ? new Color(1f, 0.76f, 0.65f) : (critical ? new Color(1f, 0.88f, 0.12f) : new Color(0.98f, 1f, 1f))); gradient.Bottom = (incoming ? new Color(0.98f, 0.1f, 0.14f) : (critical ? new Color(1f, 0.32f, 0.015f) : new Color(0.68f, 0.79f, 0.88f))); ((Shadow)outline).effectColor = (critical ? new Color(0.23f, 0.065f, 0.005f, 1f) : new Color(0.065f, 0.035f, 0.028f, 1f)); ((Shadow)outline).effectDistance = (critical ? new Vector2(3f, -3f) : (incoming ? new Vector2(2f, -2f) : new Vector2(1.5f, -1.5f))); shadow.effectDistance = (critical ? new Vector2(5f, -6f) : new Vector2(4f, -5f)); ((Graphic)number).SetVerticesDirty(); group.alpha = 1f; ((Component)number).gameObject.SetActive(true); ((Transform)Rect).SetAsLastSibling(); } public void Tick(float now, bool reducedMotion) { //IL_00e3: Unknown result type (might be due to invalid IL or missing references) //IL_00f3: Unknown result type (might be due to invalid IL or missing references) //IL_0119: Unknown result type (might be due to invalid IL or missing references) //IL_0112: 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) if (((Component)number).gameObject.activeSelf) { float num = now - startedAt; if (num >= 0.75f) { ((Component)number).gameObject.SetActive(false); return; } float num2 = Mathf.Clamp01(num / 0.75f); group.alpha = 1f - Mathf.SmoothStep(0f, 1f, Mathf.InverseLerp(0.5f, 0.75f, num)); float num3 = ((num < 0.075f) ? Mathf.Lerp(0.68f, critical ? 1.32f : 1.18f, num / 0.075f) : Mathf.Lerp(critical ? 1.32f : 1.18f, 1f, Mathf.SmoothStep(0f, 1f, (num - 0.075f) / 0.18f))); ((Transform)Rect).localScale = Vector3.one * (reducedMotion ? 1f : num3); Rect.anchoredPosition = (Vector2)(reducedMotion ? Vector2.zero : new Vector2(0f, 72f * num2)); ((Transform)Rect).localRotation = Quaternion.identity; } } } public sealed class DamageNumberGradient : BaseMeshEffect { public Color Top = Color.white; public Color Bottom = Color.white; public override void ModifyMesh(VertexHelper mesh) { //IL_0013: 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_0034: Unknown result type (might be due to invalid IL or missing references) //IL_0045: 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_0073: 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_0080: 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_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_00a0: 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_00b6: 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_00c3: Unknown result type (might be due to invalid IL or missing references) if (((UIBehaviour)this).IsActive() && mesh.currentVertCount != 0) { UIVertex val = default(UIVertex); float num = float.MaxValue; float num2 = float.MinValue; for (int i = 0; i < mesh.currentVertCount; i++) { mesh.PopulateUIVertex(ref val, i); num = Mathf.Min(num, val.position.y); num2 = Mathf.Max(num2, val.position.y); } for (int j = 0; j < mesh.currentVertCount; j++) { mesh.PopulateUIVertex(ref val, j); Color val2 = Color.Lerp(Bottom, Top, Mathf.InverseLerp(num, num2, val.position.y)); val2.a *= (float)(int)val.color.a / 255f; val.color = Color32.op_Implicit(val2); mesh.SetUIVertex(val, j); } } } } public static class CombatVisualRules { public static int AttackTier(int level) { if (level < 150) { if (level < 75) { return (level >= 25) ? 1 : 0; } return 2; } return 3; } public static void CooldownBoundary(double remaining, out double x, out double y) { double num = Math.Max(0.0, Math.Min(1.0, remaining)) * Math.PI * 2.0; x = 0.0 - Math.Sin(num); y = Math.Cos(num); double num2 = 0.5 / Math.Max(Math.Abs(x), Math.Abs(y)); x *= num2; y *= num2; } public static float PetCenterDistance(float heroSide, float petSide, float pulse) { return heroSide * 0.5f + petSide * pulse * 0.5f + 12f; } } public sealed class DungeonUiSkin : IDisposable { private readonly Sprite[] sprites = (Sprite[])(object)new Sprite[5]; private readonly Texture2D[] textures = (Texture2D[])(object)new Texture2D[5]; private readonly Sprite[] routeSprites = (Sprite[])(object)new Sprite[3]; private readonly Sprite[] gaugeSprites = (Sprite[])(object)new Sprite[4]; public void Gauge(Image image, int kind) { //IL_0127: 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: Expected O, but got Unknown //IL_00de: Unknown result type (might be due to invalid IL or missing references) //IL_00ed: 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_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) if ((Object)(object)gaugeSprites[kind] == (Object)null) { Texture2D val = new Texture2D(128, 32, (TextureFormat)4, false); ((Object)val).name = "DungeonGauge_" + kind; ((Texture)val).filterMode = (FilterMode)1; ((Texture)val).wrapMode = (TextureWrapMode)1; byte[] array = RoundedGaugePixels.Create(kind); Color32[] array2 = (Color32[])(object)new Color32[4096]; for (int i = 0; i < 32; i++) { for (int j = 0; j < 128; j++) { int num = (i * 128 + j) * 4; array2[i * 128 + j] = new Color32(array[num], array[num + 1], array[num + 2], array[num + 3]); } } val.SetPixels32(array2); val.Apply(false, true); gaugeSprites[kind] = Sprite.Create(val, new Rect(0f, 0f, 128f, 32f), new Vector2(0.5f, 0.5f), 100f, 0u, (SpriteMeshType)0, new Vector4(14f, 14f, 14f, 14f)); } image.sprite = gaugeSprites[kind]; ((Graphic)image).color = Color.white; ((Graphic)image).raycastTarget = false; image.type = (Type)1; image.pixelsPerUnitMultiplier = 1.4f; } public Sprite RouteSprite(int kind) { //IL_001f: Unknown result type (might be due to invalid IL or missing references) //IL_0025: Expected O, but got Unknown //IL_00db: 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_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) if ((Object)(object)routeSprites[kind] != (Object)null) { return routeSprites[kind]; } Texture2D val = new Texture2D(64, 64, (TextureFormat)4, false); ((Object)val).name = "DungeonRoute_" + kind; ((Texture)val).filterMode = (FilterMode)0; ((Texture)val).wrapMode = (TextureWrapMode)1; byte[] array = DungeonRouteArt.Create(kind); Color32[] array2 = (Color32[])(object)new Color32[4096]; for (int i = 0; i < 64; i++) { for (int j = 0; j < 64; j++) { int num = (i * 64 + j) * 4; array2[(63 - i) * 64 + j] = new Color32(array[num], array[num + 1], array[num + 2], array[num + 3]); } } val.SetPixels32(array2); val.Apply(false, true); return routeSprites[kind] = Sprite.Create(val, new Rect(0f, 0f, 64f, 64f), new Vector2(0.5f, 0.5f), 100f); } public DungeonUiSkin() { //IL_0049: Unknown result type (might be due to invalid IL or missing references) //IL_004f: Expected O, but got Unknown //IL_0120: Unknown result type (might be due to invalid IL or missing references) //IL_012f: Unknown result type (might be due to invalid IL or missing references) //IL_014f: 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) for (int i = 0; i < sprites.Length; i++) { Texture2D val = new Texture2D(128, 128, (TextureFormat)4, false); ((Object)val).name = "DungeonSkin_" + i; ((Texture)val).filterMode = (FilterMode)0; ((Texture)val).wrapMode = (TextureWrapMode)1; byte[] array = DungeonSkinPixels.Create(i); Color32[] array2 = (Color32[])(object)new Color32[16384]; for (int j = 0; j < 128; j++) { for (int k = 0; k < 128; k++) { int num = (j * 128 + k) * 4; array2[(127 - j) * 128 + k] = new Color32(array[num], array[num + 1], array[num + 2], array[num + 3]); } } val.SetPixels32(array2); val.Apply(false, true); textures[i] = val; sprites[i] = Sprite.Create(val, new Rect(0f, 0f, 128f, 128f), new Vector2(0.5f, 0.5f), 100f, 0u, (SpriteMeshType)0, new Vector4(20f, 20f, 20f, 20f)); } } public void Panel(Image image, string name) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) if (!(((Graphic)image).color.a < 0.1f) && !(name == "ScreenBlocker")) { int style = ((name.Contains("Gem") || name.Contains("Relic")) ? 2 : 0); Apply(image, style); } } public void Button(Image image, string name) { Apply(image, (name.Contains("Close") || name.Contains("Cancel")) ? 3 : ((!name.Contains("Buy") && !name.Contains("Start")) ? 1 : 4)); } private void Apply(Image image, int style) { //IL_0021: Unknown result type (might be due to invalid IL or missing references) image.sprite = sprites[style]; image.type = (Type)1; image.pixelsPerUnitMultiplier = 1.5f; ((Graphic)image).color = Color.white; } public void Dispose() { Sprite[] array = gaugeSprites; foreach (Sprite val in array) { if ((Object)(object)val != (Object)null) { Object.Destroy((Object)(object)val.texture); Object.Destroy((Object)(object)val); } } array = routeSprites; foreach (Sprite val2 in array) { if ((Object)(object)val2 != (Object)null) { Object.Destroy((Object)(object)val2.texture); Object.Destroy((Object)(object)val2); } } array = sprites; for (int i = 0; i < array.Length; i++) { Object.Destroy((Object)(object)array[i]); } Texture2D[] array2 = textures; for (int i = 0; i < array2.Length; i++) { Object.Destroy((Object)(object)array2[i]); } } } public sealed class InputFocusController : IDisposable { private static InputFocusController? active; private readonly Harmony harmony = new Harmony("com.pocketexpedition.inputfocus"); private readonly FieldInfo[] gameplayFields; private readonly MethodInfo? refreshHostCursor; private CursorLockMode previousLock; private bool previousVisible; private bool captured; private int releaseAfterFrame = -1; public Action? BeforeHostInput; public bool IsCaptured => captured; public InputFocusController() { //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_0010: Expected O, but got Unknown //IL_00a8: 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_00ca: Expected O, but got Unknown //IL_00ca: Expected O, but got Unknown //IL_010d: Unknown result type (might be due to invalid IL or missing references) //IL_011b: Expected O, but got Unknown //IL_017e: Unknown result type (might be due to invalid IL or missing references) //IL_018b: Expected O, but got Unknown Type type = AccessTools.TypeByName("CharacterInput") ?? throw new InvalidOperationException("PEAK CharacterInput adapter unavailable."); gameplayFields = (from f in type.GetFields(BindingFlags.Instance | BindingFlags.Public) where (f.FieldType == typeof(bool) && f.Name != "pauseWasPressed" && f.Name != "pushToTalkPressed" && f.Name != "itemSwitchBlocked") || f.Name == "movementInput" || f.Name == "lookInput" || f.Name == "scrollInput" select f).ToArray(); MethodInfo methodInfo = AccessTools.Method(type, "Sample", (Type[])null, (Type[])null) ?? throw new InvalidOperationException("PEAK CharacterInput.Sample unavailable."); active = this; try { harmony.Patch((MethodBase)methodInfo, new HarmonyMethod(typeof(InputFocusController), "BeforeSample", (Type[])null), new HarmonyMethod(typeof(InputFocusController), "AfterSample", (Type[])null), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null); string[] array = new string[2] { "HotbarKeyWasPressed", "HotbarKeyIsPressed" }; foreach (string text in array) { harmony.Patch((MethodBase)AccessTools.Method(type, text, (Type[])null, (Type[])null), new HarmonyMethod(typeof(InputFocusController), "BeforeHotbar", (Type[])null), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null); } Type type2 = AccessTools.TypeByName("CursorHandler"); refreshHostCursor = ((type2 == null) ? null : AccessTools.Method(type2, "Update", (Type[])null, (Type[])null)); if (refreshHostCursor != null) { harmony.Patch((MethodBase)refreshHostCursor, (HarmonyMethod)null, new HarmonyMethod(typeof(InputFocusController), "AfterCursor", (Type[])null), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null); } } catch { Dispose(); throw; } } private static void BeforeSample() { active?.BeforeHostInput?.Invoke(); active?.Tick(); } private static void AfterSample(object __instance) { //IL_006b: Unknown result type (might be due to invalid IL or missing references) if (active != null && active.captured) { FieldInfo[] array = active.gameplayFields; foreach (FieldInfo fieldInfo in array) { fieldInfo.SetValue(__instance, (fieldInfo.FieldType == typeof(Vector2)) ? ((object)Vector2.zero) : ((fieldInfo.FieldType == typeof(float)) ? ((object)0f) : ((object)false))); } } } private static bool BeforeHotbar(ref bool __result) { if (active == null || !active.captured) { return true; } __result = false; return false; } private static void AfterCursor() { InputFocusController? inputFocusController = active; if (inputFocusController != null && inputFocusController.captured) { EnforceCursor(); } } public void CaptureForOverlay() { //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) releaseAfterFrame = -1; if (!captured) { previousLock = Cursor.lockState; previousVisible = Cursor.visible; captured = true; } EnforceCursor(); } public void Tick() { if (releaseAfterFrame >= 0 && Time.frameCount > releaseAfterFrame) { ReleaseToGame(); } if (captured) { EnforceCursor(); } } public void EnsureOverlayCursor() { if (captured) { EnforceCursor(); } } public void ReleaseAfterPointerFrame() { if (captured) { releaseAfterFrame = Time.frameCount; } } public void ReleaseToGame() { //IL_0018: Unknown result type (might be due to invalid IL or missing references) releaseAfterFrame = -1; if (!captured) { return; } captured = false; Cursor.lockState = previousLock; Cursor.visible = previousVisible; if (refreshHostCursor?.DeclaringType != null) { Object val = Object.FindAnyObjectByType(refreshHostCursor.DeclaringType); if (val != (Object)null) { refreshHostCursor.Invoke(val, null); } } } public void Dispose() { ReleaseToGame(); BeforeHostInput = null; harmony.UnpatchSelf(); if (active == this) { active = null; } } private static void EnforceCursor() { Cursor.lockState = (CursorLockMode)0; Cursor.visible = true; } } [DataContract] public sealed class ModOptions { [DataMember] public int Music = 100; [DataMember] public int Sfx = 100; [DataMember] public int Hits = 100; [DataMember] public int Ui = 100; [DataMember] public int LevelUp = 100; [DataMember] public int BackgroundQuality = 2; [DataMember] public int Effects = 2; [DataMember] public int Particles = 2; [DataMember] public int AntiAliasing; [DataMember] public bool VSync; [DataMember] public bool ShowFps = true; [DataMember] public bool DisplayOptionsInitialized; [DataMember] public int[] Keys = DefaultKeys(); private static ModOptions? current; public static ModOptions Current => current ?? (current = Load()); private static string FilePath => Path.Combine(Paths.ConfigPath, "PocketExpedition", "options.json"); private static int[] DefaultKeys() { int[] array = new int[13]; for (int i = 0; i < 4; i++) { array[i] = 41 + i; } return array; } private static ModOptions Load() { ModOptions modOptions = new ModOptions(); try { if (File.Exists(FilePath)) { using FileStream stream = File.OpenRead(FilePath); modOptions = (ModOptions)new DataContractJsonSerializer(typeof(ModOptions)).ReadObject(stream); } } catch { } if (modOptions.Keys == null || modOptions.Keys.Length != 13) { modOptions.Keys = DefaultKeys(); } if (!modOptions.DisplayOptionsInitialized) { modOptions.AntiAliasing = QualitySettings.antiAliasing; modOptions.VSync = QualitySettings.vSyncCount > 0; modOptions.ShowFps = true; modOptions.DisplayOptionsInitialized = true; } if (Array.IndexOf(new int[4] { 0, 2, 4, 8 }, modOptions.AntiAliasing) < 0) { modOptions.AntiAliasing = 0; } modOptions.Music = Clamp(modOptions.Music); modOptions.Sfx = Clamp(modOptions.Sfx); modOptions.Hits = Clamp(modOptions.Hits); modOptions.Ui = Clamp(modOptions.Ui); modOptions.LevelUp = Clamp(modOptions.LevelUp); modOptions.BackgroundQuality = Math.Max(0, Math.Min(2, modOptions.BackgroundQuality)); modOptions.Effects = Math.Max(0, Math.Min(2, modOptions.Effects)); modOptions.Particles = Math.Max(0, Math.Min(2, modOptions.Particles)); return modOptions; } private static int Clamp(int v) { return Math.Max(0, Math.Min(100, v)); } public void Save() { Directory.CreateDirectory(Path.GetDirectoryName(FilePath)); using (FileStream fileStream = new FileStream(FilePath + ".tmp", FileMode.Create, FileAccess.Write, FileShare.None)) { new DataContractJsonSerializer(typeof(ModOptions)).WriteObject(fileStream, this); fileStream.Flush(flushToDisk: true); } if (File.Exists(FilePath)) { File.Replace(FilePath + ".tmp", FilePath, null); } else { File.Move(FilePath + ".tmp", FilePath); } } } public sealed class PixelAssetLoader : IDisposable { public const int StructuredFrameCount = 64; private const int StructuredGridColumns = 8; private const int StructuredGridRows = 8; private readonly List<Object> ownedObjects = new List<Object>(); private readonly SpriteActionCache speciesActions; private readonly SpriteActionCache equipmentActions; private static readonly string[] EquipmentActionNames = new string[8] { "Idle", "Run", "Attack_A", "Attack_B", "Skill", "Hurt", "Death", "Victory" }; private static readonly string[] HeroStructuredFiles = new string[8] { "Character_Idle.png", "Character_Run.png", "Character_Attack_A.png", "Character_Attack_B.png", "Character_Skill.png", "Character_Hurt.png", "Character_Death.png", "Character_Victory.png" }; private static readonly string[] MonsterAStructuredBases = new string[8] { "Monster_A_Slime", "Monster_A_Bat", "Monster_A_Skeleton", "Monster_A_Lava_Golem", "Monster_A_Mushroom", "Monster_A_Ice_Golem", "Monster_A_Wraith", "Monster_A_Mimic" }; private static readonly string[] MonsterBStructuredBases = new string[8] { "Monster_B_Rat", "Monster_B_Crystal_Beast", "Monster_B_Skull_Shaman", "Monster_B_Water_Wraith", "Monster_B_Magma_Hound", "Monster_B_Frost_Ranger", "Monster_B_Cursed_Tome", "Monster_B_Void_Eye" }; private static readonly string[] BossStructuredBases = new string[8] { "Boss_Slime_Keeper", "Boss_Bat_Queen", "Boss_Spore_Lord", "Boss_Oblivion_Knight", "Boss_Lava_Titan", "Boss_Frost_King", "Boss_Cursed_Librarian", "Boss_Void_Observer" }; private static readonly string[] MonsterAStructuredIdleFiles = ActionFiles(MonsterAStructuredBases, "_Idle"); private static readonly string[] MonsterAStructuredAttackFiles = ActionFiles(MonsterAStructuredBases, "_Attack"); private static readonly string[] MonsterAStructuredHitFiles = ActionFiles(MonsterAStructuredBases, "_Hurt"); private static readonly string[] MonsterAStructuredDeathFiles = ActionFiles(MonsterAStructuredBases, "_Death"); private static readonly string[] MonsterBStructuredIdleFiles = ActionFiles(MonsterBStructuredBases, "_Idle"); private static readonly string[] MonsterBStructuredAttackFiles = ActionFiles(MonsterBStructuredBases, "_Attack"); private static readonly string[] MonsterBStructuredHitFiles = ActionFiles(MonsterBStructuredBases, "_Hurt"); private static readonly string[] MonsterBStructuredDeathFiles = ActionFiles(MonsterBStructuredBases, "_Death"); private static readonly string[] BossStructuredIdleFiles = ActionFiles(BossStructuredBases, "_Idle"); private static readonly string[] BossStructuredAttackFiles = ActionFiles(BossStructuredBases, "_Attack"); private static readonly string[] BossStructuredHitFiles = ActionFiles(BossStructuredBases, "_Hurt"); private static readonly string[] BossStructuredDeathFiles = ActionFiles(BossStructuredBases, "_Death"); private static readonly string[] HeroStripFiles = new string[8] { "hero_idle.png", "hero_run.png", "hero_attack_a.png", "hero_attack_b.png", "hero_skill.png", "hero_hurt.png", "hero_death.png", "hero_victory.png" }; private static readonly string[] MonsterAStripFiles = new string[8] { "monster_a_slime.png", "monster_a_bat.png", "monster_a_skeleton.png", "monster_a_lava_golem.png", "monster_a_mushroom.png", "monster_a_ice_golem.png", "monster_a_wraith.png", "monster_a_mimic.png" }; private static readonly string[] MonsterBStripFiles = new string[8] { "monster_b_rat.png", "monster_b_crystal_beast.png", "monster_b_skull_shaman.png", "monster_b_water_wraith.png", "monster_b_magma_hound.png", "monster_b_frost_ranger.png", "monster_b_cursed_tome.png", "monster_b_void_eye.png" }; private static readonly string[] BossStripFiles = new string[8] { "boss_slime_keeper.png", "boss_bat_queen.png", "boss_spore_lord.png", "boss_oblivion_knight.png", "boss_lava_titan.png", "boss_frost_king.png", "boss_cursed_librarian.png", "boss_void_observer.png" }; private readonly Sprite?[] menuSymbols = (Sprite?[])(object)new Sprite[2]; public BundleAssetStore Bundle { get; } public Sprite[] HeroFrames { get; private set; } = Array.Empty<Sprite>(); public Sprite? HeroFrontFace { get; private set; } public Sprite? HeroFrontBody { get; private set; } public Sprite?[] BasicAttackEffects { get; } = (Sprite?[])(object)new Sprite[3]; public Sprite[] MonsterFramesA { get; private set; } = Array.Empty<Sprite>(); public Sprite[] MonsterFramesB { get; private set; } = Array.Empty<Sprite>(); public Sprite[] MonsterAttackFramesA { get; private set; } = Array.Empty<Sprite>(); public Sprite[] MonsterAttackFramesB { get; private set; } = Array.Empty<Sprite>(); public Sprite[] MonsterHitFramesA { get; private set; } = Array.Empty<Sprite>(); public Sprite[] MonsterHitFramesB { get; private set; } = Array.Empty<Sprite>(); public Sprite[] MonsterDeathFramesA { get; private set; } = Array.Empty<Sprite>(); public Sprite[] MonsterDeathFramesB { get; private set; } = Array.Empty<Sprite>(); public Sprite[] BossFrames { get; private set; } = Array.Empty<Sprite>(); public Sprite[] BossAttackFrames { get; private set; } = Array.Empty<Sprite>(); public Sprite[] BossHitFrames { get; private set; } = Array.Empty<Sprite>(); public Sprite[] BossDeathFrames { get; private set; } = Array.Empty<Sprite>(); public Sprite[] EffectFrames { get; private set; } = Array.Empty<Sprite>(); public Sprite[] CombatEffectFrames { get; private set; } = Array.Empty<Sprite>(); public Sprite? LevelUpEffect { get; private set; } public Sprite? QuestCompleteEffect { get; private set; } public Sprite?[] SkillEffects { get; } = (Sprite?[])(object)new Sprite[4]; public Sprite[] UiIcons { get; private set; } = Array.Empty<Sprite>(); public Sprite[] EquipmentIcons { get; private set; } = Array.Empty<Sprite>(); public Sprite?[] EquipmentVisuals { get; } = (Sprite?[])(object)new Sprite[18]; public Sprite[] Backgrounds { get; private set; } = Array.Empty<Sprite>(); public Sprite[] TitleBackground { get; private set; } = Array.Empty<Sprite>(); public Sprite?[] WindowGlyphs { get; } = (Sprite?[])(object)new Sprite[4]; public Texture2D?[] ResizeCursors { get; } = (Texture2D?[])(object)new Texture2D[2]; public bool IsComplete { get; private set; } public string AssetDirectory { get; private set; } = ""; public PixelAssetLoader(BundleAssetStore bundle) { Bundle = bundle; speciesActions = new SpriteActionCache(6, bundle.OpenRead); equipmentActions = new SpriteActionCache(32, bundle.OpenRead); } public Sprite EquipmentFrame(int itemId, int action, int frame) { return equipmentActions.Get(Path.Combine(AssetDirectory, "EquipmentVisuals", "Actions", itemId + "_" + EquipmentActionNames[action] + ".png"))[frame]; } public Sprite ArmedHeroFrame(int action, int frame) { return equipmentActions.Get(Path.Combine(AssetDirectory, "EquipmentVisuals", "Actions", "hero_" + EquipmentActionNames[action] + ".png"))[frame]; } public Sprite[] SpeciesFrames(int species, string action) { return speciesActions.Get(Path.Combine(AssetDirectory, "NewSpecies", CombatSoundCatalog.SpeciesIds[species] + "_" + action + ".png")); } public Sprite[] GuardianFrames(string action) { return speciesActions.Get(Path.Combine(AssetDirectory, "Guardian", "Guardian_" + action + ".png")); } private static string[] ActionFiles(string[] bases, string suffix) { string[] array = new string[bases.Length]; for (int i = 0; i < bases.Length; i++) { array[i] = bases[i] + suffix + ".png"; } return array; } public void Load(string pluginDirectory, Action<string> log) { //IL_0063: Unknown result type (might be due to invalid IL or missing references) //IL_00c3: Unknown result type (might be due to invalid IL or missing references) //IL_0108: 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_0192: Unknown result type (might be due to invalid IL or missing references) //IL_01e2: 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_026c: Unknown result type (might be due to invalid IL or missing references) //IL_02bc: 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_0346: Unknown result type (might be due to invalid IL or missing references) //IL_0398: Unknown result type (might be due to invalid IL or missing references) //IL_03de: 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_046d: Unknown result type (might be due to invalid IL or missing references) //IL_04c0: Unknown result type (might be due to invalid IL or missing references) //IL_0513: Unknown result type (might be due to invalid IL or missing references) //IL_0554: Unknown result type (might be due to invalid IL or missing references) //IL_05f0: Unknown result type (might be due to invalid IL or missing references) //IL_0693: Unknown result type (might be due to invalid IL or missing references) //IL_074b: Unknown result type (might be due to invalid IL or missing references) //IL_0752: Expected O, but got Unknown //IL_0817: Unknown result type (might be due to invalid IL or missing references) //IL_08ad: Unknown result type (might be due to invalid IL or missing references) //IL_0947: Unknown result type (might be due to invalid IL or missing references) //IL_09b0: Unknown result type (might be due to invalid IL or missing references) //IL_0a34: Unknown result type (might be due to invalid IL or missing references) string assetDirectory = Path.Combine(pluginDirectory, "Assets"); AssetDirectory = assetDirectory; TitleBackground = LoadGrid(ResolvePath(pluginDirectory, assetDirectory, "Menu/title-dungeon-expedition.png"), 1, 1, cleanGeneratedBackground: false, new Vector2(0.5f, 0.5f), log); if (TitleBackground.Length != 0) { ((Texture)TitleBackground[0].texture).filterMode = (FilterMode)1; } HeroFrames = LoadStructuredRows(pluginDirectory, assetDirectory, "structured_v5\\characters", HeroStructuredFiles, 8, cleanGeneratedBackground: true, new Vector2(0.5f, 0f), log, () => LoadSeparatedRows(pluginDirectory, assetDirectory, "characters_v2", HeroStripFiles, ResolvePath(pluginDirectory, assetDirectory, "hero_master_8x8.png"), 8, cleanGeneratedBackground: true, new Vector2(0.5f, 0.08f), log, 24, 0)); MonsterFramesA = LoadStructuredRows(pluginDirectory, assetDirectory, "structured_v5\\monsters", MonsterAStructuredIdleFiles, 8, cleanGeneratedBackground: true, new Vector2(0.5f, 0f), log, () => LoadSeparatedRows(pluginDirectory, assetDirectory, "monsters_v2", MonsterAStripFiles, ResolvePath(pluginDirectory, assetDirectory, "monsters_a_8x8.png"), 8, cleanGeneratedBackground: true, new Vector2(0.5f, 0.08f), log, 0, 0)); MonsterAttackFramesA = LoadStructuredRows(pluginDirectory, assetDirectory, "structured_v5\\monsters", MonsterAStructuredAttackFiles, 8, cleanGeneratedBackground: true, new Vector2(0.5f, 0f), log, () => MonsterFramesA); MonsterHitFramesA = LoadStructuredRows(pluginDirectory, assetDirectory, "structured_v5\\monsters", MonsterAStructuredHitFiles, 8, cleanGeneratedBackground: true, new Vector2(0.5f, 0f), log, () => MonsterFramesA); MonsterDeathFramesA = Array.Empty<Sprite>(); MonsterFramesB = LoadStructuredRows(pluginDirectory, assetDirectory, "structured_v5\\monsters", MonsterBStructuredIdleFiles, 8, cleanGeneratedBackground: true, new Vector2(0.5f, 0f), log, () => LoadSeparatedRows(pluginDirectory, assetDirectory, "monsters_v2", MonsterBStripFiles, ResolvePath(pluginDirectory, assetDirectory, "monsters_b_8x8.png"), 8, cleanGeneratedBackground: true, new Vector2(0.5f, 0.08f), log, 0, 0)); MonsterAttackFramesB = LoadStructuredRows(pluginDirectory, assetDirectory, "structured_v5\\monsters", MonsterBStructuredAttackFiles, 8, cleanGeneratedBackground: true, new Vector2(0.5f, 0f), log, () => MonsterFramesB); MonsterHitFramesB = LoadStructuredRows(pluginDirectory, assetDirectory, "structured_v5\\monsters", MonsterBStructuredHitFiles, 8, cleanGeneratedBackground: true, new Vector2(0.5f, 0f), log, () => MonsterFramesB); MonsterDeathFramesB = Array.Empty<Sprite>(); BossFrames = LoadStructuredRows(pluginDirectory, assetDirectory, "structured_v5\\bosses", BossStructuredIdleFiles, 8, cleanGeneratedBackground: true, new Vector2(0.5f, 0f), log, () => LoadSeparatedRows(pluginDirectory, assetDirectory, "bosses_v2", BossStripFiles, ResolvePath(pluginDirectory, assetDirectory, "bosses_8x8.png"), 8, cleanGeneratedBackground: true, new Vector2(0.5f, 0.08f), log, 0, 0)); BossAttackFrames = LoadStructuredRows(pluginDirectory, assetDirectory, "structured_v5\\bosses", BossStructuredAttackFiles, 8, cleanGeneratedBackground: true, new Vector2(0.5f, 0f), log, () => BossFrames); BossHitFrames = LoadStructuredRows(pluginDirectory, assetDirectory, "structured_v5\\bosses", BossStructuredHitFiles, 8, cleanGeneratedBackground: true, new Vector2(0.5f, 0f), log, () => BossFrames); BossDeathFrames = Array.Empty<Sprite>(); EffectFrames = LoadGrid(ResolvePath(pluginDirectory, assetDirectory, "effects_8x8.png"), 8, 8, cleanGeneratedBackground: true, new Vector2(0.5f, 0.5f), log); CombatEffectFrames = LoadGrid(ResolvePath(pluginDirectory, assetDirectory, "structured_v5\\effects\\Combat_Slash_64.png"), 8, 8, cleanGeneratedBackground: false, new Vector2(0.5f, 0f), log, 0f, 0, 0, "Combat_Slash_64", 0, 8); UiIcons = LoadGrid(ResolvePath(pluginDirectory, assetDirectory, "ui_icons_8x8.png"), 8, 8, cleanGeneratedBackground: true, new Vector2(0.5f, 0.5f), log); Sprite[] array = LoadGrid(ResolvePath(pluginDirectory, assetDirectory, "SkillEffects/level-up.png"), 1, 1, cleanGeneratedBackground: false, new Vector2(0.5f, 0.5f), log); LevelUpEffect = ((array.Length == 1) ? array[0] : null); Sprite[] array2 = LoadGrid(ResolvePath(pluginDirectory, assetDirectory, "SkillEffects/quest-complete.png"), 1, 1, cleanGeneratedBackground: false, new Vector2(0.5f, 0.5f), log); QuestCompleteEffect = ((array2.Length == 1) ? array2[0] : null); Sprite[] array3 = LoadGrid(ResolvePath(pluginDirectory, assetDirectory, "Portraits/hero-front-face.png"), 1, 1, cleanGeneratedBackground: false, new Vector2(0.5f, 0.5f), log); Sprite[] array4 = LoadGrid(ResolvePath(pluginDirectory, assetDirectory, "Portraits/hero-front-body.png"), 1, 1, cleanGeneratedBackground: false, new Vector2(0.5f, 0.5f), log); HeroFrontFace = ((array3.Length == 1) ? array3[0] : null); HeroFrontBody = ((array4.Length == 1) ? array4[0] : null); string[] array5 = new string[3] { "slash-25", "slash-75", "slash-150" }; for (int num = 0; num < array5.Length; num++) { Sprite[] array6 = LoadGrid(ResolvePath(pluginDirectory, assetDirectory, "AttackEffects/" + array5[num] + ".png"), 1, 1, cleanGeneratedBackground: false, new Vector2(0.5f, 0.5f), log); BasicAttackEffects[num] = ((array6.Length == 1) ? array6[0] : null); } string[] array7 = new string[4] { "minimize", "maximize", "restore", "close" }; for (int num2 = 0; num2 < array7.Length; num2++) { Sprite[] array8 = LoadGrid(ResolvePath(pluginDirectory, assetDirectory, "WindowChrome/" + array7[num2] + ".png"), 1, 1, cleanGeneratedBackground: false, new Vector2(0.5f, 0.5f), log); WindowGlyphs[num2] = ((array8.Length == 1) ? array8[0] : null); } string[] array9 = new string[2] { "resize-nwse", "resize-nesw" }; for (int num3 = 0; num3 < array9.Length; num3++) { string text = ResolvePath(pluginDirectory, assetDirectory, "WindowChrome/" + array9[num3] + ".png"); if (!Bundle.Exists(text)) { log("Resize cursor missing: " + text); continue; } Texture2D val = new Texture2D(32, 32, (TextureFormat)4, false); ownedObjects.Add((Object)(object)val); if (ImageConversion.LoadImage(val, Bundle.ReadBytes(text), false) && ((Texture)val).width == 32 && ((Texture)val).height == 32) { ((Texture)val).filterMode = (FilterMode)0; ((Texture)val).wrapMode = (TextureWrapMode)1; ResizeCursors[num3] = val; } } string[] array10 = new string[4] { "rift-cut.png", "rally.png", "stone-ward.png", "judgment.png" }; for (int num4 = 0; num4 < array10.Length; num4++) { Sprite[] array11 = LoadGrid(ResolvePath(pluginDirectory, assetDirectory, "SkillEffects/" + array10[num4]), 1, 1, cleanGeneratedBackground: false, new Vector2(0.5f, 0.5f), log); SkillEffects[num4] = ((array11.Length == 1) ? array11[0] : null); if ((Object)(object)SkillEffects[num4] == (Object)null) { log("스킬 이펙트 누락: " + array10[num4]); } } EquipmentIcons = LoadGrid(ResolvePath(pluginDirectory, assetDirectory, "equipment_8x8.png"), 8, 8, cleanGeneratedBackground: true, new Vector2(0.5f, 0.5f), log, 0f, 0, 0, null, 0, -1, trimAlpha: true); for (int num5 = 0; num5 < 18; num5++) { EquipmentDefinition equipmentDefinition = EquipmentCatalog.Get(num5); Sprite[] array12 = LoadGrid(ResolvePath(pluginDirectory, assetDirectory, "EquipmentVisuals/" + (int)equipmentDefinition.Slot + "_" + equipmentDefinition.Tier + ".png"), 1, 1, cleanGeneratedBackground: false, new Vector2(0.5f, 0.5f), log); EquipmentVisuals[num5] = ((array12.Length == 1) ? array12[0] : null); } Backgrounds = LoadGrid(ResolvePath(pluginDirectory, assetDirectory, "dungeons_4x2.png"), 4, 2, cleanGeneratedBackground: false, new Vector2(0.5f, 0.5f), log, 1.65f); List<Sprite> list = new List<Sprite>(Backgrounds); string[] array13 = new string[2] { "forge", "crypt" }; foreach (string text2 in array13) { list.AddRange(LoadGrid(ResolvePath(pluginDirectory, assetDirectory, "ThemeBackgrounds/" + text2 + ".jpg"), 1, 1, cleanGeneratedBackground: false, new Vector2(0.5f, 0.5f), log)); } Backgrounds = list.ToArray(); IsComplete = (Object)(object)LevelUpEffect != (Object)null && HeroFrames.Length == 64 * HeroStructuredFiles.Length && MonsterFramesA.Length == 64 * MonsterAStructuredBases.Length && MonsterFramesB.Length == 64 * MonsterBStructuredBases.Length && MonsterAttackFramesA.Length == 64 * MonsterAStructuredBases.Length && MonsterAttackFramesB.Length == 64 * MonsterBStructuredBases.Length && MonsterHitFramesA.Length == 64 * MonsterAStructuredBases.Length && MonsterHitFramesB.Length == 64 * MonsterBStructuredBases.Length && BossFrames.Length == 64 * BossStructuredBases.Length && BossAttackFrames.Length == 64 * BossStructuredBases.Length && BossHitFrames.Length == 64 * BossStructuredBases.Length && EffectFrames.Length == 64 && CombatEffectFrames.Length == 64 && Array.TrueForAll(SkillEffects, (Sprite s) => (Object)(object)s != (Object)null) && UiIcons.Length == 64 && EquipmentIcons.Length == 64 && Backgrounds.Length == 10; log(IsComplete ? "분리 스프라이트 시트와 던전 테마 10개 로드 완료" : "일부 에셋이 누락되어 폴백 표시를 사용함"); } public Sprite? Icon(int row, int column) { return At(UiIcons, row, column); } public Sprite? Equipment(int row, int column) { return At(EquipmentIcons, row, column); } public Sprite? EquipmentVisual(int id) { if (id < 0 || id >= EquipmentVisuals.Length) { return null; } return EquipmentVisuals[id]; } public Sprite? Effect(int row, int column) { return At(EffectFrames, row, column); } private static Sprite? At(Sprite[] frames, int row, int column) { int num = Math.Max(0, row) * 8 + Math.Max(0, column); if (num >= frames.Length) { return null; } return frames[num]; } private string ResolvePath(string pluginDirectory, string assetDirectory, string fileName) { string text = Path.Combine(assetDirectory, fileName); if (!Bundle.Exists(text)) { return Path.Combine(pluginDirectory, fileName); } return text; } private string ResolveSeparatedPath(string pluginDirectory, string assetDirectory, string folder, string fileName) { string text = Path.Combine(assetDirectory, folder, fileName); if (Bundle.Exists(text)) { return text; } string text2 = Path.Combine(pluginDirectory, folder, fileName); if (!Bundle.Exists(text2)) { return text; } return text2; } private static Sprite[] FirstRow(Sprite[] frames, int columns) { if (frames == null || frames.Length < columns) { return Array.Empty<Sprite>(); } Sprite[] array = (Sprite[])(object)new Sprite[columns]; Array.Copy(frames, 0, array, 0, columns); return array; } private Sprite[] LoadStructuredRows(string pluginDirectory, string assetDirectory, string folder, string[] rowFiles, int columns, bool cleanGeneratedBackground, Vector2 pivot, Action<string> log, Func<Sprite[]> fallbackLoader) { //IL_0041: Unknown result type (might be due to invalid IL or missing references) Sprite[] array = (Sprite[])(object)new Sprite[64 * rowFiles.Length]; bool[] array2 = new bool[rowFiles.Length]; for (int i = 0; i < rowFiles.Length; i++) { string path = ResolveSeparatedPath(pluginDirectory, assetDirectory, folder, rowFiles[i]); if (Bundle.Exists(path)) { Sprite[] array3 = LoadGrid(path, 8, 8, cleanGeneratedBackground: false, pivot, log, 0f, 0, 0, Path.GetFileNameWithoutExtension(rowFiles[i]), 0, 8); if (array3.Length >= 64) { Array.Copy(array3, 0, array, i * 64, 64); array2[i] = true; } } } bool flag = false; for (int j = 0; j < array2.Length; j++) { if (!array2[j]) { flag = true; break; } } if (!flag) { return array; } Sprite[] array4 = fallbackLoader(); if (array4.Length == 0) { return array; } for (int k = 0; k < array2.Length; k++) { if (!array2[k]) { int num = k * columns; int num2 = k * 64; for (int l = 0; l < 64; l++) { array[num2 + l] = array4[(num + l) % array4.Length]; } } } return array; } private Sprite[] LoadSeparatedRows(string pluginDirectory, string assetDirectory, string folder, string[] rowFiles, string combinedPath, int columns, bool cleanGeneratedBackground, Vector2 pivot, Action<string> log, int edgeCropTop, int edgeCropBottom) { //IL_0043: 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) Sprite[] array = (Sprite[])(object)new Sprite[columns * rowFiles.Length]; bool[] array2 = new bool[rowFiles.Length]; for (int i = 0; i < rowFiles.Length; i++) { string path = ResolveSeparatedPath(pluginDirectory, assetDirectory, folder, rowFiles[i]); if (Bundle.Exists(path)) { Sprite[] array3 = LoadGrid(path, columns, 1, cleanGeneratedBackground, pivot, log, 0f, (i != 0) ? edgeCropTop : 0, (i != rowFiles.Length - 1 && i != 0) ? edgeCropBottom : 0); if (array3.Length == columns) { Array.Copy(array3, 0, array, i * columns, columns); array2[i] = true; } } } bool flag = false; for (int j = 0; j < array2.Length; j++) { if (!array2[j]) { flag = true; break; } } if (!flag) { return array; } Sprite[] array4 = LoadGrid(combinedPath, columns, rowFiles.Length, cleanGeneratedBackground, pivot, log); if (array4.Length != array.Length) { return array; } for (int k = 0; k < array2.Length; k++) { if (!array2[k]) { Array.Copy(array4, k * columns, array, k * columns, columns); } } return array; } public void Dispose() { speciesActions.Dispose(); equipmentActions.Dispose(); for (int num = ownedObjects.Count - 1; num >= 0; num--) { if (ownedObjects[num] != (Object)null) { AssetLifetime.Destroy(ownedObjects[num]); } } ownedObjects.Clear(); } private Sprite[] LoadGrid(string path, int columns, int rows, bool cleanGeneratedBackground, Vector2 pivot, Action<string> log, float cropAspect = 0f, int edgeCropTop = 0, int edgeCropBottom = 0, string? spriteNamePrefix = null, int firstRow = 0, int rowCount = -1, bool trimAlpha = false) { //IL_002b: Unknown result type (might be due to invalid IL or missing references) //IL_0031: Expected O, but got Unknown //IL_0347: Unknown result type (might be due to invalid IL or missing references) //IL_034e: Expected O, but got Unknown //IL_03ff: Unknown result type (might be due to invalid IL or missing references) //IL_0404: Unknown result type (might be due to invalid IL or missing references) if (!Bundle.Exists(path)) { log("에셋 누락: " + path); return Array.Empty<Sprite>(); } try { Texture2D val = new Texture2D(2, 2, (TextureFormat)4, false); ((Object)val).name = Path.GetFileNameWithoutExtension(path); if (!ImageConversion.LoadImage(val, Bundle.ReadBytes(path), false)) { AssetLifetime.Destroy((Object)(object)val); return Array.Empty<Sprite>(); } if (!string.IsNullOrEmpty(spriteNamePrefix) && (((Texture)val).width != 2048 || ((Texture)val).height != 2048 || columns != 8 || rows != 8)) { log("구조형 시트 규격 오류: " + Path.GetFileName(path) + " · 2048x2048 / 8x8 필요"); AssetLifetime.Destroy((Object)(object)val); return Array.Empty<Sprite>(); } ((Texture)val).filterMode = (FilterMode)0; ((Texture)val).wrapMode = (TextureWrapMode)1; if (cleanGeneratedBackground) { RemoveGeneratedBackdrop(val); } int num = Math.Max(0, Math.Min(rows - 1, firstRow)); int num2 = ((rowCount < 0) ? rows : Math.Max(1, Math.Min(rows - num, rowCount))); Sprite[] array = (Sprite[])(object)new Sprite[columns * num2]; Rect val3 = default(Rect); for (int i = 0; i < num2; i++) { int num3 = num + i; int num4 = Mathf.RoundToInt((float)(((Texture)val).height * (rows - num3)) / (float)rows); int num5 = Mathf.RoundToInt((float)(((Texture)val).height * (rows - num3 - 1)) / (float)rows); for (int j = 0; j < columns; j++) { int num6 = Mathf.RoundToInt((float)(((Texture)val).width * j) / (float)columns); int num7 = Mathf.RoundToInt((float)(((Texture)val).width * (j + 1)) / (float)columns); int num8 = Math.Max(1, num7 - num6); int num9 = Math.Max(1, num4 - num5); if (cropAspect > 0f) { int val2 = Math.Max(1, Mathf.RoundToInt((float)num8 / cropAspect)); num9 = Math.Min(num9, val2); } int num10 = (cleanGeneratedBackground ? 2 : 0); int num11 = Math.Min(Math.Max(0, edgeCropTop), Math.Max(0, num9 - num10 * 2 - 1)); int num12 = Math.Min(Math.Max(0, edgeCropBottom), Math.Max(0, num9 - num10 * 2 - num11 - 1)); ((Rect)(ref val3))..ctor((float)(num6 + num10), (float)(num5 + num10 + num12), (float)Math.Max(1, num8 - num10 * 2), (float)Math.Max(1, num9 - num10 * 2 - num11 - num12)); if (trimAlpha) { int num13 = (int)((Rect)(ref val3)).width; int num14 = (int)((Rect)(ref val3)).height; int num15 = num13; int num16 = num14; int num17 = -1; int num18 = -1; Color[] pixels = val.GetPixels((int)((Rect)(ref val3)).x, (int)((Rect)(ref val3)).y, num13, num14); for (int k = 0; k < num14; k++) { for (int l = 0; l < num13; l++) { if (pixels[k * num13 + l].a > 0.1f) { num15 = Math.Min(num15, l); num16 = Math.Min(num16, k); num17 = Math.Max(num17, l); num18 = Math.Max(num18, k); } } } if (num17 >= num15) { ((Rect)(ref val3))..ctor(((Rect)(ref val3)).x + (float)num15, ((Rect)(ref val3)).y + (float)num16, (float)(num17 - num15 + 1), (float)(num18 - num16 + 1)); } } int num19 = Math.Max(1, Mathf.RoundToInt(((Rect)(ref val3)).width)); int num20 = Math.Max(1, Mathf.RoundToInt(((Rect)(ref val3)).height)); Texture2D val4 = new Texture2D(num19, num20, (TextureFormat)4, false); string text = (string.IsNullOrEmpty(spriteNamePrefix) ? ((Object)val).name : spriteNamePrefix); ((Object)val4).name = text + "_cell_" + num3 + "_" + j; ((Texture)val4).filterMode = (FilterMode)0; ((Texture)val4).wrapMode = (TextureWrapMode)1; val4.SetPixels(val.GetPixels(Mathf.RoundToInt(((Rect)(ref val3)).x), Mathf.RoundToInt(((Rect)(ref val3)).y), num19, num20)); val4.Apply(false, true); ownedObjects.Add((Object)(object)val4); Sprite val5 = Sprite.Create(val4, new Rect(0f, 0f, (float)num19, (float)num20), pivot, 100f, 0u, (SpriteMeshType)0); if (!string.IsNullOrEmpty(spriteNamePrefix)) { ((Object)val5).name = spriteNamePrefix + "_" + (num3 * columns + j).ToString("00"); } else { ((Object)val5).name = text + "_r" + num3.ToString("00") + "_c" + j.ToString("00"); } array[i * columns + j] = val5; ownedObjects.Add((Object)(object)val5); } } AssetLifetime.Destroy((Object)(object)val); return array; } catch (Exception ex) { log("에셋 로드 실패(" + Path.GetFileName(path) + "): " + ex.Message); return Array.Empty<Sprite>(); } } private static void RemoveGeneratedBackdrop(Texture2D texture) { Color32[] pixels = texture.GetPixels32(); if (pixels.Length == 0) { return; } int width = ((Texture)texture).width; int height = ((Texture)texture).height; int num = 0; if (pixels[0].a < 32) { num++; } if (pixels[width - 1].a < 32) { num++; } if (pixels[(height - 1) * width].a < 32) { num++; } if (pixels[^1].a < 32) { num++; } if (num >= 2) { return; } bool[] visited = new bool[pixels.Length]; Queue<int> queue = new Queue<int>(); for (int i = 0; i < width; i++) { TryEnqueue(i, pixels, visited, queue); TryEnqueue((height - 1) * width + i, pixels, visited, queue); } for (int j = 0; j < height; j++) { TryEnqueue(j * width, pixels, visited, queue); TryEnqueue(j * width + width - 1, pixels, visited, queue); } while (queue.Count > 0) { int num2 = queue.Dequeue(); pixels[num2].a = 0; int num3 = num2 % width; int num4 = num2 / width; if (num3 > 0) { TryEnqueue(num2 - 1, pixels, visited, queue); } if (num3 + 1 < width) { TryEnqueue(num2 + 1, pixels, visited, queue); } if (num4 > 0) { TryEnqueue(num2 - width, pixels, visited, queue); } if (num4 + 1 < height) { TryEnqueue(num2 + width, pixels, visited, queue); } } texture.SetPixels32(pixels); texture.Apply(false, false); } private static void TryEnqueue(int index, Color32[] pixels, bool[] visited, Queue<int> queue) { //IL_000c: Unknown result type (might be due to invalid IL or missing references) //IL_0011: Unknown result type (might be due to invalid IL or missing references) //IL_0012: 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_002e: 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_003a: 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) if (!visited[index]) { visited[index] = true; Color32 val = pixels[index]; byte num = Math.Max(val.r, Math.Max(val.g, val.b)); byte b = Math.Min(val.r, Math.Min(val.g, val.b)); bool flag = num - b < 24; bool flag2 = num < 42; bool flag3 = flag && b > 82; if (val.a < 20 || flag2 || flag3) { queue.Enqueue(index); } } } public Sprite MenuSymbol(bool ranking) { //IL_007f: 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_00b1: 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_00d1: Unknown result type (might be due to invalid IL or missing references) //IL_00e4: Unknown result type (might be due to invalid IL or missing references) //IL_00f3: Unknown result type (might be due to invalid IL or missing references) //IL_0102: Unknown result type (might be due to invalid IL or missing references) //IL_0110: 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) //IL_02d8: Unknown result type (might be due to invalid IL or missing references) //IL_02df: Unknown result type (might be due to invalid IL or missing references) //IL_02e8: Expected O, but got Unknown //IL_0314: Unknown result type (might be due to invalid IL or missing references) //IL_0323: 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_015d: Unknown result type (might be due to invalid IL or missing references) //IL_017f: Unknown result type (might be due to invalid IL or missing references) //IL_0180: Unknown result type (might be due to invalid IL or missing references) //IL_0212: 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_02a8: Unknown result type (might be due to invalid IL or missing references) //IL_02aa: 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_0259: 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) int num = (ranking ? 1 : 0); if ((Object)(object)menuSymbols[num] != (Object)null) { return menuSymbols[num]; } Color[] pixels = (Color[])(object)new Color[9216]; Color val = default(Color); ((Color)(ref val))..ctor(0.12f, 0.15f, 0.21f); Color color = default(Color); ((Color)(ref color))..ctor(1f, 0.76f, 0.22f); Color val2 = default(Color); ((Color)(ref val2))..ctor(0.7f, 0.83f, 0.94f); if (ranking) { Box(40, 15, 14, 51, val); Box(44, 18, 6, 46, new Color(0.63f, 0.34f, 0.15f)); Box(20, 54, 57, 23, val); Box(24, 58, 49, 15, val2); Box(26, 68, 45, 4, Color.white); Box(69, 13, 7, 24, color); Box(62, 31, 21, 5, color); Box(65, 36, 15, 5, color); Box(69, 41, 7, 5, color); } else { for (int i = 0; i < 96; i++) { for (int j = 0; j < 96; j++) { float num2 = (float)j - 48f; float num3 = (float)i - 48f; float num4 = (num2 - num3) * 0.70710677f; float num5 = (num2 + num3) * 0.70710677f; Color val3 = Color.clear; if (Mathf.Abs(num4) <= 8f && num5 >= -39f && num5 <= 19f) { val3 = val; } if (Mathf.Abs(num4) <= 5f && num5 >= -35f && num5 <= 17f) { ((Color)(ref val3))..ctor(0.58f, 0.29f, 0.12f); } if (num4 >= -4f && num4 <= -1f && num5 >= -34f && num5 <= 15f) { ((Color)(ref val3))..ctor(0.87f, 0.56f, 0.25f); } if (Mathf.Abs(num4) <= 25f && num5 >= 9f && num5 <= 32f) { val3 = val; } if (Mathf.Abs(num4) <= 21f && num5 >= 13f && num5 <= 28f) { val3 = val2; } if (Mathf.Abs(num4) <= 20f && num5 >= 24f && num5 <= 28f) { val3 = Color.white; } if (num4 >= 16f && num4 <= 21f && num5 >= 13f && num5 <= 24f) { ((Color)(ref val3))..ctor(0.37f, 0.5f, 0.65f); } pixels[i * 96 + j] = val3; } } } Texture2D val4 = new Texture2D(96, 96, (TextureFormat)4, false) { filterMode = (FilterMode)0, wrapMode = (TextureWrapMode)1 }; val4.SetPixels(pixels); val4.Apply(false, true); Sprite val5 = Sprite.Create(val4, new Rect(0f, 0f, 96f, 96f), new Vector2(0.5f, 0.5f), 100f, 0u, (SpriteMeshType)0); ownedObjects.Add((Object)(object)val4); ownedObjects.Add((Object)(object)val5); menuSymbols[num] = val5; return val5; void Box(int x, int y, int w, int h, Color val6) { //IL_0021: 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) for (int k = Mathf.Max(0, y); k < Mathf.Min(96, y + h); k++) { for (int l = Mathf.Max(0, x); l < Mathf.Min(96, x + w); l++) { pixels[k * 96 + l] = val6; } } } } } public sealed class PocketAudio : IDisposable { private sealed class CombatVoice { public AudioSource Source; public AudioClip? Pending; public float Started; public float ReplaceAt; public float Gain; public float PendingGain; public float DuckUntil; public bool Important; public bool PendingImportant; public bool Species; public bool PendingSpecies; } private enum Wave { Sine, Square, Triangle } private const int SampleRate = 22050; public const int MusicTrackCount = 9; public static readonly string[] MusicTrackNamesKorean = MusicCatalog.KoreanNames; public static readonly string[] MusicTrackNamesEnglish = MusicCatalog.EnglishNames; private readonly GameObject root; private readonly AudioSource music; private readonly AudioSource effects; private readonly Dictionary<string, AudioClip> clips = new Dictionary<string, AudioClip>(); private readonly Action<string> log; private const float BaseMusicVolume = 0.58f; private const float BaseEffectsVolume = 0.82f; private const float EffectGainBoost = 2f; private bool disposed; private int musicTrackIndex = -1; private readonly MusicShuffle playlist = new MusicShuffle(8); private bool musicStarted; private bool musicPaused; private bool expeditionActive; private string audioProfile = ""; private float retryMusicAt; private readonly string musicDirectory; private readonly BundleAssetStore bundle; private readonly CombatVoice[] combatVoices = new CombatVoice[6]; private float masterVolume = 1f; private int hurtIndex; private int lastImpact = -1; private float lastHurtAt = -100f; private bool overlayActive; private bool soundEnabled; private float lastHoverSound = -100f; private float lastLevelUpSound = -10f; public bool IsMusicLoading { get { //IL_001e: Unknown result type (might be due to invalid IL or missing references) //IL_0024: Invalid comparison between Unknown and I4 if ((Object)(object)music.clip != (Object)null) { return (int)music.clip.loadState == 1; } return false; } } public bool MusicLoadFailed { get; private set; } public int MusicTrackIndex => musicTrackIndex; public PocketAudio(string pluginDirectory, BundleAssetStore bundle, Action<string> log) { //IL_00a1: Unknown result type (might be due to invalid IL or missing references) //IL_00ab: Expected O, but got Unknown this.log = log; this.bundle = bundle; musicDirectory = Path.Combine(pluginDirectory, "Assets", "Music"); root = new GameObject("PocketExpeditionAudio"); Object.DontDestroyOnLoad((Object)(object)root); music = root.AddComponent<AudioSource>(); effects = root.AddComponent<AudioSource>(); for (int i = 0; i < combatVoices.Length; i++) { AudioSource val = root.AddComponent<AudioSource>(); val.playOnAwake = false; val.ignoreListenerPause = true; val.spatialBlend = 0f; combatVoices[i] = new CombatVoice { Source = val }; } music.loop = false; music.playOnAwake = false; music.ignoreListenerPause = true; effects.ignoreListenerPause = true; music.spatialBlend = 0f; effects.spatialBlend = 0f; music.priority = 0; effects.priority = 0; music.volume = 0.58f; effects.volume = 0.82f; clips["click"] = MakeTone("ui_click", 0.075f, 620f, 920f, Wave.Square, 0.36f); LoadCombatEffects(pluginDirectory, new string[4] { "player_normal.wav", "player_critical.wav", "player_hurt_01.wav", "player_hurt_02.wav" }); LoadCombatEffects(pluginDirectory, CombatSoundCatalog.SpeciesAttacks); clips["death"] = MakeTone("enemy_down", 0.28f, 260f, 55f, Wave.Triangle, 0.48f); clips["portal"] = MakeTone("portal", 0.42f, 260f, 760f, Wave.Sine, 0.4f); LoadCombatEffects(pluginDirectory, new string[1] { "level_up.wav" }); LoadCombatEffects(pluginDirectory, new string[1] { "quest_complete.ogg" }); clips["skill1"] = MakeNoiseSweep("skill_rift_cut", 0.12f, 0.28f); clips["skill2"] = MakeTone("skill_rally", 0.28f, 180f, 480f, Wave.Triangle, 0.3f); clips["skill3"] = MakeTone("skill_stone_ward", 0.32f, 620f, 260f, Wave.Triangle, 0.28f); clips["skill4"] = MakeNoiseSweep("skill_judgment", 0.2f, 0.34f); SetMusicTrack(8); log("오디오 준비 완료 · " + AudioSettings.outputSampleRate + "Hz · 던전 배경음 " + 9 + "종 · Listener 일시정지 무시"); } public void SetOverlayActive(bool active, bool enabled) { if (disposed) { return; } overlayActive = active; soundEnabled = enabled; effects.mute = !active || !enabled; CombatVoice[] array = combatVoices; foreach (CombatVoice combatVoice in array) { combatVoice.Source.mute = effects.mute; if (effects.mute) { combatVoice.Source.Stop(); combatVoice.Pending = null; } } music.mute = !active || !enabled; if (active && enabled && (Object)(object)music.clip != (Object)null) { if (musicPaused) { music.UnPause(); musicPaused = false; } else if (!musicStarted) { music.Play(); musicStarted = true; } } else if (music.isPlaying) { music.Pause(); musicPaused = true; } if (active) { log(enabled ? "오디오 재생 시작" : "오디오 설정이 꺼져 있음"); } } public void SetVolume(float normalizedVolume) { if (disposed) { return; } float num = (masterVolume = Mathf.Clamp01(normalizedVolume)); music.volume = 0.58f * num * (float)ModOptions.Current.Music / 100f; effects.volume = 0.82f * num; if (num == 0f) { CombatVoice[] array = combatVoices; foreach (CombatVoice obj in array) { obj.Source.Stop(); obj.Pending = null; } } UpdateCombatVoices(); } private void StopCombatVoices() { CombatVoice[] array = combatVoices; foreach (CombatVoice obj in array) { obj.Source.Stop(); obj.Pending = null; obj.Important = false; obj.PendingImportant = false; obj.Species = false; obj.PendingSpecies = false; } lastImpact = -1; lastHurtAt = -100f; } public void SetExpeditionActive(bool active, string profileId = "") { if (disposed) { return; } bool num = active && audioProfile != profileId; bool flag = !active && expeditionActive; if (num || flag) { audioProfile = profileId; hurtIndex = 0; StopCombatVoices(); } if (expeditionActive != active) { expeditionActive = active; if (active) { hurtIndex = 0; lastImpact = -1; lastHurtAt = -100f; } SetMusicTrack(MusicCatalog.NextForMode(active, playlist)); } } private void ReleaseClip(AudioClip clip) { if (!((Object)(object)clip == (Object)null) && !bundle.ReleaseAudio(clip)) { Object.Destroy((Object)(object)clip); } } private void SetMusicTrack(int index) { if (disposed) { return; } index = Mathf.Clamp(index, 0, 8); if (index == musicTrackIndex && !MusicLoadFailed) { return; } musicTrackIndex = index; music.Stop(); music.clip = null; if (clips.TryGetValue("music", out AudioClip value)) { ReleaseClip(value); } clips.Remove("music"); music.loop = !expeditionActive; musicStarted = false; musicPaused = false; MusicLoadFailed = false; try { AudioClip val = bundle.LoadAudio(Path.Combine(musicDirectory, MusicCatalog.FileNames[index])); clips["music"] = val; music.clip = val; if (overlayActive && soundEnabled) { music.Play(); musicStarted = true; } log("Bundle music ready · " + MusicCatalog.FileNames[index] + " · " + val.length.ToString("0.0") + "s"); } catch (Exception ex) { MusicLoadFailed = true; retryMusicAt = Time.unscaledTime + 2f; log("Bundle music failed · " + MusicCatalog.FileNames[index] + " · " + ex.Message); } } public void Tick() { if (disposed) { return; } UpdateCombatVoices(); if (overlayActive && soundEnabled && !musicPaused && !IsMusicLoading) { if (MusicLoadFailed && Time.unscaledTime >= retryMusicAt) { SetMusicTrack(MusicCatalog.NextForMode(expeditionActive, playlist)); } else if (!MusicLoadFailed && musicStarted && !music.isPlaying) { SetMusicTrack(MusicCatalog.NextForMode(expeditionActive, playlist)); } } } public void PlayHover() { if (!(Time.unscaledTime - lastHoverSound < 0.09f)) { lastHoverSound = Time.unscaledTime; Play("click", 0.22f); } } public void PlayUi() { Play("click", 0.8f); } public void PlayQuestComplete() { Play("quest_complete.ogg", 0.65f); } public void PlayAttack(bool critical) { Play(critical ? "player_critical.wav" : "player_normal.wav", 0.65f); } public void PlayHit(int speciesIndex, int impactId) { if (impactId == lastImpact) { return; } lastImpact = impactId; if (disposed || effects.mute) { return; } if (speciesIndex >= 0 && speciesIndex < CombatSoundCatalog.SpeciesAttacks.Length) { PlayCombat(CombatSoundCatalog.SpeciesAttacks[speciesIndex], 0.45f, important: false, species: true); } if (Time.unscaledTime - lastHurtAt < 0.08f) { return; } lastHurtAt = Time.unscaledTime; CombatVoice[] array = combatVoices; foreach (CombatVoice combatVoice in array) { if (combatVoice.Species) { combatVoice.DuckUntil = Time.unscaledTime + 0.12f; } } PlayCombat((hurtIndex++ % 2 == 0) ? "player_hurt_01.wav" : "player_hurt_02.wav", 0.55f, important: true, species: false); } public void PlayDeath() { Play("death", 0.9f); } public void PlayPortal() { Play("portal", 0.85f); } public void PlayLevelUp() { if (!(Time.unscaledTime - lastLevelUpSound < 0.5f)) { lastLevelUpSound = Time.unscaledTime; Play("level_up.wav", 0.8f); } } public void PlaySkill(int index) { Play("skill" + (Mathf.Clamp(index, 0, 3) + 1), 0.9f); } private void Play(string name, float volume) { if (!disposed && !effects.mute && clips.TryGetValue(name, out AudioClip value)) { int num; switch (name) { case "player_normal.wav": case "player_critical.wav": PlayCombat(name, volume, name == "player_critical.wav", species: false); return; default: num = ModOptions.Current.Sfx; break; case "level_up.wav": num = ModOptions.Current.LevelUp; break; case "click": num = ModOptions.Current.Ui; break; } int num2 = num; effects.PlayOneShot(value, Mathf.Min(1f, volume * 2f * (float)num2 / 100f)); } } private void PlayCombat(string name, float gain, bool important, bool species) { if (disposed || effects.mute || masterVolume <= 0f || !clips.TryGetValue(name, out AudioClip value)) { return; } CombatVoice combatVoice = null; CombatVoice[] array = combatVoices; foreach (CombatVoice combatVoice2 in array) { if (!combatVoice2.Source.isPlaying && (Object)(object)combatVoice2.Pending == (Object)null) { combatVoice = combatVoice2; break; } } if (combatVoice == null) { array = combatVoices; foreach (CombatVoice combatVoice3 in array) { if (!combatVoice3.Important && (Object)(object)combatVoice3.Pending == (Object)null && (combatVoice == null || combatVoice3.Started < combatVoice.Started)) { combatVoice = combatVoice3; } } if (combatVoice != null) { combatVoice.Pending = value; combatVoice.PendingGain = gain; combatVoice.PendingImportant = important; combatVoice.PendingSpecies = species; combatVoice.ReplaceAt = Time.unscaledTime + 0.02f; } } else { combatVoice.Source.clip = value; combatVoice.Gain = gain; combatVoice.Important = important; combatVoice.Species = species; combatVoice.Started = Time.unscaledTime; combatVoice.DuckUntil = (species ? (Time.unscaledTime + 0.12f) : 0f); UpdateCombatVoices(); combatVoice.Source.Play(); } } private void UpdateCombatVoices() { float[] array = new float[combatVoices.Length]; float num = 0f; for (int i = 0; i < combatVoices.Length; i++) { CombatVoice combatVoice = combatVoices[i]; if (combatVoice == null) { continue; } float num2 = 1f; if ((Object)(object)combatVoice.Pending != (Object)null) { num2 = Mathf.Clamp01((combatVoice.ReplaceAt - Time.unscaledTime) / 0.02f); if (num2 == 0f) { combatVoice.Source.Stop(); combatVoice.Source.clip = combatVoice.Pending; combatVoice.Pending = null; combatVoice.Gain = combatVoice.PendingGain; combatVoice.Important = combatVoice.PendingImportant; combatVoice.Species = combatVoice.PendingSpecies; combatVoice.DuckUntil = (combatVoice.Species ? (Time.unscaledTime + 0.12f) : 0f); combatVoice.Started = Time.unscaledTime; combatVoice.Source.Play(); num2 = 1f; } } array[i] = 0.5f * ((float)ModOptions.Current.Hits / 100f) * combatVoice.Gain * num2 * ((combatVoice.Species && Time.unscaledTime < combatVoice.DuckUntil) ? 0.6f : 1f); if (combatVoice.Source.isPlaying) { num += array[i]; } } float num3 = ((num > 0.92f) ? (0.92f / num) : 1f); for (int j = 0; j < combatVoices.Length; j++) { combatVoices[j].Source.volume = 0.82f * masterVolume * array[j] * num3; } } public void Dispose() { if (disposed) { return; } disposed = true; music.Stop(); music.clip = null; effects.Stop(); CombatVoice[] array = combatVoices; foreach (CombatVoice obj in array) { obj.Source.Stop(); obj.Source.clip = null; obj.Pending = null; } foreach (AudioClip value in clips.Values) { ReleaseClip(value); } clips.Clear(); if ((Object)(object)root != (Object)null) { Object.Destroy((Object)(object)root); } } private static AudioClip MakeTone(string name, float seconds, float from, float to, Wave wave, float gain) { int num = Math.Max(1, Mathf.RoundToInt(seconds * 22050f)); float[] array = new float[num]; double num2 = 0.0; for (int i = 0; i < num; i++) { float num3 = (float)i / (float)Math.Max(1, num - 1); float num4 = Mathf.Lerp(from, to, num3); num2 += (double)(num4 / 22050f); float num5 = Mathf.Sin(MathF.PI * Mathf.Clamp01(num3 / 0.06f)) * Mathf.Pow(1f - num3, 1.7f); array[i] = Sample(wave, num2) * num5 * gain; } AudioClip obj = AudioClip.Create(name, num, 1, 22050, false); obj.SetData(array, 0); return obj; } private static AudioClip MakeNoiseSweep(string name, float seconds, float gain) { int num = Math.Max(1, Mathf.RoundToInt(seconds * 22050f)); float[] array = new float[num]; Random random = new Random(713); float num2 = 0f; for (int i = 0; i < num; i++) { float num3 = (float)i / (float)Math.Max(1, num - 1); num2 = num2 * 0.72f + ((float)random.NextDouble() * 2f - 1f) * 0.28f; array[i] = num2 * Mathf.Sin(MathF.PI * num3) * gain; } AudioClip obj = AudioClip.Create(name, num, 1, 22050, false); obj.SetData(array, 0); return obj; } private void LoadCombatEffects(string pluginDirectory, string[] files) { foreach (string text in files) { AudioClip val = bundle.LoadAudio(Path.Combine(pluginDirectory, "Assets", "Sounds", text)); clips[text] = val; log("Bundle SFX ready · " + text + " · " + val.length.ToString("0.000") + "s"); } } private void PlayVariant(string[] files, ref int nextIndex, float volume) { if (disposed || effects.mute) { return; } for (int i = 0; i < files.Length; i++) { string text = files[nextIndex]; nextIndex = (nextIndex + 1) % files.Length; if (clips.ContainsKey(text)) { Play(text, volume); break; } } } private static float Sample(Wave wave, double phase) { double num = phase - Math.Floor(phase); return wave switch { Wave.Square => (num < 0.5) ? 1 : (-1), Wave.Triangle => (float)(1.0 - 4.0 * Math.Abs(num - 0.5)), _ => (float)Math.Sin(phase * Math.PI * 2.0), }; } } public sealed class PocketExpeditionView : IDisposable { private sealed class BidirectionalScrollRect : ScrollRect, IPointerClickHandler, IEventSystemHandler { private bool manualDragging; private bool manualDragMoved; private InputButton manualDragButton; private Vector2 lastDragLocalPosition; public override void OnScroll(PointerEventData data) { //IL_001d: 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) //IL_0069: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)((ScrollRect)this).content == (Object)null || (Object)(object)((ScrollRect)this).viewport == (Object)null || Mathf.Abs(data.scrollDelta.y) < 0.001f) { ((ScrollRect)this).OnScroll(data); return; } float num = Mathf.Clamp(Mathf.Abs(data.scrollDelta.y) * 0.08f, 0.04f, 0.25f); ((ScrollRect)this).verticalNormalizedPosition = Mathf.Clamp01(((ScrollRect)this).verticalNormalizedPosition + ((data.scrollDelta.y > 0f) ? num : (0f - num))); ((AbstractEventData)data).Use(); } public override void OnBeginDrag(PointerEventData data