271 lines
8.9 KiB
Plaintext
271 lines
8.9 KiB
Plaintext
@using Fluxor
|
|
@using Koogle.Application.DTOs
|
|
@using Koogle.Application.Games
|
|
@using Koogle.Application.Games.Shit
|
|
@using Koogle.Web.Store.GameState
|
|
@using Koogle.Web.Store.DayState
|
|
@using MudBlazor
|
|
|
|
@inherits Fluxor.Blazor.Web.Components.FluxorComponent
|
|
|
|
@implements IDisposable
|
|
@inject IState<GameState> GameState
|
|
@inject IState<DayState> DayState
|
|
|
|
<MudPaper Class="pa-4">
|
|
@* <MudText Typo="Typo.h6" Class="mb-4">
|
|
<MudIcon Icon="@Icons.Material.Filled.TableChart" Class="mr-2" />
|
|
Scheiss-Spiel - Tafel
|
|
</MudText> *@
|
|
|
|
@if (_model == null)
|
|
{
|
|
<MudAlert Severity="Severity.Info">
|
|
Spiel noch nicht gestartet.
|
|
</MudAlert>
|
|
}
|
|
else
|
|
{
|
|
@* Game info header *@
|
|
<MudPaper Class="pa-3 mb-4" Elevation="0" Style="background-color: var(--mud-palette-background-grey);">
|
|
<MudStack Row="true" Justify="Justify.SpaceBetween" AlignItems="AlignItems.Center">
|
|
<MudText Typo="Typo.body1">
|
|
<strong>Scheiss-Zahl:</strong>
|
|
<MudChip T="string" Size="Size.Small" Color="Color.Error" Variant="Variant.Filled">
|
|
@_model.ShitNumber
|
|
</MudChip>
|
|
</MudText>
|
|
<MudText Typo="Typo.body1">
|
|
<strong>Gesammelte Punkte:</strong>
|
|
@if (_model.CollectedPoints > 0)
|
|
{
|
|
<MudChip T="string" Size="Size.Small" Color="Color.Warning" Variant="Variant.Filled">
|
|
@_model.CollectedPoints
|
|
</MudChip>
|
|
}
|
|
else
|
|
{
|
|
<span>0</span>
|
|
}
|
|
</MudText>
|
|
</MudStack>
|
|
</MudPaper>
|
|
|
|
@* Last throw info *@
|
|
@if (_model.LastThrowPins.HasValue)
|
|
{
|
|
<MudAlert Severity="@GetLastThrowSeverity()" Class="mb-4" Dense="true">
|
|
@if (_model.LastThrowWasShitNumber)
|
|
{
|
|
<span>Scheiss-Zahl getroffen! Du bekommst alle gesammelten Punkte.</span>
|
|
}
|
|
else if (_model.LastThrowWasGutter)
|
|
{
|
|
<span>Rinne! Du bekommst alle gesammelten Punkte.</span>
|
|
}
|
|
else
|
|
{
|
|
<span>@_model.LastThrowPins Kegel - @_model.LastThrowPins Punkte abgezogen.</span>
|
|
}
|
|
</MudAlert>
|
|
}
|
|
|
|
@* Winner announcement *@
|
|
@if (_model.IsGameOver && _model.WinnerId.HasValue)
|
|
{
|
|
var winnerName = GetPlayerName(_model.WinnerId.Value);
|
|
<MudAlert Severity="Severity.Success" Class="mb-4">
|
|
<MudStack Row="true" AlignItems="AlignItems.Center" Spacing="2">
|
|
<MudIcon Icon="@Icons.Material.Filled.EmojiEvents" />
|
|
<MudText Typo="Typo.h6">@winnerName hat gewonnen!</MudText>
|
|
</MudStack>
|
|
</MudAlert>
|
|
}
|
|
|
|
@* Players table *@
|
|
<MudTable Items="@_playerStats"
|
|
Dense="true"
|
|
Hover="true"
|
|
Striped="true"
|
|
Bordered="true"
|
|
Class="mb-4">
|
|
<HeaderContent>
|
|
<MudTh>Spieler</MudTh>
|
|
<MudTh Style="text-align: right">Punkte</MudTh>
|
|
<MudTh Style="text-align: center">Status</MudTh>
|
|
</HeaderContent>
|
|
<RowTemplate>
|
|
<MudTd>
|
|
@if (context.IsCurrentPlayer && !_model.IsGameOver)
|
|
{
|
|
<MudBadge Color="Color.Primary" Dot="true" Overlap="true">
|
|
<MudText Typo="Typo.body1" Style="font-weight: 600">
|
|
@context.PlayerName
|
|
</MudText>
|
|
</MudBadge>
|
|
}
|
|
else
|
|
{
|
|
<MudText Typo="Typo.body1">@context.PlayerName</MudText>
|
|
}
|
|
</MudTd>
|
|
<MudTd Style="text-align: right">
|
|
<MudText Typo="Typo.h6" Style="@GetPointsStyle(context)">
|
|
@context.Points
|
|
</MudText>
|
|
</MudTd>
|
|
<MudTd Style="text-align: center">
|
|
@if (context.IsWinner)
|
|
{
|
|
<MudChip T="string" Size="Size.Small" Color="Color.Success" Variant="Variant.Filled"
|
|
Icon="@Icons.Material.Filled.EmojiEvents">
|
|
GEWINNER
|
|
</MudChip>
|
|
}
|
|
else if (_model.IsGameOver)
|
|
{
|
|
<MudChip T="string" Size="Size.Small" Color="Color.Error" Variant="Variant.Outlined"
|
|
Icon="@Icons.Material.Filled.MoneyOff">
|
|
-@context.Points Strafe
|
|
</MudChip>
|
|
}
|
|
else if (context.IsCurrentPlayer)
|
|
{
|
|
<MudChip T="string" Size="Size.Small" Color="Color.Primary" Variant="Variant.Outlined">
|
|
Am Zug
|
|
</MudChip>
|
|
}
|
|
</MudTd>
|
|
</RowTemplate>
|
|
</MudTable>
|
|
|
|
@* Progress indicator *@
|
|
@if (!_model.IsGameOver)
|
|
{
|
|
<MudPaper Class="pa-3" Elevation="0" Style="background-color: var(--mud-palette-background-grey);">
|
|
<MudText Typo="Typo.body2" Color="Color.Secondary">
|
|
Wer zuerst 0 Punkte erreicht, gewinnt!
|
|
</MudText>
|
|
</MudPaper>
|
|
}
|
|
}
|
|
</MudPaper>
|
|
|
|
@code {
|
|
private ShitGameModel? _model;
|
|
private List<PlayerStatsRow> _playerStats = [];
|
|
|
|
protected override void OnInitialized()
|
|
{
|
|
base.OnInitialized();
|
|
GameState.StateChanged += OnGameStateChanged;
|
|
UpdateStats();
|
|
}
|
|
|
|
private void OnGameStateChanged(object? sender, EventArgs e)
|
|
{
|
|
UpdateStats();
|
|
InvokeAsync(StateHasChanged);
|
|
}
|
|
|
|
private void UpdateStats()
|
|
{
|
|
_playerStats.Clear();
|
|
_model = null;
|
|
|
|
var gameState = GameState.Value;
|
|
if (gameState.GameModel is ShitGameModel model)
|
|
{
|
|
_model = model;
|
|
}
|
|
else if (gameState.GameModel is System.Text.Json.JsonElement jsonElement)
|
|
{
|
|
try
|
|
{
|
|
_model = System.Text.Json.JsonSerializer.Deserialize<ShitGameModel>(
|
|
jsonElement.GetRawText(),
|
|
GameModelFactory.JsonSerializerOptions);
|
|
}
|
|
catch
|
|
{
|
|
return;
|
|
}
|
|
}
|
|
|
|
if (_model?.PlayerPoints == null)
|
|
{
|
|
return;
|
|
}
|
|
|
|
var currentPlayerId = gameState.Participants.CurrentPlayerId;
|
|
var persons = DayState.Value.AvailablePersons;
|
|
|
|
foreach (var (playerId, points) in _model.PlayerPoints)
|
|
{
|
|
var person = persons.FirstOrDefault(p => p.Id == playerId);
|
|
var playerName = person?.Name ?? "Unbekannt";
|
|
|
|
_playerStats.Add(new PlayerStatsRow
|
|
{
|
|
PlayerId = playerId,
|
|
PlayerName = playerName,
|
|
Points = points,
|
|
IsWinner = _model.WinnerId == playerId,
|
|
IsCurrentPlayer = playerId == currentPlayerId
|
|
});
|
|
}
|
|
|
|
// Sort: Winner first, then by points ascending (lowest is best)
|
|
_playerStats = _playerStats
|
|
.OrderByDescending(p => p.IsWinner)
|
|
.ThenBy(p => p.Points)
|
|
.ToList();
|
|
}
|
|
|
|
private string GetPlayerName(Guid playerId)
|
|
{
|
|
var person = DayState.Value.AvailablePersons.FirstOrDefault(p => p.Id == playerId);
|
|
return person?.Name ?? "Unbekannt";
|
|
}
|
|
|
|
private Severity GetLastThrowSeverity()
|
|
{
|
|
if (_model?.LastThrowWasShitNumber == true || _model?.LastThrowWasGutter == true)
|
|
{
|
|
return Severity.Error;
|
|
}
|
|
return Severity.Info;
|
|
}
|
|
|
|
private string GetPointsStyle(PlayerStatsRow row)
|
|
{
|
|
if (row.IsWinner)
|
|
{
|
|
return "color: var(--mud-palette-success); font-weight: bold;";
|
|
}
|
|
if (_model?.IsGameOver == true)
|
|
{
|
|
return "color: var(--mud-palette-error);";
|
|
}
|
|
if (row.Points <= 10)
|
|
{
|
|
return "color: var(--mud-palette-warning);";
|
|
}
|
|
return "";
|
|
}
|
|
|
|
public void Dispose()
|
|
{
|
|
GameState.StateChanged -= OnGameStateChanged;
|
|
}
|
|
|
|
private record PlayerStatsRow
|
|
{
|
|
public Guid PlayerId { get; init; }
|
|
public string PlayerName { get; init; } = "";
|
|
public int Points { get; init; }
|
|
public bool IsWinner { get; init; }
|
|
public bool IsCurrentPlayer { get; init; }
|
|
}
|
|
}
|