Files
tbd-station-14/Content.Client/Arcade/BlockGameMenu.cs
Brandon Li 545cacbcae StyleNano removal: Palette system and Sheetlets (#29903)
* Apply patch 1777eea9a4..6b32bb2b14

Signed-off-by: Brandon Li <sirbrandonthenerd@gmail.com>

* make red squiggly line go away

Signed-off-by: Brandon Li <sirbrandonthenerd@gmail.com>

* Add todo list

Signed-off-by: Brandon Li <sirbrandonthenerd@gmail.com>

* Add palette to `TextureButton`

Signed-off-by: Brandon Li <sirbrandonthenerd@gmail.com>

* Rename `PalettedButtonSheetlet` to `NTButtonSheetlet` and move useful methods to `ButtonSheetlet`

Signed-off-by: Brandon Li <sirbrandonthenerd@gmail.com>

* migrate `ContextMenu` styles

Signed-off-by: Brandon Li <sirbrandonthenerd@gmail.com>

* Update todo

Signed-off-by: Brandon Li <sirbrandonthenerd@gmail.com>

* tweak NT colors

* New stylesheet: `InterfaceStylesheet` & `InterfaceTooltipSheetlet`

* Move inheritance of `IButtonConfig` to `NanotransenStylesheet.Buttons`

* move `MenuButtonSheetlet` & actually implement `InterfaceStylesheet` correctly

Signed-off-by: Brandon Li <sirbrandonthenerd@gmail.com>

* tweak color & update todo

Signed-off-by: Brandon Li <sirbrandonthenerd@gmail.com>

* chat is this real (update chat palette)

Signed-off-by: Brandon Li <sirbrandonthenerd@gmail.com>

* Update todo

Signed-off-by: Brandon Li <sirbrandonthenerd@gmail.com>

* `SmallButton` and remove some obsolete things from `StyleNano`

Signed-off-by: Brandon Li <sirbrandonthenerd@gmail.com>

* rename `StyleClasses` to `StyleClass` so `Stylesheets.Redux.StyleClasses` syntax is dead

Signed-off-by: Brandon Li <sirbrandonthenerd@gmail.com>

* replace `ButtonColorGreen` with `Positive`

Signed-off-by: Brandon Li <sirbrandonthenerd@gmail.com>

* `Placeholder`

Signed-off-by: Brandon Li <sirbrandonthenerd@gmail.com>

* Examine popup buttons

Signed-off-by: Brandon Li <sirbrandonthenerd@gmail.com>

* move over more things & cleanup `StyleNano` more (under 1000 lines!!!!)

Signed-off-by: Brandon Li <sirbrandonthenerd@gmail.com>

* Remove some more redundant stuff

Signed-off-by: Brandon Li <sirbrandonthenerd@gmail.com>

* Undo style change for chat window

Signed-off-by: Brandon Li <sirbrandonthenerd@gmail.com>

* paper editing works now

Signed-off-by: Brandon Li <sirbrandonthenerd@gmail.com>

* `OptionButton` styles

Signed-off-by: Brandon Li <sirbrandonthenerd@gmail.com>

* `ListContainer`, move `DefaultWindow` styles (for now) & more cleanup

Signed-off-by: Brandon Li <sirbrandonthenerd@gmail.com>

* fix `ActionButton` not having highlighting

Signed-off-by: Brandon Li <sirbrandonthenerd@gmail.com>

* remove imports of `Robust.Client.UserInterface.StylesheetHelpers` & format

Signed-off-by: Brandon Li <sirbrandonthenerd@gmail.com>

* `ButtonBig` and more cleanup

Signed-off-by: Brandon Li <sirbrandonthenerd@gmail.com>

* Move items inheriting from `ISheetletConfig` into their own directory

Signed-off-by: Brandon Li <sirbrandonthenerd@gmail.com>

* Cleanup & move `Label` styles

Signed-off-by: Brandon Li <sirbrandonthenerd@gmail.com>

* Action search box styles

Signed-off-by: Brandon Li <sirbrandonthenerd@gmail.com>

* Moved, stuff is

Signed-off-by: Brandon Li <sirbrandonthenerd@gmail.com>

* rename `LabelSubtext` to `LabelSubText` & move more stuff (were almost there!!)

Signed-off-by: Brandon Li <sirbrandonthenerd@gmail.com>

* yap & move over MORE stuff (just like one thing left!!!)

Signed-off-by: Brandon Li <sirbrandonthenerd@gmail.com>

* Change status classes to appropriate existing classes

Signed-off-by: Brandon Li <sirbrandonthenerd@gmail.com>

* remove remaining references to `StyleNano`

Signed-off-by: Brandon Li <sirbrandonthenerd@gmail.com>

* Fix some hardcoding & broken code, `GetFromControl`

Signed-off-by: Brandon Li <sirbrandonthenerd@gmail.com>

* Scrollbars!

Signed-off-by: Brandon Li <sirbrandonthenerd@gmail.com>

* chores

Signed-off-by: Brandon Li <sirbrandonthenerd@gmail.com>

* clean up `StyleClass.cs`

Signed-off-by: Brandon Li <sirbrandonthenerd@gmail.com>

* `ItemListSheetlet` refactor

Signed-off-by: Brandon Li <sirbrandonthenerd@gmail.com>

* more chores!

Signed-off-by: Brandon Li <sirbrandonthenerd@gmail.com>

* Consistency w/ directory structure

Signed-off-by: Brandon Li <sirbrandonthenerd@gmail.com>

* Move `MainMenuSheetlet`

Signed-off-by: Brandon Li <sirbrandonthenerd@gmail.com>

* `ColorPalette`

Signed-off-by: Brandon Li <sirbrandonthenerd@gmail.com>

* whoopsie

Signed-off-by: Brandon Li <sirbrandonthenerd@gmail.com>

* Remove most sheet-specific sheetlets

Signed-off-by: Brandon Li <sirbrandonthenerd@gmail.com>

* fix warnings, cleanup, & fix scrollbar (this is why we fix warnings boys)

Signed-off-by: Brandon Li <sirbrandonthenerd@gmail.com>

* yap

Signed-off-by: Brandon Li <sirbrandonthenerd@gmail.com>

* MASSIVE resharper skill issue

Signed-off-by: Brandon Li <sirbrandonthenerd@gmail.com>

* actually use `ISheetletConfig`

Signed-off-by: Brandon Li <sirbrandonthenerd@gmail.com>

* have specific sheetlet be specific

Signed-off-by: Brandon Li <sirbrandonthenerd@gmail.com>

* `GetResourceOr`

Signed-off-by: Brandon Li <sirbrandonthenerd@gmail.com>

* cleanup & move / remove `IPalette`s

Signed-off-by: Brandon Li <sirbrandonthenerd@gmail.com>

* actually do specific stylesheets correctly & fix tooltips

Signed-off-by: Brandon Li <sirbrandonthenerd@gmail.com>

* cleanup & logging

Signed-off-by: Brandon Li <sirbrandonthenerd@gmail.com>

* Move `FontKind` and `FontKindExtensions` to their own files

Signed-off-by: Brandon Li <sirbrandonthenerd@gmail.com>

* rename `InterfaceStylesheet` to `SystemStylesheet`

Signed-off-by: Brandon Li <sirbrandonthenerd@gmail.com>

* change `ButtonHovered` etc to `PseudoHovered` etc

Signed-off-by: Brandon Li <sirbrandonthenerd@gmail.com>

* give the palettes fun names

Signed-off-by: Brandon Li <sirbrandonthenerd@gmail.com>

* `StyleSpace` is no more

Signed-off-by: Brandon Li <sirbrandonthenerd@gmail.com>

* It should compile now! I am now going to bed (fr) if it fails it fails

Signed-off-by: Brandon Li <sirbrandonthenerd@gmail.com>

* make squiggly red line go away

Signed-off-by: Brandon Li <sirbrandonthenerd@gmail.com>

* add additional type restrictions to sheetlets

* `CommonStylesheet`

* minor cleanup

* Make `GetSheetletRules` not horrible

* wait this was duplicating style rules. oops!

* move some sheetlets to their associated xamls

* oh wait apparently that was important

* review pass 1

* review pass 2 (font & color stuff)

* review pass 3: remove unused stuff / filename fix

* fix warnings & "replace cast with explicit variable type"

* move `Palette` stuff to its own directory

* tweak colors (they're different now that I actually fixed the OKlab thing)

* review pass 4: little things

* make window close button grey before hovering

* refactor `HLine` to make it less terrible and allow it to be styled

* fix `NanoHeading` (it's been broken for a while whoops) and cleanup hardcoding

* band-aid missing references in `StyleNano`

* move `StyleBox` generating functions out of `IButtonSheetlet` into `StyleBoxHelper`

* remove dictionary field from `IStylesheetManager`

* Add check for unloaded sheetlets

* style tweaks to satisfy OCD

* I somehow missed this: `Caution` styleclass replaced with `negative`, refactor `PowerChargeWindow`

* tweak palettes for like the fourth time

* construct `StyleNano` / `StyleSpace` in `StylesheetManager` and mark them as obsolete

* rename `BackgroundPanel` classes for consistency

* tweak window / `ListContainer`

* oh right you use `///` not `/**`

* font system is bad, make it temporary

* acknowledge Divider funkyness

* remove use of class `Disabled`

* `ColorPalette` allow overriding colors with brace initialization

* review pass again

* tweak disabled button colors

* `StatusPalette` tweaks

* typo

* Make squiggly red line go away

* Delete `Redux`

* Remove all references to `Redux`

* make red less radioactive

* Store stylesheet name inside stylesheet class

* fix merge errors

* use RT's Oklab support instead

* shuffle around `StylesheetManager` fields

* apply stylesheets based off `StylesheetComponent`

* simplify `ColorPalette` construction

* add todo for `SheetletConfigType`

* `OptionButton` has a background color now

* fix disabled buttons

* sigh (red color palette fixed)

* make `ItemList` use primary palette

* Revert "apply stylesheets based off `StylesheetComponent`"

This reverts commit c05b147da845f6e04ff33d1cbd91a18a92c676d7.

* dead code removal

* buttons are green when pressed (we need togglebuttons)

---------

Signed-off-by: Brandon Li <sirbrandonthenerd@gmail.com>
Co-authored-by: Janet Blackquill <uhhadd@gmail.com>
2025-10-19 21:10:44 +00:00

691 lines
25 KiB
C#

using System;
using System.Collections.Generic;
using System.Linq;
using System.Numerics;
using System.Text;
using Content.Client.Arcade.UI;
using Content.Client.Resources;
using Content.Shared.Arcade;
using Content.Shared.Input;
using Robust.Client.Graphics;
using Robust.Client.ResourceManagement;
using Robust.Client.UserInterface;
using Robust.Client.UserInterface.Controls;
using Robust.Client.UserInterface.CustomControls;
using Robust.Shared.Graphics;
using Robust.Shared.IoC;
using Robust.Shared.Localization;
using Robust.Shared.Maths;
using Robust.Shared.Utility;
using static Robust.Client.UserInterface.Controls.BoxContainer;
namespace Content.Client.Arcade
{
public sealed class BlockGameMenu : DefaultWindow
{
private static readonly Color OverlayBackgroundColor = new(74, 74, 81, 180);
private static readonly Color OverlayShadowColor = new(0, 0, 0, 83);
private static readonly Vector2 BlockSize = new(15, 15);
private readonly PanelContainer _mainPanel;
private readonly BoxContainer _gameRootContainer;
private GridContainer _gameGrid = default!;
private GridContainer _nextBlockGrid = default!;
private GridContainer _holdBlockGrid = default!;
private readonly Label _pointsLabel;
private readonly Label _levelLabel;
private readonly Button _pauseButton;
private readonly PanelContainer _menuRootContainer;
private readonly Button _unpauseButton;
private readonly Control _unpauseButtonMargin;
private readonly Button _newGameButton;
private readonly Button _scoreBoardButton;
private readonly PanelContainer _gameOverRootContainer;
private readonly Label _finalScoreLabel;
private readonly Button _finalNewGameButton;
private readonly PanelContainer _highscoresRootContainer;
private readonly Label _localHighscoresLabel;
private readonly Label _globalHighscoresLabel;
private readonly Button _highscoreBackButton;
private bool _isPlayer = false;
private bool _gameOver = false;
public event Action<BlockGamePlayerAction>? OnAction;
public BlockGameMenu()
{
Title = Loc.GetString("blockgame-menu-title");
MinSize = SetSize = new Vector2(410, 490);
var resourceCache = IoCManager.Resolve<IResourceCache>();
var backgroundTexture = resourceCache.GetTexture("/Textures/Interface/Nano/button.svg.96dpi.png");
_mainPanel = new PanelContainer();
#region Game Menu
// building the game container
_gameRootContainer = new BoxContainer
{
Orientation = LayoutOrientation.Vertical
};
_levelLabel = new Label
{
Align = Label.AlignMode.Center,
HorizontalExpand = true
};
_gameRootContainer.AddChild(_levelLabel);
_gameRootContainer.AddChild(new Control
{
MinSize = new Vector2(1, 5)
});
_pointsLabel = new Label
{
Align = Label.AlignMode.Center,
HorizontalExpand = true
};
_gameRootContainer.AddChild(_pointsLabel);
_gameRootContainer.AddChild(new Control
{
MinSize = new Vector2(1, 10)
});
var gameBox = new BoxContainer
{
Orientation = LayoutOrientation.Horizontal
};
gameBox.AddChild(SetupHoldBox(backgroundTexture));
gameBox.AddChild(new Control
{
MinSize = new Vector2(10, 1)
});
gameBox.AddChild(SetupGameGrid(backgroundTexture));
gameBox.AddChild(new Control
{
MinSize = new Vector2(10, 1)
});
gameBox.AddChild(SetupNextBox(backgroundTexture));
_gameRootContainer.AddChild(gameBox);
_gameRootContainer.AddChild(new Control
{
MinSize = new Vector2(1, 10)
});
_pauseButton = new Button
{
Text = Loc.GetString("blockgame-menu-button-pause"),
TextAlign = Label.AlignMode.Center
};
_pauseButton.OnPressed += (e) => TryPause();
_gameRootContainer.AddChild(_pauseButton);
#endregion
_mainPanel.AddChild(_gameRootContainer);
#region Pause Menu
var pauseRootBack = new StyleBoxTexture
{
Texture = backgroundTexture,
Modulate = OverlayShadowColor
};
pauseRootBack.SetPatchMargin(StyleBox.Margin.All, 10);
_menuRootContainer = new PanelContainer
{
PanelOverride = pauseRootBack,
VerticalAlignment = VAlignment.Center,
HorizontalAlignment = HAlignment.Center
};
var pauseInnerBack = new StyleBoxTexture
{
Texture = backgroundTexture,
Modulate = OverlayBackgroundColor
};
pauseInnerBack.SetPatchMargin(StyleBox.Margin.All, 10);
var pauseMenuInnerPanel = new PanelContainer
{
PanelOverride = pauseInnerBack,
VerticalAlignment = VAlignment.Center,
HorizontalAlignment = HAlignment.Center
};
_menuRootContainer.AddChild(pauseMenuInnerPanel);
var pauseMenuContainer = new BoxContainer
{
Orientation = LayoutOrientation.Vertical,
HorizontalAlignment = HAlignment.Center,
VerticalAlignment = VAlignment.Center
};
_newGameButton = new Button
{
Text = Loc.GetString("blockgame-menu-button-new-game"),
TextAlign = Label.AlignMode.Center
};
_newGameButton.OnPressed += (e) =>
{
OnAction?.Invoke(BlockGamePlayerAction.NewGame);
};
pauseMenuContainer.AddChild(_newGameButton);
pauseMenuContainer.AddChild(new Control { MinSize = new Vector2(1, 10) });
_scoreBoardButton = new Button
{
Text = Loc.GetString("blockgame-menu-button-scoreboard"),
TextAlign = Label.AlignMode.Center
};
_scoreBoardButton.OnPressed += (e) =>
{
OnAction?.Invoke(BlockGamePlayerAction.ShowHighscores);
};
pauseMenuContainer.AddChild(_scoreBoardButton);
_unpauseButtonMargin = new Control { MinSize = new Vector2(1, 10), Visible = false };
pauseMenuContainer.AddChild(_unpauseButtonMargin);
_unpauseButton = new Button
{
Text = Loc.GetString("blockgame-menu-button-unpause"),
TextAlign = Label.AlignMode.Center,
Visible = false
};
_unpauseButton.OnPressed += (e) =>
{
OnAction?.Invoke(BlockGamePlayerAction.Unpause);
};
pauseMenuContainer.AddChild(_unpauseButton);
pauseMenuInnerPanel.AddChild(pauseMenuContainer);
#endregion
#region Gameover Screen
var gameOverRootBack = new StyleBoxTexture
{
Texture = backgroundTexture,
Modulate = OverlayShadowColor
};
gameOverRootBack.SetPatchMargin(StyleBox.Margin.All, 10);
_gameOverRootContainer = new PanelContainer
{
PanelOverride = gameOverRootBack,
VerticalAlignment = VAlignment.Center,
HorizontalAlignment = HAlignment.Center
};
var gameOverInnerBack = new StyleBoxTexture
{
Texture = backgroundTexture,
Modulate = OverlayBackgroundColor
};
gameOverInnerBack.SetPatchMargin(StyleBox.Margin.All, 10);
var gameOverMenuInnerPanel = new PanelContainer
{
PanelOverride = gameOverInnerBack,
VerticalAlignment = VAlignment.Center,
HorizontalAlignment = HAlignment.Center
};
_gameOverRootContainer.AddChild(gameOverMenuInnerPanel);
var gameOverMenuContainer = new BoxContainer
{
Orientation = LayoutOrientation.Vertical,
HorizontalAlignment = HAlignment.Center,
VerticalAlignment = VAlignment.Center
};
gameOverMenuContainer.AddChild(new Label { Text = Loc.GetString("blockgame-menu-msg-game-over"), Align = Label.AlignMode.Center });
gameOverMenuContainer.AddChild(new Control { MinSize = new Vector2(1, 10) });
_finalScoreLabel = new Label { Align = Label.AlignMode.Center };
gameOverMenuContainer.AddChild(_finalScoreLabel);
gameOverMenuContainer.AddChild(new Control { MinSize = new Vector2(1, 10) });
_finalNewGameButton = new Button
{
Text = Loc.GetString("blockgame-menu-button-new-game"),
TextAlign = Label.AlignMode.Center
};
_finalNewGameButton.OnPressed += (e) =>
{
OnAction?.Invoke(BlockGamePlayerAction.NewGame);
};
gameOverMenuContainer.AddChild(_finalNewGameButton);
gameOverMenuInnerPanel.AddChild(gameOverMenuContainer);
#endregion
#region High Score Screen
var rootBack = new StyleBoxTexture
{
Texture = backgroundTexture,
Modulate = OverlayShadowColor
};
rootBack.SetPatchMargin(StyleBox.Margin.All, 10);
_highscoresRootContainer = new PanelContainer
{
PanelOverride = rootBack,
VerticalAlignment = VAlignment.Center,
HorizontalAlignment = HAlignment.Center
};
var c = new Color(OverlayBackgroundColor.R, OverlayBackgroundColor.G, OverlayBackgroundColor.B, 220);
var innerBack = new StyleBoxTexture
{
Texture = backgroundTexture,
Modulate = c
};
innerBack.SetPatchMargin(StyleBox.Margin.All, 10);
var menuInnerPanel = new PanelContainer
{
PanelOverride = innerBack,
VerticalAlignment = VAlignment.Center,
HorizontalAlignment = HAlignment.Center
};
_highscoresRootContainer.AddChild(menuInnerPanel);
var menuContainer = new BoxContainer
{
Orientation = LayoutOrientation.Vertical,
HorizontalAlignment = HAlignment.Center,
VerticalAlignment = VAlignment.Center
};
menuContainer.AddChild(new Label { Text = Loc.GetString("blockgame-menu-label-highscores") });
menuContainer.AddChild(new Control { MinSize = new Vector2(1, 10) });
var highScoreBox = new BoxContainer
{
Orientation = LayoutOrientation.Horizontal
};
_localHighscoresLabel = new Label
{
Align = Label.AlignMode.Center
};
highScoreBox.AddChild(_localHighscoresLabel);
highScoreBox.AddChild(new Control { MinSize = new Vector2(40, 1) });
_globalHighscoresLabel = new Label
{
Align = Label.AlignMode.Center
};
highScoreBox.AddChild(_globalHighscoresLabel);
menuContainer.AddChild(highScoreBox);
menuContainer.AddChild(new Control { MinSize = new Vector2(1, 10) });
_highscoreBackButton = new Button
{
Text = Loc.GetString("blockgame-menu-button-back"),
TextAlign = Label.AlignMode.Center
};
_highscoreBackButton.OnPressed += (e) =>
{
OnAction?.Invoke(BlockGamePlayerAction.Pause);
};
menuContainer.AddChild(_highscoreBackButton);
menuInnerPanel.AddChild(menuContainer);
#endregion
ContentsContainer.AddChild(_mainPanel);
CanKeyboardFocus = true;
}
public void SetUsability(bool isPlayer)
{
_isPlayer = isPlayer;
UpdateUsability();
}
private void UpdateUsability()
{
_pauseButton.Disabled = !_isPlayer;
_newGameButton.Disabled = !_isPlayer;
_scoreBoardButton.Disabled = !_isPlayer;
_unpauseButton.Disabled = !_isPlayer;
_finalNewGameButton.Disabled = !_isPlayer;
_highscoreBackButton.Disabled = !_isPlayer;
}
private Control SetupGameGrid(Texture panelTex)
{
_gameGrid = new GridContainer
{
Columns = 10,
HSeparationOverride = 1,
VSeparationOverride = 1
};
UpdateBlocks(Array.Empty<BlockGameBlock>());
var back = new StyleBoxTexture
{
Texture = panelTex,
Modulate = Color.FromHex("#4a4a51"),
};
back.SetPatchMargin(StyleBox.Margin.All, 10);
var gamePanel = new PanelContainer
{
PanelOverride = back,
HorizontalExpand = true,
SizeFlagsStretchRatio = 34.25f
};
var backgroundPanel = new PanelContainer
{
PanelOverride = new StyleBoxFlat { BackgroundColor = Color.FromHex("#86868d") }
};
backgroundPanel.AddChild(_gameGrid);
gamePanel.AddChild(backgroundPanel);
return gamePanel;
}
private Control SetupNextBox(Texture panelTex)
{
var previewBack = new StyleBoxTexture
{
Texture = panelTex,
Modulate = Color.FromHex("#4a4a51")
};
previewBack.SetPatchMargin(StyleBox.Margin.All, 10);
var grid = new GridContainer
{
Columns = 1,
HorizontalExpand = true,
SizeFlagsStretchRatio = 20
};
var nextBlockPanel = new PanelContainer
{
PanelOverride = previewBack,
MinSize = BlockSize * 6.5f,
HorizontalAlignment = HAlignment.Left,
VerticalAlignment = VAlignment.Top
};
var nextCenterContainer = new CenterContainer();
_nextBlockGrid = new GridContainer
{
HSeparationOverride = 1,
VSeparationOverride = 1
};
nextCenterContainer.AddChild(_nextBlockGrid);
nextBlockPanel.AddChild(nextCenterContainer);
grid.AddChild(nextBlockPanel);
grid.AddChild(new Label { Text = Loc.GetString("blockgame-menu-label-next"), Align = Label.AlignMode.Center });
return grid;
}
private Control SetupHoldBox(Texture panelTex)
{
var previewBack = new StyleBoxTexture
{
Texture = panelTex,
Modulate = Color.FromHex("#4a4a51")
};
previewBack.SetPatchMargin(StyleBox.Margin.All, 10);
var grid = new GridContainer
{
Columns = 1,
HorizontalExpand = true,
SizeFlagsStretchRatio = 20
};
var holdBlockPanel = new PanelContainer
{
PanelOverride = previewBack,
MinSize = BlockSize * 6.5f,
HorizontalAlignment = HAlignment.Left,
VerticalAlignment = VAlignment.Top
};
var holdCenterContainer = new CenterContainer();
_holdBlockGrid = new GridContainer
{
HSeparationOverride = 1,
VSeparationOverride = 1
};
holdCenterContainer.AddChild(_holdBlockGrid);
holdBlockPanel.AddChild(holdCenterContainer);
grid.AddChild(holdBlockPanel);
grid.AddChild(new Label { Text = Loc.GetString("blockgame-menu-label-hold"), Align = Label.AlignMode.Center });
return grid;
}
protected override void KeyboardFocusExited()
{
if (!IsOpen)
return;
if (_gameOver)
return;
TryPause();
}
private void TryPause()
{
OnAction?.Invoke(BlockGamePlayerAction.Pause);
}
public void SetStarted()
{
_gameOver = false;
_unpauseButton.Visible = true;
_unpauseButtonMargin.Visible = true;
}
public void SetScreen(BlockGameMessages.BlockGameScreen screen)
{
if (_gameOver)
return;
switch (screen)
{
case BlockGameMessages.BlockGameScreen.Game:
GrabKeyboardFocus();
CloseMenus();
_pauseButton.Disabled = !_isPlayer;
break;
case BlockGameMessages.BlockGameScreen.Pause:
//ReleaseKeyboardFocus();
CloseMenus();
_mainPanel.AddChild(_menuRootContainer);
_pauseButton.Disabled = true;
break;
case BlockGameMessages.BlockGameScreen.Gameover:
_gameOver = true;
_pauseButton.Disabled = true;
//ReleaseKeyboardFocus();
CloseMenus();
_mainPanel.AddChild(_gameOverRootContainer);
break;
case BlockGameMessages.BlockGameScreen.Highscores:
//ReleaseKeyboardFocus();
CloseMenus();
_mainPanel.AddChild(_highscoresRootContainer);
break;
}
}
private void CloseMenus()
{
if (_mainPanel.Children.Contains(_menuRootContainer))
_mainPanel.RemoveChild(_menuRootContainer);
if (_mainPanel.Children.Contains(_gameOverRootContainer))
_mainPanel.RemoveChild(_gameOverRootContainer);
if (_mainPanel.Children.Contains(_highscoresRootContainer))
_mainPanel.RemoveChild(_highscoresRootContainer);
}
public void SetGameoverInfo(int amount, int? localPlacement, int? globalPlacement)
{
var globalPlacementText = globalPlacement == null ? "-" : $"#{globalPlacement}";
var localPlacementText = localPlacement == null ? "-" : $"#{localPlacement}";
_finalScoreLabel.Text =
Loc.GetString("blockgame-menu-gameover-info",
("global", globalPlacementText),
("local", localPlacementText),
("points", amount));
}
public void UpdatePoints(int points)
{
_pointsLabel.Text = Loc.GetString("blockgame-menu-label-points", ("points", points));
}
public void UpdateLevel(int level)
{
_levelLabel.Text = Loc.GetString("blockgame-menu-label-level", ("level", level + 1));
}
public void UpdateHighscores(List<BlockGameMessages.HighScoreEntry> localHighscores,
List<BlockGameMessages.HighScoreEntry> globalHighscores)
{
var localHighscoreText = new StringBuilder(Loc.GetString("blockgame-menu-text-station") + "\n");
var globalHighscoreText = new StringBuilder(Loc.GetString("blockgame-menu-text-nanotrasen") + "\n");
for (var i = 0; i < 5; i++)
{
localHighscoreText.AppendLine(localHighscores.Count > i
? $"#{i + 1}: {localHighscores[i].Name} - {localHighscores[i].Score}"
: $"#{i + 1}: ??? - 0");
globalHighscoreText.AppendLine(globalHighscores.Count > i
? $"#{i + 1}: {globalHighscores[i].Name} - {globalHighscores[i].Score}"
: $"#{i + 1}: ??? - 0");
}
_localHighscoresLabel.Text = localHighscoreText.ToString();
_globalHighscoresLabel.Text = globalHighscoreText.ToString();
}
protected override void KeyBindDown(GUIBoundKeyEventArgs args)
{
base.KeyBindDown(args);
if (!_isPlayer || args.Handled)
return;
else if (args.Function == ContentKeyFunctions.ArcadeLeft)
OnAction?.Invoke(BlockGamePlayerAction.StartLeft);
else if (args.Function == ContentKeyFunctions.ArcadeRight)
OnAction?.Invoke(BlockGamePlayerAction.StartRight);
else if (args.Function == ContentKeyFunctions.ArcadeUp)
OnAction?.Invoke(BlockGamePlayerAction.Rotate);
else if (args.Function == ContentKeyFunctions.Arcade3)
OnAction?.Invoke(BlockGamePlayerAction.CounterRotate);
else if (args.Function == ContentKeyFunctions.ArcadeDown)
OnAction?.Invoke(BlockGamePlayerAction.SoftdropStart);
else if (args.Function == ContentKeyFunctions.Arcade2)
OnAction?.Invoke(BlockGamePlayerAction.Hold);
else if (args.Function == ContentKeyFunctions.Arcade1)
OnAction?.Invoke(BlockGamePlayerAction.Harddrop);
}
protected override void KeyBindUp(GUIBoundKeyEventArgs args)
{
base.KeyBindUp(args);
if (!_isPlayer || args.Handled)
return;
else if (args.Function == ContentKeyFunctions.ArcadeLeft)
OnAction?.Invoke(BlockGamePlayerAction.EndLeft);
else if (args.Function == ContentKeyFunctions.ArcadeRight)
OnAction?.Invoke(BlockGamePlayerAction.EndRight);
else if (args.Function == ContentKeyFunctions.ArcadeDown)
OnAction?.Invoke(BlockGamePlayerAction.SoftdropEnd);
}
public void UpdateNextBlock(BlockGameBlock[] blocks)
{
_nextBlockGrid.RemoveAllChildren();
if (blocks.Length == 0)
return;
var columnCount = blocks.Max(b => b.Position.X) + 1;
var rowCount = blocks.Max(b => b.Position.Y) + 1;
_nextBlockGrid.Columns = columnCount;
for (var y = 0; y < rowCount; y++)
{
for (var x = 0; x < columnCount; x++)
{
var c = GetColorForPosition(blocks, x, y);
_nextBlockGrid.AddChild(new PanelContainer
{
PanelOverride = new StyleBoxFlat { BackgroundColor = c },
MinSize = BlockSize,
RectDrawClipMargin = 0
});
}
}
}
public void UpdateHeldBlock(BlockGameBlock[] blocks)
{
_holdBlockGrid.RemoveAllChildren();
if (blocks.Length == 0)
return;
var columnCount = blocks.Max(b => b.Position.X) + 1;
var rowCount = blocks.Max(b => b.Position.Y) + 1;
_holdBlockGrid.Columns = columnCount;
for (var y = 0; y < rowCount; y++)
{
for (var x = 0; x < columnCount; x++)
{
var c = GetColorForPosition(blocks, x, y);
_holdBlockGrid.AddChild(new PanelContainer
{
PanelOverride = new StyleBoxFlat { BackgroundColor = c },
MinSize = BlockSize,
RectDrawClipMargin = 0
});
}
}
}
public void UpdateBlocks(BlockGameBlock[] blocks)
{
_gameGrid.RemoveAllChildren();
for (var y = 0; y < 20; y++)
{
for (var x = 0; x < 10; x++)
{
var c = GetColorForPosition(blocks, x, y);
_gameGrid.AddChild(new PanelContainer
{
PanelOverride = new StyleBoxFlat { BackgroundColor = c },
MinSize = BlockSize,
RectDrawClipMargin = 0
});
}
}
}
private static Color GetColorForPosition(BlockGameBlock[] blocks, int x, int y)
{
var c = Color.Transparent;
var matchingBlock = blocks.FirstOrNull(b => b.Position.X == x && b.Position.Y == y);
if (matchingBlock.HasValue)
{
c = BlockGameBlock.ToColor(matchingBlock.Value.GameBlockColor);
}
return c;
}
}
}