예제 #1
0
        private void TrySpringInteractions()
        {
            if (!interactWithEntities)
            {
                return;
            }

            foreach (Entity entity in FrostModule.CollideAll(this))
            {
                SkateboardInteraction interaction;
                if (entity != null && (interaction = entity.Get <SkateboardInteraction>()) != null)
                {
                    interaction.DoInteraction(entity, this);
                }
                else if (entity is Spring spring)
                {
                    switch (spring.Orientation)
                    {
                    case Spring.Orientations.Floor:
                        speedY = -145f;
                        break;

                    case Spring.Orientations.WallLeft:
                        speedX = Math.Abs(targetSpeedX) * 2f;
                        break;

                    case Spring.Orientations.WallRight:
                        speedX = Math.Abs(targetSpeedX) * -2f;
                        break;
                    }
                    hasMoved = true;
                    CustomSpring.Spring_BounceAnimate.Invoke(spring, null);
                }
            }
        }
예제 #2
0
        public EntityMover(EntityData data, Vector2 offset) : base(data.Position + offset)
        {
            Collider = new Hitbox(data.Width, data.Height);

            Types       = FrostModule.GetTypes(data.Attr("types", "")).ToList();
            isBlacklist = data.Bool("blacklist");

            pauseTime    = data.Float("pauseTimeLength", 0f);
            pauseTimer   = data.Float("startPauseTimeLength", 0f);
            relativeMode = data.Bool("relativeMovementMode", false);
            onEndSFX     = data.Attr("onEndSFX", "");
            if (isBlacklist)
            {
                // Some basic types we don't want to move D:
                foreach (Type type in new List <Type>()
                {
                    typeof(Player), typeof(SolidTiles), typeof(BackgroundTiles), typeof(SpeedrunTimerDisplay), typeof(StrawberriesCounter)
                })
                {
                    Types.Add(type);
                }
            }

            endNode     = data.FirstNodeNullable(offset).GetValueOrDefault();
            easer       = EaseHelper.GetEase(data.Attr("easing", "CubeInOut"));
            duration    = data.Float("moveDuration", 1f);
            mustCollide = data.Bool("mustCollide", true);
            distance    = new Vector2(endNode.X - Position.X, endNode.Y - Position.Y);
        }
예제 #3
0
 public static void LoadHooks()
 {
     IL.Celeste.Player.UpdateHair += modFeatherState;
     IL.Celeste.Player.OnCollideH += modFeatherState;
     IL.Celeste.Player.OnCollideV += modFeatherState;
     IL.Celeste.Player.Render     += modFeatherState;
     FrostModule.RegisterILHook(new ILHook(typeof(Player).GetMethod("orig_Update", BindingFlags.Instance | BindingFlags.Public), modFeatherState));
 }
        public RainbowTilesetController(EntityData data, Vector2 offset) : base(data.Position + offset)
        {
            BG         = data.Bool("bg", false);
            TilesetIDs = FrostModule.GetCharArrayFromCommaSeparatedList(data.Attr("tilesets"));

            TilesetTexturePaths = new string[TilesetIDs.Length];
            for (int i = 0; i < TilesetIDs.Length; i++)
            {
                var autotiler = BG ? GFX.BGAutotiler : GFX.FGAutotiler;
                TilesetTexturePaths[i] = autotiler.GenerateMap(new VirtualMap <char>(new char[, ] {
                    { TilesetIDs[i] }
                }), true).TileGrid.Tiles[0, 0].Parent.AtlasPath;
            }
        }
