diff --git a/Source/Entities/LockBlocks/BaseLockBlock.cs b/Source/Entities/LockBlocks/BaseLockBlock.cs index 1de8cef..9c3cdb4 100644 --- a/Source/Entities/LockBlocks/BaseLockBlock.cs +++ b/Source/Entities/LockBlocks/BaseLockBlock.cs @@ -1,20 +1,44 @@ +using Celeste.Mod.DzhakeHelper; +using Celeste.Mod.DzhakeHelper.Entities; using Microsoft.Xna.Framework; using Monocle; +using System; using System.Collections; using System.Runtime.CompilerServices; -using Celeste.Mod.DzhakeHelper; -using Celeste.Mod.DzhakeHelper.Entities; namespace Celeste.Mod.MoreLockBlocks.Entities { - public abstract class BaseLockBlock : Solid + public abstract class LegacyBaseLockBlock : Solid + { + public EntityID ID => component.ID; + + protected internal string overrideSpritePath => component.overrideSpritePath; + public Sprite Sprite => component.Sprite; + + protected internal BaseLockBlockComponent.OpeningSettings openingSettings { get => component.openingSettings; set => component.openingSettings = value; } + + protected internal bool opening { get => component.opening; set => component.opening = value; } + public bool UnlockingRegistered { get => component.UnlockingRegistered; set => component.UnlockingRegistered = value; } + + protected internal bool stepMusicProgress => component.stepMusicProgress; + + protected internal string unlockSfxName => component.unlockSfxName; + public LegacyBaseLockBlock(EntityData data, Vector2 offset, EntityID id, string defaultSpriteID = "MoreLockBlocks_generic_lock", string defaultUnlockSfx = "event:/game/03_resort/key_unlock") + : base(data.Position + offset, 32f, 32f, false) + { + Add(component = new BaseLockBlockComponent(this, data, offset, id, defaultSpriteID, defaultSpriteID)); + } + protected readonly BaseLockBlockComponent component; + } + public class BaseLockBlockComponent : Component { + public Solid RealEntity; public EntityID ID; - protected readonly string overrideSpritePath; + protected internal readonly string overrideSpritePath; public readonly Sprite Sprite; - protected struct OpeningSettings + public struct OpeningSettings { public bool VanillaKeys; @@ -22,24 +46,44 @@ protected struct OpeningSettings public bool DzhakeHelperKeysAll; public int DzhakeHelperKeyGroup; } - protected OpeningSettings openingSettings; + protected internal OpeningSettings openingSettings; - protected bool opening; + protected internal bool opening; public bool UnlockingRegistered; - protected readonly bool stepMusicProgress; + protected internal readonly bool stepMusicProgress; + + protected internal readonly string unlockSfxName; - protected readonly string unlockSfxName; + private PlayerCollider playerCollider; - public BaseLockBlock(EntityData data, Vector2 offset, EntityID id, string defaultSpriteID = "MoreLockBlocks_generic_lock", string defaultUnlockSfx = "event:/game/03_resort/key_unlock") : base(data.Position + offset, 32f, 32f, false) + public BaseLockBlockComponent(Solid This, EntityData data, Vector2 offset, EntityID id, string defaultSpriteID = "MoreLockBlocks_generic_lock", string defaultUnlockSfx = "event:/game/03_resort/key_unlock") + //: base(data.Position + offset, 32f, 32f, false) + : base(true, true) { + RealEntity = This; + if (MoreLockBlocksModule.Instance.DzhakeHelperLoaded) + { + OnPlayer = default_OnPlayer_DzhakeHelperLoaded; + UnlockRoutine = default_UnlockRoutine_DzhakeHelperLoaded; + TryOpen = default_TryOpen_DzhakeHelperLoaded; + } + else + { + OnPlayer = default_OnPlayer_DzhakeHelperUnloaded; + UnlockRoutine = default_UnlockRoutine_DzhakeHelperUnloaded; + TryOpen = default_TryOpen_DzhakeHelperUnloaded; + } + + + ID = id; - DisableLightsInside = false; - Add(new PlayerCollider(OnPlayer, new Circle(60f, 16f, 16f))); + RealEntity.DisableLightsInside = false; + RealEntity.Add(playerCollider = new PlayerCollider(OnPlayer, new Circle(60f, 16f, 16f))); - Add(Sprite = string.IsNullOrWhiteSpace(overrideSpritePath = data.Attr("spritePath", "")) ? MoreLockBlocksGFX.SpriteBank.Create(defaultSpriteID) : BuildCustomSprite(overrideSpritePath)); + RealEntity.Add(Sprite = string.IsNullOrWhiteSpace(overrideSpritePath = data.Attr("spritePath", "")) ? MoreLockBlocksGFX.SpriteBank.Create(defaultSpriteID) : BuildCustomSprite(overrideSpritePath)); Sprite.Play("idle"); - Sprite.Position = new Vector2(Width / 2f, Height / 2f); + Sprite.Position = new Vector2(RealEntity.Width / 2f, RealEntity.Height / 2f); string dzhakeHelperKeySettings = data.Attr("dzhakeHelperKeySettings", ""); bool _ = int.TryParse(dzhakeHelperKeySettings, out int dzhakeHelperKeyGroup); @@ -58,7 +102,7 @@ public BaseLockBlock(EntityData data, Vector2 offset, EntityID id, string defaul unlockSfxName = SFX.EventnameByHandle(unlockSfxName); } - protected static Sprite BuildCustomSprite(string spritePath) + protected internal static Sprite BuildCustomSprite(string spritePath) { /* @@ -79,20 +123,9 @@ protected static Sprite BuildCustomSprite(string spritePath) #region OnPlayer - protected void OnPlayer(Player player) - { - if (MoreLockBlocksModule.Instance.DzhakeHelperLoaded) - { - OnPlayer_DzhakeHelperLoaded(player); - } - else - { - OnPlayer_DzhakeHelperUnloaded(player); - } - } - + protected internal Action OnPlayer; [MethodImpl(MethodImplOptions.NoInlining)] - protected virtual void OnPlayer_DzhakeHelperLoaded(Player player) + protected internal virtual void default_OnPlayer_DzhakeHelperLoaded(Player player) { if (opening) { @@ -114,7 +147,7 @@ protected virtual void OnPlayer_DzhakeHelperLoaded(Player player) } [MethodImpl(MethodImplOptions.NoInlining)] - protected virtual void OnPlayer_DzhakeHelperUnloaded(Player player) + protected internal virtual void default_OnPlayer_DzhakeHelperUnloaded(Player player) { if (opening) { @@ -133,23 +166,12 @@ protected virtual void OnPlayer_DzhakeHelperUnloaded(Player player) #endregion #region TryOpen - protected void TryOpen(Player player, Follower fol) - { - if (MoreLockBlocksModule.Instance.DzhakeHelperLoaded) - { - TryOpen_DzhakeHelperLoaded(player, fol); - } - else - { - TryOpen_DzhakeHelperUnloaded(player, fol); - } - } - + protected internal Action TryOpen; [MethodImpl(MethodImplOptions.NoInlining)] - protected virtual void TryOpen_DzhakeHelperLoaded(Player player, Follower fol) + protected internal virtual void default_TryOpen_DzhakeHelperLoaded(Player player, Follower fol) { - Collidable = false; - if (!Scene.CollideCheck(player.Center, Center)) + RealEntity.Collidable = false; + if (!RealEntity.Scene.CollideCheck(player.Center, RealEntity.Center)) { opening = true; if (fol.Entity is Key key) @@ -160,58 +182,47 @@ protected virtual void TryOpen_DzhakeHelperLoaded(Player player, Follower fol) { key2.StartedUsing = true; } - Add(new Coroutine(UnlockRoutine(fol))); + RealEntity.Add(new Coroutine(UnlockRoutine(fol))); } - Collidable = true; + RealEntity.Collidable = true; } [MethodImpl(MethodImplOptions.NoInlining)] - protected virtual void TryOpen_DzhakeHelperUnloaded(Player player, Follower fol) + protected internal virtual void default_TryOpen_DzhakeHelperUnloaded(Player player, Follower fol) { - Collidable = false; - if (!Scene.CollideCheck(player.Center, Center)) + RealEntity.Collidable = false; + if (!RealEntity.Scene.CollideCheck(player.Center, RealEntity.Center)) { opening = true; if (fol.Entity is Key key) { key.StartedUsing = true; } - Add(new Coroutine(UnlockRoutine(fol))); + RealEntity.Add(new Coroutine(UnlockRoutine(fol))); } - Collidable = true; + RealEntity.Collidable = true; } #endregion #region UnlockRoutine - protected IEnumerator UnlockRoutine(Follower fol) - { - if (MoreLockBlocksModule.Instance.DzhakeHelperLoaded) - { - yield return new SwapImmediately(UnlockRoutine_DzhakeHelperLoaded(fol)); - } - else - { - yield return new SwapImmediately(UnlockRoutine_DzhakeHelperUnloaded(fol)); - } - } - + protected internal Func UnlockRoutine; [MethodImpl(MethodImplOptions.NoInlining)] - protected virtual IEnumerator UnlockRoutine_DzhakeHelperLoaded(Follower fol) + protected internal virtual IEnumerator default_UnlockRoutine_DzhakeHelperLoaded(Follower fol) { - SoundEmitter emitter = SoundEmitter.Play(unlockSfxName, this); + SoundEmitter emitter = SoundEmitter.Play(unlockSfxName, RealEntity); emitter.Source.DisposeOnTransition = true; - Level level = SceneAs(); + Level level = RealEntity.SceneAs(); Key key = fol.Entity as Key; CustomKey key2 = fol.Entity as CustomKey; if (key is not null) { - Add(new Coroutine(key.UseRoutine(Center + new Vector2(0f, 2f)))); + RealEntity.Add(new Coroutine(key.UseRoutine(RealEntity.Center + new Vector2(0f, 2f)))); } else if (key2 is not null) { - Add(new Coroutine(key2.UseRoutine(Center + new Vector2(0f, 2f)))); + RealEntity.Add(new Coroutine(key2.UseRoutine(RealEntity.Center + new Vector2(0f, 2f)))); } yield return 1.2f; @@ -242,8 +253,8 @@ protected virtual IEnumerator UnlockRoutine_DzhakeHelperLoaded(Follower fol) } } - Tag |= Tags.TransitionUpdate; - Collidable = false; + RealEntity.Tag |= Tags.TransitionUpdate; + RealEntity.Collidable = false; emitter.Source.DisposeOnTransition = false; yield return Sprite.PlayRoutine("open"); @@ -251,18 +262,18 @@ protected virtual IEnumerator UnlockRoutine_DzhakeHelperLoaded(Follower fol) Input.Rumble(RumbleStrength.Medium, RumbleLength.Medium); yield return Sprite.PlayRoutine("burst"); - RemoveSelf(); + RealEntity.RemoveSelf(); } [MethodImpl(MethodImplOptions.NoInlining)] - protected virtual IEnumerator UnlockRoutine_DzhakeHelperUnloaded(Follower fol) + protected internal virtual IEnumerator default_UnlockRoutine_DzhakeHelperUnloaded(Follower fol) { - SoundEmitter emitter = SoundEmitter.Play(unlockSfxName, this); + SoundEmitter emitter = SoundEmitter.Play(unlockSfxName, RealEntity); emitter.Source.DisposeOnTransition = true; - Level level = SceneAs(); + Level level = RealEntity.SceneAs(); Key key = fol.Entity as Key; - Add(new Coroutine(key.UseRoutine(Center + new Vector2(0f, 2f)))); + RealEntity.Add(new Coroutine(key.UseRoutine(RealEntity.Center + new Vector2(0f, 2f)))); yield return 1.2f; UnlockingRegistered = true; @@ -278,8 +289,8 @@ protected virtual IEnumerator UnlockRoutine_DzhakeHelperUnloaded(Follower fol) yield return null; } - Tag |= Tags.TransitionUpdate; - Collidable = false; + RealEntity.Tag |= Tags.TransitionUpdate; + RealEntity.Collidable = false; emitter.Source.DisposeOnTransition = false; yield return Sprite.PlayRoutine("open"); @@ -287,7 +298,13 @@ protected virtual IEnumerator UnlockRoutine_DzhakeHelperUnloaded(Follower fol) Input.Rumble(RumbleStrength.Medium, RumbleLength.Medium); yield return Sprite.PlayRoutine("burst"); - RemoveSelf(); + RealEntity.RemoveSelf(); + } + + internal void Remove() + { + playerCollider.RemoveSelf(); + Sprite.RemoveSelf(); } #endregion diff --git a/Source/Entities/LockBlocks/DreamLockBlock.cs b/Source/Entities/LockBlocks/DreamLockBlock.cs index 7ce0157..f3f5cd8 100644 --- a/Source/Entities/LockBlocks/DreamLockBlock.cs +++ b/Source/Entities/LockBlocks/DreamLockBlock.cs @@ -16,9 +16,20 @@ namespace Celeste.Mod.MoreLockBlocks.Entities { [Tracked] - [CustomEntity("MoreLockBlocks/DreamLockBlock")] - public class DreamLockBlock : BaseLockBlock + [CustomEntity("MoreLockBlocks/DreamLockBlock=Load")] + public class DreamLockBlock : LegacyBaseLockBlock { + public static Entity Load(Level level, LevelData levelData, Vector2 offset, EntityData entityData) + { + if (MoreLockBlocksModule.PatchLoaded) + { + return new DreamLockBlockV2(entityData, offset, new EntityID(levelData.Name, entityData.ID)); + } + else + { + return new DreamLockBlock(entityData, offset, new EntityID(levelData.Name, entityData.ID)); + } + } [TrackedAs(typeof(DreamBlock))] internal class DreamBlockDummy : DreamBlock { @@ -121,6 +132,11 @@ public IEnumerator DummyUnlockRoutine() public static void Load() { + if (MoreLockBlocksModule.PatchLoaded) + { + DreamLockBlockV2.Load(); + return; + } IL.Celeste.DreamBlock.Added += DreamBlock_Added; On.Celeste.DreamBlock.Activate += DreamBlock_Activate; On.Celeste.DreamBlock.FastActivate += DreamBlock_FastActivate; @@ -139,6 +155,11 @@ public static void Load() public static void Unload() { + if (MoreLockBlocksModule.PatchLoaded) + { + DreamLockBlockV2.Unload(); + return; + } IL.Celeste.DreamBlock.Added -= DreamBlock_Added; On.Celeste.DreamBlock.Activate -= DreamBlock_Activate; On.Celeste.DreamBlock.FastActivate -= DreamBlock_FastActivate; @@ -257,6 +278,16 @@ public DreamLockBlock(EntityData data, Vector2 offset, EntityID id) : base(data, SurfaceSoundIndex = 11; dummyBelow = data.Bool("below", false); dummyIgnoreInventory = data.Bool("ignoreInventory", false); + if (MoreLockBlocksModule.Instance.DzhakeHelperLoaded) + { + component.TryOpen = TryOpen_DzhakeHelperLoaded; + component.UnlockRoutine = UnlockRoutine_DzhakeHelperLoaded; + } + else + { + component.TryOpen = TryOpen_DzhakeHelperUnloaded; + component.UnlockRoutine = UnlockRoutine_DzhakeHelperUnloaded; + } } public override void Added(Scene scene) @@ -274,7 +305,7 @@ public override void Added(Scene scene) #region TryOpen [MethodImpl(MethodImplOptions.NoInlining)] - protected override void TryOpen_DzhakeHelperLoaded(Player player, Follower fol) + protected void TryOpen_DzhakeHelperLoaded(Player player, Follower fol) { Collidable = dummy.Collidable = false; if (!Scene.CollideCheck(player.Center, Center)) @@ -288,13 +319,13 @@ protected override void TryOpen_DzhakeHelperLoaded(Player player, Follower fol) { key2.StartedUsing = true; } - Add(new Coroutine(UnlockRoutine(fol))); + Add(new Coroutine(component.UnlockRoutine(fol))); } Collidable = dummy.Collidable = true; } [MethodImpl(MethodImplOptions.NoInlining)] - protected override void TryOpen_DzhakeHelperUnloaded(Player player, Follower fol) + protected void TryOpen_DzhakeHelperUnloaded(Player player, Follower fol) { Collidable = dummy.Collidable = false; if (!Scene.CollideCheck(player.Center, Center)) @@ -304,7 +335,7 @@ protected override void TryOpen_DzhakeHelperUnloaded(Player player, Follower fol { key.StartedUsing = true; } - Add(new Coroutine(UnlockRoutine(fol))); + Add(new Coroutine(component.UnlockRoutine(fol))); } Collidable = dummy.Collidable = true; } @@ -313,7 +344,7 @@ protected override void TryOpen_DzhakeHelperUnloaded(Player player, Follower fol #region UnlockRoutine [MethodImpl(MethodImplOptions.NoInlining)] - protected override IEnumerator UnlockRoutine_DzhakeHelperLoaded(Follower fol) + protected IEnumerator UnlockRoutine_DzhakeHelperLoaded(Follower fol) { SoundEmitter emitter = SoundEmitter.Play(unlockSfxName, this); emitter.Source.DisposeOnTransition = true; @@ -373,7 +404,7 @@ protected override IEnumerator UnlockRoutine_DzhakeHelperLoaded(Follower fol) } [MethodImpl(MethodImplOptions.NoInlining)] - protected override IEnumerator UnlockRoutine_DzhakeHelperUnloaded(Follower fol) + protected IEnumerator UnlockRoutine_DzhakeHelperUnloaded(Follower fol) { SoundEmitter emitter = SoundEmitter.Play(unlockSfxName, this); emitter.Source.DisposeOnTransition = true; diff --git a/Source/Entities/LockBlocks/DreamLockBlockV2.cs b/Source/Entities/LockBlocks/DreamLockBlockV2.cs new file mode 100644 index 0000000..a0a7982 --- /dev/null +++ b/Source/Entities/LockBlocks/DreamLockBlockV2.cs @@ -0,0 +1,235 @@ +using Celeste.Mod.DzhakeHelper; +using Celeste.Mod.DzhakeHelper.Entities; +using Celeste.Mod.Entities; +using Microsoft.Xna.Framework; +using Monocle; +using MonoMod; +using MonoMod.RuntimeDetour; +using System; +using System.Collections; + +namespace Celeste.Mod.MoreLockBlocks.Entities +{ + [CustomEntity("MoreLockBlocks/DreamLockBlock")] + [TrackedAs(typeof(DreamBlock))] + internal class DreamLockBlockV2 : DreamBlock + { + readonly bool ignoreInventory; + BaseLockBlockComponent component; + bool unlocked; + public DreamLockBlockV2(EntityData data, Vector2 offset, EntityID id) + : base(data.Position + offset, 32, 32, null, false, false, data.Bool("below", false)) + // : base(data, offset, id, defaultUnlockSfx: MoreLockBlocksSFX.game_lockblocks_dreamlockblock_key_unlock) + { + Add(component = new BaseLockBlockComponent(this, data, offset, id, defaultUnlockSfx: MoreLockBlocksSFX.game_lockblocks_dreamlockblock_key_unlock)); + SurfaceSoundIndex = 11; + ignoreInventory = data.Bool("ignoreInventory", false); + if (MoreLockBlocksModule.Instance.DzhakeHelperLoaded) + { + component.UnlockRoutine = UnlockRoutine_DzhakeHelperLoaded; + } + else + { + component.UnlockRoutine = UnlockRoutine_DzhakeHelperUnloaded; + } + } + public override void Added(Scene scene) + { + if (MoreLockBlocksModule.Session.UnlockedDreamLockBlocks.Contains(component.ID)) + { + unlocked = true; + component.Remove(); + } + base.Added(scene); + } + public override void Render() + { + base.Render(); + //:sobeline: + Entity_Render(this); + } + [MonoModLinkTo("Monocle.Entity", "System.Void Render()")] + private static void Entity_Render(Entity self) + { + throw new NotImplementedException(); + } + + private const float chargeUpDuration = 6f, unlockDuration = 0.25f, chargeDownDuration = 0.1f; + + public IEnumerator DummyUnlockRoutine() + { + if (!Activated) + { + yield break; + } + Level level = SceneAs(); + Input.Rumble(RumbleStrength.Light, RumbleLength.Long); + Add(shaker = new Shaker(true, delegate (Vector2 s) + { + shake = s; + })); + shaker.Interval = 0.02f; + + for (float percent = 0f; percent < 1f; percent += Engine.DeltaTime / chargeUpDuration) + { + whiteFill = Ease.CubeIn(percent); + yield return null; + } + UpdateNoRoutine(); // in some cases, this will not be called. + shaker.On = false; // so better to close it manually. + + whiteHeight = 1f; + whiteFill = 1f; + for (float percent = 1f; percent > 0f; percent -= Engine.DeltaTime / unlockDuration) + { + whiteHeight = percent; + Glitch.Value = percent * 0.2f; + if (level.OnInterval(0.1f)) + { + for (int i = 0; i < Width; i += 4) + { + level.ParticlesFG.Emit(Strawberry.P_WingsBurst, new Vector2(X + i, Y + Height * whiteHeight + 1f)); + } + } + if (level.OnInterval(0.1f)) + { + level.Shake(); + } + Input.Rumble(RumbleStrength.Strong, RumbleLength.Short); + yield return null; + } + whiteHeight = Glitch.Value = 0f; + + while (whiteFill > 0f) + { + whiteFill -= Engine.DeltaTime / chargeDownDuration; + yield return null; + } + } + + IEnumerator UnlockRoutine_DzhakeHelperLoaded(Follower fol) + { + SoundEmitter emitter = SoundEmitter.Play(component.unlockSfxName, this); + emitter.Source.DisposeOnTransition = true; + Level level = SceneAs(); + + Key key = fol.Entity as Key; + CustomKey key2 = fol.Entity as CustomKey; + if (key is not null) + { + Add(new Coroutine(key.UseRoutine(Center + new Vector2(0f, 2f)))); + } + else if (key2 is not null) + { + Add(new Coroutine(key2.UseRoutine(Center + new Vector2(0f, 2f)))); + } + yield return 1.2f; + + component.UnlockingRegistered = true; + if (component.stepMusicProgress) + { + level.Session.Audio.Music.Progress++; + level.Session.Audio.Apply(); + } + MoreLockBlocksModule.Session.UnlockedDreamLockBlocks.Add(component.ID); + if (key is not null) + { + key.RegisterUsed(); + + while (key.Turning) + { + yield return null; + } + } + else if (key2 is not null) + { + key2.RegisterUsed(); + DzhakeHelperModule.Session.CurrentKeys.RemoveAll(info => info.ID.ID == key2.ID.ID); + + while (key2.Turning) + { + yield return null; + } + } + + Tag |= Tags.TransitionUpdate; + //Collidable = false; + unlocked = true; + emitter.Source.DisposeOnTransition = false; + Add(new Coroutine(DummyUnlockRoutine())); + SurfaceSoundIndex = 12; + yield return component.Sprite.PlayRoutine("open"); + + level.Shake(); + Input.Rumble(RumbleStrength.Medium, RumbleLength.Medium); + yield return component.Sprite.PlayRoutine("burst"); + + } + + IEnumerator UnlockRoutine_DzhakeHelperUnloaded(Follower fol) + { + SoundEmitter emitter = SoundEmitter.Play(component.unlockSfxName, this); + emitter.Source.DisposeOnTransition = true; + Level level = SceneAs(); + + Key key = fol.Entity as Key; + Add(new Coroutine(key.UseRoutine(Center + new Vector2(0f, 2f)))); + yield return 1.2f; + + component.UnlockingRegistered = true; + if (component.stepMusicProgress) + { + level.Session.Audio.Music.Progress++; + level.Session.Audio.Apply(); + } + MoreLockBlocksModule.Session.UnlockedDreamLockBlocks.Add(component.ID); + key.RegisterUsed(); + while (key.Turning) + { + yield return null; + } + + Tag |= Tags.TransitionUpdate; + //Collidable = false; + unlocked = true; + emitter.Source.DisposeOnTransition = false; + Add(new Coroutine(DummyUnlockRoutine())); + SurfaceSoundIndex = 12; + yield return component.Sprite.PlayRoutine("open"); + + level.Shake(); + Input.Rumble(RumbleStrength.Medium, RumbleLength.Medium); + yield return component.Sprite.PlayRoutine("burst"); + } + static Hook patch; + internal static void Load() + { + patch = new Hook(typeof(DreamBlock).GetProperty(nameof(DreamBlock.Activated)).GetMethod, static (Func orig, DreamBlock self) => + { + bool o = orig(self); + if (self is DreamLockBlockV2 v2) + { + if (!v2.unlocked) + { + return false; + } + if (v2.ignoreInventory) + { + return v2.unlocked; + } + } + return o; + }); + + } + + internal static void Unload() + { + patch?.Dispose(); + } + } +} + + + + diff --git a/Source/Entities/LockBlocks/GlassLockBlock.cs b/Source/Entities/LockBlocks/GlassLockBlock.cs index 6df2685..d3493c0 100644 --- a/Source/Entities/LockBlocks/GlassLockBlock.cs +++ b/Source/Entities/LockBlocks/GlassLockBlock.cs @@ -10,7 +10,7 @@ namespace Celeste.Mod.MoreLockBlocks.Entities { [Tracked] [CustomEntity("MoreLockBlocks/GlassLockBlock")] - public class GlassLockBlock : BaseLockBlock + public class GlassLockBlock : LegacyBaseLockBlock { private const string spriteID = "MoreLockBlocks_generic_lock"; diff --git a/Source/MoreLockBlocksModule.cs b/Source/MoreLockBlocksModule.cs index 3ac43a0..234e335 100644 --- a/Source/MoreLockBlocksModule.cs +++ b/Source/MoreLockBlocksModule.cs @@ -9,6 +9,8 @@ namespace Celeste.Mod.MoreLockBlocks; public class MoreLockBlocksModule : EverestModule { + public static readonly bool PatchLoaded = typeof(DreamBlock).GetField("DreamBlockPatch", BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic) is not null; + public static MoreLockBlocksModule Instance { get; private set; } public override Type SettingsType => typeof(MoreLockBlocksModuleSettings);