public async Task <IActionResult> PlayCard(Guid gameId, [FromBody] DtoPlayCardMove move) { var result = await this.gamesService.PlayCard(gameId, move).ConfigureAwait(false); return(this.utility.GetActionResult(result)); }
public async Task <VoidAppResult> PlayCard(Guid gameId, DtoPlayCardMove move, CancellationToken cancellationToken = default(CancellationToken)) { var game = await this.dbContext.Games.IncludeUserParticipations().IncludeEntities().SingleOrDefaultAsync(_ => _.Id == gameId, cancellationToken); if (game == null) { return(VoidAppResult.Error(ErrorPreset.OnLoadingData)); } var currentTurnPlayerResult = await this.GetCurrentTurnPlayer(game, cancellationToken); if (currentTurnPlayerResult.IsErrorResult) { return(currentTurnPlayerResult.GetVoidAppResult()); } var currentTurnPlayer = currentTurnPlayerResult.SuccessReturnValue; var playedGameCard = await this.dbContext.GameCards.IncludeCards().SingleOrDefaultAsync(_ => _.Id == move.CardId); if (playedGameCard == null || playedGameCard.CardLocation != CardLocation.Hand) { return(VoidAppResult.Error(AppActionResultType.RuleError, "Selected card cannot be played.")); } if (currentTurnPlayer.Mail != this.loginManager.LoggedInUser.Mail) { return(VoidAppResult.Error(ErrorPreset.NotYourTurn)); } if (game.UserParticipations.All(_ => _.Mail != this.loginManager.LoggedInUser.Mail)) { return(VoidAppResult.Error(ErrorPreset.NotAParticipant)); } playedGameCard.CardLocation = CardLocation.Board; // Discard cards if (playedGameCard.Card.Cost != move.DiscardedCardIds.Count) { return(VoidAppResult.Error(AppActionResultType.RuleError, $"You must discard exactly {playedGameCard.Card.Cost} cards.")); } foreach (var entityId in move.DiscardedCardIds) { var gameCard = game.Entities.SingleOrDefault(_ => _.Id == entityId) as GameCard; if (gameCard == null || gameCard.CardLocation != CardLocation.Hand) { return(VoidAppResult.Error(AppActionResultType.RuleError, "The selected card cannot be discarded.")); } gameCard.CardLocation = CardLocation.OutOfPlay; } // Execute effects foreach (var effect in move.EffectTargets) { var executeEffectResult = await this.effectsService.ExecuteEffect(effect, game, currentTurnPlayer, cancellationToken); if (executeEffectResult.IsErrorResult) { return(executeEffectResult); } } await dbContext.SaveChangesAsync(cancellationToken); return(VoidAppResult.Success()); }