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(); }
public static void destroyAllResolve( final AbilityFactory af, final SpellAbility sa, final boolean noRegen) { HashMap<String, String> params = af.getMapParams(); String DrawBack = params.get("SubAbility"); Card card = sa.getSourceCard(); if (!AbilityFactory.checkConditional(params, sa)) { AbilityFactory.resolveSubAbility(sa); return; } String Valid = ""; if (params.containsKey("ValidCards")) Valid = params.get("ValidCards"); // Ugh. If calculateAmount needs to be called with DestroyAll it _needs_ to use the X variable // We really need a better solution to this if (Valid.contains("X")) Valid = Valid.replace("X", Integer.toString(AbilityFactory.calculateAmount(card, "X", sa))); CardList list = AllZoneUtil.getCardsInPlay(); list = list.getValidCards(Valid.split(","), card.getController(), card); boolean remDestroyed = params.containsKey("RememberDestroyed"); if (remDestroyed) card.clearRemembered(); if (noRegen) { for (int i = 0; i < list.size(); i++) if (AllZone.GameAction.destroyNoRegeneration(list.get(i)) && remDestroyed) card.addRemembered(list.get(i)); } else { for (int i = 0; i < list.size(); i++) if (AllZone.GameAction.destroy(list.get(i)) && remDestroyed) card.addRemembered(list.get(i)); } 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, null, sa); } }
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 destroyAllCanPlayAI( final AbilityFactory af, final SpellAbility sa, final boolean noRegen) { // 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(); final Card source = sa.getSourceCard(); final HashMap<String, String> params = af.getMapParams(); String Valid = ""; if (params.containsKey("ValidCards")) Valid = params.get("ValidCards"); if (Valid.contains("X") && source.getSVar("X").equals("Count$xPaid")) { // Set PayX here to maximum value. int xPay = ComputerUtil.determineLeftoverMana(sa); source.setSVar("PayX", Integer.toString(xPay)); Valid = Valid.replace("X", Integer.toString(xPay)); } CardList humanlist = AllZoneUtil.getPlayerCardsInPlay(AllZone.HumanPlayer); CardList computerlist = AllZoneUtil.getPlayerCardsInPlay(AllZone.ComputerPlayer); humanlist = humanlist.getValidCards(Valid.split(","), source.getController(), source); computerlist = computerlist.getValidCards(Valid.split(","), source.getController(), source); humanlist = humanlist.getNotKeyword("Indestructible"); computerlist = computerlist.getNotKeyword("Indestructible"); if (abCost != null) { // AI currently disabled for some costs if (abCost.getSacCost()) { // OK } if (abCost.getLifeCost()) { if (AllZone.ComputerPlayer.getLife() - abCost.getLifeAmount() < 4) return false; } if (abCost.getDiscardCost()) ; // OK 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()); // if only creatures are affected evaluate both lists and pass only if human creatures are more // valuable if (humanlist.getNotType("Creature").size() == 0 && computerlist.getNotType("Creature").size() == 0) { if (CardFactoryUtil.evaluateCreatureList(computerlist) + 200 >= CardFactoryUtil.evaluateCreatureList(humanlist)) return false; } // only lands involved else if (humanlist.getNotType("Land").size() == 0 && computerlist.getNotType("Land").size() == 0) { if (CardFactoryUtil.evaluatePermanentList(computerlist) + 1 >= CardFactoryUtil.evaluatePermanentList(humanlist)) return false; } // otherwise evaluate both lists by CMC and pass only if human permanents are more valuable else if (CardFactoryUtil.evaluatePermanentList(computerlist) + 3 >= CardFactoryUtil.evaluatePermanentList(humanlist)) return false; Ability_Sub subAb = sa.getSubAbility(); if (subAb != null) chance &= subAb.chkAI_Drawback(); return ((r.nextFloat() < .9667) && chance); }
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); }