public override bool AddInteraction(Entity entity) { Holdable holdable = entity.Get <Holdable>(); // Depends on SpeedGetter and OnRelease being defined if (holdable != null && holdable.SpeedGetter != null && holdable.OnRelease != null && !HasClearPipeInteraction(entity)) { Vector2 pipeOffset = Vector2.Zero; if (entity.Collider != null) { pipeOffset = -entity.Collider.Center; } MarioClearPipeInteraction interaction = new MarioClearPipeInteraction(pipeOffset); interaction.OnPipeBlocked = HoldableInteraction.HoldableOnPipeBlocked; interaction.OnPipeEnter = HoldableInteraction.HoldableOnPipeEnter; interaction.OnPipeExit = HoldableInteraction.HoldableOnPipeExit; interaction.OnPipeUpdate = HoldableInteraction.HoldableOnPipeUpdate; interaction.CanEnterPipe = HoldableInteraction.HoldableCanEnterPipe; entity.Add(interaction); return(true); } return(false); }
public static void PlayerOnPipeExit(Entity entity, MarioClearPipeInteraction interaction) { Player player = entity as Player; if (player != null && interaction != null) { player.StateMachine.Locked = false; player.DummyGravity = true; player.DummyAutoAnimate = true; player.ForceCameraUpdate = false; if (player.StateMachine.State != Player.StRedDash) { player.StateMachine.State = Player.StNormal; } player.Speed = interaction.DirectionVector * interaction.CurrentClearPipe.TransportSpeed; if (Math.Abs(player.Speed.X) > 0.707) { if (interaction.CurrentClearPipe.HasPipeSolids && (player.Speed.X < 0 && Input.MoveX > 0 || player.Speed.X > 0 && Input.MoveX < 0) && Input.Grab.Check && player.StateMachine.State != Player.StRedDash) { player.Speed = Vector2.Zero; } } if (player.StateMachine.State == Player.StRedDash) { player.DashDir = player.Speed.SafeNormalize(); } } }
public static void HoldableOnPipeExit(Entity entity, MarioClearPipeInteraction interaction) { Holdable holdable = entity?.Get <Holdable>(); if (holdable != null && entity.Scene != null && !holdable.IsHeld) { Vector2 speed = Vector2.Zero; switch (interaction.Direction) { case Direction.Left: speed = new Vector2(-1.0f, 0.1f); break; case Direction.Right: speed = new Vector2(1.0f, -0.1f); break; case Direction.Up: speed = new Vector2(0, -1.0f); break; case Direction.Down: speed = new Vector2(0, 1.0f); break; default: break; } holdable.Release(speed); } }
public static void PlayerOnPipeBlocked(Entity entity, MarioClearPipeInteraction interaction) { Player player = entity as Player; if (player != null && !player.Dead) { player.Die(Vector2.Zero); } }
public static void PlayerOnPipeUpdate(Entity entity, MarioClearPipeInteraction interaction) { Player player = entity as Player; if (player != null && player.Dead) { interaction.ExitEarly = true; } }
public static void HoldableOnPipeUpdate(Entity entity, MarioClearPipeInteraction interaction) { Holdable holdable = entity?.Get <Holdable>(); if (holdable != null && holdable.IsHeld) { interaction.ExitEarly = true; } }
public static void PufferOnPipeExit(Entity entity, MarioClearPipeInteraction interaction) { Puffer puffer = entity as Puffer; if (puffer != null) { gotoHitSpeedMethod.Invoke(puffer, new Object[] { interaction.DirectionVector *interaction.TravelSpeed }); } }
public static void HoldableOnPipeEnter(Entity entity, MarioClearPipeInteraction interaction) { Holdable holdable = entity?.Get <Holdable>(); if (holdable != null) { // Reset speeds and remove holder holdable.Release(Vector2.Zero); } }
private void Player_OnCollideH(On.Celeste.Player.orig_OnCollideH orig, Player self, CollisionData data) { // Prevent dust particles / footstep sounds MarioClearPipeInteraction interaction = self.Get <MarioClearPipeInteraction>(); bool inClearPipe = interaction != null && interaction.CurrentClearPipe != null; if (!inClearPipe) { orig(self, data); } }
private void Player_UpdateCarry(On.Celeste.Player.orig_UpdateCarry orig, Player self) { // Player UpdateCarry happens before the collision check with triggers and player colliders // Updating the speed here makes exiting into spikes work as expected orig(self); MarioClearPipeInteraction interaction = self.Get <MarioClearPipeInteraction>(); bool inClearPipe = interaction != null && interaction.CurrentClearPipe != null; if (inClearPipe) { self.Speed = interaction.DirectionVector * interaction.TravelSpeed; } }
private static void Player_Added(On.Celeste.Player.orig_Added orig, Player self, Scene scene) { if (!HasClearPipeInteraction(self)) { MarioClearPipeInteraction interaction = new MarioClearPipeInteraction(new Vector2(0f, 10f)); interaction.OnPipeBlocked = PlayerOnPipeBlocked; interaction.OnPipeEnter = PlayerOnPipeEnter; interaction.OnPipeExit = PlayerOnPipeExit; interaction.CanEnterPipe = PlayerCanEnterPipe; interaction.OnPipeUpdate = PlayerOnPipeUpdate; self.Add(interaction); } orig(self, scene); }
public static void HoldableOnPipeBlocked(Entity entity, MarioClearPipeInteraction interaction) { Actor actor = entity as Actor; if (actor != null) { // Attempt to force a squish by moving the colliding solid by 0 pixels Solid solid = actor.CollideFirst <Solid>(actor.Position); if (solid != null) { solid.MoveHExact(0); } } else { entity?.Scene?.Remove(entity); } }
public static void PlayerOnPipeEnter(Entity entity, MarioClearPipeInteraction interaction) { Player player = entity as Player; if (player != null) { if (player.StateMachine.State != Player.StRedDash) { player.StateMachine.State = Player.StDummy; } player.StateMachine.Locked = true; player.DummyGravity = false; player.DummyAutoAnimate = false; player.ForceCameraUpdate = true; player.Speed = Vector2.Zero; player.Sprite.Play("spin"); } }
public override bool AddInteraction(Entity entity) { Puffer puffer = entity as Puffer; if (puffer != null && !HasClearPipeInteraction(entity)) { MarioClearPipeInteraction interaction = new MarioClearPipeInteraction(Vector2.Zero); interaction.OnPipeBlocked = PufferOnPipeBlocked; interaction.OnPipeEnter = PufferOnPipeEnter; interaction.OnPipeExit = PufferOnPipeExit; interaction.OnPipeUpdate = PufferOnPipeUpdate; interaction.CanEnterPipe = PufferCanEnterPipe; entity.Add(interaction); return(true); } return(false); }
public static void PlayerOnPipeExit(Entity entity, MarioClearPipeInteraction interaction) { Player player = entity as Player; if (player != null && !player.Dead && interaction != null) { player.StateMachine.Locked = false; player.DummyGravity = true; player.DummyAutoAnimate = true; player.ForceCameraUpdate = false; if (player.StateMachine.State != Player.StRedDash) { player.StateMachine.State = Player.StNormal; playerDashCooldownTimerMethod.SetValue(player, 0f); } player.Speed = interaction.DirectionVector * interaction.CurrentClearPipe.TransportSpeed; if (Math.Abs(player.Speed.X) > 0.707) { bool inputTowardsPipe = (player.Speed.X < 0 && Input.MoveX > 0 || player.Speed.X > 0 && Input.MoveX < 0); bool notRedBooster = player.StateMachine.State != Player.StRedDash; bool wallClimbable = !ClimbBlocker.Check(player.Scene, player, player.Position + Vector2.UnitX * 3f * Math.Sign(Input.MoveX)); if (interaction.CurrentClearPipe.HasPipeSolids && inputTowardsPipe && notRedBooster && wallClimbable && Input.Grab.Check && notRedBooster) { player.Speed = Vector2.Zero; } } if (player.StateMachine.State == Player.StRedDash) { player.DashDir = player.Speed.SafeNormalize(); } } }
public static void PufferOnPipeBlocked(Entity entity, MarioClearPipeInteraction interaction) { }
public static void PufferOnPipeUpdate(Entity entity, MarioClearPipeInteraction interaction) { }