@@ -21,6 +21,8 @@ class UpsideDownJumpThru : JumpThru {
2121
2222 private static ILHook playerOrigUpdateHook ;
2323
24+ private static readonly Hitbox normalHitbox = new Hitbox ( 8f , 11f , - 4f , - 11f ) ;
25+
2426 public static void Load ( ) {
2527 using ( new DetourContext { Before = { "*" } } ) { // these don't always call the orig methods, better apply them first.
2628 // fix general actor/platform behavior to make them comply with jumpthrus.
@@ -42,6 +44,9 @@ public static void Load() {
4244 playerOrigUpdateHook = new ILHook ( typeof ( Player ) . GetMethod ( "orig_Update" ) , filterOutJumpThrusFromCollideChecks ) ;
4345 IL . Celeste . Player . DashUpdate += filterOutJumpThrusFromCollideChecks ;
4446 IL . Celeste . Player . RedDashUpdate += filterOutJumpThrusFromCollideChecks ;
47+
48+ // listen for the player unducking, to knock the player down before they would go through upside down jumpthrus.
49+ On . Celeste . Player . Update += onPlayerUpdate ;
4550 }
4651 }
4752
@@ -55,6 +60,8 @@ public static void Unload() {
5560 playerOrigUpdateHook ? . Dispose ( ) ;
5661 IL . Celeste . Player . DashUpdate -= filterOutJumpThrusFromCollideChecks ;
5762 IL . Celeste . Player . RedDashUpdate -= filterOutJumpThrusFromCollideChecks ;
63+
64+ On . Celeste . Player . Update -= onPlayerUpdate ;
5865 }
5966
6067 private static bool onActorMoveVExact ( On . Celeste . Actor . orig_MoveVExact orig , Actor self , int moveV , Collision onCollide , Solid pusher ) {
@@ -289,6 +296,25 @@ private static void patchPlayerClimbUpdate(ILContext il) {
289296 }
290297 }
291298
299+ private static void onPlayerUpdate ( On . Celeste . Player . orig_Update orig , Player self ) {
300+ bool unduckWouldGoThroughPlatform = self . Ducking && ! self . CollideCheck < UpsideDownJumpThru > ( ) ;
301+ if ( unduckWouldGoThroughPlatform ) {
302+ Collider bak = self . Collider ;
303+ self . Collider = normalHitbox ;
304+ unduckWouldGoThroughPlatform = self . CollideCheck < UpsideDownJumpThru > ( ) ;
305+ self . Collider = bak ;
306+ }
307+
308+ orig ( self ) ;
309+
310+ if ( unduckWouldGoThroughPlatform && ! self . Ducking ) {
311+ // we just unducked, and are now inside an upside-down jumpthru.
312+ // knock the player down if possible!
313+ while ( self . CollideCheck < UpsideDownJumpThru > ( ) && ! self . CollideCheck < Solid > ( self . Position + new Vector2 ( 0f , 1f ) ) ) {
314+ self . Position . Y ++ ;
315+ }
316+ }
317+ }
292318
293319
294320
0 commit comments