Files
LuaCsForBarotraumaEP/Barotrauma/BarotraumaClient/ClientSource/Screens/SlideshowPlayer.cs
2025-09-17 13:44:21 +03:00

178 lines
6.9 KiB
C#

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);
}
}
}
}