private IEnumerator DealDamageResponse(PlayCardAction pc) { //this card deals that Hero Character 1 sonic damage. List <Card> results = new List <Card>(); IEnumerator coroutine = base.FindCharacterCardToTakeDamage(pc.TurnTakerController.TurnTaker, results, Card, 1, DamageType.Sonic); if (base.UseUnityCoroutines) { yield return(base.GameController.StartCoroutine(coroutine)); } else { base.GameController.ExhaustCoroutine(coroutine); } coroutine = base.DealDamage(base.Card, results.First(), 1, DamageType.Sonic, cardSource: base.GetCardSource()); if (base.UseUnityCoroutines) { yield return(base.GameController.StartCoroutine(coroutine)); } else { base.GameController.ExhaustCoroutine(coroutine); } yield break; }
/// <summary> /// /// </summary> /// <param name="action"></param> /// <param name="player"></param> /// <param name="playerCanCastSorceries"></param> private void PlayCard(PlayCardAction action, Player player, bool playerCanCastSorceries) { // If it's a land card, it bypasses the stack if (action.Card.IsALand) { // Only play the land if the player is allowed to play a turn right now if (playerCanCastSorceries && player.LandsPlayedThisTurn < player.MaxLandsPlayedThisTurn) { PlayLand(action.Card); player.LandsPlayedThisTurn++; CardHasChangedZones?.Invoke(this, action.Card, Common.Enums.Zone.Stack, Common.Enums.Zone.Battlefield); } } else { // Make player pay the cost of the Card if (action.Card.Cost.Pay()) { // Put the Card onto the stack action.Card.OnCast?.Invoke(this, action.Card); player.Hand.Remove(action.Card); PushOntoStack(action.Card, Common.Enums.Zone.Hand); } } CheckStateBasedActions(); }
public static void Postfix(PlayCardAction __instance) { if (!Configuration.Bombagan.PlayerRoundEndAuto) { return; } if (__instance.Board.Mode == ABBG.ABBG.Mode.Tutorial) { return; } if (__instance.Board.Side != Board.PlayerType.Hero) { return; } Validator validator = __instance.Board.Validator; foreach (Card card in __instance.Board.GetCards(Board.LocationType.PlayerHand)) { validator.SetCard(card); if (validator.CanPlayCard() == 0) { validator.Reset(); return; } } validator.Reset(); __instance.Board.Main.AddCommand(new NextTurnCommand()); }
private IEnumerator DealDamageResponse(PlayCardAction pca) { List <Card> result = new List <Card>(); IEnumerator coroutine = base.FindCharacterCardToTakeDamage(pca.TurnTakerController.TurnTaker, result, Card, 2, DamageType.Lightning); if (base.UseUnityCoroutines) { yield return(base.GameController.StartCoroutine(coroutine)); } else { base.GameController.ExhaustCoroutine(coroutine); } var target = result.FirstOrDefault(); if (target != null) { coroutine = DealDamage(Card, target, 2, DamageType.Lightning, cardSource: GetCardSource()); if (base.UseUnityCoroutines) { yield return(base.GameController.StartCoroutine(coroutine)); } else { base.GameController.ExhaustCoroutine(coroutine); } } }
public IEnumerator EnteringTerrainSequenceResponse(PlayCardAction pca) { // "Whenever a Terrain card enters play, destroy all other Terrain cards and all environment cards..." Card newTerrain = pca.CardToPlay; IEnumerator destroyCoroutine = base.GameController.DestroyCards(this.DecisionMaker, new LinqCardCriteria((Card c) => (c.DoKeywordsContain("terrain") || c.IsEnvironment) && c != newTerrain), cardSource: GetCardSource()); if (base.UseUnityCoroutines) { yield return(this.GameController.StartCoroutine(destroyCoroutine)); } else { this.GameController.ExhaustCoroutine(destroyCoroutine); } // "... then play the top card of the environment deck." IEnumerator playEnvironmentCoroutine = PlayTheTopCardOfTheEnvironmentDeckResponse(pca); if (base.UseUnityCoroutines) { yield return(this.GameController.StartCoroutine(playEnvironmentCoroutine)); } else { this.GameController.ExhaustCoroutine(playEnvironmentCoroutine); } yield break; }
public override void Enter() { base.Enter(); var action = new PlayCardAction(owner.activeCardView.card); owner.game.Perform(action); owner.stateMachine.ChangeState <ResetState> (); }
private IEnumerator AugmentTargetResponse(PlayCardAction action) { //When a villain target enters play, flip {SwarmEater}'s villain character cards. IEnumerator coroutine = base.GameController.FlipCard(this, cardSource: base.GetCardSource()); if (base.UseUnityCoroutines) { yield return(base.GameController.StartCoroutine(coroutine)); } else { base.GameController.ExhaustCoroutine(coroutine); } List <RevealCardsAction> storedResult = new List <RevealCardsAction>(); //When {SwarmEater} flips to this side, discard cards from the top of the villain deck until a target is discarded. coroutine = base.GameController.RevealCards(base.TurnTakerController, base.TurnTaker.Deck, (Card c) => this.IsNanomutant(c), 1, storedResult, RevealedCardDisplay.ShowMatchingCards, base.GetCardSource()); if (base.UseUnityCoroutines) { yield return(base.GameController.StartCoroutine(coroutine)); } else { base.GameController.ExhaustCoroutine(coroutine); } //Put the discarded target beneath the villain target that just entered play. coroutine = base.GameController.MoveCard(base.TurnTakerController, storedResult.FirstOrDefault().RevealedCards.LastOrDefault(), action.CardToPlay.UnderLocation); if (base.UseUnityCoroutines) { yield return(base.GameController.StartCoroutine(coroutine)); } else { base.GameController.ExhaustCoroutine(coroutine); } coroutine = base.CleanupRevealedCards(base.TurnTaker.Revealed, base.TurnTaker.Trash); if (base.UseUnityCoroutines) { yield return(base.GameController.StartCoroutine(coroutine)); } else { base.GameController.ExhaustCoroutine(coroutine); } //Then flip {SwarmEater}'s character cards. coroutine = base.GameController.FlipCard(this, cardSource: base.GetCardSource()); if (base.UseUnityCoroutines) { yield return(base.GameController.StartCoroutine(coroutine)); } else { base.GameController.ExhaustCoroutine(coroutine); } }
protected virtual ActionBase PlayCardsToField() { // Get all available cards... List <HRCard> availableCards = HRCard.GetCards(HRPlayer.GetLocalPlayer(), HRCardZone.HAND); if (availableCards.Count > 0) { HRCard coin = null; foreach (var item in availableCards) { #region Skip The Coin string cardID = item.GetEntity().GetCardId(); if (cardID == "GAME_005" || cardID == "GAME_005e") { coin = item; continue; } #endregion if (item.GetEntity().GetCost() <= HRPlayer.GetLocalPlayer().GetNumAvailableResources()) { if (HRBattle.CanUseCard(item.GetEntity()) && HRCardManager.IsCardAllowedByRule(item)) { return(new PlayCardAction(item)); } } } #region The Coin Feature // Feature: The Coin // https://github.com/juce-mmocrawlerbots/HREngine/issues/13 if (coin != null) { foreach (var card in availableCards) { if (card.GetEntity().GetCardId() != coin.GetEntity().GetCardId()) { if (card.GetEntity().IsMinion() || card.GetEntity().IsSpell() || (!HRPlayer.GetLocalPlayer().HasWeapon() && card.GetEntity().IsWeapon())) { if (card.GetEntity().GetCost() <= (HRPlayer.GetLocalPlayer().GetNumAvailableResources() + 1)) { HRLog.Write( String.Format("Spawn [{0}] and then [{1}]", coin.GetEntity().GetName(), card.GetEntity().GetName())); NextFixedAction = new PlayCardAction(card); return(new PlayCardAction(coin)); } } } } } #endregion } return(null); }
public override IEnumerator UsePower(int index = 0) { IEnumerator dealFire; int powerNumeral = base.GetPowerNumeral(0, 1); List <MoveCardAction> storedResults = new List <MoveCardAction>(); IEnumerator discardTopCard = base.GameController.DiscardTopCard(this.TurnTaker.Deck, storedResults, null, base.TurnTaker, GetCardSource(null)); if (base.UseUnityCoroutines) { yield return(base.GameController.StartCoroutine(discardTopCard)); } else { base.GameController.ExhaustCoroutine(discardTopCard); } MoveCardAction moveCard = storedResults.FirstOrDefault <MoveCardAction>(); if (moveCard != null && moveCard.CardToMove != null && moveCard.CardToMove.IsOneShot) { List <PlayCardAction> playedCard = new List <PlayCardAction>(); IEnumerator mayPlayCard = base.GameController.PlayCard(this.DecisionMaker, moveCard.CardToMove, true, null, true, null, null, false, null, playedCard, null, false, false, true, GetCardSource(null)); if (base.UseUnityCoroutines) { yield return(base.GameController.StartCoroutine(mayPlayCard)); } else { base.GameController.ExhaustCoroutine(mayPlayCard); } PlayCardAction playCard = playedCard.FirstOrDefault <PlayCardAction>(); if (playCard == null) { dealFire = base.GameController.DealDamage(this.DecisionMaker, base.CharacterCard, (Card c) => !c.IsHero && c.IsTarget && c.IsInPlayAndHasGameText, powerNumeral, DamageType.Fire, false, false, null, null, null, false, null, null, false, false, GetCardSource(null)); if (base.UseUnityCoroutines) { yield return(base.GameController.StartCoroutine(dealFire)); } else { base.GameController.ExhaustCoroutine(dealFire); } } } else { dealFire = base.GameController.DealDamage(this.DecisionMaker, base.CharacterCard, (Card c) => !c.IsHero && c.IsTarget && c.IsInPlayAndHasGameText, powerNumeral, DamageType.Fire, false, false, null, null, null, false, null, null, false, false, GetCardSource(null)); if (base.UseUnityCoroutines) { yield return(base.GameController.StartCoroutine(dealFire)); } else { base.GameController.ExhaustCoroutine(dealFire); } } yield break; }
public void OnClickNotification(object sender, object args) { var gameStateMachine = InputSystem.Game.GetSystem <StateMachine>(); var cardSystem = InputSystem.Game.GetSystem <CardSystem>(); if (!(gameStateMachine.CurrentState is PlayerIdleState)) { return; } var clickable = (Clickable)sender; var cardView = clickable.GetComponent <CardView>(); if (cardView == null) { return; } var playerOwnsCard = cardView.Card.Owner.Index == InputSystem.Game.Match.CurrentPlayerIndex; var cardInHand = cardView.Card.Zone == Zones.Hand; var clickData = (PointerEventData)args; if (clickData.button == PointerEventData.InputButton.Right) { if (playerOwnsCard && cardInHand || cardView.Card.Zone.IsInBoard()) { gameStateMachine.ChangeState <PlayerInputState>(); InputSystem.ActiveCard = cardView; InputSystem.StateMachine.ChangeState <PreviewState>(); } } else if (clickData.button == PointerEventData.InputButton.Left) { // TODO: Handle cases like activating a card's effect here (?) if (playerOwnsCard && cardInHand) { InputSystem.ActiveCard = cardView; if (cardView.Card.GetAttribute <ManualTarget>() != null && cardSystem.IsPlayable(cardView.Card)) { InputSystem.StateMachine.ChangeState <TargetingState>(); } else { var action = new PlayCardAction(cardView.Card); InputSystem.Game.Perform(action); InputSystem.StateMachine.ChangeState <ResetState>(); } } } }
private void ValidateAbilityTarget(PlayCardAction action, Validator validator) { var ability = action.Card.GetAttributes <Ability>().SingleOrDefault(a => a.Type == AbilityType.WhenPlayed); if (ability != null && ability.TargetSelector != null) { if (!ability.TargetSelector.HasEnoughTargets(Container, action.Card)) { validator.Invalidate("Not enough valid targets"); } } }
public async static Task PlayCard(PlayCardAction action) { var values = new { GameState.gameId, playerId = GameState.mainPlayerId, action.cardId, action.x, action.y }; await HttpRequest.Post(Config.GAME_SERVER_URL + "playCard", values); }
private IEnumerator RefillRiverbankResponse(PlayCardAction p) { IEnumerator coroutine = RefillRiverbankResponseHelper(); if (this.UseUnityCoroutines) { yield return(this.GameController.StartCoroutine(coroutine)); } else { this.GameController.ExhaustCoroutine(coroutine); } }
public void Refresh() { var match = container.GetMatch(); playable.Clear(); foreach (Card card in match.CurrentPlayer[Zones.Hand]) { var playAction = new PlayCardAction(card); if (playAction.Validate()) { playable.Add(card); } } }
private IEnumerator GainHPResponse(PlayCardAction pca) { // "Whenever a player plays a hero card, if it's a One-Shot, their hero regains 2 HP. If not, 1 non-Terrain villain target with less than its maximum HP regains 2 HP." if (pca.WasCardPlayed) { if (pca.CardToPlay.DoKeywordsContain("one-shot")) { // "... their hero regains 2 HP." HeroTurnTakerController playing = pca.TurnTakerController.ToHero(); TurnTaker player = pca.TurnTakerController.TurnTaker; List <Card> resultsHeroCharacter = new List <Card>(); // The player chooses one of their hero characters to regain HP (stored in resultsHeroCharacter) IEnumerator chooseHeroCoroutine = base.FindCharacterCard(player, SelectionType.GainHP, resultsHeroCharacter); if (base.UseUnityCoroutines) { yield return(this.GameController.StartCoroutine(chooseHeroCoroutine)); } else { this.GameController.ExhaustCoroutine(chooseHeroCoroutine); } // That hero regains 2 HP IEnumerator healHeroCoroutine = base.GameController.GainHP(resultsHeroCharacter.First(), 2, cardSource: GetCardSource()); if (base.UseUnityCoroutines) { yield return(this.GameController.StartCoroutine(healHeroCoroutine)); } else { this.GameController.ExhaustCoroutine(healHeroCoroutine); } } else { // "... 1 non-Terrain villain target with less than its maximum HP regains 2 HP." IEnumerator healVillainCoroutine = base.GameController.SelectAndGainHP(base.DecisionMaker, 2, additionalCriteria: (Card c) => c.IsVillainTarget && c.HitPoints < c.MaximumHitPoints && !c.DoKeywordsContain("terrain"), numberOfTargets: 1, cardSource: GetCardSource()); if (base.UseUnityCoroutines) { yield return(this.GameController.StartCoroutine(healVillainCoroutine)); } else { this.GameController.ExhaustCoroutine(healVillainCoroutine); } } } yield break; }
private IEnumerator RoomChangeResponse(PlayCardAction pca) { IEnumerator coroutine = base.GameController.SendMessageAction($"{Card.Title} is no longer immune to damage", Priority.High, base.GetCardSource()); if (base.UseUnityCoroutines) { yield return(base.GameController.StartCoroutine(coroutine)); } else { base.GameController.ExhaustCoroutine(coroutine); } yield break; }
bool PlayACard() { var system = container.GetAspect <CardSystem> (); if (system.playable.Count == 0) { return(false); } var card = system.playable.Random(); var action = new PlayCardAction(card); container.Perform(action); return(true); }
private IEnumerator DealDamageResponse(PlayCardAction action) { //...{SwarmEater} deals the non-hero target other than itself with the lowest HP 3 melee damage. IEnumerator coroutine = base.DealDamageToLowestHP(base.Card, 1, (Card c) => c != base.Card && !c.IsHero, (Card c) => 3, DamageType.Melee); if (base.UseUnityCoroutines) { yield return(base.GameController.StartCoroutine(coroutine)); } else { base.GameController.ExhaustCoroutine(coroutine); } }
private IEnumerator DealDamageResponse(PlayCardAction pca) { IEnumerator coroutine = DealDamageToHighestHP(this.Card, 1, (Card c) => c.IsHeroCharacterCard, (c) => 2, DamageType.Psychic); if (UseUnityCoroutines) { yield return(GameController.StartCoroutine(coroutine)); } else { GameController.ExhaustCoroutine(coroutine); } yield break; }
public void Refresh(ControlMode mode) { PlayableCards.Clear(); foreach (var card in Container.Match.CurrentPlayer[Zones.Hand]) { _targetSystem.AutoTarget(card, mode); var playAction = new PlayCardAction(card); if (playAction.Validate().IsValid) { PlayableCards.Add(card); } } }
private IEnumerator WolfPlay(PlayCardAction arg) { if (ShouldActivate("wolf")) { var play = SelectAndPlayCardFromHand(HeroTurnTakerController, true, null, new LinqCardCriteria(c => !c.DoKeywordsContain("feral"))); if (UseUnityCoroutines) { yield return(this.GameController.StartCoroutine(play)); } else { this.GameController.ExhaustCoroutine(play); } } }
private IEnumerator DrawCardResponse(PlayCardAction pca) { SetCardPropertyToTrueIfRealAction(FirstTimePlayingMomentumKey); IEnumerator coroutine = GameController.SelectHeroToDrawCard(HeroTurnTakerController, cardSource: GetCardSource()); if (base.UseUnityCoroutines) { yield return(base.GameController.StartCoroutine(coroutine)); } else { base.GameController.ExhaustCoroutine(coroutine); } yield break; }
private IEnumerator Weave(PlayCardAction arg) { if (IsFirstTimeCardPlayedThisTurn(arg.CardToPlay, c => c.DoKeywordsContain("weave"), TriggerTiming.After)) { var weave = SelectAndUsePower(this); if (UseUnityCoroutines) { yield return(this.GameController.StartCoroutine(weave)); } else { this.GameController.ExhaustCoroutine(weave); } } }
private IEnumerator AlternateElementResponse(PlayCardAction action) { //Whenever the corresponding "Element of" Card enters play and the firstHead is decapitated, if the secondHead is active do the alternate response. IEnumerator coroutine = alternateElementCoroutine; if (base.UseUnityCoroutines) { yield return(base.GameController.StartCoroutine(coroutine)); } else { base.GameController.ExhaustCoroutine(coroutine); } yield break; }
private void PlayActiveCard() { InputSystem.ActiveCard.Highlight(Color.clear); _candidateViews.Highlight(Color.clear); _targetAttribute.Selected = _targets.Select(t => t.Card).ToList(); _targets.Clear(); var action = new PlayCardAction(InputSystem.ActiveCard.Card); InputSystem.Game.Perform(action); InputSystem.StateMachine.ChangeState <ResetState>(); }
private IEnumerator TargetEnterResponse(PlayCardAction action) { //Whenever a target enters play, {SwarmEater} deals that target 1 melee damage. IEnumerator coroutine = base.DealDamage(base.CharacterCard, action.CardToPlay, 1, DamageType.Melee, cardSource: base.GetCardSource()); if (base.UseUnityCoroutines) { yield return(base.GameController.StartCoroutine(coroutine)); } else { base.GameController.ExhaustCoroutine(coroutine); } yield break; }
//Permite saber qué cartas se pueden jugar desde la mano public void Refresh(ControlModes mode) { var match = container.GetMatch(); var targetSystem = container.GetAspect <TargetSystem> (); playable.Clear(); foreach (Card card in match.CurrentPlayer[Zones.Hand]) { targetSystem.AutoTarget(card, mode); var playAction = new PlayCardAction(card); if (playAction.Validate()) { playable.Add(card); } } }
private IEnumerator DealDamageResponse(PlayCardAction pca) { // Viability of target was checked with trigger, so only worry about the card. Card nextToCard = pca.CardToPlay.Location.OwnerCard; // That target damages themselves. IEnumerator coroutine = this.DealDamage(nextToCard, nextToCard, 1, DamageType.Psychic, false, false, false, null, null, null, false, null); if (this.UseUnityCoroutines) { yield return(this.GameController.StartCoroutine(coroutine)); } else { this.GameController.ExhaustCoroutine(coroutine); } }
public override void Enter() { base.Enter(); if (owner.activeCardView != null) { var action = new PlayCardAction(owner.activeCardView.card); owner.game.Perform(action); owner.stateMachine.ChangeState <ResetState>(); } if (!owner.game.GetAspect <ActionSystem>().IsActive) { owner.gameStateMachine.ChangeState <PlayerIdleState>(); } owner.activeCardView = null; owner.target = null; owner.stateMachine.ChangeState <ResetState>(); }
private void OnPrepareNextTurn(object sender, object args) { //var action = args as NextTurnAction; var player = Container.GetMatch().CurrentPlayer as Player; if (player == null) { return; } foreach (var card in player.hand) { if (card.Type == CardType.Curse) { var reaction = new PlayCardAction(card); Container.AddReaction(reaction); } } }
protected virtual ActionBase PlayCardsToField() { // Get all available cards... List<HRCard> availableCards = HRCard.GetCards(HRPlayer.GetLocalPlayer(), HRCardZone.HAND); if (availableCards.Count > 0) { HRCard coin = null; foreach (var item in availableCards) { #region Skip The Coin string cardID = item.GetEntity().GetCardId(); if (cardID == "GAME_005" || cardID == "GAME_005e") { coin = item; continue; } #endregion if (item.GetEntity().GetCost() <= HRPlayer.GetLocalPlayer().GetNumAvailableResources()) { if (HRBattle.CanUseCard(item.GetEntity()) && HRCardManager.IsCardAllowedByRule(item)) return new PlayCardAction(item); } } #region The Coin Feature // Feature: The Coin // https://github.com/juce-mmocrawlerbots/HREngine/issues/13 if (coin != null) { foreach (var card in availableCards) { if (card.GetEntity().GetCardId() != coin.GetEntity().GetCardId()) { if (card.GetEntity().IsMinion() || card.GetEntity().IsSpell() || (!HRPlayer.GetLocalPlayer().HasWeapon() && card.GetEntity().IsWeapon())) { if (card.GetEntity().GetCost() <= (HRPlayer.GetLocalPlayer().GetNumAvailableResources() + 1)) { HRLog.Write( String.Format("Spawn [{0}] and then [{1}]", coin.GetEntity().GetName(), card.GetEntity().GetName())); NextFixedAction = new PlayCardAction(card); return new PlayCardAction(coin); } } } } } #endregion } return null; }
protected virtual HREngine.API.Actions.ActionBase UpdateBattleState() { HREngine.API.Actions.ActionBase result = NextFixedAction; if (result != null) { NextFixedAction = null; return result; } // If a previous action was not handled successful the Bot remains // in target mode. // Target here with 'LastTarget'. If the specified Target is null // the bot automatically selects the best target based on a rule // or enemy condition. if (HRBattle.IsInTargetMode()) { HRLog.Write("Targeting..."); HREntity TargetEntity = PlayCardAction.LastTarget; if (TargetEntity == null) { HRCardManager.GetTargetForCard(PlayCardAction.LastPlayedCard); if (TargetEntity == null) TargetEntity = GetNextAttackToAttack(); } return new TargetAction(TargetEntity); } var localPlayerState = new PlayerState(HRPlayer.GetLocalPlayer()); var enemyPlayerState = new PlayerState(HRPlayer.GetEnemyPlayer()); // Fix: Druid: doesn't attack (and even other) // https://github.com/Hearthcrawler/HREngine/issues/40 if (!localPlayerState.Player.HasWeapon() && localPlayerState.Player.GetHero().CanAttack() && localPlayerState.Player.GetHero().GetATK() > 0 && HRBattle.CanUseCard(localPlayerState.Player.GetHero())) { return new AttackAction( localPlayerState.Player.GetHero(), GetNextAttackToAttack()); } if (!enemyPlayerState.Player.HasATauntMinion()) { if (enemyPlayerState.Player.GetHero().CanBeAttacked()) { var current = PlayerState.GetPossibleAttack( localPlayerState.Player, enemyPlayerState.Health); if (current.Attack >= enemyPlayerState.Health) { if (current.Cards.Count > 0) return new AttackAction(current.Cards[0], enemyPlayerState.Player.GetHero()); } } } if (IsDefaultHealingEnabled()) { if (localPlayerState.Player.GetHero().GetClass() == HRClass.PRIEST) { if (localPlayerState.Player.GetHeroPower().GetCost() <= localPlayerState.Mana) { if (localPlayerState.Health <= 17) { if (HRBattle.CanUseCard(localPlayerState.Player.GetHeroPower())) return new PlayCardAction( localPlayerState.Player.GetHeroPower().GetCard(), HRPlayer.GetLocalPlayer().GetHero()); } else { // FIX: Heal minions if possible // https://github.com/Hearthcrawler/HREngine/issues/27 foreach (var item in localPlayerState.ReadyMinions) { if (item.GetRemainingHP() < item.GetHealth()) { // Heal damaged minions... if (HRBattle.CanUseCard(localPlayerState.Player.GetHeroPower())) return new PlayCardAction( localPlayerState.Player.GetHeroPower().GetCard(), HRPlayer.GetLocalPlayer().GetHero()); } } } } } } // Next cards to push... if (HRPlayer.GetLocalPlayer().GetNumFriendlyMinionsInPlay() < 7) { result = PlayCardsToField(); if (result != null) return result; else { // There are no cards to play.. if (localPlayerState.Player.GetHero().GetClass() == HRClass.WARLOCK) { // Can we use our hero power? // Warlock should not suicide. // FIX: https://github.com/Hearthcrawler/HREngine/issues/30 if (localPlayerState.Health >= 10) { // At least 3 mana left if we draw a card, okay? if (localPlayerState.Player.GetHeroPower().GetCost() + 3 <= localPlayerState.Mana) { if (HRBattle.CanUseCard(localPlayerState.Player.GetHeroPower())) return new PlayCardAction(localPlayerState.Player.GetHeroPower().GetCard()); } } } } } // Priority: Always attack taunt minions first. if (enemyPlayerState.TauntMinions.Count > 0) { result = AttackTauntMinions(enemyPlayerState); if (result != null) return result; } // Bot does not attack when there is stealthed taunts // Fix: https://github.com/Hearthcrawler/HREngine/issues/60 // If AttackTauntMinions() cannot attack because of stealthed - the action is null // and the bot should continue with default attack routine. // // Attack other minions or hero... result = Attack(); if (result != null) return result; // Use Hero Power that make sense at last... if (localPlayerState.Player.GetHeroPower().GetCost() <= localPlayerState.Mana) { switch (localPlayerState.Player.GetHero().GetClass()) { case HRClass.DRUID: case HRClass.WARRIOR: case HRClass.MAGE: case HRClass.PALADIN: case HRClass.HUNTER: case HRClass.SHAMAN: case HRClass.ROGUE: { if (HRBattle.CanUseCard(localPlayerState.Player.GetHeroPower())) return new PlayCardAction(localPlayerState.Player.GetHeroPower().GetCard()); } break; default: break; } } return null; }