From 318543db38c8bccf2b0dbc811b48cff79ab09ec2 Mon Sep 17 00:00:00 2001 From: Agetian Date: Tue, 24 Jan 2017 10:59:59 +0000 Subject: [PATCH] - Trying to restore the new SpellAbilityAi format for ManaEffectAi. - Limited mana ritual AI a bit more, it's bad at prioritizing instants for it. --- .../src/main/java/forge/ai/SpecialCardAi.java | 18 +---- .../java/forge/ai/ability/ManaEffectAi.java | 73 ++++++++++++++++--- 2 files changed, 65 insertions(+), 26 deletions(-) diff --git a/forge-ai/src/main/java/forge/ai/SpecialCardAi.java b/forge-ai/src/main/java/forge/ai/SpecialCardAi.java index 3fca3500e47..6dac57f7c2d 100644 --- a/forge-ai/src/main/java/forge/ai/SpecialCardAi.java +++ b/forge-ai/src/main/java/forge/ai/SpecialCardAi.java @@ -332,12 +332,7 @@ public class SpecialCardAi { public static class ManaRitual { public static boolean consider(final Player ai, SpellAbility sa) { final Card host = sa.getHostCard(); - final PhaseHandler ph = ai.getGame().getPhaseHandler(); - - if (!(ph.getPlayerTurn().equals(ai) && (ph.is(PhaseType.MAIN2) || ph.is(PhaseType.MAIN1)))) { - return false; - } - + CardCollection manaSources = ComputerUtilMana.getAvailableMana(ai, true); int numManaSrcs = manaSources.size(); int manaReceived = AbilityUtils.calculateAmount(host, sa.getParam("Amount"), sa); @@ -377,16 +372,11 @@ public class SpecialCardAi { SpellAbility testSaNoCost = testSa.copyWithNoManaCost(); testSaNoCost.setActivatingPlayer(ai); if (((PlayerControllerAi)ai.getController()).getAi().canPlaySa(testSaNoCost) == AiPlayDecision.WillPlay) { - if (!testSa.getHostCard().isInstant() && !ph.is(PhaseType.MAIN2)) { - // AI sometimes thinks that it's willing to cast a sorcery in Main1 and then it doesn't, - // so avoid evaluating them unless already in Main2 - continue; - } - if (testSa.getApi() == ApiType.Counter || testSa.getApi() == ApiType.Mana) { - // do not specifically look to activate this for a counterspell or for another mana- - // producing ability. + if (testSa.getHostCard().isInstant()) { + // AI is bad at choosing which instants are worth a Ritual continue; } + // the AI is willing to play the spell if (!cardList.contains(testSa.getHostCard())) { cardList.add(testSa.getHostCard()); diff --git a/forge-ai/src/main/java/forge/ai/ability/ManaEffectAi.java b/forge-ai/src/main/java/forge/ai/ability/ManaEffectAi.java index 075f32dfbc8..dd3cb280ec8 100644 --- a/forge-ai/src/main/java/forge/ai/ability/ManaEffectAi.java +++ b/forge-ai/src/main/java/forge/ai/ability/ManaEffectAi.java @@ -4,36 +4,85 @@ package forge.ai.ability; import forge.ai.ComputerUtil; import forge.ai.SpecialCardAi; import forge.ai.SpellAbilityAi; +import forge.game.phase.PhaseHandler; import forge.game.phase.PhaseType; import forge.game.player.Player; import forge.game.spellability.SpellAbility; public class ManaEffectAi extends SpellAbilityAi { + /* + * (non-Javadoc) + * + * @see forge.ai.SpellAbilityAi#checkAiLogic(forge.game.player.Player, + * forge.game.spellability.SpellAbility, java.lang.String) + */ @Override - protected boolean canPlayAI(Player ai, SpellAbility sa) { - if ("ManaRitual".equals(sa.getParam("AILogic"))) { + protected boolean checkAiLogic(Player ai, SpellAbility sa, String aiLogic) { + if ("ManaRitual".equals(aiLogic)) { return SpecialCardAi.ManaRitual.consider(ai, sa); } - if (ai.getGame().getPhaseHandler().is(PhaseType.MAIN2) && ComputerUtil.activateForCost(sa, ai)) { - return true; + return super.checkAiLogic(ai, sa, aiLogic); + } + + /* + * (non-Javadoc) + * + * @see + * forge.ai.SpellAbilityAi#checkPhaseRestrictions(forge.game.player.Player, + * forge.game.spellability.SpellAbility, forge.game.phase.PhaseHandler) + */ + @Override + protected boolean checkPhaseRestrictions(Player ai, SpellAbility sa, PhaseHandler ph) { + if (!ph.is(PhaseType.MAIN2) || !ComputerUtil.activateForCost(sa, ai)) { + return false; } - if (sa.getPayCosts() != null && sa.getPayCosts().hasNoManaCost() - && sa.getPayCosts().isReusuableResource() - && sa.getSubAbility() == null - && ComputerUtil.playImmediately(ai, sa)) { - return true; + return super.checkPhaseRestrictions(ai, sa, ph); + } + + /* + * (non-Javadoc) + * + * @see + * forge.ai.SpellAbilityAi#checkPhaseRestrictions(forge.game.player.Player, + * forge.game.spellability.SpellAbility, forge.game.phase.PhaseHandler, + * java.lang.String) + */ + @Override + protected boolean checkPhaseRestrictions(Player ai, SpellAbility sa, PhaseHandler ph, String logic) { + if ("ManaRitual".equals(logic)) { + return ph.is(PhaseType.MAIN2, ai) || ph.is(PhaseType.MAIN1, ai); } - return false; + return super.checkPhaseRestrictions(ai, sa, ph, logic); + } + + /* + * (non-Javadoc) + * + * @see forge.ai.SpellAbilityAi#checkApiLogic(forge.game.player.Player, + * forge.game.spellability.SpellAbility) + */ + @Override + protected boolean checkApiLogic(Player ai, SpellAbility sa) { + if (sa.hasParam("AILogic")) { + return true; // handled elsewhere, does not meet the standard requirements + } + + if (!(sa.getPayCosts() != null && sa.getPayCosts().hasNoManaCost() && sa.getPayCosts().isReusuableResource() + && sa.getSubAbility() == null && ComputerUtil.playImmediately(ai, sa))) { + return false; + } + return true; + // return super.checkApiLogic(ai, sa); } /** + * @param ai + * the AI player. * @param sa * a {@link forge.game.spellability.SpellAbility} object. * @param mandatory * a boolean. - * @param af - * a {@link forge.game.ability.AbilityFactory} object. * * @return a boolean. */