@@ -32,6 +32,7 @@ private enum DisableMode
32
32
33
33
public bool IceMode ;
34
34
public bool NoRefillsOnIce ;
35
+ public bool Ceiling ;
35
36
36
37
private DisableMode disableMode ;
37
38
@@ -41,9 +42,12 @@ private enum DisableMode
41
42
public int MoveSpeed ;
42
43
43
44
public FloorBooster ( EntityData data , Vector2 offset )
44
- : this ( data . Position + offset , data . Width , data . Bool ( "left" ) , data . Int ( "speed" ) , data . Bool ( "iceMode" ) , data . Bool ( "noRefillOnIce" ) , data . Bool ( "notAttached" ) ) { }
45
+ : this ( data . Position + offset , data . Width , data . Bool ( "left" ) , data . Int ( "speed" ) , data . Bool ( "iceMode" ) , data . Bool ( "noRefillOnIce" ) , data . Bool ( "notAttached" ) , data . Bool ( "ceiling" ) ) { }
45
46
46
47
public FloorBooster ( Vector2 position , int width , bool left , int speed , bool iceMode , bool noRefillOnIce , bool notAttached )
48
+ : this ( position , width , left , speed , iceMode , noRefillOnIce , notAttached , false ) { }
49
+
50
+ public FloorBooster ( Vector2 position , int width , bool left , int speed , bool iceMode , bool noRefillOnIce , bool notAttached , bool ceiling )
47
51
: base ( position )
48
52
{
49
53
this . Tag = Tags . TransitionUpdate ;
@@ -54,8 +58,9 @@ public FloorBooster(Vector2 position, int width, bool left, int speed, bool iceM
54
58
this . IceMode = iceMode ;
55
59
this . MoveSpeed = ( int ) Calc . Max ( 0 , speed ) ;
56
60
this . Facing = left ? Facings . Left : Facings . Right ;
61
+ this . Ceiling = ceiling ;
57
62
58
- this . Collider = new Hitbox ( width , 3 , 0 , 5 ) ;
63
+ this . Collider = new Hitbox ( width , 3 , 0 , ceiling ? 0 : 5 ) ;
59
64
if ( ! this . notCoreMode )
60
65
Add ( new CoreModeListener ( OnChangeMode ) ) ;
61
66
@@ -74,7 +79,7 @@ public FloorBooster(Vector2 position, int width, bool left, int speed, bool iceM
74
79
} ) ;
75
80
}
76
81
77
- this . tiles = BuildSprite ( left ) ;
82
+ this . tiles = BuildSprite ( left , ceiling ) ;
78
83
}
79
84
80
85
public void SetColor ( Color color )
@@ -109,7 +114,7 @@ private void OnDisable()
109
114
this . Visible = false ;
110
115
}
111
116
112
- private List < Sprite > BuildSprite ( bool left )
117
+ private List < Sprite > BuildSprite ( bool left , bool ceiling )
113
118
{
114
119
var list = new List < Sprite > ( ) ;
115
120
for ( int i = 0 ; i < this . Width ; i += 8 )
@@ -128,6 +133,8 @@ private List<Sprite> BuildSprite(bool left)
128
133
Sprite sprite = VortexHelperModule . FloorBoosterSpriteBank . Create ( "FloorBooster" + id ) ;
129
134
if ( ! left )
130
135
sprite . FlipX = true ;
136
+ if ( ceiling )
137
+ sprite . FlipY = true ;
131
138
132
139
sprite . Position = new Vector2 ( i , 0 ) ;
133
140
list . Add ( sprite ) ;
@@ -151,11 +158,11 @@ private void OnChangeMode(Session.CoreModes mode)
151
158
this . idleSfx . Play ( SFX . env_loc_09_conveyer_idle ) ;
152
159
}
153
160
154
- private bool IsRiding ( JumpThru jumpThru ) => CollideCheckOutside ( jumpThru , this . Position + Vector2 . UnitY ) ;
161
+ private bool IsRiding ( JumpThru jumpThru ) => CollideCheckOutside ( jumpThru , this . Position + ( this . Ceiling ? - Vector2 . UnitY : Vector2 . UnitY ) ) ;
155
162
156
163
private bool IsRiding ( Solid solid )
157
164
{
158
- if ( CollideCheckOutside ( solid , this . Position + Vector2 . UnitY ) )
165
+ if ( CollideCheckOutside ( solid , this . Position + ( this . Ceiling ? - Vector2 . UnitY : Vector2 . UnitY ) ) )
159
166
{
160
167
this . disableMode = ( solid is CassetteBlock or SwitchBlock ) ? DisableMode . ColorFade : DisableMode . Disappear ;
161
168
return true ;
@@ -192,8 +199,10 @@ public override void Update()
192
199
bool isUsed = false ;
193
200
base . Update ( ) ;
194
201
195
- if ( player is not null && CollideCheck ( player ) && player . OnGround ( ) && player . Bottom <= this . Bottom )
196
- isUsed = true ;
202
+ var matchGravity = this . Ceiling == GravityHelperInterop . IsPlayerInverted ( ) ;
203
+
204
+ if ( matchGravity && player is not null && CollideCheck ( player ) && player . OnGround ( ) )
205
+ isUsed = this . Ceiling ? player . Top >= this . Top : player . Bottom <= this . Bottom ;
197
206
198
207
PlayActivateSfx ( this . IceMode || ! isUsed ) ;
199
208
}
@@ -224,7 +233,7 @@ private void PositionSfx(Player entity)
224
233
return ;
225
234
226
235
this . idleSfx . Position = Calc . ClosestPointOnLine ( this . Position , this . Position + new Vector2 ( this . Width , 0f ) , entity . Center ) - this . Position ;
227
- this . idleSfx . Position . Y += 7 ;
236
+ if ( ! this . Ceiling ) this . idleSfx . Position . Y += 7 ;
228
237
this . activateSfx . Position = this . idleSfx . Position ;
229
238
this . idleSfx . UpdateSfxPosition ( ) ; this . activateSfx . UpdateSfxPosition ( ) ;
230
239
}
@@ -258,13 +267,18 @@ private static bool Player_RefillDash(On.Celeste.Player.orig_RefillDash orig, Pl
258
267
if ( level . Transitioning )
259
268
return orig ( self ) ;
260
269
270
+ var playerInverted = GravityHelperInterop . IsPlayerInverted ( ) ;
271
+
261
272
foreach ( FloorBooster entity in self . Scene . Tracker . GetEntities < FloorBooster > ( ) )
262
273
{
263
274
if ( ! entity . IceMode )
264
275
continue ;
265
276
277
+ if ( entity . Ceiling != playerInverted )
278
+ continue ;
279
+
266
280
if ( self . CollideCheck ( entity ) && self . OnGround ( )
267
- && self . Bottom <= entity . Bottom
281
+ && ( entity . Ceiling ? self . Top >= entity . Top : self . Bottom <= entity . Bottom )
268
282
&& entity . NoRefillsOnIce )
269
283
return false ;
270
284
}
@@ -289,8 +303,9 @@ private static int Player_NormalUpdate(On.Celeste.Player.orig_NormalUpdate orig,
289
303
playerData . Set ( "lastFloorBooster" , null ) ;
290
304
291
305
FloorBooster lastFloorBooster = playerData . Get < FloorBooster > ( "lastFloorBooster" ) ;
306
+ var playerInverted = GravityHelperInterop . IsPlayerInverted ( ) ;
292
307
293
- if ( lastFloorBooster is not null && ! self . CollideCheck ( lastFloorBooster ) )
308
+ if ( lastFloorBooster is not null && ( lastFloorBooster . Ceiling != playerInverted || ! self . CollideCheck ( lastFloorBooster ) ) )
294
309
{
295
310
Vector2 vec = Vector2 . UnitX
296
311
* playerData . Get < float > ( "floorBoosterSpeed" )
@@ -310,8 +325,11 @@ private static int Player_NormalUpdate(On.Celeste.Player.orig_NormalUpdate orig,
310
325
{
311
326
if ( entity . IceMode )
312
327
continue ;
328
+
329
+ if ( entity . Ceiling != playerInverted )
330
+ continue ;
313
331
314
- if ( self . CollideCheck ( entity ) && self . OnGround ( ) && self . StateMachine != Player . StClimb && self . Bottom <= entity . Bottom )
332
+ if ( self . CollideCheck ( entity ) && self . OnGround ( ) && self . StateMachine != Player . StClimb && ( entity . Ceiling ? self . Top >= entity . Top : self . Bottom <= entity . Bottom ) )
315
333
{
316
334
if ( ! touchedFloorBooster )
317
335
{
@@ -349,14 +367,19 @@ private static float GetPlayerFriction()
349
367
{
350
368
if ( ! Util . TryGetPlayer ( out Player player ) )
351
369
return 1.0f ;
370
+
371
+ var playerInverted = GravityHelperInterop . IsPlayerInverted ( ) ;
352
372
353
373
foreach ( FloorBooster entity in player . Scene . Tracker . GetEntities < FloorBooster > ( ) )
354
374
{
355
375
if ( ! entity . IceMode )
356
376
continue ;
377
+
378
+ if ( entity . Ceiling != playerInverted )
379
+ continue ;
357
380
358
381
if ( player . CollideCheck ( entity ) && player . OnGround ( ) && player . StateMachine != Player . StClimb
359
- && player . Bottom <= entity . Bottom )
382
+ && ( entity . Ceiling ? player . Top >= entity . Top : player . Bottom <= entity . Bottom ) )
360
383
return player . SceneAs < Level > ( ) . CoreMode is Session . CoreModes . Cold ? 0.4f : 0.2f ;
361
384
}
362
385
0 commit comments