private IEnumerator BadelineVanishes() { yield return(0.2f); badeline.Vanish(); Input.Rumble(RumbleStrength.Medium, RumbleLength.Medium); badeline = null; yield return(0.2f); }
private void RemoveBadeline(BadelineDummy badeline) { if (respawnTimer <= 0) { respawnTimer = respwanTime; } Disappear(badeline); badelines.Remove(badeline); }
private void Disappear(BadelineDummy badeline, bool silent = false) { if (!silent) { Audio.Play("event:/char/badeline/disappear", badeline.Position); } SceneAs <Level>()?.Displacement.AddBurst(badeline.Center, 0.5f, 24f, 96f, 0.4f); SceneAs <Level>()?.Particles.Emit(BadelineOldsite.P_Vanish, 12, badeline.Center, Vector2.One * 6f); badeline.RemoveSelf(); }
private void AddBadeline(bool silent = false) { BadelineDummy badeline = new BadelineDummy(Vector2.Zero) { Collider = new Hitbox(8f, 9f, -4f, -11f), Tag = Tags.Persistent }; badeline.Add(new Coroutine(Appear(badeline, silent))); Scene.Add(badeline); }
private IEnumerator WalkRightEnding() { Add(new Coroutine(_player.DummyWalkTo(_player.Position.X + 128f, speedMultiplier: 0.5f))); yield return(0.5f); BadelineDummy badeline; Level.Add(badeline = new BadelineDummy(_player.Position - new Vector2(250f, 24f))); badeline.FloatSpeed = 20f; yield return(badeline.FloatTo(badeline.Position + Vector2.UnitX * 48f)); yield return(1.5f); EndCutscene(Level); }
private IEnumerator BadelineAppears() { Audio.Play("event:/char/badeline/maddy_split", player.Position); Level.Add(badeline = new BadelineDummy(player.Center)); Level.Displacement.AddBurst(badeline.Center, 0.5f, 8f, 32f, 0.5f); Level.Session.Inventory.Dashes = 1; player.Dashes = 1; badeline.Sprite.Scale.X = -1f; yield return(badeline.FloatTo(player.Center + new Vector2(18f, -10f), -1, false)); yield return(0.2f); player.Facing = Facings.Right; yield return(null); }
public static Entity Load(Level level, LevelData levelData, Vector2 offset, EntityData entityData) { // there is literally something made for this in vanilla... but it cannot be placed as an entity. BadelineDummy dummy = new BadelineDummy(entityData.Position + offset); if (!entityData.Bool("left")) { dummy.Sprite.Scale.X = 1; } if (!entityData.Bool("floating")) { dummy.Floatness = 0f; dummy.Sprite.Play("idle"); } return(dummy); }
private IEnumerator Appear(BadelineDummy badeline, bool silent = false) { if (Scene == null) { badeline.RemoveSelf(); yield break; } badelines.Add(badeline); ResetPosition(); if (!silent) { Audio.Play("event:/char/badeline/appear", badeline.Position); } SceneAs <Level>().Displacement.AddBurst(badeline.Center, 0.5f, 24f, 96f, 0.4f); SceneAs <Level>().Particles.Emit(BadelineOldsite.P_Vanish, 12, badeline.Center, Vector2.One * 6f); }
private void ResetPosition() { if (clockwise) { rotationPercent -= Engine.DeltaTime / rotationTime; ++rotationPercent; } else { rotationPercent += Engine.DeltaTime / rotationTime; } rotationPercent %= 1f; for (var i = 0; i < badelines.Count; i++) { BadelineDummy badeline = badelines[i]; float badelineRotationPercent = (rotationPercent + i * 1.0f / badelines.Count) % 1f; badeline.Position = player.Center + Calc.AngleToVector(GetAngle(badelineRotationPercent), radius); badeline.Sprite.Scale.X = Math.Sign(badeline.X - player.X); } }
private int SummitLaunchReset(On.Celeste.Player.orig_SummitLaunchUpdate orig, Player self) { var level = Engine.Scene as Level; if (this.InRandomizer && self.Y < level.Bounds.Y - 8) { // teleport to spawn point self.Position = level.Session.RespawnPoint.Value; // reset camera var tmp = level.CameraLockMode; level.CameraLockMode = Level.CameraLockModes.None; level.Camera.Position = level.GetFullCameraTargetAt(self, self.Position); level.CameraLockMode = tmp; level.CameraUpwardMaxY = level.Camera.Y + 180f; // remove effects AscendManager mgr = null; Entity fader = null; HeightDisplay h = null; BadelineDummy b = null; foreach (var ent in Engine.Scene.Entities) { if (ent is AscendManager manager) { mgr = manager; } if (ent.GetType().Name == "Fader") { fader = ent; } if (ent is HeightDisplay heightDisplay) { h = heightDisplay; } if (ent is BadelineDummy bd) { b = bd; } } if (mgr != null) { level.Remove(mgr); } if (fader != null) { level.Remove(fader); } if (h != null) { level.Remove(h); } if (b != null) { level.Remove(b); } level.NextTransitionDuration = 0.65f; // return to normal return(Player.StNormal); } else { return(orig(self)); } }
public static Entity CreateEntityCopy(Entity savedEntity, string tag = "EntitiesSavedButNotLoaded") { Entity loadedEntity = null; Type savedType = savedEntity.GetType(); if (savedEntity.GetEntityData() != null) { // 一般 Entity 都是 EntityData + Vector2 loadedEntity = (savedType.GetConstructor(new[] { typeof(EntityData), typeof(Vector2) }) ?.Invoke(new object[] { savedEntity.GetEntityData(), Vector2.Zero })) as Entity; if (loadedEntity == null) { // 部分例如草莓则是 EntityData + Vector2 + EntityID loadedEntity = savedType .GetConstructor(new[] { typeof(EntityData), typeof(Vector2), typeof(EntityID) }) ?.Invoke(new object[] { savedEntity.GetEntityData(), Vector2.Zero, savedEntity.GetEntityId2().EntityId }) as Entity; } if (loadedEntity == null && savedType.IsType <CrystalStaticSpinner>()) { loadedEntity = new CrystalStaticSpinner(savedEntity.GetEntityData(), Vector2.Zero, (CrystalColor)savedEntity.GetField(typeof(CrystalStaticSpinner), "color")); } if (loadedEntity == null && savedType.IsType <TriggerSpikes>()) { loadedEntity = new TriggerSpikes(savedEntity.GetEntityData(), Vector2.Zero, (TriggerSpikes.Directions)savedEntity.GetField(typeof(TriggerSpikes), "direction")); } if (loadedEntity == null && savedType.IsType <Spikes>()) { loadedEntity = new Spikes(savedEntity.GetEntityData(), Vector2.Zero, ((Spikes)savedEntity).Direction); } if (loadedEntity == null && savedType.IsType <TriggerSpikes>()) { loadedEntity = new Spring(savedEntity.GetEntityData(), Vector2.Zero, ((Spring)savedEntity).Orientation); } if (loadedEntity != null) { loadedEntity.Position = savedEntity.Position; loadedEntity.CopyEntityData(savedEntity); loadedEntity.CopyEntityId2(savedEntity); return(loadedEntity); } } // TODO 如果是他们的子类该怎么办…… if (savedType.IsType <BadelineDummy>()) { loadedEntity = new BadelineDummy(savedEntity.GetStartPosition()); } else if (savedType.IsType <AngryOshiro>()) { loadedEntity = new AngryOshiro(savedEntity.GetStartPosition(), (bool)savedEntity.GetField("fromCutscene")); } else if (savedType.IsType <Snowball>()) { loadedEntity = new Snowball(); } else if (savedType.IsType <SlashFx>() && savedEntity is SlashFx slashFx) { loadedEntity = slashFx.Clone(); } else if (savedType.IsType <SpeedRing>() && savedEntity is SpeedRing speedRing) { loadedEntity = speedRing.Clone(); } else if (savedType.IsType <FinalBossShot>() && savedEntity is FinalBossShot finalBossShot) { loadedEntity = finalBossShot.Clone(); } else if (savedType.IsType <FinalBossBeam>() && savedEntity is FinalBossBeam finalBossBeam) { loadedEntity = finalBossBeam.Clone(); } else if (savedType.IsType <BirdTutorialGui>() && savedEntity is BirdTutorialGui birdTutorialGui) { loadedEntity = birdTutorialGui.Clone(); } else if (savedType.IsType <SoundEmitter>() && savedEntity is SoundEmitter soundEmitter) { loadedEntity = SoundEmitter.Play(soundEmitter.Source.EventName, new Entity(soundEmitter.Position)); if (SoundSourceAction.PlayingSoundSources.FirstOrDefault(source => source.EventName == soundEmitter.Source.EventName) == null) { (loadedEntity as SoundEmitter)?.Source.TryCopyObject(soundEmitter.Source); } else { (loadedEntity as SoundEmitter)?.Source.Stop(); } } else if (savedType.IsType <Debris>() && savedEntity is Debris debris) { loadedEntity = Engine.Pooler.Create <Debris>() .Init(debris.GetStartPosition(), (char)debris.GetField("tileset"), (bool)debris.GetField("playSound")); } else if (savedType == typeof(TalkComponent.TalkComponentUI)) { // ignore } else if (savedType.IsType <Entity>()) { loadedEntity = new Entity(savedEntity.GetStartPosition()); } else { if (savedEntity.GetType().FullName == "Celeste.MoveBlock+Debris") { loadedEntity = (savedEntity as Actor).CloneMoveBlockDebris(); } else if (savedEntity.ForceCreateInstance(tag) is Entity newEntity) { loadedEntity = newEntity; } } if (loadedEntity == null) { return(null); } loadedEntity.Position = savedEntity.Position; loadedEntity.CopyEntityId2(savedEntity); loadedEntity.CopyStartPosition(savedEntity); return(loadedEntity); }
public override void Update() { base.Update(); if (player.Dead) { RemoveSelf(); } ResetPosition(); if (respawnTimer > 0.0 && badelines.Count < maxQuantity) { respawnTimer -= Engine.DeltaTime; if (respawnTimer <= 0.0) { respawnTimer = respwanTime; AddBadeline(); } } for (var i = badelines.Count - 1; i >= 0; i--) { BadelineDummy badeline = badelines[i]; foreach (TouchSwitch touchSwitch in Scene.Tracker.GetEntities <TouchSwitch>()) { if (badeline.CollideCheck(touchSwitch) && !touchSwitch.Switch.Activated) { touchSwitch.TurnOn(); RemoveBadeline(badeline); break; } } foreach (Seeker seeker in Scene.Tracker.GetEntities <Seeker>()) { if (badeline.CollideCheck(seeker)) { SeekerGotBounced.Invoke(seeker, new object[] { this }); RemoveBadeline(badeline); break; } } foreach (SeekerBossShot seekerBossShot in Scene.Tracker.GetEntities <SeekerBossShot>()) { if (badeline.CollideCheck(seekerBossShot)) { seekerBossShot.RemoveSelf(); RemoveBadeline(badeline); break; } } foreach (FinalBossShot finalBossShot in Scene.Tracker.GetEntities <FinalBossShot>()) { if (badeline.CollideCheck(finalBossShot)) { finalBossShot.RemoveSelf(); RemoveBadeline(badeline); break; } } foreach (SeekerBoss seekerBoss in Scene.Tracker.GetEntities <SeekerBoss>()) { if (badeline.CollideCheck(seekerBoss)) { RemoveBadeline(badeline); break; } } if (!player.Dead) { foreach (Key key in Scene.Entities.FindAll <Key>()) { if (badeline.CollideCheck(key)) { KeyOnPlayer.Invoke(key, new object[] { player }); RemoveBadeline(badeline); break; } } foreach (Strawberry berry in Scene.Entities.FindAll <Strawberry>()) { if (berry.Follower.Leader == null && false == (bool)BerryCollected.GetValue(berry) && badeline.CollideCheck(berry)) { if (ReturnBerryType.Value == berry.GetType() && ReturnBerryOnPlayer.Value != null) { ReturnBerryOnPlayer.Value.Invoke(berry, new object[] { player }); } else { berry.OnPlayer(player); } RemoveBadeline(badeline); break; } } foreach (StrawberrySeed seed in Scene.Tracker.GetEntities <StrawberrySeed>()) { if (badeline.CollideCheck(seed)) { BerrySeedOnPlayer.Invoke(seed, new object[] { player }); RemoveBadeline(badeline); break; } } } } }
private IEnumerator BoostRoutine(Player player) { holding = player; travelling = true; ++nodeIndex; sprite.Visible = false; sprite.Position = Vector2.Zero; Collidable = false; var finalBoost = nodeIndex >= nodes.Length; Level level = SceneAs <Level>(); Stopwatch sw = new Stopwatch(); sw.Start(); if (!finalBoost) { Audio.Play("event:/char/badeline/booster_begin", Position); } else { Audio.Play("event:/char/badeline/booster_final", Position); } if (player.Holding != null) { player.Drop(); } player.StateMachine.State = 11; player.DummyAutoAnimate = false; player.DummyGravity = false; if (player.Inventory.Dashes > 1) { player.Dashes = 1; } else { player.RefillDash(); } player.RefillStamina(); player.Speed = Vector2.Zero; var side = Math.Sign(player.X - X); if (side == 0) { side = -1; } BadelineDummy badeline = new BadelineDummy(Position); Scene.Add(badeline); if (side == -1) { player.Facing = Facings.Right; } else { player.Facing = Facings.Left; } badeline.Sprite.Scale.X = side; Vector2 playerFrom = player.Position; Vector2 playerTo = Position + new Vector2(side * 4, -3f); Vector2 badelineFrom = badeline.Position; Vector2 badelineTo = Position + new Vector2(-side * 4, 3f); for (var p = 0.0f; (double)p < 1.0; p += Engine.DeltaTime / 0.2f) { Vector2 target = Vector2.Lerp(playerFrom, playerTo, p); if (player.Scene != null) { player.MoveToX(target.X); } if (player.Scene != null) { player.MoveToY(target.Y); } badeline.Position = Vector2.Lerp(badelineFrom, badelineTo, p); yield return(null); } if (finalBoost) { Vector2 center = new Vector2(Calc.Clamp(player.X - level.Camera.X, 120f, 200f), Calc.Clamp(player.Y - level.Camera.Y, 60f, 120f)); Add(new Coroutine(level.ZoomTo(center, 1.5f, 0.18f))); Engine.TimeRate = 0.5f; } else { Audio.Play("event:/char/badeline/booster_throw", Position); } badeline.Sprite.Play("boost"); yield return(0.1f); if (!player.Dead) { player.MoveV(5f); } yield return(0.1f); Add(Alarm.Create(Alarm.AlarmMode.Oneshot, () => { if (player.Dashes < player.Inventory.Dashes) { ++player.Dashes; } Scene.Remove(badeline); (Scene as Level)?.Displacement.AddBurst(badeline.Position, 0.25f, 8f, 32f, 0.5f); }, 0.15f, true)); (Scene as Level)?.Shake(); holding = null; if (!finalBoost) { player.BadelineBoostLaunch(CenterX); Vector2 from = Position; Vector2 to = nodes[nodeIndex]; var time = Vector2.Distance(from, to) / MoveSpeed; time = Math.Min(3f, time); stretch.Visible = true; stretch.Rotation = (to - from).Angle(); Tween tween = Tween.Create(Tween.TweenMode.Oneshot, Ease.SineInOut, time, true); tween.OnUpdate = t => { Position = Vector2.Lerp(from, to, t.Eased); stretch.Scale.X = (float)(1.0 + Calc.YoYo(t.Eased) * 2.0); stretch.Scale.Y = (float)(1.0 - Calc.YoYo(t.Eased) * 0.75); if (t.Eased >= 0.899999976158142 || !Scene.OnInterval(0.03f)) { return; } TrailManager.Add(this, Player.TwoDashesHairColor, 0.5f, false); level.ParticlesFG.Emit(BadelineBoost.P_Move, 1, Center, Vector2.One * 4f); }; tween.OnComplete = t => { if (level != null && X >= (double)level.Bounds.Right) { RemoveSelf(); } else { travelling = false; stretch.Visible = false; sprite.Visible = true; Collidable = true; Audio.Play("event:/char/badeline/booster_reappear", Position); } }; Add(tween); relocateSfx.Play("event:/char/badeline/booster_relocate"); Input.Rumble(RumbleStrength.Strong, RumbleLength.Medium); level.DirectionalShake(-Vector2.UnitY); level.Displacement.AddBurst(Center, 0.4f, 8f, 32f, 0.5f); } else { Console.WriteLine("TIME: " + sw.ElapsedMilliseconds); Engine.FreezeTimer = 0.1f; yield return(null); Input.Rumble(RumbleStrength.Strong, RumbleLength.Long); level.Flash(Color.White * 0.5f, true); level.DirectionalShake(Vector2.UnitY, 0.6f); level.Displacement.AddBurst(Center, 0.6f, 8f, 64f, 0.5f); level.ResetZoom(); player.StateMachine.State = 18; Engine.TimeRate = 1f; Finish(); } }