Skip to content

Commit

Permalink
finished?
Browse files Browse the repository at this point in the history
  • Loading branch information
wuke32767 committed Nov 18, 2024
1 parent bca0075 commit 0d30d26
Show file tree
Hide file tree
Showing 4 changed files with 268 additions and 2 deletions.
10 changes: 9 additions & 1 deletion Source/Entities/LockBlocks/BaseLockBlock.cs
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,8 @@ public struct OpeningSettings

protected internal readonly string unlockSfxName;

private PlayerCollider playerCollider;

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)
Expand All @@ -77,7 +79,7 @@ public BaseLockBlockComponent(Solid This, EntityData data, Vector2 offset, Entit

ID = id;
RealEntity.DisableLightsInside = false;
RealEntity.Add(new PlayerCollider(OnPlayer, new Circle(60f, 16f, 16f)));
RealEntity.Add(playerCollider = new PlayerCollider(OnPlayer, new Circle(60f, 16f, 16f)));

RealEntity.Add(Sprite = string.IsNullOrWhiteSpace(overrideSpritePath = data.Attr("spritePath", "")) ? MoreLockBlocksGFX.SpriteBank.Create(defaultSpriteID) : BuildCustomSprite(overrideSpritePath));
Sprite.Play("idle");
Expand Down Expand Up @@ -299,6 +301,12 @@ protected internal virtual IEnumerator default_UnlockRoutine_DzhakeHelperUnloade
RealEntity.RemoveSelf();
}

internal void Remove()
{
playerCollider.RemoveSelf();
Sprite.RemoveSelf();
}

#endregion
}
}
23 changes: 22 additions & 1 deletion Source/Entities/LockBlocks/DreamLockBlock.cs
Original file line number Diff line number Diff line change
Expand Up @@ -16,9 +16,20 @@
namespace Celeste.Mod.MoreLockBlocks.Entities
{
[Tracked]
[CustomEntity("MoreLockBlocks/DreamLockBlock")]
[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
{
Expand Down Expand Up @@ -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;
Expand All @@ -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;
Expand Down
235 changes: 235 additions & 0 deletions Source/Entities/LockBlocks/DreamLockBlockV2.cs
Original file line number Diff line number Diff line change
@@ -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<Level>();
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<Level>();

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

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<DreamBlock, bool> 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();
}
}
}




2 changes: 2 additions & 0 deletions Source/MoreLockBlocksModule.cs
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down

0 comments on commit 0d30d26

Please sign in to comment.