/// <summary> /// [EN] /// This handler is executed when the local player turn is active. /// /// [DE] /// Dieses Event wird ausgelöst wenn der Spieler am Zug ist. /// </summary> private HREngine.API.Actions.ActionBase HandleOnBattleStateUpdate() { try { if (this.isgoingtoconcede) { if (HREngine.API.Utilities.HRSettings.Get.SelectedGameMode == HRGameMode.ARENA) { this.isgoingtoconcede = false; } else { return(new HREngine.API.Actions.ConcedeAction()); } } if (Settings.Instance.passiveWaiting && sf.waitingForSilver) { if (!this.sf.readActionFile(true)) { return(new HREngine.API.Actions.MakeNothingAction()); } } if (Settings.Instance.learnmode && (HRBattle.IsInTargetMode() || HRChoice.IsChoiceActive())) { return(new HREngine.API.Actions.MakeNothingAction()); } if (HRBattle.IsInTargetMode() && dirtytarget >= 0) { Helpfunctions.Instance.ErrorLog("dirty targeting..."); HREntity target = getEntityWithNumber(dirtytarget); dirtytarget = -1; return(new HREngine.API.Actions.TargetAction(target)); } if (HRChoice.IsChoiceActive()) { if (this.dirtychoice >= 1) { List <HREntity> choices = HRChoice.GetChoiceCards(); int choice = this.dirtychoice; this.dirtychoice = -1; string ccId = this.choiceCardId; this.choiceCardId = ""; HREntity target = choices[choice - 1]; if (ccId == "EX1_160") { foreach (HREntity hre in choices) { if (choice == 1 && hre.GetCardId() == "EX1_160b") { target = hre; } if (choice == 2 && hre.GetCardId() == "EX1_160a") { target = hre; } } } if (ccId == "NEW1_008") { foreach (HREntity hre in choices) { if (choice == 1 && hre.GetCardId() == "NEW1_008a") { target = hre; } if (choice == 2 && hre.GetCardId() == "NEW1_008b") { target = hre; } } } if (ccId == "EX1_178") { foreach (HREntity hre in choices) { if (choice == 1 && hre.GetCardId() == "EX1_178a") { target = hre; } if (choice == 2 && hre.GetCardId() == "EX1_178b") { target = hre; } } } if (ccId == "EX1_573") { foreach (HREntity hre in choices) { if (choice == 1 && hre.GetCardId() == "EX1_573a") { target = hre; } if (choice == 2 && hre.GetCardId() == "EX1_573b") { target = hre; } } } if (ccId == "EX1_165")//druid of the claw { foreach (HREntity hre in choices) { if (choice == 1 && hre.GetCardId() == "EX1_165t1") { target = hre; } if (choice == 2 && hre.GetCardId() == "EX1_165t2") { target = hre; } } } if (ccId == "EX1_166")//keeper of the grove { foreach (HREntity hre in choices) { if (choice == 1 && hre.GetCardId() == "EX1_166a") { target = hre; } if (choice == 2 && hre.GetCardId() == "EX1_166b") { target = hre; } } } if (ccId == "EX1_155") { foreach (HREntity hre in choices) { if (choice == 1 && hre.GetCardId() == "EX1_155a") { target = hre; } if (choice == 2 && hre.GetCardId() == "EX1_155b") { target = hre; } } } if (ccId == "EX1_164") { foreach (HREntity hre in choices) { if (choice == 1 && hre.GetCardId() == "EX1_164a") { target = hre; } if (choice == 2 && hre.GetCardId() == "EX1_164b") { target = hre; } } } if (ccId == "New1_007")//starfall { foreach (HREntity hre in choices) { if (choice == 1 && hre.GetCardId() == "New1_007b") { target = hre; } if (choice == 2 && hre.GetCardId() == "New1_007a") { target = hre; } } } if (ccId == "EX1_154")//warth { foreach (HREntity hre in choices) { if (choice == 1 && hre.GetCardId() == "EX1_154a") { target = hre; } if (choice == 2 && hre.GetCardId() == "EX1_154b") { target = hre; } } } Helpfunctions.Instance.logg("chooses the card: " + target.GetCardId()); return(new HREngine.API.Actions.ChoiceAction(target)); } else { //Todo: ultimate tracking-simulation! List <HREntity> choices = HRChoice.GetChoiceCards(); Random r = new Random(); int choice = r.Next(0, choices.Count); Helpfunctions.Instance.logg("chooses a random card"); return(new HREngine.API.Actions.ChoiceAction(choices[choice])); } } bool templearn = sf.updateEverything(behave, Settings.Instance.useExternalProcess, Settings.Instance.passiveWaiting); if (templearn == true) { Settings.Instance.printlearnmode = true; } if (Settings.Instance.passiveWaiting && sf.waitingForSilver) { return(new HREngine.API.Actions.MakeNothingAction()); } if (Settings.Instance.learnmode) { if (Settings.Instance.printlearnmode) { Ai.Instance.simmulateWholeTurnandPrint(); } Settings.Instance.printlearnmode = false; return(new HREngine.API.Actions.MakeNothingAction()); } if (Ai.Instance.bestmoveValue <= -900 && Settings.Instance.enemyConcede) { return(new HREngine.API.Actions.ConcedeAction()); } Action moveTodo = Ai.Instance.bestmove; if (moveTodo == null || moveTodo.actionType == actionEnum.endturn) { Helpfunctions.Instance.ErrorLog("end turn"); return(null); } Helpfunctions.Instance.ErrorLog("play action"); moveTodo.print(); if (moveTodo.actionType == actionEnum.playcard) { HRCard cardtoplay = getCardWithNumber(moveTodo.card.entity); if (moveTodo.target != null) { HREntity target = getEntityWithNumber(moveTodo.target.entitiyID); Helpfunctions.Instance.ErrorLog("play: " + cardtoplay.GetEntity().GetName() + " target: " + target.GetName()); Helpfunctions.Instance.logg("play: " + cardtoplay.GetEntity().GetName() + " target: " + target.GetName() + " choice: " + moveTodo.druidchoice); if (moveTodo.druidchoice >= 1) { this.dirtytarget = moveTodo.target.entitiyID; this.dirtychoice = moveTodo.druidchoice; //1=leftcard, 2= rightcard this.choiceCardId = moveTodo.card.card.cardIDenum.ToString(); } if (moveTodo.card.card.type == CardDB.cardtype.MOB) { return(new HREngine.API.Actions.PlayCardAction(cardtoplay, target, moveTodo.place)); } return(new HREngine.API.Actions.PlayCardAction(cardtoplay, target)); } else { Helpfunctions.Instance.ErrorLog("play: " + cardtoplay.GetEntity().GetName() + " target nothing"); Helpfunctions.Instance.logg("play: " + cardtoplay.GetEntity().GetName() + " choice: " + moveTodo.druidchoice); if (moveTodo.druidchoice >= 1) { this.dirtychoice = moveTodo.druidchoice; //1=leftcard, 2= rightcard this.choiceCardId = moveTodo.card.card.cardIDenum.ToString(); } if (moveTodo.card.card.type == CardDB.cardtype.MOB) { return(new HREngine.API.Actions.PlayCardAction(cardtoplay, null, moveTodo.place)); } return(new HREngine.API.Actions.PlayCardAction(cardtoplay)); } } if (moveTodo.actionType == actionEnum.attackWithMinion) { HREntity attacker = getEntityWithNumber(moveTodo.own.entitiyID); HREntity target = getEntityWithNumber(moveTodo.target.entitiyID); Helpfunctions.Instance.ErrorLog("minion attack: " + attacker.GetName() + " target: " + target.GetName()); Helpfunctions.Instance.logg("minion attack: " + attacker.GetName() + " target: " + target.GetName()); return(new HREngine.API.Actions.AttackAction(attacker, target)); } if (moveTodo.actionType == actionEnum.attackWithHero) { HREntity attacker = getEntityWithNumber(moveTodo.own.entitiyID); HREntity target = getEntityWithNumber(moveTodo.target.entitiyID); this.dirtytarget = moveTodo.target.entitiyID; Helpfunctions.Instance.ErrorLog("heroattack: " + attacker.GetName() + " target: " + target.GetName()); Helpfunctions.Instance.logg("heroattack: " + attacker.GetName() + " target: " + target.GetName()); if (HRPlayer.GetLocalPlayer().HasWeapon()) { Helpfunctions.Instance.ErrorLog("hero attack with weapon"); return(new HREngine.API.Actions.AttackAction(HRPlayer.GetLocalPlayer().GetWeaponCard().GetEntity(), target)); } Helpfunctions.Instance.ErrorLog("hero attack without weapon"); //Helpfunctions.Instance.ErrorLog("attacker entity: " + HRPlayer.GetLocalPlayer().GetHero().GetEntityId()); //return new HREngine.API.Actions.AttackAction(HRPlayer.GetLocalPlayer().GetHero(), target); return(new HREngine.API.Actions.PlayCardAction(HRPlayer.GetLocalPlayer().GetHeroCard(), target)); } if (moveTodo.actionType == actionEnum.useHeroPower) { HRCard cardtoplay = HRPlayer.GetLocalPlayer().GetHeroPower().GetCard(); if (moveTodo.target != null) { HREntity target = getEntityWithNumber(moveTodo.target.entitiyID); Helpfunctions.Instance.ErrorLog("use ablitiy: " + cardtoplay.GetEntity().GetName() + " target " + target.GetName()); Helpfunctions.Instance.logg("use ablitiy: " + cardtoplay.GetEntity().GetName() + " target " + target.GetName()); return(new HREngine.API.Actions.PlayCardAction(cardtoplay, target)); } else { Helpfunctions.Instance.ErrorLog("use ablitiy: " + cardtoplay.GetEntity().GetName() + " target nothing"); Helpfunctions.Instance.logg("use ablitiy: " + cardtoplay.GetEntity().GetName() + " target nothing"); return(new HREngine.API.Actions.PlayCardAction(cardtoplay)); } } } catch (Exception Exception) { Helpfunctions.Instance.ErrorLog(Exception.Message); Helpfunctions.Instance.ErrorLog(Environment.StackTrace); if (Settings.Instance.learnmode) { return(new HREngine.API.Actions.MakeNothingAction()); } } return(null); //HRBattle.FinishRound(); }
/// <summary> /// [EN] /// This handler is executed when the local player turn is active. /// /// [DE] /// Dieses Event wird ausgelöst wenn der Spieler am Zug ist. /// </summary> private HREngine.API.Actions.ActionBase HandleOnBattleStateUpdate() { try { if (HRBattle.IsInTargetMode() && dirtytarget >= 0) { HRLog.Write("dirty targeting..."); HREntity target = getEntityWithNumber(dirtytarget); dirtytarget = -1; return(new HREngine.API.Actions.TargetAction(target)); } //SafeHandleBattleLocalPlayerTurnHandler(); sf.updateEverything(this); Action moveTodo = Ai.Instance.bestmove; if (moveTodo == null) { HRLog.Write("end turn"); return(null); } HRLog.Write("play action"); moveTodo.print(); if (moveTodo.cardplay) { HRCard cardtoplay = getCardWithNumber(moveTodo.cardEntitiy); if (moveTodo.enemytarget >= 0) { HREntity target = getEntityWithNumber(moveTodo.enemyEntitiy); HRLog.Write("play: " + cardtoplay.GetEntity().GetName() + " target: " + target.GetName()); Helpfunctions.Instance.logg("play: " + cardtoplay.GetEntity().GetName() + " target: " + target.GetName()); if (moveTodo.handcard.card.type == CardDB.cardtype.MOB) { return(new HREngine.API.Actions.PlayCardAction(cardtoplay, target, moveTodo.owntarget + 1)); } return(new HREngine.API.Actions.PlayCardAction(cardtoplay, target)); } else { HRLog.Write("play: " + cardtoplay.GetEntity().GetName() + " target nothing"); if (moveTodo.handcard.card.type == CardDB.cardtype.MOB) { return(new HREngine.API.Actions.PlayCardAction(cardtoplay, null, moveTodo.owntarget + 1)); } return(new HREngine.API.Actions.PlayCardAction(cardtoplay)); } } if (moveTodo.minionplay) { HREntity attacker = getEntityWithNumber(moveTodo.ownEntitiy); HREntity target = getEntityWithNumber(moveTodo.enemyEntitiy); HRLog.Write("minion attack: " + attacker.GetName() + " target: " + target.GetName()); Helpfunctions.Instance.logg("minion attack: " + attacker.GetName() + " target: " + target.GetName()); return(new HREngine.API.Actions.AttackAction(attacker, target)); } if (moveTodo.heroattack) { HREntity attacker = getEntityWithNumber(moveTodo.ownEntitiy); HREntity target = getEntityWithNumber(moveTodo.enemyEntitiy); this.dirtytarget = moveTodo.enemyEntitiy; //HRLog.Write("heroattack: attkr:" + moveTodo.ownEntitiy + " defender: " + moveTodo.enemyEntitiy); HRLog.Write("heroattack: " + attacker.GetName() + " target: " + target.GetName()); Helpfunctions.Instance.logg("heroattack: " + attacker.GetName() + " target: " + target.GetName()); if (HRPlayer.GetLocalPlayer().HasWeapon()) { HRLog.Write("hero attack with weapon"); return(new HREngine.API.Actions.AttackAction(HRPlayer.GetLocalPlayer().GetWeaponCard().GetEntity(), target)); } HRLog.Write("hero attack without weapon"); //HRLog.Write("attacker entity: " + HRPlayer.GetLocalPlayer().GetHero().GetEntityId()); return(new HREngine.API.Actions.AttackAction(HRPlayer.GetLocalPlayer().GetHero(), target)); } if (moveTodo.useability) { HRCard cardtoplay = HRPlayer.GetLocalPlayer().GetHeroPower().GetCard(); if (moveTodo.enemytarget >= 0) { HREntity target = getEntityWithNumber(moveTodo.enemyEntitiy); HRLog.Write("use ablitiy: " + cardtoplay.GetEntity().GetName() + " target " + target.GetName()); Helpfunctions.Instance.logg("use ablitiy: " + cardtoplay.GetEntity().GetName() + " target " + target.GetName()); return(new HREngine.API.Actions.PlayCardAction(cardtoplay, target)); } else { HRLog.Write("use ablitiy: " + cardtoplay.GetEntity().GetName() + " target nothing"); Helpfunctions.Instance.logg("use ablitiy: " + cardtoplay.GetEntity().GetName() + " target nothing"); return(new HREngine.API.Actions.PlayCardAction(cardtoplay)); } } } catch (Exception Exception) { HRLog.Write(Exception.Message); HRLog.Write(Environment.StackTrace); } return(null); //HRBattle.FinishRound(); }
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); }