public static boolean isValidBand(List<Card> band, boolean shareDamage) { if (band.isEmpty()) { // An empty band is not a valid band return false; } int bandingCreatures = CardLists.getKeyword(band, "Banding").size(); int neededBandingCreatures = shareDamage ? 1 : band.size() - 1; if (neededBandingCreatures <= bandingCreatures) { // For starting a band, only one can be non-Banding // For sharing damage, only one needs to be Banding return true; } // Legends lands, Master of the Hunt, Old Fogey (just in case) // Since Bands With Other is a dead keyword, no major reason to make this more generic // But if someone is super motivated, feel free to do it. Just make sure you update Tolaria and // Shelkie Brownie String[] bandsWithString = { "Bands with Other Legendary Creatures", "Bands with Other Creatures named Wolves of the Hunt", "Bands with Other Dinosaurs" }; String[] validString = {"Legendary.Creature", "Creature.namedWolves of the Hunt", "Dinosaur"}; Card source = band.get(0); for (int i = 0; i < bandsWithString.length; i++) { String keyword = bandsWithString[i]; String valid = validString[i]; // Check if a bands with other keyword exists in band, and each creature in the band fits the // valid quality if (!CardLists.getKeyword(band, keyword).isEmpty() && CardLists.getValidCards(band, valid, source.getController(), source).size() == band.size()) { return true; } } return false; }
private boolean sacrificeTgtAI(final Player ai, final SpellAbility sa) { final Card source = sa.getHostCard(); final TargetRestrictions tgt = sa.getTargetRestrictions(); final boolean destroy = sa.hasParam("Destroy"); Player opp = ai.getOpponent(); if (tgt != null) { sa.resetTargets(); if (!opp.canBeTargetedBy(sa)) { return false; } sa.getTargets().add(opp); final String valid = sa.getParam("SacValid"); String num = sa.getParam("Amount"); num = (num == null) ? "1" : num; final int amount = AbilityUtils.calculateAmount(sa.getHostCard(), num, sa); List<Card> list = CardLists.getValidCards( ai.getOpponent().getCardsIn(ZoneType.Battlefield), valid.split(","), sa.getActivatingPlayer(), sa.getHostCard()); for (Card c : list) { if (c.hasSVar("SacMe") && Integer.parseInt(c.getSVar("SacMe")) > 3) { return false; } } if (!destroy) { list = CardLists.filter(list, CardPredicates.canBeSacrificedBy(sa)); } else { if (!CardLists.getKeyword(list, "Indestructible").isEmpty()) { // human can choose to destroy indestructibles return false; } } if (list.isEmpty()) { return false; } if (num.equals("X") && source.getSVar(num).equals("Count$xPaid")) { // Set PayX here to maximum value. final int xPay = Math.min(ComputerUtilMana.determineLeftoverMana(sa, ai), amount); source.setSVar("PayX", Integer.toString(xPay)); } final int half = (amount / 2) + (amount % 2); // Half of amount // rounded up // If the Human has at least half rounded up of the amount to be // sacrificed, cast the spell if (!sa.isTrigger() && list.size() < half) { return false; } } final String defined = sa.getParam("Defined"); final String valid = sa.getParam("SacValid"); if (defined == null) { // Self Sacrifice. } else if (defined.equals("Each") || (defined.equals("Opponent") && !sa.isTrigger())) { // If Sacrifice hits both players: // Only cast it if Human has the full amount of valid // Only cast it if AI doesn't have the full amount of Valid // TODO: Cast if the type is favorable: my "worst" valid is // worse than his "worst" valid final String num = sa.hasParam("Amount") ? sa.getParam("Amount") : "1"; int amount = AbilityUtils.calculateAmount(source, num, sa); if (num.equals("X") && source.getSVar(num).equals("Count$xPaid")) { // Set PayX here to maximum value. amount = Math.min(ComputerUtilMana.determineLeftoverMana(sa, ai), amount); } List<Card> humanList = CardLists.getValidCards( opp.getCardsIn(ZoneType.Battlefield), valid.split(","), sa.getActivatingPlayer(), sa.getHostCard()); // Since all of the cards have remAIDeck:True, I enabled 1 for 1 // (or X for X) trades for special decks if (humanList.size() < amount) { return false; } } else if (defined.equals("You")) { List<Card> computerList = CardLists.getValidCards( ai.getCardsIn(ZoneType.Battlefield), valid.split(","), sa.getActivatingPlayer(), sa.getHostCard()); for (Card c : computerList) { if (c.hasSVar("SacMe") || ComputerUtilCard.evaluateCreature(c) <= 135) { return true; } } return false; } return true; }