예제 #5
0
        public static IEnumerator CustomFeatherCoroutine()
        {
            Player           player  = FrostModule.StateGetPlayer();
            DynData <Player> data    = new DynData <Player>(player);
            CustomFeather    feather = (CustomFeather)data["fh.customFeather"];

            while (player.Sprite.CurrentAnimationID == "startStarFly")
            {
                yield return(null);
            }
            while (player.Speed != Vector2.Zero)
            {
                yield return(null);
            }
            yield return(0.1f);

            player.Sprite.Color                 = feather.FlyColor;
            player.Sprite.HairCount             = 7;
            player.Hair.DrawPlayerSpriteOutline = true;
            player.SceneAs <Level>().Displacement.AddBurst(player.Center, 0.25f, 8f, 32f, 1f, null, null);
            data["starFlyTransforming"] = false;
            data["starFlyTimer"]        = feather.FlyTime;
            player.RefillDash();
            player.RefillStamina();
            Vector2 dir  = Input.Aim.Value;
            bool    flag = dir == Vector2.Zero;

            if (flag)
            {
                dir = Vector2.UnitX * (float)player.Facing;
            }
            player.Speed           = dir * 250f;
            data["starFlyLastDir"] = dir;
            player.SceneAs <Level>().Particles.Emit(feather.P_Boost, 12, player.Center, Vector2.One * 4f, feather.FlyColor, (-dir).Angle());
            Input.Rumble(RumbleStrength.Strong, RumbleLength.Medium);
            player.SceneAs <Level>().DirectionalShake((Vector2)data["starFlyLastDir"], 0.3f);
            while ((float)data["starFlyTimer"] > 0.5f)
            {
                yield return(null);
            }
            ((SoundSource)data["starFlyWarningSfx"]).Play("event:/game/06_reflection/feather_state_warning", null, 0f);
            yield break;
        }
예제 #6
0
        public static void DreamDashEnd()
        {
            Player           player = FrostModule.StateGetPlayer();
            DynData <Player> data   = new DynData <Player>(player);

            player.Depth = 0;
            if (!data.Get <bool>("dreamJump"))
            {
                player.AutoJump      = true;
                player.AutoJumpTimer = 0f;
            }
            bool flag2 = !player.Inventory.NoRefills;

            if (flag2)
            {
                player.RefillDash();
            }
            player.RefillStamina();
            player.TreatNaive = false;
            CustomDreamBlock dreamBlock = data.Get <CustomDreamBlock>("customDreamBlock");

            if (dreamBlock != null)
            {
                bool flag4 = player.DashDir.X != 0f;
                if (flag4)
                {
                    data.Set("jumpGraceTimer", 0.1f);
                    data.Set("dreamJump", true);
                }
                else
                {
                    data.Set("jumpGraceTimer", 0f);
                }
                dreamBlock.OnPlayerExit(player);
                data.Set <CustomDreamBlock>("customDreamBlock", null);
            }
            player.Stop(data.Get <SoundSource>("dreamSfxLoop"));
            player.Play("event:/char/madeline/dreamblock_exit", null, 0f);
            Input.Rumble(RumbleStrength.Medium, RumbleLength.Short);
        }
예제 #7
0
        public static void CustomFeatherEnd()
        {
            Player           player  = FrostModule.StateGetPlayer();
            DynData <Player> data    = new DynData <Player>(player);
            CustomFeather    feather = (CustomFeather)data["fh.customFeather"];

            player.Play("event:/game/06_reflection/feather_state_end", null, 0f);
            ((SoundSource)data["starFlyWarningSfx"]).Stop(true);
            ((SoundSource)data["starFlyLoopSfx"]).Stop(true);
            player.Hair.DrawPlayerSpriteOutline = false;
            player.Sprite.Color = Color.White;
            player.SceneAs <Level>().Displacement.AddBurst(player.Center, 0.25f, 8f, 32f, 1f, null, null);
            ((BloomPoint)data["starFlyBloom"]).Visible = false;
            player.Sprite.HairCount = (int)data["startHairCount"];
            player_StarFlyReturnToNormalHitbox.Invoke(player, null);
            bool flag = player.StateMachine.State != 2;

            if (flag)
            {
                player.SceneAs <Level>().Particles.Emit(feather.P_Boost, 12, player.Center, Vector2.One * 4f, (-player.Speed).Angle());
            }
        }
