Oathbreaker: added support of 2 partners with 2 spells, improved signature spell hint and checks;

This commit is contained in:
Oleg Agafonov 2019-05-29 03:03:17 +04:00
parent 50e5a3e050
commit a9329c130d
8 changed files with 146 additions and 196 deletions

View file

@ -2,13 +2,17 @@ package mage.abilities.condition.common;
import mage.abilities.Ability;
import mage.abilities.condition.Condition;
import mage.cards.Card;
import mage.filter.FilterMana;
import mage.filter.common.FilterControlledPermanent;
import mage.filter.predicate.Predicates;
import mage.filter.predicate.permanent.PermanentIdPredicate;
import mage.game.Game;
import mage.util.ManaUtil;
import java.util.ArrayList;
import java.util.List;
import java.util.Set;
import java.util.UUID;
/**
@ -20,23 +24,42 @@ public class OathbreakerOnBattlefieldCondition implements Condition {
private UUID playerId;
private FilterControlledPermanent filter;
private String compatibleNames;
public OathbreakerOnBattlefieldCondition(UUID playerId, List<UUID> oathbreakersToSearch) {
public OathbreakerOnBattlefieldCondition(Game game, UUID playerId, UUID signatureSpellId, Set<UUID> oathbreakersToSearch) {
this.playerId = playerId;
this.filter = new FilterControlledPermanent("oathbreaker on battlefield");
Card spell = game.getCard(signatureSpellId);
FilterMana spellColors = spell != null ? spell.getColorIdentity() : null;
// spell can be casted by any compatible oathbreakers
List<PermanentIdPredicate> compatibleList = new ArrayList<>();
List<String> compatibleNames = new ArrayList<>();
if (oathbreakersToSearch != null && !oathbreakersToSearch.isEmpty()) {
// any commander on battlefield
List<PermanentIdPredicate> idsList = new ArrayList<>();
for (UUID id : oathbreakersToSearch) {
idsList.add(new PermanentIdPredicate(id));
Card commander = game.getCard(id);
if (commander != null && ManaUtil.isColorIdentityCompatible(commander.getColorIdentity(), spellColors)) {
compatibleList.add(new PermanentIdPredicate(id));
compatibleNames.add(commander.getName());
}
}
this.filter.add(Predicates.or(idsList));
} else {
}
this.compatibleNames = String.join("; ", compatibleNames);
if (compatibleList.isEmpty()) {
// random id to disable condition
this.filter.add(new PermanentIdPredicate(UUID.randomUUID()));
} else {
// oathbreaker on battlefield
this.filter.add(Predicates.or(compatibleList));
}
}
public String getCompatibleNames() {
return !this.compatibleNames.isEmpty() ? this.compatibleNames : "you haven't compatible oathbreaker";
}
@Override
public boolean apply(Game game, Ability source) {
// source.getSourceId() is null for commander's effects

View file

@ -11,6 +11,7 @@ import mage.abilities.mana.*;
import mage.cards.Card;
import mage.choices.Choice;
import mage.constants.ColoredManaSymbol;
import mage.filter.FilterMana;
import mage.game.Game;
import java.util.*;
@ -26,23 +27,23 @@ public final class ManaUtil {
/**
* In case the choice of mana to be produced is obvious, let's discard all
* other abilities.
*
* <p>
* Example: Pay {W}{R}
*
* <p>
* Land produces {W} or {G}.
*
* <p>
* No need to ask what player wants to choose. {W} mana ability should be
* left only.
*
* <p>
* But we CAN do auto choice only in case we have basic mana abilities.
* Example: we should pay {1} and we have Cavern of Souls that can produce
* {1} or any mana of creature type choice. We can't simply auto choose {1}
* as the second mana ability also makes spell uncounterable.
*
* <p>
* In case we can't auto choose we'll simply return the useableAbilities map
* back to caller without any modification.
*
* @param unpaid Mana we need to pay. Can be null (it is for X costs now).
* @param unpaid Mana we need to pay. Can be null (it is for X costs now).
* @param useableAbilities List of mana abilities permanent may produce
* @return List of mana abilities permanent may produce and are reasonable
* for unpaid mana
@ -430,7 +431,6 @@ public final class ManaUtil {
* Converts a collection of mana symbols into a single condensed string e.g.
* {1}{1}{1}{1}{1}{W} = {5}{W} {2}{B}{2}{B}{2}{B} = {6}{B}{B}{B}
* {1}{2}{R}{U}{1}{1} = {5}{R}{U} {B}{G}{R} = {B}{G}{R}
*
*/
public static String condenseManaCostString(String rawCost) {
int total = 0;
@ -466,4 +466,32 @@ public final class ManaUtil {
// Return the condensed string
return sb.toString();
}
public static boolean isColorIdentityCompatible(FilterMana needColors, FilterMana cardColors) {
// colorless can be used with any color
return needColors != null
&& !(cardColors.isBlack() && !needColors.isBlack()
|| cardColors.isBlue() && !needColors.isBlue()
|| cardColors.isGreen() && !needColors.isGreen()
|| cardColors.isRed() && !needColors.isRed()
|| cardColors.isWhite() && !needColors.isWhite());
}
public static void collectColorIdentity(FilterMana destColors, FilterMana newColors) {
if (newColors.isWhite()) {
destColors.setWhite(true);
}
if (newColors.isBlue()) {
destColors.setBlue(true);
}
if (newColors.isBlack()) {
destColors.setBlack(true);
}
if (newColors.isRed()) {
destColors.setRed(true);
}
if (newColors.isGreen()) {
destColors.setGreen(true);
}
}
}