forked from External/mage
121 lines
4.4 KiB
Java
121 lines
4.4 KiB
Java
package mage.target.common;
|
|
|
|
import mage.abilities.Ability;
|
|
import mage.abilities.assignment.common.PredicateCardAssignment;
|
|
import mage.cards.Card;
|
|
import mage.cards.Cards;
|
|
import mage.cards.CardsImpl;
|
|
import mage.constants.CardType;
|
|
import mage.constants.Zone;
|
|
import mage.filter.FilterCard;
|
|
import mage.filter.predicate.Predicate;
|
|
import mage.filter.predicate.Predicates;
|
|
import mage.filter.predicate.mageobject.NamePredicate;
|
|
import mage.game.Game;
|
|
import mage.target.TargetCard;
|
|
import mage.util.CardUtil;
|
|
|
|
import java.util.HashSet;
|
|
import java.util.Set;
|
|
import java.util.UUID;
|
|
|
|
/**
|
|
* @author Susucr
|
|
* <p>
|
|
* almost identical to {@link TargetCardAndOrCardInLibrary}
|
|
*/
|
|
public class TargetCardAndOrCard extends TargetCard {
|
|
|
|
private static FilterCard makeFilter(Predicate<? super Card> firstPredicate,
|
|
Predicate<? super Card> secondPredicate,
|
|
String filterText) {
|
|
FilterCard filter = new FilterCard(filterText);
|
|
filter.add(Predicates.or(
|
|
firstPredicate, secondPredicate
|
|
));
|
|
return filter;
|
|
}
|
|
|
|
private static String makeFilterText(String first, String second) {
|
|
return CardUtil.addArticle(first) + " card and/or " + CardUtil.addArticle(second) + " card";
|
|
}
|
|
|
|
private final PredicateCardAssignment assignment;
|
|
|
|
/**
|
|
* a [firstType] card and/or a [secondType] card
|
|
*/
|
|
protected TargetCardAndOrCard(Predicate<? super Card> firstPredicate, Predicate<? super Card> secondPredicate, String filterText) {
|
|
super(0, 2, Zone.ALL, makeFilter(firstPredicate, secondPredicate, filterText));
|
|
this.assignment = new PredicateCardAssignment(firstPredicate, secondPredicate);
|
|
}
|
|
|
|
public TargetCardAndOrCard(String firstName, String secondName) {
|
|
this(new NamePredicate(firstName), new NamePredicate(secondName), "a card named " + firstName + " and/or a card named " + secondName);
|
|
}
|
|
|
|
public TargetCardAndOrCard(CardType firstType, CardType secondType) {
|
|
this(firstType.getPredicate(), secondType.getPredicate(), makeFilterText(
|
|
CardUtil.getTextWithFirstCharLowerCase(firstType.toString()),
|
|
CardUtil.getTextWithFirstCharLowerCase(secondType.toString())));
|
|
}
|
|
|
|
protected TargetCardAndOrCard(final TargetCardAndOrCard target) {
|
|
super(target);
|
|
this.assignment = target.assignment;
|
|
}
|
|
|
|
@Override
|
|
public TargetCardAndOrCard copy() {
|
|
return new TargetCardAndOrCard(this);
|
|
}
|
|
|
|
@Override
|
|
public boolean canTarget(UUID playerId, UUID id, Ability source, Game game) {
|
|
if (!super.canTarget(playerId, id, source, game)) {
|
|
return false;
|
|
}
|
|
Card card = game.getCard(id);
|
|
if (card == null) {
|
|
return false;
|
|
}
|
|
if (this.getTargets().isEmpty()) {
|
|
return true;
|
|
}
|
|
Cards cards = new CardsImpl(this.getTargets());
|
|
cards.add(card);
|
|
return assignment.getRoleCount(cards, game) >= cards.size();
|
|
}
|
|
|
|
@Override
|
|
public Set<UUID> possibleTargets(UUID sourceControllerId, Ability source, Game game) {
|
|
Set<UUID> possibleTargets = super.possibleTargets(sourceControllerId, source, game);
|
|
// assuming max targets = 2, need to expand this code if not
|
|
Card card = game.getCard(this.getFirstTarget());
|
|
if (card == null) {
|
|
return possibleTargets; // no further restriction if no target yet chosen
|
|
}
|
|
Cards cards = new CardsImpl(card);
|
|
if (assignment.getRoleCount(cards, game) == 2) {
|
|
// if the first chosen target is both types, no further restriction
|
|
return possibleTargets;
|
|
}
|
|
Set<UUID> leftPossibleTargets = new HashSet<>();
|
|
for (UUID possibleId : possibleTargets) {
|
|
Card possibleCard = game.getCard(possibleId);
|
|
Cards checkCards = cards.copy();
|
|
checkCards.add(possibleCard);
|
|
if (assignment.getRoleCount(checkCards, game) == 2) {
|
|
// if the possible target and the existing target have both types, it's legal
|
|
// but this prevents the case of both targets with the same type
|
|
leftPossibleTargets.add(possibleId);
|
|
}
|
|
}
|
|
return leftPossibleTargets;
|
|
}
|
|
|
|
@Override
|
|
public String getDescription() {
|
|
return filter.getMessage();
|
|
}
|
|
}
|