Exemplo n.º 1
0
        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);
        }
Exemplo n.º 6
0
        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);
        }
Exemplo n.º 7
0
        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);
            }
        }
Exemplo n.º 10
0
        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));
            }
        }
Exemplo n.º 11
0
        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();
            }
        }