public static boolean destroyDoTriggerAI( final AbilityFactory af, SpellAbility sa, boolean mandatory) { if (!ComputerUtil.canPayCost(sa)) return false; Target tgt = sa.getTarget(); final Card source = sa.getSourceCard(); final boolean noRegen = af.getMapParams().containsKey("NoRegen"); if (tgt != null) { CardList list; list = AllZoneUtil.getCardsInPlay(); list = list.getTargetableCards(source); list = list.getValidCards(tgt.getValidTgts(), source.getController(), source); if (list.size() == 0 || list.size() < tgt.getMinTargets(sa.getSourceCard(), sa)) return false; tgt.resetTargets(); CardList preferred = list.getNotKeyword("Indestructible"); preferred = list.getController(AllZone.HumanPlayer); // If NoRegen is not set, filter out creatures that have a regeneration shield if (!noRegen) { // TODO: filter out things that could regenerate in response? might be tougher? preferred = preferred.filter( new CardListFilter() { public boolean addCard(Card c) { return c.getShield() == 0; } }); } for (Card c : preferred) list.remove(c); while (tgt.getNumTargeted() < tgt.getMaxTargets(sa.getSourceCard(), sa)) { if (preferred.size() == 0) { if (tgt.getNumTargeted() == 0 || tgt.getNumTargeted() < tgt.getMinTargets(sa.getSourceCard(), sa)) { if (!mandatory) { tgt.resetTargets(); return false; } else break; } else { break; } } else { Card c; if (preferred.getNotType("Creature").size() == 0) { c = CardFactoryUtil.AI_getBestCreature(preferred); } else if (preferred.getNotType("Land").size() == 0) { c = CardFactoryUtil.AI_getBestLand(preferred); } else { c = CardFactoryUtil.AI_getMostExpensivePermanent(preferred, source, false); } tgt.addTarget(c); preferred.remove(c); } } while (tgt.getNumTargeted() < tgt.getMinTargets(sa.getSourceCard(), sa)) { if (list.size() == 0) { break; } else { Card c; if (list.getNotType("Creature").size() == 0) { c = CardFactoryUtil.AI_getWorstCreature(list); } else { c = CardFactoryUtil.AI_getCheapestPermanent(list, source, false); } tgt.addTarget(c); list.remove(c); } } if (tgt.getNumTargeted() < tgt.getMinTargets(sa.getSourceCard(), sa)) return false; } else { if (!mandatory) return false; } Ability_Sub subAb = sa.getSubAbility(); if (subAb != null) return subAb.doTrigger(mandatory); return true; }
public static boolean destroyCanPlayAI(final AbilityFactory af, final SpellAbility sa) { // AI needs to be expanded, since this function can be pretty complex based on what the expected // targets could be Random r = MyRandom.random; Cost abCost = sa.getPayCosts(); Target abTgt = sa.getTarget(); final Card source = sa.getSourceCard(); final boolean noRegen = af.getMapParams().containsKey("NoRegen"); CardList list; list = AllZoneUtil.getPlayerCardsInPlay(AllZone.HumanPlayer); list = list.getTargetableCards(source); if (abTgt != null) { list = list.getValidCards(abTgt.getValidTgts(), source.getController(), source); list = list.getNotKeyword("Indestructible"); // If NoRegen is not set, filter out creatures that have a regeneration shield if (!noRegen) { // TODO: filter out things that could regenerate in response? might be tougher? list = list.filter( new CardListFilter() { public boolean addCard(Card c) { return (c.getShield() == 0 && !ComputerUtil.canRegenerate(c)); } }); } if (list.size() == 0) return false; } if (abCost != null) { // AI currently disabled for some costs if (abCost.getSacCost() && !abCost.getSacThis()) { // only sacrifice something that's supposed to be sacrificed String sacType = abCost.getSacType(); CardList typeList = AllZoneUtil.getPlayerCardsInPlay(AllZone.ComputerPlayer); typeList = typeList.getValidCards(sacType.split(","), source.getController(), source); if (ComputerUtil.getCardPreference(source, "SacCost", typeList) == null) return false; } if (abCost.getLifeCost()) { if (AllZone.ComputerPlayer.getLife() - abCost.getLifeAmount() < 4) return false; } if (abCost.getDiscardCost()) return false; if (abCost.getSubCounter()) { // OK } } if (!ComputerUtil.canPayCost(sa)) return false; // prevent run-away activations - first time will always return true boolean chance = r.nextFloat() <= Math.pow(.6667, source.getAbilityUsed()); // Targeting if (abTgt != null) { abTgt.resetTargets(); // target loop while (abTgt.getNumTargeted() < abTgt.getMaxTargets(sa.getSourceCard(), sa)) { if (list.size() == 0) { if (abTgt.getNumTargeted() < abTgt.getMinTargets(sa.getSourceCard(), sa) || abTgt.getNumTargeted() == 0) { abTgt.resetTargets(); return false; } else { // TODO is this good enough? for up to amounts? break; } } Card choice = null; if (list.getNotType("Creature").size() == 0) choice = CardFactoryUtil.AI_getBestCreature( list); // if the targets are only creatures, take the best else choice = CardFactoryUtil.AI_getMostExpensivePermanent(list, af.getHostCard(), true); if (choice == null) { // can't find anything left if (abTgt.getNumTargeted() < abTgt.getMinTargets(sa.getSourceCard(), sa) || abTgt.getNumTargeted() == 0) { abTgt.resetTargets(); return false; } else { // TODO is this good enough? for up to amounts? break; } } list.remove(choice); abTgt.addTarget(choice); } } else { return false; } Ability_Sub subAb = sa.getSubAbility(); if (subAb != null) chance &= subAb.chkAI_Drawback(); return ((r.nextFloat() < .6667) && chance); }