replace filter generators with filter parsers
parent
5b371494a1
commit
91605aa3c1
|
@ -36,6 +36,15 @@ public class ARG {
|
|||
}
|
||||
}
|
||||
|
||||
public static final String NUMBER2 = "(?<number2>[0-9]+)";
|
||||
public static int number2(final Matcher m) {
|
||||
if (m.group("number2") == null) {
|
||||
return 1;
|
||||
} else {
|
||||
return Integer.parseInt(m.group("number2"));
|
||||
}
|
||||
}
|
||||
|
||||
public static final String AMOUNT = "(?<amount>(a|an|one|two|three|four|five|six|seven|eight|nine|ten|eleven|twelve|thirteen|fourteen|fifteen|twenty|x|[0-9]+))";
|
||||
public static int amount(final Matcher m) {
|
||||
return EnglishToInt.convert(m.group("amount"));
|
||||
|
@ -64,7 +73,9 @@ public class ARG {
|
|||
}
|
||||
|
||||
public static final String COLOR = "(?<color>[^ ]+)";
|
||||
public static String color(final Matcher m) {return m.group("color");}
|
||||
public static MagicColor color(final Matcher m) {
|
||||
return MagicColor.getColor(m.group("color"));
|
||||
}
|
||||
|
||||
public static final String EFFECT = "(?<effect>.+)";
|
||||
public static String effect(final Matcher m) {
|
||||
|
|
|
@ -23,8 +23,7 @@ public enum MagicAmountParser {
|
|||
Devotion("your devotion to " + ARG.COLOR) {
|
||||
@Override
|
||||
public MagicAmount toAmount(final Matcher arg) {
|
||||
final MagicColor color = MagicColor.getColor(ARG.color(arg));
|
||||
return MagicAmountFactory.Devotion(color);
|
||||
return MagicAmountFactory.Devotion(ARG.color(arg));
|
||||
}
|
||||
},
|
||||
Equipment("Equipment attached to (it|SN)") {
|
||||
|
|
|
@ -147,7 +147,7 @@ public enum MagicConditionParser {
|
|||
@Override
|
||||
public MagicCondition toCondition(final Matcher arg) {
|
||||
final int amount = ARG.amount(arg);
|
||||
final MagicColor color = MagicColor.valueOf(ARG.color(arg));
|
||||
final MagicColor color = ARG.color(arg);
|
||||
return MagicConditionFactory.DevotionAtLeast(color, amount);
|
||||
}
|
||||
},
|
||||
|
@ -155,7 +155,7 @@ public enum MagicConditionParser {
|
|||
@Override
|
||||
public MagicCondition toCondition(final Matcher arg) {
|
||||
final int amount = 1;
|
||||
final MagicColor color = MagicColor.getColor(ARG.color(arg));
|
||||
final MagicColor color = ARG.color(arg);
|
||||
return MagicConditionFactory.DevotionAtLeast(color, amount);
|
||||
}
|
||||
},
|
||||
|
|
|
@ -2251,12 +2251,6 @@ public class MagicTargetFilterFactory {
|
|||
private static final Map<String, MagicCardFilterImpl> partial =
|
||||
new TreeMap<>(String.CASE_INSENSITIVE_ORDER);
|
||||
|
||||
/**
|
||||
* Single text generators for text with numeric parameters, completely specifying the targeting condition.
|
||||
*/
|
||||
private static final Map<String, MagicTargetFilterGenerator<?>> generatedSingle =
|
||||
new TreeMap<>(String.CASE_INSENSITIVE_ORDER);
|
||||
|
||||
private static void add(final String key, final MagicTargetFilter<?> filter) {
|
||||
if (single.containsKey(key)) {
|
||||
throw new RuntimeException("duplicate key \"" + key + "\"");
|
||||
|
@ -2264,13 +2258,6 @@ public class MagicTargetFilterFactory {
|
|||
single.put(key, filter);
|
||||
}
|
||||
|
||||
private static void add(final String key, final MagicTargetFilterGenerator<?> generator) {
|
||||
if (generatedSingle.containsKey(key)) {
|
||||
throw new RuntimeException("duplicate key \"" + key + "\"");
|
||||
}
|
||||
generatedSingle.put(key, generator);
|
||||
}
|
||||
|
||||
private static void addp(final String key, final MagicCardFilterImpl filter) {
|
||||
if (partial.containsKey(key)) {
|
||||
throw new RuntimeException("duplicate key \"" + key + "\"");
|
||||
|
@ -2342,23 +2329,13 @@ public class MagicTargetFilterFactory {
|
|||
|
||||
// <color|type|subtype> card from your graveyard
|
||||
add("card from your graveyard", CARD_FROM_GRAVEYARD);
|
||||
add("artifact card with converted mana cost # or less from your graveyard",
|
||||
(MagicTargetFilterGenerator<MagicCard>) params ->
|
||||
card(MagicType.Artifact).cmcLEQ(params[0]).from(MagicTargetType.Graveyard));
|
||||
add("noncreature artifact card with converted mana cost 1 or less from your graveyard",
|
||||
NONCREATURE_ARTIFACT_CARD_WITH_CMC_LEQ_1_FROM_GRAVEYARD);
|
||||
add("Rebel permanent card with converted mana cost # or less from your graveyard",
|
||||
(MagicTargetFilterGenerator<MagicCard>) params ->
|
||||
permanentCardMaxCMC(MagicSubType.Rebel, MagicTargetType.Graveyard, params[0]));
|
||||
|
||||
// <color|type|subtype> permanent card from your graveyard
|
||||
add("permanent card from your graveyard", PERMANENT_CARD_FROM_GRAVEYARD);
|
||||
add("permanent card with converted mana cost # or less from your graveyard",
|
||||
(MagicTargetFilterGenerator<MagicCard>) params -> permanentCardMaxCMC(MagicTargetType.Graveyard, params[0]));
|
||||
|
||||
// <color|type|subtype> creature card from your graveyard
|
||||
add("creature card with converted mana cost # or less from your graveyard",
|
||||
(MagicTargetFilterGenerator<MagicCard>) params -> card(MagicType.Creature).cmcLEQ(params[0]).from(MagicTargetType.Graveyard));
|
||||
add("creature card with power 2 or less from your graveyard", CREATURE_CARD_POWER_LEQ_2_FROM_GRAVEYARD);
|
||||
add("creature card with infect from your graveyard", CREATURE_CARD_WITH_INFECT_FROM_GRAVEYARD);
|
||||
add("creature card with scavenge from your graveyard", PAYABLE_CREATURE_CARD_FROM_GRAVEYARD);
|
||||
|
@ -2369,39 +2346,18 @@ public class MagicTargetFilterFactory {
|
|||
|
||||
// <color|type|subtype> card from your hand
|
||||
add("card from your hand", CARD_FROM_HAND);
|
||||
add("instant card with converted mana cost # or less from your hand",
|
||||
(MagicTargetFilterGenerator<MagicCard>) params -> card(MagicType.Instant).from(MagicTargetType.Hand).cmcLEQ(params[0]));
|
||||
|
||||
// <color|type|subtype> card from your library
|
||||
add("card from your library", CARD_FROM_LIBRARY);
|
||||
add("land card with a basic land type from your library", LAND_CARD_WITH_BASIC_LAND_TYPE_FROM_LIBRARY);
|
||||
add("instant card or a card with flash from your library", INSTANT_OR_FLASH_CARD_FROM_LIBRARY);
|
||||
add("enchantment card with converted mana cost # or less from your library",
|
||||
(MagicTargetFilterGenerator<MagicCard>) params -> permanentCardMaxCMC(MagicType.Enchantment, MagicTargetType.Library, params[0]));
|
||||
|
||||
add("artifact card with converted mana cost # or less from your library",
|
||||
(MagicTargetFilterGenerator<MagicCard>) params -> permanentCardMaxCMC(MagicType.Artifact, MagicTargetType.Library, params[0]));
|
||||
add("artifact card with converted mana cost # or greater from your library",
|
||||
(MagicTargetFilterGenerator<MagicCard>) params -> permanentCardMinCMC(MagicType.Artifact, MagicTargetType.Library, params[0]));
|
||||
add("artifact card with converted mana cost # from your library",
|
||||
(MagicTargetFilterGenerator<MagicCard>) params -> permanentCardEqualCMC(MagicType.Artifact, MagicTargetType.Library, params[0]));
|
||||
|
||||
// <color|type|subtype> permanent card from your library
|
||||
MagicSubType[] someSubtypes = new MagicSubType[]{MagicSubType.Rebel, MagicSubType.Mercenary};
|
||||
for (MagicSubType subType: someSubtypes) {
|
||||
add(subType.name() + " permanent card with converted mana cost # or less from your library",
|
||||
(MagicTargetFilterGenerator<MagicCard>) params -> permanentCardMaxCMC(subType, MagicTargetType.Library, params[0])
|
||||
);
|
||||
}
|
||||
|
||||
add("legendary Spirit permanent card from your library", LEGENDARY_SPIRIT_PERMANENT_CARD_FROM_LIBRARY);
|
||||
add("permanent card from your library", PERMANENT_CARD_FROM_LIBRARY);
|
||||
|
||||
// <color|type|subtype> creature card from your library
|
||||
add("creature card with converted mana cost # or less from your library",
|
||||
(MagicTargetFilterGenerator<MagicCard>) params -> permanentCardMaxCMC(MagicType.Creature, MagicTargetType.Library, params[0]));
|
||||
add("creature card with converted mana cost # or greater from your library",
|
||||
(MagicTargetFilterGenerator<MagicCard>) params -> permanentCardMinCMC(MagicType.Creature, MagicTargetType.Library, params[0]));
|
||||
add("creature card with power 2 or less from your library", CREATURE_CARD_POWER_LEQ_2_FROM_LIBRARY);
|
||||
add("creature card with deathtouch, hexproof, reach, or trample from your library", CREATURE_WITH_DEATHTOUCH_HEXPROOF_REACH_OR_TRAMPLE_FROM_LIBRARY);
|
||||
add("nonlegendary green creature card with converted mana cost 3 or less from your library", NON_LEGENDARY_GREEN_CREATURE_CARD_WITH_CMC_LEQ_3_FROM_LIBRARY);
|
||||
|
@ -2413,12 +2369,6 @@ public class MagicTargetFilterFactory {
|
|||
for (MagicColor c1 : MagicColor.values()) {
|
||||
// Single colored attacking, i.e. "nonblue attacking creature"
|
||||
add("non" + c1.name() + " attacking creature", creatureNon(c1, Control.Any).andAttacking());
|
||||
// Single colored with power, i.e. "white creature with power 3 or greater"
|
||||
add(c1.name() + " creature with power # or greater", (MagicTargetFilterGenerator<MagicPermanent>) params ->
|
||||
new MagicPTTargetFilter(creature(c1, Control.Any), Operator.GREATER_THAN_OR_EQUAL, params[0]));
|
||||
// Single colored with power, i.e. "nonwhite creature with power 3 or greater"
|
||||
add("non" + c1.name() + " creature with power # or greater", (MagicTargetFilterGenerator<MagicPermanent>) params ->
|
||||
new MagicPTTargetFilter(creatureNon(c1, Control.Any), Operator.GREATER_THAN_OR_EQUAL, params[0]));
|
||||
|
||||
for (MagicColor c2 : MagicColor.values()) {
|
||||
if (c1 != c2) {
|
||||
|
@ -2437,8 +2387,6 @@ public class MagicTargetFilterFactory {
|
|||
add("black or red creature that's attacking or blocking", BLACK_OR_RED_CREATURE_ATTACKING_OR_BLOCKING);
|
||||
add("blue or black creature with flying", BLUE_OR_BLACK_CREATURE_WITH_FLYING);
|
||||
|
||||
add("#/# creature", (MagicTargetFilterGenerator<MagicPermanent>) params ->
|
||||
new MagicPTTargetFilter(CREATURE, Operator.EQUAL, params[0], Operator.EQUAL, params[1]));
|
||||
add("creature with modular", MODULAR_CREATURE);
|
||||
add("creature with trample", CREATURE_WITH_TRAMPLE);
|
||||
add("creature with level up", LEVELUP_CREATURE);
|
||||
|
@ -2461,8 +2409,6 @@ public class MagicTargetFilterFactory {
|
|||
add("nonattacking creature", NONATTACKING_CREATURE);
|
||||
add("blocked creature", BLOCKED_CREATURE);
|
||||
add("blocking creature", BLOCKING_CREATURE);
|
||||
add("creature with converted mana cost # or less", (MagicTargetFilterGenerator<MagicPermanent>) params ->
|
||||
permanent(MagicType.Creature, Control.Any).cmcLEQ(params[0]));
|
||||
add("creature with flying", CREATURE_WITH_FLYING);
|
||||
add("creature with flying or reach", CREATURE_WITH_FLYING_OR_REACH);
|
||||
add("creature without flying", CREATURE_WITHOUT_FLYING);
|
||||
|
@ -2473,15 +2419,6 @@ public class MagicTargetFilterFactory {
|
|||
add("creature with horsemanship", CREATURE_WITH_HORSEMANSHIP);
|
||||
add("creature with islandwalk", CREATURE_WITH_ISLANDWALK);
|
||||
|
||||
add("creature with power # or less", (MagicTargetFilterGenerator<MagicPermanent>) params ->
|
||||
new MagicPTTargetFilter(CREATURE, Operator.LESS_THAN_OR_EQUAL, params[0]));
|
||||
add("creature with power # or greater", (MagicTargetFilterGenerator<MagicPermanent>) params ->
|
||||
new MagicPTTargetFilter(CREATURE, Operator.GREATER_THAN_OR_EQUAL, params[0]));
|
||||
add("creature with toughness # or less", (MagicTargetFilterGenerator<MagicPermanent>) params ->
|
||||
MagicPTTargetFilter.Toughness(CREATURE, Operator.LESS_THAN_OR_EQUAL, params[0]));
|
||||
add("creature with toughness # or greater", (MagicTargetFilterGenerator<MagicPermanent>) params ->
|
||||
MagicPTTargetFilter.Toughness(CREATURE, Operator.GREATER_THAN_OR_EQUAL, params[0]));
|
||||
|
||||
add("creature with power or toughness 1 or less", CREATURE_POWER_OR_TOUGHNESS_1_OR_LESS);
|
||||
add("creature with power greater than SN's power", CREATURE_POWER_GREATER_THAN_SN);
|
||||
add("creature with power less than SN's power", CREATURE_POWER_LESS_THAN_SN);
|
||||
|
@ -2595,9 +2532,6 @@ public class MagicTargetFilterFactory {
|
|||
add("artifact or land", ARTIFACT_OR_LAND);
|
||||
add("artifact land", ARTIFACT_LAND);
|
||||
add("artifact or enchantment", ARTIFACT_OR_ENCHANTMENT);
|
||||
add("artifact or enchantment with converted mana cost # or less",
|
||||
(MagicTargetFilterGenerator<MagicPermanent>) params ->
|
||||
new MagicCMCPermanentFilter(ARTIFACT_OR_ENCHANTMENT, Operator.LESS_THAN_OR_EQUAL, params[0]));
|
||||
add("artifact, enchantment, or land", ARTIFACT_OR_ENCHANTMENT_OR_LAND);
|
||||
add("artifact, creature, or land", ARTIFACT_OR_CREATURE_OR_LAND);
|
||||
add("artifact, creature, or enchantment", ARTIFACT_OR_CREATURE_OR_ENCHANTMENT);
|
||||
|
@ -2674,28 +2608,12 @@ public class MagicTargetFilterFactory {
|
|||
add("enchantment, instant, or sorcery spell", ENCHANTMENT_OR_INSTANT_OR_SORCERY_SPELL);
|
||||
add("white or blue instant or sorcery spell", WHITE_OR_BLUE_INSTANT_OR_SORCERY_SPELL);
|
||||
add("instant or sorcery spell you control", INSTANT_OR_SORCERY_SPELL_YOU_CONTROL);
|
||||
add("spell with converted mana cost #",
|
||||
(MagicTargetFilterGenerator<MagicItemOnStack>) params -> SPELL.cmcEQ(params[0]));
|
||||
add("spell with converted mana cost # or less",
|
||||
(MagicTargetFilterGenerator<MagicItemOnStack>) params -> SPELL.cmcLEQ(params[0]));
|
||||
add("spell with converted mana cost # or greater",
|
||||
(MagicTargetFilterGenerator<MagicItemOnStack>) params -> SPELL.cmcGEQ(params[0]));
|
||||
add("instant spell you control with converted mana cost # or less",
|
||||
(MagicTargetFilterGenerator<MagicItemOnStack>) params -> spell(MagicType.Instant).youControl().cmcLEQ(params[0]));
|
||||
add("sorcery spell you control with converted mana cost # or less",
|
||||
(MagicTargetFilterGenerator<MagicItemOnStack>) params -> spell(MagicType.Sorcery).youControl().cmcLEQ(params[0]));
|
||||
add("creature spell with converted mana cost # or less",
|
||||
(MagicTargetFilterGenerator<MagicItemOnStack>) params -> spell(MagicType.Creature).cmcLEQ(params[0]));
|
||||
add("creature spell with converted mana cost # or greater",
|
||||
(MagicTargetFilterGenerator<MagicItemOnStack>) params -> spell(MagicType.Creature).cmcGEQ(params[0]));
|
||||
add("creature spell with infect", CREATURE_SPELL_WITH_INFECT);
|
||||
add("creature or Aura spell", CREATURE_OR_AURA_SPELL);
|
||||
add("creature or sorcery spell", CREATURE_OR_SORCERY_SPELL);
|
||||
add("Spirit or Arcane spell", SPIRIT_OR_ARCANE_SPELL);
|
||||
add("multicolored spell", MULTICOLORED_SPELL);
|
||||
add("colorless spell", COLORLESS_SPELL);
|
||||
add("colorless spell with converted mana cost # or greater",
|
||||
(MagicTargetFilterGenerator<MagicItemOnStack>) params -> COLORLESS_SPELL.cmcGEQ(params[0]));
|
||||
add("aura, equipment, or vehicle spell", AURA_EQUIPMENT_OR_VEHICLE_SPELL);
|
||||
|
||||
// player
|
||||
|
@ -2821,7 +2739,7 @@ public class MagicTargetFilterFactory {
|
|||
final String filter = arg
|
||||
.replaceFirst("^(a|an) ", "")
|
||||
.replaceFirst(" to sacrifice$", " you control");
|
||||
if (singleContainsKey(filter)) {
|
||||
if (single.containsKey(filter)) {
|
||||
assert single.get(filter) != null : "return null for " + filter;
|
||||
return single.get(filter);
|
||||
} else {
|
||||
|
@ -2829,6 +2747,14 @@ public class MagicTargetFilterFactory {
|
|||
}
|
||||
}
|
||||
|
||||
public static MagicTargetFilter<?> singleOrNone(final String arg) {
|
||||
try {
|
||||
return single(arg);
|
||||
} catch (final RuntimeException e) {
|
||||
return NONE;
|
||||
}
|
||||
}
|
||||
|
||||
public static MagicCardFilterImpl matchCardPrefix(final String arg, final String prefix, final MagicTargetType location) {
|
||||
DetectedPrefixes dp = DetectedPrefixes.parseFrom(prefix);
|
||||
switch (dp.prefixType) {
|
||||
|
@ -2923,16 +2849,21 @@ public class MagicTargetFilterFactory {
|
|||
default:
|
||||
}
|
||||
final String withSuffix = prefix + " permanent";
|
||||
if (singleContainsKey(withSuffix)) {
|
||||
if (!withSuffix.equals(arg)) {
|
||||
@SuppressWarnings("unchecked")
|
||||
final MagicTargetFilter<MagicPermanent> filter = (MagicPermanentFilterImpl)single.get(withSuffix);
|
||||
return permanent(filter, control);
|
||||
final MagicTargetFilter<MagicPermanent> filter = (MagicPermanentFilterImpl)singleOrNone(withSuffix);
|
||||
if (filter != NONE) {
|
||||
return permanent(filter, control);
|
||||
}
|
||||
}
|
||||
if (singleContainsKey(prefix)) {
|
||||
if (!prefix.equals(arg)) {
|
||||
@SuppressWarnings("unchecked")
|
||||
final MagicTargetFilter<MagicPermanent> filter = (MagicPermanentFilterImpl)single.get(prefix);
|
||||
return permanent(filter, control);
|
||||
final MagicTargetFilter<MagicPermanent> filter = (MagicPermanentFilterImpl)singleOrNone(prefix);
|
||||
if (filter != NONE) {
|
||||
return permanent(filter, control);
|
||||
}
|
||||
}
|
||||
|
||||
throw new RuntimeException("unknown target filter \"" + arg + "\"");
|
||||
}
|
||||
|
||||
|
@ -2950,21 +2881,6 @@ public class MagicTargetFilterFactory {
|
|||
return params.toArray(EMPTY_INTEGER_ARRAY);
|
||||
}
|
||||
|
||||
private static boolean singleContainsKey(String key) {
|
||||
if (single.containsKey(key)) {
|
||||
return true;
|
||||
}
|
||||
String numericKey = NUM_PATTERN.matcher(key).replaceAll("#");
|
||||
if (generatedSingle.containsKey(numericKey)) {
|
||||
// We can use parametric filter generator
|
||||
Integer[] params = extractMatches(NUM_PATTERN, key);
|
||||
MagicTargetFilterGenerator<?> generator = generatedSingle.get(numericKey);
|
||||
MagicTargetFilter<?> generated = generator.generate(params);
|
||||
single.put(key, generated);
|
||||
}
|
||||
return single.containsKey(key);
|
||||
}
|
||||
|
||||
public static MagicTargetFilter<MagicPermanent> matchCreaturePrefix(final String arg, final String prefix, final Control control) {
|
||||
DetectedPrefixes dp = DetectedPrefixes.parseFrom(prefix);
|
||||
switch (dp.prefixType) {
|
||||
|
@ -2983,11 +2899,15 @@ public class MagicTargetFilterFactory {
|
|||
default:
|
||||
}
|
||||
final String withSuffix = prefix + " creature";
|
||||
if (singleContainsKey(withSuffix)) {
|
||||
|
||||
if (!withSuffix.equals(arg)) {
|
||||
@SuppressWarnings("unchecked")
|
||||
final MagicTargetFilter<MagicPermanent> filter = (MagicPermanentFilterImpl)single.get(withSuffix);
|
||||
return permanent(filter, control);
|
||||
final MagicTargetFilter<MagicPermanent> filter = (MagicPermanentFilterImpl)singleOrNone(withSuffix);
|
||||
if (filter != NONE) {
|
||||
return permanent(filter, control);
|
||||
}
|
||||
}
|
||||
|
||||
throw new RuntimeException("unknown target filter \"" + arg + "\"");
|
||||
}
|
||||
|
||||
|
@ -3001,7 +2921,7 @@ public class MagicTargetFilterFactory {
|
|||
default:
|
||||
}
|
||||
final String withSuffix = prefix + " planeswalker";
|
||||
if (singleContainsKey(withSuffix)) {
|
||||
if (single.containsKey(withSuffix)) {
|
||||
@SuppressWarnings("unchecked")
|
||||
final MagicTargetFilter<MagicPermanent> filter = (MagicPermanentFilterImpl)single.get(withSuffix);
|
||||
return permanent(filter, control);
|
||||
|
|
|
@ -1,10 +0,0 @@
|
|||
package magic.model.target;
|
||||
|
||||
/**
|
||||
* Generator for parametric filters with one or more numeric parameters.
|
||||
* Each '#' in the text is matched with one number from input.
|
||||
* Number of parameters will always be equal to the number of '#' characters in the text.
|
||||
*/
|
||||
public interface MagicTargetFilterGenerator<T extends MagicTarget> {
|
||||
MagicTargetFilter<T> generate(Integer... parameters);
|
||||
}
|
|
@ -5,10 +5,194 @@ import java.util.regex.Pattern;
|
|||
|
||||
import magic.model.ARG;
|
||||
import magic.model.MagicPermanentState;
|
||||
import magic.model.MagicType;
|
||||
import magic.model.MagicSubType;
|
||||
import magic.model.target.MagicTargetFilterFactory.Control;
|
||||
|
||||
public enum MagicTargetFilterParser {
|
||||
import static magic.model.target.MagicTargetFilterFactory.*;
|
||||
|
||||
public enum MagicTargetFilterParser {
|
||||
CARD1("artifact card with converted mana cost " + ARG.NUMBER + " or less from your graveyard") {
|
||||
@Override
|
||||
public MagicTargetFilter<?> toTargetFilter(final Matcher arg) {
|
||||
return card(MagicType.Artifact).cmcLEQ(ARG.number(arg)).from(MagicTargetType.Graveyard);
|
||||
}
|
||||
},
|
||||
CARD2("Rebel permanent card with converted mana cost " + ARG.NUMBER + " or less from your graveyard") {
|
||||
@Override
|
||||
public MagicTargetFilter<?> toTargetFilter(final Matcher arg) {
|
||||
return permanentCardMaxCMC(MagicSubType.Rebel, MagicTargetType.Graveyard, ARG.number(arg));
|
||||
}
|
||||
},
|
||||
CARD3("permanent card with converted mana cost " + ARG.NUMBER + " or less from your graveyard") {
|
||||
@Override
|
||||
public MagicTargetFilter<?> toTargetFilter(final Matcher arg) {
|
||||
return permanentCardMaxCMC(MagicTargetType.Graveyard, ARG.number(arg));
|
||||
}
|
||||
},
|
||||
CARD4("creature card with converted mana cost " + ARG.NUMBER + " or less from your graveyard") {
|
||||
@Override
|
||||
public MagicTargetFilter<?> toTargetFilter(final Matcher arg) {
|
||||
return card(MagicType.Creature).cmcLEQ(ARG.number(arg)).from(MagicTargetType.Graveyard);
|
||||
}
|
||||
},
|
||||
CARD5("instant card with converted mana cost " + ARG.NUMBER + " or less from your hand") {
|
||||
@Override
|
||||
public MagicTargetFilter<?> toTargetFilter(final Matcher arg) {
|
||||
return card(MagicType.Instant).from(MagicTargetType.Hand).cmcLEQ(ARG.number(arg));
|
||||
}
|
||||
},
|
||||
CARD6("enchantment card with converted mana cost " + ARG.NUMBER + " or less from your library") {
|
||||
@Override
|
||||
public MagicTargetFilter<?> toTargetFilter(final Matcher arg) {
|
||||
return permanentCardMaxCMC(MagicType.Enchantment, MagicTargetType.Library, ARG.number(arg));
|
||||
}
|
||||
},
|
||||
CARD7("artifact card with converted mana cost " + ARG.NUMBER + " or less from your library") {
|
||||
@Override
|
||||
public MagicTargetFilter<?> toTargetFilter(final Matcher arg) {
|
||||
return permanentCardMaxCMC(MagicType.Artifact, MagicTargetType.Library, ARG.number(arg));
|
||||
}
|
||||
},
|
||||
CARD8("artifact card with converted mana cost " + ARG.NUMBER + " or greater from your library") {
|
||||
@Override
|
||||
public MagicTargetFilter<?> toTargetFilter(final Matcher arg) {
|
||||
return permanentCardMinCMC(MagicType.Artifact, MagicTargetType.Library, ARG.number(arg));
|
||||
}
|
||||
},
|
||||
CARD9("artifact card with converted mana cost " + ARG.NUMBER + " from your library") {
|
||||
@Override
|
||||
public MagicTargetFilter<?> toTargetFilter(final Matcher arg) {
|
||||
return permanentCardEqualCMC(MagicType.Artifact, MagicTargetType.Library, ARG.number(arg));
|
||||
}
|
||||
},
|
||||
CARD10("Rebel permanent card with converted mana cost " + ARG.NUMBER + " or less from your library") {
|
||||
@Override
|
||||
public MagicTargetFilter<?> toTargetFilter(final Matcher arg) {
|
||||
return permanentCardMaxCMC(MagicSubType.Rebel, MagicTargetType.Library, ARG.number(arg));
|
||||
}
|
||||
},
|
||||
CARD11("Mercenary permanent card with converted mana cost " + ARG.NUMBER + " or less from your library") {
|
||||
@Override
|
||||
public MagicTargetFilter<?> toTargetFilter(final Matcher arg) {
|
||||
return permanentCardMaxCMC(MagicSubType.Mercenary, MagicTargetType.Library, ARG.number(arg));
|
||||
}
|
||||
},
|
||||
CARD12("creature card with converted mana cost " + ARG.NUMBER + " or less from your library") {
|
||||
@Override
|
||||
public MagicTargetFilter<?> toTargetFilter(final Matcher arg) {
|
||||
return permanentCardMaxCMC(MagicType.Creature, MagicTargetType.Library, ARG.number(arg));
|
||||
}
|
||||
},
|
||||
CARD13("creature card with converted mana cost " + ARG.NUMBER + " or greater from your library") {
|
||||
@Override
|
||||
public MagicTargetFilter<?> toTargetFilter(final Matcher arg) {
|
||||
return permanentCardMinCMC(MagicType.Creature, MagicTargetType.Library, ARG.number(arg));
|
||||
}
|
||||
},
|
||||
|
||||
PERM2("non" + ARG.COLOR + " creature with power " + ARG.NUMBER + " or greater") {
|
||||
@Override
|
||||
public MagicTargetFilter<?> toTargetFilter(final Matcher arg) {
|
||||
return new MagicPTTargetFilter(creatureNon(ARG.color(arg), Control.Any), Operator.GREATER_THAN_OR_EQUAL, ARG.number(arg));
|
||||
}
|
||||
},
|
||||
PERM1(ARG.COLOR + " creature with power " + ARG.NUMBER + " or greater") {
|
||||
@Override
|
||||
public MagicTargetFilter<?> toTargetFilter(final Matcher arg) {
|
||||
return new MagicPTTargetFilter(creature(ARG.color(arg), Control.Any), Operator.GREATER_THAN_OR_EQUAL, ARG.number(arg));
|
||||
}
|
||||
},
|
||||
PERM3(ARG.NUMBER + "/" + ARG.NUMBER2 + " creature") {
|
||||
@Override
|
||||
public MagicTargetFilter<?> toTargetFilter(final Matcher arg) {
|
||||
return new MagicPTTargetFilter(CREATURE, Operator.EQUAL, ARG.number(arg), Operator.EQUAL, ARG.number2(arg));
|
||||
}
|
||||
},
|
||||
PERM4("creature with converted mana cost " + ARG.NUMBER + " or less") {
|
||||
@Override
|
||||
public MagicTargetFilter<?> toTargetFilter(final Matcher arg) {
|
||||
return permanent(MagicType.Creature, Control.Any).cmcLEQ(ARG.number(arg));
|
||||
}
|
||||
},
|
||||
PERM5("creature with power " + ARG.NUMBER + " or less") {
|
||||
@Override
|
||||
public MagicTargetFilter<?> toTargetFilter(final Matcher arg) {
|
||||
return new MagicPTTargetFilter(CREATURE, Operator.LESS_THAN_OR_EQUAL, ARG.number(arg));
|
||||
}
|
||||
},
|
||||
PERM6("creature with power " + ARG.NUMBER + " or greater") {
|
||||
@Override
|
||||
public MagicTargetFilter<?> toTargetFilter(final Matcher arg) {
|
||||
return new MagicPTTargetFilter(CREATURE, Operator.GREATER_THAN_OR_EQUAL, ARG.number(arg));
|
||||
}
|
||||
},
|
||||
PERM7("creature with toughness " + ARG.NUMBER + " or less") {
|
||||
@Override
|
||||
public MagicTargetFilter<?> toTargetFilter(final Matcher arg) {
|
||||
return MagicPTTargetFilter.Toughness(CREATURE, Operator.LESS_THAN_OR_EQUAL, ARG.number(arg));
|
||||
}
|
||||
},
|
||||
PERM8("creature with toughness " + ARG.NUMBER + " or greater") {
|
||||
@Override
|
||||
public MagicTargetFilter<?> toTargetFilter(final Matcher arg) {
|
||||
return MagicPTTargetFilter.Toughness(CREATURE, Operator.GREATER_THAN_OR_EQUAL, ARG.number(arg));
|
||||
}
|
||||
},
|
||||
PERM9("artifact or enchantment with converted mana cost " + ARG.NUMBER + " or less") {
|
||||
@Override
|
||||
public MagicTargetFilter<?> toTargetFilter(final Matcher arg) {
|
||||
return new MagicCMCPermanentFilter(ARTIFACT_OR_ENCHANTMENT, Operator.LESS_THAN_OR_EQUAL, ARG.number(arg));
|
||||
}
|
||||
},
|
||||
SPELL1("spell with converted mana cost " + ARG.NUMBER) {
|
||||
@Override
|
||||
public MagicTargetFilter<?> toTargetFilter(final Matcher arg) {
|
||||
return SPELL.cmcEQ(ARG.number(arg));
|
||||
}
|
||||
},
|
||||
SPELL2("spell with converted mana cost " + ARG.NUMBER + " or less") {
|
||||
@Override
|
||||
public MagicTargetFilter<?> toTargetFilter(final Matcher arg) {
|
||||
return SPELL.cmcLEQ(ARG.number(arg));
|
||||
}
|
||||
},
|
||||
SPELL3("spell with converted mana cost " + ARG.NUMBER + " or greater") {
|
||||
@Override
|
||||
public MagicTargetFilter<?> toTargetFilter(final Matcher arg) {
|
||||
return SPELL.cmcGEQ(ARG.number(arg));
|
||||
}
|
||||
},
|
||||
SPELL4("instant spell you control with converted mana cost " + ARG.NUMBER + " or less") {
|
||||
@Override
|
||||
public MagicTargetFilter<?> toTargetFilter(final Matcher arg) {
|
||||
return spell(MagicType.Instant).youControl().cmcLEQ(ARG.number(arg));
|
||||
}
|
||||
},
|
||||
SPELL5("sorcery spell you control with converted mana cost " + ARG.NUMBER + " or less") {
|
||||
@Override
|
||||
public MagicTargetFilter<?> toTargetFilter(final Matcher arg) {
|
||||
return spell(MagicType.Sorcery).youControl().cmcLEQ(ARG.number(arg));
|
||||
}
|
||||
},
|
||||
SPELL6("creature spell with converted mana cost " + ARG.NUMBER + " or less") {
|
||||
@Override
|
||||
public MagicTargetFilter<?> toTargetFilter(final Matcher arg) {
|
||||
return spell(MagicType.Creature).cmcLEQ(ARG.number(arg));
|
||||
}
|
||||
},
|
||||
SPELL7("creature spell with converted mana cost " + ARG.NUMBER + " or greater") {
|
||||
@Override
|
||||
public MagicTargetFilter<?> toTargetFilter(final Matcher arg) {
|
||||
return spell(MagicType.Creature).cmcGEQ(ARG.number(arg));
|
||||
}
|
||||
},
|
||||
SPELL8("colorless spell with converted mana cost " + ARG.NUMBER + " or greater") {
|
||||
@Override
|
||||
public MagicTargetFilter<?> toTargetFilter(final Matcher arg) {
|
||||
return COLORLESS_SPELL.cmcGEQ(ARG.number(arg));
|
||||
}
|
||||
},
|
||||
CardNamedFromYourLibrary("card named " + ARG.ANY + " from your library") {
|
||||
@Override
|
||||
public MagicTargetFilter<?> toTargetFilter(final Matcher arg) {
|
||||
|
|
Loading…
Reference in New Issue