protected override ActionContext DoAction(ActionContext context) { if (context.Game == null) { throw new InvalidOperationException("Action context missing required property (Game)"); } GameActionData actionData = MakeActionData(context); Game game = context.Game; if (!game.GameOptions.Contains(GameOption.AssignTurnOrder)) { game.RandomizeTurns(); } if (game.TurnOrder.Length == 2) { game.ScoringTokens[4] = new int[0]; } game.FirstPlayer = game.TurnOrder[0]; game.Status = GameStatus.PlacingFirstTrees; game.AddGameAction(actionData); return(context); }
protected override ActionContext DoAction(ActionContext context) { if (context.Game == null) { throw new InvalidOperationException("Action context missing required property (Game)"); } if (context.PieceType == null) { throw new InvalidOperationException("Action context missing required property (PieceType)"); } GameActionData actionData = MakeActionData(context); Game game = context.Game; PieceType pieceType = (PieceType)context.PieceType; PlayerBoard playerBoard = PlayerBoard.Get(game, context.PlayerId); int price = playerBoard.Pieces(pieceType).NextPrice; playerBoard.SpendLight(price); playerBoard.Pieces(pieceType).DecreaseOnPlayerBoard(); playerBoard.Pieces(pieceType).IncreaseAvailable(); game.SetPlayerBoard(context.PlayerId, playerBoard); context.Game = game; game.AddGameAction(actionData); return(context); }
public override bool CanExecute(AgricolaPlayer player, GameActionData data) { if (!base.CanExecute(player, data)) { return(false); } if (Mode == BuildingResourcesActionMode.DoubleResourceOrFamilyGrowth && ((BuildingResourcesActionData)data).Growth == true) { if (Game.CurrentRound < 5 || !Curator.CanGrowFamily(player)) { return(false); } } else { if (!((BuildingResourcesActionData)data).Resource1.HasValue) { return(false); } if (Mode == BuildingResourcesActionMode.DoubleResource || Mode == BuildingResourcesActionMode.DoubleResourceOrFamilyGrowth) { if (!((BuildingResourcesActionData)data).Resource2.HasValue) { return(false); } } } return(true); }
private async Task <BetCommandResponseTransaction> SettleBet(BetCommandTransactionRequest transaction, Func <GameActionData, GameActionContext, Task <Guid> > settleMethod, string batchId = null) { var isDuplicate = 0; Guid gameActionId; try { var actionData = new GameActionData { RoundId = transaction.RoundId, ExternalTransactionId = transaction.Id, TransactionReferenceId = transaction.ReferenceId, Amount = transaction.Amount, CurrencyCode = transaction.CurrencyCode, Description = transaction.Description, BatchId = batchId, ExternalGameId = transaction.GameId }; gameActionId = await settleMethod(actionData, Context); } catch (DuplicateGameActionException ex) { gameActionId = ex.GameActionId; isDuplicate = 1; } return(new BetCommandResponseTransaction { GameActionId = gameActionId, Id = transaction.Id, IsDuplicate = isDuplicate }); }
public override bool CanExecute(AgricolaPlayer player, GameActionData data) { if (!base.CanExecute(player, data)) { return(false); } var rooms = ((BuildRoomsAndStablesActionData)data).RoomData.ToImmutableArray(); var stables = ((BuildRoomsAndStablesActionData)data).StableData.ToImmutableArray(); if (rooms.Length == 0 && stables.Length == 0 || rooms.Intersect <int>(stables).Count() > 0) { return(false); } if (rooms.Length > 0) { if (!ActionService.CanBuildRooms(player, data.ActionId, rooms)) { return(false); } } if (stables.Length > 0) { if (!ActionService.CanBuildStables(player, stables, Id)) { return(false); } } return(true); }
async Task <Guid> IGameCommands.AdjustTransaction([NotNull] GameActionData actionData, [NotNull] GameActionContext context) { var gameProviderId = await ValidateGameProviderAsync(context.GameProviderCode); ValidateTransactionIsUnique(actionData.ExternalTransactionId, gameProviderId); using (var scope = CustomTransactionScope.GetTransactionScope()) { var round = GetRound(actionData); var gameActionToAdjust = round.GetGameActionByReferenceId(actionData.TransactionReferenceId); if (gameActionToAdjust == null) { throw new GameActionNotFoundException(); } var walletTransactionId = _walletOperations.AdjustBetTransaction(round.Data.PlayerId, round.Data.GameId, gameActionToAdjust.Id, actionData.Amount); var adjustmentGameActionId = AdjustRound(round, actionData, walletTransactionId); _repository.SaveChanges(); await _gameEventsProcessor.Process(round.Events, context.PlayerToken, round.Data.BrandCode, actionData, context.GameProviderCode); scope.Complete(); return(adjustmentGameActionId); } }
public void OnTileClicked(TileBehavior tileClicked) { if (this.selectedAction == null) { if (this.prevTileClicked != null) //todo: && !this.Player.ActionExecuted.Started) { Point destination = tileClicked.Pos; this.EnqueueMovePath(destination); } else { this.prevTileClicked = tileClicked; StartCoroutine(this.RemoveClickedTileAfterDelay()); } return; } if (highlightedTiles.Contains(tileClicked)) { this.ActionExecutor.EnqueueAction(this.Player, this.selectedAction, this.targetTiles.ToArray()); } this.Player.ActionMenu.IsVisible = false; this.selectedAction = null; }
async Task <Guid> IGameCommands.WinBetAsync([NotNull] GameActionData actionData, [NotNull] GameActionContext context) { var gameProviderId = await ValidateGameProviderAsync(context.GameProviderCode); ValidateTransactionIsUnique(actionData.ExternalTransactionId, gameProviderId); using (var scope = CustomTransactionScope.GetTransactionScopeAsync()) { var round = GetRound(actionData); var walletTransactionId = await _walletOperations.WinBetAsync(round.Data.PlayerId, round.Data.GameId, round.Data.Id, actionData.Amount); var winGameActionId = round.Win( actionData.Amount, actionData.Description, walletTransactionId, actionData.ExternalTransactionId, actionData.ExternalBetId, actionData.TransactionReferenceId, actionData.BatchId); await _repository.SaveChangesAsync(); await _gameEventsProcessor.Process(round.Events, context.PlayerToken, round.Data.BrandCode, actionData, context.GameProviderCode); scope.Complete(); return(winGameActionId); } }
/// <summary> /// Places a bet /// </summary> async Task <Guid> IGameCommands.PlaceBetAsync([NotNull] GameActionData gameActionData, [NotNull] GameActionContext context, Guid playerId) { var player = await ValidatePlayer(playerId); await ValidateBrand(player.BrandId); var gameProviderId = await ValidateGameProvider(context.GameProviderCode); ValidateTransactionIsUnique(gameActionData.ExternalTransactionId, gameProviderId); using (var scope = CustomTransactionScope.GetTransactionScopeAsync()) { var game = GetGameByExternalGameId(gameActionData.ExternalGameId); var round = _repository.GetOrCreateRound(gameActionData.RoundId, game.Id, player.Id, player.BrandId); await _walletOperations.PlaceBetAsync(playerId, game.Id, round.Data.Id, gameActionData.Amount, gameActionData.ExternalTransactionId); var placeBetGameActionId = round.Place(gameActionData, context); _repository.Rounds.AddOrUpdate(x => x.ExternalRoundId, round.Data); _repository.SaveChanges(); round.Events.ForEach(ev => _eventBus.Publish(ev)); scope.Complete(); return(placeBetGameActionId); } }
/// <summary> /// Registers a Win bet action /// </summary> /// <param name="gameActionData"></param> /// <param name="context"></param> /// <returns></returns> async Task <Guid> IGameCommands.WinBetAsync([NotNull] GameActionData gameActionData, [NotNull] GameActionContext context) { var gameProviderId = await ValidateGameProvider(context.GameProviderCode); ValidateTransactionIsUnique(gameActionData.ExternalTransactionId, gameProviderId); using (var scope = CustomTransactionScope.GetTransactionScopeAsync()) { var round = GetRound(gameActionData); await _walletOperations.WinBetAsync(round.Data.PlayerId, round.Data.GameId, round.Data.Id, gameActionData.Amount, gameActionData.ExternalTransactionId); var winGameActionId = round.Win(gameActionData, context); await _repository.SaveChangesAsync(); round.Events.ForEach(ev => _eventBus.Publish(ev)); scope.Complete(); return(winGameActionId); } }
public bool EnqueueAction(Character character, GameActionData gameActionData, TileBehavior[] targets) { GameAction gameAction = new GameAction(gameActionData, character, targets); //check if move to not valid target // var moveGameAction = gameAction as MoveGameAction; // if (moveGameAction != null && // (moveGameAction.Target.Character || this.GetActionMovingToTile(target) != null)) // { // return false; // } //check if enough stamina to execute if (character.Stamina < gameActionData.StaminaCost) { return(false); } Debug.LogFormat("EnqueueAction {0} will {1}", character.Name, gameActionData.Name); this.Enqueue(gameAction, character); if (character is Player) { this.Play(); } return(true); }
public override GameAction OnExecute(AgricolaPlayer player, GameActionData data) { base.OnExecute(player, data); ActionService.BuyImprovement(player, (ImprovementActionData)data, ResultingNotices); return(this); }
public override bool CanExecute(AgricolaPlayer player, GameActionData data) { if (!base.CanExecute(player, data)) { return(false); } return(ActionService.CanBuyImprovement(player, (ImprovementActionData)data)); }
protected override ActionContext DoAction(ActionContext context) { if (context.Game == null) { throw new InvalidOperationException("Action context missing required property (Game)"); } if (context.Board == null) { throw new InvalidOperationException("Action context missing required property (Board)"); } GameActionData actionData = MakeActionData(context); Game game = context.Game; Board board = context.Board; string[] turnOrder = game.TurnOrder; game.CurrentTurn++; game.CurrentTurn %= turnOrder.Length; game.turnCount++; game.TilesActiveThisTurn = new int[0]; if (game.FirstPlayer != game.CurrentPlayer) { game.AddGameAction(actionData); return(context); } game.CurrentTurn++; game.CurrentTurn %= turnOrder.Length; game.FirstPlayer = turnOrder[game.CurrentTurn]; game.SunPosition = (SunPosition)(((int)game.SunPosition + 1) % Enum.GetNames(typeof(SunPosition)).Length); if (game.SunPosition == SunPosition.NorthWest) { game.Revolution++; if (game.Revolution == game.LengthOfGame) { game.Status = GameStatus.Ended; game.AddGameAction(actionData); context.Game = game; context.Board = board; return(context); } } board.Tiles = Shadow.UpdateAllShadows(board, game.SunPosition); foreach (string playerId in game.TurnOrder) { PlayerBoard playerBoard = PlayerBoard.Get(game, playerId); int earnedLight = BoardOperations.CountLight(board, playerBoard.TreeType); Console.WriteLine($"{playerId} - {earnedLight}"); playerBoard.RecoverLight(earnedLight); game.SetPlayerBoard(playerId, playerBoard); } game.AddGameAction(actionData); return(context); }
private async Task <int> ProcessBatchSettleTransactionsAsync(BatchSettle request, ConcurrentBag <BatchCommandTransactionError> errorsList) { var txCount = 0; var brands = new ConcurrentDictionary <string, Brand>(); var userGroups = request.Transactions.GroupBy(x => x.UserId); await Task.WhenAll( userGroups.Select(userTransactions => Task.Run(async() => { var commands = _container.Resolve <IGameCommands>(); foreach (var transaction in userTransactions) { try { var betData = new GameActionData { RoundId = transaction.RoundId, TransactionReferenceId = transaction.ReferenceId, ExternalTransactionId = transaction.Id, Amount = transaction.Amount, CurrencyCode = transaction.CurrencyCode, Description = transaction.Description, BatchId = request.BatchId, }; switch (transaction.TransactionType) { case BatchSettleBetTransactionType.Win: await commands.WinBetAsync(betData, Context); break; case BatchSettleBetTransactionType.Lose: await commands.LoseBetAsync(betData, Context); break; case BatchSettleBetTransactionType.Free: await commands.FreeBetAsync(betData, Context); break; case BatchSettleBetTransactionType.Tie: await commands.TieBetAsync(betData, Context); break; } Interlocked.Increment(ref txCount); } catch (Exception ex) { errorsList.Add(CreateBatchTransactionError(ex, transaction.Id, transaction.UserId)); } } }))); return(txCount); }
public override bool CanExecute(AgricolaPlayer player, GameActionData data) { if (!base.CanExecute(player, data)) { return(false); } return(true); }
public Guid Tie(GameActionData gameActionData, GameActionContext context) { ValidateAsSecondaryAction(gameActionData.TransactionReferenceId); var gameActionTransactionId = GenerateGameAction <BetTied>(GameActionType.Tied, gameActionData, context); CloseRound(); return(gameActionTransactionId); }
private Round GetRound(GameActionData gameActionData) { var round = _repository.GetRound(gameActionData.RoundId); if (round == null) { throw new RoundNotFoundException(); } return(round); }
public override Boolean CanExecute(AgricolaPlayer player, GameActionData data) { ImmutableDictionary <string, Object> cardData; if (MaxUses > 0 && player.TryGetCardMetadata(CardId, out cardData) && MaxUses <= (int)cardData["usedCount"]) { return(false); } return(meetsPrerequisites(player)); }
/// <summary> /// Checks if a player can bake. /// </summary> /// <param name="player"></param> /// <param name="data"></param> /// <returns></returns> public override bool CanExecute(AgricolaPlayer player, GameActionData data) { var bakeData = ImmutableArray.Create(((BakeActionData)data).BakeData); if (bakeData == null || bakeData.Length == 0) { return(true); } return(ActionService.CanBake(player, bakeData)); }
private Guid CancelRound(Entities.Round round, decimal amount, GameActionData actionData, Guid walletTxId) { return(round.Cancel( amount, actionData.Description, walletTxId, actionData.ExternalTransactionId, actionData.ExternalBetId, actionData.TransactionReferenceId, actionData.BatchId)); }
private Guid AdjustRound(Entities.Round round, GameActionData actionData, Guid walletTxId) { return(round.Adjust( actionData.Amount, actionData.Description, walletTxId, actionData.ExternalTransactionId, actionData.ExternalBetId, actionData.TransactionReferenceId, actionData.BatchId)); }
private void PushAction(IGameAction gameAction, GameActionData args) { if (InAction) { return; } InAction = true; Target.CurrentAction = gameAction; Target.CurrentAction.Activate(Target, args); }
private void CancelBet(string roundId, decimal amount, string transactionIdToCancel, string gameProviderCode) { var newBet = GameActionData.NewGameActionData(roundId, amount, "CAD"); newBet.TransactionReferenceId = transactionIdToCancel; _gameCommands.CancelTransactionAsync(newBet, new GameActionContext() { GameProviderCode = gameProviderCode }); }
public Guid Win(GameActionData gameActionData, GameActionContext context) { ValidateAsSecondaryAction(gameActionData.TransactionReferenceId); ValidatePositiveAmount(gameActionData.Amount); var gameActionTransactionId = GenerateGameAction <BetWon>(GameActionType.Won, gameActionData, context); CloseRound(); return(gameActionTransactionId); }
public async Task LoseBet(string roundId, string placeBetTxId, string gameProviderCode) { await _gameCommands.LoseBetAsync( GameActionData.NewGameActionData(roundId, 0, "CAD", transactionReferenceId: placeBetTxId), new GameActionContext { GameProviderCode = gameProviderCode }); }
protected override ActionContext DoAction(ActionContext context) { if (context.Game == null) { throw new InvalidOperationException("Action context missing required property (Game)"); } if (context.Board == null) { throw new InvalidOperationException("Action context missing required property (Board)"); } if (context.Origin == null) { throw new InvalidOperationException("Action context missing required property (Origin)"); } if (context.Target == null) { throw new InvalidOperationException("Action context missing required property (Target)"); } GameActionData actionData = MakeActionData(context); Game game = context.Game; Board board = context.Board; Hex origin = context.Origin.Value; string playerId = context.PlayerId; int tileCode = board[origin]; int growingTypeCode = (int)(Tile.GetPieceType(tileCode) ?? 0); int grownTypeCode = growingTypeCode + 1; int price = grownTypeCode; PlayerBoard playerBoard = PlayerBoard.Get(game, playerId); playerBoard.Pieces((PieceType)grownTypeCode).DecreaseAvailable(); int resultingTile = Tile.SetPieceType(tileCode, (PieceType)grownTypeCode); playerBoard.Pieces((PieceType)growingTypeCode).IncreaseOnPlayerBoard(); playerBoard.SpendLight(price); game.SetPlayerBoard(playerId, playerBoard); board[origin] = resultingTile; board.Tiles = Shadow.UpdateAllShadows(board, game.SunPosition); game.TilesActiveThisTurn = game.TilesActiveThisTurn.Where(h => h != origin.HexCode).Append(origin.HexCode).ToArray(); game.AddGameAction(actionData); context.Game = game; context.Board = board; return(context); }
private Guid GenerateGameAction <TEvent>(GameActionType gameActionType, GameActionData gameActionData, GameActionContext context) where TEvent : GameActionEventBase, new() { if (gameActionData.ExternalTransactionId == null) { throw new ArgumentNullException("externalTransactionId"); } var gameActionId = Guid.NewGuid(); var amount = gameActionData.Amount; if (gameActionType == GameActionType.Placed) { amount = -amount; } Data.GameActions.Add(new GameAction { Id = gameActionId, ExternalTransactionId = gameActionData.ExternalTransactionId, ExternalBetId = gameActionData.ExternalBetId, ExternalTransactionReferenceId = gameActionData.TransactionReferenceId, Round = Data, GameActionType = gameActionType, Amount = amount, Description = gameActionData.Description, WalletTransactionId = gameActionData.WalletTransactionId, Timestamp = DateTimeOffset.UtcNow.ToBrandOffset(Data.Brand.TimezoneId), Context = context }); var relatedGameAction = GetGameActionByReferenceId(gameActionData.TransactionReferenceId); Events.Add(new TEvent { Amount = gameActionData.Amount, GameActionId = gameActionId, BrandId = Data.BrandId, GameId = Data.GameId, PlayerId = Data.PlayerId, RoundId = Data.Id, Turnover = context.TurnoverContribution, Ggr = context.GgrContribution, UnsettledBets = context.UnsettledBetsContribution, RelatedGameActionId = relatedGameAction == null? (Guid?)null : relatedGameAction.Id, CreatedOn = DateTimeOffset.UtcNow.ToBrandOffset(Data.Brand.TimezoneId) }); return(gameActionId); }
protected override ActionContext DoAction(ActionContext context) { if (context.Game == null) { throw new InvalidOperationException("Action context missing required property (Game)"); } if (context.Board == null) { throw new InvalidOperationException("Action context missing required property (Board)"); } if (context.Origin == null) { throw new InvalidOperationException("Action context missing required property (Origin)"); } if (context.Target == null) { throw new InvalidOperationException("Action context missing required property (Target)"); } GameActionData actionData = MakeActionData(context); string playerId = context.PlayerId; Game game = context.Game; Board board = context.Board; Hex origin = (Hex)context.Origin; PlayerBoard playerBoard = PlayerBoard.Get(game, playerId); Scoring.Token[] playerScore = game.Scores[playerId]; playerBoard.SpendLight(4); board[origin] = Tile.Empty; playerBoard.Pieces(PieceType.LargeTree).IncreaseOnPlayerBoard(); if (ScoreTokens.Take(game, origin, out Scoring.Token? token)) { if (token != null) { game.Scores[playerId] = playerScore !.Append(token).ToArray(); } } PlayerBoard.Set(game, playerId, playerBoard); board.Tiles = Shadow.UpdateAllShadows(board, game.SunPosition); game.TilesActiveThisTurn = game.TilesActiveThisTurn.Where(h => h != origin.HexCode).Append(origin.HexCode).ToArray(); game.AddGameAction(actionData); return(context); }
public override GameAction OnExecute(AgricolaPlayer player, GameActionData data) { base.OnExecute(player, data); if (data.GetType() == typeof(CacheExchangeData) && ((CacheExchangeData)data).exchanges != null) { var leave = new Dictionary <Resource, int>(); var exchangeData = (CacheExchangeData)data; var gains = new Dictionary <Resource, int>(); foreach (var exchange in exchangeData.exchanges) { if (exchange.Count > 0) { // This only checks the resource conversions. // Currently the activation evetns are only client side. // I was too drunk to write the server side at the time. var conversionDefinition = availableConversions.FirstOrDefault(x => x.Id == exchange.Id && x.InType == exchange.InType && x.InAmount == exchange.InAmount && x.OutType == exchange.OutType); if (!leave.ContainsKey(exchange.InType)) { leave[exchange.InType] = exchange.Count; } else { leave[exchange.InType] += exchange.Count; } var newAmount = (exchange.Count / exchange.InAmount) * conversionDefinition.OutAmount; if (!gains.ContainsKey(exchange.OutType)) { gains[exchange.OutType] = newAmount; } else { gains[exchange.OutType] += newAmount; } } } TakeCaches(player, leave, gains); } else { TakeCaches(player); } return(this); }