예제 #8
0
        public static void DreamDashBegin()
        {
            Player           player       = FrostModule.StateGetPlayer();
            DynData <Player> data         = new DynData <Player>(player);
            SoundSource      dreamSfxLoop = data.Get <SoundSource>("dreamSfxLoop");
            bool             flag         = dreamSfxLoop == null;

            if (flag)
            {
                dreamSfxLoop = new SoundSource();
                player.Add(dreamSfxLoop);
                data.Set("dreamSfxLoop", dreamSfxLoop);
            }
            player.Speed      = player.DashDir * 240f;
            player.TreatNaive = true;
            player.Depth      = -12000;
            data.Set("dreamDashCanEndTimer", 0.1f);
            player.Stamina = 110f;
            data.Set("dreamJump", false);
            player.Play("event:/char/madeline/dreamblock_enter", null, 0f);
            player.Loop(dreamSfxLoop, "event:/char/madeline/dreamblock_travel");
        }
예제 #9
0
        public static void CustomFeatherBegin()
        {
            Player           player  = FrostModule.StateGetPlayer();
            DynData <Player> data    = new DynData <Player>(player);
            CustomFeather    feather = (CustomFeather)data["fh.customFeather"];

            player.Sprite.Play("startStarFly", false, false);
            data["starFlyTransforming"] = true;
            data["starFlyTimer"]        = feather.FlyTime;
            data["starFlySpeedLerp"]    = 0f;
            data["jumpGraceTimer"]      = 0f;
            BloomPoint starFlyBloom = (BloomPoint)data["starFlyBloom"];

            if (starFlyBloom == null)
            {
                player.Add(starFlyBloom = new BloomPoint(new Vector2(0f, -6f), 0f, 16f));
            }
            starFlyBloom.Visible = true;
            starFlyBloom.Alpha   = 0f;
            data["starFlyBloom"] = starFlyBloom;
            player.Collider      = (Hitbox)data["starFlyHitbox"];
            data["hurtbox"]      = data["starFlyHurtbox"];
            SoundSource starFlyLoopSfx    = (SoundSource)data["starFlyLoopSfx"];
            SoundSource starFlyWarningSfx = (SoundSource)data["starFlyWarningSfx"];

            if (starFlyLoopSfx == null)
            {
                player.Add(starFlyLoopSfx             = new SoundSource());
                starFlyLoopSfx.DisposeOnTransition    = false;
                player.Add(starFlyWarningSfx          = new SoundSource());
                starFlyWarningSfx.DisposeOnTransition = false;
            }
            starFlyLoopSfx.Play("event:/game/06_reflection/feather_state_loop", "feather_speed", 1f);
            starFlyWarningSfx.Stop(true);
            data["starFlyLoopSfx"]    = starFlyLoopSfx;
            data["starFlyWarningSfx"] = starFlyWarningSfx;
        }
예제 #10
0
        public CustomSpring(EntityData data, Vector2 offset, Orientations orientation) : base(data.Position + offset, orientation, data.Bool("playerCanUse", true))
        {
            bool playerCanUse = data.Bool("playerCanUse", true);

            dir = data.Attr("directory", "objects/spring/");

            speedMult = FrostModule.StringToVec2(data.Attr("speedMult", "1"));
            Vector2 position = data.Position + offset;

            DisabledColor     = Color.White;
            Orientation       = orientation;
            this.playerCanUse = playerCanUse;
            Remove(Get <PlayerCollider>());
            Add(new PlayerCollider(new Action <Player>(OnCollide), null, null));
            Remove(Get <HoldableCollider>());
            Add(new HoldableCollider(new Action <Holdable>(OnHoldable), null));
            Remove(Get <PufferCollider>());
            PufferCollider pufferCollider = new PufferCollider(new Action <Puffer>(OnPuffer), null);

            Add(pufferCollider);
            DynData <Spring> dyndata = new DynData <Spring>(this);
            Sprite           spr     = dyndata.Get <Sprite>("sprite");

            Remove(spr);
            Sprite sprite;

            Add(sprite = new Sprite(GFX.Game, dir));
            sprite.Add("idle", "", 0f, new int[1]);
            sprite.Add("bounce", "", 0.07f, "idle", new int[]
            {
                0, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 3, 4, 5
            });
            sprite.Add("disabled", "white", 0.07f);
            sprite.Play("idle", false, false);
            sprite.Origin.X = sprite.Width / 2f;
            sprite.Origin.Y = sprite.Height;
            Depth           = -8501;

            Add(Wiggler.Create(1f, 4f, delegate(float v)
            {
                sprite.Scale.Y = 1f + v * 0.2f;
            }, false, false));

            switch (orientation)
            {
            case Orientations.Floor:
                Collider = new Hitbox(16f, 6f, -8f, -6f);
                pufferCollider.Collider = new Hitbox(16f, 10f, -8f, -10f);
                break;

            case Orientations.WallLeft:
                Collider = new Hitbox(6f, 16f, 0f, -8f);
                pufferCollider.Collider = new Hitbox(12f, 16f, 0f, -8f);
                sprite.Rotation         = 1.57079637f;
                break;

            case Orientations.WallRight:
                Collider = new Hitbox(6f, 16f, -6f, -8f);
                pufferCollider.Collider = new Hitbox(12f, 16f, -12f, -8f);
                sprite.Rotation         = -1.57079637f;
                break;

            default:
                throw new Exception("Orientation not supported!");
            }

            dyndata.Set <Sprite>("sprite", sprite);
            OneUse = data.Bool("oneUse", false);
            if (OneUse)
            {
                Add(new Coroutine(OneUseParticleRoutine()));
            }
        }
