public static String destroyAllStackDescription( final AbilityFactory af, SpellAbility sa, boolean noRegen) { // when getStackDesc is called, just build exactly what is happening StringBuilder sb = new StringBuilder(); String name = af.getHostCard().getName(); String conditionDesc = af.getMapParams().get("ConditionDescription"); if (conditionDesc != null) sb.append(conditionDesc).append(" "); ArrayList<Card> tgtCards; Target tgt = af.getAbTgt(); if (tgt != null) tgtCards = tgt.getTargetCards(); else { tgtCards = new ArrayList<Card>(); tgtCards.add(sa.getSourceCard()); } sb.append(name).append(" - Destroy permanents"); if (noRegen) sb.append(". They can't be regenerated"); Ability_Sub abSub = sa.getSubAbility(); if (abSub != null) { sb.append(abSub.getStackDescription()); } return sb.toString(); }
private static String destroyStackDescription(final AbilityFactory af, SpellAbility sa) { final boolean noRegen = af.getMapParams().containsKey("NoRegen"); StringBuilder sb = new StringBuilder(); Card host = af.getHostCard(); String conditionDesc = af.getMapParams().get("ConditionDescription"); if (conditionDesc != null) sb.append(conditionDesc).append(" "); ArrayList<Card> tgtCards; Target tgt = af.getAbTgt(); if (tgt != null) tgtCards = tgt.getTargetCards(); else { tgtCards = AbilityFactory.getDefinedCards(sa.getSourceCard(), af.getMapParams().get("Defined"), sa); } if (sa instanceof Ability_Sub) sb.append(" "); else sb.append(host).append(" - "); sb.append("Destroy "); Iterator<Card> it = tgtCards.iterator(); while (it.hasNext()) { Card tgtC = it.next(); if (tgtC.isFaceDown()) sb.append("Morph ").append("(").append(tgtC.getUniqueNumber()).append(")"); else sb.append(tgtC); if (it.hasNext()) sb.append(", "); } if (noRegen) { sb.append(". "); if (tgtCards.size() == 1) sb.append("It"); else sb.append("They"); sb.append(" can't be regenerated"); } sb.append("."); Ability_Sub abSub = sa.getSubAbility(); if (abSub != null) { sb.append(abSub.getStackDescription()); } return sb.toString(); }
public static void destroyResolve(final AbilityFactory af, final SpellAbility sa) { HashMap<String, String> params = af.getMapParams(); String DrawBack = params.get("SubAbility"); final boolean noRegen = params.containsKey("NoRegen"); Card card = sa.getSourceCard(); if (!AbilityFactory.checkConditional(params, sa)) { AbilityFactory.resolveSubAbility(sa); return; } ArrayList<Card> tgtCards; Target tgt = af.getAbTgt(); if (tgt != null) tgtCards = tgt.getTargetCards(); else { tgtCards = AbilityFactory.getDefinedCards(sa.getSourceCard(), af.getMapParams().get("Defined"), sa); } for (Card tgtC : tgtCards) { if (AllZoneUtil.isCardInPlay(tgtC) && (tgt == null || CardFactoryUtil.canTarget(card, tgtC))) { if (noRegen) AllZone.GameAction.destroyNoRegeneration(tgtC); else AllZone.GameAction.destroy(tgtC); } } if (af.hasSubAbility()) { Ability_Sub abSub = sa.getSubAbility(); if (abSub != null) { abSub.resolve(); } else CardFactoryUtil.doDrawBack( DrawBack, 0, card.getController(), card.getController().getOpponent(), card.getController(), card, tgtCards.get(0), sa); } }
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); }