using Microsoft.Xna.Framework; using Microsoft.Xna.Framework.Graphics; using Microsoft.Xna.Framework.Input; using Myra.Graphics2D; using Myra.Graphics2D.Brushes; using Myra.Graphics2D.UI; using Theriapolis.Core; using Theriapolis.Game.Platform; namespace Theriapolis.Game.Screens; /// /// Phase 5 M6: shown when the player's death-save loop fails (3 cumulative /// failures). Permadeath per the §9 resolved decision — the only option is /// "Return to Title". The autosave_combat slot persists, so the player can /// load it from the title screen and retry. /// public sealed class DefeatedScreen : IScreen { private readonly string _causeOfDeath; private Game1 _game = null!; private Desktop _desktop = null!; private bool _enterWas = true; private bool _escWas = true; public DefeatedScreen(string causeOfDeath = "") { _causeOfDeath = causeOfDeath ?? ""; } public void Initialize(Game1 game) { _game = game; var root = new VerticalStackPanel { Spacing = 14, HorizontalAlignment = HorizontalAlignment.Center, VerticalAlignment = VerticalAlignment.Center, Padding = new Thickness(50, 40, 50, 40), Background = new SolidBrush(new Color(20, 0, 0, 230)), }; root.Widgets.Add(new Label { Text = "YOU HAVE DIED", HorizontalAlignment = HorizontalAlignment.Center }); root.Widgets.Add(new Label { Text = " " }); if (!string.IsNullOrEmpty(_causeOfDeath)) { root.Widgets.Add(new Label { Text = _causeOfDeath, HorizontalAlignment = HorizontalAlignment.Center }); root.Widgets.Add(new Label { Text = " " }); } root.Widgets.Add(new Label { Text = $"Your last autosave is at slot \"{C.SAVE_SLOT_AUTOSAVE_COMBAT}\".", HorizontalAlignment = HorizontalAlignment.Center, }); root.Widgets.Add(new Label { Text = "Load from the title to retry the encounter.", HorizontalAlignment = HorizontalAlignment.Center, }); root.Widgets.Add(new Label { Text = " " }); var ret = new TextButton { Text = "Return to Title (ENTER)", Width = 280, HorizontalAlignment = HorizontalAlignment.Center }; ret.Click += (_, _) => ReturnToTitle(); root.Widgets.Add(ret); _desktop = new Desktop { Root = root }; } private void ReturnToTitle() { // Pop everything above the TitleScreen. Stack at this point is: // Title → CharacterCreation (popped) → WorldGenProgress (popped) → // PlayScreen → CombatHUD (popped earlier) → DefeatedScreen. // So we need to pop DefeatedScreen + PlayScreen = 2 pops. // ScreenManager.Pop is queue-based now, so multiple calls all apply. _game.Screens.Pop(); _game.Screens.Pop(); } public void Update(GameTime gt) { var ks = Keyboard.GetState(); bool enter = ks.IsKeyDown(Keys.Enter); bool esc = ks.IsKeyDown(Keys.Escape); bool enterPressed = enter && !_enterWas; bool escPressed = esc && !_escWas; _enterWas = enter; _escWas = esc; if (enterPressed || escPressed) ReturnToTitle(); } public void Draw(GameTime gt, SpriteBatch sb) { // Don't clear — leave the play-screen's last frame underneath. _desktop.Render(); } public void Deactivate() { } public void Reactivate() { } }