diff --git a/FancyTileEntities/Entities/BetterIntroCrusher.cs b/FancyTileEntities/Entities/BetterIntroCrusher.cs new file mode 100644 index 0000000..a9d7efe --- /dev/null +++ b/FancyTileEntities/Entities/BetterIntroCrusher.cs @@ -0,0 +1,107 @@ +using Celeste.Mod.Entities; +using Microsoft.Xna.Framework; +using Monocle; +using MonoMod.Utils; +using System; +using System.Collections; + +namespace Celeste.Mod.FancyTileEntities { + public class BetterIntroCrusher : IntroCrusher { + + protected bool manualTrigger; + protected bool triggered; + + protected float delay; + + protected float speed; + + protected DynData baseData; + + public BetterIntroCrusher(EntityData data, Vector2 offset) + : base(data, offset) { + baseData = new DynData(this); + + manualTrigger = data.Bool("manualTrigger"); + delay = data.Float("delay", 1.2f); + speed = data.Float("speed", 2f); + + Remove(Get()); // Remove Everest added listener if it exists + Add(new EntityTriggerListener(Trigger, StartTriggered)); + } + + internal static IEnumerator Sequence(On.Celeste.IntroCrusher.orig_Sequence orig, IntroCrusher self) { + if (self is BetterIntroCrusher crusher) + yield return new SwapImmediately(crusher.Sequence()); + else + yield return new SwapImmediately(orig(self)); + } + + private IEnumerator Sequence() { + Player player; + + do { + yield return null; + player = Scene.Tracker.GetEntity(); + } + while (!triggered && (manualTrigger || player == null || player.X < X + 30f || player.X > Right + 8f)); + + SoundSource shakingSfx = baseData.Get("shakingSfx"); + shakingSfx.Play(SFX.game_00_fallingblock_prologue_shake); + float time = delay; + Shaker shaker = new Shaker(time, removeOnFinish: true, v => baseData["shake"] = v); + if (delay > 0f) { + Add(shaker); + } + Input.Rumble(RumbleStrength.Medium, RumbleLength.Medium); + + while (time > 0f) { + player = Scene.Tracker.GetEntity(); + if (!manualTrigger && player != null && (player.X >= X + Width - 8f || player.X < X + 28f)) { + shaker.RemoveSelf(); + break; + } + yield return null; + time -= Engine.DeltaTime; + } + + for (int i = 2; i < Width; i += 4) { + SceneAs().Particles.Emit(FallingBlock.P_FallDustA, 2, new Vector2(X + i, Y), Vector2.One * 4f, (float) Math.PI / 2f); + SceneAs().Particles.Emit(FallingBlock.P_FallDustB, 2, new Vector2(X + i, Y), Vector2.One * 4f); + } + shakingSfx.Param("release", 1f); + + time = 0f; + do { + yield return null; + time = Calc.Approach(time, 1f, speed * Engine.DeltaTime); + MoveTo(Vector2.Lerp(baseData.Get("start"), baseData.Get("end"), Ease.CubeIn(time))); + } + while (time < 1f); + + for (int j = 0; j <= Width; j += 4) { + SceneAs().ParticlesFG.Emit(FallingBlock.P_FallDustA, 1, new Vector2(X + j, Bottom), Vector2.One * 4f, -(float) Math.PI / 2f); + float direction = (j < Width / 2f) ? ((float) Math.PI) : 0f; + SceneAs().ParticlesFG.Emit(FallingBlock.P_LandDust, 1, new Vector2(X + j, Bottom), Vector2.One * 4f, direction); + } + shakingSfx.Stop(); + Audio.Play(SFX.game_00_fallingblock_prologue_impact, Position); + SceneAs().Shake(); + Input.Rumble(RumbleStrength.Strong, RumbleLength.Medium); + Add(new Shaker(0.25f, removeOnFinish: true, v => baseData["shake"] = v)); + } + + public void Trigger() { + if (manualTrigger) { + triggered = true; + } + } + + public void StartTriggered() { + if (manualTrigger) { + triggered = true; + Position = baseData.Get("end"); + Remove(Get()); + } + } + } +} diff --git a/FancyTileEntities/Entities/IntroCrusher.cs b/FancyTileEntities/Entities/IntroCrusher.cs index 35bb4d6..ba6c359 100644 --- a/FancyTileEntities/Entities/IntroCrusher.cs +++ b/FancyTileEntities/Entities/IntroCrusher.cs @@ -1,7 +1,6 @@ using Celeste.Mod.Entities; using Microsoft.Xna.Framework; using Monocle; -using MonoMod.Utils; using System; using System.Collections.Generic; using System.Reflection; @@ -10,10 +9,9 @@ namespace Celeste.Mod.FancyTileEntities { [CustomEntity("FancyTileEntities/FancyIntroCrusher")] - class FancyIntroCrusher : IntroCrusher { + class FancyIntroCrusher : BetterIntroCrusher { private static readonly FieldInfo> f_Solid_riders; - private DynData baseData; private VirtualMap tileMap; static FancyIntroCrusher() { @@ -22,7 +20,6 @@ class FancyIntroCrusher : IntroCrusher { public FancyIntroCrusher(EntityData data, Vector2 offset) : base(data, offset) { - baseData = new DynData(this); Remove(baseData.Get("tilegrid")); tileMap = GenerateTileMap(data.Attr("tileData", "")); diff --git a/FancyTileEntities/FancyTileEntitiesModule.cs b/FancyTileEntities/FancyTileEntitiesModule.cs index ddfacab..c9edcbb 100644 --- a/FancyTileEntities/FancyTileEntitiesModule.cs +++ b/FancyTileEntities/FancyTileEntitiesModule.cs @@ -18,6 +18,7 @@ public class FancyTileEntitiesModule : EverestModule { On.Celeste.CrumbleWallOnRumble.Break += FancyCrumbleWallOnRumble.Break; On.Celeste.DashBlock.Break_Vector2_Vector2_bool_bool += FancyDashBlock.Break; + On.Celeste.IntroCrusher.Sequence += BetterIntroCrusher.Sequence; On.Celeste.FallingBlock.LandParticles += FancyFallingBlock.LandParticles; hook_FallingBlock_Sequence = new ILHook( typeof(FallingBlock).GetMethod("Sequence", System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance).GetStateMachineTarget(), diff --git a/everest.yaml b/everest.yaml index 77df179..bc3550f 100644 --- a/everest.yaml +++ b/everest.yaml @@ -3,4 +3,4 @@ DLL: FancyTileEntities/bin/Debug/net452/FancyTileEntities.dll Dependencies: - Name: Everest - Version: 1.0.0 + Version: 1.2824.0