예제 #11
0
        public static int StarFlyUpdate()
        {
            Player           player     = FrostModule.StateGetPlayer();
            Level            level      = player.SceneAs <Level>();
            DynData <Player> data       = new DynData <Player>(player);
            BloomPoint       bloomPoint = (BloomPoint)data["starFlyBloom"];
            CustomFeather    feather    = (CustomFeather)data["fh.customFeather"];
            // 2f -> StarFlyTime
            float StarFlyTime = feather.FlyTime;

            bloomPoint.Alpha     = Calc.Approach(bloomPoint.Alpha, 0.7f, Engine.DeltaTime * StarFlyTime);
            data["starFlyBloom"] = bloomPoint;
            Input.Rumble(RumbleStrength.Climb, RumbleLength.Short);
            if ((bool)data["starFlyTransforming"])
            {
                player.Speed = Calc.Approach(player.Speed, Vector2.Zero, 1000f * Engine.DeltaTime);
            }
            else
            {
                Vector2 aimValue  = Input.Aim.Value;
                bool    notAiming = false;
                bool    flag3     = aimValue == Vector2.Zero;
                if (flag3)
                {
                    notAiming = true;
                    aimValue  = (Vector2)data["starFlyLastDir"];
                }
                Vector2 lastSpeed = player.Speed.SafeNormalize(Vector2.Zero);
                bool    flag4     = lastSpeed == Vector2.Zero;
                if (flag4)
                {
                    lastSpeed = aimValue;
                }
                else
                {
                    lastSpeed = lastSpeed.RotateTowards(aimValue.Angle(), 5.58505344f * Engine.DeltaTime);
                }
                data["starFlyLastDir"] = lastSpeed;
                float target;
                if (notAiming)
                {
                    data["starFlySpeedLerp"] = 0f;
                    target = feather.NeutralSpeed; // was 91f
                }
                else
                {
                    bool flag6 = lastSpeed != Vector2.Zero && Vector2.Dot(lastSpeed, aimValue) >= 0.45f;
                    if (flag6)
                    {
                        data["starFlySpeedLerp"] = Calc.Approach((float)data["starFlySpeedLerp"], 1f, Engine.DeltaTime / 1f);
                        target = MathHelper.Lerp(feather.LowSpeed, feather.MaxSpeed, (float)data["starFlySpeedLerp"]);
                    }
                    else
                    {
                        data["starFlySpeedLerp"] = 0f;
                        target = 140f;
                    }
                }
                SoundSource ss = (SoundSource)data["starFlyLoopSfx"];
                ss.Param("feather_speed", notAiming ? 0 : 1);
                data["starFlyLoopSfx"] = ss;

                float num = player.Speed.Length();
                num          = Calc.Approach(num, target, 1000f * Engine.DeltaTime);
                player.Speed = lastSpeed * num;
                bool flag7 = level.OnInterval(0.02f);
                if (flag7)
                {
                    level.Particles.Emit(feather.P_Flying, 1, player.Center, Vector2.One * 2f, feather.FlyColor, (-player.Speed).Angle());
                }
                bool pressed = Input.Jump.Pressed;
                if (pressed)
                {
                    bool flag8 = player.OnGround(3);
                    if (flag8)
                    {
                        player.Jump(true, true);
                        return(0);
                    }
                    bool flag9 = (bool)player_WallJumpCheck.Invoke(player, new object[] { -1 });
                    if (flag9)
                    {
                        player_WallJump.Invoke(player, new object[] { 1 });
                        return(0);
                    }
                    bool flag10 = (bool)player_WallJumpCheck.Invoke(player, new object[] { 1 });
                    if (flag10)
                    {
                        player_WallJump.Invoke(player, new object[] { -1 });
                        return(0);
                    }
                }
                bool check = Input.Grab.Check;
                if (check)
                {
                    bool flag11 = false;
                    int  dir    = 0;
                    bool flag12 = Input.MoveX.Value != -1 && player.ClimbCheck(1, 0);
                    if (flag12)
                    {
                        player.Facing = Facings.Right;
                        dir           = 1;
                        flag11        = true;
                    }
                    else
                    {
                        bool flag13 = Input.MoveX.Value != 1 && player.ClimbCheck(-1, 0);
                        if (flag13)
                        {
                            player.Facing = Facings.Left;
                            dir           = -1;
                            flag11        = true;
                        }
                    }
                    bool flag14 = flag11;
                    if (flag14)
                    {
                        bool noGrabbing = Celeste.SaveData.Instance.Assists.NoGrabbing;
                        if (noGrabbing)
                        {
                            player.Speed = Vector2.Zero;
                            player.ClimbTrigger(dir);
                            return(0);
                        }
                        return(1);
                    }
                }
                bool canDash = player.CanDash;
                if (canDash)
                {
                    return(player.StartDash());
                }
                float starFlyTimer = (float)data["starFlyTimer"];
                starFlyTimer        -= Engine.DeltaTime;
                data["starFlyTimer"] = starFlyTimer;
                bool flag15 = starFlyTimer <= 0f;
                if (flag15)
                {
                    bool flag16 = Input.MoveY.Value == -1;
                    if (flag16)
                    {
                        player.Speed.Y = -100f;
                    }
                    bool flag17 = Input.MoveY.Value < 1;
                    if (flag17)
                    {
                        data["varJumpSpeed"] = player.Speed.Y;
                        player.AutoJump      = true;
                        player.AutoJumpTimer = 0f;
                        data["varJumpTimer"] = 0.2f;
                    }
                    bool flag18 = player.Speed.Y > 0f;
                    if (flag18)
                    {
                        player.Speed.Y = 0f;
                    }
                    bool flag19 = Math.Abs(player.Speed.X) > 140f;
                    if (flag19)
                    {
                        player.Speed.X = 140f * Math.Sign(player.Speed.X);
                    }
                    Input.Rumble(RumbleStrength.Medium, RumbleLength.Medium);
                    return(0);
                }
                bool flag20 = starFlyTimer < 0.5f && player.Scene.OnInterval(0.05f);
                if (flag20)
                {
                    Color starFlyColor = feather.FlyColor;
                    if (player.Sprite.Color == starFlyColor)
                    {
                        player.Sprite.Color = Player.NormalHairColor;
                    }
                    else
                    {
                        player.Sprite.Color = starFlyColor;
                    }
                }
            }
            return(CustomFeatherState);
        }
