mirror of
https://github.com/correl/mage.git
synced 2024-11-14 19:19:32 +00:00
Added modal double faces cards implementation (MDF cards, #7012)
This commit is contained in:
parent
bbed5a16b8
commit
8ac78b4b9e
60 changed files with 1128 additions and 764 deletions
|
@ -1,8 +1,6 @@
|
|||
package mage.view;
|
||||
|
||||
import com.google.gson.annotations.Expose;
|
||||
import java.util.*;
|
||||
import java.util.stream.Collectors;
|
||||
import mage.MageObject;
|
||||
import mage.ObjectColor;
|
||||
import mage.abilities.Abilities;
|
||||
|
@ -31,6 +29,9 @@ import mage.target.Targets;
|
|||
import mage.util.CardUtil;
|
||||
import mage.util.SubTypeList;
|
||||
|
||||
import java.util.*;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
/**
|
||||
* @author BetaSteward_at_googlemail.com
|
||||
*/
|
||||
|
@ -95,6 +96,8 @@ public class CardView extends SimpleCardView {
|
|||
protected List<String> rightSplitRules;
|
||||
protected String rightSplitTypeLine;
|
||||
|
||||
protected boolean isModalDoubleFacesCard;
|
||||
|
||||
protected ArtRect artRect = ArtRect.NORMAL;
|
||||
|
||||
protected List<UUID> targets;
|
||||
|
@ -187,6 +190,8 @@ public class CardView extends SimpleCardView {
|
|||
this.rightSplitRules = cardView.rightSplitRules == null ? null : new ArrayList<>(cardView.rightSplitRules);
|
||||
this.rightSplitTypeLine = cardView.rightSplitTypeLine;
|
||||
|
||||
this.isModalDoubleFacesCard = cardView.isModalDoubleFacesCard;
|
||||
|
||||
this.artRect = cardView.artRect;
|
||||
this.targets = cardView.targets == null ? null : new ArrayList<>(cardView.targets);
|
||||
this.pairedCard = cardView.pairedCard;
|
||||
|
@ -299,7 +304,7 @@ public class CardView extends SimpleCardView {
|
|||
}
|
||||
|
||||
SplitCard splitCard = null;
|
||||
if (card.isSplitCard()) {
|
||||
if (card instanceof SplitCard) {
|
||||
splitCard = (SplitCard) card;
|
||||
rotate = (card.getSpellAbility().getSpellAbilityType()) != SpellAbilityType.SPLIT_AFTERMATH;
|
||||
} else if (card instanceof Spell) {
|
||||
|
@ -316,6 +321,10 @@ public class CardView extends SimpleCardView {
|
|||
case SPLIT_RIGHT:
|
||||
rotate = true;
|
||||
break;
|
||||
case MODAL_LEFT:
|
||||
case MODAL_RIGHT:
|
||||
rotate = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -334,6 +343,12 @@ public class CardView extends SimpleCardView {
|
|||
fullCardName = card.getName(); // split card contains full name as normal
|
||||
this.manaCostLeft = splitCard.getLeftHalfCard().getManaCost().getSymbols();
|
||||
this.manaCostRight = splitCard.getRightHalfCard().getManaCost().getSymbols();
|
||||
} else if (card instanceof ModalDoubleFacesCard) {
|
||||
this.isModalDoubleFacesCard = true;
|
||||
ModalDoubleFacesCard mainCard = ((ModalDoubleFacesCard) card);
|
||||
fullCardName = mainCard.getLeftHalfCard().getName() + MockCard.MODAL_DOUBLE_FACES_NAME_SEPARATOR + mainCard.getRightHalfCard().getName();
|
||||
this.manaCostLeft = mainCard.getLeftHalfCard().getManaCost().getSymbols();
|
||||
this.manaCostRight = mainCard.getRightHalfCard().getManaCost().getSymbols();
|
||||
} else if (card instanceof AdventureCard) {
|
||||
AdventureCard adventureCard = ((AdventureCard) card);
|
||||
AdventureCardSpell adventureCardSpell = ((AdventureCardSpell) adventureCard.getSpellCard());
|
||||
|
@ -455,6 +470,7 @@ public class CardView extends SimpleCardView {
|
|||
|
||||
// Determine what part of the art to slice out for spells on the stack which originate
|
||||
// from a split, fuse, or aftermath split card.
|
||||
// Modal double faces cards draws as normal cards
|
||||
SpellAbilityType ty = spell.getSpellAbility().getSpellAbilityType();
|
||||
if (ty == SpellAbilityType.SPLIT_RIGHT || ty == SpellAbilityType.SPLIT_LEFT || ty == SpellAbilityType.SPLIT_FUSED) {
|
||||
// Needs a special art rect
|
||||
|
|
|
@ -1,9 +1,6 @@
|
|||
package mage.deck;
|
||||
|
||||
import mage.cards.Card;
|
||||
import mage.cards.ExpansionSet;
|
||||
import mage.cards.Sets;
|
||||
import mage.cards.SplitCard;
|
||||
import mage.cards.*;
|
||||
import mage.cards.decks.Constructed;
|
||||
import mage.cards.decks.Deck;
|
||||
import mage.cards.decks.DeckValidatorErrorType;
|
||||
|
@ -199,21 +196,27 @@ public class TinyLeaders extends Constructed {
|
|||
return false;
|
||||
}
|
||||
|
||||
//905.5b - Converted mana cost must be 3 or less
|
||||
// 906.5b
|
||||
// Each card must have a converted mana cost of three or less. Cards with {x} in their mana cost count X
|
||||
// as zero for this purpose. Split cards are legal only if both of their halves would be legal independently.
|
||||
List<Integer> costs = new ArrayList<>();
|
||||
if (card instanceof SplitCard) {
|
||||
if (((SplitCard) card).getLeftHalfCard().getManaCost().convertedManaCost() > 3) {
|
||||
addError(DeckValidatorErrorType.OTHER, card.getName(), "Invalid cost (" + ((SplitCard) card).getLeftHalfCard().getManaCost().convertedManaCost() + ')', true);
|
||||
return false;
|
||||
}
|
||||
if (((SplitCard) card).getRightHalfCard().getManaCost().convertedManaCost() > 3) {
|
||||
addError(DeckValidatorErrorType.OTHER, card.getName(), "Invalid cost (" + ((SplitCard) card).getRightHalfCard().getManaCost().convertedManaCost() + ')', true);
|
||||
return false;
|
||||
}
|
||||
} else if (card.getManaCost().convertedManaCost() > 3) {
|
||||
addError(DeckValidatorErrorType.OTHER, card.getName(), "Invalid cost (" + card.getManaCost().convertedManaCost() + ')', true);
|
||||
return false;
|
||||
costs.add(((SplitCard) card).getLeftHalfCard().getManaCost().convertedManaCost());
|
||||
costs.add(((SplitCard) card).getRightHalfCard().getManaCost().convertedManaCost());
|
||||
} else if (card instanceof ModalDoubleFacesCard) {
|
||||
costs.add(((ModalDoubleFacesCard) card).getLeftHalfCard().getManaCost().convertedManaCost());
|
||||
costs.add(((ModalDoubleFacesCard) card).getRightHalfCard().getManaCost().convertedManaCost());
|
||||
} else {
|
||||
costs.add(card.getManaCost().convertedManaCost());
|
||||
}
|
||||
return true;
|
||||
|
||||
return costs.stream().allMatch(cost -> {
|
||||
if (cost > 3) {
|
||||
addError(DeckValidatorErrorType.OTHER, card.getName(), "Invalid cost (" + cost + ')', true);
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -1,37 +0,0 @@
|
|||
package mage.cards.a;
|
||||
|
||||
import mage.abilities.common.EntersBattlefieldTappedAbility;
|
||||
import mage.abilities.mana.RedManaAbility;
|
||||
import mage.cards.CardImpl;
|
||||
import mage.cards.CardSetInfo;
|
||||
import mage.constants.CardType;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
/**
|
||||
* @author TheElk801
|
||||
*/
|
||||
public final class AkoumTeeth extends CardImpl {
|
||||
|
||||
public AkoumTeeth(UUID ownerId, CardSetInfo setInfo) {
|
||||
super(ownerId, setInfo, new CardType[]{CardType.LAND}, "");
|
||||
|
||||
this.modalDFC = true;
|
||||
this.nightCard = true;
|
||||
|
||||
// Akoum Teeth enters the battlefield tapped.
|
||||
this.addAbility(new EntersBattlefieldTappedAbility());
|
||||
|
||||
// {T}: Add {R}.
|
||||
this.addAbility(new RedManaAbility());
|
||||
}
|
||||
|
||||
private AkoumTeeth(final AkoumTeeth card) {
|
||||
super(card);
|
||||
}
|
||||
|
||||
@Override
|
||||
public AkoumTeeth copy() {
|
||||
return new AkoumTeeth(this);
|
||||
}
|
||||
}
|
|
@ -1,32 +1,38 @@
|
|||
package mage.cards.a;
|
||||
|
||||
import mage.MageInt;
|
||||
import mage.abilities.common.EntersBattlefieldTappedAbility;
|
||||
import mage.abilities.keyword.TrampleAbility;
|
||||
import mage.cards.CardImpl;
|
||||
import mage.abilities.mana.RedManaAbility;
|
||||
import mage.cards.CardSetInfo;
|
||||
import mage.cards.ModalDoubleFacesCard;
|
||||
import mage.constants.CardType;
|
||||
import mage.constants.SubType;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
/**
|
||||
* @author TheElk801
|
||||
* @author JayDi85
|
||||
*/
|
||||
public final class AkoumWarrior extends CardImpl {
|
||||
public final class AkoumWarrior extends ModalDoubleFacesCard {
|
||||
|
||||
public AkoumWarrior(UUID ownerId, CardSetInfo setInfo) {
|
||||
super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{5}{R}");
|
||||
|
||||
this.subtype.add(SubType.MINOTAUR);
|
||||
this.subtype.add(SubType.WARRIOR);
|
||||
this.power = new MageInt(4);
|
||||
this.toughness = new MageInt(5);
|
||||
|
||||
this.modalDFC = true;
|
||||
this.secondSideCardClazz = mage.cards.a.AkoumTeeth.class;
|
||||
super(ownerId, setInfo,
|
||||
new CardType[]{CardType.CREATURE}, new SubType[]{SubType.MINOTAUR, SubType.WARRIOR}, "{5}{R}",
|
||||
"Akoum Teeth", new CardType[]{CardType.LAND}, new SubType[]{}, ""
|
||||
);
|
||||
|
||||
// Akoum Warrior
|
||||
// Creature — Minotaur Warrior
|
||||
this.getLeftHalfCard().setPT(new MageInt(4), new MageInt(5));
|
||||
// Trample
|
||||
this.addAbility(TrampleAbility.getInstance());
|
||||
this.getLeftHalfCard().addAbility(TrampleAbility.getInstance());
|
||||
|
||||
// Akoum Teeth
|
||||
// Akoum Teeth enters the battlefield tapped.
|
||||
this.getRightHalfCard().addAbility(new EntersBattlefieldTappedAbility());
|
||||
// {T}: Add {R}.
|
||||
this.getRightHalfCard().addAbility(new RedManaAbility());
|
||||
}
|
||||
|
||||
private AkoumWarrior(final AkoumWarrior card) {
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
package mage.cards.a;
|
||||
|
||||
import java.util.UUID;
|
||||
import mage.MageObject;
|
||||
import mage.abilities.Ability;
|
||||
import mage.abilities.common.SimpleActivatedAbility;
|
||||
|
@ -12,7 +11,6 @@ import mage.cards.Card;
|
|||
import mage.cards.CardImpl;
|
||||
import mage.cards.CardSetInfo;
|
||||
import mage.cards.CardsImpl;
|
||||
import mage.cards.SplitCard;
|
||||
import mage.constants.CardType;
|
||||
import mage.constants.Outcome;
|
||||
import mage.filter.FilterCard;
|
||||
|
@ -23,9 +21,11 @@ import mage.players.Player;
|
|||
import mage.target.Target;
|
||||
import mage.target.common.TargetCardInHand;
|
||||
import mage.target.common.TargetCardInLibrary;
|
||||
import mage.util.CardUtil;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author TheElk801
|
||||
*/
|
||||
public final class AssemblyHall extends CardImpl {
|
||||
|
@ -84,7 +84,7 @@ class AssemblyHallEffect extends OneShotEffect {
|
|||
return false;
|
||||
}
|
||||
controller.revealCards("from hand :" + sourceObject.getName(), new CardsImpl(cardToReveal), game);
|
||||
String nameToSearch = cardToReveal.isSplitCard() ? ((SplitCard) cardToReveal).getLeftHalfCard().getName() : cardToReveal.getName();
|
||||
String nameToSearch = CardUtil.getCardNameForSameNameSearch(cardToReveal);
|
||||
FilterCard filterCard = new FilterCard("card named " + nameToSearch);
|
||||
filterCard.add(new NamePredicate(nameToSearch));
|
||||
return new SearchLibraryPutInHandEffect(new TargetCardInLibrary(filterCard), true, true).apply(game, source);
|
||||
|
|
|
@ -105,22 +105,39 @@ class BolassCitadelPlayTheTopCardEffect extends AsThoughEffectImpl {
|
|||
if (topCard == null || !topCard.getId().equals(objectIdToCast)) {
|
||||
return false;
|
||||
}
|
||||
if (!topCard.isLand()) {
|
||||
if (topCard instanceof SplitCard) {
|
||||
SplitCardHalf leftCard = ((SplitCard) topCard).getLeftHalfCard();
|
||||
PayLifeCost lifeCost = new PayLifeCost(leftCard.getSpellAbility().getManaCosts().convertedManaCost());
|
||||
Costs leftCosts = new CostsImpl();
|
||||
leftCosts.add(lifeCost);
|
||||
leftCosts.addAll(leftCard.getSpellAbility().getCosts());
|
||||
player.setCastSourceIdWithAlternateMana(leftCard.getId(), null, leftCosts);
|
||||
|
||||
SplitCardHalf rightCard = ((SplitCard) topCard).getRightHalfCard();
|
||||
lifeCost = new PayLifeCost(rightCard.getSpellAbility().getManaCosts().convertedManaCost());
|
||||
Costs rightCosts = new CostsImpl();
|
||||
rightCosts.add(lifeCost);
|
||||
rightCosts.addAll(rightCard.getSpellAbility().getCosts());
|
||||
player.setCastSourceIdWithAlternateMana(rightCard.getId(), null, rightCosts);
|
||||
if (topCard instanceof SplitCard || topCard instanceof ModalDoubleFacesCard) {
|
||||
// double faces cards
|
||||
Card card1;
|
||||
Card card2;
|
||||
if (topCard instanceof SplitCard) {
|
||||
card1 = ((SplitCard) topCard).getLeftHalfCard();
|
||||
card2 = ((SplitCard) topCard).getRightHalfCard();
|
||||
} else {
|
||||
card1 = ((ModalDoubleFacesCard) topCard).getLeftHalfCard();
|
||||
card2 = ((ModalDoubleFacesCard) topCard).getRightHalfCard();
|
||||
}
|
||||
|
||||
// left
|
||||
if (!card1.isLand()) {
|
||||
PayLifeCost lifeCost = new PayLifeCost(card1.getSpellAbility().getManaCosts().convertedManaCost());
|
||||
Costs newCosts = new CostsImpl();
|
||||
newCosts.add(lifeCost);
|
||||
newCosts.addAll(card1.getSpellAbility().getCosts());
|
||||
player.setCastSourceIdWithAlternateMana(card1.getId(), null, newCosts);
|
||||
}
|
||||
|
||||
// right
|
||||
if (!card2.isLand()) {
|
||||
PayLifeCost lifeCost = new PayLifeCost(card2.getSpellAbility().getManaCosts().convertedManaCost());
|
||||
Costs newCosts = new CostsImpl();
|
||||
newCosts.add(lifeCost);
|
||||
newCosts.addAll(card2.getSpellAbility().getCosts());
|
||||
player.setCastSourceIdWithAlternateMana(card2.getId(), null, newCosts);
|
||||
}
|
||||
} else {
|
||||
// other single face cards
|
||||
if (!topCard.isLand()) {
|
||||
if (affectedAbility == null) {
|
||||
affectedAbility = topCard.getSpellAbility();
|
||||
} else {
|
||||
|
@ -134,7 +151,6 @@ class BolassCitadelPlayTheTopCardEffect extends AsThoughEffectImpl {
|
|||
}
|
||||
}
|
||||
return true;
|
||||
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
|
|
@ -1,8 +1,5 @@
|
|||
|
||||
package mage.cards.d;
|
||||
|
||||
import java.util.UUID;
|
||||
import java.util.regex.Pattern;
|
||||
import mage.MageInt;
|
||||
import mage.MageObject;
|
||||
import mage.abilities.Ability;
|
||||
|
@ -11,18 +8,21 @@ import mage.abilities.effects.common.ReturnToHandTargetEffect;
|
|||
import mage.abilities.keyword.FlyingAbility;
|
||||
import mage.cards.CardImpl;
|
||||
import mage.cards.CardSetInfo;
|
||||
import mage.cards.ModalDoubleFacesCard;
|
||||
import mage.cards.SplitCard;
|
||||
import mage.constants.CardType;
|
||||
import mage.constants.SubType;
|
||||
import mage.constants.SpellAbilityType;
|
||||
import mage.constants.SubType;
|
||||
import mage.filter.FilterPermanent;
|
||||
import mage.filter.predicate.Predicate;
|
||||
import mage.game.Game;
|
||||
import mage.game.stack.Spell;
|
||||
import mage.target.TargetPermanent;
|
||||
|
||||
import java.util.UUID;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author L_J
|
||||
*/
|
||||
public final class DoubleHeader extends CardImpl {
|
||||
|
@ -34,7 +34,7 @@ public final class DoubleHeader extends CardImpl {
|
|||
}
|
||||
|
||||
public DoubleHeader(UUID ownerId, CardSetInfo setInfo) {
|
||||
super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{3}{U}{U}");
|
||||
super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{3}{U}{U}");
|
||||
this.subtype.add(SubType.DRAKE);
|
||||
|
||||
this.power = new MageInt(2);
|
||||
|
@ -68,14 +68,16 @@ class DoubleHeaderPredicate implements Predicate<MageObject> {
|
|||
public boolean apply(MageObject input, Game game) {
|
||||
String name = input.getName();
|
||||
if (input instanceof SplitCard) {
|
||||
return hasTwoWords(((SplitCard)input).getLeftHalfCard().getName()) || hasTwoWords(((SplitCard)input).getRightHalfCard().getName());
|
||||
} else if (input instanceof Spell && ((Spell) input).getSpellAbility().getSpellAbilityType() == SpellAbilityType.SPLIT_FUSED){
|
||||
SplitCard card = (SplitCard) ((Spell)input).getCard();
|
||||
return hasTwoWords(((SplitCard) input).getLeftHalfCard().getName()) || hasTwoWords(((SplitCard) input).getRightHalfCard().getName());
|
||||
} else if (input instanceof ModalDoubleFacesCard) {
|
||||
return hasTwoWords(((ModalDoubleFacesCard) input).getLeftHalfCard().getName()) || hasTwoWords(((ModalDoubleFacesCard) input).getRightHalfCard().getName());
|
||||
} else if (input instanceof Spell && ((Spell) input).getSpellAbility().getSpellAbilityType() == SpellAbilityType.SPLIT_FUSED) {
|
||||
SplitCard card = (SplitCard) ((Spell) input).getCard();
|
||||
return hasTwoWords(card.getLeftHalfCard().getName()) || hasTwoWords(card.getRightHalfCard().getName());
|
||||
} else {
|
||||
if (name.contains(" // ")) {
|
||||
String leftName = name.substring(0, name.indexOf(" // "));
|
||||
String rightName = name.substring(name.indexOf(" // ") + 4, name.length());
|
||||
String rightName = name.substring(name.indexOf(" // ") + 4);
|
||||
return hasTwoWords(leftName) || hasTwoWords(rightName);
|
||||
} else {
|
||||
return hasTwoWords(name);
|
||||
|
|
|
@ -1,8 +1,5 @@
|
|||
|
||||
package mage.cards.e;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
import mage.MageObject;
|
||||
import mage.Mana;
|
||||
import mage.abilities.Ability;
|
||||
|
@ -13,14 +10,11 @@ import mage.abilities.costs.common.SacrificeTargetCost;
|
|||
import mage.abilities.costs.mana.GenericManaCost;
|
||||
import mage.abilities.dynamicvalue.common.CreaturesYouControlCount;
|
||||
import mage.abilities.effects.OneShotEffect;
|
||||
import mage.abilities.effects.common.search.SearchLibraryPutInHandEffect;
|
||||
import mage.abilities.effects.common.GainLifeEffect;
|
||||
import mage.abilities.effects.common.search.SearchLibraryPutInHandEffect;
|
||||
import mage.abilities.effects.mana.BasicManaEffect;
|
||||
import mage.abilities.mana.SimpleManaAbility;
|
||||
import mage.cards.Card;
|
||||
import mage.cards.CardImpl;
|
||||
import mage.cards.CardSetInfo;
|
||||
import mage.cards.SplitCard;
|
||||
import mage.cards.*;
|
||||
import mage.constants.CardType;
|
||||
import mage.constants.Outcome;
|
||||
import mage.constants.SpellAbilityType;
|
||||
|
@ -35,24 +29,25 @@ import mage.target.common.TargetCardInLibrary;
|
|||
import mage.target.common.TargetControlledCreaturePermanent;
|
||||
import mage.target.common.TargetControlledPermanent;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Ketsuban
|
||||
*/
|
||||
public final class EverythingamajigE extends CardImpl {
|
||||
|
||||
public EverythingamajigE(UUID ownerId, CardSetInfo setInfo) {
|
||||
super(ownerId,setInfo,new CardType[]{CardType.ARTIFACT},"{5}");
|
||||
super(ownerId, setInfo, new CardType[]{CardType.ARTIFACT}, "{5}");
|
||||
|
||||
// Zuran Orb
|
||||
// Sacrifice a land: You gain 2 life.
|
||||
this.addAbility(new SimpleActivatedAbility(Zone.BATTLEFIELD, new GainLifeEffect(2), new SacrificeTargetCost(new TargetControlledPermanent(StaticFilters.FILTER_CONTROLLED_LAND_SHORT_TEXT))));
|
||||
|
||||
|
||||
// Ashnod's Altar
|
||||
// Sacrifice a creature: Add {C}{C} to your mana pool.
|
||||
SacrificeTargetCost cost = new SacrificeTargetCost(new TargetControlledCreaturePermanent(StaticFilters.FILTER_CONTROLLED_CREATURE_SHORT_TEXT));
|
||||
this.addAbility(new SimpleManaAbility(Zone.BATTLEFIELD,
|
||||
new BasicManaEffect(Mana.ColorlessMana(2), CreaturesYouControlCount.instance),
|
||||
this.addAbility(new SimpleManaAbility(Zone.BATTLEFIELD,
|
||||
new BasicManaEffect(Mana.ColorlessMana(2), CreaturesYouControlCount.instance),
|
||||
cost));
|
||||
|
||||
// Urza's Hot Tub
|
||||
|
@ -117,21 +112,23 @@ class UrzasHotTubPredicate implements Predicate<MageObject> {
|
|||
public boolean apply(MageObject input, Game game) {
|
||||
String name = input.getName();
|
||||
if (input instanceof SplitCard) {
|
||||
return sharesWordWithName(((SplitCard)input).getLeftHalfCard().getName()) || sharesWordWithName(((SplitCard)input).getRightHalfCard().getName());
|
||||
} else if (input instanceof Spell && ((Spell) input).getSpellAbility().getSpellAbilityType() == SpellAbilityType.SPLIT_FUSED){
|
||||
SplitCard card = (SplitCard) ((Spell)input).getCard();
|
||||
return sharesWordWithName(((SplitCard) input).getLeftHalfCard().getName()) || sharesWordWithName(((SplitCard) input).getRightHalfCard().getName());
|
||||
} else if (input instanceof ModalDoubleFacesCard) {
|
||||
return sharesWordWithName(((ModalDoubleFacesCard) input).getLeftHalfCard().getName()) || sharesWordWithName(((ModalDoubleFacesCard) input).getRightHalfCard().getName());
|
||||
} else if (input instanceof Spell && ((Spell) input).getSpellAbility().getSpellAbilityType() == SpellAbilityType.SPLIT_FUSED) {
|
||||
SplitCard card = (SplitCard) ((Spell) input).getCard();
|
||||
return sharesWordWithName(card.getLeftHalfCard().getName()) || sharesWordWithName(card.getRightHalfCard().getName());
|
||||
} else {
|
||||
if (name.contains(" // ")) {
|
||||
String leftName = name.substring(0, name.indexOf(" // "));
|
||||
String rightName = name.substring(name.indexOf(" // ") + 4, name.length());
|
||||
String rightName = name.substring(name.indexOf(" // ") + 4);
|
||||
return sharesWordWithName(leftName) || sharesWordWithName(rightName);
|
||||
} else {
|
||||
return sharesWordWithName(name);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private boolean sharesWordWithName(String str) {
|
||||
if (referenceName == null || referenceName.equals("")) {
|
||||
return false;
|
||||
|
|
|
@ -1,7 +1,5 @@
|
|||
package mage.cards.e;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.UUID;
|
||||
import mage.MageObject;
|
||||
import mage.abilities.Ability;
|
||||
import mage.abilities.effects.OneShotEffect;
|
||||
|
@ -9,7 +7,6 @@ import mage.abilities.keyword.SplitSecondAbility;
|
|||
import mage.cards.Card;
|
||||
import mage.cards.CardImpl;
|
||||
import mage.cards.CardSetInfo;
|
||||
import mage.cards.SplitCard;
|
||||
import mage.constants.CardType;
|
||||
import mage.constants.Outcome;
|
||||
import mage.constants.SuperType;
|
||||
|
@ -22,19 +19,22 @@ import mage.players.Player;
|
|||
import mage.target.TargetCard;
|
||||
import mage.target.common.TargetCardInGraveyard;
|
||||
import mage.target.common.TargetCardInLibrary;
|
||||
import mage.util.CardUtil;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.UUID;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author jonubuu
|
||||
*/
|
||||
public final class Extirpate extends CardImpl {
|
||||
|
||||
|
||||
private static final FilterCard filter = new FilterCard("card in a graveyard other than a basic land card");
|
||||
|
||||
|
||||
static {
|
||||
filter.add(Predicates.not(Predicates.and(CardType.LAND.getPredicate(), SuperType.BASIC.getPredicate())));
|
||||
}
|
||||
|
||||
|
||||
public Extirpate(UUID ownerId, CardSetInfo setInfo) {
|
||||
super(ownerId, setInfo, new CardType[]{CardType.INSTANT}, "{B}");
|
||||
|
||||
|
@ -46,11 +46,11 @@ public final class Extirpate extends CardImpl {
|
|||
this.getSpellAbility().addEffect(new ExtirpateEffect());
|
||||
this.getSpellAbility().addTarget(new TargetCardInGraveyard(filter));
|
||||
}
|
||||
|
||||
|
||||
public Extirpate(final Extirpate card) {
|
||||
super(card);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public Extirpate copy() {
|
||||
return new Extirpate(this);
|
||||
|
@ -58,7 +58,7 @@ public final class Extirpate extends CardImpl {
|
|||
}
|
||||
|
||||
class ExtirpateEffect extends OneShotEffect {
|
||||
|
||||
|
||||
public ExtirpateEffect() {
|
||||
super(Outcome.Exile);
|
||||
this.staticText = "Choose target card in a graveyard other than "
|
||||
|
@ -66,16 +66,16 @@ class ExtirpateEffect extends OneShotEffect {
|
|||
+ "and library for any number of cards with the same name "
|
||||
+ "as that card and exile them. Then that player shuffles their library";
|
||||
}
|
||||
|
||||
|
||||
public ExtirpateEffect(final ExtirpateEffect effect) {
|
||||
super(effect);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public ExtirpateEffect copy() {
|
||||
return new ExtirpateEffect(this);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public boolean apply(Game game, Ability source) {
|
||||
Player controller = game.getPlayer(source.getControllerId());
|
||||
|
@ -90,7 +90,7 @@ class ExtirpateEffect extends OneShotEffect {
|
|||
// Exile all cards with the same name
|
||||
// Building a card filter with the name
|
||||
FilterCard filterNamedCard = new FilterCard();
|
||||
String nameToSearch = chosenCard.isSplitCard() ? ((SplitCard) chosenCard).getLeftHalfCard().getName() : chosenCard.getName();
|
||||
String nameToSearch = CardUtil.getCardNameForSameNameSearch(chosenCard);
|
||||
filterNamedCard.add(new NamePredicate(nameToSearch));
|
||||
|
||||
// The cards you're searching for must be found and exiled if they're in the graveyard because it's a public zone.
|
||||
|
@ -133,5 +133,5 @@ class ExtirpateEffect extends OneShotEffect {
|
|||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
package mage.cards.e;
|
||||
|
||||
import mage.ApprovingObject;
|
||||
import mage.abilities.Ability;
|
||||
import mage.abilities.TriggeredAbilityImpl;
|
||||
import mage.abilities.effects.Effect;
|
||||
|
@ -21,7 +22,6 @@ import mage.target.targetpointer.FixedTarget;
|
|||
import mage.util.CardUtil;
|
||||
|
||||
import java.util.UUID;
|
||||
import mage.ApprovingObject;
|
||||
|
||||
/**
|
||||
* @author spjspj
|
||||
|
@ -127,9 +127,12 @@ class EyeOfTheStormEffect1 extends OneShotEffect {
|
|||
// Check if owner of card is still in game
|
||||
card = game.getCard(uuid);
|
||||
if (card != null && game.getPlayer(card.getOwnerId()) != null) {
|
||||
if (card.isSplitCard()) {
|
||||
if (card instanceof SplitCard) {
|
||||
copiedCards.add(((SplitCard) card).getLeftHalfCard());
|
||||
copiedCards.add(((SplitCard) card).getRightHalfCard());
|
||||
} else if (card instanceof ModalDoubleFacesCard) {
|
||||
copiedCards.add(((ModalDoubleFacesCard) card).getLeftHalfCard());
|
||||
copiedCards.add(((ModalDoubleFacesCard) card).getRightHalfCard());
|
||||
} else {
|
||||
copiedCards.add(card);
|
||||
}
|
||||
|
|
|
@ -1,9 +1,5 @@
|
|||
package mage.cards.g;
|
||||
|
||||
import java.util.HashSet;
|
||||
import java.util.Iterator;
|
||||
import java.util.Set;
|
||||
import java.util.UUID;
|
||||
import mage.MageInt;
|
||||
import mage.MageObject;
|
||||
import mage.abilities.Ability;
|
||||
|
@ -24,8 +20,12 @@ import mage.players.Player;
|
|||
import mage.target.common.TargetOpponent;
|
||||
import mage.util.CardUtil;
|
||||
|
||||
import java.util.HashSet;
|
||||
import java.util.Iterator;
|
||||
import java.util.Set;
|
||||
import java.util.UUID;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author jeffwadsworth
|
||||
*/
|
||||
public final class GrimoireThief extends CardImpl {
|
||||
|
@ -197,30 +197,24 @@ class GrimoireThiefCounterspellEffect extends OneShotEffect {
|
|||
}
|
||||
// then counter any with the same name as the card exiled with Grimoire Thief
|
||||
for (Card card : cards.getCards(game)) {
|
||||
for (Iterator<StackObject> iterator = game.getStack().iterator(); iterator.hasNext();) {
|
||||
for (Iterator<StackObject> iterator = game.getStack().iterator(); iterator.hasNext(); ) {
|
||||
StackObject stackObject = iterator.next();
|
||||
MageObject mageObject = game.getObject(card.getId());
|
||||
// handle split cards
|
||||
String name1;
|
||||
String name2;
|
||||
if (mageObject instanceof SplitCard) {
|
||||
if (stackObject instanceof Spell
|
||||
&& (stackObject.getName().contains(((SplitCard) mageObject).getLeftHalfCard().getName())
|
||||
|| stackObject.getName().contains(((SplitCard) mageObject).getRightHalfCard().getName()))) {
|
||||
Spell spell = (Spell) stackObject;
|
||||
game.getStack().counter(stackObject.getId(), source.getSourceId(), game);
|
||||
game.informPlayers(sourceObject.getLogName()
|
||||
+ ": the split-card spell named "
|
||||
+ spell.getName()
|
||||
+ " was countered.");
|
||||
}
|
||||
name1 = ((SplitCard) mageObject).getLeftHalfCard().getName();
|
||||
name2 = ((SplitCard) mageObject).getRightHalfCard().getName();
|
||||
} else {
|
||||
// modal double faces cards, adventure cards -- all have one name in non stack/battlefield zone
|
||||
name1 = mageObject.getName();
|
||||
name2 = name1;
|
||||
}
|
||||
if (stackObject instanceof Spell
|
||||
&& stackObject.getName().contains(card.getName())) {
|
||||
|
||||
if (CardUtil.haveSameNames(stackObject, name1, game) || CardUtil.haveSameNames(stackObject, name2, game)) {
|
||||
Spell spell = (Spell) stackObject;
|
||||
game.getStack().counter(spell.getId(), source.getSourceId(), game);
|
||||
game.informPlayers(sourceObject.getLogName()
|
||||
+ ": the spell named "
|
||||
+ spell.getName()
|
||||
+ " was countered.");
|
||||
game.getStack().counter(stackObject.getId(), source.getSourceId(), game);
|
||||
game.informPlayers(sourceObject.getLogName() + ": spell " + spell.getIdName() + " was countered.");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,4 +1,3 @@
|
|||
|
||||
package mage.cards.h;
|
||||
|
||||
import mage.abilities.Ability;
|
||||
|
@ -6,7 +5,6 @@ import mage.abilities.effects.OneShotEffect;
|
|||
import mage.cards.Card;
|
||||
import mage.cards.CardImpl;
|
||||
import mage.cards.CardSetInfo;
|
||||
import mage.cards.SplitCard;
|
||||
import mage.constants.CardType;
|
||||
import mage.constants.Outcome;
|
||||
import mage.filter.FilterCard;
|
||||
|
@ -16,12 +14,12 @@ import mage.game.Game;
|
|||
import mage.players.Player;
|
||||
import mage.target.TargetPlayer;
|
||||
import mage.target.common.TargetCardInLibrary;
|
||||
import mage.util.CardUtil;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.UUID;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author BetaSteward_at_googlemail.com
|
||||
*/
|
||||
public final class HauntingEchoes extends CardImpl {
|
||||
|
@ -63,9 +61,10 @@ class HauntingEchoesEffect extends OneShotEffect {
|
|||
if (!StaticFilters.FILTER_CARD_BASIC_LAND.match(card, game)) {
|
||||
card.moveToExile(null, "", source.getSourceId(), game);
|
||||
|
||||
FilterCard filterCard = new FilterCard("cards named " + card.getName());
|
||||
String nameToSearch = card.isSplitCard() ? ((SplitCard) card).getLeftHalfCard().getName() : card.getName();
|
||||
String nameToSearch = CardUtil.getCardNameForSameNameSearch(card);
|
||||
FilterCard filterCard = new FilterCard("cards named " + nameToSearch);
|
||||
filterCard.add(new NamePredicate(nameToSearch));
|
||||
|
||||
int count = targetPlayer.getLibrary().count(filterCard, game);
|
||||
TargetCardInLibrary target = new TargetCardInLibrary(count, count, filterCard);
|
||||
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
package mage.cards.i;
|
||||
|
||||
import java.util.UUID;
|
||||
import mage.MageObject;
|
||||
import mage.abilities.Ability;
|
||||
import mage.abilities.condition.common.HellbentCondition;
|
||||
|
@ -12,7 +11,6 @@ import mage.cards.Card;
|
|||
import mage.cards.CardImpl;
|
||||
import mage.cards.CardSetInfo;
|
||||
import mage.cards.CardsImpl;
|
||||
import mage.cards.SplitCard;
|
||||
import mage.constants.CardType;
|
||||
import mage.constants.Outcome;
|
||||
import mage.filter.FilterCard;
|
||||
|
@ -23,9 +21,11 @@ import mage.players.Player;
|
|||
import mage.target.Target;
|
||||
import mage.target.common.TargetCardInHand;
|
||||
import mage.target.common.TargetCardInLibrary;
|
||||
import mage.util.CardUtil;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author LevelX2
|
||||
*/
|
||||
public final class InfernalTutor extends CardImpl {
|
||||
|
@ -89,7 +89,7 @@ class InfernalTutorEffect extends OneShotEffect {
|
|||
FilterCard filterCard;
|
||||
if (cardToReveal != null) {
|
||||
controller.revealCards("from hand :" + sourceObject.getName(), new CardsImpl(cardToReveal), game);
|
||||
String nameToSearch = cardToReveal.isSplitCard() ? ((SplitCard) cardToReveal).getLeftHalfCard().getName() : cardToReveal.getName();
|
||||
String nameToSearch = CardUtil.getCardNameForSameNameSearch(cardToReveal);
|
||||
filterCard = new FilterCard("card named " + nameToSearch);
|
||||
filterCard.add(new NamePredicate(nameToSearch));
|
||||
} else {
|
||||
|
|
|
@ -161,14 +161,15 @@ class JestersScepterCost extends CostImpl {
|
|||
Card card = game.getCard(target.getFirstTarget());
|
||||
if (card != null) {
|
||||
if (controller.moveCardToGraveyardWithInfo(card, sourceId, game, Zone.EXILED)) {
|
||||
// Split Card check
|
||||
if (card instanceof SplitCard) {
|
||||
game.getState().setValue(sourceId + "_nameOfExiledCardPayment", ((SplitCard) card).getLeftHalfCard().getName());
|
||||
game.getState().setValue(sourceId + "_nameOfExiledCardPayment2", ((SplitCard) card).getRightHalfCard().getName());
|
||||
paid = true;
|
||||
return paid;
|
||||
} else if (card instanceof ModalDoubleFacesCard) {
|
||||
game.getState().setValue(sourceId + "_nameOfExiledCardPayment", ((ModalDoubleFacesCard) card).getLeftHalfCard().getName());
|
||||
game.getState().setValue(sourceId + "_nameOfExiledCardPayment2", ((ModalDoubleFacesCard) card).getRightHalfCard().getName());
|
||||
} else {
|
||||
game.getState().setValue(sourceId + "_nameOfExiledCardPayment", card.getName());
|
||||
}
|
||||
game.getState().setValue(sourceId + "_nameOfExiledCardPayment", card.getName());
|
||||
paid = true;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -8,7 +8,6 @@ import mage.abilities.effects.OneShotEffect;
|
|||
import mage.cards.Card;
|
||||
import mage.cards.CardImpl;
|
||||
import mage.cards.CardSetInfo;
|
||||
import mage.cards.SplitCard;
|
||||
import mage.cards.repository.CardRepository;
|
||||
import mage.choices.Choice;
|
||||
import mage.choices.ChoiceImpl;
|
||||
|
@ -85,14 +84,6 @@ class LiarsPendulumEffect extends OneShotEffect {
|
|||
boolean rightGuess = !opponentGuess;
|
||||
|
||||
for (Card card : controller.getHand().getCards(game)) {
|
||||
if (card.isSplitCard()) {
|
||||
SplitCard splitCard = (SplitCard) card;
|
||||
if (splitCard.getLeftHalfCard().getName().equals(cardName)) {
|
||||
rightGuess = opponentGuess;
|
||||
} else if (splitCard.getRightHalfCard().getName().equals(cardName)) {
|
||||
rightGuess = opponentGuess;
|
||||
}
|
||||
}
|
||||
if (CardUtil.haveSameNames(card, cardName, game)) {
|
||||
rightGuess = opponentGuess;
|
||||
}
|
||||
|
|
|
@ -1,7 +1,5 @@
|
|||
|
||||
package mage.cards.l;
|
||||
|
||||
import java.util.UUID;
|
||||
import mage.MageObject;
|
||||
import mage.abilities.Ability;
|
||||
import mage.abilities.effects.OneShotEffect;
|
||||
|
@ -18,9 +16,11 @@ import mage.players.Player;
|
|||
import mage.target.TargetCard;
|
||||
import mage.target.TargetPlayer;
|
||||
import mage.target.common.TargetCardInLibrary;
|
||||
import mage.util.CardUtil;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author jeffwadsworth
|
||||
*/
|
||||
public final class Lobotomy extends CardImpl {
|
||||
|
@ -83,8 +83,8 @@ class LobotomyEffect extends OneShotEffect {
|
|||
FilterCard filterNamedCards = new FilterCard();
|
||||
String nameToSearch = "---";// so no card matches
|
||||
if (chosenCard != null) {
|
||||
nameToSearch = chosenCard.isSplitCard() ? ((SplitCard) chosenCard).getLeftHalfCard().getName() : chosenCard.getName();
|
||||
filterNamedCards.setMessage("cards named " + chosenCard.getName());
|
||||
nameToSearch = CardUtil.getCardNameForSameNameSearch(chosenCard);
|
||||
filterNamedCards.setMessage("cards named " + nameToSearch);
|
||||
}
|
||||
filterNamedCards.add(new NamePredicate(nameToSearch));
|
||||
Cards cardsToExile = new CardsImpl();
|
||||
|
|
|
@ -1,9 +1,5 @@
|
|||
|
||||
package mage.cards.m;
|
||||
|
||||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
import java.util.UUID;
|
||||
import mage.MageInt;
|
||||
import mage.MageObject;
|
||||
import mage.abilities.Ability;
|
||||
|
@ -16,30 +12,30 @@ import mage.abilities.keyword.HeroicAbility;
|
|||
import mage.cards.Card;
|
||||
import mage.cards.CardImpl;
|
||||
import mage.cards.CardSetInfo;
|
||||
import mage.cards.SplitCard;
|
||||
import mage.constants.CardType;
|
||||
import mage.constants.SubType;
|
||||
import mage.constants.Outcome;
|
||||
import mage.constants.SpellAbilityType;
|
||||
import mage.constants.SubType;
|
||||
import mage.constants.Zone;
|
||||
import mage.filter.FilterSpell;
|
||||
import mage.filter.predicate.Predicate;
|
||||
import mage.game.ExileZone;
|
||||
import mage.game.Game;
|
||||
import mage.game.stack.Spell;
|
||||
import mage.players.Player;
|
||||
import mage.target.TargetPlayer;
|
||||
import mage.target.TargetSpell;
|
||||
import mage.util.CardUtil;
|
||||
|
||||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
import java.util.UUID;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author LevelX2
|
||||
*/
|
||||
public final class Mindreaver extends CardImpl {
|
||||
|
||||
public Mindreaver(UUID ownerId, CardSetInfo setInfo) {
|
||||
super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{U}{U}");
|
||||
super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{U}{U}");
|
||||
this.subtype.add(SubType.HUMAN);
|
||||
this.subtype.add(SubType.WIZARD);
|
||||
|
||||
|
@ -121,16 +117,7 @@ class MindreaverNamePredicate implements Predicate<MageObject> {
|
|||
cardNames.add(card.getName());
|
||||
}
|
||||
}
|
||||
// If a player names a card, the player may name either half of a split card, but not both.
|
||||
// A split card has the chosen name if one of its two names matches the chosen name.
|
||||
if (input instanceof SplitCard) {
|
||||
return cardNames.contains(((SplitCard) input).getLeftHalfCard().getName()) || cardNames.contains(((SplitCard) input).getRightHalfCard().getName());
|
||||
} else if (input instanceof Spell && ((Spell) input).getSpellAbility().getSpellAbilityType() == SpellAbilityType.SPLIT_FUSED) {
|
||||
SplitCard card = (SplitCard) ((Spell) input).getCard();
|
||||
return cardNames.contains(card.getLeftHalfCard().getName()) || cardNames.contains(card.getRightHalfCard().getName());
|
||||
} else {
|
||||
return cardNames.contains(input.getName());
|
||||
}
|
||||
return cardNames.stream().anyMatch(needName -> CardUtil.haveSameNames(input, needName, game));
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
package mage.cards.p;
|
||||
|
||||
import java.util.UUID;
|
||||
import mage.ApprovingObject;
|
||||
import mage.abilities.Ability;
|
||||
import mage.abilities.common.BeginningOfUpkeepTriggeredAbility;
|
||||
|
@ -9,11 +8,7 @@ import mage.abilities.costs.common.TapSourceCost;
|
|||
import mage.abilities.costs.mana.VariableManaCost;
|
||||
import mage.abilities.effects.OneShotEffect;
|
||||
import mage.cards.*;
|
||||
import mage.constants.CardType;
|
||||
import mage.constants.ComparisonType;
|
||||
import mage.constants.Outcome;
|
||||
import mage.constants.TargetController;
|
||||
import mage.constants.Zone;
|
||||
import mage.constants.*;
|
||||
import mage.filter.FilterCard;
|
||||
import mage.filter.common.FilterInstantOrSorceryCard;
|
||||
import mage.filter.predicate.mageobject.ConvertedManaCostPredicate;
|
||||
|
@ -24,8 +19,9 @@ import mage.target.TargetCard;
|
|||
import mage.target.common.TargetCardInHand;
|
||||
import mage.util.CardUtil;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Plopman
|
||||
*/
|
||||
public final class PanopticMirror extends CardImpl {
|
||||
|
@ -83,7 +79,7 @@ class PanopticMirrorExileEffect extends OneShotEffect {
|
|||
}
|
||||
|
||||
TargetCardInHand target = new TargetCardInHand(filter);
|
||||
if (player.choose(outcome.PlayForFree, target, source.getSourceId(), game)) {
|
||||
if (player.choose(Outcome.PlayForFree, target, source.getSourceId(), game)) {
|
||||
Card card = game.getCard(target.getFirstTarget());
|
||||
if (card != null) {
|
||||
card.moveToExile(CardUtil.getCardExileZoneId(game, source), "Panoptic Mirror", source.getSourceId(), game);
|
||||
|
@ -129,9 +125,12 @@ class PanopticMirrorCastEffect extends OneShotEffect {
|
|||
for (UUID uuid : PanopticMirror.getImprinted()) {
|
||||
Card card = game.getCard(uuid);
|
||||
if (card != null) {
|
||||
if (card.isSplitCard()) {
|
||||
if (card instanceof SplitCard) {
|
||||
cards.add(((SplitCard) card).getLeftHalfCard());
|
||||
cards.add(((SplitCard) card).getRightHalfCard());
|
||||
} else if (card instanceof ModalDoubleFacesCard) {
|
||||
cards.add(((ModalDoubleFacesCard) card).getLeftHalfCard());
|
||||
cards.add(((ModalDoubleFacesCard) card).getRightHalfCard());
|
||||
} else {
|
||||
cards.add(card);
|
||||
}
|
||||
|
@ -147,7 +146,7 @@ class PanopticMirrorCastEffect extends OneShotEffect {
|
|||
}
|
||||
if (cardToCopy != null) {
|
||||
Card copy = game.copyCard(cardToCopy, source, source.getControllerId());
|
||||
if (controller.chooseUse(outcome.PlayForFree, "Cast the copied card without paying mana cost?", source, game)) {
|
||||
if (controller.chooseUse(Outcome.PlayForFree, "Cast the copied card without paying mana cost?", source, game)) {
|
||||
game.getState().setValue("PlayFromNotOwnHandZone" + copy.getId(), Boolean.TRUE);
|
||||
controller.cast(controller.chooseAbilityForCast(copy, game, true),
|
||||
game, true, new ApprovingObject(source, game));
|
||||
|
|
|
@ -24,7 +24,6 @@ public final class ParallaxTide extends CardImpl {
|
|||
public ParallaxTide(UUID ownerId, CardSetInfo setInfo) {
|
||||
super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{2}{U}{U}");
|
||||
|
||||
|
||||
// Fading 5
|
||||
this.addAbility(new FadingAbility(5, this));
|
||||
|
||||
|
@ -34,7 +33,7 @@ public final class ParallaxTide extends CardImpl {
|
|||
this.addAbility(ability);
|
||||
|
||||
// When Parallax Tide leaves the battlefield, each player returns to the battlefield all cards they own exiled with Parallax Tide.
|
||||
this.addAbility(new LeavesBattlefieldTriggeredAbility(new ReturnFromExileForSourceEffect(Zone.BATTLEFIELD), splitCard));
|
||||
this.addAbility(new LeavesBattlefieldTriggeredAbility(new ReturnFromExileForSourceEffect(Zone.BATTLEFIELD), false));
|
||||
}
|
||||
|
||||
public ParallaxTide(final ParallaxTide card) {
|
||||
|
|
|
@ -12,16 +12,17 @@ import mage.filter.predicate.Predicates;
|
|||
import mage.filter.predicate.mageobject.NamePredicate;
|
||||
import mage.game.Game;
|
||||
import mage.players.Player;
|
||||
import mage.target.TargetCard;
|
||||
import mage.target.common.TargetCardInGraveyard;
|
||||
import mage.target.common.TargetCardInLibrary;
|
||||
import mage.target.common.TargetOpponent;
|
||||
import mage.util.CardUtil;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.UUID;
|
||||
import mage.target.TargetCard;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author jeffwadsworth
|
||||
*/
|
||||
public final class ReapIntellect extends CardImpl {
|
||||
|
@ -100,12 +101,11 @@ class ReapIntellectEffect extends OneShotEffect {
|
|||
List<NamePredicate> names = new ArrayList<>();
|
||||
FilterCard filterNamedCards = new FilterCard();
|
||||
for (Card card : exiledCards.getCards(game)) {
|
||||
String nameToSearch = CardUtil.getCardNameForSameNameSearch(card);
|
||||
if (exiledCards.size() == 1) {
|
||||
filterNamedCards.add(new NamePredicate(card.isSplitCard()
|
||||
? ((SplitCard) card).getLeftHalfCard().getName() : card.getName()));
|
||||
filterNamedCards.add(new NamePredicate(nameToSearch));
|
||||
} else {
|
||||
names.add(new NamePredicate(card.isSplitCard()
|
||||
? ((SplitCard) card).getLeftHalfCard().getName() : card.getName()));
|
||||
names.add(new NamePredicate(nameToSearch));
|
||||
}
|
||||
}
|
||||
if (exiledCards.size() > 1) {
|
||||
|
|
|
@ -1,4 +1,3 @@
|
|||
|
||||
package mage.cards.s;
|
||||
|
||||
import mage.MageInt;
|
||||
|
@ -11,8 +10,8 @@ import mage.cards.Card;
|
|||
import mage.cards.CardImpl;
|
||||
import mage.cards.CardSetInfo;
|
||||
import mage.constants.CardType;
|
||||
import mage.constants.SubType;
|
||||
import mage.constants.Outcome;
|
||||
import mage.constants.SubType;
|
||||
import mage.filter.FilterCard;
|
||||
import mage.game.Game;
|
||||
import mage.players.Player;
|
||||
|
@ -24,7 +23,6 @@ import java.util.Map;
|
|||
import java.util.UUID;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author jeffwadsworth
|
||||
*/
|
||||
public final class ScytheSpecter extends CardImpl {
|
||||
|
@ -80,13 +78,7 @@ class ScytheSpecterEffect extends OneShotEffect {
|
|||
opponent.chooseTarget(Outcome.Discard, target, source, game);
|
||||
Card targetCard = game.getCard(target.getFirstTarget());
|
||||
if (targetCard != null) {
|
||||
if (targetCard.isSplitCard()) { //check Split Cards
|
||||
if (targetCard.getSecondCardFace().getConvertedManaCost() < targetCard.getConvertedManaCost()) {
|
||||
currentCMC = targetCard.getConvertedManaCost();
|
||||
}
|
||||
} else {
|
||||
currentCMC = targetCard.getConvertedManaCost();
|
||||
}
|
||||
currentCMC = targetCard.getConvertedManaCost();
|
||||
if (highestCMC <= currentCMC) {
|
||||
highestCMC = currentCMC;
|
||||
}
|
||||
|
|
|
@ -1,16 +1,9 @@
|
|||
|
||||
package mage.cards.s;
|
||||
|
||||
import java.util.UUID;
|
||||
import mage.MageObject;
|
||||
import mage.abilities.Ability;
|
||||
import mage.abilities.effects.OneShotEffect;
|
||||
import mage.cards.Card;
|
||||
import mage.cards.CardImpl;
|
||||
import mage.cards.CardSetInfo;
|
||||
import mage.cards.Cards;
|
||||
import mage.cards.CardsImpl;
|
||||
import mage.cards.SplitCard;
|
||||
import mage.cards.*;
|
||||
import mage.constants.CardType;
|
||||
import mage.constants.Outcome;
|
||||
import mage.constants.Zone;
|
||||
|
@ -21,9 +14,11 @@ import mage.game.Game;
|
|||
import mage.players.Player;
|
||||
import mage.target.common.TargetCardInLibrary;
|
||||
import mage.target.common.TargetCardInYourGraveyard;
|
||||
import mage.util.CardUtil;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author LevelX2
|
||||
*/
|
||||
public final class SecretSalvage extends CardImpl {
|
||||
|
@ -72,9 +67,11 @@ class SecretSalvageEffect extends OneShotEffect {
|
|||
Card targetCard = game.getCard(getTargetPointer().getFirst(game, source));
|
||||
if (targetCard != null) {
|
||||
controller.moveCards(targetCard, Zone.EXILED, source, game);
|
||||
|
||||
String nameToSearch = CardUtil.getCardNameForSameNameSearch(targetCard);
|
||||
FilterCard nameFilter = new FilterCard();
|
||||
String nameToSearch = targetCard.isSplitCard() ? ((SplitCard) targetCard).getLeftHalfCard().getName() : targetCard.getName();
|
||||
nameFilter.add(new NamePredicate(nameToSearch));
|
||||
|
||||
TargetCardInLibrary target = new TargetCardInLibrary(0, Integer.MAX_VALUE, nameFilter);
|
||||
if (controller.searchLibrary(target, source, game)) {
|
||||
if (!target.getTargets().isEmpty()) {
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
package mage.cards.s;
|
||||
|
||||
import java.util.UUID;
|
||||
import mage.MageInt;
|
||||
import mage.MageObject;
|
||||
import mage.abilities.Ability;
|
||||
|
@ -10,10 +9,9 @@ import mage.abilities.keyword.FlyingAbility;
|
|||
import mage.cards.Card;
|
||||
import mage.cards.CardImpl;
|
||||
import mage.cards.CardSetInfo;
|
||||
import mage.cards.SplitCard;
|
||||
import mage.constants.CardType;
|
||||
import mage.constants.SubType;
|
||||
import mage.constants.Outcome;
|
||||
import mage.constants.SubType;
|
||||
import mage.constants.Zone;
|
||||
import mage.filter.FilterCard;
|
||||
import mage.filter.common.FilterNonlandCard;
|
||||
|
@ -23,9 +21,11 @@ import mage.game.Game;
|
|||
import mage.players.Player;
|
||||
import mage.target.TargetCard;
|
||||
import mage.target.common.TargetCardInLibrary;
|
||||
import mage.util.CardUtil;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author jeffwadsworth
|
||||
*/
|
||||
public final class ShimianSpecter extends CardImpl {
|
||||
|
@ -103,9 +103,7 @@ class ShimianSpecterEffect extends OneShotEffect {
|
|||
FilterCard filterNamedCards = new FilterCard();
|
||||
String nameToSearch = "---";// so no card matches
|
||||
if (chosenCard != null) {
|
||||
nameToSearch = chosenCard.isSplitCard()
|
||||
? ((SplitCard) chosenCard).getLeftHalfCard().getName()
|
||||
: chosenCard.getName();
|
||||
nameToSearch = CardUtil.getCardNameForSameNameSearch(chosenCard);
|
||||
}
|
||||
filterNamedCards.add(new NamePredicate(nameToSearch));
|
||||
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
package mage.cards.s;
|
||||
|
||||
import java.util.UUID;
|
||||
import mage.MageInt;
|
||||
import mage.MageObject;
|
||||
import mage.abilities.Ability;
|
||||
|
@ -11,11 +10,9 @@ import mage.abilities.effects.Effect;
|
|||
import mage.abilities.effects.GainAbilitySpellsEffect;
|
||||
import mage.abilities.effects.ReplacementEffectImpl;
|
||||
import mage.abilities.keyword.LifelinkAbility;
|
||||
import mage.cards.AdventureCardSpell;
|
||||
import mage.cards.Card;
|
||||
import mage.cards.CardImpl;
|
||||
import mage.cards.CardSetInfo;
|
||||
import mage.cards.SplitCardHalf;
|
||||
import mage.constants.*;
|
||||
import mage.filter.FilterCard;
|
||||
import mage.filter.FilterObject;
|
||||
|
@ -26,6 +23,8 @@ import mage.game.events.ZoneChangeEvent;
|
|||
import mage.game.stack.Spell;
|
||||
import mage.players.Player;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
/**
|
||||
* @author LevelX2
|
||||
*/
|
||||
|
@ -142,15 +141,7 @@ class SoulfireGrandMasterCastFromHandReplacementEffect extends ReplacementEffect
|
|||
&& event.getTargetId().equals(spellId)) {
|
||||
if (game.getStack().getFirst() instanceof Spell) {
|
||||
Card cardOfSpell = ((Spell) game.getStack().getFirst()).getCard();
|
||||
if (cardOfSpell instanceof SplitCardHalf) {
|
||||
return ((SplitCardHalf) cardOfSpell).getParentCard().getId().equals(spellId);
|
||||
} else if (cardOfSpell instanceof AdventureCardSpell) {
|
||||
return (((AdventureCardSpell) cardOfSpell).getParentCard().getId().equals(spellId));
|
||||
} else {
|
||||
if (cardOfSpell.getId().equals(spellId)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return cardOfSpell.getMainCard().getId().equals(spellId);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -16,6 +16,7 @@ import mage.filter.predicate.mageobject.NamePredicate;
|
|||
import mage.game.Game;
|
||||
import mage.players.Player;
|
||||
import mage.target.common.TargetCardInHand;
|
||||
import mage.util.CardUtil;
|
||||
|
||||
import java.util.HashSet;
|
||||
import java.util.Map;
|
||||
|
@ -108,10 +109,12 @@ class TargetTwoNonLandCardsWithSameNameInHand extends TargetCardInHand {
|
|||
}
|
||||
} else {
|
||||
for (UUID cardToCheck : cardsToCheck) {
|
||||
FilterCard nameFilter = new FilterCard();
|
||||
Card card = game.getCard(cardToCheck);
|
||||
if (card != null) {
|
||||
nameFilter.add(new NamePredicate(card.isSplitCard() ? ((SplitCard) card).getLeftHalfCard().getName() : card.getName()));
|
||||
String nameToSearch = CardUtil.getCardNameForSameNameSearch(card);
|
||||
FilterCard nameFilter = new FilterCard();
|
||||
nameFilter.add(new NamePredicate(nameToSearch));
|
||||
|
||||
if (cardsToCheck.count(nameFilter, game) > 1) {
|
||||
newPossibleTargets.add(cardToCheck);
|
||||
}
|
||||
|
@ -133,8 +136,10 @@ class TargetTwoNonLandCardsWithSameNameInHand extends TargetCardInHand {
|
|||
}
|
||||
int possibleCards = 0;
|
||||
for (Card card : cardsToCheck.getCards(game)) {
|
||||
String nameToSearch = CardUtil.getCardNameForSameNameSearch(card);
|
||||
FilterCard nameFilter = new FilterCard();
|
||||
nameFilter.add(new NamePredicate(card.isSplitCard() ? ((SplitCard) card).getLeftHalfCard().getName() : card.getName()));
|
||||
nameFilter.add(new NamePredicate(nameToSearch));
|
||||
|
||||
if (cardsToCheck.count(nameFilter, game) > 1) {
|
||||
++possibleCards;
|
||||
}
|
||||
|
@ -149,10 +154,12 @@ class TargetTwoNonLandCardsWithSameNameInHand extends TargetCardInHand {
|
|||
if (card != null) {
|
||||
if (targets.size() == 1) {
|
||||
Card card2 = game.getCard(targets.entrySet().iterator().next().getKey());
|
||||
return card2 != null && card2.getName().equals(card.getName());
|
||||
return CardUtil.haveSameNames(card2, card);
|
||||
} else {
|
||||
String nameToSearch = CardUtil.getCardNameForSameNameSearch(card);
|
||||
FilterCard nameFilter = new FilterCard();
|
||||
nameFilter.add(new NamePredicate(card.isSplitCard() ? ((SplitCard) card).getLeftHalfCard().getName() : card.getName()));
|
||||
nameFilter.add(new NamePredicate(nameToSearch));
|
||||
|
||||
Player player = game.getPlayer(card.getOwnerId());
|
||||
return player != null && player.getHand().getCards(nameFilter, game).size() > 1;
|
||||
}
|
||||
|
|
|
@ -5,7 +5,6 @@ import mage.abilities.effects.OneShotEffect;
|
|||
import mage.cards.Card;
|
||||
import mage.cards.CardImpl;
|
||||
import mage.cards.CardSetInfo;
|
||||
import mage.cards.SplitCard;
|
||||
import mage.constants.CardType;
|
||||
import mage.constants.Outcome;
|
||||
import mage.constants.SuperType;
|
||||
|
@ -15,12 +14,13 @@ import mage.filter.predicate.Predicates;
|
|||
import mage.filter.predicate.mageobject.NamePredicate;
|
||||
import mage.game.Game;
|
||||
import mage.players.Player;
|
||||
import mage.target.TargetCard;
|
||||
import mage.target.common.TargetCardInGraveyard;
|
||||
import mage.target.common.TargetCardInLibrary;
|
||||
import mage.util.CardUtil;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.UUID;
|
||||
import mage.target.TargetCard;
|
||||
|
||||
/**
|
||||
* @author North
|
||||
|
@ -82,8 +82,7 @@ class SurgicalExtractionEffect extends OneShotEffect {
|
|||
if (chosenCard != null && controller != null) {
|
||||
Player owner = game.getPlayer(chosenCard.getOwnerId());
|
||||
if (owner != null) {
|
||||
String nameToSearch = chosenCard.isSplitCard()
|
||||
? ((SplitCard) chosenCard).getLeftHalfCard().getName() : chosenCard.getName();
|
||||
String nameToSearch = CardUtil.getCardNameForSameNameSearch(chosenCard);
|
||||
FilterCard filterNamedCard = new FilterCard("card named " + nameToSearch);
|
||||
filterNamedCard.add(new NamePredicate(nameToSearch));
|
||||
|
||||
|
|
|
@ -17,6 +17,7 @@ import mage.game.events.GameEvent;
|
|||
import mage.game.permanent.Permanent;
|
||||
import mage.players.Player;
|
||||
import mage.target.common.TargetCardInYourGraveyard;
|
||||
import mage.util.CardUtil;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
|
@ -131,13 +132,7 @@ class TamiyoCollectorOfTalesEffect extends OneShotEffect {
|
|||
Cards cards2 = new CardsImpl();
|
||||
player.revealCards(source, cards, game);
|
||||
for (Card card : cards.getCards(game)) {
|
||||
if (card.isSplitCard()) {
|
||||
if (((SplitCard) card).getLeftHalfCard().getName().equals(choice.getChoice())
|
||||
|| ((SplitCard) card).getRightHalfCard().getName().equals(choice.getChoice())) {
|
||||
cards2.add(card);
|
||||
}
|
||||
}
|
||||
if (card.getName().equals(choice.getChoice())) {
|
||||
if (CardUtil.haveSameNames(card, choice.getChoice(), game)) {
|
||||
cards2.add(card);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,7 +1,5 @@
|
|||
|
||||
package mage.cards.u;
|
||||
|
||||
import java.util.UUID;
|
||||
import mage.MageObject;
|
||||
import mage.abilities.Ability;
|
||||
import mage.abilities.common.SimpleActivatedAbility;
|
||||
|
@ -10,10 +8,7 @@ import mage.abilities.costs.common.DiscardTargetCost;
|
|||
import mage.abilities.costs.mana.ManaCostsImpl;
|
||||
import mage.abilities.effects.OneShotEffect;
|
||||
import mage.abilities.effects.common.search.SearchLibraryPutInHandEffect;
|
||||
import mage.cards.Card;
|
||||
import mage.cards.CardImpl;
|
||||
import mage.cards.CardSetInfo;
|
||||
import mage.cards.SplitCard;
|
||||
import mage.cards.*;
|
||||
import mage.constants.CardType;
|
||||
import mage.constants.Outcome;
|
||||
import mage.constants.SpellAbilityType;
|
||||
|
@ -25,14 +20,15 @@ import mage.game.stack.Spell;
|
|||
import mage.target.common.TargetCardInHand;
|
||||
import mage.target.common.TargetCardInLibrary;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author L_J
|
||||
*/
|
||||
public class UrzasHotTub extends CardImpl {
|
||||
|
||||
public UrzasHotTub(UUID ownerId, CardSetInfo setInfo) {
|
||||
super(ownerId,setInfo,new CardType[]{CardType.ARTIFACT},"{2}");
|
||||
super(ownerId, setInfo, new CardType[]{CardType.ARTIFACT}, "{2}");
|
||||
|
||||
// {2}, Discard a card: Search your library for a card that shares a complete word in its name with the discarded card, reveal it, put it into your hand, then shuffle your library.
|
||||
Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new UrzasHotTubEffect(), new ManaCostsImpl("{2}"));
|
||||
|
@ -95,21 +91,23 @@ class UrzasHotTubPredicate implements Predicate<MageObject> {
|
|||
public boolean apply(MageObject input, Game game) {
|
||||
String name = input.getName();
|
||||
if (input instanceof SplitCard) {
|
||||
return sharesWordWithName(((SplitCard)input).getLeftHalfCard().getName()) || sharesWordWithName(((SplitCard)input).getRightHalfCard().getName());
|
||||
} else if (input instanceof Spell && ((Spell) input).getSpellAbility().getSpellAbilityType() == SpellAbilityType.SPLIT_FUSED){
|
||||
SplitCard card = (SplitCard) ((Spell)input).getCard();
|
||||
return sharesWordWithName(((SplitCard) input).getLeftHalfCard().getName()) || sharesWordWithName(((SplitCard) input).getRightHalfCard().getName());
|
||||
} else if (input instanceof ModalDoubleFacesCard) {
|
||||
return sharesWordWithName(((ModalDoubleFacesCard) input).getLeftHalfCard().getName()) || sharesWordWithName(((ModalDoubleFacesCard) input).getRightHalfCard().getName());
|
||||
} else if (input instanceof Spell && ((Spell) input).getSpellAbility().getSpellAbilityType() == SpellAbilityType.SPLIT_FUSED) {
|
||||
SplitCard card = (SplitCard) ((Spell) input).getCard();
|
||||
return sharesWordWithName(card.getLeftHalfCard().getName()) || sharesWordWithName(card.getRightHalfCard().getName());
|
||||
} else {
|
||||
if (name.contains(" // ")) {
|
||||
String leftName = name.substring(0, name.indexOf(" // "));
|
||||
String rightName = name.substring(name.indexOf(" // ") + 4, name.length());
|
||||
String rightName = name.substring(name.indexOf(" // ") + 4);
|
||||
return sharesWordWithName(leftName) || sharesWordWithName(rightName);
|
||||
} else {
|
||||
return sharesWordWithName(name);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private boolean sharesWordWithName(String str) {
|
||||
if (referenceName == null || referenceName == "") {
|
||||
return false;
|
||||
|
|
|
@ -1,94 +1,15 @@
|
|||
package mage.sets;
|
||||
|
||||
import mage.cards.ExpansionSet;
|
||||
import mage.cards.a.AkoumWarrior;
|
||||
import mage.constants.Rarity;
|
||||
import mage.constants.SetType;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @author TheElk801
|
||||
*/
|
||||
public final class ZendikarRising extends ExpansionSet {
|
||||
|
||||
private static final List<String> unfinishedLand = Arrays.asList(
|
||||
"Agadeem, the Undercrypt",
|
||||
"Akoum Teeth",
|
||||
"Bala Ged Sanctuary",
|
||||
"Beyeen Coast",
|
||||
"Blackbloom Bog",
|
||||
"Branchloft Pathway",
|
||||
"Boulderloft Pathway",
|
||||
"Brightclimb Pathway",
|
||||
"Grimclimb Pathway",
|
||||
"Clearwater Pathway",
|
||||
"Murkwater Pathway",
|
||||
"Cragcrown Pathway",
|
||||
"Timbercrown Pathway",
|
||||
"Emeria, Shattered Skyclave",
|
||||
"Glasspool Shore",
|
||||
"Hagra Broodpit",
|
||||
"Jwari Ruins",
|
||||
"Kabira Plateau",
|
||||
"Kazandu Valley",
|
||||
"Kazuul's Cliffs",
|
||||
"Khalni Territory",
|
||||
"Makindi Mesas",
|
||||
"Malakir Mire",
|
||||
"Needleverge Pathway",
|
||||
"Pillarverge Pathway",
|
||||
"Ondu Skyruins",
|
||||
"Pelakka Caverns",
|
||||
"Riverglide Pathway",
|
||||
"Lavaglide Pathway",
|
||||
"Sea Gate, Reborn",
|
||||
"Sejiri Glacier",
|
||||
"Shatterskull, the Hammer Pass",
|
||||
"Silundi Isle",
|
||||
"Skyclave Basilica",
|
||||
"Song-Mad Ruins",
|
||||
"Spikefield Cave",
|
||||
"Tangled Vale",
|
||||
"Turntimber, Serpentine Wood",
|
||||
"Umara Skyfalls",
|
||||
"Valakut Stoneforge",
|
||||
"Vastwood Thicket",
|
||||
"Zof Bloodbog"
|
||||
);
|
||||
private static final List<String> unfinishedNonland = Arrays.asList(
|
||||
"Agadeem's Awakening",
|
||||
"Akoum Warrior",
|
||||
"Bala Ged Recovery",
|
||||
"Beyeen Veil",
|
||||
"Blackbloom Rogue",
|
||||
"Emeria's Call",
|
||||
"Glasspool Mimic",
|
||||
"Hagra Mauling",
|
||||
"Jwari Disruption",
|
||||
"Kabira Takedown",
|
||||
"Kazandu Mammoth",
|
||||
"Kazuul's Fury",
|
||||
"Khalni Ambush",
|
||||
"Makindi Stampede",
|
||||
"Malakir Rebirth",
|
||||
"Ondu Inversion",
|
||||
"Pelakka Predation",
|
||||
"Sea Gate Restoration",
|
||||
"Sejiri Shelter",
|
||||
"Shatterskull Smashing",
|
||||
"Silundi Vision",
|
||||
"Skyclave Cleric",
|
||||
"Song-Mad Treachery",
|
||||
"Spikefield Hazard",
|
||||
"Tangled Florahedron",
|
||||
"Turntimber Symbiosis",
|
||||
"Umara Wizard",
|
||||
"Valakut Awakening",
|
||||
"Vastwood Fortification",
|
||||
"Zof Consumption"
|
||||
);
|
||||
|
||||
private static final ZendikarRising instance = new ZendikarRising();
|
||||
|
||||
public static ZendikarRising getInstance() {
|
||||
|
@ -110,30 +31,20 @@ public final class ZendikarRising extends ExpansionSet {
|
|||
|
||||
cards.add(new SetCardInfo("Acquisitions Expert", 89, Rarity.UNCOMMON, mage.cards.a.AcquisitionsExpert.class));
|
||||
cards.add(new SetCardInfo("Adventure Awaits", 177, Rarity.COMMON, mage.cards.a.AdventureAwaits.class));
|
||||
cards.add(new SetCardInfo("Agadeem's Awakening", 336, Rarity.MYTHIC, mage.cards.a.AgadeemsAwakening.class));
|
||||
cards.add(new SetCardInfo("Agadeem's Awakening", 90, Rarity.MYTHIC, mage.cards.a.AgadeemsAwakening.class));
|
||||
cards.add(new SetCardInfo("Agadeem, the Undercrypt", 336, Rarity.MYTHIC, mage.cards.a.AgadeemTheUndercrypt.class));
|
||||
cards.add(new SetCardInfo("Agadeem, the Undercrypt", 90, Rarity.MYTHIC, mage.cards.a.AgadeemTheUndercrypt.class));
|
||||
cards.add(new SetCardInfo("Akiri, Fearless Voyager", 220, Rarity.RARE, mage.cards.a.AkiriFearlessVoyager.class, NON_FULL_USE_VARIOUS));
|
||||
cards.add(new SetCardInfo("Akiri, Fearless Voyager", 365, Rarity.RARE, mage.cards.a.AkiriFearlessVoyager.class, NON_FULL_USE_VARIOUS));
|
||||
cards.add(new SetCardInfo("Akoum Hellhound", 133, Rarity.COMMON, mage.cards.a.AkoumHellhound.class, NON_FULL_USE_VARIOUS));
|
||||
cards.add(new SetCardInfo("Akoum Hellhound", 299, Rarity.COMMON, mage.cards.a.AkoumHellhound.class, NON_FULL_USE_VARIOUS));
|
||||
cards.add(new SetCardInfo("Akoum Teeth", 134, Rarity.UNCOMMON, mage.cards.a.AkoumTeeth.class));
|
||||
cards.add(new SetCardInfo("Akoum Warrior", 134, Rarity.UNCOMMON, mage.cards.a.AkoumWarrior.class));
|
||||
cards.add(new SetCardInfo("Akiri, Fearless Voyager", 220, Rarity.RARE, mage.cards.a.AkiriFearlessVoyager.class));
|
||||
cards.add(new SetCardInfo("Akoum Hellhound", 133, Rarity.COMMON, mage.cards.a.AkoumHellhound.class));
|
||||
cards.add(new SetCardInfo("Akoum Warrior", 134, Rarity.UNCOMMON, AkoumWarrior.class));
|
||||
cards.add(new SetCardInfo("Allied Assault", 1, Rarity.UNCOMMON, mage.cards.a.AlliedAssault.class));
|
||||
cards.add(new SetCardInfo("Ancient Greenwarden", 178, Rarity.MYTHIC, mage.cards.a.AncientGreenwarden.class, NON_FULL_USE_VARIOUS));
|
||||
cards.add(new SetCardInfo("Ancient Greenwarden", 357, Rarity.MYTHIC, mage.cards.a.AncientGreenwarden.class, NON_FULL_USE_VARIOUS));
|
||||
cards.add(new SetCardInfo("Angel of Destiny", 2, Rarity.MYTHIC, mage.cards.a.AngelOfDestiny.class, NON_FULL_USE_VARIOUS));
|
||||
cards.add(new SetCardInfo("Angel of Destiny", 314, Rarity.MYTHIC, mage.cards.a.AngelOfDestiny.class, NON_FULL_USE_VARIOUS));
|
||||
cards.add(new SetCardInfo("Ancient Greenwarden", 178, Rarity.MYTHIC, mage.cards.a.AncientGreenwarden.class));
|
||||
cards.add(new SetCardInfo("Angel of Destiny", 2, Rarity.MYTHIC, mage.cards.a.AngelOfDestiny.class));
|
||||
cards.add(new SetCardInfo("Angelheart Protector", 3, Rarity.COMMON, mage.cards.a.AngelheartProtector.class));
|
||||
cards.add(new SetCardInfo("Anticognition", 45, Rarity.COMMON, mage.cards.a.Anticognition.class));
|
||||
cards.add(new SetCardInfo("Archon of Emeria", 315, Rarity.RARE, mage.cards.a.ArchonOfEmeria.class, NON_FULL_USE_VARIOUS));
|
||||
cards.add(new SetCardInfo("Archon of Emeria", 4, Rarity.RARE, mage.cards.a.ArchonOfEmeria.class, NON_FULL_USE_VARIOUS));
|
||||
cards.add(new SetCardInfo("Archpriest of Iona", 316, Rarity.RARE, mage.cards.a.ArchpriestOfIona.class, NON_FULL_USE_VARIOUS));
|
||||
cards.add(new SetCardInfo("Archpriest of Iona", 5, Rarity.RARE, mage.cards.a.ArchpriestOfIona.class, NON_FULL_USE_VARIOUS));
|
||||
cards.add(new SetCardInfo("Archon of Emeria", 4, Rarity.RARE, mage.cards.a.ArchonOfEmeria.class));
|
||||
cards.add(new SetCardInfo("Archpriest of Iona", 5, Rarity.RARE, mage.cards.a.ArchpriestOfIona.class));
|
||||
cards.add(new SetCardInfo("Ardent Electromancer", 135, Rarity.COMMON, mage.cards.a.ArdentElectromancer.class));
|
||||
cards.add(new SetCardInfo("Ashaya, Soul of the Wild", 179, Rarity.MYTHIC, mage.cards.a.AshayaSoulOfTheWild.class, NON_FULL_USE_VARIOUS));
|
||||
cards.add(new SetCardInfo("Ashaya, Soul of the Wild", 358, Rarity.MYTHIC, mage.cards.a.AshayaSoulOfTheWild.class, NON_FULL_USE_VARIOUS));
|
||||
cards.add(new SetCardInfo("Ashaya, Soul of the Wild", 179, Rarity.MYTHIC, mage.cards.a.AshayaSoulOfTheWild.class));
|
||||
cards.add(new SetCardInfo("Attended Healer", 6, Rarity.UNCOMMON, mage.cards.a.AttendedHealer.class));
|
||||
cards.add(new SetCardInfo("Bala Ged Recovery", 180, Rarity.UNCOMMON, mage.cards.b.BalaGedRecovery.class));
|
||||
cards.add(new SetCardInfo("Bala Ged Sanctuary", 180, Rarity.UNCOMMON, mage.cards.b.BalaGedSanctuary.class));
|
||||
|
@ -144,48 +55,32 @@ public final class ZendikarRising extends ExpansionSet {
|
|||
cards.add(new SetCardInfo("Blackbloom Rogue", 91, Rarity.UNCOMMON, mage.cards.b.BlackbloomRogue.class));
|
||||
cards.add(new SetCardInfo("Blood Beckoning", 92, Rarity.COMMON, mage.cards.b.BloodBeckoning.class));
|
||||
cards.add(new SetCardInfo("Blood Price", 93, Rarity.COMMON, mage.cards.b.BloodPrice.class));
|
||||
cards.add(new SetCardInfo("Bloodchief's Thirst", 388, Rarity.UNCOMMON, mage.cards.b.BloodchiefsThirst.class, NON_FULL_USE_VARIOUS));
|
||||
cards.add(new SetCardInfo("Bloodchief's Thirst", 94, Rarity.UNCOMMON, mage.cards.b.BloodchiefsThirst.class, NON_FULL_USE_VARIOUS));
|
||||
cards.add(new SetCardInfo("Bloodchief's Thirst", 94, Rarity.UNCOMMON, mage.cards.b.BloodchiefsThirst.class));
|
||||
cards.add(new SetCardInfo("Boulderloft Pathway", 258, Rarity.RARE, mage.cards.b.BoulderloftPathway.class));
|
||||
cards.add(new SetCardInfo("Boulderloft Pathway", 284, Rarity.RARE, mage.cards.b.BoulderloftPathway.class));
|
||||
cards.add(new SetCardInfo("Branchloft Pathway", 258, Rarity.RARE, mage.cards.b.BranchloftPathway.class));
|
||||
cards.add(new SetCardInfo("Branchloft Pathway", 284, Rarity.RARE, mage.cards.b.BranchloftPathway.class));
|
||||
cards.add(new SetCardInfo("Brightclimb Pathway", 259, Rarity.RARE, mage.cards.b.BrightclimbPathway.class));
|
||||
cards.add(new SetCardInfo("Brightclimb Pathway", 285, Rarity.RARE, mage.cards.b.BrightclimbPathway.class));
|
||||
cards.add(new SetCardInfo("Broken Wings", 181, Rarity.COMMON, mage.cards.b.BrokenWings.class));
|
||||
cards.add(new SetCardInfo("Brushfire Elemental", 221, Rarity.UNCOMMON, mage.cards.b.BrushfireElemental.class, NON_FULL_USE_VARIOUS));
|
||||
cards.add(new SetCardInfo("Brushfire Elemental", 311, Rarity.UNCOMMON, mage.cards.b.BrushfireElemental.class, NON_FULL_USE_VARIOUS));
|
||||
cards.add(new SetCardInfo("Brushfire Elemental", 221, Rarity.UNCOMMON, mage.cards.b.BrushfireElemental.class));
|
||||
cards.add(new SetCardInfo("Bubble Snare", 47, Rarity.COMMON, mage.cards.b.BubbleSnare.class));
|
||||
cards.add(new SetCardInfo("Canopy Baloth", 182, Rarity.COMMON, mage.cards.c.CanopyBaloth.class, NON_FULL_USE_VARIOUS));
|
||||
cards.add(new SetCardInfo("Canopy Baloth", 304, Rarity.COMMON, mage.cards.c.CanopyBaloth.class, NON_FULL_USE_VARIOUS));
|
||||
cards.add(new SetCardInfo("Canyon Jerboa", 290, Rarity.UNCOMMON, mage.cards.c.CanyonJerboa.class, NON_FULL_USE_VARIOUS));
|
||||
cards.add(new SetCardInfo("Canyon Jerboa", 7, Rarity.UNCOMMON, mage.cards.c.CanyonJerboa.class, NON_FULL_USE_VARIOUS));
|
||||
cards.add(new SetCardInfo("Canopy Baloth", 182, Rarity.COMMON, mage.cards.c.CanopyBaloth.class));
|
||||
cards.add(new SetCardInfo("Canyon Jerboa", 7, Rarity.UNCOMMON, mage.cards.c.CanyonJerboa.class));
|
||||
cards.add(new SetCardInfo("Cascade Seer", 48, Rarity.COMMON, mage.cards.c.CascadeSeer.class));
|
||||
cards.add(new SetCardInfo("Charix, the Raging Isle", 325, Rarity.RARE, mage.cards.c.CharixTheRagingIsle.class, NON_FULL_USE_VARIOUS));
|
||||
cards.add(new SetCardInfo("Charix, the Raging Isle", 386, Rarity.RARE, mage.cards.c.CharixTheRagingIsle.class, NON_FULL_USE_VARIOUS));
|
||||
cards.add(new SetCardInfo("Charix, the Raging Isle", 49, Rarity.RARE, mage.cards.c.CharixTheRagingIsle.class, NON_FULL_USE_VARIOUS));
|
||||
cards.add(new SetCardInfo("Charix, the Raging Isle", 49, Rarity.RARE, mage.cards.c.CharixTheRagingIsle.class));
|
||||
cards.add(new SetCardInfo("Chilling Trap", 50, Rarity.COMMON, mage.cards.c.ChillingTrap.class));
|
||||
cards.add(new SetCardInfo("Cinderclasm", 136, Rarity.UNCOMMON, mage.cards.c.Cinderclasm.class));
|
||||
cards.add(new SetCardInfo("Cleansing Wildfire", 137, Rarity.COMMON, mage.cards.c.CleansingWildfire.class));
|
||||
cards.add(new SetCardInfo("Clearwater Pathway", 260, Rarity.RARE, mage.cards.c.ClearwaterPathway.class));
|
||||
cards.add(new SetCardInfo("Clearwater Pathway", 286, Rarity.RARE, mage.cards.c.ClearwaterPathway.class));
|
||||
cards.add(new SetCardInfo("Cleric of Chill Depths", 51, Rarity.COMMON, mage.cards.c.ClericOfChillDepths.class));
|
||||
cards.add(new SetCardInfo("Cleric of Life's Bond", 222, Rarity.UNCOMMON, mage.cards.c.ClericOfLifesBond.class));
|
||||
cards.add(new SetCardInfo("Cliffhaven Kitesail", 243, Rarity.COMMON, mage.cards.c.CliffhavenKitesail.class));
|
||||
cards.add(new SetCardInfo("Cliffhaven Sell-Sword", 8, Rarity.COMMON, mage.cards.c.CliffhavenSellSword.class));
|
||||
cards.add(new SetCardInfo("Concerted Defense", 52, Rarity.UNCOMMON, mage.cards.c.ConcertedDefense.class));
|
||||
cards.add(new SetCardInfo("Confounding Conundrum", 326, Rarity.RARE, mage.cards.c.ConfoundingConundrum.class, NON_FULL_USE_VARIOUS));
|
||||
cards.add(new SetCardInfo("Confounding Conundrum", 53, Rarity.RARE, mage.cards.c.ConfoundingConundrum.class, NON_FULL_USE_VARIOUS));
|
||||
cards.add(new SetCardInfo("Coralhelm Chronicler", 327, Rarity.RARE, mage.cards.c.CoralhelmChronicler.class, NON_FULL_USE_VARIOUS));
|
||||
cards.add(new SetCardInfo("Coralhelm Chronicler", 54, Rarity.RARE, mage.cards.c.CoralhelmChronicler.class, NON_FULL_USE_VARIOUS));
|
||||
cards.add(new SetCardInfo("Coveted Prize", 337, Rarity.RARE, mage.cards.c.CovetedPrize.class, NON_FULL_USE_VARIOUS));
|
||||
cards.add(new SetCardInfo("Coveted Prize", 95, Rarity.RARE, mage.cards.c.CovetedPrize.class, NON_FULL_USE_VARIOUS));
|
||||
cards.add(new SetCardInfo("Confounding Conundrum", 53, Rarity.RARE, mage.cards.c.ConfoundingConundrum.class));
|
||||
cards.add(new SetCardInfo("Coralhelm Chronicler", 54, Rarity.RARE, mage.cards.c.CoralhelmChronicler.class));
|
||||
cards.add(new SetCardInfo("Coveted Prize", 95, Rarity.RARE, mage.cards.c.CovetedPrize.class));
|
||||
cards.add(new SetCardInfo("Cragcrown Pathway", 261, Rarity.RARE, mage.cards.c.CragcrownPathway.class));
|
||||
cards.add(new SetCardInfo("Cragcrown Pathway", 287, Rarity.RARE, mage.cards.c.CragcrownPathway.class));
|
||||
cards.add(new SetCardInfo("Cragplate Baloth", 183, Rarity.RARE, mage.cards.c.CragplateBaloth.class, NON_FULL_USE_VARIOUS));
|
||||
cards.add(new SetCardInfo("Cragplate Baloth", 359, Rarity.RARE, mage.cards.c.CragplateBaloth.class, NON_FULL_USE_VARIOUS));
|
||||
cards.add(new SetCardInfo("Crawling Barrens", 262, Rarity.RARE, mage.cards.c.CrawlingBarrens.class, NON_FULL_USE_VARIOUS));
|
||||
cards.add(new SetCardInfo("Crawling Barrens", 378, Rarity.RARE, mage.cards.c.CrawlingBarrens.class, NON_FULL_USE_VARIOUS));
|
||||
cards.add(new SetCardInfo("Cragplate Baloth", 183, Rarity.RARE, mage.cards.c.CragplateBaloth.class));
|
||||
cards.add(new SetCardInfo("Crawling Barrens", 262, Rarity.RARE, mage.cards.c.CrawlingBarrens.class));
|
||||
cards.add(new SetCardInfo("Cunning Geysermage", 55, Rarity.COMMON, mage.cards.c.CunningGeysermage.class));
|
||||
cards.add(new SetCardInfo("Dauntless Survivor", 184, Rarity.COMMON, mage.cards.d.DauntlessSurvivor.class));
|
||||
cards.add(new SetCardInfo("Dauntless Unity", 9, Rarity.COMMON, mage.cards.d.DauntlessUnity.class));
|
||||
|
@ -194,71 +89,47 @@ public final class ZendikarRising extends ExpansionSet {
|
|||
cards.add(new SetCardInfo("Demon's Disciple", 97, Rarity.UNCOMMON, mage.cards.d.DemonsDisciple.class));
|
||||
cards.add(new SetCardInfo("Disenchant", 10, Rarity.COMMON, mage.cards.d.Disenchant.class));
|
||||
cards.add(new SetCardInfo("Drana's Silencer", 99, Rarity.COMMON, mage.cards.d.DranasSilencer.class));
|
||||
cards.add(new SetCardInfo("Drana, the Last Bloodchief", 338, Rarity.MYTHIC, mage.cards.d.DranaTheLastBloodchief.class, NON_FULL_USE_VARIOUS));
|
||||
cards.add(new SetCardInfo("Drana, the Last Bloodchief", 98, Rarity.MYTHIC, mage.cards.d.DranaTheLastBloodchief.class, NON_FULL_USE_VARIOUS));
|
||||
cards.add(new SetCardInfo("Dreadwurm", 100, Rarity.COMMON, mage.cards.d.Dreadwurm.class, NON_FULL_USE_VARIOUS));
|
||||
cards.add(new SetCardInfo("Dreadwurm", 297, Rarity.COMMON, mage.cards.d.Dreadwurm.class, NON_FULL_USE_VARIOUS));
|
||||
cards.add(new SetCardInfo("Drana, the Last Bloodchief", 98, Rarity.MYTHIC, mage.cards.d.DranaTheLastBloodchief.class));
|
||||
cards.add(new SetCardInfo("Dreadwurm", 100, Rarity.COMMON, mage.cards.d.Dreadwurm.class));
|
||||
cards.add(new SetCardInfo("Emeria Captain", 11, Rarity.UNCOMMON, mage.cards.e.EmeriaCaptain.class));
|
||||
cards.add(new SetCardInfo("Emeria's Call", 12, Rarity.MYTHIC, mage.cards.e.EmeriasCall.class));
|
||||
cards.add(new SetCardInfo("Emeria's Call", 317, Rarity.MYTHIC, mage.cards.e.EmeriasCall.class));
|
||||
cards.add(new SetCardInfo("Emeria, Shattered Skyclave", 12, Rarity.MYTHIC, mage.cards.e.EmeriaShatteredSkyclave.class));
|
||||
cards.add(new SetCardInfo("Emeria, Shattered Skyclave", 317, Rarity.MYTHIC, mage.cards.e.EmeriaShatteredSkyclave.class));
|
||||
cards.add(new SetCardInfo("Expedition Champion", 138, Rarity.COMMON, mage.cards.e.ExpeditionChampion.class));
|
||||
cards.add(new SetCardInfo("Expedition Diviner", 57, Rarity.COMMON, mage.cards.e.ExpeditionDiviner.class));
|
||||
cards.add(new SetCardInfo("Expedition Healer", 13, Rarity.COMMON, mage.cards.e.ExpeditionHealer.class));
|
||||
cards.add(new SetCardInfo("Expedition Skulker", 101, Rarity.COMMON, mage.cards.e.ExpeditionSkulker.class));
|
||||
cards.add(new SetCardInfo("Farsight Adept", 14, Rarity.COMMON, mage.cards.f.FarsightAdept.class));
|
||||
cards.add(new SetCardInfo("Fearless Fledgling", 15, Rarity.UNCOMMON, mage.cards.f.FearlessFledgling.class, NON_FULL_USE_VARIOUS));
|
||||
cards.add(new SetCardInfo("Fearless Fledgling", 291, Rarity.UNCOMMON, mage.cards.f.FearlessFledgling.class, NON_FULL_USE_VARIOUS));
|
||||
cards.add(new SetCardInfo("Fearless Fledgling", 15, Rarity.UNCOMMON, mage.cards.f.FearlessFledgling.class));
|
||||
cards.add(new SetCardInfo("Feed the Swarm", 102, Rarity.COMMON, mage.cards.f.FeedTheSwarm.class));
|
||||
cards.add(new SetCardInfo("Felidar Retreat", 16, Rarity.RARE, mage.cards.f.FelidarRetreat.class, NON_FULL_USE_VARIOUS));
|
||||
cards.add(new SetCardInfo("Felidar Retreat", 292, Rarity.RARE, mage.cards.f.FelidarRetreat.class, NON_FULL_USE_VARIOUS));
|
||||
cards.add(new SetCardInfo("Felidar Retreat", 16, Rarity.RARE, mage.cards.f.FelidarRetreat.class));
|
||||
cards.add(new SetCardInfo("Field Research", 58, Rarity.COMMON, mage.cards.f.FieldResearch.class));
|
||||
cards.add(new SetCardInfo("Fireblade Charger", 139, Rarity.UNCOMMON, mage.cards.f.FirebladeCharger.class));
|
||||
cards.add(new SetCardInfo("Fissure Wizard", 140, Rarity.COMMON, mage.cards.f.FissureWizard.class));
|
||||
cards.add(new SetCardInfo("Forest", 278, Rarity.LAND, mage.cards.basiclands.Forest.class, FULL_ART_BFZ_VARIOUS));
|
||||
cards.add(new SetCardInfo("Forest", 279, Rarity.LAND, mage.cards.basiclands.Forest.class, FULL_ART_BFZ_VARIOUS));
|
||||
cards.add(new SetCardInfo("Forest", 280, Rarity.LAND, mage.cards.basiclands.Forest.class, FULL_ART_BFZ_VARIOUS));
|
||||
cards.add(new SetCardInfo("Forest", 384, Rarity.LAND, mage.cards.basiclands.Forest.class, FULL_ART_BFZ_VARIOUS));
|
||||
cards.add(new SetCardInfo("Forsaken Monument", 244, Rarity.MYTHIC, mage.cards.f.ForsakenMonument.class, NON_FULL_USE_VARIOUS));
|
||||
cards.add(new SetCardInfo("Forsaken Monument", 374, Rarity.MYTHIC, mage.cards.f.ForsakenMonument.class, NON_FULL_USE_VARIOUS));
|
||||
cards.add(new SetCardInfo("Forsaken Monument", 244, Rarity.MYTHIC, mage.cards.f.ForsakenMonument.class));
|
||||
cards.add(new SetCardInfo("Ghastly Gloomhunter", 103, Rarity.COMMON, mage.cards.g.GhastlyGloomhunter.class));
|
||||
cards.add(new SetCardInfo("Glacial Grasp", 59, Rarity.COMMON, mage.cards.g.GlacialGrasp.class));
|
||||
cards.add(new SetCardInfo("Glasspool Mimic", 328, Rarity.RARE, mage.cards.g.GlasspoolMimic.class));
|
||||
cards.add(new SetCardInfo("Glasspool Mimic", 60, Rarity.RARE, mage.cards.g.GlasspoolMimic.class));
|
||||
cards.add(new SetCardInfo("Glasspool Shore", 328, Rarity.RARE, mage.cards.g.GlasspoolShore.class));
|
||||
cards.add(new SetCardInfo("Glasspool Shore", 60, Rarity.RARE, mage.cards.g.GlasspoolShore.class));
|
||||
cards.add(new SetCardInfo("Gnarlid Colony", 185, Rarity.COMMON, mage.cards.g.GnarlidColony.class));
|
||||
cards.add(new SetCardInfo("Goma Fada Vanguard", 141, Rarity.UNCOMMON, mage.cards.g.GomaFadaVanguard.class));
|
||||
cards.add(new SetCardInfo("Grakmaw, Skyclave Ravager", 223, Rarity.RARE, mage.cards.g.GrakmawSkyclaveRavager.class, NON_FULL_USE_VARIOUS));
|
||||
cards.add(new SetCardInfo("Grakmaw, Skyclave Ravager", 366, Rarity.RARE, mage.cards.g.GrakmawSkyclaveRavager.class, NON_FULL_USE_VARIOUS));
|
||||
cards.add(new SetCardInfo("Grakmaw, Skyclave Ravager", 223, Rarity.RARE, mage.cards.g.GrakmawSkyclaveRavager.class));
|
||||
cards.add(new SetCardInfo("Grimclimb Pathway", 259, Rarity.RARE, mage.cards.g.GrimclimbPathway.class));
|
||||
cards.add(new SetCardInfo("Grimclimb Pathway", 285, Rarity.RARE, mage.cards.g.GrimclimbPathway.class));
|
||||
cards.add(new SetCardInfo("Grotag Bug-Catcher", 142, Rarity.COMMON, mage.cards.g.GrotagBugCatcher.class));
|
||||
cards.add(new SetCardInfo("Grotag Night-Runner", 143, Rarity.UNCOMMON, mage.cards.g.GrotagNightRunner.class));
|
||||
cards.add(new SetCardInfo("Guul Draz Mucklord", 104, Rarity.COMMON, mage.cards.g.GuulDrazMucklord.class));
|
||||
cards.add(new SetCardInfo("Hagra Broodpit", 106, Rarity.RARE, mage.cards.h.HagraBroodpit.class));
|
||||
cards.add(new SetCardInfo("Hagra Broodpit", 339, Rarity.RARE, mage.cards.h.HagraBroodpit.class));
|
||||
cards.add(new SetCardInfo("Hagra Constrictor", 105, Rarity.COMMON, mage.cards.h.HagraConstrictor.class));
|
||||
cards.add(new SetCardInfo("Hagra Mauling", 106, Rarity.RARE, mage.cards.h.HagraMauling.class));
|
||||
cards.add(new SetCardInfo("Hagra Mauling", 339, Rarity.RARE, mage.cards.h.HagraMauling.class));
|
||||
cards.add(new SetCardInfo("Highborn Vampire", 107, Rarity.COMMON, mage.cards.h.HighbornVampire.class));
|
||||
cards.add(new SetCardInfo("Inordinate Rage", 144, Rarity.COMMON, mage.cards.i.InordinateRage.class));
|
||||
cards.add(new SetCardInfo("Inscription of Abundance", 186, Rarity.RARE, mage.cards.i.InscriptionOfAbundance.class, NON_FULL_USE_VARIOUS));
|
||||
cards.add(new SetCardInfo("Inscription of Abundance", 360, Rarity.RARE, mage.cards.i.InscriptionOfAbundance.class, NON_FULL_USE_VARIOUS));
|
||||
cards.add(new SetCardInfo("Inscription of Insight", 329, Rarity.RARE, mage.cards.i.InscriptionOfInsight.class, NON_FULL_USE_VARIOUS));
|
||||
cards.add(new SetCardInfo("Inscription of Insight", 61, Rarity.RARE, mage.cards.i.InscriptionOfInsight.class, NON_FULL_USE_VARIOUS));
|
||||
cards.add(new SetCardInfo("Inscription of Ruin", 108, Rarity.RARE, mage.cards.i.InscriptionOfRuin.class, NON_FULL_USE_VARIOUS));
|
||||
cards.add(new SetCardInfo("Inscription of Ruin", 340, Rarity.RARE, mage.cards.i.InscriptionOfRuin.class, NON_FULL_USE_VARIOUS));
|
||||
cards.add(new SetCardInfo("Into the Roil", 387, Rarity.COMMON, mage.cards.i.IntoTheRoil.class, NON_FULL_USE_VARIOUS));
|
||||
cards.add(new SetCardInfo("Into the Roil", 62, Rarity.COMMON, mage.cards.i.IntoTheRoil.class, NON_FULL_USE_VARIOUS));
|
||||
cards.add(new SetCardInfo("Inscription of Abundance", 186, Rarity.RARE, mage.cards.i.InscriptionOfAbundance.class));
|
||||
cards.add(new SetCardInfo("Inscription of Insight", 61, Rarity.RARE, mage.cards.i.InscriptionOfInsight.class));
|
||||
cards.add(new SetCardInfo("Inscription of Ruin", 108, Rarity.RARE, mage.cards.i.InscriptionOfRuin.class));
|
||||
cards.add(new SetCardInfo("Into the Roil", 62, Rarity.COMMON, mage.cards.i.IntoTheRoil.class));
|
||||
cards.add(new SetCardInfo("Iridescent Hornbeetle", 187, Rarity.UNCOMMON, mage.cards.i.IridescentHornbeetle.class));
|
||||
cards.add(new SetCardInfo("Island", 269, Rarity.LAND, mage.cards.basiclands.Island.class, FULL_ART_BFZ_VARIOUS));
|
||||
cards.add(new SetCardInfo("Island", 270, Rarity.LAND, mage.cards.basiclands.Island.class, FULL_ART_BFZ_VARIOUS));
|
||||
cards.add(new SetCardInfo("Island", 271, Rarity.LAND, mage.cards.basiclands.Island.class, FULL_ART_BFZ_VARIOUS));
|
||||
cards.add(new SetCardInfo("Island", 381, Rarity.LAND, mage.cards.basiclands.Island.class, FULL_ART_BFZ_VARIOUS));
|
||||
cards.add(new SetCardInfo("Jace, Mirror Mage", 281, Rarity.MYTHIC, mage.cards.j.JaceMirrorMage.class, NON_FULL_USE_VARIOUS));
|
||||
cards.add(new SetCardInfo("Jace, Mirror Mage", 63, Rarity.MYTHIC, mage.cards.j.JaceMirrorMage.class, NON_FULL_USE_VARIOUS));
|
||||
cards.add(new SetCardInfo("Jace, Mirror Mage", 63, Rarity.MYTHIC, mage.cards.j.JaceMirrorMage.class));
|
||||
cards.add(new SetCardInfo("Joraga Visionary", 188, Rarity.COMMON, mage.cards.j.JoragaVisionary.class));
|
||||
cards.add(new SetCardInfo("Journey to Oblivion", 17, Rarity.UNCOMMON, mage.cards.j.JourneyToOblivion.class));
|
||||
cards.add(new SetCardInfo("Jwari Disruption", 64, Rarity.UNCOMMON, mage.cards.j.JwariDisruption.class));
|
||||
|
@ -266,19 +137,13 @@ public final class ZendikarRising extends ExpansionSet {
|
|||
cards.add(new SetCardInfo("Kabira Outrider", 18, Rarity.COMMON, mage.cards.k.KabiraOutrider.class));
|
||||
cards.add(new SetCardInfo("Kabira Plateau", 19, Rarity.UNCOMMON, mage.cards.k.KabiraPlateau.class));
|
||||
cards.add(new SetCardInfo("Kabira Takedown", 19, Rarity.UNCOMMON, mage.cards.k.KabiraTakedown.class));
|
||||
cards.add(new SetCardInfo("Kargan Intimidator", 145, Rarity.RARE, mage.cards.k.KarganIntimidator.class, NON_FULL_USE_VARIOUS));
|
||||
cards.add(new SetCardInfo("Kargan Intimidator", 347, Rarity.RARE, mage.cards.k.KarganIntimidator.class, NON_FULL_USE_VARIOUS));
|
||||
cards.add(new SetCardInfo("Kargan Warleader", 224, Rarity.UNCOMMON, mage.cards.k.KarganWarleader.class, NON_FULL_USE_VARIOUS));
|
||||
cards.add(new SetCardInfo("Kargan Warleader", 391, Rarity.UNCOMMON, mage.cards.k.KarganWarleader.class, NON_FULL_USE_VARIOUS));
|
||||
cards.add(new SetCardInfo("Kaza, Roil Chaser", 225, Rarity.RARE, mage.cards.k.KazaRoilChaser.class, NON_FULL_USE_VARIOUS));
|
||||
cards.add(new SetCardInfo("Kaza, Roil Chaser", 367, Rarity.RARE, mage.cards.k.KazaRoilChaser.class, NON_FULL_USE_VARIOUS));
|
||||
cards.add(new SetCardInfo("Kargan Intimidator", 145, Rarity.RARE, mage.cards.k.KarganIntimidator.class));
|
||||
cards.add(new SetCardInfo("Kargan Warleader", 224, Rarity.UNCOMMON, mage.cards.k.KarganWarleader.class));
|
||||
cards.add(new SetCardInfo("Kaza, Roil Chaser", 225, Rarity.RARE, mage.cards.k.KazaRoilChaser.class));
|
||||
cards.add(new SetCardInfo("Kazandu Mammoth", 189, Rarity.RARE, mage.cards.k.KazanduMammoth.class));
|
||||
cards.add(new SetCardInfo("Kazandu Mammoth", 305, Rarity.RARE, mage.cards.k.KazanduMammoth.class));
|
||||
cards.add(new SetCardInfo("Kazandu Nectarpot", 190, Rarity.COMMON, mage.cards.k.KazanduNectarpot.class, NON_FULL_USE_VARIOUS));
|
||||
cards.add(new SetCardInfo("Kazandu Nectarpot", 306, Rarity.COMMON, mage.cards.k.KazanduNectarpot.class, NON_FULL_USE_VARIOUS));
|
||||
cards.add(new SetCardInfo("Kazandu Nectarpot", 190, Rarity.COMMON, mage.cards.k.KazanduNectarpot.class));
|
||||
cards.add(new SetCardInfo("Kazandu Stomper", 191, Rarity.COMMON, mage.cards.k.KazanduStomper.class));
|
||||
cards.add(new SetCardInfo("Kazandu Valley", 189, Rarity.RARE, mage.cards.k.KazanduValley.class));
|
||||
cards.add(new SetCardInfo("Kazandu Valley", 305, Rarity.RARE, mage.cards.k.KazanduValley.class));
|
||||
cards.add(new SetCardInfo("Kazuul's Cliffs", 146, Rarity.UNCOMMON, mage.cards.k.KazuulsCliffs.class));
|
||||
cards.add(new SetCardInfo("Kazuul's Fury", 146, Rarity.UNCOMMON, mage.cards.k.KazuulsFury.class));
|
||||
cards.add(new SetCardInfo("Khalni Ambush", 192, Rarity.UNCOMMON, mage.cards.k.KhalniAmbush.class));
|
||||
|
@ -287,39 +152,26 @@ public final class ZendikarRising extends ExpansionSet {
|
|||
cards.add(new SetCardInfo("Kor Blademaster", 21, Rarity.UNCOMMON, mage.cards.k.KorBlademaster.class));
|
||||
cards.add(new SetCardInfo("Kor Celebrant", 22, Rarity.COMMON, mage.cards.k.KorCelebrant.class));
|
||||
cards.add(new SetCardInfo("Lavaglide Pathway", 264, Rarity.RARE, mage.cards.l.LavaglidePathway.class));
|
||||
cards.add(new SetCardInfo("Lavaglide Pathway", 289, Rarity.RARE, mage.cards.l.LavaglidePathway.class));
|
||||
cards.add(new SetCardInfo("Legion Angel", 23, Rarity.RARE, mage.cards.l.LegionAngel.class, NON_FULL_USE_VARIOUS));
|
||||
cards.add(new SetCardInfo("Legion Angel", 318, Rarity.RARE, mage.cards.l.LegionAngel.class, NON_FULL_USE_VARIOUS));
|
||||
cards.add(new SetCardInfo("Leyline Tyrant", 147, Rarity.MYTHIC, mage.cards.l.LeylineTyrant.class, NON_FULL_USE_VARIOUS));
|
||||
cards.add(new SetCardInfo("Leyline Tyrant", 348, Rarity.MYTHIC, mage.cards.l.LeylineTyrant.class, NON_FULL_USE_VARIOUS));
|
||||
cards.add(new SetCardInfo("Linvala, Shield of Sea Gate", 226, Rarity.RARE, mage.cards.l.LinvalaShieldOfSeaGate.class, NON_FULL_USE_VARIOUS));
|
||||
cards.add(new SetCardInfo("Linvala, Shield of Sea Gate", 368, Rarity.RARE, mage.cards.l.LinvalaShieldOfSeaGate.class, NON_FULL_USE_VARIOUS));
|
||||
cards.add(new SetCardInfo("Legion Angel", 23, Rarity.RARE, mage.cards.l.LegionAngel.class));
|
||||
cards.add(new SetCardInfo("Leyline Tyrant", 147, Rarity.MYTHIC, mage.cards.l.LeylineTyrant.class));
|
||||
cards.add(new SetCardInfo("Linvala, Shield of Sea Gate", 226, Rarity.RARE, mage.cards.l.LinvalaShieldOfSeaGate.class));
|
||||
cards.add(new SetCardInfo("Lithoform Blight", 109, Rarity.UNCOMMON, mage.cards.l.LithoformBlight.class));
|
||||
cards.add(new SetCardInfo("Lithoform Engine", 245, Rarity.MYTHIC, mage.cards.l.LithoformEngine.class, NON_FULL_USE_VARIOUS));
|
||||
cards.add(new SetCardInfo("Lithoform Engine", 375, Rarity.MYTHIC, mage.cards.l.LithoformEngine.class, NON_FULL_USE_VARIOUS));
|
||||
cards.add(new SetCardInfo("Living Tempest", 65, Rarity.COMMON, mage.cards.l.LivingTempest.class));
|
||||
cards.add(new SetCardInfo("Lotus Cobra", 193, Rarity.RARE, mage.cards.l.LotusCobra.class, NON_FULL_USE_VARIOUS));
|
||||
cards.add(new SetCardInfo("Lotus Cobra", 307, Rarity.RARE, mage.cards.l.LotusCobra.class, NON_FULL_USE_VARIOUS));
|
||||
cards.add(new SetCardInfo("Lotus Cobra", 193, Rarity.RARE, mage.cards.l.LotusCobra.class));
|
||||
cards.add(new SetCardInfo("Lullmage's Domination", 66, Rarity.UNCOMMON, mage.cards.l.LullmagesDomination.class));
|
||||
cards.add(new SetCardInfo("Lullmage's Familiar", 227, Rarity.UNCOMMON, mage.cards.l.LullmagesFamiliar.class));
|
||||
cards.add(new SetCardInfo("Luminarch Aspirant", 24, Rarity.RARE, mage.cards.l.LuminarchAspirant.class, NON_FULL_USE_VARIOUS));
|
||||
cards.add(new SetCardInfo("Luminarch Aspirant", 319, Rarity.RARE, mage.cards.l.LuminarchAspirant.class, NON_FULL_USE_VARIOUS));
|
||||
cards.add(new SetCardInfo("Maddening Cacophony", 330, Rarity.RARE, mage.cards.m.MaddeningCacophony.class, NON_FULL_USE_VARIOUS));
|
||||
cards.add(new SetCardInfo("Maddening Cacophony", 67, Rarity.RARE, mage.cards.m.MaddeningCacophony.class, NON_FULL_USE_VARIOUS));
|
||||
cards.add(new SetCardInfo("Magmatic Channeler", 148, Rarity.RARE, mage.cards.m.MagmaticChanneler.class, NON_FULL_USE_VARIOUS));
|
||||
cards.add(new SetCardInfo("Magmatic Channeler", 349, Rarity.RARE, mage.cards.m.MagmaticChanneler.class, NON_FULL_USE_VARIOUS));
|
||||
cards.add(new SetCardInfo("Luminarch Aspirant", 24, Rarity.RARE, mage.cards.l.LuminarchAspirant.class));
|
||||
cards.add(new SetCardInfo("Maddening Cacophony", 67, Rarity.RARE, mage.cards.m.MaddeningCacophony.class));
|
||||
cards.add(new SetCardInfo("Magmatic Channeler", 148, Rarity.RARE, mage.cards.m.MagmaticChanneler.class));
|
||||
cards.add(new SetCardInfo("Makindi Mesas", 26, Rarity.UNCOMMON, mage.cards.m.MakindiMesas.class));
|
||||
cards.add(new SetCardInfo("Makindi Ox", 25, Rarity.COMMON, mage.cards.m.MakindiOx.class, NON_FULL_USE_VARIOUS));
|
||||
cards.add(new SetCardInfo("Makindi Ox", 293, Rarity.COMMON, mage.cards.m.MakindiOx.class, NON_FULL_USE_VARIOUS));
|
||||
cards.add(new SetCardInfo("Makindi Ox", 25, Rarity.COMMON, mage.cards.m.MakindiOx.class));
|
||||
cards.add(new SetCardInfo("Makindi Stampede", 26, Rarity.UNCOMMON, mage.cards.m.MakindiStampede.class));
|
||||
cards.add(new SetCardInfo("Malakir Blood-Priest", 110, Rarity.COMMON, mage.cards.m.MalakirBloodPriest.class));
|
||||
cards.add(new SetCardInfo("Malakir Mire", 111, Rarity.UNCOMMON, mage.cards.m.MalakirMire.class));
|
||||
cards.add(new SetCardInfo("Malakir Rebirth", 111, Rarity.UNCOMMON, mage.cards.m.MalakirRebirth.class));
|
||||
cards.add(new SetCardInfo("Marauding Blight-Priest", 112, Rarity.COMMON, mage.cards.m.MaraudingBlightPriest.class));
|
||||
cards.add(new SetCardInfo("Master of Winds", 331, Rarity.RARE, mage.cards.m.MasterOfWinds.class, NON_FULL_USE_VARIOUS));
|
||||
cards.add(new SetCardInfo("Master of Winds", 68, Rarity.RARE, mage.cards.m.MasterOfWinds.class, NON_FULL_USE_VARIOUS));
|
||||
cards.add(new SetCardInfo("Maul of the Skyclaves", 27, Rarity.RARE, mage.cards.m.MaulOfTheSkyclaves.class, NON_FULL_USE_VARIOUS));
|
||||
cards.add(new SetCardInfo("Maul of the Skyclaves", 320, Rarity.RARE, mage.cards.m.MaulOfTheSkyclaves.class, NON_FULL_USE_VARIOUS));
|
||||
cards.add(new SetCardInfo("Master of Winds", 68, Rarity.RARE, mage.cards.m.MasterOfWinds.class));
|
||||
cards.add(new SetCardInfo("Maul of the Skyclaves", 27, Rarity.RARE, mage.cards.m.MaulOfTheSkyclaves.class));
|
||||
cards.add(new SetCardInfo("Merfolk Falconer", 69, Rarity.UNCOMMON, mage.cards.m.MerfolkFalconer.class));
|
||||
cards.add(new SetCardInfo("Merfolk Windrobber", 70, Rarity.UNCOMMON, mage.cards.m.MerfolkWindrobber.class));
|
||||
cards.add(new SetCardInfo("Mesa Lynx", 28, Rarity.COMMON, mage.cards.m.MesaLynx.class));
|
||||
|
@ -327,66 +179,41 @@ public final class ZendikarRising extends ExpansionSet {
|
|||
cards.add(new SetCardInfo("Mind Carver", 113, Rarity.UNCOMMON, mage.cards.m.MindCarver.class));
|
||||
cards.add(new SetCardInfo("Mind Drain", 114, Rarity.COMMON, mage.cards.m.MindDrain.class));
|
||||
cards.add(new SetCardInfo("Molten Blast", 149, Rarity.COMMON, mage.cards.m.MoltenBlast.class));
|
||||
cards.add(new SetCardInfo("Moraug, Fury of Akoum", 150, Rarity.MYTHIC, mage.cards.m.MoraugFuryOfAkoum.class, NON_FULL_USE_VARIOUS));
|
||||
cards.add(new SetCardInfo("Moraug, Fury of Akoum", 300, Rarity.MYTHIC, mage.cards.m.MoraugFuryOfAkoum.class, NON_FULL_USE_VARIOUS));
|
||||
cards.add(new SetCardInfo("Moraug, Fury of Akoum", 150, Rarity.MYTHIC, mage.cards.m.MoraugFuryOfAkoum.class));
|
||||
cards.add(new SetCardInfo("Moss-Pit Skeleton", 228, Rarity.UNCOMMON, mage.cards.m.MossPitSkeleton.class));
|
||||
cards.add(new SetCardInfo("Mountain", 275, Rarity.LAND, mage.cards.basiclands.Mountain.class, FULL_ART_BFZ_VARIOUS));
|
||||
cards.add(new SetCardInfo("Mountain", 276, Rarity.LAND, mage.cards.basiclands.Mountain.class, FULL_ART_BFZ_VARIOUS));
|
||||
cards.add(new SetCardInfo("Mountain", 277, Rarity.LAND, mage.cards.basiclands.Mountain.class, FULL_ART_BFZ_VARIOUS));
|
||||
cards.add(new SetCardInfo("Mountain", 383, Rarity.LAND, mage.cards.basiclands.Mountain.class, FULL_ART_BFZ_VARIOUS));
|
||||
cards.add(new SetCardInfo("Murasa Brute", 195, Rarity.COMMON, mage.cards.m.MurasaBrute.class));
|
||||
cards.add(new SetCardInfo("Murasa Rootgrazer", 229, Rarity.UNCOMMON, mage.cards.m.MurasaRootgrazer.class));
|
||||
cards.add(new SetCardInfo("Murasa Sproutling", 196, Rarity.UNCOMMON, mage.cards.m.MurasaSproutling.class));
|
||||
cards.add(new SetCardInfo("Murkwater Pathway", 260, Rarity.RARE, mage.cards.m.MurkwaterPathway.class));
|
||||
cards.add(new SetCardInfo("Murkwater Pathway", 286, Rarity.RARE, mage.cards.m.MurkwaterPathway.class));
|
||||
cards.add(new SetCardInfo("Myriad Construct", 246, Rarity.RARE, mage.cards.m.MyriadConstruct.class, NON_FULL_USE_VARIOUS));
|
||||
cards.add(new SetCardInfo("Myriad Construct", 376, Rarity.RARE, mage.cards.m.MyriadConstruct.class, NON_FULL_USE_VARIOUS));
|
||||
cards.add(new SetCardInfo("Myriad Construct", 246, Rarity.RARE, mage.cards.m.MyriadConstruct.class));
|
||||
cards.add(new SetCardInfo("Nahiri's Binding", 29, Rarity.COMMON, mage.cards.n.NahirisBinding.class));
|
||||
cards.add(new SetCardInfo("Nahiri's Lithoforming", 151, Rarity.RARE, mage.cards.n.NahirisLithoforming.class, NON_FULL_USE_VARIOUS));
|
||||
cards.add(new SetCardInfo("Nahiri's Lithoforming", 350, Rarity.RARE, mage.cards.n.NahirisLithoforming.class, NON_FULL_USE_VARIOUS));
|
||||
cards.add(new SetCardInfo("Nahiri, Heir of the Ancients", 230, Rarity.MYTHIC, mage.cards.n.NahiriHeirOfTheAncients.class, NON_FULL_USE_VARIOUS));
|
||||
cards.add(new SetCardInfo("Nahiri, Heir of the Ancients", 282, Rarity.MYTHIC, mage.cards.n.NahiriHeirOfTheAncients.class, NON_FULL_USE_VARIOUS));
|
||||
cards.add(new SetCardInfo("Nahiri's Lithoforming", 151, Rarity.RARE, mage.cards.n.NahirisLithoforming.class));
|
||||
cards.add(new SetCardInfo("Nahiri, Heir of the Ancients", 230, Rarity.MYTHIC, mage.cards.n.NahiriHeirOfTheAncients.class));
|
||||
cards.add(new SetCardInfo("Needleverge Pathway", 263, Rarity.RARE, mage.cards.n.NeedlevergePathway.class));
|
||||
cards.add(new SetCardInfo("Needleverge Pathway", 288, Rarity.RARE, mage.cards.n.NeedlevergePathway.class));
|
||||
cards.add(new SetCardInfo("Negate", 71, Rarity.COMMON, mage.cards.n.Negate.class));
|
||||
cards.add(new SetCardInfo("Nighthawk Scavenger", 115, Rarity.RARE, mage.cards.n.NighthawkScavenger.class, NON_FULL_USE_VARIOUS));
|
||||
cards.add(new SetCardInfo("Nighthawk Scavenger", 341, Rarity.RARE, mage.cards.n.NighthawkScavenger.class, NON_FULL_USE_VARIOUS));
|
||||
cards.add(new SetCardInfo("Nighthawk Scavenger", 115, Rarity.RARE, mage.cards.n.NighthawkScavenger.class));
|
||||
cards.add(new SetCardInfo("Nimana Skitter-Sneak", 116, Rarity.COMMON, mage.cards.n.NimanaSkitterSneak.class));
|
||||
cards.add(new SetCardInfo("Nimana Skydancer", 117, Rarity.COMMON, mage.cards.n.NimanaSkydancer.class));
|
||||
cards.add(new SetCardInfo("Nimble Trapfinder", 332, Rarity.RARE, mage.cards.n.NimbleTrapfinder.class, NON_FULL_USE_VARIOUS));
|
||||
cards.add(new SetCardInfo("Nimble Trapfinder", 72, Rarity.RARE, mage.cards.n.NimbleTrapfinder.class, NON_FULL_USE_VARIOUS));
|
||||
cards.add(new SetCardInfo("Nissa of Shadowed Boughs", 231, Rarity.MYTHIC, mage.cards.n.NissaOfShadowedBoughs.class, NON_FULL_USE_VARIOUS));
|
||||
cards.add(new SetCardInfo("Nissa of Shadowed Boughs", 283, Rarity.MYTHIC, mage.cards.n.NissaOfShadowedBoughs.class, NON_FULL_USE_VARIOUS));
|
||||
cards.add(new SetCardInfo("Nimble Trapfinder", 72, Rarity.RARE, mage.cards.n.NimbleTrapfinder.class));
|
||||
cards.add(new SetCardInfo("Nissa of Shadowed Boughs", 231, Rarity.MYTHIC, mage.cards.n.NissaOfShadowedBoughs.class));
|
||||
cards.add(new SetCardInfo("Nissa's Zendikon", 197, Rarity.COMMON, mage.cards.n.NissasZendikon.class));
|
||||
cards.add(new SetCardInfo("Nullpriest of Oblivion", 118, Rarity.RARE, mage.cards.n.NullpriestOfOblivion.class, NON_FULL_USE_VARIOUS));
|
||||
cards.add(new SetCardInfo("Nullpriest of Oblivion", 342, Rarity.RARE, mage.cards.n.NullpriestOfOblivion.class, NON_FULL_USE_VARIOUS));
|
||||
cards.add(new SetCardInfo("Nullpriest of Oblivion", 118, Rarity.RARE, mage.cards.n.NullpriestOfOblivion.class));
|
||||
cards.add(new SetCardInfo("Oblivion's Hunger", 119, Rarity.COMMON, mage.cards.o.OblivionsHunger.class));
|
||||
cards.add(new SetCardInfo("Omnath, Locus of Creation", 232, Rarity.MYTHIC, mage.cards.o.OmnathLocusOfCreation.class, NON_FULL_USE_VARIOUS));
|
||||
cards.add(new SetCardInfo("Omnath, Locus of Creation", 312, Rarity.MYTHIC, mage.cards.o.OmnathLocusOfCreation.class, NON_FULL_USE_VARIOUS));
|
||||
cards.add(new SetCardInfo("Omnath, Locus of Creation", 232, Rarity.MYTHIC, mage.cards.o.OmnathLocusOfCreation.class));
|
||||
cards.add(new SetCardInfo("Ondu Inversion", 30, Rarity.RARE, mage.cards.o.OnduInversion.class));
|
||||
cards.add(new SetCardInfo("Ondu Inversion", 321, Rarity.RARE, mage.cards.o.OnduInversion.class));
|
||||
cards.add(new SetCardInfo("Ondu Skyruins", 30, Rarity.RARE, mage.cards.o.OnduSkyruins.class));
|
||||
cards.add(new SetCardInfo("Ondu Skyruins", 321, Rarity.RARE, mage.cards.o.OnduSkyruins.class));
|
||||
cards.add(new SetCardInfo("Orah, Skyclave Hierophant", 233, Rarity.RARE, mage.cards.o.OrahSkyclaveHierophant.class, NON_FULL_USE_VARIOUS));
|
||||
cards.add(new SetCardInfo("Orah, Skyclave Hierophant", 369, Rarity.RARE, mage.cards.o.OrahSkyclaveHierophant.class, NON_FULL_USE_VARIOUS));
|
||||
cards.add(new SetCardInfo("Orah, Skyclave Hierophant", 385, Rarity.RARE, mage.cards.o.OrahSkyclaveHierophant.class, NON_FULL_USE_VARIOUS));
|
||||
cards.add(new SetCardInfo("Oran-Rief Ooze", 198, Rarity.RARE, mage.cards.o.OranRiefOoze.class, NON_FULL_USE_VARIOUS));
|
||||
cards.add(new SetCardInfo("Oran-Rief Ooze", 361, Rarity.RARE, mage.cards.o.OranRiefOoze.class, NON_FULL_USE_VARIOUS));
|
||||
cards.add(new SetCardInfo("Orah, Skyclave Hierophant", 233, Rarity.RARE, mage.cards.o.OrahSkyclaveHierophant.class));
|
||||
cards.add(new SetCardInfo("Oran-Rief Ooze", 198, Rarity.RARE, mage.cards.o.OranRiefOoze.class));
|
||||
cards.add(new SetCardInfo("Paired Tactician", 31, Rarity.UNCOMMON, mage.cards.p.PairedTactician.class));
|
||||
cards.add(new SetCardInfo("Pelakka Caverns", 120, Rarity.UNCOMMON, mage.cards.p.PelakkaCaverns.class));
|
||||
cards.add(new SetCardInfo("Pelakka Predation", 120, Rarity.UNCOMMON, mage.cards.p.PelakkaPredation.class));
|
||||
cards.add(new SetCardInfo("Phylath, World Sculptor", 234, Rarity.RARE, mage.cards.p.PhylathWorldSculptor.class, NON_FULL_USE_VARIOUS));
|
||||
cards.add(new SetCardInfo("Phylath, World Sculptor", 313, Rarity.RARE, mage.cards.p.PhylathWorldSculptor.class, NON_FULL_USE_VARIOUS));
|
||||
cards.add(new SetCardInfo("Phylath, World Sculptor", 234, Rarity.RARE, mage.cards.p.PhylathWorldSculptor.class));
|
||||
cards.add(new SetCardInfo("Pillarverge Pathway", 263, Rarity.RARE, mage.cards.p.PillarvergePathway.class));
|
||||
cards.add(new SetCardInfo("Pillarverge Pathway", 288, Rarity.RARE, mage.cards.p.PillarvergePathway.class));
|
||||
cards.add(new SetCardInfo("Plains", 266, Rarity.LAND, mage.cards.basiclands.Plains.class, FULL_ART_BFZ_VARIOUS));
|
||||
cards.add(new SetCardInfo("Plains", 267, Rarity.LAND, mage.cards.basiclands.Plains.class, FULL_ART_BFZ_VARIOUS));
|
||||
cards.add(new SetCardInfo("Plains", 268, Rarity.LAND, mage.cards.basiclands.Plains.class, FULL_ART_BFZ_VARIOUS));
|
||||
cards.add(new SetCardInfo("Plains", 380, Rarity.LAND, mage.cards.basiclands.Plains.class, FULL_ART_BFZ_VARIOUS));
|
||||
cards.add(new SetCardInfo("Practiced Tactics", 32, Rarity.COMMON, mage.cards.p.PracticedTactics.class));
|
||||
cards.add(new SetCardInfo("Pressure Point", 33, Rarity.COMMON, mage.cards.p.PressurePoint.class));
|
||||
cards.add(new SetCardInfo("Prowling Felidar", 294, Rarity.COMMON, mage.cards.p.ProwlingFelidar.class, NON_FULL_USE_VARIOUS));
|
||||
cards.add(new SetCardInfo("Prowling Felidar", 34, Rarity.COMMON, mage.cards.p.ProwlingFelidar.class, NON_FULL_USE_VARIOUS));
|
||||
cards.add(new SetCardInfo("Prowling Felidar", 34, Rarity.COMMON, mage.cards.p.ProwlingFelidar.class));
|
||||
cards.add(new SetCardInfo("Pyroclastic Hellion", 152, Rarity.COMMON, mage.cards.p.PyroclasticHellion.class));
|
||||
cards.add(new SetCardInfo("Rabid Bite", 199, Rarity.COMMON, mage.cards.r.RabidBite.class));
|
||||
cards.add(new SetCardInfo("Ravager's Mace", 235, Rarity.UNCOMMON, mage.cards.r.RavagersMace.class));
|
||||
|
@ -394,173 +221,116 @@ public final class ZendikarRising extends ExpansionSet {
|
|||
cards.add(new SetCardInfo("Relic Amulet", 247, Rarity.UNCOMMON, mage.cards.r.RelicAmulet.class));
|
||||
cards.add(new SetCardInfo("Relic Axe", 248, Rarity.UNCOMMON, mage.cards.r.RelicAxe.class));
|
||||
cards.add(new SetCardInfo("Relic Golem", 249, Rarity.UNCOMMON, mage.cards.r.RelicGolem.class));
|
||||
cards.add(new SetCardInfo("Relic Robber", 153, Rarity.RARE, mage.cards.r.RelicRobber.class, NON_FULL_USE_VARIOUS));
|
||||
cards.add(new SetCardInfo("Relic Robber", 351, Rarity.RARE, mage.cards.r.RelicRobber.class, NON_FULL_USE_VARIOUS));
|
||||
cards.add(new SetCardInfo("Relic Robber", 153, Rarity.RARE, mage.cards.r.RelicRobber.class));
|
||||
cards.add(new SetCardInfo("Relic Vial", 250, Rarity.UNCOMMON, mage.cards.r.RelicVial.class));
|
||||
cards.add(new SetCardInfo("Resolute Strike", 35, Rarity.COMMON, mage.cards.r.ResoluteStrike.class));
|
||||
cards.add(new SetCardInfo("Risen Riptide", 73, Rarity.COMMON, mage.cards.r.RisenRiptide.class));
|
||||
cards.add(new SetCardInfo("Riverglide Pathway", 264, Rarity.RARE, mage.cards.r.RiverglidePathway.class));
|
||||
cards.add(new SetCardInfo("Riverglide Pathway", 289, Rarity.RARE, mage.cards.r.RiverglidePathway.class));
|
||||
cards.add(new SetCardInfo("Rockslide Sorcerer", 154, Rarity.UNCOMMON, mage.cards.r.RockslideSorcerer.class));
|
||||
cards.add(new SetCardInfo("Roil Eruption", 155, Rarity.COMMON, mage.cards.r.RoilEruption.class, NON_FULL_USE_VARIOUS));
|
||||
cards.add(new SetCardInfo("Roil Eruption", 389, Rarity.COMMON, mage.cards.r.RoilEruption.class, NON_FULL_USE_VARIOUS));
|
||||
cards.add(new SetCardInfo("Roiling Regrowth", 201, Rarity.UNCOMMON, mage.cards.r.RoilingRegrowth.class, NON_FULL_USE_VARIOUS));
|
||||
cards.add(new SetCardInfo("Roiling Regrowth", 390, Rarity.UNCOMMON, mage.cards.r.RoilingRegrowth.class, NON_FULL_USE_VARIOUS));
|
||||
cards.add(new SetCardInfo("Roiling Vortex", 156, Rarity.RARE, mage.cards.r.RoilingVortex.class, NON_FULL_USE_VARIOUS));
|
||||
cards.add(new SetCardInfo("Roiling Vortex", 352, Rarity.RARE, mage.cards.r.RoilingVortex.class, NON_FULL_USE_VARIOUS));
|
||||
cards.add(new SetCardInfo("Roil Eruption", 155, Rarity.COMMON, mage.cards.r.RoilEruption.class));
|
||||
cards.add(new SetCardInfo("Roiling Regrowth", 201, Rarity.UNCOMMON, mage.cards.r.RoilingRegrowth.class));
|
||||
cards.add(new SetCardInfo("Roiling Vortex", 156, Rarity.RARE, mage.cards.r.RoilingVortex.class));
|
||||
cards.add(new SetCardInfo("Roost of Drakes", 74, Rarity.UNCOMMON, mage.cards.r.RoostOfDrakes.class));
|
||||
cards.add(new SetCardInfo("Ruin Crab", 295, Rarity.UNCOMMON, mage.cards.r.RuinCrab.class, NON_FULL_USE_VARIOUS));
|
||||
cards.add(new SetCardInfo("Ruin Crab", 75, Rarity.UNCOMMON, mage.cards.r.RuinCrab.class, NON_FULL_USE_VARIOUS));
|
||||
cards.add(new SetCardInfo("Ruin Crab", 75, Rarity.UNCOMMON, mage.cards.r.RuinCrab.class));
|
||||
cards.add(new SetCardInfo("Scale the Heights", 202, Rarity.COMMON, mage.cards.s.ScaleTheHeights.class));
|
||||
cards.add(new SetCardInfo("Scavenged Blade", 157, Rarity.COMMON, mage.cards.s.ScavengedBlade.class));
|
||||
cards.add(new SetCardInfo("Scion of the Swarm", 121, Rarity.UNCOMMON, mage.cards.s.ScionOfTheSwarm.class));
|
||||
cards.add(new SetCardInfo("Scorch Rider", 158, Rarity.COMMON, mage.cards.s.ScorchRider.class));
|
||||
cards.add(new SetCardInfo("Scourge of the Skyclaves", 122, Rarity.MYTHIC, mage.cards.s.ScourgeOfTheSkyclaves.class, NON_FULL_USE_VARIOUS));
|
||||
cards.add(new SetCardInfo("Scourge of the Skyclaves", 343, Rarity.MYTHIC, mage.cards.s.ScourgeOfTheSkyclaves.class, NON_FULL_USE_VARIOUS));
|
||||
cards.add(new SetCardInfo("Scute Swarm", 203, Rarity.RARE, mage.cards.s.ScuteSwarm.class, NON_FULL_USE_VARIOUS));
|
||||
cards.add(new SetCardInfo("Scute Swarm", 308, Rarity.RARE, mage.cards.s.ScuteSwarm.class, NON_FULL_USE_VARIOUS));
|
||||
cards.add(new SetCardInfo("Scourge of the Skyclaves", 122, Rarity.MYTHIC, mage.cards.s.ScourgeOfTheSkyclaves.class));
|
||||
cards.add(new SetCardInfo("Scute Swarm", 203, Rarity.RARE, mage.cards.s.ScuteSwarm.class));
|
||||
cards.add(new SetCardInfo("Sea Gate Banneret", 36, Rarity.COMMON, mage.cards.s.SeaGateBanneret.class));
|
||||
cards.add(new SetCardInfo("Sea Gate Colossus", 251, Rarity.COMMON, mage.cards.s.SeaGateColossus.class));
|
||||
cards.add(new SetCardInfo("Sea Gate Restoration", 333, Rarity.MYTHIC, mage.cards.s.SeaGateRestoration.class));
|
||||
cards.add(new SetCardInfo("Sea Gate Restoration", 76, Rarity.MYTHIC, mage.cards.s.SeaGateRestoration.class));
|
||||
cards.add(new SetCardInfo("Sea Gate Stormcaller", 334, Rarity.MYTHIC, mage.cards.s.SeaGateStormcaller.class, NON_FULL_USE_VARIOUS));
|
||||
cards.add(new SetCardInfo("Sea Gate Stormcaller", 77, Rarity.MYTHIC, mage.cards.s.SeaGateStormcaller.class, NON_FULL_USE_VARIOUS));
|
||||
cards.add(new SetCardInfo("Sea Gate, Reborn", 333, Rarity.MYTHIC, mage.cards.s.SeaGateReborn.class));
|
||||
cards.add(new SetCardInfo("Sea Gate Stormcaller", 77, Rarity.MYTHIC, mage.cards.s.SeaGateStormcaller.class));
|
||||
cards.add(new SetCardInfo("Sea Gate, Reborn", 76, Rarity.MYTHIC, mage.cards.s.SeaGateReborn.class));
|
||||
cards.add(new SetCardInfo("Seafloor Stalker", 78, Rarity.COMMON, mage.cards.s.SeafloorStalker.class));
|
||||
cards.add(new SetCardInfo("Sejiri Glacier", 37, Rarity.UNCOMMON, mage.cards.s.SejiriGlacier.class));
|
||||
cards.add(new SetCardInfo("Sejiri Shelter", 37, Rarity.UNCOMMON, mage.cards.s.SejiriShelter.class));
|
||||
cards.add(new SetCardInfo("Shadow Stinger", 123, Rarity.UNCOMMON, mage.cards.s.ShadowStinger.class));
|
||||
cards.add(new SetCardInfo("Shadows' Verdict", 124, Rarity.RARE, mage.cards.s.ShadowsVerdict.class, NON_FULL_USE_VARIOUS));
|
||||
cards.add(new SetCardInfo("Shadows' Verdict", 344, Rarity.RARE, mage.cards.s.ShadowsVerdict.class, NON_FULL_USE_VARIOUS));
|
||||
cards.add(new SetCardInfo("Shatterskull Charger", 159, Rarity.RARE, mage.cards.s.ShatterskullCharger.class, NON_FULL_USE_VARIOUS));
|
||||
cards.add(new SetCardInfo("Shatterskull Charger", 353, Rarity.RARE, mage.cards.s.ShatterskullCharger.class, NON_FULL_USE_VARIOUS));
|
||||
cards.add(new SetCardInfo("Shadows' Verdict", 124, Rarity.RARE, mage.cards.s.ShadowsVerdict.class));
|
||||
cards.add(new SetCardInfo("Shatterskull Charger", 159, Rarity.RARE, mage.cards.s.ShatterskullCharger.class));
|
||||
cards.add(new SetCardInfo("Shatterskull Minotaur", 160, Rarity.UNCOMMON, mage.cards.s.ShatterskullMinotaur.class));
|
||||
cards.add(new SetCardInfo("Shatterskull Smashing", 161, Rarity.MYTHIC, mage.cards.s.ShatterskullSmashing.class));
|
||||
cards.add(new SetCardInfo("Shatterskull Smashing", 354, Rarity.MYTHIC, mage.cards.s.ShatterskullSmashing.class));
|
||||
cards.add(new SetCardInfo("Shatterskull, the Hammer Pass", 161, Rarity.MYTHIC, mage.cards.s.ShatterskullTheHammerPass.class));
|
||||
cards.add(new SetCardInfo("Shatterskull, the Hammer Pass", 354, Rarity.MYTHIC, mage.cards.s.ShatterskullTheHammerPass.class));
|
||||
cards.add(new SetCardInfo("Shell Shield", 79, Rarity.COMMON, mage.cards.s.ShellShield.class));
|
||||
cards.add(new SetCardInfo("Shepherd of Heroes", 38, Rarity.COMMON, mage.cards.s.ShepherdOfHeroes.class));
|
||||
cards.add(new SetCardInfo("Silundi Isle", 80, Rarity.UNCOMMON, mage.cards.s.SilundiIsle.class));
|
||||
cards.add(new SetCardInfo("Silundi Vision", 80, Rarity.UNCOMMON, mage.cards.s.SilundiVision.class));
|
||||
cards.add(new SetCardInfo("Sizzling Barrage", 162, Rarity.COMMON, mage.cards.s.SizzlingBarrage.class));
|
||||
cards.add(new SetCardInfo("Skyclave Apparition", 322, Rarity.RARE, mage.cards.s.SkyclaveApparition.class, NON_FULL_USE_VARIOUS));
|
||||
cards.add(new SetCardInfo("Skyclave Apparition", 39, Rarity.RARE, mage.cards.s.SkyclaveApparition.class, NON_FULL_USE_VARIOUS));
|
||||
cards.add(new SetCardInfo("Skyclave Apparition", 39, Rarity.RARE, mage.cards.s.SkyclaveApparition.class));
|
||||
cards.add(new SetCardInfo("Skyclave Basilica", 40, Rarity.UNCOMMON, mage.cards.s.SkyclaveBasilica.class));
|
||||
cards.add(new SetCardInfo("Skyclave Cleric", 40, Rarity.UNCOMMON, mage.cards.s.SkyclaveCleric.class));
|
||||
cards.add(new SetCardInfo("Skyclave Geopede", 163, Rarity.UNCOMMON, mage.cards.s.SkyclaveGeopede.class, NON_FULL_USE_VARIOUS));
|
||||
cards.add(new SetCardInfo("Skyclave Geopede", 301, Rarity.UNCOMMON, mage.cards.s.SkyclaveGeopede.class, NON_FULL_USE_VARIOUS));
|
||||
cards.add(new SetCardInfo("Skyclave Pick-Axe", 204, Rarity.UNCOMMON, mage.cards.s.SkyclavePickAxe.class, NON_FULL_USE_VARIOUS));
|
||||
cards.add(new SetCardInfo("Skyclave Pick-Axe", 309, Rarity.UNCOMMON, mage.cards.s.SkyclavePickAxe.class, NON_FULL_USE_VARIOUS));
|
||||
cards.add(new SetCardInfo("Skyclave Geopede", 163, Rarity.UNCOMMON, mage.cards.s.SkyclaveGeopede.class));
|
||||
cards.add(new SetCardInfo("Skyclave Pick-Axe", 204, Rarity.UNCOMMON, mage.cards.s.SkyclavePickAxe.class));
|
||||
cards.add(new SetCardInfo("Skyclave Plunder", 81, Rarity.UNCOMMON, mage.cards.s.SkyclavePlunder.class));
|
||||
cards.add(new SetCardInfo("Skyclave Relic", 252, Rarity.RARE, mage.cards.s.SkyclaveRelic.class, NON_FULL_USE_VARIOUS));
|
||||
cards.add(new SetCardInfo("Skyclave Relic", 377, Rarity.RARE, mage.cards.s.SkyclaveRelic.class, NON_FULL_USE_VARIOUS));
|
||||
cards.add(new SetCardInfo("Skyclave Relic", 252, Rarity.RARE, mage.cards.s.SkyclaveRelic.class));
|
||||
cards.add(new SetCardInfo("Skyclave Sentinel", 253, Rarity.COMMON, mage.cards.s.SkyclaveSentinel.class));
|
||||
cards.add(new SetCardInfo("Skyclave Shade", 125, Rarity.RARE, mage.cards.s.SkyclaveShade.class, NON_FULL_USE_VARIOUS));
|
||||
cards.add(new SetCardInfo("Skyclave Shade", 298, Rarity.RARE, mage.cards.s.SkyclaveShade.class, NON_FULL_USE_VARIOUS));
|
||||
cards.add(new SetCardInfo("Skyclave Shade", 125, Rarity.RARE, mage.cards.s.SkyclaveShade.class));
|
||||
cards.add(new SetCardInfo("Skyclave Shadowcat", 126, Rarity.UNCOMMON, mage.cards.s.SkyclaveShadowcat.class));
|
||||
cards.add(new SetCardInfo("Skyclave Squid", 296, Rarity.COMMON, mage.cards.s.SkyclaveSquid.class, NON_FULL_USE_VARIOUS));
|
||||
cards.add(new SetCardInfo("Skyclave Squid", 82, Rarity.COMMON, mage.cards.s.SkyclaveSquid.class, NON_FULL_USE_VARIOUS));
|
||||
cards.add(new SetCardInfo("Skyclave Squid", 82, Rarity.COMMON, mage.cards.s.SkyclaveSquid.class));
|
||||
cards.add(new SetCardInfo("Smite the Monstrous", 42, Rarity.COMMON, mage.cards.s.SmiteTheMonstrous.class));
|
||||
cards.add(new SetCardInfo("Sneaking Guide", 164, Rarity.COMMON, mage.cards.s.SneakingGuide.class));
|
||||
cards.add(new SetCardInfo("Soaring Thought-Thief", 236, Rarity.UNCOMMON, mage.cards.s.SoaringThoughtThief.class));
|
||||
cards.add(new SetCardInfo("Song-Mad Ruins", 165, Rarity.UNCOMMON, mage.cards.s.SongMadRuins.class));
|
||||
cards.add(new SetCardInfo("Song-Mad Treachery", 165, Rarity.UNCOMMON, mage.cards.s.SongMadTreachery.class));
|
||||
cards.add(new SetCardInfo("Soul Shatter", 127, Rarity.RARE, mage.cards.s.SoulShatter.class, NON_FULL_USE_VARIOUS));
|
||||
cards.add(new SetCardInfo("Soul Shatter", 345, Rarity.RARE, mage.cards.s.SoulShatter.class, NON_FULL_USE_VARIOUS));
|
||||
cards.add(new SetCardInfo("Soul Shatter", 127, Rarity.RARE, mage.cards.s.SoulShatter.class));
|
||||
cards.add(new SetCardInfo("Spare Supplies", 254, Rarity.COMMON, mage.cards.s.SpareSupplies.class));
|
||||
cards.add(new SetCardInfo("Spikefield Cave", 166, Rarity.UNCOMMON, mage.cards.s.SpikefieldCave.class));
|
||||
cards.add(new SetCardInfo("Spikefield Hazard", 166, Rarity.UNCOMMON, mage.cards.s.SpikefieldHazard.class));
|
||||
cards.add(new SetCardInfo("Spitfire Lagac", 167, Rarity.COMMON, mage.cards.s.SpitfireLagac.class, NON_FULL_USE_VARIOUS));
|
||||
cards.add(new SetCardInfo("Spitfire Lagac", 302, Rarity.COMMON, mage.cards.s.SpitfireLagac.class, NON_FULL_USE_VARIOUS));
|
||||
cards.add(new SetCardInfo("Spitfire Lagac", 167, Rarity.COMMON, mage.cards.s.SpitfireLagac.class));
|
||||
cards.add(new SetCardInfo("Spoils of Adventure", 237, Rarity.UNCOMMON, mage.cards.s.SpoilsOfAdventure.class));
|
||||
cards.add(new SetCardInfo("Springmantle Cleric", 205, Rarity.UNCOMMON, mage.cards.s.SpringmantleCleric.class));
|
||||
cards.add(new SetCardInfo("Squad Commander", 323, Rarity.RARE, mage.cards.s.SquadCommander.class, NON_FULL_USE_VARIOUS));
|
||||
cards.add(new SetCardInfo("Squad Commander", 41, Rarity.RARE, mage.cards.s.SquadCommander.class, NON_FULL_USE_VARIOUS));
|
||||
cards.add(new SetCardInfo("Squad Commander", 41, Rarity.RARE, mage.cards.s.SquadCommander.class));
|
||||
cards.add(new SetCardInfo("Stonework Packbeast", 255, Rarity.COMMON, mage.cards.s.StoneworkPackbeast.class));
|
||||
cards.add(new SetCardInfo("Strength of Solidarity", 206, Rarity.COMMON, mage.cards.s.StrengthOfSolidarity.class));
|
||||
cards.add(new SetCardInfo("Subtle Strike", 128, Rarity.COMMON, mage.cards.s.SubtleStrike.class));
|
||||
cards.add(new SetCardInfo("Sure-Footed Infiltrator", 83, Rarity.UNCOMMON, mage.cards.s.SureFootedInfiltrator.class));
|
||||
cards.add(new SetCardInfo("Swamp", 272, Rarity.LAND, mage.cards.basiclands.Swamp.class, FULL_ART_BFZ_VARIOUS));
|
||||
cards.add(new SetCardInfo("Swamp", 273, Rarity.LAND, mage.cards.basiclands.Swamp.class, FULL_ART_BFZ_VARIOUS));
|
||||
cards.add(new SetCardInfo("Swamp", 274, Rarity.LAND, mage.cards.basiclands.Swamp.class, FULL_ART_BFZ_VARIOUS));
|
||||
cards.add(new SetCardInfo("Swamp", 382, Rarity.LAND, mage.cards.basiclands.Swamp.class, FULL_ART_BFZ_VARIOUS));
|
||||
cards.add(new SetCardInfo("Swarm Shambler", 207, Rarity.RARE, mage.cards.s.SwarmShambler.class, NON_FULL_USE_VARIOUS));
|
||||
cards.add(new SetCardInfo("Swarm Shambler", 362, Rarity.RARE, mage.cards.s.SwarmShambler.class, NON_FULL_USE_VARIOUS));
|
||||
cards.add(new SetCardInfo("Swarm Shambler", 207, Rarity.RARE, mage.cards.s.SwarmShambler.class));
|
||||
cards.add(new SetCardInfo("Synchronized Spellcraft", 168, Rarity.COMMON, mage.cards.s.SynchronizedSpellcraft.class));
|
||||
cards.add(new SetCardInfo("Taborax, Hope's Demise", 129, Rarity.RARE, mage.cards.t.TaboraxHopesDemise.class, NON_FULL_USE_VARIOUS));
|
||||
cards.add(new SetCardInfo("Taborax, Hope's Demise", 346, Rarity.RARE, mage.cards.t.TaboraxHopesDemise.class, NON_FULL_USE_VARIOUS));
|
||||
cards.add(new SetCardInfo("Taborax, Hope's Demise", 129, Rarity.RARE, mage.cards.t.TaboraxHopesDemise.class));
|
||||
cards.add(new SetCardInfo("Tajuru Blightblade", 208, Rarity.COMMON, mage.cards.t.TajuruBlightblade.class));
|
||||
cards.add(new SetCardInfo("Tajuru Paragon", 209, Rarity.RARE, mage.cards.t.TajuruParagon.class, NON_FULL_USE_VARIOUS));
|
||||
cards.add(new SetCardInfo("Tajuru Paragon", 363, Rarity.RARE, mage.cards.t.TajuruParagon.class, NON_FULL_USE_VARIOUS));
|
||||
cards.add(new SetCardInfo("Tajuru Paragon", 209, Rarity.RARE, mage.cards.t.TajuruParagon.class));
|
||||
cards.add(new SetCardInfo("Tajuru Snarecaster", 210, Rarity.COMMON, mage.cards.t.TajuruSnarecaster.class));
|
||||
cards.add(new SetCardInfo("Tangled Florahedron", 211, Rarity.UNCOMMON, mage.cards.t.TangledFlorahedron.class));
|
||||
cards.add(new SetCardInfo("Tangled Vale", 211, Rarity.UNCOMMON, mage.cards.t.TangledVale.class));
|
||||
cards.add(new SetCardInfo("Taunting Arbormage", 212, Rarity.UNCOMMON, mage.cards.t.TauntingArbormage.class));
|
||||
cards.add(new SetCardInfo("Tazeem Raptor", 43, Rarity.COMMON, mage.cards.t.TazeemRaptor.class));
|
||||
cards.add(new SetCardInfo("Tazeem Roilmage", 84, Rarity.COMMON, mage.cards.t.TazeemRoilmage.class));
|
||||
cards.add(new SetCardInfo("Tazri, Beacon of Unity", 324, Rarity.MYTHIC, mage.cards.t.TazriBeaconOfUnity.class, NON_FULL_USE_VARIOUS));
|
||||
cards.add(new SetCardInfo("Tazri, Beacon of Unity", 44, Rarity.MYTHIC, mage.cards.t.TazriBeaconOfUnity.class, NON_FULL_USE_VARIOUS));
|
||||
cards.add(new SetCardInfo("Tazri, Beacon of Unity", 44, Rarity.MYTHIC, mage.cards.t.TazriBeaconOfUnity.class));
|
||||
cards.add(new SetCardInfo("Teeterpeak Ambusher", 169, Rarity.COMMON, mage.cards.t.TeeterpeakAmbusher.class));
|
||||
cards.add(new SetCardInfo("Territorial Scythecat", 213, Rarity.COMMON, mage.cards.t.TerritorialScythecat.class, NON_FULL_USE_VARIOUS));
|
||||
cards.add(new SetCardInfo("Territorial Scythecat", 310, Rarity.COMMON, mage.cards.t.TerritorialScythecat.class, NON_FULL_USE_VARIOUS));
|
||||
cards.add(new SetCardInfo("Thieving Skydiver", 335, Rarity.RARE, mage.cards.t.ThievingSkydiver.class, NON_FULL_USE_VARIOUS));
|
||||
cards.add(new SetCardInfo("Thieving Skydiver", 85, Rarity.RARE, mage.cards.t.ThievingSkydiver.class, NON_FULL_USE_VARIOUS));
|
||||
cards.add(new SetCardInfo("Throne of Makindi", 265, Rarity.RARE, mage.cards.t.ThroneOfMakindi.class, NON_FULL_USE_VARIOUS));
|
||||
cards.add(new SetCardInfo("Throne of Makindi", 379, Rarity.RARE, mage.cards.t.ThroneOfMakindi.class, NON_FULL_USE_VARIOUS));
|
||||
cards.add(new SetCardInfo("Territorial Scythecat", 213, Rarity.COMMON, mage.cards.t.TerritorialScythecat.class));
|
||||
cards.add(new SetCardInfo("Thieving Skydiver", 85, Rarity.RARE, mage.cards.t.ThievingSkydiver.class));
|
||||
cards.add(new SetCardInfo("Throne of Makindi", 265, Rarity.RARE, mage.cards.t.ThroneOfMakindi.class));
|
||||
cards.add(new SetCardInfo("Thundering Rebuke", 170, Rarity.UNCOMMON, mage.cards.t.ThunderingRebuke.class));
|
||||
cards.add(new SetCardInfo("Thundering Sparkmage", 171, Rarity.UNCOMMON, mage.cards.t.ThunderingSparkmage.class));
|
||||
cards.add(new SetCardInfo("Thwart the Grave", 130, Rarity.UNCOMMON, mage.cards.t.ThwartTheGrave.class));
|
||||
cards.add(new SetCardInfo("Timbercrown Pathway", 261, Rarity.RARE, mage.cards.t.TimbercrownPathway.class));
|
||||
cards.add(new SetCardInfo("Timbercrown Pathway", 287, Rarity.RARE, mage.cards.t.TimbercrownPathway.class));
|
||||
cards.add(new SetCardInfo("Tormenting Voice", 172, Rarity.COMMON, mage.cards.t.TormentingVoice.class));
|
||||
cards.add(new SetCardInfo("Tuktuk Rubblefort", 173, Rarity.COMMON, mage.cards.t.TuktukRubblefort.class));
|
||||
cards.add(new SetCardInfo("Turntimber Ascetic", 214, Rarity.COMMON, mage.cards.t.TurntimberAscetic.class));
|
||||
cards.add(new SetCardInfo("Turntimber Symbiosis", 215, Rarity.MYTHIC, mage.cards.t.TurntimberSymbiosis.class));
|
||||
cards.add(new SetCardInfo("Turntimber Symbiosis", 364, Rarity.MYTHIC, mage.cards.t.TurntimberSymbiosis.class));
|
||||
cards.add(new SetCardInfo("Turntimber, Serpentine Wood", 215, Rarity.MYTHIC, mage.cards.t.TurntimberSerpentineWood.class));
|
||||
cards.add(new SetCardInfo("Turntimber, Serpentine Wood", 364, Rarity.MYTHIC, mage.cards.t.TurntimberSerpentineWood.class));
|
||||
cards.add(new SetCardInfo("Umara Mystic", 238, Rarity.UNCOMMON, mage.cards.u.UmaraMystic.class));
|
||||
cards.add(new SetCardInfo("Umara Skyfalls", 86, Rarity.UNCOMMON, mage.cards.u.UmaraSkyfalls.class));
|
||||
cards.add(new SetCardInfo("Umara Wizard", 86, Rarity.UNCOMMON, mage.cards.u.UmaraWizard.class));
|
||||
cards.add(new SetCardInfo("Utility Knife", 256, Rarity.COMMON, mage.cards.u.UtilityKnife.class));
|
||||
cards.add(new SetCardInfo("Valakut Awakening", 174, Rarity.RARE, mage.cards.v.ValakutAwakening.class));
|
||||
cards.add(new SetCardInfo("Valakut Awakening", 355, Rarity.RARE, mage.cards.v.ValakutAwakening.class));
|
||||
cards.add(new SetCardInfo("Valakut Exploration", 175, Rarity.RARE, mage.cards.v.ValakutExploration.class, NON_FULL_USE_VARIOUS));
|
||||
cards.add(new SetCardInfo("Valakut Exploration", 303, Rarity.RARE, mage.cards.v.ValakutExploration.class, NON_FULL_USE_VARIOUS));
|
||||
cards.add(new SetCardInfo("Valakut Exploration", 175, Rarity.RARE, mage.cards.v.ValakutExploration.class));
|
||||
cards.add(new SetCardInfo("Valakut Stoneforge", 174, Rarity.RARE, mage.cards.v.ValakutStoneforge.class));
|
||||
cards.add(new SetCardInfo("Valakut Stoneforge", 355, Rarity.RARE, mage.cards.v.ValakutStoneforge.class));
|
||||
cards.add(new SetCardInfo("Vanquish the Weak", 131, Rarity.COMMON, mage.cards.v.VanquishTheWeak.class));
|
||||
cards.add(new SetCardInfo("Vastwood Fortification", 216, Rarity.UNCOMMON, mage.cards.v.VastwoodFortification.class));
|
||||
cards.add(new SetCardInfo("Vastwood Surge", 217, Rarity.UNCOMMON, mage.cards.v.VastwoodSurge.class));
|
||||
cards.add(new SetCardInfo("Vastwood Thicket", 216, Rarity.UNCOMMON, mage.cards.v.VastwoodThicket.class));
|
||||
cards.add(new SetCardInfo("Verazol, the Split Current", 239, Rarity.RARE, mage.cards.v.VerazolTheSplitCurrent.class, NON_FULL_USE_VARIOUS));
|
||||
cards.add(new SetCardInfo("Verazol, the Split Current", 370, Rarity.RARE, mage.cards.v.VerazolTheSplitCurrent.class, NON_FULL_USE_VARIOUS));
|
||||
cards.add(new SetCardInfo("Veteran Adventurer", 218, Rarity.UNCOMMON, mage.cards.v.VeteranAdventurer.class));
|
||||
cards.add(new SetCardInfo("Vine Gecko", 219, Rarity.UNCOMMON, mage.cards.v.VineGecko.class));
|
||||
cards.add(new SetCardInfo("Wayward Guide-Beast", 176, Rarity.RARE, mage.cards.w.WaywardGuideBeast.class, NON_FULL_USE_VARIOUS));
|
||||
cards.add(new SetCardInfo("Wayward Guide-Beast", 356, Rarity.RARE, mage.cards.w.WaywardGuideBeast.class, NON_FULL_USE_VARIOUS));
|
||||
cards.add(new SetCardInfo("Wayward Guide-Beast", 176, Rarity.RARE, mage.cards.w.WaywardGuideBeast.class));
|
||||
cards.add(new SetCardInfo("Windrider Wizard", 87, Rarity.UNCOMMON, mage.cards.w.WindriderWizard.class));
|
||||
cards.add(new SetCardInfo("Yasharn, Implacable Earth", 240, Rarity.RARE, mage.cards.y.YasharnImplacableEarth.class, NON_FULL_USE_VARIOUS));
|
||||
cards.add(new SetCardInfo("Yasharn, Implacable Earth", 371, Rarity.RARE, mage.cards.y.YasharnImplacableEarth.class, NON_FULL_USE_VARIOUS));
|
||||
cards.add(new SetCardInfo("Zagras, Thief of Heartbeats", 241, Rarity.RARE, mage.cards.z.ZagrasThiefOfHeartbeats.class, NON_FULL_USE_VARIOUS));
|
||||
cards.add(new SetCardInfo("Zagras, Thief of Heartbeats", 372, Rarity.RARE, mage.cards.z.ZagrasThiefOfHeartbeats.class, NON_FULL_USE_VARIOUS));
|
||||
cards.add(new SetCardInfo("Zareth San, the Trickster", 242, Rarity.RARE, mage.cards.z.ZarethSanTheTrickster.class, NON_FULL_USE_VARIOUS));
|
||||
cards.add(new SetCardInfo("Zareth San, the Trickster", 373, Rarity.RARE, mage.cards.z.ZarethSanTheTrickster.class, NON_FULL_USE_VARIOUS));
|
||||
cards.add(new SetCardInfo("Yasharn, Implacable Earth", 240, Rarity.RARE, mage.cards.y.YasharnImplacableEarth.class));
|
||||
cards.add(new SetCardInfo("Zagras, Thief of Heartbeats", 241, Rarity.RARE, mage.cards.z.ZagrasThiefOfHeartbeats.class));
|
||||
cards.add(new SetCardInfo("Zareth San, the Trickster", 242, Rarity.RARE, mage.cards.z.ZarethSanTheTrickster.class));
|
||||
cards.add(new SetCardInfo("Zof Bloodbog", 132, Rarity.UNCOMMON, mage.cards.z.ZofBloodbog.class));
|
||||
cards.add(new SetCardInfo("Zof Consumption", 132, Rarity.UNCOMMON, mage.cards.z.ZofConsumption.class));
|
||||
cards.add(new SetCardInfo("Zulaport Duelist", 88, Rarity.COMMON, mage.cards.z.ZulaportDuelist.class));
|
||||
|
||||
cards.removeIf(setCardInfo -> checkName(setCardInfo.getName())); // remove when mechanics are fully implemented
|
||||
}
|
||||
|
||||
private static boolean checkName(String name) {
|
||||
boolean keepNonland = false;
|
||||
keepNonland = true; // comment out this line to test front faces of MDFCs
|
||||
if (keepNonland && unfinishedNonland.contains(name)) {
|
||||
return true;
|
||||
}
|
||||
return unfinishedLand.contains(name);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,162 @@
|
|||
package org.mage.test.cards.cost.modaldoublefaces;
|
||||
|
||||
import mage.constants.PhaseStep;
|
||||
import mage.constants.Zone;
|
||||
import org.junit.Test;
|
||||
import org.mage.test.serverside.base.CardTestPlayerBase;
|
||||
|
||||
/**
|
||||
* @author JayDi85
|
||||
*/
|
||||
public class ModalDoubleFacesCardsTest extends CardTestPlayerBase {
|
||||
|
||||
@Test
|
||||
public void test_Playable_AsCreature() {
|
||||
removeAllCardsFromHand(playerA);
|
||||
|
||||
// Akoum Warrior {5}{R} - creature
|
||||
// Akoum Teeth - land
|
||||
addCard(Zone.HAND, playerA, "Akoum Warrior");
|
||||
addCard(Zone.BATTLEFIELD, playerA, "Mountain", 6 - 1);
|
||||
addCard(Zone.HAND, playerA, "Mountain", 1);
|
||||
|
||||
// can't cast without mana, but can play land
|
||||
checkPlayableAbility("before land left", 1, PhaseStep.PRECOMBAT_MAIN, playerA, "Cast Akoum Warrior", false);
|
||||
checkPlayableAbility("before land right", 1, PhaseStep.PRECOMBAT_MAIN, playerA, "Play Akoum Teeth", true);
|
||||
checkPlayableAbility("before land both", 1, PhaseStep.PRECOMBAT_MAIN, playerA, "Cast Akoum Warrior // Akoum Teeth", false);
|
||||
|
||||
// play land
|
||||
playLand(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Mountain");
|
||||
// can cast creature, but can't play land
|
||||
checkPlayableAbility("after land left", 1, PhaseStep.PRECOMBAT_MAIN, playerA, "Cast Akoum Warrior", true);
|
||||
checkPlayableAbility("after land right", 1, PhaseStep.PRECOMBAT_MAIN, playerA, "Play Akoum Teeth", false);
|
||||
checkPlayableAbility("after land both", 1, PhaseStep.PRECOMBAT_MAIN, playerA, "Cast Akoum Warrior // Akoum Teeth", false);
|
||||
|
||||
// cast creature
|
||||
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Akoum Warrior");
|
||||
waitStackResolved(1, PhaseStep.PRECOMBAT_MAIN);
|
||||
checkHandCount("hand after", 1, PhaseStep.PRECOMBAT_MAIN, playerA, 0);
|
||||
checkPermanentCount("after cast", 1, PhaseStep.PRECOMBAT_MAIN, playerA, "Akoum Warrior", 1);
|
||||
checkPermanentCount("after cast", 1, PhaseStep.PRECOMBAT_MAIN, playerA, "Akoum Teeth", 0);
|
||||
|
||||
setStrictChooseMode(true);
|
||||
setStopAt(1, PhaseStep.END_TURN);
|
||||
execute();
|
||||
assertAllCommandsUsed();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void test_Playable_AsLand() {
|
||||
removeAllCardsFromHand(playerA);
|
||||
|
||||
// Akoum Warrior {5}{R} - creature
|
||||
// Akoum Teeth - land
|
||||
addCard(Zone.HAND, playerA, "Akoum Warrior");
|
||||
addCard(Zone.HAND, playerA, "Mountain", 1);
|
||||
|
||||
// cast and play restrictions tested in prev test, so use here simple land play
|
||||
|
||||
checkPlayableAbility("before play", 1, PhaseStep.PRECOMBAT_MAIN, playerA, "{T}: Add {R}", false);
|
||||
checkPlayableAbility("before play", 1, PhaseStep.PRECOMBAT_MAIN, playerA, "Play Mountain", true);
|
||||
checkHandCount("before play", 1, PhaseStep.PRECOMBAT_MAIN, playerA, 2);
|
||||
|
||||
// play as land
|
||||
playLand(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Akoum Teeth");
|
||||
checkHandCount("hand after", 1, PhaseStep.PRECOMBAT_MAIN, playerA, 2 - 1);
|
||||
checkPermanentCount("after play", 1, PhaseStep.PRECOMBAT_MAIN, playerA, "Akoum Warrior", 0);
|
||||
checkPermanentCount("after play", 1, PhaseStep.PRECOMBAT_MAIN, playerA, "Akoum Teeth", 1);
|
||||
checkPlayableAbility("after play", 1, PhaseStep.PRECOMBAT_MAIN, playerA, "{T}: Add {R}", false);
|
||||
checkPlayableAbility("can't play second land", 1, PhaseStep.PRECOMBAT_MAIN, playerA, "Play Mountain", false);
|
||||
|
||||
setStrictChooseMode(true);
|
||||
setStopAt(1, PhaseStep.END_TURN);
|
||||
execute();
|
||||
assertAllCommandsUsed();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void test_CostModification() {
|
||||
removeAllCardsFromHand(playerA);
|
||||
|
||||
// Akoum Warrior {5}{R} - creature
|
||||
// Akoum Teeth - land
|
||||
addCard(Zone.HAND, playerA, "Akoum Warrior");
|
||||
addCard(Zone.BATTLEFIELD, playerA, "Mountain", 6 - 3);
|
||||
|
||||
addCustomEffect_SpellCostModification(playerA, -3);
|
||||
|
||||
// cast creature
|
||||
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Akoum Warrior");
|
||||
waitStackResolved(1, PhaseStep.PRECOMBAT_MAIN);
|
||||
checkHandCount("hand after", 1, PhaseStep.PRECOMBAT_MAIN, playerA, 0);
|
||||
checkPermanentCount("after cast", 1, PhaseStep.PRECOMBAT_MAIN, playerA, "Akoum Warrior", 1);
|
||||
checkPermanentCount("after cast", 1, PhaseStep.PRECOMBAT_MAIN, playerA, "Akoum Teeth", 0);
|
||||
|
||||
setStrictChooseMode(true);
|
||||
setStopAt(1, PhaseStep.END_TURN);
|
||||
execute();
|
||||
assertAllCommandsUsed();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void test_PlayFromNonHand_LibraryByBolassCitadel() {
|
||||
removeAllCardsFromHand(playerA);
|
||||
removeAllCardsFromLibrary(playerA);
|
||||
|
||||
// Akoum Warrior {5}{R} - creature
|
||||
// Akoum Teeth - land
|
||||
addCard(Zone.LIBRARY, playerA, "Akoum Warrior");
|
||||
//
|
||||
// You may play the top card of your library. If you cast a spell this way, pay life equal
|
||||
// to its converted mana cost rather than pay its mana cost.
|
||||
addCard(Zone.BATTLEFIELD, playerA, "Bolas's Citadel");
|
||||
|
||||
checkLibraryCount("library before", 1, PhaseStep.PRECOMBAT_MAIN, playerA, "Akoum Warrior", 1);
|
||||
checkPlayableAbility("can play as land", 1, PhaseStep.PRECOMBAT_MAIN, playerA, "Cast Akoum Warrior", true);
|
||||
checkPlayableAbility("can play as creature", 1, PhaseStep.PRECOMBAT_MAIN, playerA, "Play Akoum Teeth", true);
|
||||
|
||||
// play as creature
|
||||
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Akoum Warrior");
|
||||
waitStackResolved(1, PhaseStep.PRECOMBAT_MAIN);
|
||||
checkLibraryCount("library after", 1, PhaseStep.PRECOMBAT_MAIN, playerA, "Akoum Warrior", 0);
|
||||
checkPermanentCount("after cast", 1, PhaseStep.PRECOMBAT_MAIN, playerA, "Akoum Warrior", 1);
|
||||
checkPermanentCount("after cast", 1, PhaseStep.PRECOMBAT_MAIN, playerA, "Akoum Teeth", 0);
|
||||
|
||||
setStrictChooseMode(true);
|
||||
setStopAt(1, PhaseStep.END_TURN);
|
||||
execute();
|
||||
assertAllCommandsUsed();
|
||||
|
||||
assertLife(playerA, 20 - 6); // creature life pay instead mana
|
||||
}
|
||||
|
||||
@Test
|
||||
public void test_PlayFromNonHand_GraveyardByYawgmothsAgenda() {
|
||||
removeAllCardsFromHand(playerA);
|
||||
removeAllCardsFromLibrary(playerA);
|
||||
|
||||
// Akoum Warrior {5}{R} - creature
|
||||
// Akoum Teeth - land
|
||||
addCard(Zone.GRAVEYARD, playerA, "Akoum Warrior");
|
||||
addCard(Zone.BATTLEFIELD, playerA, "Mountain", 6);
|
||||
//
|
||||
// You may play cards from your graveyard.
|
||||
addCard(Zone.BATTLEFIELD, playerA, "Yawgmoth's Agenda");
|
||||
|
||||
checkGraveyardCount("grave before", 1, PhaseStep.PRECOMBAT_MAIN, playerA, "Akoum Warrior", 1);
|
||||
checkPlayableAbility("can play as land", 1, PhaseStep.PRECOMBAT_MAIN, playerA, "Cast Akoum Warrior", true);
|
||||
checkPlayableAbility("can play as creature", 1, PhaseStep.PRECOMBAT_MAIN, playerA, "Play Akoum Teeth", true);
|
||||
|
||||
// play as creature
|
||||
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Akoum Warrior");
|
||||
waitStackResolved(1, PhaseStep.PRECOMBAT_MAIN);
|
||||
checkGraveyardCount("grave after", 1, PhaseStep.PRECOMBAT_MAIN, playerA, "Akoum Warrior", 0);
|
||||
checkPermanentCount("after cast", 1, PhaseStep.PRECOMBAT_MAIN, playerA, "Akoum Warrior", 1);
|
||||
checkPermanentCount("after cast", 1, PhaseStep.PRECOMBAT_MAIN, playerA, "Akoum Teeth", 0);
|
||||
|
||||
setStrictChooseMode(true);
|
||||
setStopAt(1, PhaseStep.END_TURN);
|
||||
execute();
|
||||
assertAllCommandsUsed();
|
||||
}
|
||||
}
|
|
@ -257,9 +257,12 @@ public class VerifyCardDataTest {
|
|||
int cardIndex = 0;
|
||||
for (Card card : CardScanner.getAllCards()) {
|
||||
cardIndex++;
|
||||
if (card.isSplitCard()) {
|
||||
if (card instanceof SplitCard) {
|
||||
check(((SplitCard) card).getLeftHalfCard(), cardIndex);
|
||||
check(((SplitCard) card).getRightHalfCard(), cardIndex);
|
||||
} else if (card instanceof ModalDoubleFacesCard) {
|
||||
check(((ModalDoubleFacesCard) card).getLeftHalfCard(), cardIndex);
|
||||
check(((ModalDoubleFacesCard) card).getRightHalfCard(), cardIndex);
|
||||
} else {
|
||||
check(card, cardIndex);
|
||||
}
|
||||
|
@ -1351,7 +1354,7 @@ public class VerifyCardDataTest {
|
|||
Card card = CardImpl.createCard(cardInfo.getClassName(), testSet);
|
||||
System.out.println();
|
||||
System.out.println(card.getName() + " " + card.getManaCost().getText());
|
||||
if (card instanceof SplitCard) {
|
||||
if (card instanceof SplitCard || card instanceof ModalDoubleFacesCard) {
|
||||
card.getAbilities().getRules(card.getName()).forEach(this::printAbilityText);
|
||||
} else {
|
||||
card.getRules().forEach(this::printAbilityText);
|
||||
|
|
|
@ -3,13 +3,13 @@ package mage.abilities.effects;
|
|||
import mage.abilities.Ability;
|
||||
import mage.abilities.ActivatedAbility;
|
||||
import mage.cards.Card;
|
||||
import mage.cards.ModalDoubleFacesCard;
|
||||
import mage.cards.SplitCard;
|
||||
import mage.constants.*;
|
||||
import mage.game.Game;
|
||||
import mage.players.Player;
|
||||
|
||||
import java.util.UUID;
|
||||
import mage.cards.SplitCard;
|
||||
import mage.cards.SplitCardHalf;
|
||||
import mage.players.Player;
|
||||
|
||||
/**
|
||||
* @author BetaSteward_at_googlemail.com
|
||||
|
@ -22,7 +22,7 @@ public abstract class AsThoughEffectImpl extends ContinuousEffectImpl implements
|
|||
public AsThoughEffectImpl(AsThoughEffectType type, Duration duration, Outcome outcome) {
|
||||
this(type, duration, outcome, false);
|
||||
}
|
||||
|
||||
|
||||
public AsThoughEffectImpl(AsThoughEffectType type, Duration duration, Outcome outcome, boolean consumable) {
|
||||
super(duration, outcome);
|
||||
this.type = type;
|
||||
|
@ -74,12 +74,12 @@ public abstract class AsThoughEffectImpl extends ContinuousEffectImpl implements
|
|||
* Internal method to do the neccessary to allow the card from objectId to be cast or played (if it's a land) without paying any mana.
|
||||
* Additional costs (like sacrificing or discarding) have still to be payed.
|
||||
* Checks if the card is of the correct type or in the correct zone have to be done before.
|
||||
*
|
||||
* @param objectId sourceId of the card to play
|
||||
* @param source source ability that allows this effect
|
||||
*
|
||||
* @param objectId sourceId of the card to play
|
||||
* @param source source ability that allows this effect
|
||||
* @param affectedControllerId player allowed to play the card
|
||||
* @param game
|
||||
* @return
|
||||
* @return
|
||||
*/
|
||||
protected boolean allowCardToPlayWithoutMana(UUID objectId, Ability source, UUID affectedControllerId, Game game) {
|
||||
Player player = game.getPlayer(affectedControllerId);
|
||||
|
@ -89,9 +89,14 @@ public abstract class AsThoughEffectImpl extends ContinuousEffectImpl implements
|
|||
}
|
||||
if (!card.isLand()) {
|
||||
if (card instanceof SplitCard) {
|
||||
SplitCardHalf leftCard = ((SplitCard) card).getLeftHalfCard();
|
||||
Card leftCard = ((SplitCard) card).getLeftHalfCard();
|
||||
player.setCastSourceIdWithAlternateMana(leftCard.getId(), null, leftCard.getSpellAbility().getCosts());
|
||||
SplitCardHalf rightCard = ((SplitCard) card).getRightHalfCard();
|
||||
Card rightCard = ((SplitCard) card).getRightHalfCard();
|
||||
player.setCastSourceIdWithAlternateMana(rightCard.getId(), null, rightCard.getSpellAbility().getCosts());
|
||||
} else if (card instanceof ModalDoubleFacesCard) {
|
||||
Card leftCard = ((ModalDoubleFacesCard) card).getLeftHalfCard();
|
||||
player.setCastSourceIdWithAlternateMana(leftCard.getId(), null, leftCard.getSpellAbility().getCosts());
|
||||
Card rightCard = ((ModalDoubleFacesCard) card).getRightHalfCard();
|
||||
player.setCastSourceIdWithAlternateMana(rightCard.getId(), null, rightCard.getSpellAbility().getCosts());
|
||||
} else {
|
||||
player.setCastSourceIdWithAlternateMana(objectId, null, card.getSpellAbility().getCosts());
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
package mage.abilities.effects;
|
||||
|
||||
import mage.ApprovingObject;
|
||||
import mage.MageObject;
|
||||
import mage.abilities.Ability;
|
||||
import mage.abilities.MageSingleton;
|
||||
|
@ -7,6 +8,8 @@ import mage.abilities.StaticAbility;
|
|||
import mage.abilities.effects.common.continuous.BecomesFaceDownCreatureEffect;
|
||||
import mage.abilities.effects.common.continuous.CommanderReplacementEffect;
|
||||
import mage.cards.*;
|
||||
import mage.choices.Choice;
|
||||
import mage.choices.ChoiceImpl;
|
||||
import mage.constants.*;
|
||||
import mage.filter.FilterCard;
|
||||
import mage.filter.predicate.Predicate;
|
||||
|
@ -29,9 +32,6 @@ import java.io.Serializable;
|
|||
import java.util.*;
|
||||
import java.util.Map.Entry;
|
||||
import java.util.stream.Collectors;
|
||||
import mage.ApprovingObject;
|
||||
import mage.choices.Choice;
|
||||
import mage.choices.ChoiceImpl;
|
||||
|
||||
/**
|
||||
* @author BetaSteward_at_googlemail.com
|
||||
|
@ -334,7 +334,7 @@ public class ContinuousEffects implements Serializable {
|
|||
* @param event
|
||||
* @param game
|
||||
* @return a list of all {@link ReplacementEffect} that apply to the current
|
||||
* event
|
||||
* event
|
||||
*/
|
||||
private Map<ReplacementEffect, Set<Ability>> getApplicableReplacementEffects(GameEvent event, Game game) {
|
||||
Map<ReplacementEffect, Set<Ability>> replaceEffects = new HashMap<>();
|
||||
|
@ -343,7 +343,7 @@ public class ContinuousEffects implements Serializable {
|
|||
}
|
||||
// boolean checkLKI = event.getType().equals(EventType.ZONE_CHANGE) || event.getType().equals(EventType.DESTROYED_PERMANENT);
|
||||
//get all applicable transient Replacement effects
|
||||
for (Iterator<ReplacementEffect> iterator = replacementEffects.iterator(); iterator.hasNext();) {
|
||||
for (Iterator<ReplacementEffect> iterator = replacementEffects.iterator(); iterator.hasNext(); ) {
|
||||
ReplacementEffect effect = iterator.next();
|
||||
if (!effect.checksEventType(event, game)) {
|
||||
continue;
|
||||
|
@ -376,7 +376,7 @@ public class ContinuousEffects implements Serializable {
|
|||
}
|
||||
}
|
||||
|
||||
for (Iterator<PreventionEffect> iterator = preventionEffects.iterator(); iterator.hasNext();) {
|
||||
for (Iterator<PreventionEffect> iterator = preventionEffects.iterator(); iterator.hasNext(); ) {
|
||||
PreventionEffect effect = iterator.next();
|
||||
if (!effect.checksEventType(event, game)) {
|
||||
continue;
|
||||
|
@ -507,7 +507,7 @@ public class ContinuousEffects implements Serializable {
|
|||
* @param controllerId
|
||||
* @param game
|
||||
* @return sourceId of the permitting effect if any exists otherwise returns
|
||||
* null
|
||||
* null
|
||||
*/
|
||||
public ApprovingObject asThough(UUID objectId, AsThoughEffectType type, Ability affectedAbility, UUID controllerId, Game game) {
|
||||
List<AsThoughEffect> asThoughEffectsList = getApplicableAsThoughEffects(type, game);
|
||||
|
@ -515,6 +515,8 @@ public class ContinuousEffects implements Serializable {
|
|||
UUID idToCheck;
|
||||
if (affectedAbility != null && affectedAbility.getSourceObject(game) instanceof SplitCardHalf) {
|
||||
idToCheck = ((SplitCardHalf) affectedAbility.getSourceObject(game)).getParentCard().getId();
|
||||
} else if (affectedAbility != null && affectedAbility.getSourceObject(game) instanceof ModalDoubleFacesCardHalf) {
|
||||
idToCheck = ((ModalDoubleFacesCardHalf) affectedAbility.getSourceObject(game)).getParentCard().getId();
|
||||
} else if (affectedAbility != null && affectedAbility.getSourceObject(game) instanceof AdventureCardSpell
|
||||
&& !type.needPlayCardAbility()) {
|
||||
// adventure spell uses alternative characteristics for spell/stack
|
||||
|
@ -523,6 +525,8 @@ public class ContinuousEffects implements Serializable {
|
|||
Card card = game.getCard(objectId);
|
||||
if (card instanceof SplitCardHalf) {
|
||||
idToCheck = ((SplitCardHalf) card).getParentCard().getId();
|
||||
} else if (card instanceof ModalDoubleFacesCardHalf) {
|
||||
idToCheck = ((ModalDoubleFacesCardHalf) card).getParentCard().getId();
|
||||
} else if (card instanceof AdventureCardSpell
|
||||
&& !type.needPlayCardAbility()) {
|
||||
// adventure spell uses alternative characteristics for spell/stack
|
||||
|
@ -568,24 +572,24 @@ public class ContinuousEffects implements Serializable {
|
|||
} else if (possibleApprovingObjects.size() > 1) {
|
||||
// Select the ability that you use to permit the action
|
||||
Map<String, String> keyChoices = new HashMap<>();
|
||||
for(ApprovingObject approvingObject :possibleApprovingObjects) {
|
||||
MageObject mageObject = game.getObject(approvingObject.getApprovingAbility().getSourceId());
|
||||
keyChoices.put(approvingObject.getApprovingAbility().getId().toString(),
|
||||
for (ApprovingObject approvingObject : possibleApprovingObjects) {
|
||||
MageObject mageObject = game.getObject(approvingObject.getApprovingAbility().getSourceId());
|
||||
keyChoices.put(approvingObject.getApprovingAbility().getId().toString(),
|
||||
(approvingObject.getApprovingAbility().getRule(mageObject == null ? "" : mageObject.getName()))
|
||||
+ (mageObject == null ? "" : " (" + mageObject.getIdName() + ")"));
|
||||
+ (mageObject == null ? "" : " (" + mageObject.getIdName() + ")"));
|
||||
}
|
||||
Choice choicePermitting = new ChoiceImpl(true);
|
||||
choicePermitting.setMessage("Choose the permitting object");
|
||||
choicePermitting.setKeyChoices(keyChoices);
|
||||
Player player = game.getPlayer(controllerId);
|
||||
player.choose(Outcome.Detriment, choicePermitting, game);
|
||||
for(ApprovingObject approvingObject: possibleApprovingObjects) {
|
||||
for (ApprovingObject approvingObject : possibleApprovingObjects) {
|
||||
if (approvingObject.getApprovingAbility().getId().toString().equals(choicePermitting.getChoiceKey())) {
|
||||
return approvingObject;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
return null;
|
||||
|
||||
|
@ -833,7 +837,7 @@ public class ContinuousEffects implements Serializable {
|
|||
do {
|
||||
Map<ReplacementEffect, Set<Ability>> rEffects = getApplicableReplacementEffects(event, game);
|
||||
// Remove all consumed effects (ability dependant)
|
||||
for (Iterator<ReplacementEffect> it1 = rEffects.keySet().iterator(); it1.hasNext();) {
|
||||
for (Iterator<ReplacementEffect> it1 = rEffects.keySet().iterator(); it1.hasNext(); ) {
|
||||
ReplacementEffect entry = it1.next();
|
||||
if (consumed.containsKey(entry.getId()) /*&& !(entry instanceof CommanderReplacementEffect) */) { // 903.9.
|
||||
Set<UUID> consumedAbilitiesIds = consumed.get(entry.getId());
|
||||
|
@ -1018,7 +1022,7 @@ public class ContinuousEffects implements Serializable {
|
|||
.entrySet()
|
||||
.stream()
|
||||
.filter(entry -> dependentTo.contains(entry.getKey().getId())
|
||||
&& entry.getValue().contains(effect.getId()))
|
||||
&& entry.getValue().contains(effect.getId()))
|
||||
.forEach(entry -> {
|
||||
entry.getValue().remove(effect.getId());
|
||||
dependentTo.remove(entry.getKey().getId());
|
||||
|
@ -1052,7 +1056,7 @@ public class ContinuousEffects implements Serializable {
|
|||
continue;
|
||||
}
|
||||
// check if waiting effects can be applied now
|
||||
for (Iterator<Map.Entry<ContinuousEffect, Set<UUID>>> iterator = waitingEffects.entrySet().iterator(); iterator.hasNext();) {
|
||||
for (Iterator<Map.Entry<ContinuousEffect, Set<UUID>>> iterator = waitingEffects.entrySet().iterator(); iterator.hasNext(); ) {
|
||||
Map.Entry<ContinuousEffect, Set<UUID>> entry = iterator.next();
|
||||
if (!appliedEffects.containsAll(entry.getValue())) { // all dependent to effects are applied now so apply the effect itself
|
||||
continue;
|
||||
|
|
|
@ -8,6 +8,7 @@ import mage.abilities.condition.common.SourceIsSpellCondition;
|
|||
import mage.abilities.costs.AlternativeCostSourceAbility;
|
||||
import mage.abilities.effects.ContinuousEffectImpl;
|
||||
import mage.cards.Card;
|
||||
import mage.cards.ModalDoubleFacesCardHalf;
|
||||
import mage.cards.SplitCardHalf;
|
||||
import mage.constants.*;
|
||||
import mage.filter.FilterCard;
|
||||
|
@ -21,7 +22,7 @@ import java.util.UUID;
|
|||
public class CastFromHandWithoutPayingManaCostEffect extends ContinuousEffectImpl {
|
||||
|
||||
private final AlternativeCostSourceAbility alternativeCastingCostAbility;
|
||||
|
||||
|
||||
public CastFromHandWithoutPayingManaCostEffect() {
|
||||
this(StaticFilters.FILTER_CARDS_NON_LAND, true);
|
||||
}
|
||||
|
@ -37,7 +38,7 @@ public class CastFromHandWithoutPayingManaCostEffect extends ContinuousEffectImp
|
|||
condition = new CompoundCondition(SourceIsSpellCondition.instance, IsBeingCastFromHandCondition.instance);
|
||||
} else {
|
||||
condition = SourceIsSpellCondition.instance;
|
||||
}
|
||||
}
|
||||
this.alternativeCastingCostAbility = new AlternativeCostSourceAbility(null, condition, null, filter, true);
|
||||
this.staticText = "You may cast " + filter.getMessage()
|
||||
+ (fromHand ? " from your hand" : "")
|
||||
|
@ -87,9 +88,9 @@ enum IsBeingCastFromHandCondition implements Condition {
|
|||
@Override
|
||||
public boolean apply(Game game, Ability source) {
|
||||
MageObject object = game.getObject(source.getSourceId());
|
||||
if (object instanceof SplitCardHalf) {
|
||||
UUID splitCardId = ((Card) object).getMainCard().getId();
|
||||
object = game.getObject(splitCardId);
|
||||
if (object instanceof SplitCardHalf || object instanceof ModalDoubleFacesCardHalf) {
|
||||
UUID mainCardId = ((Card) object).getMainCard().getId();
|
||||
object = game.getObject(mainCardId);
|
||||
}
|
||||
if (object instanceof Spell) { // needed to check if it can be cast by alternate cost
|
||||
Spell spell = (Spell) object;
|
||||
|
|
|
@ -1,24 +1,31 @@
|
|||
package mage.abilities.keyword;
|
||||
|
||||
import java.util.UUID;
|
||||
import mage.abilities.Ability;
|
||||
import mage.abilities.common.SimpleStaticAbility;
|
||||
import mage.abilities.effects.*;
|
||||
import mage.abilities.effects.AsThoughEffectImpl;
|
||||
import mage.abilities.effects.ContinuousRuleModifyingEffectImpl;
|
||||
import mage.abilities.effects.ReplacementEffectImpl;
|
||||
import mage.cards.Card;
|
||||
import mage.cards.ModalDoubleFacesCardHalf;
|
||||
import mage.cards.SplitCardHalf;
|
||||
import mage.constants.*;
|
||||
import mage.constants.AsThoughEffectType;
|
||||
import mage.constants.Duration;
|
||||
import mage.constants.Outcome;
|
||||
import mage.constants.Zone;
|
||||
import mage.game.Game;
|
||||
import mage.game.events.GameEvent;
|
||||
import mage.game.events.ZoneChangeEvent;
|
||||
import mage.game.stack.Spell;
|
||||
import mage.players.Player;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
/**
|
||||
* Aftermath
|
||||
*
|
||||
* <p>
|
||||
* TODO: Implement once we get details on the comprehensive rules meaning of the
|
||||
* ability
|
||||
*
|
||||
* <p>
|
||||
* Current text is a shell copied from Flashback
|
||||
*
|
||||
* @author stravant
|
||||
|
@ -113,9 +120,7 @@ class AftermathCantCastFromHand extends ContinuousRuleModifyingEffectImpl {
|
|||
Card card = game.getCard(event.getSourceId());
|
||||
if (card != null && card.getId().equals(source.getSourceId())) {
|
||||
Zone zone = game.getState().getZone(card.getId());
|
||||
if (zone != null && (zone != Zone.GRAVEYARD)) {
|
||||
return true;
|
||||
}
|
||||
return zone != null && (zone != Zone.GRAVEYARD);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
@ -155,14 +160,16 @@ class AftermathExileAsResolvesFromGraveyard extends ReplacementEffectImpl {
|
|||
sourceCard = ((SplitCardHalf) sourceCard).getParentCard();
|
||||
sourceId = sourceCard.getId();
|
||||
}
|
||||
if (sourceCard instanceof ModalDoubleFacesCardHalf) {
|
||||
sourceCard = ((ModalDoubleFacesCardHalf) sourceCard).getParentCard();
|
||||
sourceId = sourceCard.getId();
|
||||
}
|
||||
|
||||
if (event.getTargetId().equals(sourceId)) {
|
||||
// Moving this spell from stack to yard
|
||||
Spell spell = game.getStack().getSpell(source.getSourceId());
|
||||
if (spell != null && spell.getFromZone() == Zone.GRAVEYARD) {
|
||||
// And this spell was cast from the graveyard, so we need to exile it
|
||||
return true;
|
||||
}
|
||||
// And this spell was cast from the graveyard, so we need to exile it
|
||||
return spell != null && spell.getFromZone() == Zone.GRAVEYARD;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
|
@ -174,6 +181,9 @@ class AftermathExileAsResolvesFromGraveyard extends ReplacementEffectImpl {
|
|||
if (sourceCard instanceof SplitCardHalf) {
|
||||
sourceCard = ((SplitCardHalf) sourceCard).getParentCard();
|
||||
}
|
||||
if (sourceCard instanceof ModalDoubleFacesCardHalf) {
|
||||
sourceCard = ((ModalDoubleFacesCardHalf) sourceCard).getParentCard();
|
||||
}
|
||||
if (sourceCard != null) {
|
||||
Player player = game.getPlayer(sourceCard.getOwnerId());
|
||||
if (player != null) {
|
||||
|
|
|
@ -7,6 +7,7 @@ import mage.abilities.costs.Costs;
|
|||
import mage.abilities.effects.ContinuousEffect;
|
||||
import mage.abilities.effects.ReplacementEffectImpl;
|
||||
import mage.cards.Card;
|
||||
import mage.cards.ModalDoubleFacesCard;
|
||||
import mage.cards.SplitCard;
|
||||
import mage.constants.*;
|
||||
import mage.game.Game;
|
||||
|
@ -68,12 +69,18 @@ public class FlashbackAbility extends SpellAbility {
|
|||
}
|
||||
// Flashback can never cast a split card by Fuse, because Fuse only works from hand
|
||||
// https://tappedout.net/mtg-questions/snapcaster-mage-and-flashback-on-a-fuse-card-one-or-both-halves-legal-targets/
|
||||
if (card.isSplitCard()) {
|
||||
if (card instanceof SplitCard) {
|
||||
if (((SplitCard) card).getLeftHalfCard().getName().equals(abilityName)) {
|
||||
return ((SplitCard) card).getLeftHalfCard().getSpellAbility().canActivate(playerId, game);
|
||||
} else if (((SplitCard) card).getRightHalfCard().getName().equals(abilityName)) {
|
||||
return ((SplitCard) card).getRightHalfCard().getSpellAbility().canActivate(playerId, game);
|
||||
}
|
||||
} else if (card instanceof ModalDoubleFacesCard) {
|
||||
if (((ModalDoubleFacesCard) card).getLeftHalfCard().getName().equals(abilityName)) {
|
||||
return ((ModalDoubleFacesCard) card).getLeftHalfCard().getSpellAbility().canActivate(playerId, game);
|
||||
} else if (((ModalDoubleFacesCard) card).getRightHalfCard().getName().equals(abilityName)) {
|
||||
return ((ModalDoubleFacesCard) card).getRightHalfCard().getSpellAbility().canActivate(playerId, game);
|
||||
}
|
||||
}
|
||||
return card.getSpellAbility().canActivate(playerId, game);
|
||||
}
|
||||
|
@ -87,12 +94,18 @@ public class FlashbackAbility extends SpellAbility {
|
|||
if (card != null) {
|
||||
if (spellAbilityToResolve == null) {
|
||||
SpellAbility spellAbilityCopy = null;
|
||||
if (card.isSplitCard()) {
|
||||
if (card instanceof SplitCard) {
|
||||
if (((SplitCard) card).getLeftHalfCard().getName().equals(abilityName)) {
|
||||
spellAbilityCopy = ((SplitCard) card).getLeftHalfCard().getSpellAbility().copy();
|
||||
} else if (((SplitCard) card).getRightHalfCard().getName().equals(abilityName)) {
|
||||
spellAbilityCopy = ((SplitCard) card).getRightHalfCard().getSpellAbility().copy();
|
||||
}
|
||||
} else if (card instanceof ModalDoubleFacesCard) {
|
||||
if (((ModalDoubleFacesCard) card).getLeftHalfCard().getName().equals(abilityName)) {
|
||||
spellAbilityCopy = ((ModalDoubleFacesCard) card).getLeftHalfCard().getSpellAbility().copy();
|
||||
} else if (((ModalDoubleFacesCard) card).getRightHalfCard().getName().equals(abilityName)) {
|
||||
spellAbilityCopy = ((ModalDoubleFacesCard) card).getRightHalfCard().getSpellAbility().copy();
|
||||
}
|
||||
} else {
|
||||
spellAbilityCopy = card.getSpellAbility().copy();
|
||||
}
|
||||
|
|
|
@ -1,8 +1,3 @@
|
|||
/*
|
||||
* To change this license header, choose License Headers in Project Properties.
|
||||
* To change this template file, choose Tools | Templates
|
||||
* and open the template in the editor.
|
||||
*/
|
||||
package mage.cards;
|
||||
|
||||
import mage.abilities.Modes;
|
||||
|
|
|
@ -1,7 +1,5 @@
|
|||
package mage.cards;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.UUID;
|
||||
import mage.MageObject;
|
||||
import mage.Mana;
|
||||
import mage.abilities.Abilities;
|
||||
|
@ -16,6 +14,9 @@ import mage.game.Game;
|
|||
import mage.game.GameState;
|
||||
import mage.game.permanent.Permanent;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.UUID;
|
||||
|
||||
public interface Card extends MageObject {
|
||||
|
||||
UUID getOwnerId();
|
||||
|
@ -29,8 +30,9 @@ public interface Card extends MageObject {
|
|||
/**
|
||||
* For cards: return all basic and dynamic abilities
|
||||
* For permanents: return all basic and dynamic abilities
|
||||
*
|
||||
* @param game
|
||||
* @return
|
||||
* @return
|
||||
*/
|
||||
Abilities<Ability> getAbilities(Game game);
|
||||
|
||||
|
@ -62,8 +64,6 @@ public interface Card extends MageObject {
|
|||
|
||||
String getFlipCardName();
|
||||
|
||||
boolean isSplitCard();
|
||||
|
||||
boolean isTransformable();
|
||||
|
||||
void setTransformable(boolean transformable);
|
||||
|
@ -76,21 +76,23 @@ public interface Card extends MageObject {
|
|||
|
||||
void addInfo(String key, String value, Game game);
|
||||
|
||||
// WARNING, don't add new move/remove methods (if you add then you must override it in all multi-part cards like Split or MDF)
|
||||
|
||||
/**
|
||||
* Moves the card to the specified zone
|
||||
*
|
||||
* @param zone
|
||||
* @param sourceId
|
||||
* @param game
|
||||
* @param flag If zone
|
||||
* <ul>
|
||||
* <li>LIBRARY: <ul><li>true - put on top</li><li>false - put on
|
||||
* bottom</li></ul></li>
|
||||
* <li>BATTLEFIELD: <ul><li>true - tapped</li><li>false -
|
||||
* untapped</li></ul></li>
|
||||
* <li>GRAVEYARD: <ul><li>true - not from Battlefield</li><li>false - from
|
||||
* Battlefield</li></ul></li>
|
||||
* </ul>
|
||||
* @param flag If zone
|
||||
* <ul>
|
||||
* <li>LIBRARY: <ul><li>true - put on top</li><li>false - put on
|
||||
* bottom</li></ul></li>
|
||||
* <li>BATTLEFIELD: <ul><li>true - tapped</li><li>false -
|
||||
* untapped</li></ul></li>
|
||||
* <li>GRAVEYARD: <ul><li>true - not from Battlefield</li><li>false - from
|
||||
* Battlefield</li></ul></li>
|
||||
* </ul>
|
||||
* @return true if card was moved to zone
|
||||
*/
|
||||
boolean moveToZone(Zone zone, UUID sourceId, Game game, boolean flag);
|
||||
|
@ -100,8 +102,8 @@ public interface Card extends MageObject {
|
|||
/**
|
||||
* Moves the card to an exile zone
|
||||
*
|
||||
* @param exileId set to null for generic exile zone
|
||||
* @param name used for exile zone with the specified exileId
|
||||
* @param exileId set to null for generic exile zone
|
||||
* @param name used for exile zone with the specified exileId
|
||||
* @param sourceId
|
||||
* @param game
|
||||
* @return true if card was moved to zone
|
||||
|
@ -112,6 +114,7 @@ public interface Card extends MageObject {
|
|||
|
||||
boolean cast(Game game, Zone fromZone, SpellAbility ability, UUID controllerId);
|
||||
|
||||
// WARNING, don't add new move/remove methods (if you add then you must override it in all multi-parts card like Split Half or MDF Half)
|
||||
boolean removeFromZone(Game game, Zone fromZone, UUID sourceId);
|
||||
|
||||
boolean putOntoBattlefield(Game game, Zone fromZone, UUID sourceId, UUID controllerId);
|
||||
|
|
|
@ -57,7 +57,6 @@ public abstract class CardImpl extends MageObjectImpl implements Card {
|
|||
protected boolean flipCard;
|
||||
protected String flipCardName;
|
||||
protected boolean usesVariousArt = false;
|
||||
protected boolean splitCard;
|
||||
protected boolean morphCard;
|
||||
protected boolean modalDFC; // modal double faces card
|
||||
|
||||
|
@ -139,7 +138,6 @@ public abstract class CardImpl extends MageObjectImpl implements Card {
|
|||
flipCard = card.flipCard;
|
||||
flipCardName = card.flipCardName;
|
||||
usesVariousArt = card.usesVariousArt;
|
||||
splitCard = card.splitCard;
|
||||
morphCard = card.morphCard;
|
||||
modalDFC = card.modalDFC;
|
||||
|
||||
|
@ -563,13 +561,22 @@ public abstract class CardImpl extends MageObjectImpl implements Card {
|
|||
stackObject = game.getStack().getSpell(this.getId(), false);
|
||||
}
|
||||
|
||||
if (stackObject == null && (this instanceof SplitCard)) { // handle if half of Split cast is on the stack
|
||||
// handle half of Split Cards on stack
|
||||
if (stackObject == null && (this instanceof SplitCard)) {
|
||||
stackObject = game.getStack().getSpell(((SplitCard) this).getLeftHalfCard().getId(), false);
|
||||
if (stackObject == null) {
|
||||
stackObject = game.getStack().getSpell(((SplitCard) this).getRightHalfCard().getId(), false);
|
||||
}
|
||||
}
|
||||
|
||||
// handle half of Modal Double Faces Cards on stack
|
||||
if (stackObject == null && (this instanceof ModalDoubleFacesCard)) {
|
||||
stackObject = game.getStack().getSpell(((ModalDoubleFacesCard) this).getLeftHalfCard().getId(), false);
|
||||
if (stackObject == null) {
|
||||
stackObject = game.getStack().getSpell(((ModalDoubleFacesCard) this).getRightHalfCard().getId(), false);
|
||||
}
|
||||
}
|
||||
|
||||
if (stackObject == null && (this instanceof AdventureCard)) {
|
||||
stackObject = game.getStack().getSpell(((AdventureCard) this).getSpellCard().getId(), false);
|
||||
}
|
||||
|
@ -687,10 +694,6 @@ public abstract class CardImpl extends MageObjectImpl implements Card {
|
|||
|
||||
@Override
|
||||
public final Card getSecondCardFace() {
|
||||
// TODO: remove when MDFCs are implemented
|
||||
if (modalDFC) {
|
||||
return null;
|
||||
}
|
||||
// init second side card on first call
|
||||
if (secondSideCardClazz == null && secondSideCard == null) {
|
||||
return null;
|
||||
|
@ -726,11 +729,6 @@ public abstract class CardImpl extends MageObjectImpl implements Card {
|
|||
return flipCardName;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isSplitCard() {
|
||||
return splitCard;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean getUsesVariousArt() {
|
||||
return usesVariousArt;
|
||||
|
|
184
Mage/src/main/java/mage/cards/ModalDoubleFacesCard.java
Normal file
184
Mage/src/main/java/mage/cards/ModalDoubleFacesCard.java
Normal file
|
@ -0,0 +1,184 @@
|
|||
package mage.cards;
|
||||
|
||||
import mage.MageObject;
|
||||
import mage.abilities.Abilities;
|
||||
import mage.abilities.AbilitiesImpl;
|
||||
import mage.abilities.Ability;
|
||||
import mage.abilities.SpellAbility;
|
||||
import mage.constants.CardType;
|
||||
import mage.constants.SpellAbilityType;
|
||||
import mage.constants.SubType;
|
||||
import mage.constants.Zone;
|
||||
import mage.game.Game;
|
||||
import mage.game.events.ZoneChangeEvent;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.UUID;
|
||||
|
||||
/**
|
||||
* @author JayDi85
|
||||
*/
|
||||
public abstract class ModalDoubleFacesCard extends CardImpl {
|
||||
|
||||
protected Card leftHalfCard;
|
||||
protected Card rightHalfCard;
|
||||
|
||||
public ModalDoubleFacesCard(UUID ownerId, CardSetInfo setInfo,
|
||||
CardType[] typesLeft, SubType[] subTypesLeft, String costsLeft,
|
||||
String secondSideName, CardType[] typesRight, SubType[] subTypesRight, String costsRight) {
|
||||
super(ownerId, setInfo, typesLeft, costsLeft + costsRight, SpellAbilityType.MODAL);
|
||||
// main card name must be same as left side
|
||||
leftHalfCard = new ModalDoubleFacesCardHalfImpl(this.getOwnerId(), new CardSetInfo(setInfo.getName(), setInfo.getExpansionSetCode(), setInfo.getCardNumber(), setInfo.getRarity(), setInfo.getGraphicInfo()),
|
||||
typesLeft, subTypesLeft, costsLeft, this, SpellAbilityType.MODAL_LEFT);
|
||||
rightHalfCard = new ModalDoubleFacesCardHalfImpl(this.getOwnerId(), new CardSetInfo(secondSideName, setInfo.getExpansionSetCode(), setInfo.getCardNumber(), setInfo.getRarity(), setInfo.getGraphicInfo()),
|
||||
typesRight, subTypesRight, costsRight, this, SpellAbilityType.MODAL_RIGHT);
|
||||
this.modalDFC = true;
|
||||
}
|
||||
|
||||
public ModalDoubleFacesCard(ModalDoubleFacesCard card) {
|
||||
super(card);
|
||||
this.leftHalfCard = card.getLeftHalfCard().copy();
|
||||
((ModalDoubleFacesCardHalf) leftHalfCard).setParentCard(this);
|
||||
this.rightHalfCard = card.rightHalfCard.copy();
|
||||
((ModalDoubleFacesCardHalf) rightHalfCard).setParentCard(this);
|
||||
}
|
||||
|
||||
public ModalDoubleFacesCardHalf getLeftHalfCard() {
|
||||
return (ModalDoubleFacesCardHalf) leftHalfCard;
|
||||
}
|
||||
|
||||
public ModalDoubleFacesCardHalf getRightHalfCard() {
|
||||
return (ModalDoubleFacesCardHalf) rightHalfCard;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void assignNewId() {
|
||||
super.assignNewId();
|
||||
leftHalfCard.assignNewId();
|
||||
rightHalfCard.assignNewId();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setCopy(boolean isCopy, MageObject copiedFrom) {
|
||||
super.setCopy(isCopy, copiedFrom);
|
||||
leftHalfCard.setCopy(isCopy, copiedFrom);
|
||||
rightHalfCard.setCopy(isCopy, copiedFrom);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean moveToZone(Zone toZone, UUID sourceId, Game game, boolean flag, List<UUID> appliedEffects) {
|
||||
if (super.moveToZone(toZone, sourceId, game, flag, appliedEffects)) {
|
||||
game.getState().setZone(getLeftHalfCard().getId(), toZone);
|
||||
game.getState().setZone(getRightHalfCard().getId(), toZone);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setZone(Zone zone, Game game) {
|
||||
super.setZone(zone, game);
|
||||
game.setZone(getLeftHalfCard().getId(), zone);
|
||||
game.setZone(getRightHalfCard().getId(), zone);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean moveToExile(UUID exileId, String name, UUID sourceId, Game game, List<UUID> appliedEffects) {
|
||||
if (super.moveToExile(exileId, name, sourceId, game, appliedEffects)) {
|
||||
Zone currentZone = game.getState().getZone(getId());
|
||||
game.getState().setZone(getLeftHalfCard().getId(), currentZone);
|
||||
game.getState().setZone(getRightHalfCard().getId(), currentZone);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean removeFromZone(Game game, Zone fromZone, UUID sourceId) {
|
||||
// zone contains only one main card
|
||||
return super.removeFromZone(game, fromZone, sourceId);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateZoneChangeCounter(Game game, ZoneChangeEvent event) {
|
||||
if (isCopy()) { // same as meld cards
|
||||
super.updateZoneChangeCounter(game, event);
|
||||
return;
|
||||
}
|
||||
super.updateZoneChangeCounter(game, event);
|
||||
getLeftHalfCard().updateZoneChangeCounter(game, event);
|
||||
getRightHalfCard().updateZoneChangeCounter(game, event);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean cast(Game game, Zone fromZone, SpellAbility ability, UUID controllerId) {
|
||||
switch (ability.getSpellAbilityType()) {
|
||||
case MODAL_LEFT:
|
||||
return this.getLeftHalfCard().cast(game, fromZone, ability, controllerId);
|
||||
case MODAL_RIGHT:
|
||||
return this.getRightHalfCard().cast(game, fromZone, ability, controllerId);
|
||||
default:
|
||||
this.getLeftHalfCard().getSpellAbility().setControllerId(controllerId);
|
||||
this.getRightHalfCard().getSpellAbility().setControllerId(controllerId);
|
||||
return super.cast(game, fromZone, ability, controllerId);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Abilities<Ability> getAbilities() {
|
||||
Abilities<Ability> allAbilites = new AbilitiesImpl<>();
|
||||
allAbilites.addAll(super.getAbilities());
|
||||
allAbilites.addAll(leftHalfCard.getAbilities());
|
||||
allAbilites.addAll(rightHalfCard.getAbilities());
|
||||
return allAbilites;
|
||||
}
|
||||
|
||||
public Abilities<Ability> getSharedAbilities(Game game) {
|
||||
return super.getAbilities(game);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Abilities<Ability> getAbilities(Game game) {
|
||||
Abilities<Ability> allAbilites = new AbilitiesImpl<>();
|
||||
|
||||
// ignore default spell ability from main card (only halfes are actual)
|
||||
for (Ability ability : super.getAbilities(game)) {
|
||||
if (ability instanceof SpellAbility && ((SpellAbility) ability).getSpellAbilityType() == SpellAbilityType.MODAL) {
|
||||
continue;
|
||||
}
|
||||
allAbilites.add(ability);
|
||||
}
|
||||
|
||||
allAbilites.addAll(leftHalfCard.getAbilities(game));
|
||||
allAbilites.addAll(rightHalfCard.getAbilities(game));
|
||||
return allAbilites;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<String> getRules() {
|
||||
return new ArrayList<>();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setOwnerId(UUID ownerId) {
|
||||
super.setOwnerId(ownerId);
|
||||
abilities.setControllerId(ownerId);
|
||||
leftHalfCard.getAbilities().setControllerId(ownerId);
|
||||
leftHalfCard.setOwnerId(ownerId);
|
||||
rightHalfCard.getAbilities().setControllerId(ownerId);
|
||||
rightHalfCard.setOwnerId(ownerId);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getConvertedManaCost() {
|
||||
// Rules:
|
||||
// The converted mana cost of a modal double-faced card is based on the characteristics of the
|
||||
// face that’s being considered. On the stack and battlefield, consider whichever face is up.
|
||||
// In all other zones, consider only the front face. This is different than how the converted
|
||||
// mana cost of a transforming double-faced card is determined.
|
||||
|
||||
// on stack or battlefield it must be half card with own cost
|
||||
return getLeftHalfCard().getConvertedManaCost();
|
||||
}
|
||||
}
|
18
Mage/src/main/java/mage/cards/ModalDoubleFacesCardHalf.java
Normal file
18
Mage/src/main/java/mage/cards/ModalDoubleFacesCardHalf.java
Normal file
|
@ -0,0 +1,18 @@
|
|||
package mage.cards;
|
||||
|
||||
import mage.MageInt;
|
||||
|
||||
/**
|
||||
* @author JayDi85
|
||||
*/
|
||||
public interface ModalDoubleFacesCardHalf extends Card {
|
||||
|
||||
@Override
|
||||
ModalDoubleFacesCardHalf copy();
|
||||
|
||||
void setParentCard(ModalDoubleFacesCard card);
|
||||
|
||||
ModalDoubleFacesCard getParentCard();
|
||||
|
||||
void setPT(MageInt power, MageInt toughtness);
|
||||
}
|
101
Mage/src/main/java/mage/cards/ModalDoubleFacesCardHalfImpl.java
Normal file
101
Mage/src/main/java/mage/cards/ModalDoubleFacesCardHalfImpl.java
Normal file
|
@ -0,0 +1,101 @@
|
|||
package mage.cards;
|
||||
|
||||
import mage.MageInt;
|
||||
import mage.constants.CardType;
|
||||
import mage.constants.SpellAbilityType;
|
||||
import mage.constants.SubType;
|
||||
import mage.constants.Zone;
|
||||
import mage.game.Game;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.UUID;
|
||||
|
||||
/**
|
||||
* @author JayDi85
|
||||
*/
|
||||
public class ModalDoubleFacesCardHalfImpl extends CardImpl implements ModalDoubleFacesCardHalf {
|
||||
|
||||
ModalDoubleFacesCard parentCard;
|
||||
|
||||
public ModalDoubleFacesCardHalfImpl(UUID ownerId, CardSetInfo setInfo, CardType[] cardTypes, SubType[] cardSubTypes,
|
||||
String costs, ModalDoubleFacesCard parentCard, SpellAbilityType spellAbilityType) {
|
||||
super(ownerId, setInfo, cardTypes, costs, spellAbilityType);
|
||||
this.parentCard = parentCard;
|
||||
}
|
||||
|
||||
public ModalDoubleFacesCardHalfImpl(final ModalDoubleFacesCardHalfImpl card) {
|
||||
super(card);
|
||||
this.parentCard = card.parentCard;
|
||||
}
|
||||
|
||||
@Override
|
||||
public UUID getOwnerId() {
|
||||
return parentCard.getOwnerId();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getImageName() {
|
||||
// TODO: own name?
|
||||
return parentCard.getImageName();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getExpansionSetCode() {
|
||||
// TODO: own set code?
|
||||
return parentCard.getExpansionSetCode();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getCardNumber() {
|
||||
// TODO: own card number?
|
||||
return parentCard.getCardNumber();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean moveToZone(Zone toZone, UUID sourceId, Game game, boolean flag, List<UUID> appliedEffects) {
|
||||
return parentCard.moveToZone(toZone, sourceId, game, flag, appliedEffects);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean moveToExile(UUID exileId, String name, UUID sourceId, Game game, List<UUID> appliedEffects) {
|
||||
return parentCard.moveToExile(exileId, name, sourceId, game, appliedEffects);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean removeFromZone(Game game, Zone fromZone, UUID sourceId) {
|
||||
return parentCard.removeFromZone(game, fromZone, sourceId);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ModalDoubleFacesCard getMainCard() {
|
||||
return parentCard;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setZone(Zone zone, Game game) {
|
||||
game.setZone(parentCard.getId(), zone);
|
||||
game.setZone(parentCard.getLeftHalfCard().getId(), zone);
|
||||
game.setZone(parentCard.getRightHalfCard().getId(), zone);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ModalDoubleFacesCardHalfImpl copy() {
|
||||
return new ModalDoubleFacesCardHalfImpl(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setParentCard(ModalDoubleFacesCard card) {
|
||||
this.parentCard = card;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ModalDoubleFacesCard getParentCard() {
|
||||
return this.parentCard;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setPT(MageInt power, MageInt toughness) {
|
||||
this.power = power;
|
||||
this.toughness = toughness;
|
||||
}
|
||||
}
|
|
@ -32,7 +32,6 @@ public abstract class SplitCard extends CardImpl {
|
|||
String[] names = setInfo.getName().split(" // ");
|
||||
leftHalfCard = new SplitCardHalfImpl(this.getOwnerId(), new CardSetInfo(names[0], setInfo.getExpansionSetCode(), setInfo.getCardNumber(), setInfo.getRarity(), setInfo.getGraphicInfo()), typesLeft, costsLeft, this, SpellAbilityType.SPLIT_LEFT);
|
||||
rightHalfCard = new SplitCardHalfImpl(this.getOwnerId(), new CardSetInfo(names[1], setInfo.getExpansionSetCode(), setInfo.getCardNumber(), setInfo.getRarity(), setInfo.getGraphicInfo()), typesRight, costsRight, this, SpellAbilityType.SPLIT_RIGHT);
|
||||
this.splitCard = true;
|
||||
}
|
||||
|
||||
public SplitCard(SplitCard card) {
|
||||
|
@ -187,4 +186,15 @@ public abstract class SplitCard extends CardImpl {
|
|||
rightHalfCard.getAbilities().setControllerId(ownerId);
|
||||
rightHalfCard.setOwnerId(ownerId);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getConvertedManaCost() {
|
||||
// 202.3d The converted mana cost of a split card not on the stack or of a fused split spell on the
|
||||
// stack is determined from the combined mana costs of its halves. Otherwise, while a split card is
|
||||
// on the stack, the converted mana cost of the spell is determined by the mana cost of the half
|
||||
// that was chosen to be cast. See rule 708, “Split Cards.”
|
||||
|
||||
// split card and it's halfes contains own mana costs, so no need to rewrite logic
|
||||
return super.getConvertedManaCost();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,12 +1,6 @@
|
|||
/*
|
||||
* To change this license header, choose License Headers in Project Properties.
|
||||
* To change this template file, choose Tools | Templates
|
||||
* and open the template in the editor.
|
||||
*/
|
||||
package mage.cards;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author LevelX2
|
||||
*/
|
||||
public interface SplitCardHalf extends Card {
|
||||
|
|
|
@ -1,8 +1,3 @@
|
|||
/*
|
||||
* To change this license header, choose License Headers in Project Properties.
|
||||
* To change this template file, choose Tools | Templates
|
||||
* and open the template in the editor.
|
||||
*/
|
||||
package mage.cards;
|
||||
|
||||
import mage.constants.CardType;
|
||||
|
@ -14,7 +9,6 @@ import java.util.List;
|
|||
import java.util.UUID;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author LevelX2
|
||||
*/
|
||||
public class SplitCardHalfImpl extends CardImpl implements SplitCardHalf {
|
||||
|
@ -61,6 +55,11 @@ public class SplitCardHalfImpl extends CardImpl implements SplitCardHalf {
|
|||
return splitCardParent.moveToExile(exileId, name, sourceId, game, appliedEffects);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean removeFromZone(Game game, Zone fromZone, UUID sourceId) {
|
||||
return splitCardParent.removeFromZone(game, fromZone, sourceId);
|
||||
}
|
||||
|
||||
@Override
|
||||
public SplitCard getMainCard() {
|
||||
return splitCardParent;
|
||||
|
|
|
@ -20,6 +20,7 @@ import java.util.List;
|
|||
public class MockCard extends CardImpl {
|
||||
|
||||
static public String ADVENTURE_NAME_SEPARATOR = " // ";
|
||||
static public String MODAL_DOUBLE_FACES_NAME_SEPARATOR = " // ";
|
||||
|
||||
// Needs to be here, as it is normally calculated from the
|
||||
// PlaneswalkerEntersWithLoyaltyAbility of the card... but the MockCard
|
||||
|
@ -30,6 +31,7 @@ public class MockCard extends CardImpl {
|
|||
protected ManaCosts<ManaCost> manaCostLeft;
|
||||
protected ManaCosts<ManaCost> manaCostRight;
|
||||
protected String adventureSpellName;
|
||||
protected String modalDoubleFacesSecondSideName;
|
||||
|
||||
public MockCard(CardInfo card) {
|
||||
super(null, card.getName());
|
||||
|
@ -53,7 +55,6 @@ public class MockCard extends CardImpl {
|
|||
this.frameColor = card.getFrameColor();
|
||||
this.frameStyle = card.getFrameStyle();
|
||||
|
||||
this.splitCard = card.isSplitCard();
|
||||
this.flipCard = card.isFlipCard();
|
||||
|
||||
this.transformable = card.isDoubleFaced();
|
||||
|
@ -66,6 +67,10 @@ public class MockCard extends CardImpl {
|
|||
this.adventureSpellName = card.getAdventureSpellName();
|
||||
}
|
||||
|
||||
if (card.isModalDoubleFacesCard()) {
|
||||
this.modalDoubleFacesSecondSideName = card.getModalDoubleFacesSecondSideName();
|
||||
}
|
||||
|
||||
if (this.isPlaneswalker()) {
|
||||
String startingLoyaltyString = card.getStartingLoyalty();
|
||||
if (startingLoyaltyString.isEmpty()) {
|
||||
|
@ -117,8 +122,14 @@ public class MockCard extends CardImpl {
|
|||
}
|
||||
|
||||
public String getFullName(boolean showSecondName) {
|
||||
if (!showSecondName) {
|
||||
return getName();
|
||||
}
|
||||
|
||||
if (adventureSpellName != null) {
|
||||
return getName() + ADVENTURE_NAME_SEPARATOR + adventureSpellName;
|
||||
} else if (modalDoubleFacesSecondSideName != null) {
|
||||
return getName() + MODAL_DOUBLE_FACES_NAME_SEPARATOR + modalDoubleFacesSecondSideName;
|
||||
} else {
|
||||
return getName();
|
||||
}
|
||||
|
|
|
@ -35,7 +35,6 @@ public class MockSplitCard extends SplitCard {
|
|||
this.usesVariousArt = card.usesVariousArt();
|
||||
|
||||
this.color = card.getColor();
|
||||
this.splitCard = card.isSplitCard();
|
||||
this.flipCard = card.isFlipCard();
|
||||
|
||||
this.transformable = card.isDoubleFaced();
|
||||
|
|
|
@ -3,8 +3,6 @@ package mage.cards.repository;
|
|||
import com.j256.ormlite.field.DataType;
|
||||
import com.j256.ormlite.field.DatabaseField;
|
||||
import com.j256.ormlite.table.DatabaseTable;
|
||||
import java.util.*;
|
||||
import java.util.stream.Collectors;
|
||||
import mage.ObjectColor;
|
||||
import mage.abilities.Ability;
|
||||
import mage.abilities.SpellAbility;
|
||||
|
@ -17,6 +15,9 @@ import mage.util.CardUtil;
|
|||
import mage.util.SubTypeList;
|
||||
import org.apache.log4j.Logger;
|
||||
|
||||
import java.util.*;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
/**
|
||||
* @author North
|
||||
*/
|
||||
|
@ -103,6 +104,10 @@ public class CardInfo {
|
|||
protected boolean adventureCard;
|
||||
@DatabaseField
|
||||
protected String adventureSpellName;
|
||||
@DatabaseField
|
||||
protected boolean modalDoubleFacesCard;
|
||||
@DatabaseField
|
||||
protected String modalDoubleFacesSecondSideName;
|
||||
|
||||
public enum ManaCostSide {
|
||||
LEFT, RIGHT, ALL
|
||||
|
@ -121,7 +126,7 @@ public class CardInfo {
|
|||
this.toughness = card.getToughness().toString();
|
||||
this.convertedManaCost = card.getConvertedManaCost();
|
||||
this.rarity = card.getRarity();
|
||||
this.splitCard = card.isSplitCard();
|
||||
this.splitCard = card instanceof SplitCard;
|
||||
this.splitCardFuse = card.getSpellAbility() != null && card.getSpellAbility().getSpellAbilityType() == SpellAbilityType.SPLIT_FUSED;
|
||||
this.splitCardAftermath = card.getSpellAbility() != null && card.getSpellAbility().getSpellAbilityType() == SpellAbilityType.SPLIT_AFTERMATH;
|
||||
|
||||
|
@ -140,6 +145,11 @@ public class CardInfo {
|
|||
this.adventureSpellName = ((AdventureCard) card).getSpellCard().getName();
|
||||
}
|
||||
|
||||
if (card instanceof ModalDoubleFacesCard) {
|
||||
this.modalDoubleFacesCard = true;
|
||||
this.modalDoubleFacesSecondSideName = ((ModalDoubleFacesCard) card).getRightHalfCard().getName();
|
||||
}
|
||||
|
||||
this.frameStyle = card.getFrameStyle().toString();
|
||||
this.frameColor = card.getFrameColor(null).toString();
|
||||
this.variousArt = card.getUsesVariousArt();
|
||||
|
@ -153,13 +163,17 @@ public class CardInfo {
|
|||
this.setSubtypes(card.getSubtype(null).stream().map(SubType::toString).collect(Collectors.toList()));
|
||||
this.setSuperTypes(card.getSuperType());
|
||||
|
||||
// mana cost can contains multiple cards (split left/right, card/adventure)
|
||||
// mana cost can contains multiple cards (split left/right, modal double faces, card/adventure)
|
||||
if (card instanceof SplitCard) {
|
||||
List<String> manaCostLeft = ((SplitCard) card).getLeftHalfCard().getManaCost().getSymbols();
|
||||
List<String> manaCostRight = ((SplitCard) card).getRightHalfCard().getManaCost().getSymbols();
|
||||
this.setManaCosts(CardUtil.concatManaSymbols(SPLIT_MANA_SEPARATOR_FULL, manaCostLeft, manaCostRight));
|
||||
} else if (card instanceof ModalDoubleFacesCard) {
|
||||
List<String> manaCostLeft = ((ModalDoubleFacesCard) card).getLeftHalfCard().getManaCost().getSymbols();
|
||||
List<String> manaCostRight = ((ModalDoubleFacesCard) card).getRightHalfCard().getManaCost().getSymbols();
|
||||
this.setManaCosts(CardUtil.concatManaSymbols(SPLIT_MANA_SEPARATOR_FULL, manaCostLeft, manaCostRight));
|
||||
} else if (card instanceof AdventureCard) {
|
||||
List<String> manaCostLeft = ((AdventureCard) card).getSpellCard().getManaCost().getSymbols(); // Spell from left like MTGA
|
||||
List<String> manaCostLeft = ((AdventureCard) card).getSpellCard().getManaCost().getSymbols();
|
||||
List<String> manaCostRight = card.getManaCost().getSymbols();
|
||||
this.setManaCosts(CardUtil.concatManaSymbols(SPLIT_MANA_SEPARATOR_FULL, manaCostLeft, manaCostRight));
|
||||
} else {
|
||||
|
@ -181,6 +195,19 @@ public class CardInfo {
|
|||
length += rule.length();
|
||||
rulesList.add(rule);
|
||||
}
|
||||
} else if (card instanceof ModalDoubleFacesCard) {
|
||||
for (String rule : ((ModalDoubleFacesCard) card).getLeftHalfCard().getRules()) {
|
||||
length += rule.length();
|
||||
rulesList.add(rule);
|
||||
}
|
||||
for (String rule : ((ModalDoubleFacesCard) card).getRightHalfCard().getRules()) {
|
||||
length += rule.length();
|
||||
rulesList.add(rule);
|
||||
}
|
||||
for (String rule : card.getRules()) {
|
||||
length += rule.length();
|
||||
rulesList.add(rule);
|
||||
}
|
||||
} else {
|
||||
for (String rule : card.getRules()) {
|
||||
length += rule.length();
|
||||
|
@ -222,7 +249,6 @@ public class CardInfo {
|
|||
}
|
||||
}
|
||||
if (this.startingLoyalty == null) {
|
||||
//Logger.getLogger(CardInfo.class).warn("Planeswalker `" + card.getName() + "` missing starting loyalty");
|
||||
this.startingLoyalty = "";
|
||||
}
|
||||
} else {
|
||||
|
@ -447,4 +473,12 @@ public class CardInfo {
|
|||
public String getAdventureSpellName() {
|
||||
return adventureSpellName;
|
||||
}
|
||||
|
||||
public boolean isModalDoubleFacesCard() {
|
||||
return modalDoubleFacesCard;
|
||||
}
|
||||
|
||||
public String getModalDoubleFacesSecondSideName() {
|
||||
return modalDoubleFacesSecondSideName;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -34,9 +34,9 @@ public enum CardRepository {
|
|||
private static final String JDBC_URL = "jdbc:h2:file:./db/cards.h2;AUTO_SERVER=TRUE";
|
||||
private static final String VERSION_ENTITY_NAME = "card";
|
||||
// raise this if db structure was changed
|
||||
private static final long CARD_DB_VERSION = 52;
|
||||
private static final long CARD_DB_VERSION = 53;
|
||||
// raise this if new cards were added to the server
|
||||
private static final long CARD_CONTENT_VERSION = 232;
|
||||
private static final long CARD_CONTENT_VERSION = 233;
|
||||
private Dao<CardInfo, Object> cardDao;
|
||||
private Set<String> classNames;
|
||||
private final RepositoryEventSource eventSource = new RepositoryEventSource();
|
||||
|
|
|
@ -59,7 +59,7 @@ public final class CardScanner {
|
|||
new CardSetInfo(setInfo.getName(), set.getCode(), setInfo.getCardNumber(), setInfo.getRarity(), setInfo.getGraphicInfo()),
|
||||
errorsList);
|
||||
if (card != null) {
|
||||
cardsToAdd.add(new CardInfo(card));
|
||||
cardsToAdd.add(new CardInfo(card)); // normal, transformed, adventure, modal double faces -- all must have single face in db
|
||||
if (card instanceof SplitCard) {
|
||||
SplitCard splitCard = (SplitCard) card;
|
||||
cardsToAdd.add(new CardInfo(splitCard.getLeftHalfCard()));
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
package mage.constants;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author North
|
||||
*/
|
||||
public enum SpellAbilityType {
|
||||
|
@ -13,7 +12,9 @@ public enum SpellAbilityType {
|
|||
SPLIT_FUSED("Split SpellAbility"),
|
||||
SPLIT_LEFT("LeftSplit SpellAbility"),
|
||||
SPLIT_RIGHT("RightSplit SpellAbility"),
|
||||
MODE("Mode SpellAbility"),
|
||||
MODAL("Modal SpellAbility"), // used for modal double faces cards
|
||||
MODAL_LEFT("LeftModal SpellAbility"),
|
||||
MODAL_RIGHT("RightModal SpellAbility"),
|
||||
SPLICE("Spliced SpellAbility"),
|
||||
ADVENTURE_SPELL("Adventure SpellAbility");
|
||||
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
|
||||
package mage.filter.predicate.mageobject;
|
||||
|
||||
import mage.MageObject;
|
||||
import mage.cards.ModalDoubleFacesCardHalf;
|
||||
import mage.cards.SplitCardHalf;
|
||||
import mage.constants.Zone;
|
||||
import mage.filter.predicate.Predicate;
|
||||
|
@ -18,8 +18,13 @@ public enum MulticoloredPredicate implements Predicate<MageObject> {
|
|||
// 708.3. Each split card that consists of two halves with different colored mana symbols in their mana costs
|
||||
// is a multicolored card while it's not a spell on the stack. While it's a spell on the stack, it's only the
|
||||
// color or colors of the half or halves being cast. #
|
||||
if (input instanceof SplitCardHalf && game.getState().getZone(input.getId()) != Zone.STACK) {
|
||||
if (input instanceof SplitCardHalf
|
||||
&& game.getState().getZone(input.getId()) != Zone.STACK) {
|
||||
return 1 < ((SplitCardHalf) input).getMainCard().getColor(game).getColorCount();
|
||||
} else if (input instanceof ModalDoubleFacesCardHalf
|
||||
&& (game.getState().getZone(input.getId()) != Zone.STACK && game.getState().getZone(input.getId()) != Zone.BATTLEFIELD)) {
|
||||
// While a double-faced card isn’t on the stack or battlefield, consider only the characteristics of its front face.
|
||||
return 1 < ((ModalDoubleFacesCardHalf) input).getMainCard().getColor(game).getColorCount();
|
||||
} else {
|
||||
return 1 < input.getColor(game).getColorCount();
|
||||
}
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
package mage.filter.predicate.mageobject;
|
||||
|
||||
import mage.MageObject;
|
||||
import mage.cards.ModalDoubleFacesCard;
|
||||
import mage.cards.SplitCard;
|
||||
import mage.constants.SpellAbilityType;
|
||||
import mage.filter.predicate.Predicate;
|
||||
|
@ -32,10 +33,15 @@ public class NamePredicate implements Predicate<MageObject> {
|
|||
}
|
||||
// If a player names a card, the player may name either half of a split card, but not both.
|
||||
// A split card has the chosen name if one of its two names matches the chosen name.
|
||||
// Same for modal double faces cards
|
||||
if (input instanceof SplitCard) {
|
||||
return CardUtil.haveSameNames(name, ((SplitCard) input).getLeftHalfCard().getName(), this.ignoreMtgRuleForEmptyNames) ||
|
||||
CardUtil.haveSameNames(name, ((SplitCard) input).getRightHalfCard().getName(), this.ignoreMtgRuleForEmptyNames) ||
|
||||
CardUtil.haveSameNames(name, input.getName(), this.ignoreMtgRuleForEmptyNames);
|
||||
} else if (input instanceof ModalDoubleFacesCard) {
|
||||
return CardUtil.haveSameNames(name, ((ModalDoubleFacesCard) input).getLeftHalfCard().getName(), this.ignoreMtgRuleForEmptyNames) ||
|
||||
CardUtil.haveSameNames(name, ((ModalDoubleFacesCard) input).getRightHalfCard().getName(), this.ignoreMtgRuleForEmptyNames) ||
|
||||
CardUtil.haveSameNames(name, input.getName(), this.ignoreMtgRuleForEmptyNames);
|
||||
} else if (input instanceof Spell && ((Spell) input).getSpellAbility().getSpellAbilityType() == SpellAbilityType.SPLIT_FUSED) {
|
||||
SplitCard card = (SplitCard) ((Spell) input).getCard();
|
||||
return CardUtil.haveSameNames(name, card.getLeftHalfCard().getName(), this.ignoreMtgRuleForEmptyNames) ||
|
||||
|
|
|
@ -2,6 +2,7 @@ package mage.filter.predicate.other;
|
|||
|
||||
import mage.cards.AdventureCard;
|
||||
import mage.cards.Card;
|
||||
import mage.cards.ModalDoubleFacesCard;
|
||||
import mage.cards.SplitCard;
|
||||
import mage.cards.mock.MockCard;
|
||||
import mage.constants.SubType;
|
||||
|
@ -52,6 +53,8 @@ public class CardTextPredicate implements Predicate<Card> {
|
|||
String fullName = input.getName();
|
||||
if (input instanceof MockCard) {
|
||||
fullName = ((MockCard) input).getFullName(true);
|
||||
} else if (input instanceof ModalDoubleFacesCard) {
|
||||
fullName = input.getName() + MockCard.MODAL_DOUBLE_FACES_NAME_SEPARATOR + ((ModalDoubleFacesCard) input).getRightHalfCard().getName();
|
||||
} else if (input instanceof AdventureCard) {
|
||||
fullName = input.getName() + MockCard.ADVENTURE_NAME_SEPARATOR + ((AdventureCard) input).getSpellCard().getName();
|
||||
}
|
||||
|
@ -67,14 +70,14 @@ public class CardTextPredicate implements Predicate<Card> {
|
|||
}
|
||||
}
|
||||
|
||||
//separate by spaces
|
||||
// separate by spaces
|
||||
String[] tokens = text.toLowerCase(Locale.ENGLISH).split(" ");
|
||||
for (String token : tokens) {
|
||||
boolean found = false;
|
||||
if (!token.isEmpty()) {
|
||||
// then try to find in rules
|
||||
if (inRules) {
|
||||
if (input.isSplitCard()) {
|
||||
if (input instanceof SplitCard) {
|
||||
for (String rule : ((SplitCard) input).getLeftHalfCard().getRules(game)) {
|
||||
if (rule.toLowerCase(Locale.ENGLISH).contains(token)) {
|
||||
found = true;
|
||||
|
@ -88,6 +91,22 @@ public class CardTextPredicate implements Predicate<Card> {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (input instanceof ModalDoubleFacesCard) {
|
||||
for (String rule : ((ModalDoubleFacesCard) input).getLeftHalfCard().getRules(game)) {
|
||||
if (rule.toLowerCase(Locale.ENGLISH).contains(token)) {
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
for (String rule : ((ModalDoubleFacesCard) input).getRightHalfCard().getRules(game)) {
|
||||
if (rule.toLowerCase(Locale.ENGLISH).contains(token)) {
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (input instanceof AdventureCard) {
|
||||
for (String rule : ((AdventureCard) input).getSpellCard().getRules(game)) {
|
||||
if (rule.toLowerCase(Locale.ENGLISH).contains(token)) {
|
||||
|
@ -96,6 +115,7 @@ public class CardTextPredicate implements Predicate<Card> {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (String rule : input.getRules(game)) {
|
||||
if (rule.toLowerCase(Locale.ENGLISH).contains(token)) {
|
||||
found = true;
|
||||
|
|
|
@ -244,17 +244,29 @@ public abstract class GameImpl implements Game, Serializable {
|
|||
card.setOwnerId(ownerId);
|
||||
gameCards.put(card.getId(), card);
|
||||
state.addCard(card);
|
||||
if (card.isSplitCard()) {
|
||||
if (card instanceof SplitCard) {
|
||||
// left
|
||||
Card leftCard = ((SplitCard) card).getLeftHalfCard();
|
||||
leftCard.setOwnerId(ownerId);
|
||||
gameCards.put(leftCard.getId(), leftCard);
|
||||
state.addCard(leftCard);
|
||||
// right
|
||||
Card rightCard = ((SplitCard) card).getRightHalfCard();
|
||||
rightCard.setOwnerId(ownerId);
|
||||
gameCards.put(rightCard.getId(), rightCard);
|
||||
state.addCard(rightCard);
|
||||
}
|
||||
if (card instanceof AdventureCard) {
|
||||
} else if (card instanceof ModalDoubleFacesCard) {
|
||||
// left
|
||||
Card leftCard = ((ModalDoubleFacesCard) card).getLeftHalfCard();
|
||||
leftCard.setOwnerId(ownerId);
|
||||
gameCards.put(leftCard.getId(), leftCard);
|
||||
state.addCard(leftCard);
|
||||
// right
|
||||
Card rightCard = ((ModalDoubleFacesCard) card).getRightHalfCard();
|
||||
rightCard.setOwnerId(ownerId);
|
||||
gameCards.put(rightCard.getId(), rightCard);
|
||||
state.addCard(rightCard);
|
||||
} else if (card instanceof AdventureCard) {
|
||||
Card spellCard = ((AdventureCard) card).getSpellCard();
|
||||
spellCard.setOwnerId(ownerId);
|
||||
gameCards.put(spellCard.getId(), spellCard);
|
||||
|
@ -1911,7 +1923,7 @@ public abstract class GameImpl implements Game, Serializable {
|
|||
Iterator<Card> copiedCards = this.getState().getCopiedCards().iterator();
|
||||
while (copiedCards.hasNext()) {
|
||||
Card card = copiedCards.next();
|
||||
if (card instanceof SplitCardHalf || card instanceof AdventureCardSpell) {
|
||||
if (card instanceof SplitCardHalf || card instanceof AdventureCardSpell || card instanceof ModalDoubleFacesCardHalf) {
|
||||
continue; // only the main card is moves, not the halves (cause halfes is not copied - it uses original card -- TODO: need to fix (bugs with same card copy)?
|
||||
}
|
||||
Zone zone = state.getZone(card.getId());
|
||||
|
|
|
@ -1,9 +1,5 @@
|
|||
package mage.game;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.*;
|
||||
import static java.util.Collections.emptyList;
|
||||
import java.util.stream.Collectors;
|
||||
import mage.MageObject;
|
||||
import mage.MageObjectReference;
|
||||
import mage.abilities.*;
|
||||
|
@ -12,6 +8,7 @@ import mage.abilities.effects.ContinuousEffects;
|
|||
import mage.abilities.effects.Effect;
|
||||
import mage.cards.AdventureCard;
|
||||
import mage.cards.Card;
|
||||
import mage.cards.ModalDoubleFacesCard;
|
||||
import mage.cards.SplitCard;
|
||||
import mage.constants.Zone;
|
||||
import mage.designations.Designation;
|
||||
|
@ -40,6 +37,12 @@ import mage.util.ThreadLocalStringBuilder;
|
|||
import mage.watchers.Watcher;
|
||||
import mage.watchers.Watchers;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.*;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import static java.util.Collections.emptyList;
|
||||
|
||||
/**
|
||||
* @author BetaSteward_at_googlemail.com
|
||||
* <p>
|
||||
|
@ -626,6 +629,7 @@ public class GameState implements Serializable, Copyable<GameState> {
|
|||
// public void addMessage(String message) {
|
||||
// this.messages.add(message);
|
||||
// }
|
||||
|
||||
/**
|
||||
* Returns a list of all players of the game ignoring range or if a player
|
||||
* has lost or left the game.
|
||||
|
@ -799,7 +803,7 @@ public class GameState implements Serializable, Copyable<GameState> {
|
|||
for (Map.Entry<ZoneChangeData, List<GameEvent>> entry : eventsByKey.entrySet()) {
|
||||
Set<Card> movedCards = new LinkedHashSet<>();
|
||||
Set<PermanentToken> movedTokens = new LinkedHashSet<>();
|
||||
for (Iterator<GameEvent> it = entry.getValue().iterator(); it.hasNext();) {
|
||||
for (Iterator<GameEvent> it = entry.getValue().iterator(); it.hasNext(); ) {
|
||||
GameEvent event = it.next();
|
||||
ZoneChangeEvent castEvent = (ZoneChangeEvent) event;
|
||||
UUID targetId = castEvent.getTargetId();
|
||||
|
@ -835,10 +839,14 @@ public class GameState implements Serializable, Copyable<GameState> {
|
|||
}
|
||||
// TODO Watchers?
|
||||
// TODO Abilities?
|
||||
if (card.isSplitCard()) {
|
||||
if (card instanceof SplitCard) {
|
||||
removeCopiedCard(((SplitCard) card).getLeftHalfCard());
|
||||
removeCopiedCard(((SplitCard) card).getRightHalfCard());
|
||||
}
|
||||
if (card instanceof ModalDoubleFacesCard) {
|
||||
removeCopiedCard(((ModalDoubleFacesCard) card).getLeftHalfCard());
|
||||
removeCopiedCard(((ModalDoubleFacesCard) card).getRightHalfCard());
|
||||
}
|
||||
if (card instanceof AdventureCard) {
|
||||
removeCopiedCard(((AdventureCard) card).getSpellCard());
|
||||
}
|
||||
|
@ -1194,21 +1202,34 @@ public class GameState implements Serializable, Copyable<GameState> {
|
|||
}
|
||||
|
||||
public Card copyCard(Card cardToCopy, Ability source, Game game) {
|
||||
// main card
|
||||
Card copiedCard = cardToCopy.copy();
|
||||
copiedCard.assignNewId();
|
||||
copiedCard.setOwnerId(source.getControllerId());
|
||||
copiedCard.setCopy(true, cardToCopy);
|
||||
copiedCards.put(copiedCard.getId(), copiedCard);
|
||||
addCard(copiedCard);
|
||||
if (copiedCard.isSplitCard()) {
|
||||
|
||||
// other faces
|
||||
if (copiedCard instanceof SplitCard) {
|
||||
// left
|
||||
Card leftCard = ((SplitCard) copiedCard).getLeftHalfCard(); // TODO: must be new ID (bugs with same card copy)?
|
||||
copiedCards.put(leftCard.getId(), leftCard);
|
||||
addCard(leftCard);
|
||||
// right
|
||||
Card rightCard = ((SplitCard) copiedCard).getRightHalfCard();
|
||||
copiedCards.put(rightCard.getId(), rightCard);
|
||||
addCard(rightCard);
|
||||
}
|
||||
if (copiedCard instanceof AdventureCard) {
|
||||
} else if (copiedCard instanceof ModalDoubleFacesCard) {
|
||||
// left
|
||||
Card leftCard = ((ModalDoubleFacesCard) copiedCard).getLeftHalfCard(); // TODO: must be new ID (bugs with same card copy)?
|
||||
copiedCards.put(leftCard.getId(), leftCard);
|
||||
addCard(leftCard);
|
||||
// right
|
||||
Card rightCard = ((ModalDoubleFacesCard) copiedCard).getRightHalfCard();
|
||||
copiedCards.put(rightCard.getId(), rightCard);
|
||||
addCard(rightCard);
|
||||
} else if (copiedCard instanceof AdventureCard) {
|
||||
Card spellCard = ((AdventureCard) copiedCard).getSpellCard();
|
||||
copiedCards.put(spellCard.getId(), spellCard);
|
||||
addCard(spellCard);
|
||||
|
|
|
@ -1,9 +1,7 @@
|
|||
package mage.game;
|
||||
|
||||
import mage.cards.Card;
|
||||
import mage.cards.Cards;
|
||||
import mage.cards.CardsImpl;
|
||||
import mage.cards.MeldCard;
|
||||
import mage.abilities.keyword.TransformAbility;
|
||||
import mage.cards.*;
|
||||
import mage.constants.Outcome;
|
||||
import mage.constants.Zone;
|
||||
import mage.filter.FilterCard;
|
||||
|
@ -19,7 +17,6 @@ import mage.players.Player;
|
|||
import mage.target.TargetCard;
|
||||
|
||||
import java.util.*;
|
||||
import mage.abilities.keyword.TransformAbility;
|
||||
|
||||
/**
|
||||
* Created by samuelsandeen on 9/6/16.
|
||||
|
@ -54,7 +51,7 @@ public final class ZonesHandler {
|
|||
|
||||
public static List<ZoneChangeInfo> moveCards(List<ZoneChangeInfo> zoneChangeInfos, Game game) {
|
||||
// Handle Unmelded Meld Cards
|
||||
for (ListIterator<ZoneChangeInfo> itr = zoneChangeInfos.listIterator(); itr.hasNext();) {
|
||||
for (ListIterator<ZoneChangeInfo> itr = zoneChangeInfos.listIterator(); itr.hasNext(); ) {
|
||||
ZoneChangeInfo info = itr.next();
|
||||
MeldCard card = game.getMeldCard(info.event.getTargetId());
|
||||
// Copies should be handled as normal cards.
|
||||
|
@ -106,6 +103,10 @@ public final class ZonesHandler {
|
|||
if (!(targetCard instanceof Permanent) && targetCard != null) {
|
||||
if (targetCard instanceof MeldCard) {
|
||||
cards = ((MeldCard) targetCard).getHalves();
|
||||
} else if (targetCard instanceof ModalDoubleFacesCard) {
|
||||
cards = new CardsImpl(targetCard);
|
||||
cards.add(((ModalDoubleFacesCard) targetCard).getLeftHalfCard());
|
||||
cards.add(((ModalDoubleFacesCard) targetCard).getRightHalfCard());
|
||||
} else {
|
||||
cards = new CardsImpl(targetCard);
|
||||
}
|
||||
|
@ -174,14 +175,19 @@ public final class ZonesHandler {
|
|||
throw new UnsupportedOperationException("to Zone " + toZone.toString() + " not supported yet");
|
||||
}
|
||||
}
|
||||
|
||||
game.setZone(event.getTargetId(), event.getToZone());
|
||||
if (targetCard instanceof MeldCard && cards != null) {
|
||||
if (event.getToZone() != Zone.BATTLEFIELD) {
|
||||
((MeldCard) targetCard).setMelded(false, game);
|
||||
}
|
||||
if (cards != null && (targetCard instanceof MeldCard || targetCard instanceof ModalDoubleFacesCard)) {
|
||||
// update other parts too
|
||||
for (Card card : cards.getCards(game)) {
|
||||
game.setZone(card.getId(), event.getToZone());
|
||||
}
|
||||
// reset meld status
|
||||
if (targetCard instanceof MeldCard) {
|
||||
if (event.getToZone() != Zone.BATTLEFIELD) {
|
||||
((MeldCard) targetCard).setMelded(false, game);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -203,7 +209,7 @@ public final class ZonesHandler {
|
|||
if (info instanceof ZoneChangeInfo.Unmelded) {
|
||||
ZoneChangeInfo.Unmelded unmelded = (ZoneChangeInfo.Unmelded) info;
|
||||
MeldCard meld = game.getMeldCard(info.event.getTargetId());
|
||||
for (Iterator<ZoneChangeInfo> itr = unmelded.subInfo.iterator(); itr.hasNext();) {
|
||||
for (Iterator<ZoneChangeInfo> itr = unmelded.subInfo.iterator(); itr.hasNext(); ) {
|
||||
ZoneChangeInfo subInfo = itr.next();
|
||||
if (!maybeRemoveFromSourceZone(subInfo, game)) {
|
||||
itr.remove();
|
||||
|
@ -232,10 +238,10 @@ public final class ZonesHandler {
|
|||
if (info.faceDown) {
|
||||
card.setFaceDown(true, game);
|
||||
} else if (info.event.getToZone().equals(Zone.BATTLEFIELD)) {
|
||||
if (!card.isPermanent()
|
||||
if (!card.isPermanent()
|
||||
&& (!card.isTransformable() || Boolean.FALSE.equals(game.getState().getValue(TransformAbility.VALUE_KEY_ENTER_TRANSFORMED + card.getId())))) {
|
||||
// Non permanents (Instants, Sorceries, ... stay in the zone they are if an abilty/effect tries to move it to the battlefield
|
||||
return false;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
if (!game.replaceEvent(event)) {
|
||||
|
@ -248,9 +254,10 @@ public final class ZonesHandler {
|
|||
Permanent permanent;
|
||||
if (card instanceof MeldCard) {
|
||||
permanent = new PermanentMeld(card, event.getPlayerId(), game);
|
||||
} else if (card instanceof ModalDoubleFacesCard) {
|
||||
throw new IllegalStateException("Try to move mdf card to battlefield instead half");
|
||||
} else if (card instanceof Permanent) {
|
||||
// This should never happen.
|
||||
permanent = (Permanent) card;
|
||||
throw new IllegalStateException("Try to move permanent card to battlefield");
|
||||
} else {
|
||||
permanent = new PermanentCard(card, event.getPlayerId(), game);
|
||||
}
|
||||
|
|
|
@ -712,11 +712,6 @@ public class Spell extends StackObjImpl implements Card {
|
|||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isSplitCard() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isTransformable() {
|
||||
return false;
|
||||
|
|
|
@ -1602,6 +1602,10 @@ public abstract class PlayerImpl implements Player, Serializable {
|
|||
needId1 = object.getId();
|
||||
needId2 = ((SplitCard) object).getLeftHalfCard().getId();
|
||||
needId3 = ((SplitCard) object).getRightHalfCard().getId();
|
||||
} else if (object instanceof ModalDoubleFacesCard) {
|
||||
needId1 = object.getId();
|
||||
needId2 = ((ModalDoubleFacesCard) object).getLeftHalfCard().getId();
|
||||
needId3 = ((ModalDoubleFacesCard) object).getRightHalfCard().getId();
|
||||
} else if (object instanceof AdventureCard) {
|
||||
needId1 = object.getId();
|
||||
needId2 = ((AdventureCard) object).getMainCard().getId();
|
||||
|
@ -3402,10 +3406,16 @@ public abstract class PlayerImpl implements Player, Serializable {
|
|||
|
||||
// BASIC abilities
|
||||
if (object instanceof SplitCard) {
|
||||
SplitCard splitCard = (SplitCard) object;
|
||||
getPlayableFromObjectSingle(game, fromZone, splitCard.getLeftHalfCard(), splitCard.getLeftHalfCard().getAbilities(game), availableMana, output);
|
||||
getPlayableFromObjectSingle(game, fromZone, splitCard.getRightHalfCard(), splitCard.getRightHalfCard().getAbilities(game), availableMana, output);
|
||||
getPlayableFromObjectSingle(game, fromZone, splitCard, splitCard.getSharedAbilities(game), availableMana, output);
|
||||
SplitCard mainCard = (SplitCard) object;
|
||||
getPlayableFromObjectSingle(game, fromZone, mainCard.getLeftHalfCard(), mainCard.getLeftHalfCard().getAbilities(game), availableMana, output);
|
||||
getPlayableFromObjectSingle(game, fromZone, mainCard.getRightHalfCard(), mainCard.getRightHalfCard().getAbilities(game), availableMana, output);
|
||||
getPlayableFromObjectSingle(game, fromZone, mainCard, mainCard.getSharedAbilities(game), availableMana, output);
|
||||
}
|
||||
if (object instanceof ModalDoubleFacesCard) {
|
||||
ModalDoubleFacesCard mainCard = (ModalDoubleFacesCard) object;
|
||||
getPlayableFromObjectSingle(game, fromZone, mainCard.getLeftHalfCard(), mainCard.getLeftHalfCard().getAbilities(game), availableMana, output);
|
||||
getPlayableFromObjectSingle(game, fromZone, mainCard.getRightHalfCard(), mainCard.getRightHalfCard().getAbilities(game), availableMana, output);
|
||||
getPlayableFromObjectSingle(game, fromZone, mainCard, mainCard.getSharedAbilities(game), availableMana, output);
|
||||
} else if (object instanceof AdventureCard) {
|
||||
// adventure must use different card characteristics for different spells (main or adventure)
|
||||
AdventureCard adventureCard = (AdventureCard) object;
|
||||
|
|
|
@ -1,11 +1,5 @@
|
|||
package mage.util;
|
||||
|
||||
import java.io.UnsupportedEncodingException;
|
||||
import java.net.URLDecoder;
|
||||
import java.net.URLEncoder;
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.util.*;
|
||||
import java.util.stream.Collectors;
|
||||
import mage.MageObject;
|
||||
import mage.Mana;
|
||||
import mage.abilities.Abilities;
|
||||
|
@ -17,6 +11,8 @@ import mage.abilities.costs.mana.*;
|
|||
import mage.abilities.effects.ContinuousEffect;
|
||||
import mage.cards.Card;
|
||||
import mage.cards.MeldCard;
|
||||
import mage.cards.ModalDoubleFacesCard;
|
||||
import mage.cards.SplitCard;
|
||||
import mage.constants.*;
|
||||
import mage.filter.Filter;
|
||||
import mage.filter.predicate.mageobject.NamePredicate;
|
||||
|
@ -31,6 +27,13 @@ import mage.players.Player;
|
|||
import mage.target.Target;
|
||||
import mage.util.functions.CopyTokenFunction;
|
||||
|
||||
import java.io.UnsupportedEncodingException;
|
||||
import java.net.URLDecoder;
|
||||
import java.net.URLEncoder;
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.util.*;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
/**
|
||||
* @author nantuko
|
||||
*/
|
||||
|
@ -39,10 +42,10 @@ public final class CardUtil {
|
|||
private static final String SOURCE_EXILE_ZONE_TEXT = "SourceExileZone";
|
||||
|
||||
static final String[] numberStrings = {"zero", "one", "two", "three", "four", "five", "six", "seven", "eight", "nine",
|
||||
"ten", "eleven", "twelve", "thirteen", "fourteen", "fifteen", "sixteen", "seventeen", "eighteen", "nineteen", "twenty"};
|
||||
"ten", "eleven", "twelve", "thirteen", "fourteen", "fifteen", "sixteen", "seventeen", "eighteen", "nineteen", "twenty"};
|
||||
|
||||
static final String[] ordinalStrings = {"first", "second", "third", "fourth", "fifth", "sixth", "seventh", "eightth", "ninth",
|
||||
"tenth", "eleventh", "twelfth", "thirteenth", "fourteenth", "fifteenth", "sixteenth", "seventeenth", "eighteenth", "nineteenth", "twentieth"};
|
||||
"tenth", "eleventh", "twelfth", "thirteenth", "fourteenth", "fifteenth", "sixteenth", "seventeenth", "eighteenth", "nineteenth", "twentieth"};
|
||||
|
||||
public static final SimpleDateFormat sdf = new SimpleDateFormat("HH:mm:ss.SSS");
|
||||
|
||||
|
@ -877,4 +880,21 @@ public final class CardUtil {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Return card name for same name searching
|
||||
*
|
||||
* @param card
|
||||
* @return
|
||||
*/
|
||||
public static String getCardNameForSameNameSearch(Card card) {
|
||||
// it's ok to return one name only cause NamePredicate can find same card by first name
|
||||
if (card instanceof SplitCard) {
|
||||
return ((SplitCard) card).getLeftHalfCard().getName();
|
||||
} else if (card instanceof ModalDoubleFacesCard) {
|
||||
return ((ModalDoubleFacesCard) card).getLeftHalfCard().getName();
|
||||
} else {
|
||||
return card.getName();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue