Decompiled source of Loop The Gungeon v1.0.2
LoopTheGungeon.dll
Decompiled 2 hours ago
The result has been truncated due to the large size, download it to view full contents!
using System; using System.Collections; using System.Collections.Generic; using System.Diagnostics; using System.IO; using System.Reflection; using System.Reflection.Emit; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; using Alexandria.CharacterAPI; using Alexandria.DungeonAPI; using Alexandria.ItemAPI; using Alexandria.Misc; using Alexandria.NPCAPI; using BepInEx; using BepInEx.Configuration; using BepInEx.Logging; using Brave.BulletScript; using Dungeonator; using HarmonyLib; using HutongGames.PlayMaker; using InControl; using LoopTheGungeon.Config; using LoopTheGungeon.Console; using LoopTheGungeon.Content; using LoopTheGungeon.Core; using LoopTheGungeon.Patches; using LoopTheGungeon.Util; using LoopTheGungeon.Visuals; using Microsoft.CodeAnalysis; using SGUI; using UnityEngine; using UnityEngine.SceneManagement; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: AssemblyTitle("LoopTheGungeon")] [assembly: AssemblyDescription("")] [assembly: AssemblyConfiguration("")] [assembly: AssemblyCompany("")] [assembly: AssemblyProduct("LoopTheGungeon")] [assembly: AssemblyCopyright("Copyright © 2020")] [assembly: AssemblyTrademark("")] [assembly: ComVisible(false)] [assembly: Guid("d6d7a494-722e-4763-959b-c2d6b6a42b01")] [assembly: AssemblyFileVersion("1.0.0.0")] [assembly: AssemblyVersion("1.0.0.0")] namespace Microsoft.CodeAnalysis { [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] internal sealed class EmbeddedAttribute : Attribute { } } namespace System.Runtime.CompilerServices { [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] internal sealed class IsReadOnlyAttribute : Attribute { } } public static class HellRage { public struct RageSnapshot { public int Stacks; public float Duration; public float DamageMult; } public class HellRageOnCombat : MonoBehaviour { private float _currentDamageMultiplier = 1.2f; private float _currentDuration = 3f; private Color _currentFlatColor = new Color(0.5f, 0f, 0f, 0.75f); private PlayerController _owner; private Action _enteredCombatHandler; private Coroutine _activationCo; private Coroutine _rageCo; private StatModifier _damageMod; private float _rageTimeLeft; private bool _buffActive; public void Init(PlayerController owner) { _owner = owner; if (_enteredCombatHandler == null) { _enteredCombatHandler = OnEnteredCombat; } if ((Object)(object)_owner != (Object)null) { PlayerController owner2 = _owner; owner2.OnEnteredCombat = (Action)Delegate.Remove(owner2.OnEnteredCombat, _enteredCombatHandler); PlayerController owner3 = _owner; owner3.OnEnteredCombat = (Action)Delegate.Combine(owner3.OnEnteredCombat, _enteredCombatHandler); } } private void OnDestroy() { CleanupSubscriptions(); CleanupBuff(_owner); } private void CleanupSubscriptions() { if ((Object)(object)_owner != (Object)null && _enteredCombatHandler != null) { PlayerController owner = _owner; owner.OnEnteredCombat = (Action)Delegate.Remove(owner.OnEnteredCombat, _enteredCombatHandler); } _enteredCombatHandler = null; _owner = null; } private void OnEnteredCombat() { //IL_0099: Unknown result type (might be due to invalid IL or missing references) //IL_009e: Unknown result type (might be due to invalid IL or missing references) //IL_0071: Unknown result type (might be due to invalid IL or missing references) //IL_0076: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)_owner == (Object)null) { return; } int rageStacks = GetRageStacks(_owner); if (rageStacks > 0) { float num = 2f + 2f * (float)rageStacks; _currentDuration = Mathf.Min(num, 10f); float num2 = 1.2f; if (rageStacks > 4) { _currentDamageMultiplier = num2 + (float)(rageStacks - 4) * 0.1f; _currentFlatColor = new Color(0.388f, 0.067f, 0.729f, 0.75f); } else { _currentDamageMultiplier = num2; _currentFlatColor = new Color(0.5f, 0f, 0f, 0.75f); } _rageTimeLeft = _currentDuration; if (_rageCo == null) { _rageCo = ((MonoBehaviour)_owner).StartCoroutine(RageCR(_owner)); } } } private IEnumerator RageCR(PlayerController player) { yield return (object)new WaitForSeconds(0.5f); if (!_buffActive) { _buffActive = true; _damageMod = new StatModifier { amount = _currentDamageMultiplier, modifyType = (ModifyMethod)1, statToBoost = (StatType)5 }; player.ownerlessStatModifiers.Add(_damageMod); player.stats.RecalculateStats(player, false, false); if ((Object)(object)((GameActor)player).CurrentGun != (Object)null) { ((GameActor)player).CurrentGun.ForceImmediateReload(false); } } float particleCounter = 0f; while (_rageTimeLeft > 0f) { _rageTimeLeft -= BraveTime.DeltaTime; float num = ((_rageTimeLeft <= 1f) ? (1f - _rageTimeLeft) : 0f); player.baseFlatColorOverride = Vector3Extensions.WithAlpha(_currentFlatColor, Mathf.Lerp(_currentFlatColor.a, 0f, num)); if ((int)GameManager.Options.ShaderQuality != 0 && (int)GameManager.Options.ShaderQuality != 3 && Object.op_Implicit((Object)(object)player) && player.IsVisible && !((GameActor)player).IsFalling) { particleCounter += BraveTime.DeltaTime * 40f; if (particleCounter > 1f) { int num2 = Mathf.FloorToInt(particleCounter); particleCounter %= 1f; GlobalSparksDoer.DoRandomParticleBurst(num2, Vector2Extensions.ToVector3ZisY(((BraveBehaviour)player).sprite.WorldBottomLeft, 0f), Vector2Extensions.ToVector3ZisY(((BraveBehaviour)player).sprite.WorldTopRight, 0f), Vector3.up, 90f, 0.5f, (float?)null, (float?)null, (Color?)null, (SparksType)1); } } yield return null; if ((Object)(object)player == (Object)null) { break; } } CleanupBuff(player); _rageCo = null; } public void PlayActivationFx(float seconds = 2f, int burstCount = 40) { //IL_0053: Unknown result type (might be due to invalid IL or missing references) //IL_0058: Unknown result type (might be due to invalid IL or missing references) //IL_0032: Unknown result type (might be due to invalid IL or missing references) //IL_0037: Unknown result type (might be due to invalid IL or missing references) if (!((Object)(object)_owner == (Object)null)) { if (GetRageStacks(_owner) > 4) { _currentFlatColor = new Color(0.388f, 0.067f, 0.729f, 0.75f); } else { _currentFlatColor = new Color(0.5f, 0f, 0f, 0.75f); } if (_activationCo != null) { ((MonoBehaviour)_owner).StopCoroutine(_activationCo); } _activationCo = ((MonoBehaviour)_owner).StartCoroutine(ActivationFxCR(_owner, seconds, burstCount)); } } private IEnumerator ActivationFxCR(PlayerController player, float seconds, int burstCount) { if (!Object.op_Implicit((Object)(object)player)) { yield break; } try { if ((int)GameManager.Options.ShaderQuality != 0 && (int)GameManager.Options.ShaderQuality != 3 && player.IsVisible && !((GameActor)player).IsFalling && (Object)(object)((BraveBehaviour)player).sprite != (Object)null) { GlobalSparksDoer.DoRandomParticleBurst(Mathf.Max(1, burstCount), Vector2Extensions.ToVector3ZisY(((BraveBehaviour)player).sprite.WorldBottomLeft, 0f), Vector2Extensions.ToVector3ZisY(((BraveBehaviour)player).sprite.WorldTopRight, 0f), Vector3.up, 90f, 0.6f, (float?)null, (float?)null, (Color?)null, (SparksType)1); } } catch { } float t = 0f; float dur = Mathf.Max(0.05f, seconds); while (t < dur && Object.op_Implicit((Object)(object)player) && _rageCo == null) { t += BraveTime.DeltaTime; float num = 1f - Mathf.Clamp01(t / dur); player.baseFlatColorOverride = Vector3Extensions.WithAlpha(_currentFlatColor, _currentFlatColor.a * num); yield return null; } if (Object.op_Implicit((Object)(object)player)) { player.baseFlatColorOverride = Color.clear; } _activationCo = null; } private void CleanupBuff(PlayerController player) { //IL_000a: Unknown result type (might be due to invalid IL or missing references) //IL_000f: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)player != (Object)null) { player.baseFlatColorOverride = Color.clear; if (_buffActive && _damageMod != null) { player.ownerlessStatModifiers.Remove(_damageMod); player.stats.RecalculateStats(player, false, false); } } _damageMod = null; _buffActive = false; _rageTimeLeft = 0f; } } public static int GetRageStacks(PlayerController p) { if (!Object.op_Implicit((Object)(object)p)) { return 0; } MasteryShrineInteractable.ShrineRageMarker component = ((Component)p).GetComponent<MasteryShrineInteractable.ShrineRageMarker>(); if (!Object.op_Implicit((Object)(object)component)) { return 0; } return Mathf.Max(0, component.Stacks); } public static RageSnapshot GetRageSnapshot(PlayerController p) { RageSnapshot result = default(RageSnapshot); int num = (result.Stacks = GetRageStacks(p)); if (num <= 0) { result.Duration = 0f; result.DamageMult = 1f; return result; } float num2 = 2f + 2f * (float)num; result.Duration = Mathf.Min(num2, 10f); float num3 = 1.2f; if (num > 4) { result.DamageMult = num3 + (float)(num - 4) * 0.1f; } else { result.DamageMult = num3; } return result; } } namespace Mod.Patches { [HarmonyPatch(typeof(InfinilichDeathController), "HandleClockhair")] public static class Patch_InfinilichDeathController_HandleClockhair { private static bool _loopShotTriggeredThisClockhair; private static Vector2 _camVel; private const float MAX_CAM_DRIFT_FROM_LICH = 25f; private const float EDGE_UV = 0.1f; private const float PAN_SPEED_MAX = 5f; private const float PAN_ACCEL = 10f; [HarmonyPrefix] private static bool Prefix(InfinilichDeathController __instance, PlayerController interactor, ref IEnumerator __result) { __result = CustomHandleClockhair(__instance, interactor); return false; } private static IEnumerator CustomHandleClockhair(InfinilichDeathController self, PlayerController interactor) { _loopShotTriggeredThisClockhair = false; _camVel = Vector2.zero; try { GameManager.Instance.PrimaryPlayer.SetInputOverride("past"); if ((int)GameManager.Instance.CurrentGameType == 1 && Object.op_Implicit((Object)(object)GameManager.Instance.SecondaryPlayer)) { GameManager.Instance.SecondaryPlayer.SetInputOverride("past"); } GameUIRoot.Instance.ToggleLowerPanels(false, false, string.Empty); GameUIRoot.Instance.HideCoreUI(string.Empty); CameraController camera = GameManager.Instance.MainCameraController; Vector2 val = Vector2.op_Implicit(camera.OverridePosition); Vector2 desiredCamCenter = ((BraveBehaviour)((BraveBehaviour)self).aiAnimator).sprite.WorldCenter; camera.SetManualControl(true, true); _camVel = Vector2.zero; if (Vector2.Distance(val, desiredCamCenter) > 2.5f) { camera.OverridePosition = Vector2.op_Implicit(desiredCamCenter); } Transform clockhairTransform = ((GameObject)Object.Instantiate(BraveResources.Load("Clockhair", ".prefab"))).transform; ClockhairController clockhair = ((Component)clockhairTransform).GetComponent<ClockhairController>(); float elapsed = 0f; float duration = clockhair.ClockhairInDuration; Vector3 clockhairTargetPosition = Vector2.op_Implicit(((GameActor)GameManager.Instance.PrimaryPlayer).CenterPosition); Vector3 clockhairStartPosition = clockhairTargetPosition + new Vector3(-20f, 5f, 0f); ((BraveBehaviour)clockhair).renderer.enabled = true; ((BraveBehaviour)clockhair).spriteAnimator.alwaysUpdateOffscreen = true; ((BraveBehaviour)clockhair).spriteAnimator.Play("clockhair_intro"); clockhair.hourAnimator.Play("hour_hand_intro"); clockhair.minuteAnimator.Play("minute_hand_intro"); clockhair.secondAnimator.Play("second_hand_intro"); while (elapsed < duration) { if (GameManager.INVARIANT_DELTA_TIME == 0f) { elapsed += 0.05f; } elapsed += GameManager.INVARIANT_DELTA_TIME; float num = elapsed / duration; float num2 = Mathf.SmoothStep(0f, 1f, num); clockhairTargetPosition = Vector2.op_Implicit(GetTargetClockhairPosition(self, Vector3Extensions.XY(clockhairTargetPosition))); Vector3 val2 = Vector3.Slerp(clockhairStartPosition, clockhairTargetPosition, num2); clockhairTransform.position = Vector3Extensions.WithZ(val2, 0f); UpdateCameraDuringLichClockhair(camera, desiredCamCenter); UpdateEyes(self, Vector3Extensions.XY(clockhairTransform.position), isInDanger: false); if (num > 0.5f) { ((BraveBehaviour)clockhair).renderer.enabled = true; } if (num > 0.75f) { ((Component)clockhair.hourAnimator).GetComponent<Renderer>().enabled = true; ((Component)clockhair.minuteAnimator).GetComponent<Renderer>().enabled = true; ((Component)clockhair.secondAnimator).GetComponent<Renderer>().enabled = true; } ((BraveBehaviour)clockhair).sprite.UpdateZDepth(); yield return null; } clockhair.SetMotionType(1f); BraveInput currentInput = BraveInput.GetInstanceForPlayer(GameManager.Instance.PrimaryPlayer.PlayerIDX); float shotTargetTime2 = 0f; float holdDuration = 3f; Vector3 lastScreenShakeAmount = Vector3.zero; Vector3 lastJitterAmount = Vector3.zero; bool targetingPlayer; PlayerController targetedPlayer; while (true) { Transform transform = ((BraveBehaviour)clockhair).transform; transform.position -= lastJitterAmount; ((BraveBehaviour)clockhair).transform.position = Vector2.op_Implicit(GetTargetClockhairPosition(self, Vector3Extensions.XY(((BraveBehaviour)clockhair).transform.position))); ((BraveBehaviour)clockhair).sprite.UpdateZDepth(); bool num3 = CheckLichTarget(self, clockhairTransform); targetingPlayer = false; targetedPlayer = null; if (Object.op_Implicit((Object)(object)GameManager.Instance.PrimaryPlayer) && Object.op_Implicit((Object)(object)((BraveBehaviour)GameManager.Instance.PrimaryPlayer).healthHaver) && ((BraveBehaviour)GameManager.Instance.PrimaryPlayer).healthHaver.IsAlive && CheckPlayerTarget(GameManager.Instance.PrimaryPlayer, clockhairTransform)) { targetingPlayer = true; targetedPlayer = GameManager.Instance.PrimaryPlayer; } if (!targetingPlayer && (int)GameManager.Instance.CurrentGameType == 1 && Object.op_Implicit((Object)(object)GameManager.Instance.SecondaryPlayer) && Object.op_Implicit((Object)(object)((BraveBehaviour)GameManager.Instance.SecondaryPlayer).healthHaver) && ((BraveBehaviour)GameManager.Instance.SecondaryPlayer).healthHaver.IsAlive && CheckPlayerTarget(GameManager.Instance.SecondaryPlayer, clockhairTransform)) { targetingPlayer = true; targetedPlayer = GameManager.Instance.SecondaryPlayer; } bool flag = num3 || targetingPlayer; clockhair.SetMotionType(flag ? (-10f) : 1f); bool flag2 = ((OneAxisInputControl)currentInput.ActiveActions.ShootAction).IsPressed || ((OneAxisInputControl)currentInput.ActiveActions.InteractAction).IsPressed; shotTargetTime2 = ((flag2 && flag) ? (shotTargetTime2 + BraveTime.DeltaTime) : Mathf.Max(0f, shotTargetTime2 - BraveTime.DeltaTime * 3f)); UpdateCameraDuringLichClockhair(camera, desiredCamCenter); UpdateEyes(self, Vector3Extensions.XY(((BraveBehaviour)clockhair).transform.position), flag2); if ((((OneAxisInputControl)currentInput.ActiveActions.ShootAction).WasReleased || ((OneAxisInputControl)currentInput.ActiveActions.InteractAction).WasReleased) && flag && shotTargetTime2 > holdDuration && !GameManager.Instance.IsPaused) { break; } if (shotTargetTime2 > 0f) { lastScreenShakeAmount = camera.DoFrameScreenShake(Mathf.Lerp(0f, 0.5f, shotTargetTime2 / holdDuration), Mathf.Lerp(3f, 8f, shotTargetTime2 / holdDuration), Vector2.op_Implicit(Vector3.right), lastScreenShakeAmount, Time.realtimeSinceStartup); float num4 = Mathf.Lerp(0f, 0.35f, shotTargetTime2 / holdDuration); float num5 = 0.5f; float num6 = Mathf.Lerp(4f, 7f, shotTargetTime2 / holdDuration); clockhair.UpdateDistortion(num4, num5, num6); float num7 = Mathf.Lerp(2f, 0.25f, shotTargetTime2 / holdDuration); clockhair.UpdateDesat(true, num7); shotTargetTime2 = Mathf.Min(holdDuration + 0.25f, shotTargetTime2 + BraveTime.DeltaTime); float num8 = Mathf.Lerp(0f, 0.5f, (shotTargetTime2 - 1f) / (holdDuration - 1f)); Vector3 val3 = Vector2Extensions.ToVector3ZUp(Random.insideUnitCircle * num8, 0f); BraveInput.DoSustainedScreenShakeVibration(shotTargetTime2 / holdDuration * 0.8f); Transform transform2 = ((BraveBehaviour)clockhair).transform; transform2.position += val3; lastJitterAmount = val3; clockhair.SetMotionType(Mathf.Lerp(-10f, -2400f, shotTargetTime2 / holdDuration)); } else { lastJitterAmount = Vector3.zero; camera.ClearFrameScreenShake(lastScreenShakeAmount); lastScreenShakeAmount = Vector3.zero; clockhair.UpdateDistortion(0f, 0f, 0f); clockhair.UpdateDesat(false, 0f); shotTargetTime2 = 0f; BraveInput.DoSustainedScreenShakeVibration(0f); } yield return null; } camera.ClearFrameScreenShake(lastScreenShakeAmount); BraveInput.DoSustainedScreenShakeVibration(0f); BraveInput.DoVibrationForAllPlayers((Time)10, (Strength)30); ((MonoBehaviour)clockhair).StartCoroutine(clockhair.WipeoutDistortionAndFade(0.5f)); GameObjectExtensions.SetLayerRecursively(((Component)clockhair).gameObject, LayerMask.NameToLayer("Unoccluded")); Pixelator.Instance.FadeToBlack(0.2f, true, 0.2f); Pixelator.Instance.DoRenderGBuffer = false; Pixelator.Instance.LerpToLetterbox(0.45f, 0.45f); ((BraveBehaviour)clockhair).spriteAnimator.PlayAndDisableRenderer("clockhair_fire"); ((Component)clockhair.hourAnimator).GetComponent<Renderer>().enabled = false; ((Component)clockhair.minuteAnimator).GetComponent<Renderer>().enabled = false; ((Component)clockhair.secondAnimator).GetComponent<Renderer>().enabled = false; yield return null; if (!targetingPlayer || !((Object)(object)targetedPlayer != (Object)null) || _loopShotTriggeredThisClockhair) { yield break; } _loopShotTriggeredThisClockhair = true; LoopManager.PendingLichRewards = true; try { clockhair.UpdateDesat(false, 0f); } catch { } try { clockhair.UpdateDistortion(0f, 0f, 0f); } catch { } try { GameManager.Instance.PrimaryPlayer.ClearInputOverride("past"); } catch { } try { if (Object.op_Implicit((Object)(object)GameManager.Instance.SecondaryPlayer)) { GameManager.Instance.SecondaryPlayer.ClearInputOverride("past"); } } catch { } try { ((MonoBehaviour)GameManager.Instance).StopAllCoroutines(); } catch { } try { LoopManager.LoopLoadingScreenState.UseCustomLoadScreenOnce = true; } catch { } try { TimeTubeTransition.StartLoopTimeTubeThenLoop((MonoBehaviour)(object)GameManager.Instance, 0f, "Lich"); } catch { } } finally { _camVel = Vector2.zero; } } private static void UpdateCameraDuringLichClockhair(CameraController cam, Vector2 lichAnchor) { //IL_001e: Unknown result type (might be due to invalid IL or missing references) //IL_0023: Unknown result type (might be due to invalid IL or missing references) //IL_0028: Unknown result type (might be due to invalid IL or missing references) //IL_002f: Unknown result type (might be due to invalid IL or missing references) //IL_0051: Unknown result type (might be due to invalid IL or missing references) //IL_003c: Unknown result type (might be due to invalid IL or missing references) //IL_0077: Unknown result type (might be due to invalid IL or missing references) //IL_005e: Unknown result type (might be due to invalid IL or missing references) //IL_0099: Unknown result type (might be due to invalid IL or missing references) //IL_0084: Unknown result type (might be due to invalid IL or missing references) //IL_00bb: Unknown result type (might be due to invalid IL or missing references) //IL_00c5: Unknown result type (might be due to invalid IL or missing references) //IL_00ca: Unknown result type (might be due to invalid IL or missing references) //IL_00cb: Unknown result type (might be due to invalid IL or missing references) //IL_00d0: Unknown result type (might be due to invalid IL or missing references) //IL_00dc: Unknown result type (might be due to invalid IL or missing references) //IL_00e1: Unknown result type (might be due to invalid IL or missing references) //IL_00e7: Unknown result type (might be due to invalid IL or missing references) //IL_00ec: Unknown result type (might be due to invalid IL or missing references) //IL_00f1: Unknown result type (might be due to invalid IL or missing references) //IL_00fb: Unknown result type (might be due to invalid IL or missing references) //IL_0100: Unknown result type (might be due to invalid IL or missing references) //IL_0105: Unknown result type (might be due to invalid IL or missing references) //IL_0107: Unknown result type (might be due to invalid IL or missing references) //IL_0109: Unknown result type (might be due to invalid IL or missing references) //IL_00a6: Unknown result type (might be due to invalid IL or missing references) //IL_0141: Unknown result type (might be due to invalid IL or missing references) //IL_0143: Unknown result type (might be due to invalid IL or missing references) //IL_0148: Unknown result type (might be due to invalid IL or missing references) //IL_0123: Unknown result type (might be due to invalid IL or missing references) //IL_0124: Unknown result type (might be due to invalid IL or missing references) //IL_0126: Unknown result type (might be due to invalid IL or missing references) //IL_0127: Unknown result type (might be due to invalid IL or missing references) //IL_0134: Unknown result type (might be due to invalid IL or missing references) //IL_0139: Unknown result type (might be due to invalid IL or missing references) //IL_013e: Unknown result type (might be due to invalid IL or missing references) if (!((Object)(object)cam == (Object)null) && !((Object)(object)cam.Camera == (Object)null)) { Vector3 val = cam.Camera.ScreenToViewportPoint(Input.mousePosition); float num = 0f; if (val.x < 0.1f) { num = (val.x - 0.1f) / 0.1f; } else if (val.x > 0.9f) { num = (val.x - 0.9f) / 0.1f; } float num2 = 0f; if (val.y < 0.1f) { num2 = (val.y - 0.1f) / 0.1f; } else if (val.y > 0.9f) { num2 = (val.y - 0.9f) / 0.1f; } Vector2 val2 = new Vector2(num, num2) * 5f; _camVel = Vector2.MoveTowards(_camVel, val2, BraveTime.DeltaTime * 10f); Vector2 val3 = Vector2.op_Implicit(cam.OverridePosition) + _camVel * BraveTime.DeltaTime; float num3 = Vector2.Distance(val3, lichAnchor); if (num3 > 25f && num3 > 0.001f) { val3 = lichAnchor + (val3 - lichAnchor) * (25f / num3); } cam.OverridePosition = Vector2.op_Implicit(val3); } } private static bool CheckPlayerTarget(PlayerController target, Transform clockhairTransform) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_0015: Unknown result type (might be due to invalid IL or missing references) //IL_001a: Unknown result type (might be due to invalid IL or missing references) //IL_0020: Unknown result type (might be due to invalid IL or missing references) return Vector2.Distance(Vector3Extensions.XY(clockhairTransform.position) + new Vector2(-0.375f, 0.25f), ((GameActor)target).CenterPosition) < 0.625f; } private static bool CheckLichTarget(InfinilichDeathController self, Transform clockhairTransform) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_0015: Unknown result type (might be due to invalid IL or missing references) //IL_001a: Unknown result type (might be due to invalid IL or missing references) //IL_0025: 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_0039: Unknown result type (might be due to invalid IL or missing references) try { return Vector2.Distance(Vector3Extensions.XY(clockhairTransform.position) + new Vector2(-0.375f, 0.25f), ((GameActor)((BraveBehaviour)self).aiActor).CenterPosition + new Vector2(0f, -1.25f)) < 0.875f; } catch { return false; } } private static Vector2 GetTargetClockhairPosition(InfinilichDeathController self, Vector2 currentClockhairPosition) { //IL_0084: Unknown result type (might be due to invalid IL or missing references) //IL_0089: Unknown result type (might be due to invalid IL or missing references) //IL_008e: Unknown result type (might be due to invalid IL or missing references) //IL_009d: Unknown result type (might be due to invalid IL or missing references) //IL_00a2: Unknown result type (might be due to invalid IL or missing references) //IL_00a7: Unknown result type (might be due to invalid IL or missing references) //IL_00b2: Unknown result type (might be due to invalid IL or missing references) //IL_00b7: 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_00c8: Unknown result type (might be due to invalid IL or missing references) //IL_00cd: Unknown result type (might be due to invalid IL or missing references) //IL_00ce: Unknown result type (might be due to invalid IL or missing references) //IL_001e: Unknown result type (might be due to invalid IL or missing references) //IL_002a: Unknown result type (might be due to invalid IL or missing references) //IL_0034: Unknown result type (might be due to invalid IL or missing references) //IL_003e: Unknown result type (might be due to invalid IL or missing references) //IL_0043: Unknown result type (might be due to invalid IL or missing references) //IL_0048: Unknown result type (might be due to invalid IL or missing references) //IL_0053: Unknown result type (might be due to invalid IL or missing references) //IL_0058: Unknown result type (might be due to invalid IL or missing references) //IL_0059: Unknown result type (might be due to invalid IL or missing references) //IL_005e: 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) //IL_006e: Unknown result type (might be due to invalid IL or missing references) //IL_006f: Unknown result type (might be due to invalid IL or missing references) BraveInput instanceForPlayer = BraveInput.GetInstanceForPlayer(GameManager.Instance.PrimaryPlayer.PlayerIDX); if (!instanceForPlayer.IsKeyboardAndMouse(false)) { Vector2 val = currentClockhairPosition + ((TwoAxisInputControl)instanceForPlayer.ActiveActions.Aim).Vector * 10f * BraveTime.DeltaTime; val = Vector2.Max(GameManager.Instance.MainCameraController.MinVisiblePoint, val); return Vector2.Min(GameManager.Instance.MainCameraController.MaxVisiblePoint, val); } Vector2 val2 = Vector3Extensions.XY(GameManager.Instance.MainCameraController.Camera.ScreenToWorldPoint(Input.mousePosition)) + new Vector2(0.375f, -0.25f); val2 = Vector2.Max(GameManager.Instance.MainCameraController.MinVisiblePoint, val2); return Vector2.Min(GameManager.Instance.MainCameraController.MaxVisiblePoint, val2); } private static void UpdateEyes(InfinilichDeathController self, Vector2 clockhairPosition, bool isInDanger) { //IL_0024: Unknown result type (might be due to invalid IL or missing references) try { AccessTools.Method(typeof(InfinilichDeathController), "UpdateEyes", (Type[])null, (Type[])null)?.Invoke(self, new object[2] { clockhairPosition, isInDanger }); } catch { } } } [HarmonyPatch(typeof(LichIntroDoer), "PlayerWalkedIn")] public static class Patch_Lich_Start_TrackFlawless { [Serializable] [CompilerGenerated] private sealed class <>c { public static readonly <>c <>9 = new <>c(); public static OnDamagedEvent <>9__0_0; internal void <Postfix>b__0_0(float resultValue, float maxValue, CoreDamageTypes damageTypes, DamageCategory damageCategory, Vector2 damageDirection) { try { LoopManager.LastLichWasFlawless = false; } catch { } } } [HarmonyPostfix] private static void Postfix() { //IL_0059: Unknown result type (might be due to invalid IL or missing references) //IL_005e: Unknown result type (might be due to invalid IL or missing references) //IL_0064: Expected O, but got Unknown try { LoopManager.LastLichWasFlawless = true; GameManager instance = GameManager.Instance; if (((instance != null) ? instance.AllPlayers : null) == null) { return; } for (int i = 0; i < instance.AllPlayers.Length; i++) { PlayerController val = instance.AllPlayers[i]; if (!Object.op_Implicit((Object)(object)val) || (Object)(object)((BraveBehaviour)val).healthHaver == (Object)null) { continue; } HealthHaver healthHaver = ((BraveBehaviour)val).healthHaver; object obj = <>c.<>9__0_0; if (obj == null) { OnDamagedEvent val2 = delegate { try { LoopManager.LastLichWasFlawless = false; } catch { } }; <>c.<>9__0_0 = val2; obj = (object)val2; } healthHaver.OnDamaged += (OnDamagedEvent)obj; } } catch { } } } } namespace LoopTheGungeon { [BepInDependency(/*Could not decode attribute arguments.*/)] [BepInDependency(/*Could not decode attribute arguments.*/)] [BepInPlugin("milz.etg.loopthegungeon", "Loop The Gungeon", "1.0.2")] public class Plugin : BaseUnityPlugin { public const string GUID = "milz.etg.loopthegungeon"; public const string NAME = "Loop The Gungeon"; public const string VERSION = "1.0.2"; public static Plugin Instance; public static Harmony HarmonyInstance; public static int GlobalLoopOffset = -1; private static bool _commandsRegistered; private bool _patched; private bool _hooksInstalled; private SceneHandler _sceneHandler; private SaveHandler _saveHandler; private void Awake() { GlobalLoopOffset = -1; Instance = this; _saveHandler = new SaveHandler(); _sceneHandler = new SceneHandler(_saveHandler); try { InstallHooksOnce(); } catch (Exception arg) { ((BaseUnityPlugin)this).Logger.LogError((object)string.Format("[{0}] Hook install failed: {1}", "Loop The Gungeon", arg)); } try { ConfigManager.InitCustomConfig((BaseUnityPlugin)(object)this); ConfigManager.BindConfig(); _saveHandler.TryRestorePendingResumeFromDisk(); } catch (Exception arg2) { ((BaseUnityPlugin)this).Logger.LogError((object)string.Format("[{0}] Config init failed: {1}", "Loop The Gungeon", arg2)); } try { ToolsCharApi.AddComplex(Databases.Strings.Core, "#LOOP_SHERPA_FORGE", "Direct service to {wq}Looping{w} Chamber 5. The Forge."); } catch (Exception arg3) { ((BaseUnityPlugin)this).Logger.LogError((object)string.Format("[{0}] String injection failed: {1}", "Loop The Gungeon", arg3)); } try { TryApplyHarmonyPatches(); } catch (Exception arg4) { ((BaseUnityPlugin)this).Logger.LogError((object)string.Format("[{0}] Harmony patching failed: {1}", "Loop The Gungeon", arg4)); } } private void InstallHooksOnce() { if (_hooksInstalled) { return; } _hooksInstalled = true; try { SceneManager.sceneLoaded += _sceneHandler.OnSceneLoaded; } catch (Exception arg) { ((BaseUnityPlugin)this).Logger.LogError((object)string.Format("[{0}] sceneLoaded hook failed: {1}", "Loop The Gungeon", arg)); } try { DungeonHooks.OnPostDungeonGeneration += LoopManager.OnPostDungeonGeneration; } catch (Exception arg2) { ((BaseUnityPlugin)this).Logger.LogError((object)string.Format("[{0}] OnPostDungeonGeneration LoopManager hook failed: {1}", "Loop The Gungeon", arg2)); } try { DungeonHooks.OnPostDungeonGeneration += ForgeHandler.OnPostDungeonGeneration; } catch (Exception arg3) { ((BaseUnityPlugin)this).Logger.LogError((object)string.Format("[{0}] OnPostDungeonGeneration ForgeHandler hook failed: {1}", "Loop The Gungeon", arg3)); } try { DungeonHooks.OnPostDungeonGeneration += MasteryShrine.OnPostDungeonGeneration; } catch (Exception arg4) { ((BaseUnityPlugin)this).Logger.LogError((object)string.Format("[{0}] OnPostDungeonGeneration MasteryShrine hook failed: {1}", "Loop The Gungeon", arg4)); } } public void Start() { ETGModMainBehaviour.WaitForGameManagerStart((Action<GameManager>)GMStart); } private void GMStart(GameManager g) { if ((Object)(object)g == (Object)null) { return; } try { MasterRoundHell.Init(); } catch (Exception arg) { ((BaseUnityPlugin)this).Logger.LogError((object)string.Format("[{0}] MasterRoundHell.Init failed: {1}", "Loop The Gungeon", arg)); } IntroWave.LogIntro("Loop The Gungeon started LOoOoping!"); if (!LoopManager.IsResumeFlow()) { LoopManager.ResetNoticeEmitted = false; } if (_commandsRegistered) { return; } _commandsRegistered = true; try { ConsoleCommands.RegisterDebugCommands(); } catch (Exception arg2) { ((BaseUnityPlugin)this).Logger.LogError((object)string.Format("[{0}] RegisterDebugCommands failed: {1}", "Loop The Gungeon", arg2)); } try { ETGModConsole.Commands.AddGroup("loop", (Action<string[]>)delegate { }); } catch (Exception arg3) { ((BaseUnityPlugin)this).Logger.LogError((object)string.Format("[{0}] AddGroup(loop) failed: {1}", "Loop The Gungeon", arg3)); } } private void TryApplyHarmonyPatches() { //IL_000f: Unknown result type (might be due to invalid IL or missing references) //IL_0019: Expected O, but got Unknown //IL_005d: Unknown result type (might be due to invalid IL or missing references) //IL_006b: Expected O, but got Unknown if (_patched) { return; } try { HarmonyInstance = new Harmony("milz.etg.loopthegungeon"); Harmony harmonyInstance = HarmonyInstance; MethodInfo method = typeof(GameManager).GetMethod("DelayedLoadCharacterSelect", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); if ((object)method == null) { ((BaseUnityPlugin)this).Logger.LogError((object)"[Loop The Gungeon] Patch FAIL: GameManager.DelayedLoadCharacterSelect not found."); } else { harmonyInstance.Patch((MethodBase)method, new HarmonyMethod(typeof(LoopManager), "SaveAndQuitBoundary", (Type[])null), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null); } harmonyInstance.PatchAll(Assembly.GetExecutingAssembly()); ((BaseUnityPlugin)this).Logger.LogInfo((object)"[Loop The Gungeon] Harmony PatchAll OK."); _patched = true; } catch (Exception arg) { ((BaseUnityPlugin)this).Logger.LogError((object)string.Format("[{0}] Harmony patching FAILED: {1}", "Loop The Gungeon", arg)); } } private void OnDestroy() { try { _saveHandler?.StopCoroutines(); } catch { } try { _sceneHandler?.StopCoroutines(); } catch { } if (_hooksInstalled) { _hooksInstalled = false; if (_sceneHandler != null) { SceneManager.sceneLoaded -= _sceneHandler.OnSceneLoaded; } DungeonHooks.OnPostDungeonGeneration -= LoopManager.OnPostDungeonGeneration; DungeonHooks.OnPostDungeonGeneration -= MasteryShrine.OnPostDungeonGeneration; } DungeonHooks.OnPostDungeonGeneration -= ForgeHandler.OnPostDungeonGeneration; if (Instance == this) { Instance = null; } try { ProjectileSpeedScaler.RestoreBaselineNow(); } catch { } ButtonSpritesOverride.ClearRuntimeCaches(destroyUnityObjects: true); try { LoopManager.ResetMasteryShrineRuntime(); ShrineSpritesOverride.TryResetMasteryShrineVisuals(); ShrineSpritesOverride.ClearRuntimeCaches(destroyUnityObjects: true); } catch { } } internal static void StopAndNull(ref Coroutine c) { if (c != null && (Object)(object)Instance != (Object)null) { try { ((MonoBehaviour)Instance).StopCoroutine(c); } catch { } c = null; } } internal static Coroutine StartGlobalCoroutine(IEnumerator e) { if ((Object)(object)Instance == (Object)null) { return null; } try { return ((MonoBehaviour)Instance).StartCoroutine(e); } catch { return null; } } internal void ClearResumeAnnouncement() { try { _saveHandler?.ClearResumeAnnouncement(); } catch { } } internal void ArmResumeAnnouncementIfNeeded() { try { _saveHandler?.ArmResumeAnnouncementIfNeeded(); } catch { } } public static bool ShouldSuppressResumeArming() { try { return SaveHandler.ShouldSuppressResumeArming(); } catch { return false; } } } } namespace LoopTheGungeon.Visuals { public static class ShrineSpritesOverride { private readonly struct CreatedKey : IEquatable<CreatedKey> { public readonly string CollectionStable; public readonly string Name; public CreatedKey(tk2dSpriteCollectionData c, string name) { CollectionStable = GetCollectionStableId(c); Name = name ?? string.Empty; } public bool Equals(CreatedKey other) { if (string.Equals(CollectionStable, other.CollectionStable, StringComparison.Ordinal)) { return string.Equals(Name, other.Name, StringComparison.Ordinal); } return false; } public override bool Equals(object obj) { if (obj is CreatedKey other) { return Equals(other); } return false; } public override int GetHashCode() { return (17 * 31 + StringComparer.Ordinal.GetHashCode(CollectionStable ?? "")) * 31 + StringComparer.Ordinal.GetHashCode(Name ?? ""); } } private readonly struct MatKey : IEquatable<MatKey> { public readonly int BaseMatId; public readonly int TexId; public MatKey(Material baseMat, Texture2D tex) { BaseMatId = (Object.op_Implicit((Object)(object)baseMat) ? ((Object)baseMat).GetInstanceID() : 0); TexId = (Object.op_Implicit((Object)(object)tex) ? ((Object)tex).GetInstanceID() : 0); } public bool Equals(MatKey other) { if (BaseMatId == other.BaseMatId) { return TexId == other.TexId; } return false; } public override bool Equals(object obj) { if (obj is MatKey other) { return Equals(other); } return false; } public override int GetHashCode() { return (BaseMatId * 397) ^ TexId; } } private sealed class LruCache<TKey, TValue> { private struct Entry { public TKey Key; public TValue Value; } private readonly int _cap; private readonly Dictionary<TKey, LinkedListNode<Entry>> _map; private readonly LinkedList<Entry> _lru; private readonly Action<TValue> _onEvict; public int Count => _map.Count; public LruCache(int capacity, Action<TValue> onEvict) { _cap = Mathf.Max(1, capacity); _map = new Dictionary<TKey, LinkedListNode<Entry>>(_cap); _lru = new LinkedList<Entry>(); _onEvict = onEvict; } public bool TryGetValue(TKey key, out TValue value) { if (_map.TryGetValue(key, out var value2)) { _lru.Remove(value2); _lru.AddFirst(value2); value = value2.Value.Value; return true; } value = default(TValue); return false; } public void Set(TKey key, TValue value) { if (_map.TryGetValue(key, out var value2)) { value2.Value = new Entry { Key = key, Value = value }; _lru.Remove(value2); _lru.AddFirst(value2); return; } while (_map.Count >= _cap) { EvictOne(); } Entry value3 = default(Entry); value3.Key = key; value3.Value = value; LinkedListNode<Entry> linkedListNode = new LinkedListNode<Entry>(value3); _lru.AddFirst(linkedListNode); _map[key] = linkedListNode; } private void EvictOne() { LinkedListNode<Entry> last = _lru.Last; if (last == null) { return; } _lru.RemoveLast(); _map.Remove(last.Value.Key); if (_onEvict == null) { return; } try { _onEvict(last.Value.Value); } catch { } } public void Clear(bool destroyValues) { if (destroyValues && _onEvict != null) { foreach (Entry item in _lru) { try { _onEvict(item.Value); } catch { } } } _map.Clear(); _lru.Clear(); } } private const int MaxCachedMaterials = 64; private const int MaxCreatedIdMap = 128; private const int LEAD_LEGEND_TIER = 30; private const string INTERNAL_STATUE_BLACKSMITH_PRE = "LOOP_STATUE_BLACKSMITH_PRE"; private const string INTERNAL_STATUE_BLACKSMITH_SPENT = "LOOP_STATUE_BLACKSMITH_SPENT"; private const string INTERNAL_STATUE_LICH_PRE = "LOOP_STATUE_LICH_PRE"; private const string INTERNAL_STATUE_LICH_SPENT = "LOOP_STATUE_LICH_SPENT"; private const string INTERNAL_STATUE_BLACKSMITH_LEGEND_PRE = "LOOP_STATUE_BLACKSMITH_LEGEND_PRE"; private const string INTERNAL_STATUE_BLACKSMITH_LEGEND_SPENT = "LOOP_STATUE_BLACKSMITH_LEGEND_SPENT"; private const string INTERNAL_STATUE_LICH_LEGEND_PRE = "LOOP_STATUE_LICH_LEGEND_PRE"; private const string INTERNAL_STATUE_LICH_LEGEND_SPENT = "LOOP_STATUE_LICH_LEGEND_SPENT"; private const string INTERNAL_PEDESTAL_NORMAL = "LOOP_PEDESTAL_NORMAL"; private const string INTERNAL_PEDESTAL_LEGEND = "LOOP_PEDESTAL_LEGEND"; private static readonly LruCache<MatKey, Material> _matCache = new LruCache<MatKey, Material>(64, DestroyMaterial); private static readonly LruCache<CreatedKey, int> _createdIds = new LruCache<CreatedKey, int>(128, null); private static bool _tabletIconsInstalled; private static bool _portraitAtlasIconsInstalled; public static void ClearIds() { _createdIds.Clear(destroyValues: false); } public static void ClearRuntimeCaches(bool destroyUnityObjects) { _createdIds.Clear(destroyValues: false); _matCache.Clear(destroyUnityObjects); } public static void TryResetMasteryShrineVisuals() { try { string lastLoopSource = LoopManager.LastLoopSource; bool spent = !MasteryShrineInteractable.AnyAlivePlayerCanUseShrine(); MasteryShrineInteractable masteryShrineInteractable = Object.FindObjectOfType<MasteryShrineInteractable>(); if ((Object)(object)masteryShrineInteractable != (Object)null) { Apply(((Component)masteryShrineInteractable).gameObject, lastLoopSource, spent); } } catch { } } private static bool IsLeadLegendUnlocked() { try { return RunSummary.HasMasteryTitleReached(30); } catch { return false; } } private static string GetCollectionStableId(tk2dSpriteCollectionData c) { if (!Object.op_Implicit((Object)(object)c)) { return "null"; } if (!string.IsNullOrEmpty(c.spriteCollectionName)) { return c.spriteCollectionName; } return ((Object)c).name ?? "null"; } private static void DestroySafe(Object o) { try { if (o != (Object)null) { Object.Destroy(o); } } catch { } } private static void DestroyMaterial(Material m) { DestroySafe((Object)(object)m); } private static Material GetOrCreateMaterial(Material baseMat, Texture2D tex) { //IL_0035: Unknown result type (might be due to invalid IL or missing references) //IL_003b: Expected O, but got Unknown if (!Object.op_Implicit((Object)(object)baseMat) || !Object.op_Implicit((Object)(object)tex)) { return null; } MatKey key = new MatKey(baseMat, tex); if (_matCache.TryGetValue(key, out var value) && Object.op_Implicit((Object)(object)value)) { return value; } Material val = new Material(baseMat); val.mainTexture = (Texture)(object)tex; ((Object)val).hideFlags = (HideFlags)20; _matCache.Set(key, val); return val; } public static bool Apply(GameObject shrineRoot, string form, bool spent) { try { if (!Object.op_Implicit((Object)(object)shrineRoot)) { return false; } bool flag = false; bool flag2 = IsLeadLegendUnlocked(); tk2dBaseSprite val = FindSpriteOnChild(shrineRoot.transform, "ShrineStatue"); if (Object.op_Implicit((Object)(object)val)) { Texture2D tex = null; string internalName = null; if (flag2) { if (spent) { if (form == "Lich") { tex = ModTextures.MasteryShrine.StatueLichLegendSpentTex; internalName = "LOOP_STATUE_LICH_LEGEND_SPENT"; } else if (form == "Blacksmith") { tex = ModTextures.MasteryShrine.StatueBlacksmithLegendSpentTex; internalName = "LOOP_STATUE_BLACKSMITH_LEGEND_SPENT"; } } else if (form == "Lich") { tex = ModTextures.MasteryShrine.StatueLichLegendPreTex; internalName = "LOOP_STATUE_LICH_LEGEND_PRE"; } else if (form == "Blacksmith") { tex = ModTextures.MasteryShrine.StatueBlacksmithLegendPreTex; internalName = "LOOP_STATUE_BLACKSMITH_LEGEND_PRE"; } } else if (spent) { if (form == "Lich") { tex = ModTextures.MasteryShrine.StatueLichSpentTex; internalName = "LOOP_STATUE_LICH_SPENT"; } else if (form == "Blacksmith") { tex = ModTextures.MasteryShrine.StatueBlacksmithSpentTex; internalName = "LOOP_STATUE_BLACKSMITH_SPENT"; } } else if (form == "Lich") { tex = ModTextures.MasteryShrine.StatueLichPreTex; internalName = "LOOP_STATUE_LICH_PRE"; } else if (form == "Blacksmith") { tex = ModTextures.MasteryShrine.StatueBlacksmithPreTex; internalName = "LOOP_STATUE_BLACKSMITH_PRE"; } flag |= SwapSpriteSingle(val, tex, internalName); } tk2dBaseSprite val2 = FindSpriteOnChild(shrineRoot.transform, "shrine_Base"); if (Object.op_Implicit((Object)(object)val2)) { Texture2D tex2 = (flag2 ? ModTextures.MasteryShrine.PedestalLegendTex : ModTextures.MasteryShrine.PedestalNormalTex); string internalName2 = (flag2 ? "LOOP_PEDESTAL_LEGEND" : "LOOP_PEDESTAL_NORMAL"); flag |= SwapSpriteSingle(val2, tex2, internalName2); } return flag; } catch { return false; } } private static tk2dBaseSprite FindSpriteOnChild(Transform root, string childName) { try { if (!Object.op_Implicit((Object)(object)root)) { return null; } Transform val = root.Find(childName); if (!Object.op_Implicit((Object)(object)val)) { return null; } return ((Component)val).GetComponent<tk2dBaseSprite>(); } catch { return null; } } private static bool SwapSpriteSingle(tk2dBaseSprite spr, Texture2D tex, string internalName) { try { if (!Object.op_Implicit((Object)(object)spr) || !Object.op_Implicit((Object)(object)tex)) { return false; } tk2dSpriteCollectionData collection = spr.Collection; if (!Object.op_Implicit((Object)(object)collection) || collection.spriteDefinitions == null) { return false; } int num = spr.spriteId; if (num < 0 || num >= collection.spriteDefinitions.Length) { num = 0; } int num2 = AddTexAsSpriteDef(collection, num, tex, internalName); if (num2 < 0) { return false; } spr.SetSprite(collection, num2); spr.ForceBuild(); ModTextures.Tk2dUpdateMaterialSafe(spr); return true; } catch { return false; } } public static int AddTexAsSpriteDef(tk2dSpriteCollectionData collection, int templateSpriteId, Texture2D tex, string name, float worldHeight = -1f) { CreatedKey key = new CreatedKey(collection, name); if (_createdIds.TryGetValue(key, out var value) && value >= 0) { return value; } try { if (!Object.op_Implicit((Object)(object)collection) || !Object.op_Implicit((Object)(object)tex)) { return -1; } tk2dSpriteDefinition[] array = collection.spriteDefinitions; if (array == null || array.Length == 0) { return -1; } try { tk2dSpriteDefinition[] spriteDefinitions = collection.spriteDefinitions; if (spriteDefinitions != null) { for (int i = 0; i < spriteDefinitions.Length; i++) { tk2dSpriteDefinition val = spriteDefinitions[i]; if (val != null && string.Equals(val.name, name, StringComparison.Ordinal)) { _createdIds.Set(new CreatedKey(collection, name), i); return i; } } } } catch { } tk2dSpriteDefinition val2 = array[Mathf.Clamp(templateSpriteId, 0, array.Length - 1)]; if (val2 == null) { return -1; } tk2dSpriteDefinition val3 = CloneDefinition(val2, tex, name); ResizeDefByPixelRatio(val3, val2, tex); if (worldHeight > 0f) { ResizeDefinitionToWorldHeight(val3, tex, worldHeight); } int num = array.Length; Array.Resize(ref array, num + 1); array[num] = val3; collection.spriteDefinitions = array; _createdIds.Set(key, num); return num; } catch { return -1; } } public static int AddBadgeSpriteDef(tk2dSpriteCollectionData collection, Material baseMat, Texture2D tex, string name, float pixelsPerUnit = 16f) { //IL_00a3: Unknown result type (might be due to invalid IL or missing references) //IL_00aa: Expected O, but got Unknown //IL_00df: 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_00fb: Unknown result type (might be due to invalid IL or missing references) //IL_0100: Unknown result type (might be due to invalid IL or missing references) //IL_0117: Unknown result type (might be due to invalid IL or missing references) //IL_011c: Unknown result type (might be due to invalid IL or missing references) //IL_0133: Unknown result type (might be due to invalid IL or missing references) //IL_0138: Unknown result type (might be due to invalid IL or missing references) //IL_018c: Unknown result type (might be due to invalid IL or missing references) //IL_0191: Unknown result type (might be due to invalid IL or missing references) //IL_01a2: Unknown result type (might be due to invalid IL or missing references) //IL_01a7: Unknown result type (might be due to invalid IL or missing references) //IL_01b8: Unknown result type (might be due to invalid IL or missing references) //IL_01bd: Unknown result type (might be due to invalid IL or missing references) //IL_01cd: Unknown result type (might be due to invalid IL or missing references) //IL_01d2: Unknown result type (might be due to invalid IL or missing references) //IL_01dd: 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) if (!Object.op_Implicit((Object)(object)collection) || !Object.op_Implicit((Object)(object)tex) || !Object.op_Implicit((Object)(object)baseMat)) { return -1; } int num = Mathf.RoundToInt(pixelsPerUnit * 1000f); string text = $"{name}__ppu{num}"; CreatedKey key = new CreatedKey(collection, text); if (_createdIds.TryGetValue(key, out var value) && value >= 0) { return value; } tk2dSpriteDefinition[] spriteDefinitions = collection.spriteDefinitions; if (spriteDefinitions != null) { for (int i = 0; i < spriteDefinitions.Length; i++) { tk2dSpriteDefinition val = spriteDefinitions[i]; if (val != null && string.Equals(val.name, text, StringComparison.Ordinal)) { _createdIds.Set(key, i); return i; } } } try { tk2dSpriteDefinition val2 = new tk2dSpriteDefinition(); val2.name = text; val2.materialInst = GetOrCreateMaterial(baseMat, tex); val2.uvs = (Vector2[])(object)new Vector2[4]; val2.uvs[0] = new Vector2(0f, 0f); val2.uvs[1] = new Vector2(1f, 0f); val2.uvs[2] = new Vector2(0f, 1f); val2.uvs[3] = new Vector2(1f, 1f); float num2 = ((pixelsPerUnit <= 0.0001f) ? 0.0625f : (1f / pixelsPerUnit)); float num3 = (float)((Texture)tex).width * num2; float num4 = (float)((Texture)tex).height * num2; float num5 = num3 * 0.5f; float num6 = num4 * 0.5f; val2.position0 = new Vector3(0f - num5, 0f - num6, 0f); val2.position1 = new Vector3(num5, 0f - num6, 0f); val2.position2 = new Vector3(0f - num5, num6, 0f); val2.position3 = new Vector3(num5, num6, 0f); val2.texelSize = new Vector2(num2, num2); int num7 = collection.spriteDefinitions.Length; Array.Resize(ref collection.spriteDefinitions, num7 + 1); collection.spriteDefinitions[num7] = val2; _createdIds.Set(key, num7); return num7; } catch { return -1; } } private static tk2dSpriteDefinition CloneDefinition(tk2dSpriteDefinition template, Texture2D newTex, string name) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0006: Expected O, but got Unknown tk2dSpriteDefinition val = new tk2dSpriteDefinition(); CopyAllInstanceFields(template, val); val.name = name; if ((Object)(object)val.materialInst != (Object)null) { val.materialInst = GetOrCreateMaterial(val.materialInst, newTex); } SetFullUvsIfPresent(val); return val; } private static void CopyAllInstanceFields(object src, object dst) { if (src == null || dst == null) { return; } Type type = src.GetType(); BindingFlags bindingAttr = BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic; FieldInfo[] fields = type.GetFields(bindingAttr); foreach (FieldInfo fieldInfo in fields) { try { if (!fieldInfo.IsInitOnly) { object obj = fieldInfo.GetValue(src); if (obj != null && obj.GetType().IsArray) { obj = ((Array)obj).Clone(); } fieldInfo.SetValue(dst, obj); } } catch { } } } private static void SetFullUvsIfPresent(tk2dSpriteDefinition def) { //IL_0028: Unknown result type (might be due to invalid IL or missing references) //IL_002d: Unknown result type (might be due to invalid IL or missing references) //IL_0043: Unknown result type (might be due to invalid IL or missing references) //IL_0048: Unknown result type (might be due to invalid IL or missing references) //IL_005e: Unknown result type (might be due to invalid IL or missing references) //IL_0063: Unknown result type (might be due to invalid IL or missing references) //IL_0079: Unknown result type (might be due to invalid IL or missing references) //IL_007e: Unknown result type (might be due to invalid IL or missing references) if (def != null && def.uvs != null && def.uvs.Length >= 4) { def.uvs[0] = new Vector2(0f, 0f); def.uvs[1] = new Vector2(1f, 0f); def.uvs[2] = new Vector2(0f, 1f); def.uvs[3] = new Vector2(1f, 1f); } } private static void ResizeDefinitionToWorldHeight(tk2dSpriteDefinition def, Texture2D tex, float worldHeight) { //IL_0081: Unknown result type (might be due to invalid IL or missing references) //IL_0083: Unknown result type (might be due to invalid IL or missing references) //IL_0089: 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_0091: Unknown result type (might be due to invalid IL or missing references) //IL_0093: Unknown result type (might be due to invalid IL or missing references) //IL_0099: Unknown result type (might be due to invalid IL or missing references) //IL_009b: Unknown result type (might be due to invalid IL or missing references) if (def != null && !((Object)(object)tex == (Object)null) && ((Texture)tex).width > 0 && ((Texture)tex).height > 0) { float num = (float)((Texture)tex).width / (float)((Texture)tex).height; float num2 = worldHeight * num * 0.5f; float num3 = worldHeight * 0.5f; Vector3 position = default(Vector3); ((Vector3)(ref position))..ctor(0f - num2, 0f - num3, 0f); Vector3 position2 = default(Vector3); ((Vector3)(ref position2))..ctor(num2, 0f - num3, 0f); Vector3 position3 = default(Vector3); ((Vector3)(ref position3))..ctor(0f - num2, num3, 0f); Vector3 position4 = default(Vector3); ((Vector3)(ref position4))..ctor(num2, num3, 0f); def.position0 = position; def.position1 = position2; def.position2 = position3; def.position3 = position4; } } private static void ResizeDefByPixelRatio(tk2dSpriteDefinition def, tk2dSpriteDefinition template, Texture2D newTex) { //IL_0024: Unknown result type (might be due to invalid IL or missing references) //IL_0029: Unknown result type (might be due to invalid IL or missing references) //IL_002b: Unknown result type (might be due to invalid IL or missing references) //IL_0030: Unknown result type (might be due to invalid IL or missing references) //IL_0032: Unknown result type (might be due to invalid IL or missing references) //IL_0038: Unknown result type (might be due to invalid IL or missing references) //IL_003e: Unknown result type (might be due to invalid IL or missing references) //IL_003f: Unknown result type (might be due to invalid IL or missing references) //IL_0040: 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_0047: Unknown result type (might be due to invalid IL or missing references) //IL_004c: 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_0078: 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_0088: Unknown result type (might be due to invalid IL or missing references) //IL_0099: Unknown result type (might be due to invalid IL or missing references) //IL_00a5: Unknown result type (might be due to invalid IL or missing references) //IL_00da: Unknown result type (might be due to invalid IL or missing references) //IL_00dd: Unknown result type (might be due to invalid IL or missing references) //IL_00e2: 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_00e7: Unknown result type (might be due to invalid IL or missing references) //IL_00ec: Unknown result type (might be due to invalid IL or missing references) //IL_00ee: Unknown result type (might be due to invalid IL or missing references) //IL_00ef: Unknown result type (might be due to invalid IL or missing references) //IL_00f0: Unknown result type (might be due to invalid IL or missing references) //IL_00fa: Unknown result type (might be due to invalid IL or missing references) //IL_00ff: Unknown result type (might be due to invalid IL or missing references) //IL_0102: Unknown result type (might be due to invalid IL or missing references) //IL_0109: Unknown result type (might be due to invalid IL or missing references) //IL_010b: Unknown result type (might be due to invalid IL or missing references) //IL_0110: Unknown result type (might be due to invalid IL or missing references) //IL_0115: Unknown result type (might be due to invalid IL or missing references) //IL_011b: Unknown result type (might be due to invalid IL or missing references) //IL_0122: Unknown result type (might be due to invalid IL or missing references) //IL_0124: Unknown result type (might be due to invalid IL or missing references) //IL_0129: Unknown result type (might be due to invalid IL or missing references) //IL_012e: Unknown result type (might be due to invalid IL or missing references) //IL_0135: Unknown result type (might be due to invalid IL or missing references) //IL_013a: Unknown result type (might be due to invalid IL or missing references) //IL_013c: Unknown result type (might be due to invalid IL or missing references) //IL_0141: 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_014d: 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_0154: Unknown result type (might be due to invalid IL or missing references) if (def == null || template == null || (Object)(object)newTex == (Object)null || ((Texture)newTex).width <= 0 || ((Texture)newTex).height <= 0) { return; } Vector3 position = template.position0; Vector3 position2 = template.position1; Vector3 position3 = template.position2; _ = template.position3; Vector3 val = position2 - position; Vector3 val2 = position3 - position; float magnitude = ((Vector3)(ref val)).magnitude; float magnitude2 = ((Vector3)(ref val2)).magnitude; if (magnitude <= 0.0001f || magnitude2 <= 0.0001f) { return; } Vector2 texelSize = template.texelSize; if (!(texelSize.x <= 1E-06f) && !(texelSize.y <= 1E-06f)) { float num = magnitude / texelSize.x; float num2 = magnitude2 / texelSize.y; if (!(num <= 1f) && !(num2 <= 1f)) { float num3 = (float)((Texture)newTex).width / num; float num4 = (float)((Texture)newTex).height / num2; Vector3 val3 = val * num3; Vector3 val4 = val2 * num4; Vector3 val5 = (position + position2) * 0.5f; def.position0 = val5 - 0.5f * val3; def.position1 = val5 + 0.5f * val3; def.position2 = def.position0 + val4; def.position3 = def.position1 + val4; } } } internal static void TryInstallUiIcons() { TryInstallTabletIcons(); TryInstallConversationAtlasIcons(); } internal static void TryInstallTabletIcons() { //IL_0013: Unknown result type (might be due to invalid IL or missing references) //IL_0019: Expected O, but got Unknown if (_tabletIconsInstalled) { return; } try { GameObject val = (GameObject)ResourceCache.Acquire("ControllerButtonSprite"); tk2dBaseSprite val2 = (Object.op_Implicit((Object)(object)val) ? val.GetComponent<tk2dBaseSprite>() : null); tk2dSpriteCollectionData val3 = (Object.op_Implicit((Object)(object)val2) ? val2.Collection : null); if (!((Object)(object)val3 == (Object)null)) { EnsureSpriteInCollection(val3, ModTextures.UI.HellRoundTex, "loop_hell_round"); EnsureSpriteInCollection(val3, ModTextures.UI.CoolnessTex, "loop_coolness"); EnsureSpriteInCollection(val3, ModTextures.UI.CurseTex, "loop_curse"); EnsureSpriteInCollection(val3, ModTextures.UI.RageTex, "loop_rage"); _tabletIconsInstalled = true; } } catch { } } internal static void TryInstallConversationAtlasIcons() { if (_portraitAtlasIconsInstalled) { return; } try { GameUIRoot instance = GameUIRoot.Instance; if (!((Object)(object)instance == (Object)null) && !((Object)(object)instance.ConversationBar == (Object)null)) { dfSprite portraitSprite = instance.ConversationBar.portraitSprite; if (!((Object)(object)portraitSprite == (Object)null) && !((Object)(object)portraitSprite.Atlas == (Object)null)) { dfAtlas atlas = portraitSprite.Atlas; EnsureSpriteInAtlas(atlas, ModTextures.UI.CurseBoxTex, "loop_curse_box"); EnsureSpriteInAtlas(atlas, ModTextures.UI.HellRoundBoxTex, "loop_hell_round_box"); _portraitAtlasIconsInstalled = true; } } } catch { } } private static void EnsureSpriteInCollection(tk2dSpriteCollectionData col, Texture2D tex, string name) { if ((Object)(object)col == (Object)null || (Object)(object)tex == (Object)null || string.IsNullOrEmpty(name)) { return; } tk2dSpriteDefinition[] spriteDefinitions = col.spriteDefinitions; if (spriteDefinitions != null) { for (int i = 0; i < spriteDefinitions.Length; i++) { if (spriteDefinitions[i] != null && spriteDefinitions[i].name == name) { return; } } } SpriteBuilder.AddSpriteToCollection(tex, col, name); } private static void EnsureSpriteInAtlas(dfAtlas atlas, Texture2D tex, string name) { if ((Object)(object)atlas == (Object)null || (Object)(object)tex == (Object)null || string.IsNullOrEmpty(name)) { return; } try { if (atlas[name] != (ItemInfo)null) { return; } } catch { } try { ToolsCharApi.AddNewItemToAtlas(atlas, tex, name); } catch { } } } internal static class ModTextures { internal static class MasteryShrine { public static Texture2D StatueBlacksmithPreTex => LoadPng("Resources/MasteryShrine", "statue_blacksmith_pre.png", (FilterMode)0); public static Texture2D StatueBlacksmithSpentTex => LoadPng("Resources/MasteryShrine", "statue_blacksmith_spent.png", (FilterMode)0); public static Texture2D StatueBlacksmithLegendPreTex => LoadPng("Resources/MasteryShrine", "statue_blacksmith_legend_pre.png", (FilterMode)0); public static Texture2D StatueBlacksmithLegendSpentTex => LoadPng("Resources/MasteryShrine", "statue_blacksmith_legend_spent.png", (FilterMode)0); public static Texture2D StatueLichPreTex => LoadPng("Resources/MasteryShrine", "statue_lich_pre.png", (FilterMode)0); public static Texture2D StatueLichSpentTex => LoadPng("Resources/MasteryShrine", "statue_lich_spent.png", (FilterMode)0); public static Texture2D StatueLichLegendPreTex => LoadPng("Resources/MasteryShrine", "statue_lich_legend_pre.png", (FilterMode)0); public static Texture2D StatueLichLegendSpentTex => LoadPng("Resources/MasteryShrine", "statue_lich_legend_spent.png", (FilterMode)0); public static Texture2D PedestalNormalTex => LoadPng("Resources/MasteryShrine", "pedestal_normal.png", (FilterMode)0); public static Texture2D PedestalLegendTex => LoadPng("Resources/MasteryShrine", "pedestal_legend.png", (FilterMode)0); public static Texture2D Mr1LitTex => LoadPng("Resources/MasteryShrine", "mastery_badge_1.png", (FilterMode)0); public static Texture2D Mr2LitTex => LoadPng("Resources/MasteryShrine", "mastery_badge_2.png", (FilterMode)0); public static Texture2D Mr3LitTex => LoadPng("Resources/MasteryShrine", "mastery_badge_3.png", (FilterMode)0); public static Texture2D Mr4LitTex => LoadPng("Resources/MasteryShrine", "mastery_badge_4.png", (FilterMode)0); public static Texture2D Mr5LitTex => LoadPng("Resources/MasteryShrine", "mastery_badge_5.png", (FilterMode)0); public static Texture2D Mr6LitTex => LoadPng("Resources/MasteryShrine", "mastery_badge_6.png", (FilterMode)0); } internal static class LoopButton { public static Texture2D Talk1EvolvingTex => LoadPng("Resources/LoopButton", "loop_button_evolving_talk_1.png", (FilterMode)0); public static Texture2D Talk2EvolvingTex => LoadPng("Resources/LoopButton", "loop_button_evolving_talk_2.png", (FilterMode)0); public static Texture2D Talk3EvolvingTex => LoadPng("Resources/LoopButton", "loop_button_evolving_talk_3.png", (FilterMode)0); public static Texture2D Talk1FixedTex => LoadPng("Resources/LoopButton", "loop_button_fixed_talk_1.png", (FilterMode)0); public static Texture2D Talk2FixedTex => LoadPng("Resources/LoopButton", "loop_button_fixed_talk_2.png", (FilterMode)0); public static Texture2D Talk3FixedTex => LoadPng("Resources/LoopButton", "loop_button_fixed_talk_3.png", (FilterMode)0); } internal static class TitleScreen { public static Texture2D Looper1Tex => LoadPng("Resources/TitleScreen", "looper_1.png", (FilterMode)0); public static Texture2D Looper2Tex => LoadPng("Resources/TitleScreen", "looper_2.png", (FilterMode)0); public static Texture2D Looper3Tex => LoadPng("Resources/TitleScreen", "looper_3.png", (FilterMode)0); public static Texture2D Looper4Tex => LoadPng("Resources/TitleScreen", "looper_4.png", (FilterMode)0); public static Texture2D Looper5Tex => LoadPng("Resources/TitleScreen", "looper_5.png", (FilterMode)0); public static Texture2D Looper6Tex => LoadPng("Resources/TitleScreen", "looper_6.png", (FilterMode)0); public static Texture2D Looper7Tex => LoadPng("Resources/TitleScreen", "looper_7.png", (FilterMode)0); public static Texture2D Looper8Tex => LoadPng("Resources/TitleScreen", "looper_8.png", (FilterMode)0); } internal static class UI { public static Texture2D CoolnessTex => LoadPng("Resources/UI", "coolness_icon.png", (FilterMode)0); public static Texture2D RageTex => LoadPng("Resources/UI", "rage_icon.png", (FilterMode)0); public static Texture2D CurseTex => LoadPng("Resources/UI", "curse_icon.png", (FilterMode)0); public static Texture2D CurseBoxTex => LoadPng("Resources/UI", "curse_box_icon.png", (FilterMode)0); public static Texture2D HellRoundTex => LoadPng("Resources/UI", "hell_round_icon.png", (FilterMode)0); public static Texture2D HellRoundBoxTex => LoadPng("Resources/UI", "hell_round_box_icon.png", (FilterMode)0); } private sealed class CacheEntry { public Texture2D Tex; public long LooseLastWriteUtcTicks; } public static bool PreferLooseFiles = false; private static readonly string PluginDir = ResolvePluginDir(); private static readonly Dictionary<string, CacheEntry> _cache = new Dictionary<string, CacheEntry>(StringComparer.OrdinalIgnoreCase); private static Action<tk2dBaseSprite> _tk2dUpdateMaterial; private static string ResolvePluginDir() { try { string text = null; try { Plugin instance = Plugin.Instance; object obj; if (instance == null) { obj = null; } else { PluginInfo info = ((BaseUnityPlugin)instance).Info; obj = ((info != null) ? info.Location : null); } text = (string)obj; } catch { } if (string.IsNullOrEmpty(text)) { text = Assembly.GetExecutingAssembly().Location; } return string.IsNullOrEmpty(text) ? string.Empty : Path.GetDirectoryName(text); } catch { return string.Empty; } } private static Texture2D LoadPng(string folderUnderPluginDir, string fileName, FilterMode filter) { //IL_002a: Unknown result type (might be due to invalid IL or missing references) //IL_002c: Expected I4, but got Unknown //IL_0082: Unknown result type (might be due to invalid IL or missing references) //IL_006d: Unknown result type (might be due to invalid IL or missing references) if (string.IsNullOrEmpty(fileName)) { return null; } string cacheKey = folderUnderPluginDir + "/" + fileName + "|f=" + (int)filter; if (PreferLooseFiles && !string.IsNullOrEmpty(PluginDir)) { string fullPath = Path.Combine(Path.Combine(PluginDir, folderUnderPluginDir.Replace('/', Path.DirectorySeparatorChar)), fileName); Texture2D val = TryLoadLoosePngCached(cacheKey, fullPath, filter); if ((Object)(object)val != (Object)null) { return val; } } return TryLoadEmbeddedPngCached(cacheKey, folderUnderPluginDir, fileName, filter); } private static Texture2D TryLoadLoosePngCached(string cacheKey, string fullPath, FilterMode filter) { //IL_0069: Unknown result type (might be due to invalid IL or missing references) //IL_006f: Expected O, but got Unknown //IL_0084: Unknown result type (might be due to invalid IL or missing references) try { if (string.IsNullOrEmpty(fullPath) || !File.Exists(fullPath)) { return null; } long ticks = File.GetLastWriteTimeUtc(fullPath).Ticks; if (_cache.TryGetValue(cacheKey, out var value) && value != null && (Object)(object)value.Tex != (Object)null && value.LooseLastWriteUtcTicks == ticks) { return value.Tex; } byte[] array = File.ReadAllBytes(fullPath); Texture2D val = new Texture2D(2, 2, (TextureFormat)5, false); if (!ImageConversion.LoadImage(val, array)) { Object.Destroy((Object)(object)val); return null; } ((Texture)val).filterMode = filter; ((Texture)val).wrapMode = (TextureWrapMode)1; ((Object)val).hideFlags = (HideFlags)20; if (value != null && (Object)(object)value.Tex != (Object)null) { Object.Destroy((Object)(object)value.Tex); } _cache[cacheKey] = new CacheEntry { Tex = val, LooseLastWriteUtcTicks = ticks }; return val; } catch { return null; } } private static Texture2D TryLoadEmbeddedPngCached(string cacheKey, string folderUnderRoot, string fileName, FilterMode filter) { //IL_00bf: Unknown result type (might be due to invalid IL or missing references) //IL_00c6: Expected O, but got Unknown //IL_00df: Unknown result type (might be due to invalid IL or missing references) try { if (_cache.TryGetValue(cacheKey, out var value) && value != null && (Object)(object)value.Tex != (Object)null && value.LooseLastWriteUtcTicks == 0L) { return value.Tex; } string text = folderUnderRoot.Replace('/', '.').Replace('\\', '.'); string name = "LoopTheGungeon." + text + "." + fileName; Assembly executingAssembly = Assembly.GetExecutingAssembly(); using Stream stream = executingAssembly.GetManifestResourceStream(name); if (stream == null) { string[] manifestResourceNames = executingAssembly.GetManifestResourceNames(); for (int i = 0; i < manifestResourceNames.Length; i++) { ETGModConsole.Log((object)manifestResourceNames[i], false); } return null; } byte[] array = new byte[stream.Length]; stream.Read(array, 0, array.Length); Texture2D val = new Texture2D(2, 2, (TextureFormat)5, false); if (!ImageConversion.LoadImage(val, array)) { Object.Destroy((Object)(object)val); return null; } ((Texture)val).filterMode = filter; ((Texture)val).wrapMode = (TextureWrapMode)1; ((Object)val).hideFlags = (HideFlags)20; if (value != null && (Object)(object)value.Tex != (Object)null) { Object.Destroy((Object)(object)value.Tex); } _cache[cacheKey] = new CacheEntry { Tex = val, LooseLastWriteUtcTicks = 0L }; return val; } catch { return null; } } public static void ClearAllCachedTextures(bool destroyUnityObjects) { if (destroyUnityObjects) { foreach (KeyValuePair<string, CacheEntry> item in _cache) { try { if ((Object)(object)item.Value?.Tex != (Object)null) { Object.Destroy((Object)(object)item.Value.Tex); } } catch { } } } _cache.Clear(); } public static void Tk2dUpdateMaterialSafe(tk2dBaseSprite spr) { if ((Object)(object)spr == (Object)null) { return; } try { if (_tk2dUpdateMaterial == null) { MethodInfo method = typeof(tk2dBaseSprite).GetMethod("UpdateMaterial", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); if ((object)method == null) { return; } _tk2dUpdateMaterial = (Action<tk2dBaseSprite>)Delegate.CreateDelegate(typeof(Action<tk2dBaseSprite>), null, method); } _tk2dUpdateMaterial(spr); } catch { } } } public static class ButtonSpritesOverride { private sealed class InstancedTk2dMarker : MonoBehaviour { } private sealed class LoopButtonAppliedMarker : MonoBehaviour { public bool EvolvingEnabled; } private sealed class RuntimeAtlas { public Texture2D AtlasTex; public Material Mat; } private readonly struct CreatedKey : IEquatable<CreatedKey> { public readonly string CollectionStable; public readonly string Name; public CreatedKey(tk2dSpriteCollectionData c, string name) { CollectionStable = GetCollectionStableId(c); Name = name ?? string.Empty; } public bool Equals(CreatedKey other) { if (string.Equals(CollectionStable, other.CollectionStable, StringComparison.Ordinal)) { return string.Equals(Name, other.Name, StringComparison.Ordinal); } return false; } public override bool Equals(object obj) { if (obj is CreatedKey other) { return Equals(other); } return false; } public override int GetHashCode() { return (17 * 31 + StringComparer.Ordinal.GetHashCode(CollectionStable ?? "")) * 31 + StringComparer.Ordinal.GetHashCode(Name ?? ""); } } private readonly struct AtlasKey : IEquatable<AtlasKey> { public readonly string ShaderName; public readonly string BaseAtlasName; public readonly int BaseW; public readonly int BaseH; public AtlasKey(Material templateMat) { Texture2D val = (Texture2D)(((Object)(object)templateMat != (Object)null) ? /*isinst with value type is only supported in some contexts*/: null); ShaderName = ((Object.op_Implicit((Object)(object)templateMat) && Object.op_Implicit((Object)(object)templateMat.shader)) ? (((Object)templateMat.shader).name ?? "") : ""); BaseAtlasName = (Object.op_Implicit((Object)(object)val) ? (((Object)val).name ?? "") : ""); BaseW = (Object.op_Implicit((Object)(object)val) ? ((Texture)val).width : 0); BaseH = (Object.op_Implicit((Object)(object)val) ? ((Texture)val).height : 0); } public bool Equals(AtlasKey other) { if (BaseW == other.BaseW && BaseH == other.BaseH && string.Equals(ShaderName, other.ShaderName, StringComparison.Ordinal)) { return string.Equals(BaseAtlasName, other.BaseAtlasName, StringComparison.Ordinal); } return false; } public override bool Equals(object obj) { if (obj is AtlasKey other) { return Equals(other); } return false; } public override int GetHashCode() { return (((17 * 31 + BaseW) * 31 + BaseH) * 31 + StringComparer.Ordinal.GetHashCode(ShaderName ?? "")) * 31 + StringComparer.Ordinal.GetHashCode(BaseAtlasName ?? ""); } } private readonly struct MatKey : IEquatable<MatKey> { public readonly string ShaderName; public readonly string BaseMatName; public readonly string TexName; public readonly int TexW; public readonly int TexH; public MatKey(Material baseMat, Texture2D tex) { ShaderName = ((Object.op_Implicit((Object)(object)baseMat) && Object.op_Implicit((Object)(object)baseMat.shader)) ? (((Object)baseMat.shader).name ?? "") : ""); BaseMatName = (Object.op_Implicit((Object)(object)baseMat) ? (((Object)baseMat).name ?? "") : ""); TexName = (Object.op_Implicit((Object)(object)tex) ? (((Object)tex).name ?? "") : ""); TexW = (Object.op_Implicit((Object)(object)tex) ? ((Texture)tex).width : 0); TexH = (Object.op_Implicit((Object)(object)tex) ? ((Texture)tex).height : 0); } public bool Equals(MatKey other) { if (TexW == other.TexW && TexH == other.TexH && string.Equals(ShaderName, other.ShaderName, StringComparison.Ordinal) && string.Equals(BaseMatName, other.BaseMatName, StringComparison.Ordinal)) { return string.Equals(TexName, other.TexName, StringComparison.Ordinal); } return false; } public override bool Equals(object obj) { if (obj is MatKey other) { return Equals(other); } return false; } public override int GetHashCode() { return ((((17 * 31 + TexW) * 31 + TexH) * 31 + StringComparer.Ordinal.GetHashCode(ShaderName ?? "")) * 31 + StringComparer.Ordinal.GetHashCode(BaseMatName ?? "")) * 31 + StringComparer.Ordinal.GetHashCode(TexName ?? ""); } } private sealed class LruCache<TKey, TValue> { private struct Entry { public TKey Key; public TValue Value; } private readonly int _cap; private readonly Dictionary<TKey, LinkedListNode<Entry>> _map; private readonly LinkedList<Entry> _lru; private readonly Action<TValue> _onEvict; public int Count => _map.Count; public LruCache(int capacity, Action<TValue> onEvict) { _cap = Mathf.Max(1, capacity); _map = new Dictionary<TKey, LinkedListNode<Entry>>(_cap); _lru = new LinkedList<Entry>(); _onEvict = onEvict; } public bool TryGetValue(TKey key, out TValue value) { if (_map.TryGetValue(key, out var value2)) { _lru.Remove(value2); _lru.AddFirst(value2); value = value2.Value.Value; return true; } value = default(TValue); return false; } public void Set(TKey key, TValue value) { if (_map.TryGetValue(key, out var value2)) { value2.Value = new Entry { Key = key, Value = value }; _lru.Remove(value2); _lru.AddFirst(value2); return; } while (_map.Count >= _cap) { EvictOne(); } Entry value3 = default(Entry); value3.Key = key; value3.Value = value; LinkedListNode<Entry> linkedListNode = new LinkedListNode<Entry>(value3); _lru.AddFirst(linkedListNode); _map[key] = linkedListNode; } private void EvictOne() { LinkedListNode<Entry> last = _lru.Last; if (last == null) { return; } _lru.RemoveLast(); _map.Remove(last.Value.Key); if (_onEvict == null) { return; } try { _onEvict(last.Value.Value); } catch { } } public void Clear(bool destroyValues) { if (destroyValues && _onEvict != null) { foreach (Entry item in _lru) { try { _onEvict(item.Value); } catch { } } } _map.Clear(); _lru.Clear(); } } private readonly struct Key : IEquatable<Key> { public readonly tk2dSpriteCollectionData Col; public readonly int SpriteId; public Key(tk2dSpriteCollectionData col, int id) { Col = col; SpriteId = id; } public bool Equals(Key other) { if (Col == other.Col) { return SpriteId == other.SpriteId; } return false; } public override bool Equals(object obj) { if (obj is Key other) { return Equals(other); } return false; } public override int GetHashCode() { return (17 * 31 + (Object.op_Implicit((Object)(object)Col) ? ((Object)Col).GetInstanceID() : 0)) * 31 + SpriteId; } } private static bool? _cachedEvolvingSprites; private const int MaxCachedMaterials = 128; private const int MaxCachedAtlases = 16; private const int MaxCreatedIdMap = 512; private static readonly LruCache<MatKey, Material> _matCache = new LruCache<MatKey, Material>(128, DestroyMaterial); private static readonly LruCache<AtlasKey, RuntimeAtlas> _atlasCache = new LruCache<AtlasKey, RuntimeAtlas>(16, DestroyRuntimeAtlas); private static readonly LruCache<CreatedKey, int> _createdIds = new LruCache<CreatedKey, int>(512, null); private static bool EvolvingSpritesEnabled() { if (_cachedEvolvingSprites.HasValue) { return _cachedEvolvingSprites.Value; } try { _cachedEvolvingSprites = ConfigManager.CfgEvolvingButtonDialogue != null && ConfigManager.CfgEvolvingButtonDialogue.Value; return _cachedEvolvingSprites.Value; } catch { _cachedEvolvingSprites = false; return false; } } public static void InvalidateButtonSpriteConfigCache() { _cachedEvolvingSprites = null; } private static string GetCollectionStableId(tk2dSpriteCollectionData c) { if (!Object.op_Implicit((Object)(object)c)) { return "null"; } try { PropertyInfo property = ((object)c).GetType().GetProperty("spriteCollectionName", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); if ((object)property != null) { string text = property.GetValue(c, null) as string; if (!string.IsNullOrEmpty(text)) { return text; } } } catch { } return ((Object)c).name ?? "null"; } private static void DestroyMaterial(Material m) { try { if (Object.op_Implicit((Object)(object)m)) { Object.Destroy((Object)(object)m); } } catch { } } private static void DestroyRuntimeAtlas(RuntimeAtlas ra) { if (ra == null) { return; } try { if (Object.op_Implicit((Object)(object)ra.AtlasTex)) { Object.Destroy((Object)(object)ra.AtlasTex); } } catch { } try { if (Object.op_Implicit((Object)(object)ra.Mat)) { Object.Destroy((Object)(object)ra.Mat); } } catch { } } public static void ClearRuntimeCaches(bool destroyUnityObjects) { _createdIds.Clear(destroyValues: false); _matCache.Clear(destroyUnityObjects); _atlasCache.Clear(destroyUnityObjects); } private static Material GetOrCreateMaterial(Material baseMat, Texture2D tex) { //IL_0035: Unknown result type (might be due to invalid IL or missing references) //IL_003b: Expected O, but got Unknown if (!Object.op_Implicit((Object)(object)baseMat) || !Object.op_Implicit((Object)(object)tex)) { return null; } MatKey key = new MatKey(baseMat, tex); if (_matCache.TryGetValue(key, out var value) && Object.op_Implicit((Object)(object)value)) { return value; } Material val = new Material(baseMat); val.mainTexture = (Texture)(object)tex; ((Object)val).hideFlags = (HideFlags)20; _matCache.Set(key, val); return val; } private static void CopyAllInstanceFields(object src, object dst) { if (src == null || dst == null) { return; } Type type = src.GetType(); BindingFlags bindingAttr = BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic; FieldInfo[] fields = type.GetFields(bindingAttr); foreach (FieldInfo fieldInfo in fields) { try { if (!fieldInfo.IsInitOnly) { object obj = fieldInfo.GetValue(src); if (obj != null && obj.GetType().IsArray) { obj = ((Array)obj).Clone(); } fieldInfo.SetValue(dst, obj); } } catch { } } } private static bool TryGetTemplateUvRect(tk2dSpriteDefinition template, out float uMin, out float uMax, out float vMin, out float vMax) { //IL_005b: Unknown result type (might be due to invalid IL or missing references) //IL_0060: Unknown result type (might be due to invalid IL or missing references) //IL_0061: 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_006c: Unknown result type (might be due to invalid IL or missing references) //IL_0085: Unknown result type (might be due to invalid IL or missing references) //IL_007e: Unknown result type (might be due to invalid IL or missing references) //IL_0097: 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_00a4: Unknown result type (might be due to invalid IL or missing references) uMin = (uMax = (vMin = (vMax = 0f))); if (template == null) { return false; } Vector2[] uvs = template.uvs; if (uvs == null || uvs.Length < 4) { return false; } uMin = (uMax = uvs[0].x); vMin = (vMax = uvs[0].y); for (int i = 1; i < 4; i++) { Vector2 val = uvs[i]; if (val.x < uMin) { uMin = val.x; } if (val.x > uMax) { uMax = val.x; } if (val.y < vMin) { vMin = val.y; } if (val.y > vMax) { vMax = val.y; } } return true; } private static void UvRectToPixelRect(Texture2D atlas, float uMin, float uMax, float vMin, float vMax, out int x, out int y, out int w, out int h) { int width = ((Texture)atlas).width; int height = ((Texture)atlas).height; int num = Mathf.FloorToInt(uMin * (float)width); int num2 = Mathf.CeilToInt(uMax * (float)width); int num3 = Mathf.FloorToInt(vMin * (float)height); int num4 = Mathf.CeilToInt(vMax * (float)height); x = Mathf.Clamp(num, 0, width - 1); y = Mathf.Clamp(num3, 0, height - 1); w = Mathf.Clamp(num2 - x, 1, width - x); h = Mathf.Clamp(num4 - y, 1, height - y); } private static void BlitScaled(Texture2D src, Texture2D dst, int dstX, int dstY, int dstW, int dstH) { //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) if (!Object.op_Implicit((Object)(object)src) || !Object.op_Implicit((Object)(object)dst)) { return; } Color32[] pixels = src.GetPixels32(); int width = ((Texture)src).width; int height = ((Texture)src).height; Color32[] array = (Color32[])(object)new Color32[dstW * dstH]; for (int i = 0; i < dstH; i++) { for (int j = 0; j < dstW; j++) { int num = i * width / dstH; int num2 = j * height / dstW; if (num < 0) { num = 0; } else if (num >= width) { num = width - 1; } if (num2 < 0) { num2 = 0; } else if (num2 >= height) { num2 = height - 1; } array[i * dstW + j] = pixels[num2 * width + num]; } } dst.SetPixels32(dstX, dstY, dstW, dstH, array); } private static RuntimeAtlas GetOrCreateRuntimeAtlas(Material templateMat) { //IL_0058: Unknown result type (might be due to invalid IL or missing references) //IL_005e: Expected O, but got Unknown if (!Object.op_Implicit((Object)(object)templateMat)) { return null; } Texture mainTexture = templateMat.mainTexture; Texture2D val = (Texture2D)(object)((mainTexture is Texture2D) ? mainTexture : null); if (!Object.op_Implicit((Object)(object)val)) { return null; } AtlasKey key = new AtlasKey(templateMat); if (_atlasCache.TryGetValue(key, out var value) && value != null && Object.op_Implicit((Object)(object)value.AtlasTex)) { return value; } Texture2D val2 = new Texture2D(((Texture)val).width, ((Texture)val).height, (TextureFormat)4, false, false); ((Texture)val2).filterMode = (FilterMode)0; ((Texture)val2).wrapMode = (TextureWrapMode)1; ((Object)val2).name = ((Object)val).name + "_LOOP_RUNTIME_ATLAS"; ((Object)val2).hideFlags = (HideFlags)20; try { val2.SetPixels32(val.GetPixels32()); } catch { Color32[] pixels = (Color32[])(object)new Color32[((Texture)val2).width * ((Texture)val2).height]; val2.SetPixels32(pixels); } val2.Apply(false, false); value = new RuntimeAtlas { AtlasTex = val2, Mat = GetOrCreateMaterial(templateMat, val2) }; _atlasCache.Set(key, value); return value; } private static tk2dSpriteDefinition CloneDefinition(tk2dSpriteDefinition template, Texture2D newTex, string name) { //IL_000e: Unknown result type (might be due to invalid IL or missing references) //IL_0014: Expected O, but got Unknown if (template == null || (Object)(object)newTex == (Object)null) { return null; } tk2dSpriteDefinition val = new tk2dSpriteDefinition(); CopyAllInstanceFields(template, val); val.name = name ?? string.Empty; Material materialInst = template.materialInst; RuntimeAtlas orCreateRuntimeAtlas = GetOrCreateRuntimeAtlas(materialInst); if (orCreateRuntimeAtlas != null && (Object)(object)orCreateRuntimeAtlas.AtlasTex != (Object)null && TryGetTemplateUvRect(template, out var uMin, out var uMax, out var vMin, out var vMax)) { UvRectToPixelRect(orCreateRuntimeAtlas.AtlasTex, uMin, uMax, vMin, vMax, out var x, out var y, out var w, out var h); BlitScaled(newTex, orCreateRuntimeAtlas.AtlasTex, x, y, w, h); orCreateRuntimeAtlas.AtlasTex.Apply(false, false); } if ((Object)(object)materialInst != (Object)null && orCreateRuntimeAtlas != null && (Object)(object)orCreateRuntimeAtlas.AtlasTex != (Object)null) { val.materialInst = GetOrCreateMaterial(materialInst, orCreateRuntimeAtlas.AtlasTex); } return val; } private static int AddTexAsSpriteDef(tk2dSpriteCollectionData collection, int templateSpriteId, Texture2D tex, string name) { if (!Object.op_Implicit((Object)(object)collection) || !Object.op_Implicit((Object)(object)tex)) { return -1; } CreatedKey key = new CreatedKey(collection, name); if (_createdIds.TryGetValue(key, out var value) && value >= 0) { return value; } tk2dSpriteDefinition[] array = collection.spriteDefinitions; if (array == null || array.Length == 0) { return -1; } tk2dSpriteDefinition val = array[Mathf.Clamp(templateSpriteId, 0, array.Length - 1)]; if (val == null) { return -1; } tk2dSpriteDefinition val2 = CloneDefinition(val, tex, name); int num = array.Length; Array.Resize(ref array, num + 1); array[num] = val2; collection.spriteDefinitions = array; _createdIds.Set(key, num); return num; } private static Texture2D GetTalkTex(int idx1Based, bool evolving) { if (evolving) { return (Texture2D)(idx1Based switch { 1 => ModTextures.LoopButton.Talk1EvolvingTex, 2 => ModTextures.LoopButton.Talk2EvolvingTex, 3 => ModTextures.LoopButton.Talk3EvolvingTex, _ => null, }); } return (Texture2D)(idx1Based switch { 1 => ModTextures.LoopButton.Talk1FixedTex, 2 => ModTextures.LoopButton.Talk2FixedTex, 3 => ModTextures.LoopButton.Talk3FixedTex, _ => null, }); } private static tk2dSpriteAnimationClip FindClipByContains(tk2dSpriteAnimator animator, string token) { if ((Object)(object)animator == (Object)null || (Object)(object)animator.Library == (Object)null || animator.Library.clips == null) { return null; } if (token == null) { token = ""; } tk2dSpriteAnimationClip[] clips = animator.Library.clips; foreach (tk2dSpriteAnimationClip val in clips) { if (val != null && val.name != null && val.name.IndexOf(token, StringComparison.OrdinalIgnoreCase) >= 0) { return val; } } return null; } private static void EnsureInstancedAnimatorLibraryOnly(tk2dSpriteAnimator anim) { //IL_008a: Unknown result type (might be due to invalid IL or missing references) //IL_0091: Expected O, but got Unknown //IL_00de: Unknown result type (might be due to invalid IL or missing references) //IL_00e5: Expected O, but got Unknown if ((Object)(object)anim == (Object)null || (Object)(object)((Component)anim).gameObject.GetComponent<InstancedTk2dMarker>() != (Object)null) { return; } if ((Object)(object)anim.Library != (Object)null) { tk2dSpriteAnimation val = Object.Instantiate<tk2dSpriteAnimation>(anim.Library); ((Object)val).name = ((Object)anim.Library).name + "_LOOP_RUNTIME"; if (val.clips != null) { tk2dSpriteAnimationClip[] clips = val.clips; tk2dSpriteAnimationClip[] array = (tk2dSpriteAnimationClip[])(object)new tk2dSpriteAnimationClip[clips.Length]; for (int i = 0; i < clips.Length; i++) { tk2dSpriteAnimationClip val2 = clips[i]; if (val2 == null) { array[i] = null; continue; } tk2dSpriteAnimationClip val3 = new tk2dSpriteAnimationClip(); CopyAllInstanceFields(val2, val3); val3.name = val2.name; if (val2.frames != null) { tk2dSpriteAnimationFrame[] array2 = (tk2dSpriteAnimationFrame[])(object)new tk2dSpriteAnimationFrame[val2.frames.Length]; for (int j = 0; j < val2.frames.Length; j++) { tk2dSpriteAnimationFrame val4 = val2.frames[j]; if (val4 == null) { array2[j] = null; continue; } tk2dSpriteAnimationFrame val5 = new tk2dSpriteAnimationFrame(); CopyAllInstanceFields(val4, val5); array2[j] = val5; } val3.frames = array2; } array[i] = val3; } val.clips = array; } anim.Library = val; } ((Component)anim).gameObject.AddComponent<InstancedTk2dMarker>(); } public static bool ApplyLoopButtonAnimator(tk2dSpriteAnimator anim) { if ((Object)(object)anim == (Object)null || (Object)(object)anim.Sprite == (Object)null) { return false; } bool evolving = EvolvingSpritesEnabled(); LoopButtonAppliedMarker loopButtonAppliedMarker = ((Component)anim).gameObject.GetComponent<LoopButtonAppliedMarker>(); if ((Object)(object)loopButtonAppliedMarker != (Object)null && loopButtonAppliedMarker.EvolvingEnabled == evolving) { return false; } EnsureInstancedAnimatorLibraryOnly(anim); tk2dSpriteAnimationClip val = FindClipByContains(anim, "button_hell_talk"); tk2dSpriteAnimationClip val2 = FindClipByContains(anim, "button_hell_idle"); if (val == null && val2 == null) { return false; } bool flag = false; string text = (evolving ? "EV" : "FIXED"); if (val2 != null) { List<Key> uniqueKeysInClip = GetUniqueKeysInClip(anim, val2); List<int> list = AddLoopSequenceUsingKeys(uniqueKeysInClip, (int _) => GetTalkTex(1, evolving), "button_hell_idle_" + text + "_"); if (list.Count == uniqueKeysInClip.Count) { RemapClipByKeys(anim, val2, uniqueKeysInClip, list); flag = true; } } if (val != null) { List<Key> uniqueKeysInClip2 = GetUniqueKeysInClip(anim, val); List<int> list2 = AddLoopSequenceUsingKeys(uniqueKeysInClip2, (int idx) => GetTalkTex(idx, evolving), "button_hell_talk_" + text + "_"); if (list2.Count == uniqueKeysInClip2.Count) { RemapClipByKeys(anim, val, uniqueKeysInClip2, list2); flag = true; } } if (flag) { try { anim.Sprite.ForceBuild(); ModTextures.Tk2dUpdateMaterialSafe(anim.Sprite); anim.UpdateAnimation(0f); } catch { } if ((Object)(object)loopButtonAppliedMarker == (Object)null) { loopButtonAppliedMarker = ((Component)anim).gameObject.AddComponent<LoopButtonAppliedMarker>(); } loopButtonAppliedMarker.EvolvingEnabled = evolving; if (Scaling.DebugSpam) { ETGModConsole.Log((object)"<color=#48ff00>[LOOP]</color> <color=#FFFFFF>Button sprites applied.</color>", false); } } return flag; } private static List<Key> GetUniqueKeysInClip(tk2dSpriteAnimator anim, tk2dSpriteAnimationClip clip) { List<Key> list = new List<Key>(); if ((Object)(object)anim == (Object)null || clip == null || clip.frames == null) { return list; } HashSet<Key> hashSet = new HashSet<Key>(); for (int i = 0; i < clip.frames.Length; i++) { tk2dSpriteAnimationFrame val = clip.frames[i]; if (val == null) { continue; } tk2dSpriteCollectionData val2 = (((Object)(object)val.spriteCollection != (Object)null) ? val.spriteCollection : anim.Sprite.Collection); if (!((Object)(object)val2 == (Object)null)) { Key item = new Key(val2, val.spriteId); if (hashSet.Add(item)) { list.Add(item); } } } return list; } private static void RemapClipByKeys(tk2dSpriteAnimator anim, tk2dSpriteAnimationClip clip, List<Key> uniqueOld, List<int> newIds) { if (clip == null || clip.frames == null || uniqueOld == null || newIds == null || uniqueOld.Count != newIds.Count) { return; } Dictionary<Key, int> dictionary = new Dictionary<Key, int>(uniqueOld.Count); for (int i = 0; i < uniqueOld.Count; i++) { dictionary[uniqueOld[i]] = newIds[i]; } for (int j = 0; j < clip.frames.Length; j++) { tk2dSpriteAnimationFrame val = clip.frames[j]; if (val == null) { continue; } tk2dSpriteCollectionData val2 = (((Object)(object)val.spriteCollection != (Object)null) ? val.spriteCollection : anim.Sprite.Collection); if (!((Object)(object)val2 == (Object)null)) { Key key = new Key(val2, val.spriteId); if (dictionary.TryGetValue(key, out var value)) { val.spriteId = value; } } } } private static List<int> AddLoopSequenceUsingKeys(List<Key> uniqueOld, Func<int, Texture2D> getTex, string internalPrefix) { List<int> list = new List<int>(uniqueOld.Count); for (int i = 0; i < uniqueOld.Count; i++) { Key key = uniqueOld[i]; if ((Object)(object)key.Col == (Object)null) { return new List<int>(); } Texture2D tex = get