예제 #12
0
        // CUSTOM DREAM DASH STATE
        public static int DreamDashUpdate()
        {
            Player           player = FrostModule.StateGetPlayer();
            DynData <Player> data   = new DynData <Player>(player);

            Input.Rumble(RumbleStrength.Light, RumbleLength.Medium);
            Vector2 position = player.Position;

            player.Speed = player.DashDir * data.Get <CustomDreamBlock>("customDreamBlock").DashSpeed;
            player.NaiveMove(player.Speed * Engine.DeltaTime);
            float dreamDashCanEndTimer = data.Get <float>("dreamDashCanEndTimer");
            bool  flag = dreamDashCanEndTimer > 0f;

            if (flag)
            {
                data.Set <float>("dreamDashCanEndTimer", dreamDashCanEndTimer -= Engine.DeltaTime);
            }
            CustomDreamBlock dreamBlock = player.CollideFirst <CustomDreamBlock>();

            if (dreamBlock == null)
            {
                if (DreamDashedIntoSolid(player))
                {
                    bool invincible = SaveData.Instance.Assists.Invincible;
                    if (invincible)
                    {
                        player.Position = position;
                        player.Speed   *= -1f;
                        player.Play("event:/game/general/assist_dreamblockbounce", null, 0f);
                    }
                    else
                    {
                        player.Die(Vector2.Zero, false, true);
                    }
                }
                else
                {
                    if (dreamDashCanEndTimer <= 0f)
                    {
                        Celeste.Celeste.Freeze(0.05f);
                        bool flag5 = Input.Jump.Pressed && player.DashDir.X != 0f;
                        if (flag5)
                        {
                            data.Set("dreamJump", true);
                            player.Jump(true, true);
                        }
                        else
                        {
                            if (player.DashDir.Y >= 0f || player.DashDir.X != 0f)
                            {
                                bool flag7 = player.DashDir.X > 0f && player.CollideCheck <Solid>(player.Position - Vector2.UnitX * 5f);
                                if (flag7)
                                {
                                    player.MoveHExact(-5, null, null);
                                }
                                else
                                {
                                    bool flag8 = player.DashDir.X < 0f && player.CollideCheck <Solid>(player.Position + Vector2.UnitX * 5f);
                                    if (flag8)
                                    {
                                        player.MoveHExact(5, null, null);
                                    }
                                }
                                bool flag9  = player.ClimbCheck(-1, 0);
                                bool flag10 = player.ClimbCheck(1, 0);
                                int  moveX  = data.Get <int>("moveX");
                                bool flag11 = Input.Grab.Check && ((moveX == 1 && flag10) || (moveX == -1 && flag9));
                                if (flag11)
                                {
                                    player.Facing = (Facings)moveX;
                                    bool noGrabbing = SaveData.Instance.Assists.NoGrabbing;
                                    if (!noGrabbing)
                                    {
                                        return(1);
                                    }
                                    player.ClimbTrigger(moveX);
                                    player.Speed.X = 0f;
                                }
                            }
                        }
                        return(0);
                    }
                }
            }
            else
            {
                // new property
                data.Set("customDreamBlock", dreamBlock);
                if (player.Scene.OnInterval(0.1f))
                {
                    CreateTrail(player);
                }
                if (player.SceneAs <Level>().OnInterval(0.04f))
                {
                    DisplacementRenderer.Burst burst = player.SceneAs <Level>().Displacement.AddBurst(player.Center, 0.3f, 0f, 40f, 1f, null, null);
                    burst.WorldClipCollider = dreamBlock.Collider;
                    burst.WorldClipPadding  = 2;
                }
                if (dreamBlock.AllowRedirects && player.CanDash)
                {
                    bool sameDir = Input.GetAimVector(Facings.Right) == player.DashDir;
                    bool flag4   = !sameDir || dreamBlock.AllowRedirectsInSameDir;
                    if (flag4)
                    {
                        player.DashDir = Input.GetAimVector(Facings.Right);
                        player.Speed   = player.DashDir * player.Speed.Length();
                        player.Dashes  = Math.Max(0, player.Dashes - 1);
                        Audio.Play("event:/char/madeline/dreamblock_enter");
                        if (sameDir)
                        {
                            player.Speed   *= dreamBlock.SameDirectionSpeedMultiplier;
                            player.DashDir *= Math.Sign(dreamBlock.SameDirectionSpeedMultiplier);
                        }
                        Input.Dash.ConsumeBuffer();
                    }
                }
            }
            return(FrostModule.CustomDreamDashState);
        }
예제 #13
0
 public FrostModule()
 {
     Instance = this;
 }