Skip to content

Commit 202e81e

Browse files
committed
Fix downwards transitions during dream tunnel dash not happening until the player leaves the solid
1 parent 9eab6d9 commit 202e81e

File tree

1 file changed

+40
-17
lines changed

1 file changed

+40
-17
lines changed

src/DashStates/DreamTunnelDash/DreamTunnelDash.cs

Lines changed: 40 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -118,7 +118,7 @@ public static void Load()
118118
typeof(Player).GetMethod("orig_UpdateSprite", BindingFlags.NonPublic | BindingFlags.Instance),
119119
State_DreamDashEqual);
120120

121-
On.Celeste.Level.EnforceBounds += Level_EnforceBounds;
121+
IL.Celeste.Level.EnforceBounds += Level_EnforceBounds;
122122
On.Celeste.Level.Reload += Level_Reload;
123123
On.Celeste.LevelLoader.StartLevel += LevelLoader_StartLevel;
124124
On.Celeste.Player.OnBoundsH += Player_OnBoundsH;
@@ -151,7 +151,7 @@ public static void Unload()
151151
hook_Player_orig_Update.Dispose();
152152
hook_Player_orig_UpdateSprite.Dispose();
153153

154-
On.Celeste.Level.EnforceBounds -= Level_EnforceBounds;
154+
IL.Celeste.Level.EnforceBounds -= Level_EnforceBounds;
155155
On.Celeste.Level.Reload -= Level_Reload;
156156
On.Celeste.LevelLoader.StartLevel -= LevelLoader_StartLevel;
157157
On.Celeste.Player.OnBoundsH -= Player_OnBoundsH;
@@ -397,7 +397,7 @@ private static void Player_TransitionTo(ILContext il)
397397
}
398398
return;
399399

400-
// utility to replace one method call with another of the same signature if the player is dream dashing
400+
// utility to replace one method call with another of the same signature if the player is dream tunnel dashing
401401
static void UseInsteadIfDreamTunnelDashing<T>(ILCursor cursor, T cb) where T : Delegate
402402
{
403403
ILLabel normalCall = cursor.DefineLabel();
@@ -505,25 +505,48 @@ private static void Player_orig_Update(ILContext il)
505505
// Not used because we DO want to enforce Level bounds.
506506
//Check_State_DreamDash(cursor, false, true);
507507
}
508-
509-
// Kill the player if they attempt to DreamTunnel out of the level and transitions are not enabled
510-
private static void Level_EnforceBounds(On.Celeste.Level.orig_EnforceBounds orig, Level self, Player player)
508+
509+
private static void Level_EnforceBounds(ILContext il)
511510
{
512-
if (DynamicData.For(self).Get<Coroutine>("transition") is not null)
513-
return;
514-
515-
if (player.StateMachine.State == St.DreamTunnelDash && !CommunalHelperModule.Session.CurrentDreamTunnelDashConfiguration.AllowTransitions)
511+
ILCursor cursor = new(il);
512+
513+
// Kill the player if they attempt to DreamTunnel out of the level and transitions are not enabled
514+
if (cursor.TryGotoNext(MoveType.After,
515+
instr => instr.MatchLdarg(0),
516+
instr => instr.MatchLdfld<Level>("transition"),
517+
instr => instr.MatchBrfalse(out ILLabel _),
518+
instr => instr.MatchRet()))
516519
{
517-
Rectangle bounds = self.Bounds;
518-
if (player.Right > bounds.Right || player.Left < bounds.Left || player.Top < bounds.Top || player.Bottom > bounds.Bottom)
520+
ILLabel afterReturn = cursor.DefineLabel();
521+
522+
cursor.MoveAfterLabels();
523+
cursor.Emit(OpCodes.Ldarg_0);
524+
cursor.Emit(OpCodes.Ldarg_1);
525+
cursor.EmitDelegate<Func<Level, Player, bool>>((self, player) =>
519526
{
527+
if (player.StateMachine.State != St.DreamTunnelDash || CommunalHelperModule.Session.CurrentDreamTunnelDashConfiguration.AllowTransitions)
528+
return false;
529+
530+
Rectangle bounds = self.Bounds;
531+
if (player.Right <= bounds.Right && player.Left >= bounds.Left && player.Top >= bounds.Top && player.Bottom <= bounds.Bottom)
532+
return false;
533+
520534
player.DreamDashDie(player.Position);
521-
return;
522-
}
523-
// Continue here, since it may be caught be player.OnBoundsH/OnBoundsV
535+
return true;
536+
});
537+
cursor.Emit(OpCodes.Brfalse_S, afterReturn);
538+
cursor.Emit(OpCodes.Ret);
539+
cursor.MarkLabel(afterReturn);
540+
}
541+
542+
// Ignore check for solids on down transition if dream tunnel dashing
543+
if (cursor.TryGotoNext(MoveType.After,
544+
instr => instr.MatchCallvirt<Entity>("CollideCheck")))
545+
{
546+
cursor.Emit(OpCodes.Ldarg_1);
547+
cursor.EmitDelegate<Func<Player, bool>>(player => player.StateMachine.State != St.DreamTunnelDash);
548+
cursor.Emit(OpCodes.And);
524549
}
525-
526-
orig(self, player);
527550
}
528551

529552
private static void Level_Reload(On.Celeste.Level.orig_Reload orig, Level self)

0 commit comments

Comments
 (0)