KoogleApp/src/GoodWood.Application/Games/GameEvent.cs

122 lines
3.2 KiB
C#

using System.Text.Json.Serialization;
namespace GoodWood.Application.Games;
/// <summary>
/// Base class for game events that require UI notification (dialogs, toasts, etc.).
/// Events have a unique ID to prevent duplicate display.
/// </summary>
[JsonPolymorphic(TypeDiscriminatorPropertyName = "$type")]
[JsonDerivedType(typeof(PlayerEliminatedEvent), "PlayerEliminated")]
[JsonDerivedType(typeof(PlayerWonEvent), "PlayerWon")]
[JsonDerivedType(typeof(TeamWonEvent), "TeamWon")]
[JsonDerivedType(typeof(GameEndedEvent), "GameEnded")]
[JsonDerivedType(typeof(FoxChangedEvent), "FoxChanged")]
public abstract record GameEvent
{
/// <summary>
/// Unique identifier for this event instance.
/// </summary>
public Guid EventId { get; init; } = Guid.NewGuid();
/// <summary>
/// Timestamp when the event was created.
/// </summary>
public DateTime CreatedAt { get; init; } = DateTime.UtcNow;
/// <summary>
/// Game-specific message to display in the UI.
/// </summary>
public string? Message { get; init; }
}
/// <summary>
/// Event when a player is eliminated from the game.
/// </summary>
public record PlayerEliminatedEvent : GameEvent
{
/// <summary>
/// ID of the eliminated player.
/// </summary>
public required Guid PlayerId { get; init; }
/// <summary>
/// Elimination rank (1 = first eliminated, 2 = second, etc.).
/// </summary>
public int EliminationRank { get; init; }
/// <summary>
/// Number of players still active after this elimination.
/// </summary>
public int RemainingPlayerCount { get; init; }
}
/// <summary>
/// Event when a single player wins the game.
/// </summary>
public record PlayerWonEvent : GameEvent
{
/// <summary>
/// ID of the winning player.
/// </summary>
public required Guid PlayerId { get; init; }
}
/// <summary>
/// Event when a team wins the game.
/// </summary>
public record TeamWonEvent : GameEvent
{
/// <summary>
/// Name or identifier of the winning team.
/// </summary>
public required string TeamName { get; init; }
/// <summary>
/// IDs of players in the winning team.
/// </summary>
public required IReadOnlyList<Guid> PlayerIds { get; init; }
}
/// <summary>
/// Event when the fox role changes (fox escaped or was caught).
/// </summary>
public record FoxChangedEvent : GameEvent
{
/// <summary>
/// ID of the player who was fox.
/// </summary>
public required Guid FoxPlayerId { get; init; }
/// <summary>
/// True if the fox escaped, false if caught by hunters.
/// </summary>
public bool FoxEscaped { get; init; }
/// <summary>
/// ID of the next fox (null if game is over).
/// </summary>
public Guid? NextFoxPlayerId { get; init; }
}
/// <summary>
/// Event when the game ends (covers any end scenario).
/// </summary>
public record GameEndedEvent : GameEvent
{
/// <summary>
/// Optional winner ID (null for draws or no-winner scenarios).
/// </summary>
public Guid? WinnerId { get; init; }
/// <summary>
/// Optional winning team name.
/// </summary>
public string? WinningTeamName { get; init; }
/// <summary>
/// Whether the game ended in a draw.
/// </summary>
public bool IsDraw { get; init; }
}