Compare commits
2 Commits
4dbc81bef2
...
c249239507
| Author | SHA1 | Date |
|---|---|---|
|
|
c249239507 | |
|
|
2e3b6f8973 |
|
|
@ -122,6 +122,21 @@ namespace GoodWood.Application.Games.FoxHunt
|
|||
|
||||
var nextPlayerId = GetNextId(model, chooseNextFox);
|
||||
|
||||
|
||||
if (chooseNextFox)
|
||||
{
|
||||
gameEvents.Add(new FoxChangedEvent
|
||||
{
|
||||
FoxPlayerId = foxId,
|
||||
FoxEscaped = playerStates[foxId].FoxEscaped,
|
||||
NextFoxPlayerId = nextPlayerId,
|
||||
Message = playerStates[foxId].FoxEscaped
|
||||
? "Fuchs entkommen! Nächster Fuchs ist dran."
|
||||
: "Fuchs gefangen! Nächster Fuchs ist dran."
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
// Check GAME END
|
||||
var isGameOver = model.FoxCountLeft == 0;
|
||||
|
||||
|
|
|
|||
|
|
@ -35,7 +35,8 @@ namespace GoodWood.Application.Games.FoxHunt
|
|||
ThrowMode = throwMode,
|
||||
ThrowsPerRound = throwsPerRound,
|
||||
ParticipantsMode = participantsMode,
|
||||
LeadingThrows = leadingThrows
|
||||
LeadingThrows = leadingThrows,
|
||||
PinCountGoal = pinCountGoal
|
||||
};
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -11,6 +11,7 @@ namespace GoodWood.Application.Games;
|
|||
[JsonDerivedType(typeof(PlayerWonEvent), "PlayerWon")]
|
||||
[JsonDerivedType(typeof(TeamWonEvent), "TeamWon")]
|
||||
[JsonDerivedType(typeof(GameEndedEvent), "GameEnded")]
|
||||
[JsonDerivedType(typeof(FoxChangedEvent), "FoxChanged")]
|
||||
public abstract record GameEvent
|
||||
{
|
||||
/// <summary>
|
||||
|
|
@ -77,6 +78,27 @@ public record TeamWonEvent : GameEvent
|
|||
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>
|
||||
|
|
|
|||
|
|
@ -377,21 +377,22 @@ public class DayService : IDayService
|
|||
if (club.ExpenseCalculation == ExpenseCalculation.None)
|
||||
return;
|
||||
|
||||
// 3. Get all PersonExpense prices for this day
|
||||
var dayExpensePrices = await context.PersonExpenses
|
||||
// 3. Get total expenses per participant for this day
|
||||
var personExpenseTotals = await context.PersonExpenses
|
||||
.Where(pe => pe.DayId == dayId && !pe.IsDeleted)
|
||||
.Select(pe => pe.Price)
|
||||
.GroupBy(pe => pe.PersonId)
|
||||
.Select(g => g.Sum(pe => pe.Price))
|
||||
.ToListAsync(ct);
|
||||
|
||||
// 4. Edge case: No expenses - skip
|
||||
if (dayExpensePrices.Count == 0)
|
||||
if (personExpenseTotals.Count == 0)
|
||||
return;
|
||||
|
||||
// 5. Calculate price
|
||||
// 5. Calculate price based on per-person totals
|
||||
decimal calculatedPrice = club.ExpenseCalculation switch
|
||||
{
|
||||
ExpenseCalculation.Average => Math.Round(dayExpensePrices.Average(), 2),
|
||||
ExpenseCalculation.Maximum => dayExpensePrices.Max(),
|
||||
ExpenseCalculation.Average => Math.Round(personExpenseTotals.Average(), 2),
|
||||
ExpenseCalculation.Maximum => personExpenseTotals.Max(),
|
||||
_ => 0m
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -109,6 +109,7 @@
|
|||
var setup = new FoxHuntGameSetup
|
||||
{
|
||||
LeadingThrows = _options.LeadingThrows,
|
||||
PinCountGoal = _options.PinCountGoal,
|
||||
ParticipantsMode = _options.ParticipantsMode
|
||||
};
|
||||
await OnOptionsChanged.InvokeAsync(setup);
|
||||
|
|
|
|||
|
|
@ -34,6 +34,11 @@
|
|||
<MudText Typo="Typo.h4" Color="Color.Warning">Spiel beendet!</MudText>
|
||||
<MudText Typo="Typo.h5">@GameEndedMessage</MudText>
|
||||
}
|
||||
else if (!string.IsNullOrEmpty(FoxChangedMessage))
|
||||
{
|
||||
<MudIcon Icon="@Icons.Material.Filled.Pets" Color="Color.Info" Size="Size.Large" Style="font-size: 4rem;" />
|
||||
<MudText Typo="Typo.h5">@FoxChangedMessage</MudText>
|
||||
}
|
||||
else if (EliminatedPlayers.Count > 0)
|
||||
{
|
||||
<MudIcon Icon="@Icons.Material.Filled.PersonOff" Color="Color.Error" Size="Size.Large" Style="font-size: 4rem;" />
|
||||
|
|
@ -83,5 +88,8 @@
|
|||
[Parameter]
|
||||
public string? GameEndedMessage { get; set; }
|
||||
|
||||
[Parameter]
|
||||
public string? FoxChangedMessage { get; set; }
|
||||
|
||||
private void Close() => MudDialog.Close(DialogResult.Ok(true));
|
||||
}
|
||||
|
|
|
|||
|
|
@ -50,6 +50,7 @@
|
|||
string? winningTeamName = null;
|
||||
string? winningTeamMessage = null;
|
||||
string? gameEndedMessage = null;
|
||||
string? foxChangedMessage = null;
|
||||
|
||||
foreach (var evt in newEvents)
|
||||
{
|
||||
|
|
@ -69,11 +70,14 @@
|
|||
case GameEndedEvent ended when ended.WinnerId == null && string.IsNullOrEmpty(ended.WinningTeamName):
|
||||
gameEndedMessage = ended.Message ?? "Spiel beendet ohne Sieger";
|
||||
break;
|
||||
case FoxChangedEvent foxChanged:
|
||||
foxChangedMessage = foxChanged.Message;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Only show dialog if there's something to show
|
||||
if (eliminatedPlayers.Count == 0 && winnerName == null && winningTeamName == null && gameEndedMessage == null)
|
||||
if (eliminatedPlayers.Count == 0 && winnerName == null && winningTeamName == null && gameEndedMessage == null && foxChangedMessage == null)
|
||||
{
|
||||
_isShowingDialog = false;
|
||||
return;
|
||||
|
|
@ -87,7 +91,8 @@
|
|||
{ x => x.WinnerMessage, winnerMessage },
|
||||
{ x => x.WinningTeamName, winningTeamName },
|
||||
{ x => x.WinningTeamMessage, winningTeamMessage },
|
||||
{ x => x.GameEndedMessage, gameEndedMessage }
|
||||
{ x => x.GameEndedMessage, gameEndedMessage },
|
||||
{ x => x.FoxChangedMessage, foxChangedMessage }
|
||||
};
|
||||
|
||||
var options = new DialogOptions
|
||||
|
|
@ -101,7 +106,9 @@
|
|||
|
||||
var title = (action.IsGameOver && (winnerName != null || winningTeamName != null)) || gameEndedMessage != null
|
||||
? "Spiel beendet!"
|
||||
: "Spieler ausgeschieden!";
|
||||
: foxChangedMessage != null
|
||||
? "Fuchswechsel!"
|
||||
: "Spieler ausgeschieden!";
|
||||
|
||||
await InvokeAsync(async () =>
|
||||
{
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
@using GoodWood.Domain.Enums
|
||||
|
||||
<div class="pin @GetPinClass()" @onclick="OnClick" style="@GetStyle()">
|
||||
<span class="pin-number">@PinNumber</span>
|
||||
<span class="pin-number"></span>
|
||||
</div>
|
||||
|
||||
<style>
|
||||
|
|
|
|||
|
|
@ -30,13 +30,15 @@
|
|||
<MudSelect T="int" @bind-Value="_selectedMonth" Label="Monat" Style="width: 150px;">
|
||||
@for (int m = 1; m <= 12; m++)
|
||||
{
|
||||
<MudSelectItem Value="@m">@GetMonthName(m)</MudSelectItem>
|
||||
var month = m;
|
||||
<MudSelectItem Value="@month">@GetMonthName(month)</MudSelectItem>
|
||||
}
|
||||
</MudSelect>
|
||||
<MudSelect T="int" @bind-Value="_selectedYear" Label="Jahr" Style="width: 120px;">
|
||||
@for (int y = DateTime.Today.Year; y >= DateTime.Today.Year - 5; y--)
|
||||
{
|
||||
<MudSelectItem Value="@y">@y</MudSelectItem>
|
||||
var year = y;
|
||||
<MudSelectItem Value="@year">@year</MudSelectItem>
|
||||
}
|
||||
</MudSelect>
|
||||
<MudButton Variant="Variant.Filled" Color="Color.Primary" StartIcon="@Icons.Material.Filled.Refresh"
|
||||
|
|
|
|||
Loading…
Reference in New Issue