using Barotrauma.Extensions; using Microsoft.Xna.Framework; using Microsoft.Xna.Framework.Graphics; using System; using System.Linq; namespace Barotrauma { class SlideshowPlayer : GUIComponent { private readonly SlideshowPrefab slideshowPrefab; private readonly LocalizedString pressAnyKeyText; private int state; private Color overlayColor, textColor; private float timer; private LocalizedString currentText; public bool LastTextShown => state >= slideshowPrefab.Slides.Length; public bool Finished => state > slideshowPrefab.Slides.Length; public SlideshowPlayer(RectTransform rectT, SlideshowPrefab prefab) : base(null, rectT) { slideshowPrefab = prefab; overlayColor = Color.Black; textColor = Color.Transparent; pressAnyKeyText = TextManager.Get("pressanykey"); RefreshText(); } public void Restart() { state = 0; } public void Finish() { state = slideshowPrefab.Slides.Length + 1; } protected override void Update(float deltaTime) { if (slideshowPrefab.Slides.IsEmpty) { return; } var slide = slideshowPrefab.Slides[Math.Min(state, slideshowPrefab.Slides.Length - 1)]; if (!Visible || (Finished && timer > slide.FadeOutDuration)) { return; } timer += deltaTime; if (state == 0) { overlayColor = Color.Lerp(Color.Black, Color.White, Math.Min((timer - slide.FadeInDelay) / slide.FadeInDuration, 1.0f)); } else { overlayColor = Color.Lerp(Color.Transparent, Color.White, Math.Min((timer - slide.FadeInDelay) / slide.FadeInDuration, 1.0f)); } if (timer > slide.TextFadeInDelay) { textColor = Color.Lerp(Color.Transparent, Color.White, Math.Min((timer - slide.TextFadeInDelay) / slide.TextFadeInDuration, 1.0f)); if (AnyKeyHit()) { if (timer > slide.TextFadeInDelay + slide.FadeInDuration) { overlayColor = textColor = Color.Transparent; timer = 0.0f; state++; RefreshText(); } else { timer = slide.TextFadeInDelay + slide.TextFadeInDuration; } } } else { textColor = Color.Transparent; if (AnyKeyHit()) { timer = slide.TextFadeInDelay + slide.TextFadeInDuration; } } if (state >= slideshowPrefab.Slides.Length) { overlayColor = Color.Lerp(Color.White, Color.Transparent, Math.Min(timer / slide.FadeOutDuration, 1.0f)); textColor = Color.Lerp(Color.White, Color.Transparent, Math.Min(timer / slide.FadeOutDuration, 1.0f)); if (timer >= slide.FadeOutDuration) { state++; RefreshText(); } } static bool AnyKeyHit() { return PlayerInput.GetKeyboardState.GetPressedKeys().Any(k => PlayerInput.KeyHit(k)) || PlayerInput.PrimaryMouseButtonClicked(); } } private void RefreshText() { if (slideshowPrefab.Slides.IsEmpty) { return; } var slide = slideshowPrefab.Slides[Math.Min(state, slideshowPrefab.Slides.Length - 1)]; currentText = slide.Text .Replace("[submarine]", Submarine.MainSub?.Info.Name ?? GameMain.GameSession?.SubmarineInfo?.Name ?? "Unknown") .Replace("[location]", Level.Loaded?.StartOutpost?.Info.Name ?? "Unknown"); } protected override void Draw(SpriteBatch spriteBatch) { if (slideshowPrefab.Slides.IsEmpty) { return; } var slide = slideshowPrefab.Slides[Math.Min(state, slideshowPrefab.Slides.Length - 1)]; if ((Finished && timer > slide.FadeOutDuration)) { return; } var overlaySprite = slide.Portrait; if (overlaySprite != null) { Sprite prevPortrait = null; if (state > 0 && state < slideshowPrefab.Slides.Length) { prevPortrait = slideshowPrefab.Slides[state - 1].Portrait; DrawOverlay(prevPortrait, Color.White); } if (prevPortrait?.Texture != overlaySprite.Texture) { DrawOverlay(overlaySprite, overlayColor); } } else { GUI.DrawRectangle(spriteBatch, new Rectangle(0, 0, GameMain.GraphicsWidth, GameMain.GraphicsHeight), overlayColor, isFilled: true); } if (!currentText.IsNullOrEmpty() && textColor.A > 0) { var backgroundSprite = GUIStyle.GetComponentStyle("CommandBackground").GetDefaultSprite(); Vector2 centerPos = new Vector2(GameMain.GraphicsWidth, GameMain.GraphicsHeight) / 2; LocalizedString wrappedText = ToolBox.WrapText(currentText, GameMain.GraphicsWidth / 3, GUIStyle.Font); Vector2 textSize = GUIStyle.Font.MeasureString(wrappedText); Vector2 textPos = centerPos - textSize / 2; backgroundSprite.Draw(spriteBatch, centerPos, Color.White * (textColor.A / 255.0f), origin: backgroundSprite.size / 2, rotate: 0.0f, scale: new Vector2(GameMain.GraphicsWidth / 2 / backgroundSprite.size.X, textSize.Y / backgroundSprite.size.Y * 2.0f)); GUI.DrawString(spriteBatch, textPos + Vector2.One, wrappedText, Color.Black * (textColor.A / 255.0f)); GUI.DrawString(spriteBatch, textPos, wrappedText, textColor); if (timer > slide.TextFadeInDelay * 2) { float alpha = Math.Min(timer - slide.TextFadeInDelay * 2, 1.0f); Vector2 bottomTextPos = centerPos + new Vector2(0.0f, textSize.Y / 2 + 40 * GUI.Scale) - GUIStyle.Font.MeasureString(pressAnyKeyText) / 2; GUI.DrawString(spriteBatch, bottomTextPos + Vector2.One, pressAnyKeyText, Color.Black * (textColor.A / 255.0f) * alpha); GUI.DrawString(spriteBatch, bottomTextPos, pressAnyKeyText, textColor * alpha); } } void DrawOverlay(Sprite sprite, Color color) { if (sprite.Texture == null) { return; } GUI.DrawBackgroundSprite(spriteBatch, sprite, color); } } } }