public int GetAvailableManaNextTurn(bool considerCoin) { var opponentEntity = _game.OpponentEntity; if (opponentEntity == null) { Log.Debug("Cannot query mana when opponent entity does not exist"); return(-1); } bool hasCoin; if (_game.GetTurnNumber() == 0) { // During the mulligan, the coin doesn't exist, but second player will get it next turn. hasCoin = !opponentEntity.HasTag(GameTag.FIRST_PLAYER); } else { hasCoin = _opponent.HasCoin; } var crystals = opponentEntity.GetTag(GameTag.RESOURCES); var overload = opponentEntity.GetTag(GameTag.OVERLOAD_OWED); var coinBonus = (considerCoin && hasCoin) ? 1 : 0; // Add one mana for next turn. var mana = crystals - overload + coinBonus + 1; return(Math.Min(Math.Max(mana, 0), 10)); }
internal void TurnStart(ActivePlayer player) { if (!_isMulliganDone) { _game.Process(ChooseTask.Mulligan(_game.Player1, _toBeKept)); _game.Process(ChooseTask.Mulligan(_game.Player2, _game.Player2.Choice.Choices)); } _isMulliganDone = true; _isNewTurn = true; _activePlayer = player; _numberOfTurns++; if (_numberOfTurns > 1) { ProcessPlayerAction(); _game.MainEnd(); _game.MainNext(); } GameV2 gameV2 = Core.Game; if (player == ActivePlayer.Player) { _messenger.Reset(); _messenger.SetTitle("Turn " + gameV2.GetTurnNumber()); } Converter.AreGamesInSync(_game, gameV2); }
public static async void ShoppingStarted(GameV2 game) { if (game.GetTurnNumber() <= 1) { ResetOpponentDeadForTracker(); } for (int i = 0; i < _deadTracker.Count; i++) { _deadTracker[i]++; } var deadHeroes = game.Entities.Values.Where(x => x.IsHero && x.Health <= 0); foreach (var hero in deadHeroes) { var id = BattlegroundsBoardState.GetCorrectBoardstateHeroId(hero.CardId); if (!id.Contains(KelThuzadCardId) && !_uniqueDeadHeroes.Contains(id)) { _deadTracker.Add(0); _uniqueDeadHeroes.Add(id); } } _deadTracker.Sort((x, y) => y.CompareTo(x)); Core.Overlay.UpdateOpponentDeadForTurns(_deadTracker); var gameEntites = game.Entities.Values; var currentPlayer = gameEntites.FirstOrDefault(x => x.IsCurrentPlayer); //We loop because the next opponent tag is set slightly after the start of shopping (when this function is called). for (int i = 0; i < 5; i++) { if (currentPlayer != null && currentPlayer.HasTag(GameTag.NEXT_OPPONENT_PLAYER_ID)) { var nextOpponent = gameEntites.FirstOrDefault(x => x.GetTag(GameTag.PLAYER_ID) == currentPlayer.GetTag(GameTag.NEXT_OPPONENT_PLAYER_ID)); if (nextOpponent != null) { var leaderboardPlace = nextOpponent.GetTag(GameTag.PLAYER_LEADERBOARD_PLACE); if (leaderboardPlace >= 0 && leaderboardPlace < 8) { Core.Overlay.PositionDeadForText(leaderboardPlace); } } } await Task.Delay(NextOpponentCheckDelay); } }
public int GetTurnNumber() { return(_game.GetTurnNumber()); }
#pragma warning disable 4014 public async void HandleGameEnd() { try { if (_game.CurrentGameStats == null || _handledGameEnd) { Log.Warn("HandleGameEnd was already called."); return; } _handledGameEnd = true; TurnTimer.Instance.Stop(); Core.Overlay.HideTimers(); DeckManager.ResetAutoSelectCount(); LiveDataManager.Stop(); Log.Info("Game ended..."); _game.InvalidateMatchInfoCache(); if (_game.CurrentGameMode == Spectator && _game.CurrentGameStats.Result == GameResult.None) { Log.Info("Game was spectator mode without a game result. Probably exited spectator mode early."); return; } var player = _game.Entities.FirstOrDefault(e => e.Value?.IsPlayer ?? false).Value; var opponent = _game.Entities.FirstOrDefault(e => e.Value != null && e.Value.HasTag(PLAYER_ID) && !e.Value.IsPlayer).Value; if (player != null) { _game.CurrentGameStats.PlayerName = player.Name; _game.CurrentGameStats.Coin = !player.HasTag(FIRST_PLAYER); } if (opponent != null && CardIds.HeroIdDict.ContainsValue(_game.CurrentGameStats.OpponentHero)) { _game.CurrentGameStats.OpponentName = opponent.Name; } else { _game.CurrentGameStats.OpponentName = _game.CurrentGameStats.OpponentHero; } _game.CurrentGameStats.Turns = _game.GetTurnNumber(); if (Config.Instance.DiscardZeroTurnGame && _game.CurrentGameStats.Turns < 1) { Log.Info("Game has 0 turns, discarded. (DiscardZeroTurnGame)"); _assignedDeck = null; GameEvents.OnGameEnd.Execute(); return; } _game.CurrentGameStats.GameMode = _game.CurrentGameMode; _game.CurrentGameStats.Format = _game.CurrentFormat; Log.Info("Format: " + _game.CurrentGameStats.Format); if (_game.CurrentGameMode == Ranked && _game.MatchInfo != null) { var wild = _game.CurrentFormat == Format.Wild; _game.CurrentGameStats.Rank = wild ? _game.MatchInfo.LocalPlayer.WildRank : _game.MatchInfo.LocalPlayer.StandardRank; _game.CurrentGameStats.OpponentRank = wild ? _game.MatchInfo.OpposingPlayer.WildRank : _game.MatchInfo.OpposingPlayer.StandardRank; _game.CurrentGameStats.LegendRank = wild ? _game.MatchInfo.LocalPlayer.WildLegendRank : _game.MatchInfo.LocalPlayer.StandardLegendRank; _game.CurrentGameStats.OpponentLegendRank = wild ? _game.MatchInfo.OpposingPlayer.WildLegendRank : _game.MatchInfo.OpposingPlayer.StandardLegendRank; _game.CurrentGameStats.Stars = wild ? _game.MatchInfo.LocalPlayer.WildStars : _game.MatchInfo.LocalPlayer.StandardStars; } else if (_game.CurrentGameMode == Arena) { _game.CurrentGameStats.ArenaWins = DeckImporter.ArenaInfoCache?.Wins ?? 0; _game.CurrentGameStats.ArenaLosses = DeckImporter.ArenaInfoCache?.Losses ?? 0; } else if (_game.CurrentGameMode == Brawl && _game.BrawlInfo != null) { _game.CurrentGameStats.BrawlWins = _game.BrawlInfo.Wins; _game.CurrentGameStats.BrawlLosses = _game.BrawlInfo.Losses; } _game.CurrentGameStats.GameType = _game.CurrentGameType; _game.CurrentGameStats.ServerInfo = _game.MetaData.ServerInfo; _game.CurrentGameStats.PlayerCardbackId = _game.MatchInfo?.LocalPlayer.CardBackId ?? 0; _game.CurrentGameStats.OpponentCardbackId = _game.MatchInfo?.OpposingPlayer.CardBackId ?? 0; _game.CurrentGameStats.FriendlyPlayerId = _game.MatchInfo?.LocalPlayer.Id ?? 0; _game.CurrentGameStats.ScenarioId = _game.MatchInfo?.MissionId ?? 0; _game.CurrentGameStats.BrawlSeasonId = _game.MatchInfo?.BrawlSeasonId ?? 0; _game.CurrentGameStats.RankedSeasonId = _game.MatchInfo?.RankedSeasonId ?? 0; var confirmedCards = _game.Player.RevealedCards.Where(x => x.Collectible) .Concat(_game.Player.KnownCardsInDeck.Where(x => x.Collectible && !x.IsCreated)) .ToList(); if (_game.CurrentSelectedDeck != null && _game.CurrentSelectedDeck.Id > 0) { _game.CurrentGameStats.HsDeckId = _game.CurrentSelectedDeck.Id; _game.CurrentGameStats.SetPlayerCards(_game.CurrentSelectedDeck, confirmedCards); } else { _game.CurrentGameStats.HsDeckId = DeckList.Instance.ActiveDeckVersion?.HsId ?? 0; _game.CurrentGameStats.SetPlayerCards(DeckList.Instance.ActiveDeckVersion, confirmedCards); } _game.CurrentGameStats.SetOpponentCards(_game.Opponent.OpponentCardList.Where(x => !x.IsCreated).ToList()); _game.CurrentGameStats.GameEnd(); GameEvents.OnGameEnd.Execute(); _game.CurrentSelectedDeck = null; var selectedDeck = DeckList.Instance.ActiveDeck; if (selectedDeck != null) { var revealed = _game.Player.RevealedEntities.Where(x => x != null).ToList(); if (Config.Instance.DiscardGameIfIncorrectDeck && !revealed.Where(x => x.IsPlayableCard && !x.Info.Created && !x.Info.Stolen && x.Card.Collectible) .GroupBy(x => x.CardId).All(x => selectedDeck.GetSelectedDeckVersion().Cards.Any(c2 => x.Key == c2.Id && x.Count() <= c2.Count))) { if (Config.Instance.AskBeforeDiscardingGame) { var discardDialog = new DiscardGameDialog(_game.CurrentGameStats) { Topmost = true }; discardDialog.ShowDialog(); if (discardDialog.Result == DiscardGameDialogResult.Discard) { Log.Info("Assigned current game to NO deck - selected deck does not match cards played (dialogresult: discard)"); _assignedDeck = null; return; } if (discardDialog.Result == DiscardGameDialogResult.MoveToOther) { var moveDialog = new MoveGameDialog(DeckList.Instance.Decks.Where(d => d.Class == _game.CurrentGameStats.PlayerHero)) { Topmost = true }; moveDialog.ShowDialog(); var targetDeck = moveDialog.SelectedDeck; if (targetDeck != null) { selectedDeck = targetDeck; _game.CurrentGameStats.PlayerDeckVersion = moveDialog.SelectedVersion; //...continue as normal } else { Log.Info("No deck selected in move game dialog after discard dialog, discarding game"); _assignedDeck = null; return; } } } else { Log.Info("Assigned current game to NO deck - selected deck does not match cards played (no dialog)"); _assignedDeck = null; return; } } else { _game.CurrentGameStats.PlayerDeckVersion = selectedDeck.GetSelectedDeckVersion().Version; } _lastGame = _game.CurrentGameStats; selectedDeck.DeckStats.AddGameResult(_lastGame); if (Config.Instance.ArenaRewardDialog && (selectedDeck.IsArenaRunCompleted ?? false)) { if (selectedDeck.ArenaReward.Packs[0] == ArenaRewardPacks.None) { selectedDeck.ArenaReward.Packs[0] = Enum.GetValues(typeof(ArenaRewardPacks)).OfType <ArenaRewardPacks>().Max(); } _arenaRewardDialog = new ArenaRewardDialog(selectedDeck); } if (Config.Instance.ShowNoteDialogAfterGame && !Config.Instance.NoteDialogDelayed && !_showedNoteDialog) { _showedNoteDialog = true; new NoteDialog(_game.CurrentGameStats); } Log.Info("Assigned current game to deck: " + selectedDeck.Name); _assignedDeck = selectedDeck; // Unarchive the active deck after we have played a game with it if (_assignedDeck.Archived) { Log.Info("Automatically unarchiving deck " + selectedDeck.Name + " after assigning current game"); Core.MainWindow.ArchiveDeck(_assignedDeck, false); } _lastGame = null; } else { try { DefaultDeckStats.Instance.GetDeckStats(_game.Player.Class).AddGameResult(_game.CurrentGameStats); Log.Info($"Assigned current deck to default {_game.Player.Class} deck."); } catch (Exception ex) { Log.Error("Error saving to DefaultDeckStats: " + ex); } _assignedDeck = null; } if (_game.StoredGameStats != null) { _game.CurrentGameStats.StartTime = _game.StoredGameStats.StartTime; } await SaveReplays(); if (Config.Instance.ShowGameResultNotifications && RecordCurrentGameMode) { var deckName = _assignedDeck == null ? "No deck - " + _game.CurrentGameStats.PlayerHero : _assignedDeck.NameAndVersion; ToastManager.ShowGameResultToast(deckName, _game.CurrentGameStats); } } catch (Exception ex) { Log.Error(ex); } }