Пример #1
0
        private static void LevelOnRender(On.Celeste.Level.orig_Render orig, Level self)
        {
            orig(self);

            if (!ModSettings.Enabled || ModSettings.InfoHud == InfoPositions.Off)
            {
                return;
            }

            int viewWidth  = Engine.ViewWidth;
            int viewHeight = Engine.ViewHeight;

            float pixelScale = viewWidth / 320f;
            float margin     = 2 * pixelScale;
            float padding    = 2 * pixelScale;
            float fontSize   = 0.15f * pixelScale;
            float alpha      = 1f;

            StringBuilder     stringBuilder = new StringBuilder();
            InputController   controller    = Manager.Controller;
            List <InputFrame> inputs        = controller.Inputs;

            if (Manager.Running && controller.CurrentFrame >= 0 && controller.CurrentFrame < inputs.Count)
            {
                InputFrame previous = null;
                InputFrame next     = null;

                InputFrame current = controller.Current;
                if (controller.CurrentFrame >= 1 && current != controller.Previous)
                {
                    current = controller.Previous;
                }

                int currentIndex = inputs.IndexOf(current);
                if (currentIndex >= 1)
                {
                    previous = inputs[currentIndex - 1];
                }

                currentIndex = inputs.LastIndexOf(current);
                if (currentIndex < inputs.Count - 1)
                {
                    next = inputs[currentIndex + 1];
                }

                int maxLine     = Math.Max(current.Line, Math.Max(previous?.Line ?? 0, next?.Line ?? 0)) + 1;
                int linePadLeft = maxLine.ToString().Length;

                int maxFrames     = Math.Max(current.Frames, Math.Max(previous?.Frames ?? 0, next?.Frames ?? 0));
                int framesPadLeft = maxFrames.ToString().Length;

                if (previous != null)
                {
                    stringBuilder.Append(
                        $"{(previous.Line + 1).ToString().PadLeft(linePadLeft)}: {string.Empty.PadLeft(framesPadLeft - previous.Frames.ToString().Length)}{previous}\n");
                }

                string currentStr =
                    $"{(current.Line + 1).ToString().PadLeft(linePadLeft)}: {string.Empty.PadLeft(framesPadLeft - current.Frames.ToString().Length)}{current}";
                int maxWidth = currentStr.ToString().Length + controller.StudioFrameCount.ToString().Length + 1;
                maxWidth = Manager.PlayerStatus.Split('\n').Select(s => s.Length).Concat(new[] { maxWidth }).Max();
                stringBuilder.Append(
                    $"{currentStr.PadRight(maxWidth - controller.StudioFrameCount.ToString().Length - 1)}{controller.StudioFrameCount}\n");
                if (next != null)
                {
                    stringBuilder.Append(
                        $"{(next.Line + 1).ToString().PadLeft(linePadLeft)}: {string.Empty.PadLeft(framesPadLeft - next.Frames.ToString().Length)}{next}\n");
                }

                stringBuilder.AppendLine();
            }

            stringBuilder.Append(Manager.PlayerStatus);

            string text = stringBuilder.ToString();

            if (string.IsNullOrEmpty(text))
            {
                return;
            }

            Vector2 size = JetBrainsMono.Measure(text) * fontSize;

            float x;
            float y;

            switch (ModSettings.InfoHud)
            {
            case InfoPositions.TopLeft:
                x = margin;
                y = margin;
                if (Settings.Instance.SpeedrunClock == SpeedrunType.Chapter)
                {
                    y += 16 * pixelScale;
                }
                else if (Settings.Instance.SpeedrunClock == SpeedrunType.File)
                {
                    y += 20 * pixelScale;
                }

                break;

            case InfoPositions.TopRight:
                x = viewWidth - size.X - margin - padding * 2;
                y = margin;
                break;

            case InfoPositions.BottomLeft:
                x = margin;
                y = viewHeight - size.Y - margin - padding * 2;
                break;

            case InfoPositions.BottomRight:
                x = viewWidth - size.X - margin - padding * 2;
                y = viewHeight - size.Y - margin - padding * 2;
                break;

            case InfoPositions.Off:
                throw new ArgumentException();

            default:
                throw new ArgumentOutOfRangeException();
            }

            Rectangle bgRect = new Rectangle((int)x, (int)y, (int)(size.X + padding * 2), (int)(size.Y + padding * 2));

            if (self.Entities.FindFirst <Player>() is Player player)
            {
                Vector2   playerPosition = self.Camera.CameraToScreen(player.TopLeft) * pixelScale;
                Rectangle playerRect     = new Rectangle((int)playerPosition.X, (int)playerPosition.Y, (int)(8 * pixelScale), (int)(11 * pixelScale));
                Rectangle mirrorBgRect   = bgRect;
                if (SaveData.Instance?.Assists.MirrorMode == true)
                {
                    mirrorBgRect.X = (int)Math.Abs(x - viewWidth + size.X + padding * 2);
                }

                if (self.Paused || playerRect.Intersects(mirrorBgRect))
                {
                    alpha = 0.5f;
                }
            }

            Draw.SpriteBatch.Begin();

            Draw.Rect(bgRect, Color.Black * 0.8f * alpha);

            Vector2 textPosition = new Vector2(x + padding, y + padding);
            Vector2 scale        = new Vector2(fontSize);

            JetBrainsMono.Draw(text, textPosition, Vector2.Zero, scale, Color.White * alpha);

            Draw.SpriteBatch.End();
        }
Пример #2
0
 private static void FontsOnPrepare(On.Celeste.Fonts.orig_Prepare orig)
 {
     orig();
     JetBrainsMono.LoadFont();
 }