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);