This commit is contained in:
jeffwadsworth 2021-08-31 09:52:19 -05:00
commit 0ee1d428e1
105 changed files with 1029 additions and 479 deletions

View file

@ -6,7 +6,7 @@
<parent>
<groupId>org.mage</groupId>
<artifactId>mage-root</artifactId>
<version>1.4.49</version>
<version>1.4.50</version>
</parent>
<artifactId>mage-client</artifactId>

View file

@ -153,7 +153,14 @@ public class PickChoiceDialog extends MageDialog {
public void mouseMoved(MouseEvent e) {
// hint show
JList listSource = (JList) e.getSource();
int index = listSource.locationToIndex(e.getPoint());
// workaround to raise on real element, not empty space
int index = -1;
Rectangle r = listSource.getCellBounds(0, listSource.getLastVisibleIndex());
if (r != null && r.contains(e.getPoint())) {
index = listSource.locationToIndex(e.getPoint());
}
if (index > -1) {
choiceHintShow(index);
} else {
@ -255,7 +262,8 @@ public class PickChoiceDialog extends MageDialog {
private void choiceHintHide() {
switch (choice.getHintType()) {
case CARD: {
case CARD:
case CARD_DUNGEON: {
// as popup card
cardInfo.onMouseExited();
break;

View file

@ -171,7 +171,7 @@
int left = draftView.getPlayers().size() - right;
int height = left * 18;
lblTableImage.setSize(new Dimension(lblTableImage.getWidth(), height));
Image tableImage = ImageHelper.getImageFromResources((draftView.getBoosterNum() + 1) % 2 == 1 ? "/draft/table_left.png" : "/draft/table_right.png");
Image tableImage = ImageHelper.getImageFromResources(draftView.getBoosterNum() % 2 == 1 ? "/draft/table_left.png" : "/draft/table_right.png");
BufferedImage resizedTable = ImageHelper.getResizedImage(BufferedImageBuilder.bufferImage(tableImage, BufferedImage.TYPE_INT_ARGB), lblTableImage.getWidth(), lblTableImage.getHeight());
lblTableImage.setIcon(new ImageIcon(resizedTable));

View file

@ -667,6 +667,12 @@ public final class ManaSymbols {
if (replaced.contains(HintUtils.HINT_ICON_REQUIRE)) {
replaced = replaced.replace(HintUtils.HINT_ICON_REQUIRE, GuiDisplayUtil.getHintIconHtml("require", symbolSize) + "&nbsp;");
}
if (replaced.contains(HintUtils.HINT_ICON_DUNGEON_ROOM_CURRENT)) {
replaced = replaced.replace(HintUtils.HINT_ICON_DUNGEON_ROOM_CURRENT, GuiDisplayUtil.getHintIconHtml("arrow-right-square-fill-green", symbolSize) + "&nbsp;");
}
if (replaced.contains(HintUtils.HINT_ICON_DUNGEON_ROOM_NEXT)) {
replaced = replaced.replace(HintUtils.HINT_ICON_DUNGEON_ROOM_NEXT, GuiDisplayUtil.getHintIconHtml("arrow-down-right-square fill-yellow", symbolSize) + "&nbsp;");
}
// ignored data restore
replaced = replaced

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4 KiB

View file

@ -7,7 +7,7 @@
<parent>
<groupId>org.mage</groupId>
<artifactId>mage-root</artifactId>
<version>1.4.49</version>
<version>1.4.50</version>
</parent>
<artifactId>mage-common</artifactId>

View file

@ -17,8 +17,8 @@ public class MageVersion implements Serializable, Comparable<MageVersion> {
// * launcher gives priority to 1.4.48 instead 1.4.48-any-text, so don't use empty release info
public static final int MAGE_VERSION_MAJOR = 1;
public static final int MAGE_VERSION_MINOR = 4;
public static final int MAGE_VERSION_RELEASE = 49;
public static final String MAGE_VERSION_RELEASE_INFO = "V3"; // V1 for releases, V1-beta3 for betas
public static final int MAGE_VERSION_RELEASE = 50;
public static final String MAGE_VERSION_RELEASE_INFO = "V1"; // V1 for releases, V1-beta3 for betas
// strict mode
// Each update requires a strict version

View file

@ -19,8 +19,8 @@ public class DraftView implements Serializable {
private final List<String> sets = new ArrayList<>();
private final List<String> setCodes = new ArrayList<>();
private final int boosterNum;
private final int cardNum;
private final int boosterNum; // starts with 1
private final int cardNum; // starts with 1
private final List<String> players = new ArrayList<>();
public DraftView(Draft draft) {

View file

@ -7,7 +7,7 @@
<parent>
<groupId>org.mage</groupId>
<artifactId>mage-plugins</artifactId>
<version>1.4.49</version>
<version>1.4.50</version>
</parent>
<artifactId>mage-counter-plugin</artifactId>

View file

@ -7,7 +7,7 @@
<parent>
<groupId>org.mage</groupId>
<artifactId>mage-root</artifactId>
<version>1.4.49</version>
<version>1.4.50</version>
</parent>
<artifactId>mage-plugins</artifactId>

View file

@ -6,7 +6,7 @@
<parent>
<groupId>org.mage</groupId>
<artifactId>mage-root</artifactId>
<version>1.4.49</version>
<version>1.4.50</version>
</parent>
<artifactId>mage.server.console</artifactId>

View file

@ -7,7 +7,7 @@
<parent>
<groupId>org.mage</groupId>
<artifactId>mage-server-plugins</artifactId>
<version>1.4.49</version>
<version>1.4.50</version>
</parent>
<artifactId>mage-deck-constructed</artifactId>

View file

@ -7,7 +7,7 @@
<parent>
<groupId>org.mage</groupId>
<artifactId>mage-server-plugins</artifactId>
<version>1.4.49</version>
<version>1.4.50</version>
</parent>
<artifactId>mage-deck-limited</artifactId>

View file

@ -7,7 +7,7 @@
<parent>
<groupId>org.mage</groupId>
<artifactId>mage-server-plugins</artifactId>
<version>1.4.49</version>
<version>1.4.50</version>
</parent>
<artifactId>mage-game-brawlduel</artifactId>

View file

@ -6,7 +6,7 @@
<parent>
<groupId>org.mage</groupId>
<artifactId>mage-server-plugins</artifactId>
<version>1.4.49</version>
<version>1.4.50</version>
</parent>
<artifactId>mage-game-brawlfreeforall</artifactId>

View file

@ -7,7 +7,7 @@
<parent>
<groupId>org.mage</groupId>
<artifactId>mage-server-plugins</artifactId>
<version>1.4.49</version>
<version>1.4.50</version>
</parent>
<artifactId>mage-game-canadianhighlanderduel</artifactId>

View file

@ -7,7 +7,7 @@
<parent>
<groupId>org.mage</groupId>
<artifactId>mage-server-plugins</artifactId>
<version>1.4.49</version>
<version>1.4.50</version>
</parent>
<artifactId>mage-game-commanderduel</artifactId>

View file

@ -6,7 +6,7 @@
<parent>
<groupId>org.mage</groupId>
<artifactId>mage-server-plugins</artifactId>
<version>1.4.49</version>
<version>1.4.50</version>
</parent>
<artifactId>mage-game-commanderfreeforall</artifactId>

View file

@ -7,7 +7,7 @@
<parent>
<groupId>org.mage</groupId>
<artifactId>mage-server-plugins</artifactId>
<version>1.4.49</version>
<version>1.4.50</version>
</parent>
<artifactId>mage-game-freeforall</artifactId>

View file

@ -7,7 +7,7 @@
<parent>
<groupId>org.mage</groupId>
<artifactId>mage-server-plugins</artifactId>
<version>1.4.49</version>
<version>1.4.50</version>
</parent>
<artifactId>mage-game-freeformcommanderduel</artifactId>

View file

@ -6,7 +6,7 @@
<parent>
<groupId>org.mage</groupId>
<artifactId>mage-server-plugins</artifactId>
<version>1.4.49</version>
<version>1.4.50</version>
</parent>
<artifactId>mage-game-freeformcommanderfreeforall</artifactId>

View file

@ -7,7 +7,7 @@
<parent>
<groupId>org.mage</groupId>
<artifactId>mage-server-plugins</artifactId>
<version>1.4.49</version>
<version>1.4.50</version>
</parent>
<artifactId>mage-game-freeformunlimitedcommander</artifactId>
@ -23,7 +23,7 @@
<dependency>
<groupId>org.mage</groupId>
<artifactId>mage-game-freeformcommanderfreeforall</artifactId>
<version>1.4.49</version>
<version>1.4.50</version>
<scope>compile</scope>
</dependency>
</dependencies>

View file

@ -7,7 +7,7 @@
<parent>
<groupId>org.mage</groupId>
<artifactId>mage-server-plugins</artifactId>
<version>1.4.49</version>
<version>1.4.50</version>
</parent>
<artifactId>mage-game-momirduel</artifactId>

View file

@ -7,7 +7,7 @@
<parent>
<groupId>org.mage</groupId>
<artifactId>mage-server-plugins</artifactId>
<version>1.4.49</version>
<version>1.4.50</version>
</parent>
<artifactId>mage-game-momirfreeforall</artifactId>

View file

@ -6,7 +6,7 @@
<parent>
<groupId>org.mage</groupId>
<artifactId>mage-server-plugins</artifactId>
<version>1.4.49</version>
<version>1.4.50</version>
</parent>
<artifactId>mage-game-oathbreakerduel</artifactId>
@ -22,7 +22,7 @@
<dependency>
<groupId>org.mage</groupId>
<artifactId>mage-game-oathbreakerfreeforall</artifactId>
<version>1.4.49</version>
<version>1.4.50</version>
<scope>compile</scope>
</dependency>
</dependencies>

View file

@ -7,7 +7,7 @@
<parent>
<groupId>org.mage</groupId>
<artifactId>mage-server-plugins</artifactId>
<version>1.4.49</version>
<version>1.4.50</version>
</parent>
<artifactId>mage-game-oathbreakerfreeforall</artifactId>

View file

@ -6,7 +6,7 @@
<parent>
<groupId>org.mage</groupId>
<artifactId>mage-server-plugins</artifactId>
<version>1.4.49</version>
<version>1.4.50</version>
</parent>
<artifactId>mage-game-pennydreadfulcommanderfreeforall</artifactId>

View file

@ -7,7 +7,7 @@
<parent>
<groupId>org.mage</groupId>
<artifactId>mage-server-plugins</artifactId>
<version>1.4.49</version>
<version>1.4.50</version>
</parent>
<artifactId>mage-game-tinyleadersduel</artifactId>

View file

@ -7,7 +7,7 @@
<parent>
<groupId>org.mage</groupId>
<artifactId>mage-server-plugins</artifactId>
<version>1.4.49</version>
<version>1.4.50</version>
</parent>
<artifactId>mage-game-twoplayerduel</artifactId>

View file

@ -7,7 +7,7 @@
<parent>
<groupId>org.mage</groupId>
<artifactId>mage-server-plugins</artifactId>
<version>1.4.49</version>
<version>1.4.50</version>
</parent>
<artifactId>mage-player-ai-draftbot</artifactId>

View file

@ -7,7 +7,7 @@
<parent>
<groupId>org.mage</groupId>
<artifactId>mage-server-plugins</artifactId>
<version>1.4.49</version>
<version>1.4.50</version>
</parent>
<artifactId>mage-player-ai-ma</artifactId>

View file

@ -7,7 +7,7 @@
<parent>
<groupId>org.mage</groupId>
<artifactId>mage-server-plugins</artifactId>
<version>1.4.49</version>
<version>1.4.50</version>
</parent>
<artifactId>mage-player-ai</artifactId>

View file

@ -7,7 +7,7 @@
<parent>
<groupId>org.mage</groupId>
<artifactId>mage-server-plugins</artifactId>
<version>1.4.49</version>
<version>1.4.50</version>
</parent>
<artifactId>mage-player-ai-mcts</artifactId>

View file

@ -7,7 +7,7 @@
<parent>
<groupId>org.mage</groupId>
<artifactId>mage-server-plugins</artifactId>
<version>1.4.49</version>
<version>1.4.50</version>
</parent>
<artifactId>mage-player-aiminimax</artifactId>

View file

@ -7,7 +7,7 @@
<parent>
<groupId>org.mage</groupId>
<artifactId>mage-server-plugins</artifactId>
<version>1.4.49</version>
<version>1.4.50</version>
</parent>
<artifactId>mage-player-human</artifactId>

View file

@ -2609,6 +2609,10 @@ public class HumanPlayer extends PlayerImpl {
private boolean gameInCheckPlayableState(Game game, boolean ignoreWarning) {
if (game.inCheckPlayableState()) {
if (!ignoreWarning) {
logger.warn(String.format("Current stack: %d - %s",
game.getStack().size(),
game.getStack().stream().map(Object::toString).collect(Collectors.joining(", "))
));
logger.warn("Player interaction in checkPlayableState", new Throwable());
}
return true;

View file

@ -7,7 +7,7 @@
<parent>
<groupId>org.mage</groupId>
<artifactId>mage-server-plugins</artifactId>
<version>1.4.49</version>
<version>1.4.50</version>
</parent>
<artifactId>mage-tournament-boosterdraft</artifactId>

View file

@ -7,7 +7,7 @@
<parent>
<groupId>org.mage</groupId>
<artifactId>mage-server-plugins</artifactId>
<version>1.4.49</version>
<version>1.4.50</version>
</parent>
<artifactId>mage-tournament-constructed</artifactId>

View file

@ -7,7 +7,7 @@
<parent>
<groupId>org.mage</groupId>
<artifactId>mage-server-plugins</artifactId>
<version>1.4.49</version>
<version>1.4.50</version>
</parent>
<artifactId>mage-tournament-sealed</artifactId>

View file

@ -7,7 +7,7 @@
<parent>
<groupId>org.mage</groupId>
<artifactId>mage-root</artifactId>
<version>1.4.49</version>
<version>1.4.50</version>
</parent>
<artifactId>mage-server-plugins</artifactId>

View file

@ -6,7 +6,7 @@
<parent>
<groupId>org.mage</groupId>
<artifactId>mage-root</artifactId>
<version>1.4.49</version>
<version>1.4.50</version>
</parent>
<artifactId>mage-server</artifactId>

View file

@ -7,7 +7,7 @@
<parent>
<groupId>org.mage</groupId>
<artifactId>mage-root</artifactId>
<version>1.4.49</version>
<version>1.4.50</version>
</parent>
<artifactId>mage-sets</artifactId>

View file

@ -47,7 +47,7 @@ public final class AlibouAncientWitness extends CardImpl {
Ability ability = new AttacksWithCreaturesTriggeredAbility(
new AlibouAncientWitnessEffect(), 1,
StaticFilters.FILTER_PERMANENTS_ARTIFACT_CREATURE
);
).setTriggerPhrase("Whenever one or more artifact creatures you control attack, ");
ability.addTarget(new TargetAnyTarget());
this.addAbility(ability.addHint(AlibouAncientWitnessEffect.getHint()));
}

View file

@ -1,20 +1,20 @@
package mage.cards.a;
import java.util.UUID;
import mage.MageInt;
import mage.abilities.Ability;
import mage.abilities.common.AttacksWithCreaturesTriggeredAbility;
import mage.abilities.effects.OneShotEffect;
import mage.constants.SubType;
import mage.abilities.keyword.FlyingAbility;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.constants.Outcome;
import mage.constants.SubType;
import mage.game.Game;
import mage.players.Player;
import java.util.UUID;
/**
* @author TheElk801
*/
@ -31,7 +31,9 @@ public final class AncestorDragon extends CardImpl {
this.addAbility(FlyingAbility.getInstance());
// Whenever one or more creatures you control attack, you gain 1 life for each attacking creature.
this.addAbility(new AttacksWithCreaturesTriggeredAbility(new AncestorDragonEffect(), 1));
this.addAbility(new AttacksWithCreaturesTriggeredAbility(
new AncestorDragonEffect(), 1
).setTriggerPhrase("Whenever one or more creatures you control attack, "));
}
private AncestorDragon(final AncestorDragon card) {

View file

@ -37,7 +37,9 @@ public final class AngelicGuardian extends CardImpl {
this.addAbility(FlyingAbility.getInstance());
// Whenever one or more creatures you control attack, they gain indestructible until end of turn
this.addAbility(new AttacksWithCreaturesTriggeredAbility(new AngelicGuardianGainEffect(), 1));
this.addAbility(new AttacksWithCreaturesTriggeredAbility(
new AngelicGuardianGainEffect(), 1
).setTriggerPhrase("Whenever one or more creatures you control attack, "));
}
private AngelicGuardian(final AngelicGuardian card) {

View file

@ -84,7 +84,7 @@ class ChaosMoonEffect extends OneShotEffect {
StaticFilters.FILTER_PERMANENT, source.getSourceId(), source.getControllerId(), game
);
// Odd
if (permanentsInPlay % 2 != 0) {
if (permanentsInPlay % 2 == 1) {
game.addEffect(new BoostAllEffect(1, 1, Duration.EndOfTurn, filter, false), source);
new CreateDelayedTriggeredAbilityEffect(new ChaosMoonOddTriggeredAbility()).apply(game, source);
} // Even

View file

@ -9,6 +9,7 @@ import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.constants.SubType;
import mage.constants.TargetController;
import mage.filter.FilterCard;
import java.util.UUID;
@ -36,7 +37,7 @@ public final class ConspicuousSnoop extends CardImpl {
this.addAbility(new SimpleStaticAbility(new PlayWithTheTopCardRevealedEffect()));
// You may cast Goblin spells from the top of your library.
this.addAbility(new SimpleStaticAbility(new PlayTheTopCardEffect(filter, false)));
this.addAbility(new SimpleStaticAbility(new PlayTheTopCardEffect(TargetController.YOU, filter, false)));
// As long as the top card of your library is a Goblin card, Conspicuous Snoop has all activated abilities of that card.
this.addAbility(new SimpleStaticAbility(new GainActivatedAbilitiesOfTopCardEffect(filter.copy().withMessage("a Goblin card"))));

View file

@ -10,6 +10,7 @@ import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.constants.SubType;
import mage.constants.TargetController;
import mage.filter.FilterCard;
import mage.filter.StaticFilters;
import mage.filter.common.FilterLandCard;
@ -34,7 +35,7 @@ public final class CourserOfKruphix extends CardImpl {
this.addAbility(new SimpleStaticAbility(new PlayWithTheTopCardRevealedEffect()));
// You may play lands from the top of your library.
this.addAbility(new SimpleStaticAbility(new PlayTheTopCardEffect(filter, false)));
this.addAbility(new SimpleStaticAbility(new PlayTheTopCardEffect(TargetController.YOU, filter, false)));
// Whenever a land enters the battlefield under your control, you gain 1 life.
this.addAbility(new EntersBattlefieldControlledTriggeredAbility(new GainLifeEffect(1), StaticFilters.FILTER_LAND_A));

View file

@ -1,7 +1,5 @@
package mage.cards.d;
import java.util.Objects;
import java.util.UUID;
import mage.abilities.Ability;
import mage.abilities.TriggeredAbilityImpl;
@ -20,9 +18,7 @@ import mage.constants.Zone;
import mage.counters.CounterType;
import mage.game.Game;
import mage.game.events.GameEvent;
import mage.game.events.GameEvent.EventType;
import mage.game.permanent.Permanent;
import mage.game.stack.StackObject;
import mage.players.Player;
/**
@ -41,7 +37,7 @@ public final class DivineIntervention extends CardImpl {
// At the beginning of your upkeep, remove an intervention counter from Divine Intervention.
this.addAbility(new BeginningOfUpkeepTriggeredAbility(new RemoveCounterSourceEffect(CounterType.INTERVENTION.createInstance()), TargetController.YOU, false));
// Whenever a intervention counter is removed from Protean Hydra, put two intervention counters on it at the beginning of the next end step.
// When you remove the last intervention counter from Divine Intervention, the game is a draw.
this.addAbility(new DivineInterventionAbility());
}
@ -71,38 +67,15 @@ public final class DivineIntervention extends CardImpl {
@Override
public boolean checkEventType(GameEvent event, Game game) {
return event.getType() == GameEvent.EventType.COUNTER_REMOVED;
return event.getType() == GameEvent.EventType.COUNTERS_REMOVED;
}
@Override
public boolean checkTrigger(GameEvent event, Game game) {
if (event.getData().equals(CounterType.INTERVENTION.getName()) && event.getTargetId().equals(this.getSourceId())) {
boolean onlyYouOnStack = true;
boolean onlyOpponentOnStack = true;
UUID you = getControllerId();
boolean firstOnStack = false;
for (StackObject stackObject : game.getStack()) {
if (stackObject.getControllerId() != null && !firstOnStack) {
if (!Objects.equals(you, stackObject.getControllerId())) {
onlyYouOnStack = false;
} else if (Objects.equals(you, stackObject.getControllerId())) {
onlyOpponentOnStack = false;
}
firstOnStack = true;
}
}
if (onlyYouOnStack && !onlyOpponentOnStack) {
return true;
} else if (!onlyYouOnStack && onlyOpponentOnStack) {
return false;
}
}
return false;
return (event.getData().equals(CounterType.INTERVENTION.getName())
&& event.getTargetId().equals(this.getSourceId())
&& event.getPlayerId() != null
&& event.getPlayerId() == this.getControllerId()); // the controller of this removed the counter
}
@Override
@ -131,8 +104,10 @@ public final class DivineIntervention extends CardImpl {
public boolean apply(Game game, Ability source) {
Player controller = game.getPlayer(source.getControllerId());
Permanent sourcePermanent = game.getPermanentOrLKIBattlefield(source.getSourceId());
if (controller != null && sourcePermanent != null) {
if (game.getState().getZone(sourcePermanent.getId()) == Zone.BATTLEFIELD && sourcePermanent.getCounters(game).getCount(CounterType.INTERVENTION) == 0) {
if (controller != null
&& sourcePermanent != null) {
if (game.getState().getZone(sourcePermanent.getId()) == Zone.BATTLEFIELD
&& sourcePermanent.getCounters(game).getCount(CounterType.INTERVENTION) == 0) {
game.setDraw(controller.getId());
}
return true;

View file

@ -9,10 +9,7 @@ import mage.abilities.effects.common.continuous.PlayTheTopCardEffect;
import mage.abilities.keyword.ProwessAbility;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.constants.Duration;
import mage.constants.SubType;
import mage.constants.SuperType;
import mage.constants.*;
import mage.filter.FilterCard;
import mage.filter.common.FilterNonlandCard;
import mage.filter.predicate.Predicates;
@ -29,7 +26,7 @@ public final class ElshaOfTheInfinite extends CardImpl {
static {
filter.add(Predicates.not(CardType.CREATURE.getPredicate()));
filter.add(CardOnTopOfLibraryPredicate.instance);
filter.add(CardOnTopOfLibraryPredicate.YOUR);
}
public ElshaOfTheInfinite(UUID ownerId, CardSetInfo setInfo) {
@ -48,7 +45,7 @@ public final class ElshaOfTheInfinite extends CardImpl {
this.addAbility(new SimpleStaticAbility(new LookAtTopCardOfLibraryAnyTimeEffect()));
// You may cast noncreature spells from the top of your library. If you cast a spell this way, you may cast it as though it had flash.
Ability ability = new SimpleStaticAbility(new PlayTheTopCardEffect(filter, false));
Ability ability = new SimpleStaticAbility(new PlayTheTopCardEffect(TargetController.YOU, filter, false));
ability.addEffect(new CastAsThoughItHadFlashAllEffect(
Duration.WhileOnBattlefield, filter
).setText("If you cast a spell this way, you may cast it as though it had flash."));

View file

@ -63,7 +63,7 @@ class FadeAwayEffect extends OneShotEffect {
String message = "For how many creatures will you pay (up to " + creaturesNumber + ")?";
int payAmount = 0;
boolean paid = false;
while (!paid) {
while (player.canRespond() && !paid) {
payAmount = player.getAmount(0, creaturesNumber, message, game);
ManaCostsImpl cost = new ManaCostsImpl();
cost.add(new GenericManaCost(payAmount));

View file

@ -55,7 +55,7 @@ public final class GaleaKindlerOfHope extends CardImpl {
this.addAbility(new SimpleStaticAbility(new LookAtTopCardOfLibraryAnyTimeEffect()));
// You may cast Aura and Equipment spells from the top of your library. When you cast an Equipment spell this way, it gains "When this Equipment enters the battlefield, attach it to target creature you control."
Ability ability = new SimpleStaticAbility(new PlayTheTopCardEffect(filter, false));
Ability ability = new SimpleStaticAbility(new PlayTheTopCardEffect(TargetController.YOU, filter, false));
ability.addEffect(new InfoEffect("When you cast an Equipment spell this way, it gains " +
"\"When this Equipment enters the battlefield, attach it to target creature you control.\""));
this.addAbility(ability);

View file

@ -9,6 +9,7 @@ import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.constants.SubType;
import mage.constants.TargetController;
import mage.filter.FilterCard;
import mage.filter.common.FilterCreatureCard;
@ -35,7 +36,7 @@ public final class GarruksHorde extends CardImpl {
this.addAbility(new SimpleStaticAbility(new PlayWithTheTopCardRevealedEffect()));
// You may cast creature spells from the top of your library.
this.addAbility(new SimpleStaticAbility(new PlayTheTopCardEffect(filter, false)));
this.addAbility(new SimpleStaticAbility(new PlayTheTopCardEffect(TargetController.YOU, filter, false)));
}
private GarruksHorde(final GarruksHorde card) {

View file

@ -47,7 +47,7 @@ public final class KrydleOfBaldursGate extends CardImpl {
// Whenever you attack, you may pay {2}. If you do, target creature can't be blocked this turn.
ability = new AttacksWithCreaturesTriggeredAbility(new DoIfCostPaid(
new CantBeBlockedTargetEffect(), new GenericManaCost(2)
), 0);
), 1);
ability.addTarget(new TargetCreaturePermanent());
this.addAbility(ability);
}

View file

@ -9,10 +9,7 @@ import mage.abilities.effects.common.continuous.PlayTheTopCardEffect;
import mage.abilities.effects.common.continuous.PlayWithTheTopCardRevealedEffect;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.constants.SubType;
import mage.constants.SuperType;
import mage.constants.Zone;
import mage.constants.*;
import mage.filter.FilterCard;
import mage.filter.predicate.Predicates;
import mage.game.Game;
@ -49,7 +46,7 @@ public final class MelekIzzetParagon extends CardImpl {
this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new PlayWithTheTopCardRevealedEffect()));
// You may cast instant and sorcery spells from the top of your library.
this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new PlayTheTopCardEffect(filter, false)));
this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new PlayTheTopCardEffect(TargetController.YOU, filter, false)));
// Whenever you cast an instant or sorcery spell from your library, copy it. You may choose new targets for the copy.
this.addAbility(new MelekIzzetParagonTriggeredAbility());

View file

@ -12,6 +12,7 @@ import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.constants.Outcome;
import mage.constants.TargetController;
import mage.constants.Zone;
import mage.filter.FilterCard;
import mage.filter.common.FilterNonlandCard;
@ -43,7 +44,7 @@ public final class MysticForge extends CardImpl {
this.addAbility(new SimpleStaticAbility(new LookAtTopCardOfLibraryAnyTimeEffect()));
// You may cast artifact spells and colorless spells from the top of your library.
this.addAbility(new SimpleStaticAbility(new PlayTheTopCardEffect(filter, false)));
this.addAbility(new SimpleStaticAbility(new PlayTheTopCardEffect(TargetController.YOU, filter, false)));
// {T}, Pay 1 life: Exile the top card of your library.
Ability ability = new SimpleActivatedAbility(new MysticForgeExileEffect(), new TapSourceCost());

View file

@ -1,7 +1,7 @@
package mage.cards.n;
import mage.MageInt;
import mage.ObjectColor;
import mage.MageObject;
import mage.abilities.Ability;
import mage.abilities.common.EntersBattlefieldTriggeredAbility;
import mage.abilities.effects.OneShotEffect;
@ -9,15 +9,16 @@ import mage.abilities.keyword.FlyingAbility;
import mage.cards.*;
import mage.constants.*;
import mage.filter.FilterCard;
import mage.filter.predicate.Predicates;
import mage.filter.predicate.mageobject.ColorPredicate;
import mage.filter.predicate.Predicate;
import mage.game.Game;
import mage.players.Player;
import mage.target.TargetCard;
import mage.target.common.TargetCardInLibrary;
import mage.util.CardUtil;
import java.util.HashMap;
import java.util.Map;
import java.util.Objects;
import java.util.UUID;
import java.util.stream.Collectors;
/**
* @author TheElk801
@ -52,64 +53,6 @@ public final class NivMizzetReborn extends CardImpl {
class NivMizzetRebornEffect extends OneShotEffect {
private static enum Guild {
G0("W", "U"), G1("W", "B"), G2("U", "B"), G3("U", "R"), G4("B", "R"),
G5("B", "G"), G6("R", "G"), G7("R", "W"), G8("G", "W"), G9("G", "U");
private static final Map<String, String> nameMap = new HashMap();
static {
nameMap.put("W", "white");
nameMap.put("U", "blue");
nameMap.put("B", "black");
nameMap.put("R", "red");
nameMap.put("G", "green");
}
private final String color1;
private final String color2;
private Guild(String color1, String color2) {
this.color1 = color1;
this.color2 = color2;
}
private FilterCard makeFilter() {
FilterCard filter = new FilterCard(getDescription());
filter.add(new ColorPredicate(new ObjectColor(color1)));
filter.add(new ColorPredicate(new ObjectColor(color2)));
for (char c : getOtherColors().toCharArray()) {
filter.add(Predicates.not(new ColorPredicate(new ObjectColor("" + c))));
}
return filter;
}
private TargetCard getTarget() {
return new TargetCard(Zone.LIBRARY, makeFilter());
}
private String getDescription() {
return "card that is exactly " + nameMap.get(color1) + " and " + nameMap.get(color2);
}
private String getOtherColors() {
String colors = color1 + color2;
String otherColors = "";
for (char c : "WUBRG".toCharArray()) {
if (color1.charAt(0) == c || color2.charAt(0) == c) {
continue;
}
otherColors += c;
}
return otherColors;
}
private boolean isInCards(Cards cards, Game game) {
FilterCard filter = makeFilter();
return cards.getCards(game).stream().anyMatch(card -> filter.match(card, game));
}
}
NivMizzetRebornEffect() {
super(Outcome.Benefit);
staticText = "reveal the top ten cards of your library. For each color pair, "
@ -133,33 +76,73 @@ class NivMizzetRebornEffect extends OneShotEffect {
return false;
}
Cards cards = new CardsImpl(player.getLibrary().getTopCards(game, 10));
game.informPlayers(player.getLogName() + " reveals " +
cards.getCards(game).stream().map(card -> card.getName() + " ").reduce((a, b) -> a + b));
Cards cards2 = new CardsImpl();
game.informPlayers(player.getLogName() + " reveals " + CardUtil.concatWithAnd(
cards.getCards(game).stream().map(MageObject::getName).collect(Collectors.toList())
));
if (cards.isEmpty()) {
return false;
}
player.revealCards(source, cards, game);
for (Guild guild : Guild.values()) {
if (!guild.isInCards(cards, game)) {
continue;
}
TargetCard target = guild.getTarget();
if (player.choose(outcome, cards, target, game)) {
Card card = game.getCard(target.getFirstTarget());
if (card != null) {
cards2.add(card);
}
}
}
cards.removeAll(cards2);
TargetCard target = new NivMizzetRebornTarget();
player.choose(outcome, cards, target, game);
Cards toHand = new CardsImpl(target.getTargets());
player.moveCards(toHand, Zone.HAND, source, game);
game.informPlayers(player.getLogName() + " moves " + CardUtil.concatWithAnd(
toHand.getCards(game).stream().map(MageObject::getName).collect(Collectors.toList())
) + " to hand");
cards.retainZone(Zone.LIBRARY, game);
player.putCardsOnBottomOfLibrary(cards, game, source, false);
if (player.moveCards(cards2, Zone.HAND, source, game)) {
for (Card card : cards2.getCards(game)) {
game.informPlayers(player.getLogName() + " chose " + card.getName() + " and put it into their hand.");
}
}
return true;
}
}
// I think this is my favorite card I've ever implemented
class NivMizzetRebornTarget extends TargetCardInLibrary {
private static enum NivMizzetRebornPredicate implements Predicate<Card> {
instance;
@Override
public boolean apply(Card input, Game game) {
return input.getColor(game).getColorCount() == 2;
}
}
private static final FilterCard filter
= new FilterCard("a card of each color pair");
static {
filter.add(NivMizzetRebornPredicate.instance);
}
NivMizzetRebornTarget() {
super(0, 10, filter);
}
private NivMizzetRebornTarget(final NivMizzetRebornTarget target) {
super(target);
}
@Override
public NivMizzetRebornTarget copy() {
return new NivMizzetRebornTarget(this);
}
@Override
public boolean canTarget(UUID playerId, UUID id, Ability source, Game game) {
if (!super.canTarget(playerId, id, source, game)) {
return false;
}
Card card = game.getCard(id);
if (card == null) {
return false;
}
return this.getTargets().isEmpty()
|| this
.getTargets()
.stream()
.map(game::getCard)
.filter(Objects::nonNull)
.map(c -> c.getColor(game))
.noneMatch(card.getColor(game)::equals);
}
}

View file

@ -10,6 +10,7 @@ import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.constants.Duration;
import mage.constants.SubType;
import mage.constants.TargetController;
import mage.filter.FilterCard;
import mage.filter.common.FilterLandCard;
@ -39,7 +40,7 @@ public final class OracleOfMulDaya extends CardImpl {
this.addAbility(new SimpleStaticAbility(new PlayWithTheTopCardRevealedEffect()));
// You may play lands from the top of your library.
this.addAbility(new SimpleStaticAbility(new PlayTheTopCardEffect(filter, false)));
this.addAbility(new SimpleStaticAbility(new PlayTheTopCardEffect(TargetController.YOU, filter, false)));
}
private OracleOfMulDaya(final OracleOfMulDaya card) {

View file

@ -68,7 +68,7 @@ public final class PaladinClass extends CardImpl {
new BoostTargetEffect(xValue, xValue, Duration.EndOfTurn, true)
.setText("until end of turn, target attacking creature " +
"gets +1/+1 for each other attacking creature"),
0
1
);
ability.addEffect(new GainAbilityTargetEffect(
DoubleStrikeAbility.getInstance(), Duration.EndOfTurn

View file

@ -1,25 +1,25 @@
package mage.cards.p;
import java.util.UUID;
import mage.abilities.Ability;
import mage.abilities.common.AttacksWithCreaturesTriggeredAbility;
import mage.abilities.common.SimpleStaticAbility;
import mage.abilities.condition.Condition;
import mage.abilities.decorator.ConditionalContinuousEffect;
import mage.abilities.effects.OneShotEffect;
import mage.abilities.dynamicvalue.DynamicValue;
import mage.abilities.dynamicvalue.common.AttackingCreatureCount;
import mage.abilities.effects.common.GainLifeEffect;
import mage.abilities.effects.common.continuous.BoostAllEffect;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.constants.Duration;
import mage.constants.Outcome;
import mage.constants.TargetController;
import mage.constants.Zone;
import mage.filter.common.FilterCreaturePermanent;
import mage.game.Game;
import mage.players.Player;
import java.util.UUID;
/**
* @author jeffwadsworth
*/
@ -32,16 +32,20 @@ public final class PathOfBravery extends CardImpl {
}
static final String rule = "As long as your life total is greater than or equal to your starting life total, creatures you control get +1/+1";
private static final DynamicValue xValue = new AttackingCreatureCount();
public PathOfBravery(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{2}{W}");
// As long as your life total is greater than or equal to your starting life total, creatures you control get +1/+1.
this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new ConditionalContinuousEffect(new BoostAllEffect(1, 1, Duration.WhileOnBattlefield, filter, true), LifeCondition.instance, rule)));
this.addAbility(new SimpleStaticAbility(new ConditionalContinuousEffect(new BoostAllEffect(
1, 1, Duration.WhileOnBattlefield, filter, true
), LifeCondition.instance, rule)));
// Whenever one or more creatures you control attack, you gain life equal to the number of attacking creatures.
this.addAbility(new AttacksWithCreaturesTriggeredAbility(new PathOfBraveryEffect(), 1));
this.addAbility(new AttacksWithCreaturesTriggeredAbility(new GainLifeEffect(
xValue, "you gain life equal to the number of attacking creatures"
), 1).setTriggerPhrase("Whenever one or more creatures you control attack, "));
}
private PathOfBravery(final PathOfBravery card) {
@ -67,34 +71,3 @@ enum LifeCondition implements Condition {
return false;
}
}
class PathOfBraveryEffect extends OneShotEffect {
private int attackers;
public PathOfBraveryEffect() {
super(Outcome.GainLife);
staticText = "you gain life equal to the number of attacking creatures";
}
public PathOfBraveryEffect(final PathOfBraveryEffect effect) {
super(effect);
}
@Override
public PathOfBraveryEffect copy() {
return new PathOfBraveryEffect(this);
}
@Override
public boolean apply(Game game, Ability source) {
Player you = game.getPlayer(source.getControllerId());
attackers = game.getCombat().getAttackers().size();
if (you != null) {
you.gainLife(attackers, game, source);
attackers = 0;
return true;
}
return false;
}
}

View file

@ -82,7 +82,7 @@ public final class PlarggDeanOfChaos extends ModalDoubleFacesCard {
// Whenever you attack, untap each creature you control, then tap any number of creatures you control.
AttacksWithCreaturesTriggeredAbility augustaAbility = new AttacksWithCreaturesTriggeredAbility(
new UntapAllControllerEffect(StaticFilters.FILTER_PERMANENT_CREATURES, "untap each creature you control"), 0);
new UntapAllControllerEffect(StaticFilters.FILTER_PERMANENT_CREATURES, "untap each creature you control"), 1);
augustaAbility.addEffect(new AugustaDeanOfOrderEffect().concatBy(", then"));
this.getRightHalfCard().addAbility(augustaAbility);
}

View file

@ -12,6 +12,7 @@ import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.constants.Outcome;
import mage.constants.TargetController;
import mage.constants.Zone;
import mage.filter.FilterCard;
import mage.filter.predicate.Predicates;
@ -41,7 +42,7 @@ public final class PrecognitionField extends CardImpl {
this.addAbility(new SimpleStaticAbility(new LookAtTopCardOfLibraryAnyTimeEffect()));
// You may cast instant and sorcery spells from the top of your library.
this.addAbility(new SimpleStaticAbility(new PlayTheTopCardEffect(filter, false)));
this.addAbility(new SimpleStaticAbility(new PlayTheTopCardEffect(TargetController.YOU, filter, false)));
// {3}: Exile the top card of your library.
this.addAbility(new SimpleActivatedAbility(new PrecognitionFieldExileEffect(), new GenericManaCost(3)));

View file

@ -16,10 +16,7 @@ import mage.abilities.hint.common.MyTurnHint;
import mage.abilities.keyword.FirstStrikeAbility;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.constants.Duration;
import mage.constants.SubType;
import mage.constants.SuperType;
import mage.constants.*;
import mage.filter.FilterCard;
import mage.filter.StaticFilters;
import mage.filter.common.FilterLandCard;
@ -51,7 +48,7 @@ public final class RadhaHeartOfKeld extends CardImpl {
// You may look at the top card of your library any time, and you may play lands from the top of your library.
LookAtTopCardOfLibraryAnyTimeEffect lookEffect = new LookAtTopCardOfLibraryAnyTimeEffect();
lookEffect.setText("You may look at the top card of your library any time");
PlayTheTopCardEffect playEffect = new PlayTheTopCardEffect(filter, false);
PlayTheTopCardEffect playEffect = new PlayTheTopCardEffect(TargetController.YOU, filter, false);
playEffect.setText(", and you may play lands from the top of your library");
SimpleStaticAbility lookAndPlayAbility = new SimpleStaticAbility(lookEffect);

View file

@ -1,4 +1,3 @@
package mage.cards.r;
import mage.MageObject;
@ -33,7 +32,6 @@ import java.util.UUID;
import java.util.stream.Collectors;
/**
*
* @author L_J
*/
public final class RagingRiver extends CardImpl {
@ -42,7 +40,9 @@ public final class RagingRiver extends CardImpl {
super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{R}{R}");
// Whenever one or more creatures you control attack, each defending player divides all creatures without flying they control into a "left" pile and a "right" pile. Then, for each attacking creature you control, choose "left" or "right." That creature can't be blocked this combat except by creatures with flying and creatures in a pile with the chosen label.
this.addAbility(new AttacksWithCreaturesTriggeredAbility(new RagingRiverEffect(), 1));
this.addAbility(new AttacksWithCreaturesTriggeredAbility(
new RagingRiverEffect(), 1
).setTriggerPhrase("Whenever one or more creatures you control attack, "));
}
private RagingRiver(final RagingRiver card) {
@ -92,8 +92,7 @@ class RagingRiverEffect extends OneShotEffect {
if (target.getTargets().contains(permanent.getId())) {
left.add(permanent);
leftLog.add(permanent);
}
else if (filterBlockers.match(permanent, source.getSourceId(), defenderId, game)) {
} else if (filterBlockers.match(permanent, source.getSourceId(), defenderId, game)) {
right.add(permanent);
rightLog.add(permanent);
}

View file

@ -15,6 +15,7 @@ import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.constants.SubType;
import mage.constants.TargetController;
import mage.counters.CounterType;
import mage.filter.FilterCard;
import mage.filter.common.FilterCreatureCard;
@ -46,7 +47,7 @@ public final class RangerClass extends CardImpl {
// Whenever you attack, put a +1/+1 counter on target attacking creature.
Ability ability = new AttacksWithCreaturesTriggeredAbility(
new AddCountersTargetEffect(CounterType.P1P1.createInstance()), 0
new AddCountersTargetEffect(CounterType.P1P1.createInstance()), 1
);
ability.addTarget(new TargetAttackingCreature());
this.addAbility(new SimpleStaticAbility(new GainClassAbilitySourceEffect(ability, 2)));
@ -61,7 +62,7 @@ public final class RangerClass extends CardImpl {
// You may cast creature spells from the top of your library.
this.addAbility(new SimpleStaticAbility(new GainClassAbilitySourceEffect(
new PlayTheTopCardEffect(filter, false), 3
new PlayTheTopCardEffect(TargetController.YOU, filter, false), 3
)));
}

View file

@ -12,6 +12,7 @@ import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.constants.Outcome;
import mage.constants.SubType;
import mage.constants.TargetController;
import mage.filter.common.FilterCreatureCard;
import mage.filter.predicate.mageobject.ChosenSubtypePredicate;
@ -45,7 +46,7 @@ public final class Realmwalker extends CardImpl {
this.addAbility(new SimpleStaticAbility(new LookAtTopCardOfLibraryAnyTimeEffect()));
// You may cast creature spells of the chosen type from the top of your library.
this.addAbility(new SimpleStaticAbility(new PlayTheTopCardEffect(filter, false)));
this.addAbility(new SimpleStaticAbility(new PlayTheTopCardEffect(TargetController.YOU, filter, false)));
}
private Realmwalker(final Realmwalker card) {

View file

@ -84,13 +84,12 @@ class ShroudedLoreEffect extends OneShotEffect {
}
if (!done) {
done = true;
if (cost.canPay(source, source, you.getId(), game) && you.chooseUse(Outcome.Benefit, "Pay {B} to choose a different card ?", source, game)) {
cost.clearPaid();
if (!cost.pay(source, game, source, you.getId(), false, null)) {
done = true;
if (cost.pay(source, game, source, you.getId(), false, null)) {
done = false;
}
} else {
done = true;
}
}

View file

@ -29,7 +29,7 @@ public final class SparringRegimen extends CardImpl {
// Whenever you attack, put a +1/+1 counter on target attacking creature and untap it.
Ability ability = new AttacksWithCreaturesTriggeredAbility(
new AddCountersTargetEffect(CounterType.P1P1.createInstance()), 0
new AddCountersTargetEffect(CounterType.P1P1.createInstance()), 1
);
ability.addEffect(new UntapTargetEffect().setText("and untap it"));
ability.addTarget(new TargetAttackingCreature());

View file

@ -23,7 +23,7 @@ public final class ThoroughInvestigation extends CardImpl {
super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{2}{W}");
// Whenever you attack, investigate.
this.addAbility(new AttacksWithCreaturesTriggeredAbility(new InvestigateEffect(), 0));
this.addAbility(new AttacksWithCreaturesTriggeredAbility(new InvestigateEffect(), 1));
// Whenever you sacrifice a Clue, venture into the dungeon.
this.addAbility(new SacrificePermanentTriggeredAbility(new VentureIntoTheDungeonEffect(), filter));

View file

@ -10,6 +10,7 @@ import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.constants.SubType;
import mage.constants.TargetController;
import mage.constants.Zone;
import mage.filter.FilterCard;
import mage.filter.StaticFilters;
@ -58,7 +59,7 @@ class VergeRangersEffect extends PlayTheTopCardEffect {
private static final FilterCard filter = new FilterLandCard("play lands");
public VergeRangersEffect() {
super(filter, false);
super(TargetController.YOU, filter, false);
staticText = "As long as an opponent controls more lands than you, you may play lands from the top of your library";
}

View file

@ -52,7 +52,7 @@ public final class VivienMonstersAdvocate extends CardImpl {
this.addAbility(new SimpleStaticAbility(new LookAtTopCardOfLibraryAnyTimeEffect()));
// You may cast creature spells from the top of your library.
this.addAbility(new SimpleStaticAbility(new PlayTheTopCardEffect(filter, false)));
this.addAbility(new SimpleStaticAbility(new PlayTheTopCardEffect(TargetController.YOU, filter, false)));
// +1: Create a 3/3 green Beast creature token. Put your choice of a vigilance
// counter, a reach counter, or a trample counter on it.

View file

@ -37,7 +37,7 @@ public final class VizierOfTheMenagerie extends CardImpl {
this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new LookAtTopCardOfLibraryAnyTimeEffect()));
// You may cast creature spells from the top of your library.
this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new PlayTheTopCardEffect(filter, false)));
this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new PlayTheTopCardEffect(TargetController.YOU, filter, false)));
// You may spend mana as though it were mana of any type to cast creature spells.
this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new VizierOfTheMenagerieManaEffect()));

View file

@ -0,0 +1,185 @@
package mage.cards.x;
import mage.MageInt;
import mage.MageObject;
import mage.abilities.Ability;
import mage.abilities.common.BeginningOfUpkeepTriggeredAbility;
import mage.abilities.effects.AsThoughEffectImpl;
import mage.abilities.effects.AsThoughManaEffect;
import mage.abilities.effects.ContinuousRuleModifyingEffectImpl;
import mage.abilities.effects.OneShotEffect;
import mage.abilities.effects.common.continuous.LookAtTopCardOfLibraryAnyTimeTargetEffect;
import mage.abilities.effects.common.continuous.PlayTheTopCardTargetEffect;
import mage.cards.Card;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.*;
import mage.game.Game;
import mage.game.events.GameEvent;
import mage.players.ManaPoolItem;
import mage.players.Player;
import mage.target.common.TargetOpponent;
import mage.target.targetpointer.FixedTarget;
import mage.util.CardUtil;
import java.util.Objects;
import java.util.UUID;
/**
* @author raphael-schulz
*/
public final class XanatharGuildKingpin extends CardImpl {
public XanatharGuildKingpin(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{4}{U}{B}");
addSuperType(SuperType.LEGENDARY);
this.subtype.add(SubType.BEHOLDER);
this.power = new MageInt(5);
this.toughness = new MageInt(6);
// At the beginning of your upkeep, choose target opponent. Until end of turn, that player cant cast spells, you may look at the top card of their library any time, you may play the top card of their library, and you may spend mana as though it were mana of any color to cast spells this way.
Ability ability = new BeginningOfUpkeepTriggeredAbility(
Zone.BATTLEFIELD, new XanatharGuildKingpinRuleModifyingEffect()
.setText("choose target opponent. Until end of turn, that player can't cast spells,"),
TargetController.YOU, false
);
ability.addEffect(new LookAtTopCardOfLibraryAnyTimeTargetEffect(Duration.EndOfTurn)
.setText(" you may look at the top card of their library any time,"));
ability.addEffect(new PlayTheTopCardTargetEffect()
.setText(" you may play the top card of their library,"));
ability.addEffect(new XanatharGuildKingpinSpendManaAsAnyColorOneShotEffect()
.setText(" and you may spend mana as thought it were mana of any color to cast spells this way"));
ability.addCustomOutcome(Outcome.PreventCast);
ability.addTarget(new TargetOpponent());
this.addAbility(ability);
}
private XanatharGuildKingpin(final XanatharGuildKingpin card) {
super(card);
}
@Override
public XanatharGuildKingpin copy() {
return new XanatharGuildKingpin(this);
}
}
class XanatharGuildKingpinRuleModifyingEffect extends ContinuousRuleModifyingEffectImpl {
public XanatharGuildKingpinRuleModifyingEffect() {
super(Duration.EndOfTurn, Outcome.Benefit);
}
private XanatharGuildKingpinRuleModifyingEffect(final XanatharGuildKingpinRuleModifyingEffect effect) {
super(effect);
}
@Override
public XanatharGuildKingpinRuleModifyingEffect copy() {
return new XanatharGuildKingpinRuleModifyingEffect(this);
}
@Override
public boolean apply(Game game, Ability source) {
return true;
}
@Override
public String getInfoMessage(Ability source, GameEvent event, Game game) {
Player targetPlayer = game.getPlayer(getTargetPointer().getFirst(game, source));
MageObject mageObject = game.getObject(source.getSourceId());
if (targetPlayer != null && mageObject != null) {
return "This turn you can't cast spells" +
" (" + mageObject.getLogName() + ')';
}
return null;
}
@Override
public boolean checksEventType(GameEvent event, Game game) {
return event.getType() == GameEvent.EventType.CAST_SPELL;
}
@Override
public boolean applies(GameEvent event, Ability source, Game game) {
return event.getPlayerId().equals(getTargetPointer().getFirst(game, source));
}
}
class XanatharGuildKingpinSpendManaAsAnyColorOneShotEffect extends OneShotEffect {
public XanatharGuildKingpinSpendManaAsAnyColorOneShotEffect() {
super(Outcome.Benefit);
}
private XanatharGuildKingpinSpendManaAsAnyColorOneShotEffect(final XanatharGuildKingpinSpendManaAsAnyColorOneShotEffect effect) {
super(effect);
}
@Override
public boolean apply(Game game, Ability source) {
Card topCard = game.getPlayer(source.getFirstTarget()).getLibrary().getFromTop(game);
if (topCard == null) {
return false;
}
int zcc = game.getState().getZoneChangeCounter(topCard.getId());
game.addEffect(new SpendManaAsAnyColorToCastTopOfLibraryTargetEffect().setTargetPointer(new FixedTarget(topCard.getId(), zcc)), source);
return true;
}
@Override
public XanatharGuildKingpinSpendManaAsAnyColorOneShotEffect copy() {
return new XanatharGuildKingpinSpendManaAsAnyColorOneShotEffect(this);
}
}
class SpendManaAsAnyColorToCastTopOfLibraryTargetEffect extends AsThoughEffectImpl implements AsThoughManaEffect {
public SpendManaAsAnyColorToCastTopOfLibraryTargetEffect() {
super(AsThoughEffectType.SPEND_OTHER_MANA, Duration.EndOfTurn, Outcome.Benefit);
}
public SpendManaAsAnyColorToCastTopOfLibraryTargetEffect(final SpendManaAsAnyColorToCastTopOfLibraryTargetEffect effect) {
super(effect);
}
@Override
public boolean apply(Game game, Ability source) {
return true;
}
@Override
public SpendManaAsAnyColorToCastTopOfLibraryTargetEffect copy() {
return new SpendManaAsAnyColorToCastTopOfLibraryTargetEffect(this);
}
@Override
public boolean applies(UUID objectId, Ability source, UUID affectedControllerId, Game game) {
FixedTarget fixedTarget = ((FixedTarget) getTargetPointer());
UUID targetId = CardUtil.getMainCardId(game, fixedTarget.getTarget());
Card topCard = game.getPlayer(source.getFirstTarget()).getLibrary().getFromTop(game);
if (topCard == null) {
return false;
}
// If top card of target opponent's library changed, discard the current ContinuousEffect and create a new one
if (!topCard.getId().equals(targetId) && canLookAtNextTopLibraryCard(game) && !this.isDiscarded()) {
int zcc = game.getState().getZoneChangeCounter(topCard.getId());
game.addEffect(new SpendManaAsAnyColorToCastTopOfLibraryTargetEffect().setTargetPointer(new FixedTarget(topCard.getId(), zcc)), source);
this.discard();
}
return source.isControlledBy(affectedControllerId)
&& Objects.equals(objectId, targetId)
&& game.getState().getZoneChangeCounter(objectId) <= fixedTarget.getZoneChangeCounter() + 1
&& (game.getState().getZone(objectId) == Zone.STACK || game.getState().getZone(objectId) == Zone.LIBRARY);
}
@Override
public ManaType getAsThoughManaType(ManaType manaType, ManaPoolItem mana, UUID affectedControllerId, Ability source, Game game) {
return mana.getFirstAvailable();
}
}

View file

@ -23,8 +23,7 @@ public final class AdventuresInTheForgottenRealms extends ExpansionSet {
}
private AdventuresInTheForgottenRealms() {
super("Adventures in the Forgotten Realms", "AFR", ExpansionSet.buildDate(2021, 7, 23), SetType.EXPANSION);
// TODO: add collation object when set is fully implemented
super("Adventures in the Forgotten Realms", "AFR", ExpansionSet.buildDate(2021, 7, 23), SetType.EXPANSION, new AdventuresInTheForgottenRealmsCollator());
this.blockName = "Adventures in the Forgotten Realms";
this.hasBoosters = true;
this.hasBasicLands = true;
@ -35,182 +34,277 @@ public final class AdventuresInTheForgottenRealms extends ExpansionSet {
cards.add(new SetCardInfo("+2 Mace", 1, Rarity.COMMON, mage.cards.p.Plus2Mace.class));
cards.add(new SetCardInfo("Aberrant Mind Sorcerer", 44, Rarity.UNCOMMON, mage.cards.a.AberrantMindSorcerer.class));
cards.add(new SetCardInfo("Acererak the Archlich", 87, Rarity.MYTHIC, mage.cards.a.AcererakTheArchlich.class));
cards.add(new SetCardInfo("Adult Gold Dragon", 216, Rarity.RARE, mage.cards.a.AdultGoldDragon.class));
cards.add(new SetCardInfo("Acererak the Archlich", 372, Rarity.MYTHIC, mage.cards.a.AcererakTheArchlich.class, NON_FULL_USE_VARIOUS));
cards.add(new SetCardInfo("Acererak the Archlich", 87, Rarity.MYTHIC, mage.cards.a.AcererakTheArchlich.class, NON_FULL_USE_VARIOUS));
cards.add(new SetCardInfo("Adult Gold Dragon", 216, Rarity.RARE, mage.cards.a.AdultGoldDragon.class, NON_FULL_USE_VARIOUS));
cards.add(new SetCardInfo("Adult Gold Dragon", 297, Rarity.RARE, mage.cards.a.AdultGoldDragon.class, NON_FULL_USE_VARIOUS));
cards.add(new SetCardInfo("Air-Cult Elemental", 45, Rarity.COMMON, mage.cards.a.AirCultElemental.class));
cards.add(new SetCardInfo("Arborea Pegasus", 2, Rarity.COMMON, mage.cards.a.ArboreaPegasus.class));
cards.add(new SetCardInfo("Arborea Pegasus", 2, Rarity.COMMON, mage.cards.a.ArboreaPegasus.class, NON_FULL_USE_VARIOUS));
cards.add(new SetCardInfo("Arborea Pegasus", 299, Rarity.COMMON, mage.cards.a.ArboreaPegasus.class, NON_FULL_USE_VARIOUS));
cards.add(new SetCardInfo("Arcane Investigator", 46, Rarity.COMMON, mage.cards.a.ArcaneInvestigator.class));
cards.add(new SetCardInfo("Armory Veteran", 130, Rarity.COMMON, mage.cards.a.ArmoryVeteran.class));
cards.add(new SetCardInfo("Asmodeus the Archfiend", 88, Rarity.RARE, mage.cards.a.AsmodeusTheArchfiend.class));
cards.add(new SetCardInfo("Asmodeus the Archfiend", 373, Rarity.RARE, mage.cards.a.AsmodeusTheArchfiend.class, NON_FULL_USE_VARIOUS));
cards.add(new SetCardInfo("Asmodeus the Archfiend", 88, Rarity.RARE, mage.cards.a.AsmodeusTheArchfiend.class, NON_FULL_USE_VARIOUS));
cards.add(new SetCardInfo("Bag of Holding", 240, Rarity.UNCOMMON, mage.cards.b.BagOfHolding.class));
cards.add(new SetCardInfo("Baleful Beholder", 89, Rarity.COMMON, mage.cards.b.BalefulBeholder.class));
cards.add(new SetCardInfo("Baleful Beholder", 311, Rarity.COMMON, mage.cards.b.BalefulBeholder.class, NON_FULL_USE_VARIOUS));
cards.add(new SetCardInfo("Baleful Beholder", 89, Rarity.COMMON, mage.cards.b.BalefulBeholder.class, NON_FULL_USE_VARIOUS));
cards.add(new SetCardInfo("Bar the Gate", 47, Rarity.COMMON, mage.cards.b.BarTheGate.class));
cards.add(new SetCardInfo("Barbarian Class", 131, Rarity.UNCOMMON, mage.cards.b.BarbarianClass.class));
cards.add(new SetCardInfo("Bard Class", 217, Rarity.RARE, mage.cards.b.BardClass.class));
cards.add(new SetCardInfo("Barrowin of Clan Undurr", 218, Rarity.UNCOMMON, mage.cards.b.BarrowinOfClanUndurr.class));
cards.add(new SetCardInfo("Barrowin of Clan Undurr", 218, Rarity.UNCOMMON, mage.cards.b.BarrowinOfClanUndurr.class, NON_FULL_USE_VARIOUS));
cards.add(new SetCardInfo("Barrowin of Clan Undurr", 336, Rarity.UNCOMMON, mage.cards.b.BarrowinOfClanUndurr.class, NON_FULL_USE_VARIOUS));
cards.add(new SetCardInfo("Battle Cry Goblin", 132, Rarity.UNCOMMON, mage.cards.b.BattleCryGoblin.class));
cards.add(new SetCardInfo("Black Dragon", 90, Rarity.UNCOMMON, mage.cards.b.BlackDragon.class));
cards.add(new SetCardInfo("Brazen Dwarf", 134, Rarity.COMMON, mage.cards.b.BrazenDwarf.class));
cards.add(new SetCardInfo("Blink Dog", 3, Rarity.UNCOMMON, mage.cards.b.BlinkDog.class));
cards.add(new SetCardInfo("Blue Dragon", 49, Rarity.UNCOMMON, mage.cards.b.BlueDragon.class));
cards.add(new SetCardInfo("Black Dragon", 291, Rarity.UNCOMMON, mage.cards.b.BlackDragon.class, NON_FULL_USE_VARIOUS));
cards.add(new SetCardInfo("Black Dragon", 90, Rarity.UNCOMMON, mage.cards.b.BlackDragon.class, NON_FULL_USE_VARIOUS));
cards.add(new SetCardInfo("Blink Dog", 3, Rarity.UNCOMMON, mage.cards.b.BlinkDog.class, NON_FULL_USE_VARIOUS));
cards.add(new SetCardInfo("Blink Dog", 300, Rarity.UNCOMMON, mage.cards.b.BlinkDog.class, NON_FULL_USE_VARIOUS));
cards.add(new SetCardInfo("Blue Dragon", 289, Rarity.UNCOMMON, mage.cards.b.BlueDragon.class, NON_FULL_USE_VARIOUS));
cards.add(new SetCardInfo("Blue Dragon", 49, Rarity.UNCOMMON, mage.cards.b.BlueDragon.class, NON_FULL_USE_VARIOUS));
cards.add(new SetCardInfo("Boots of Speed", 133, Rarity.COMMON, mage.cards.b.BootsOfSpeed.class));
cards.add(new SetCardInfo("Bruenor Battlehammer", 219, Rarity.UNCOMMON, mage.cards.b.BruenorBattlehammer.class));
cards.add(new SetCardInfo("Bulette", 173, Rarity.COMMON, mage.cards.b.Bulette.class));
cards.add(new SetCardInfo("Brazen Dwarf", 134, Rarity.COMMON, mage.cards.b.BrazenDwarf.class));
cards.add(new SetCardInfo("Bruenor Battlehammer", 219, Rarity.UNCOMMON, mage.cards.b.BruenorBattlehammer.class, NON_FULL_USE_VARIOUS));
cards.add(new SetCardInfo("Bruenor Battlehammer", 337, Rarity.UNCOMMON, mage.cards.b.BruenorBattlehammer.class, NON_FULL_USE_VARIOUS));
cards.add(new SetCardInfo("Bulette", 173, Rarity.COMMON, mage.cards.b.Bulette.class, NON_FULL_USE_VARIOUS));
cards.add(new SetCardInfo("Bulette", 324, Rarity.COMMON, mage.cards.b.Bulette.class, NON_FULL_USE_VARIOUS));
cards.add(new SetCardInfo("Bull's Strength", 174, Rarity.COMMON, mage.cards.b.BullsStrength.class));
cards.add(new SetCardInfo("Burning Hands", 135, Rarity.UNCOMMON, mage.cards.b.BurningHands.class));
cards.add(new SetCardInfo("Cave of the Frost Dragon", 253, Rarity.RARE, mage.cards.c.CaveOfTheFrostDragon.class));
cards.add(new SetCardInfo("Celestial Unicorn", 5, Rarity.COMMON, mage.cards.c.CelestialUnicorn.class));
cards.add(new SetCardInfo("Cave of the Frost Dragon", 253, Rarity.RARE, mage.cards.c.CaveOfTheFrostDragon.class, NON_FULL_USE_VARIOUS));
cards.add(new SetCardInfo("Cave of the Frost Dragon", 350, Rarity.RARE, mage.cards.c.CaveOfTheFrostDragon.class, NON_FULL_USE_VARIOUS));
cards.add(new SetCardInfo("Celestial Unicorn", 301, Rarity.COMMON, mage.cards.c.CelestialUnicorn.class, NON_FULL_USE_VARIOUS));
cards.add(new SetCardInfo("Celestial Unicorn", 5, Rarity.COMMON, mage.cards.c.CelestialUnicorn.class, NON_FULL_USE_VARIOUS));
cards.add(new SetCardInfo("Chaos Channeler", 136, Rarity.UNCOMMON, mage.cards.c.ChaosChanneler.class));
cards.add(new SetCardInfo("Charmed Sleep", 50, Rarity.COMMON, mage.cards.c.CharmedSleep.class));
cards.add(new SetCardInfo("Check for Traps", 92, Rarity.UNCOMMON, mage.cards.c.CheckForTraps.class));
cards.add(new SetCardInfo("Choose Your Weapon", 175, Rarity.UNCOMMON, mage.cards.c.ChooseYourWeapon.class));
cards.add(new SetCardInfo("Circle of Dreams Druid", 176, Rarity.RARE, mage.cards.c.CircleOfDreamsDruid.class));
cards.add(new SetCardInfo("Circle of Dreams Druid", 176, Rarity.RARE, mage.cards.c.CircleOfDreamsDruid.class, NON_FULL_USE_VARIOUS));
cards.add(new SetCardInfo("Circle of Dreams Druid", 383, Rarity.RARE, mage.cards.c.CircleOfDreamsDruid.class, NON_FULL_USE_VARIOUS));
cards.add(new SetCardInfo("Circle of the Moon Druid", 177, Rarity.COMMON, mage.cards.c.CircleOfTheMoonDruid.class));
cards.add(new SetCardInfo("Clattering Skeletons", 93, Rarity.COMMON, mage.cards.c.ClatteringSkeletons.class));
cards.add(new SetCardInfo("Clattering Skeletons", 312, Rarity.COMMON, mage.cards.c.ClatteringSkeletons.class, NON_FULL_USE_VARIOUS));
cards.add(new SetCardInfo("Clattering Skeletons", 93, Rarity.COMMON, mage.cards.c.ClatteringSkeletons.class, NON_FULL_USE_VARIOUS));
cards.add(new SetCardInfo("Cleric Class", 6, Rarity.UNCOMMON, mage.cards.c.ClericClass.class));
cards.add(new SetCardInfo("Clever Conjurer", 51, Rarity.COMMON, mage.cards.c.CleverConjurer.class));
cards.add(new SetCardInfo("Cloister Gargoyle", 7, Rarity.UNCOMMON, mage.cards.c.CloisterGargoyle.class));
cards.add(new SetCardInfo("Cloister Gargoyle", 302, Rarity.UNCOMMON, mage.cards.c.CloisterGargoyle.class, NON_FULL_USE_VARIOUS));
cards.add(new SetCardInfo("Cloister Gargoyle", 7, Rarity.UNCOMMON, mage.cards.c.CloisterGargoyle.class, NON_FULL_USE_VARIOUS));
cards.add(new SetCardInfo("Compelled Duel", 178, Rarity.COMMON, mage.cards.c.CompelledDuel.class));
cards.add(new SetCardInfo("Contact Other Plane", 52, Rarity.COMMON, mage.cards.c.ContactOtherPlane.class));
cards.add(new SetCardInfo("Critical Hit", 137, Rarity.UNCOMMON, mage.cards.c.CriticalHit.class));
cards.add(new SetCardInfo("Dancing Sword", 8, Rarity.RARE, mage.cards.d.DancingSword.class));
cards.add(new SetCardInfo("Dancing Sword", 360, Rarity.RARE, mage.cards.d.DancingSword.class, NON_FULL_USE_VARIOUS));
cards.add(new SetCardInfo("Dancing Sword", 8, Rarity.RARE, mage.cards.d.DancingSword.class, NON_FULL_USE_VARIOUS));
cards.add(new SetCardInfo("Dawnbringer Cleric", 9, Rarity.COMMON, mage.cards.d.DawnbringerCleric.class));
cards.add(new SetCardInfo("Deadly Dispute", 94, Rarity.COMMON, mage.cards.d.DeadlyDispute.class));
cards.add(new SetCardInfo("Death-Priest of Myrkul", 95, Rarity.UNCOMMON, mage.cards.d.DeathPriestOfMyrkul.class));
cards.add(new SetCardInfo("Delina, Wild Mage", 138, Rarity.RARE, mage.cards.d.DelinaWildMage.class));
cards.add(new SetCardInfo("Delina, Wild Mage", 138, Rarity.RARE, mage.cards.d.DelinaWildMage.class, NON_FULL_USE_VARIOUS));
cards.add(new SetCardInfo("Delina, Wild Mage", 317, Rarity.RARE, mage.cards.d.DelinaWildMage.class, NON_FULL_USE_VARIOUS));
cards.add(new SetCardInfo("Delver's Torch", 10, Rarity.COMMON, mage.cards.d.DelversTorch.class));
cards.add(new SetCardInfo("Demilich", 53, Rarity.MYTHIC, mage.cards.d.Demilich.class));
cards.add(new SetCardInfo("Demilich", 366, Rarity.MYTHIC, mage.cards.d.Demilich.class, NON_FULL_USE_VARIOUS));
cards.add(new SetCardInfo("Demilich", 53, Rarity.MYTHIC, mage.cards.d.Demilich.class, NON_FULL_USE_VARIOUS));
cards.add(new SetCardInfo("Demogorgon's Clutches", 96, Rarity.UNCOMMON, mage.cards.d.DemogorgonsClutches.class));
cards.add(new SetCardInfo("Den of the Bugbear", 254, Rarity.RARE, mage.cards.d.DenOfTheBugbear.class));
cards.add(new SetCardInfo("Den of the Bugbear", 254, Rarity.RARE, mage.cards.d.DenOfTheBugbear.class, NON_FULL_USE_VARIOUS));
cards.add(new SetCardInfo("Den of the Bugbear", 351, Rarity.RARE, mage.cards.d.DenOfTheBugbear.class, NON_FULL_USE_VARIOUS));
cards.add(new SetCardInfo("Devoted Paladin", 11, Rarity.COMMON, mage.cards.d.DevotedPaladin.class));
cards.add(new SetCardInfo("Devour Intellect", 97, Rarity.COMMON, mage.cards.d.DevourIntellect.class));
cards.add(new SetCardInfo("Dire Wolf Prowler", 179, Rarity.COMMON, mage.cards.d.DireWolfProwler.class));
cards.add(new SetCardInfo("Displacer Beast", 54, Rarity.UNCOMMON, mage.cards.d.DisplacerBeast.class));
cards.add(new SetCardInfo("Dire Wolf Prowler", 179, Rarity.COMMON, mage.cards.d.DireWolfProwler.class, NON_FULL_USE_VARIOUS));
cards.add(new SetCardInfo("Dire Wolf Prowler", 325, Rarity.COMMON, mage.cards.d.DireWolfProwler.class, NON_FULL_USE_VARIOUS));
cards.add(new SetCardInfo("Displacer Beast", 305, Rarity.UNCOMMON, mage.cards.d.DisplacerBeast.class, NON_FULL_USE_VARIOUS));
cards.add(new SetCardInfo("Displacer Beast", 54, Rarity.UNCOMMON, mage.cards.d.DisplacerBeast.class, NON_FULL_USE_VARIOUS));
cards.add(new SetCardInfo("Divine Smite", 12, Rarity.UNCOMMON, mage.cards.d.DivineSmite.class));
cards.add(new SetCardInfo("Djinni Windseer", 55, Rarity.COMMON, mage.cards.d.DjinniWindseer.class));
cards.add(new SetCardInfo("Dragon Turtle", 56, Rarity.RARE, mage.cards.d.DragonTurtle.class));
cards.add(new SetCardInfo("Djinni Windseer", 306, Rarity.COMMON, mage.cards.d.DjinniWindseer.class, NON_FULL_USE_VARIOUS));
cards.add(new SetCardInfo("Djinni Windseer", 55, Rarity.COMMON, mage.cards.d.DjinniWindseer.class, NON_FULL_USE_VARIOUS));
cards.add(new SetCardInfo("Dragon Turtle", 307, Rarity.RARE, mage.cards.d.DragonTurtle.class, NON_FULL_USE_VARIOUS));
cards.add(new SetCardInfo("Dragon Turtle", 56, Rarity.RARE, mage.cards.d.DragonTurtle.class, NON_FULL_USE_VARIOUS));
cards.add(new SetCardInfo("Dragon's Disciple", 13, Rarity.UNCOMMON, mage.cards.d.DragonsDisciple.class));
cards.add(new SetCardInfo("Dragon's Fire", 139, Rarity.COMMON, mage.cards.d.DragonsFire.class));
cards.add(new SetCardInfo("Drider", 98, Rarity.UNCOMMON, mage.cards.d.Drider.class));
cards.add(new SetCardInfo("Drizzt Do'Urden", 220, Rarity.RARE, mage.cards.d.DrizztDoUrden.class));
cards.add(new SetCardInfo("Drizzt Do'Urden", 220, Rarity.RARE, mage.cards.d.DrizztDoUrden.class, NON_FULL_USE_VARIOUS));
cards.add(new SetCardInfo("Drizzt Do'Urden", 338, Rarity.RARE, mage.cards.d.DrizztDoUrden.class, NON_FULL_USE_VARIOUS));
cards.add(new SetCardInfo("Druid Class", 180, Rarity.UNCOMMON, mage.cards.d.DruidClass.class));
cards.add(new SetCardInfo("Dueling Rapier", 140, Rarity.COMMON, mage.cards.d.DuelingRapier.class));
cards.add(new SetCardInfo("Dungeon Crawler", 99, Rarity.UNCOMMON, mage.cards.d.DungeonCrawler.class));
cards.add(new SetCardInfo("Dungeon Descent", 255, Rarity.RARE, mage.cards.d.DungeonDescent.class));
cards.add(new SetCardInfo("Dungeon Descent", 255, Rarity.RARE, mage.cards.d.DungeonDescent.class, NON_FULL_USE_VARIOUS));
cards.add(new SetCardInfo("Dungeon Descent", 352, Rarity.RARE, mage.cards.d.DungeonDescent.class, NON_FULL_USE_VARIOUS));
cards.add(new SetCardInfo("Dungeon Map", 242, Rarity.UNCOMMON, mage.cards.d.DungeonMap.class));
cards.add(new SetCardInfo("Dwarfhold Champion", 14, Rarity.COMMON, mage.cards.d.DwarfholdChampion.class));
cards.add(new SetCardInfo("Earth-Cult Elemental", 141, Rarity.COMMON, mage.cards.e.EarthCultElemental.class));
cards.add(new SetCardInfo("Ebondeath, Dracolich", 100, Rarity.MYTHIC, mage.cards.e.EbondeathDracolich.class));
cards.add(new SetCardInfo("Ebondeath, Dracolich", 100, Rarity.MYTHIC, mage.cards.e.EbondeathDracolich.class, NON_FULL_USE_VARIOUS));
cards.add(new SetCardInfo("Ebondeath, Dracolich", 292, Rarity.MYTHIC, mage.cards.e.EbondeathDracolich.class, NON_FULL_USE_VARIOUS));
cards.add(new SetCardInfo("Eccentric Apprentice", 57, Rarity.UNCOMMON, mage.cards.e.EccentricApprentice.class));
cards.add(new SetCardInfo("Ellywick Tumblestrum", 181, Rarity.MYTHIC, mage.cards.e.EllywickTumblestrum.class));
cards.add(new SetCardInfo("Ellywick Tumblestrum", 181, Rarity.MYTHIC, mage.cards.e.EllywickTumblestrum.class, NON_FULL_USE_VARIOUS));
cards.add(new SetCardInfo("Ellywick Tumblestrum", 286, Rarity.MYTHIC, mage.cards.e.EllywickTumblestrum.class, NON_FULL_USE_VARIOUS));
cards.add(new SetCardInfo("Elturgard Ranger", 182, Rarity.COMMON, mage.cards.e.ElturgardRanger.class));
cards.add(new SetCardInfo("Evolving Wilds", 256, Rarity.COMMON, mage.cards.e.EvolvingWilds.class));
cards.add(new SetCardInfo("Eye of Vecna", 243, Rarity.RARE, mage.cards.e.EyeOfVecna.class));
cards.add(new SetCardInfo("Evolving Wilds", 256, Rarity.COMMON, mage.cards.e.EvolvingWilds.class, NON_FULL_USE_VARIOUS));
cards.add(new SetCardInfo("Evolving Wilds", 353, Rarity.COMMON, mage.cards.e.EvolvingWilds.class, NON_FULL_USE_VARIOUS));
cards.add(new SetCardInfo("Eye of Vecna", 243, Rarity.RARE, mage.cards.e.EyeOfVecna.class, NON_FULL_USE_VARIOUS));
cards.add(new SetCardInfo("Eye of Vecna", 393, Rarity.RARE, mage.cards.e.EyeOfVecna.class, NON_FULL_USE_VARIOUS));
cards.add(new SetCardInfo("Eyes of the Beholder", 101, Rarity.COMMON, mage.cards.e.EyesOfTheBeholder.class));
cards.add(new SetCardInfo("Farideh's Fireball", 142, Rarity.COMMON, mage.cards.f.FaridehsFireball.class));
cards.add(new SetCardInfo("Farideh, Devil's Chosen", 221, Rarity.UNCOMMON, mage.cards.f.FaridehDevilsChosen.class));
cards.add(new SetCardInfo("Farideh, Devil's Chosen", 221, Rarity.UNCOMMON, mage.cards.f.FaridehDevilsChosen.class, NON_FULL_USE_VARIOUS));
cards.add(new SetCardInfo("Farideh, Devil's Chosen", 339, Rarity.UNCOMMON, mage.cards.f.FaridehDevilsChosen.class, NON_FULL_USE_VARIOUS));
cards.add(new SetCardInfo("Fates' Reversal", 102, Rarity.COMMON, mage.cards.f.FatesReversal.class));
cards.add(new SetCardInfo("Feign Death", 103, Rarity.COMMON, mage.cards.f.FeignDeath.class));
cards.add(new SetCardInfo("Feywild Trickster", 58, Rarity.UNCOMMON, mage.cards.f.FeywildTrickster.class));
cards.add(new SetCardInfo("Fifty Feet of Rope", 244, Rarity.UNCOMMON, mage.cards.f.FiftyFeetOfRope.class));
cards.add(new SetCardInfo("Fighter Class", 222, Rarity.RARE, mage.cards.f.FighterClass.class));
cards.add(new SetCardInfo("Find the Path", 183, Rarity.COMMON, mage.cards.f.FindThePath.class));
cards.add(new SetCardInfo("Flameskull", 143, Rarity.MYTHIC, mage.cards.f.Flameskull.class));
cards.add(new SetCardInfo("Flumph", 15, Rarity.RARE, mage.cards.f.Flumph.class));
cards.add(new SetCardInfo("Flameskull", 143, Rarity.MYTHIC, mage.cards.f.Flameskull.class, NON_FULL_USE_VARIOUS));
cards.add(new SetCardInfo("Flameskull", 378, Rarity.MYTHIC, mage.cards.f.Flameskull.class, NON_FULL_USE_VARIOUS));
cards.add(new SetCardInfo("Flumph", 15, Rarity.RARE, mage.cards.f.Flumph.class, NON_FULL_USE_VARIOUS));
cards.add(new SetCardInfo("Flumph", 361, Rarity.RARE, mage.cards.f.Flumph.class, NON_FULL_USE_VARIOUS));
cards.add(new SetCardInfo("Fly", 59, Rarity.UNCOMMON, mage.cards.f.Fly.class));
cards.add(new SetCardInfo("Forest", 278, Rarity.LAND, mage.cards.basiclands.Forest.class, NON_FULL_USE_VARIOUS));
cards.add(new SetCardInfo("Forsworn Paladin", 104, Rarity.RARE, mage.cards.f.ForswornPaladin.class));
cards.add(new SetCardInfo("Froghemoth", 184, Rarity.RARE, mage.cards.f.Froghemoth.class));
cards.add(new SetCardInfo("Gelatinous Cube", 105, Rarity.RARE, mage.cards.g.GelatinousCube.class));
cards.add(new SetCardInfo("Forest", 279, Rarity.LAND, mage.cards.basiclands.Forest.class, NON_FULL_USE_VARIOUS));
cards.add(new SetCardInfo("Forest", 280, Rarity.LAND, mage.cards.basiclands.Forest.class, NON_FULL_USE_VARIOUS));
cards.add(new SetCardInfo("Forest", 281, Rarity.LAND, mage.cards.basiclands.Forest.class, NON_FULL_USE_VARIOUS));
cards.add(new SetCardInfo("Forsworn Paladin", 104, Rarity.RARE, mage.cards.f.ForswornPaladin.class, NON_FULL_USE_VARIOUS));
cards.add(new SetCardInfo("Forsworn Paladin", 375, Rarity.RARE, mage.cards.f.ForswornPaladin.class, NON_FULL_USE_VARIOUS));
cards.add(new SetCardInfo("Froghemoth", 184, Rarity.RARE, mage.cards.f.Froghemoth.class, NON_FULL_USE_VARIOUS));
cards.add(new SetCardInfo("Froghemoth", 384, Rarity.RARE, mage.cards.f.Froghemoth.class, NON_FULL_USE_VARIOUS));
cards.add(new SetCardInfo("Gelatinous Cube", 105, Rarity.RARE, mage.cards.g.GelatinousCube.class, NON_FULL_USE_VARIOUS));
cards.add(new SetCardInfo("Gelatinous Cube", 313, Rarity.RARE, mage.cards.g.GelatinousCube.class, NON_FULL_USE_VARIOUS));
cards.add(new SetCardInfo("Gloom Stalker", 16, Rarity.COMMON, mage.cards.g.GloomStalker.class));
cards.add(new SetCardInfo("Gnoll Hunter", 185, Rarity.COMMON, mage.cards.g.GnollHunter.class));
cards.add(new SetCardInfo("Goblin Javelineer", 144, Rarity.COMMON, mage.cards.g.GoblinJavelineer.class));
cards.add(new SetCardInfo("Gnoll Hunter", 185, Rarity.COMMON, mage.cards.g.GnollHunter.class, NON_FULL_USE_VARIOUS));
cards.add(new SetCardInfo("Gnoll Hunter", 326, Rarity.COMMON, mage.cards.g.GnollHunter.class, NON_FULL_USE_VARIOUS));
cards.add(new SetCardInfo("Goblin Javelineer", 144, Rarity.COMMON, mage.cards.g.GoblinJavelineer.class, NON_FULL_USE_VARIOUS));
cards.add(new SetCardInfo("Goblin Javelineer", 318, Rarity.COMMON, mage.cards.g.GoblinJavelineer.class, NON_FULL_USE_VARIOUS));
cards.add(new SetCardInfo("Goblin Morningstar", 145, Rarity.UNCOMMON, mage.cards.g.GoblinMorningstar.class));
cards.add(new SetCardInfo("Grand Master of Flowers", 17, Rarity.MYTHIC, mage.cards.g.GrandMasterOfFlowers.class));
cards.add(new SetCardInfo("Grazilaxx, Illithid Scholar", 60, Rarity.RARE, mage.cards.g.GrazilaxxIllithidScholar.class));
cards.add(new SetCardInfo("Grand Master of Flowers", 17, Rarity.MYTHIC, mage.cards.g.GrandMasterOfFlowers.class, NON_FULL_USE_VARIOUS));
cards.add(new SetCardInfo("Grand Master of Flowers", 282, Rarity.MYTHIC, mage.cards.g.GrandMasterOfFlowers.class, NON_FULL_USE_VARIOUS));
cards.add(new SetCardInfo("Grazilaxx, Illithid Scholar", 367, Rarity.RARE, mage.cards.g.GrazilaxxIllithidScholar.class, NON_FULL_USE_VARIOUS));
cards.add(new SetCardInfo("Grazilaxx, Illithid Scholar", 60, Rarity.RARE, mage.cards.g.GrazilaxxIllithidScholar.class, NON_FULL_USE_VARIOUS));
cards.add(new SetCardInfo("Greataxe", 245, Rarity.COMMON, mage.cards.g.Greataxe.class));
cards.add(new SetCardInfo("Green Dragon", 186, Rarity.UNCOMMON, mage.cards.g.GreenDragon.class));
cards.add(new SetCardInfo("Gretchen Titchwillow", 223, Rarity.UNCOMMON, mage.cards.g.GretchenTitchwillow.class));
cards.add(new SetCardInfo("Green Dragon", 186, Rarity.UNCOMMON, mage.cards.g.GreenDragon.class, NON_FULL_USE_VARIOUS));
cards.add(new SetCardInfo("Green Dragon", 295, Rarity.UNCOMMON, mage.cards.g.GreenDragon.class, NON_FULL_USE_VARIOUS));
cards.add(new SetCardInfo("Gretchen Titchwillow", 223, Rarity.UNCOMMON, mage.cards.g.GretchenTitchwillow.class, NON_FULL_USE_VARIOUS));
cards.add(new SetCardInfo("Gretchen Titchwillow", 340, Rarity.UNCOMMON, mage.cards.g.GretchenTitchwillow.class, NON_FULL_USE_VARIOUS));
cards.add(new SetCardInfo("Grim Bounty", 106, Rarity.COMMON, mage.cards.g.GrimBounty.class));
cards.add(new SetCardInfo("Grim Wanderer", 107, Rarity.UNCOMMON, mage.cards.g.GrimWanderer.class));
cards.add(new SetCardInfo("Guardian of Faith", 18, Rarity.RARE, mage.cards.g.GuardianOfFaith.class));
cards.add(new SetCardInfo("Guardian of Faith", 18, Rarity.RARE, mage.cards.g.GuardianOfFaith.class, NON_FULL_USE_VARIOUS));
cards.add(new SetCardInfo("Guardian of Faith", 362, Rarity.RARE, mage.cards.g.GuardianOfFaith.class, NON_FULL_USE_VARIOUS));
cards.add(new SetCardInfo("Guild Thief", 61, Rarity.UNCOMMON, mage.cards.g.GuildThief.class));
cards.add(new SetCardInfo("Half-Elf Monk", 19, Rarity.COMMON, mage.cards.h.HalfElfMonk.class));
cards.add(new SetCardInfo("Hall of Storm Giants", 257, Rarity.RARE, mage.cards.h.HallOfStormGiants.class));
cards.add(new SetCardInfo("Hama Pashar, Ruin Seeker", 224, Rarity.UNCOMMON, mage.cards.h.HamaPasharRuinSeeker.class));
cards.add(new SetCardInfo("Hand of Vecna", 246, Rarity.RARE, mage.cards.h.HandOfVecna.class));
cards.add(new SetCardInfo("Hall of Storm Giants", 257, Rarity.RARE, mage.cards.h.HallOfStormGiants.class, NON_FULL_USE_VARIOUS));
cards.add(new SetCardInfo("Hall of Storm Giants", 354, Rarity.RARE, mage.cards.h.HallOfStormGiants.class, NON_FULL_USE_VARIOUS));
cards.add(new SetCardInfo("Hama Pashar, Ruin Seeker", 224, Rarity.UNCOMMON, mage.cards.h.HamaPasharRuinSeeker.class, NON_FULL_USE_VARIOUS));
cards.add(new SetCardInfo("Hama Pashar, Ruin Seeker", 341, Rarity.UNCOMMON, mage.cards.h.HamaPasharRuinSeeker.class, NON_FULL_USE_VARIOUS));
cards.add(new SetCardInfo("Hand of Vecna", 246, Rarity.RARE, mage.cards.h.HandOfVecna.class, NON_FULL_USE_VARIOUS));
cards.add(new SetCardInfo("Hand of Vecna", 394, Rarity.RARE, mage.cards.h.HandOfVecna.class, NON_FULL_USE_VARIOUS));
cards.add(new SetCardInfo("Herald of Hadar", 108, Rarity.COMMON, mage.cards.h.HeraldOfHadar.class));
cards.add(new SetCardInfo("Hill Giant Herdgorger", 187, Rarity.COMMON, mage.cards.h.HillGiantHerdgorger.class));
cards.add(new SetCardInfo("Hired Hexblade", 109, Rarity.COMMON, mage.cards.h.HiredHexblade.class));
cards.add(new SetCardInfo("Hive of the Eye Tyrant", 258, Rarity.RARE, mage.cards.h.HiveOfTheEyeTyrant.class));
cards.add(new SetCardInfo("Hive of the Eye Tyrant", 258, Rarity.RARE, mage.cards.h.HiveOfTheEyeTyrant.class, NON_FULL_USE_VARIOUS));
cards.add(new SetCardInfo("Hive of the Eye Tyrant", 355, Rarity.RARE, mage.cards.h.HiveOfTheEyeTyrant.class, NON_FULL_USE_VARIOUS));
cards.add(new SetCardInfo("Hoard Robber", 110, Rarity.COMMON, mage.cards.h.HoardRobber.class));
cards.add(new SetCardInfo("Hoarding Ogre", 146, Rarity.COMMON, mage.cards.h.HoardingOgre.class));
cards.add(new SetCardInfo("Hobgoblin Bandit Lord", 147, Rarity.RARE, mage.cards.h.HobgoblinBanditLord.class));
cards.add(new SetCardInfo("Hobgoblin Bandit Lord", 147, Rarity.RARE, mage.cards.h.HobgoblinBanditLord.class, NON_FULL_USE_VARIOUS));
cards.add(new SetCardInfo("Hobgoblin Bandit Lord", 379, Rarity.RARE, mage.cards.h.HobgoblinBanditLord.class, NON_FULL_USE_VARIOUS));
cards.add(new SetCardInfo("Hobgoblin Captain", 148, Rarity.COMMON, mage.cards.h.HobgoblinCaptain.class));
cards.add(new SetCardInfo("Hulking Bugbear", 149, Rarity.UNCOMMON, mage.cards.h.HulkingBugbear.class));
cards.add(new SetCardInfo("Hulking Bugbear", 149, Rarity.UNCOMMON, mage.cards.h.HulkingBugbear.class, NON_FULL_USE_VARIOUS));
cards.add(new SetCardInfo("Hulking Bugbear", 319, Rarity.UNCOMMON, mage.cards.h.HulkingBugbear.class, NON_FULL_USE_VARIOUS));
cards.add(new SetCardInfo("Hunter's Mark", 188, Rarity.UNCOMMON, mage.cards.h.HuntersMark.class));
cards.add(new SetCardInfo("Icingdeath, Frost Tyrant", 20, Rarity.MYTHIC, mage.cards.i.IcingdeathFrostTyrant.class));
cards.add(new SetCardInfo("Icingdeath, Frost Tyrant", 20, Rarity.MYTHIC, mage.cards.i.IcingdeathFrostTyrant.class, NON_FULL_USE_VARIOUS));
cards.add(new SetCardInfo("Icingdeath, Frost Tyrant", 287, Rarity.MYTHIC, mage.cards.i.IcingdeathFrostTyrant.class, NON_FULL_USE_VARIOUS));
cards.add(new SetCardInfo("Improvised Weaponry", 150, Rarity.COMMON, mage.cards.i.ImprovisedWeaponry.class));
cards.add(new SetCardInfo("Inferno of the Star Mounts", 151, Rarity.MYTHIC, mage.cards.i.InfernoOfTheStarMounts.class));
cards.add(new SetCardInfo("Inferno of the Star Mounts", 151, Rarity.MYTHIC, mage.cards.i.InfernoOfTheStarMounts.class, NON_FULL_USE_VARIOUS));
cards.add(new SetCardInfo("Inferno of the Star Mounts", 293, Rarity.MYTHIC, mage.cards.i.InfernoOfTheStarMounts.class, NON_FULL_USE_VARIOUS));
cards.add(new SetCardInfo("Ingenious Smith", 21, Rarity.UNCOMMON, mage.cards.i.IngeniousSmith.class));
cards.add(new SetCardInfo("Inspiring Bard", 189, Rarity.COMMON, mage.cards.i.InspiringBard.class));
cards.add(new SetCardInfo("Instrument of the Bards", 190, Rarity.RARE, mage.cards.i.InstrumentOfTheBards.class));
cards.add(new SetCardInfo("Instrument of the Bards", 190, Rarity.RARE, mage.cards.i.InstrumentOfTheBards.class, NON_FULL_USE_VARIOUS));
cards.add(new SetCardInfo("Instrument of the Bards", 385, Rarity.RARE, mage.cards.i.InstrumentOfTheBards.class, NON_FULL_USE_VARIOUS));
cards.add(new SetCardInfo("Intrepid Outlander", 191, Rarity.UNCOMMON, mage.cards.i.IntrepidOutlander.class));
cards.add(new SetCardInfo("Iron Golem", 247, Rarity.UNCOMMON, mage.cards.i.IronGolem.class));
cards.add(new SetCardInfo("Iron Golem", 247, Rarity.UNCOMMON, mage.cards.i.IronGolem.class, NON_FULL_USE_VARIOUS));
cards.add(new SetCardInfo("Iron Golem", 348, Rarity.UNCOMMON, mage.cards.i.IronGolem.class, NON_FULL_USE_VARIOUS));
cards.add(new SetCardInfo("Island", 266, Rarity.LAND, mage.cards.basiclands.Island.class, NON_FULL_USE_VARIOUS));
cards.add(new SetCardInfo("Iymrith, Desert Doom", 62, Rarity.MYTHIC, mage.cards.i.IymrithDesertDoom.class));
cards.add(new SetCardInfo("Island", 267, Rarity.LAND, mage.cards.basiclands.Island.class, NON_FULL_USE_VARIOUS));
cards.add(new SetCardInfo("Island", 268, Rarity.LAND, mage.cards.basiclands.Island.class, NON_FULL_USE_VARIOUS));
cards.add(new SetCardInfo("Island", 269, Rarity.LAND, mage.cards.basiclands.Island.class, NON_FULL_USE_VARIOUS));
cards.add(new SetCardInfo("Iymrith, Desert Doom", 290, Rarity.MYTHIC, mage.cards.i.IymrithDesertDoom.class, NON_FULL_USE_VARIOUS));
cards.add(new SetCardInfo("Iymrith, Desert Doom", 62, Rarity.MYTHIC, mage.cards.i.IymrithDesertDoom.class, NON_FULL_USE_VARIOUS));
cards.add(new SetCardInfo("Jaded Sell-Sword", 152, Rarity.COMMON, mage.cards.j.JadedSellSword.class));
cards.add(new SetCardInfo("Kalain, Reclusive Painter", 225, Rarity.UNCOMMON, mage.cards.k.KalainReclusivePainter.class));
cards.add(new SetCardInfo("Kalain, Reclusive Painter", 225, Rarity.UNCOMMON, mage.cards.k.KalainReclusivePainter.class, NON_FULL_USE_VARIOUS));
cards.add(new SetCardInfo("Kalain, Reclusive Painter", 342, Rarity.UNCOMMON, mage.cards.k.KalainReclusivePainter.class, NON_FULL_USE_VARIOUS));
cards.add(new SetCardInfo("Keen-Eared Sentry", 22, Rarity.UNCOMMON, mage.cards.k.KeenEaredSentry.class));
cards.add(new SetCardInfo("Kick in the Door", 153, Rarity.COMMON, mage.cards.k.KickInTheDoor.class));
cards.add(new SetCardInfo("Krydle of Baldur's Gate", 226, Rarity.UNCOMMON, mage.cards.k.KrydleOfBaldursGate.class));
cards.add(new SetCardInfo("Lair of the Hydra", 259, Rarity.RARE, mage.cards.l.LairOfTheHydra.class));
cards.add(new SetCardInfo("Krydle of Baldur's Gate", 226, Rarity.UNCOMMON, mage.cards.k.KrydleOfBaldursGate.class, NON_FULL_USE_VARIOUS));
cards.add(new SetCardInfo("Krydle of Baldur's Gate", 343, Rarity.UNCOMMON, mage.cards.k.KrydleOfBaldursGate.class, NON_FULL_USE_VARIOUS));
cards.add(new SetCardInfo("Lair of the Hydra", 259, Rarity.RARE, mage.cards.l.LairOfTheHydra.class, NON_FULL_USE_VARIOUS));
cards.add(new SetCardInfo("Lair of the Hydra", 356, Rarity.RARE, mage.cards.l.LairOfTheHydra.class, NON_FULL_USE_VARIOUS));
cards.add(new SetCardInfo("Leather Armor", 248, Rarity.COMMON, mage.cards.l.LeatherArmor.class));
cards.add(new SetCardInfo("Lightfoot Rogue", 111, Rarity.UNCOMMON, mage.cards.l.LightfootRogue.class));
cards.add(new SetCardInfo("Loathsome Troll", 192, Rarity.UNCOMMON, mage.cards.l.LoathsomeTroll.class));
cards.add(new SetCardInfo("Lolth, Spider Queen", 112, Rarity.MYTHIC, mage.cards.l.LolthSpiderQueen.class));
cards.add(new SetCardInfo("Long Rest", 193, Rarity.RARE, mage.cards.l.LongRest.class));
cards.add(new SetCardInfo("Loyal Warhound", 23, Rarity.RARE, mage.cards.l.LoyalWarhound.class));
cards.add(new SetCardInfo("Lurking Roper", 194, Rarity.UNCOMMON, mage.cards.l.LurkingRoper.class));
cards.add(new SetCardInfo("Magic Missile", 154, Rarity.UNCOMMON, mage.cards.m.MagicMissile.class));
cards.add(new SetCardInfo("Manticore", 113, Rarity.COMMON, mage.cards.m.Manticore.class));
cards.add(new SetCardInfo("Meteor Swarm", 155, Rarity.RARE, mage.cards.m.MeteorSwarm.class));
cards.add(new SetCardInfo("Mimic", 249, Rarity.COMMON, mage.cards.m.Mimic.class));
cards.add(new SetCardInfo("Mind Flayer", 63, Rarity.RARE, mage.cards.m.MindFlayer.class));
cards.add(new SetCardInfo("Loathsome Troll", 192, Rarity.UNCOMMON, mage.cards.l.LoathsomeTroll.class, NON_FULL_USE_VARIOUS));
cards.add(new SetCardInfo("Loathsome Troll", 327, Rarity.UNCOMMON, mage.cards.l.LoathsomeTroll.class, NON_FULL_USE_VARIOUS));
cards.add(new SetCardInfo("Lolth, Spider Queen", 112, Rarity.MYTHIC, mage.cards.l.LolthSpiderQueen.class, NON_FULL_USE_VARIOUS));
cards.add(new SetCardInfo("Lolth, Spider Queen", 284, Rarity.MYTHIC, mage.cards.l.LolthSpiderQueen.class, NON_FULL_USE_VARIOUS));
cards.add(new SetCardInfo("Long Rest", 193, Rarity.RARE, mage.cards.l.LongRest.class, NON_FULL_USE_VARIOUS));
cards.add(new SetCardInfo("Long Rest", 386, Rarity.RARE, mage.cards.l.LongRest.class, NON_FULL_USE_VARIOUS));
cards.add(new SetCardInfo("Loyal Warhound", 23, Rarity.RARE, mage.cards.l.LoyalWarhound.class, NON_FULL_USE_VARIOUS));
cards.add(new SetCardInfo("Loyal Warhound", 363, Rarity.RARE, mage.cards.l.LoyalWarhound.class, NON_FULL_USE_VARIOUS));
cards.add(new SetCardInfo("Lurking Roper", 194, Rarity.UNCOMMON, mage.cards.l.LurkingRoper.class, NON_FULL_USE_VARIOUS));
cards.add(new SetCardInfo("Lurking Roper", 328, Rarity.UNCOMMON, mage.cards.l.LurkingRoper.class, NON_FULL_USE_VARIOUS));
cards.add(new SetCardInfo("Magic Missile", 154, Rarity.UNCOMMON, mage.cards.m.MagicMissile.class, NON_FULL_USE_VARIOUS));
cards.add(new SetCardInfo("Magic Missile", 401, Rarity.UNCOMMON, mage.cards.m.MagicMissile.class, NON_FULL_USE_VARIOUS));
cards.add(new SetCardInfo("Manticore", 113, Rarity.COMMON, mage.cards.m.Manticore.class, NON_FULL_USE_VARIOUS));
cards.add(new SetCardInfo("Manticore", 314, Rarity.COMMON, mage.cards.m.Manticore.class, NON_FULL_USE_VARIOUS));
cards.add(new SetCardInfo("Meteor Swarm", 155, Rarity.RARE, mage.cards.m.MeteorSwarm.class, NON_FULL_USE_VARIOUS));
cards.add(new SetCardInfo("Meteor Swarm", 380, Rarity.RARE, mage.cards.m.MeteorSwarm.class, NON_FULL_USE_VARIOUS));
cards.add(new SetCardInfo("Mimic", 249, Rarity.COMMON, mage.cards.m.Mimic.class, NON_FULL_USE_VARIOUS));
cards.add(new SetCardInfo("Mimic", 349, Rarity.COMMON, mage.cards.m.Mimic.class, NON_FULL_USE_VARIOUS));
cards.add(new SetCardInfo("Mind Flayer", 308, Rarity.RARE, mage.cards.m.MindFlayer.class, NON_FULL_USE_VARIOUS));
cards.add(new SetCardInfo("Mind Flayer", 63, Rarity.RARE, mage.cards.m.MindFlayer.class, NON_FULL_USE_VARIOUS));
cards.add(new SetCardInfo("Minimus Containment", 24, Rarity.COMMON, mage.cards.m.MinimusContainment.class));
cards.add(new SetCardInfo("Minion of the Mighty", 156, Rarity.RARE, mage.cards.m.MinionOfTheMighty.class));
cards.add(new SetCardInfo("Minsc, Beloved Ranger", 227, Rarity.MYTHIC, mage.cards.m.MinscBelovedRanger.class));
cards.add(new SetCardInfo("Minion of the Mighty", 156, Rarity.RARE, mage.cards.m.MinionOfTheMighty.class, NON_FULL_USE_VARIOUS));
cards.add(new SetCardInfo("Minion of the Mighty", 320, Rarity.RARE, mage.cards.m.MinionOfTheMighty.class, NON_FULL_USE_VARIOUS));
cards.add(new SetCardInfo("Minsc, Beloved Ranger", 227, Rarity.MYTHIC, mage.cards.m.MinscBelovedRanger.class, NON_FULL_USE_VARIOUS));
cards.add(new SetCardInfo("Minsc, Beloved Ranger", 344, Rarity.MYTHIC, mage.cards.m.MinscBelovedRanger.class, NON_FULL_USE_VARIOUS));
cards.add(new SetCardInfo("Monk Class", 228, Rarity.RARE, mage.cards.m.MonkClass.class));
cards.add(new SetCardInfo("Monk of the Open Hand", 25, Rarity.UNCOMMON, mage.cards.m.MonkOfTheOpenHand.class));
cards.add(new SetCardInfo("Moon-Blessed Cleric", 26, Rarity.UNCOMMON, mage.cards.m.MoonBlessedCleric.class));
cards.add(new SetCardInfo("Mordenkainen", 64, Rarity.MYTHIC, mage.cards.m.Mordenkainen.class));
cards.add(new SetCardInfo("Mordenkainen", 283, Rarity.MYTHIC, mage.cards.m.Mordenkainen.class, NON_FULL_USE_VARIOUS));
cards.add(new SetCardInfo("Mordenkainen", 64, Rarity.MYTHIC, mage.cards.m.Mordenkainen.class, NON_FULL_USE_VARIOUS));
cards.add(new SetCardInfo("Mordenkainen's Polymorph", 65, Rarity.COMMON, mage.cards.m.MordenkainensPolymorph.class));
cards.add(new SetCardInfo("Mountain", 274, Rarity.LAND, mage.cards.basiclands.Mountain.class, NON_FULL_USE_VARIOUS));
cards.add(new SetCardInfo("Nadaar, Selfless Paladin", 27, Rarity.RARE, mage.cards.n.NadaarSelflessPaladin.class));
cards.add(new SetCardInfo("Neverwinter Dryad", 195, Rarity.COMMON, mage.cards.n.NeverwinterDryad.class));
cards.add(new SetCardInfo("Ochre Jelly", 196, Rarity.RARE, mage.cards.o.OchreJelly.class));
cards.add(new SetCardInfo("Old Gnawbone", 197, Rarity.MYTHIC, mage.cards.o.OldGnawbone.class));
cards.add(new SetCardInfo("Orb of Dragonkind", 157, Rarity.RARE, mage.cards.o.OrbOfDragonkind.class));
cards.add(new SetCardInfo("Orcus, Prince of Undeath", 229, Rarity.RARE, mage.cards.o.OrcusPrinceOfUndeath.class));
cards.add(new SetCardInfo("Oswald Fiddlebender", 28, Rarity.RARE, mage.cards.o.OswaldFiddlebender.class));
cards.add(new SetCardInfo("Owlbear", 198, Rarity.COMMON, mage.cards.o.Owlbear.class));
cards.add(new SetCardInfo("Mountain", 275, Rarity.LAND, mage.cards.basiclands.Mountain.class, NON_FULL_USE_VARIOUS));
cards.add(new SetCardInfo("Mountain", 276, Rarity.LAND, mage.cards.basiclands.Mountain.class, NON_FULL_USE_VARIOUS));
cards.add(new SetCardInfo("Mountain", 277, Rarity.LAND, mage.cards.basiclands.Mountain.class, NON_FULL_USE_VARIOUS));
cards.add(new SetCardInfo("Nadaar, Selfless Paladin", 27, Rarity.RARE, mage.cards.n.NadaarSelflessPaladin.class, NON_FULL_USE_VARIOUS));
cards.add(new SetCardInfo("Nadaar, Selfless Paladin", 303, Rarity.RARE, mage.cards.n.NadaarSelflessPaladin.class, NON_FULL_USE_VARIOUS));
cards.add(new SetCardInfo("Neverwinter Dryad", 195, Rarity.COMMON, mage.cards.n.NeverwinterDryad.class, NON_FULL_USE_VARIOUS));
cards.add(new SetCardInfo("Neverwinter Dryad", 329, Rarity.COMMON, mage.cards.n.NeverwinterDryad.class, NON_FULL_USE_VARIOUS));
cards.add(new SetCardInfo("Ochre Jelly", 196, Rarity.RARE, mage.cards.o.OchreJelly.class, NON_FULL_USE_VARIOUS));
cards.add(new SetCardInfo("Ochre Jelly", 330, Rarity.RARE, mage.cards.o.OchreJelly.class, NON_FULL_USE_VARIOUS));
cards.add(new SetCardInfo("Old Gnawbone", 197, Rarity.MYTHIC, mage.cards.o.OldGnawbone.class, NON_FULL_USE_VARIOUS));
cards.add(new SetCardInfo("Old Gnawbone", 296, Rarity.MYTHIC, mage.cards.o.OldGnawbone.class, NON_FULL_USE_VARIOUS));
cards.add(new SetCardInfo("Orb of Dragonkind", 157, Rarity.RARE, mage.cards.o.OrbOfDragonkind.class, NON_FULL_USE_VARIOUS));
cards.add(new SetCardInfo("Orb of Dragonkind", 381, Rarity.RARE, mage.cards.o.OrbOfDragonkind.class, NON_FULL_USE_VARIOUS));
cards.add(new SetCardInfo("Orcus, Prince of Undeath", 229, Rarity.RARE, mage.cards.o.OrcusPrinceOfUndeath.class, NON_FULL_USE_VARIOUS));
cards.add(new SetCardInfo("Orcus, Prince of Undeath", 388, Rarity.RARE, mage.cards.o.OrcusPrinceOfUndeath.class, NON_FULL_USE_VARIOUS));
cards.add(new SetCardInfo("Oswald Fiddlebender", 28, Rarity.RARE, mage.cards.o.OswaldFiddlebender.class, NON_FULL_USE_VARIOUS));
cards.add(new SetCardInfo("Oswald Fiddlebender", 304, Rarity.RARE, mage.cards.o.OswaldFiddlebender.class, NON_FULL_USE_VARIOUS));
cards.add(new SetCardInfo("Owlbear", 198, Rarity.COMMON, mage.cards.o.Owlbear.class, NON_FULL_USE_VARIOUS));
cards.add(new SetCardInfo("Owlbear", 331, Rarity.COMMON, mage.cards.o.Owlbear.class, NON_FULL_USE_VARIOUS));
cards.add(new SetCardInfo("Paladin Class", 29, Rarity.RARE, mage.cards.p.PaladinClass.class));
cards.add(new SetCardInfo("Paladin's Shield", 30, Rarity.COMMON, mage.cards.p.PaladinsShield.class));
cards.add(new SetCardInfo("Pixie Guide", 66, Rarity.COMMON, mage.cards.p.PixieGuide.class));
cards.add(new SetCardInfo("Pixie Guide", 309, Rarity.COMMON, mage.cards.p.PixieGuide.class, NON_FULL_USE_VARIOUS));
cards.add(new SetCardInfo("Pixie Guide", 66, Rarity.COMMON, mage.cards.p.PixieGuide.class, NON_FULL_USE_VARIOUS));
cards.add(new SetCardInfo("Plains", 262, Rarity.LAND, mage.cards.basiclands.Plains.class, NON_FULL_USE_VARIOUS));
cards.add(new SetCardInfo("Plains", 263, Rarity.LAND, mage.cards.basiclands.Plains.class, NON_FULL_USE_VARIOUS));
cards.add(new SetCardInfo("Plains", 264, Rarity.LAND, mage.cards.basiclands.Plains.class, NON_FULL_USE_VARIOUS));
cards.add(new SetCardInfo("Plains", 265, Rarity.LAND, mage.cards.basiclands.Plains.class, NON_FULL_USE_VARIOUS));
cards.add(new SetCardInfo("Planar Ally", 31, Rarity.COMMON, mage.cards.p.PlanarAlly.class));
cards.add(new SetCardInfo("Plate Armor", 32, Rarity.UNCOMMON, mage.cards.p.PlateArmor.class));
cards.add(new SetCardInfo("Plummet", 199, Rarity.COMMON, mage.cards.p.Plummet.class));
cards.add(new SetCardInfo("Plundering Barbarian", 158, Rarity.COMMON, mage.cards.p.PlunderingBarbarian.class));
cards.add(new SetCardInfo("Portable Hole", 33, Rarity.UNCOMMON, mage.cards.p.PortableHole.class));
cards.add(new SetCardInfo("Portable Hole", 33, Rarity.UNCOMMON, mage.cards.p.PortableHole.class, NON_FULL_USE_VARIOUS));
cards.add(new SetCardInfo("Portable Hole", 398, Rarity.UNCOMMON, mage.cards.p.PortableHole.class, NON_FULL_USE_VARIOUS));
cards.add(new SetCardInfo("Potion of Healing", 34, Rarity.COMMON, mage.cards.p.PotionOfHealing.class));
cards.add(new SetCardInfo("Power Word Kill", 114, Rarity.UNCOMMON, mage.cards.p.PowerWordKill.class));
cards.add(new SetCardInfo("Power Word Kill", 114, Rarity.UNCOMMON, mage.cards.p.PowerWordKill.class, NON_FULL_USE_VARIOUS));
cards.add(new SetCardInfo("Power Word Kill", 400, Rarity.UNCOMMON, mage.cards.p.PowerWordKill.class, NON_FULL_USE_VARIOUS));
cards.add(new SetCardInfo("Power of Persuasion", 67, Rarity.UNCOMMON, mage.cards.p.PowerOfPersuasion.class));
cards.add(new SetCardInfo("Precipitous Drop", 115, Rarity.COMMON, mage.cards.p.PrecipitousDrop.class));
cards.add(new SetCardInfo("Price of Loyalty", 159, Rarity.COMMON, mage.cards.p.PriceOfLoyalty.class));
cards.add(new SetCardInfo("Priest of Ancient Lore", 35, Rarity.COMMON, mage.cards.p.PriestOfAncientLore.class));
cards.add(new SetCardInfo("Prosperous Innkeeper", 200, Rarity.UNCOMMON, mage.cards.p.ProsperousInnkeeper.class));
cards.add(new SetCardInfo("Purple Worm", 201, Rarity.UNCOMMON, mage.cards.p.PurpleWorm.class));
cards.add(new SetCardInfo("Prosperous Innkeeper", 200, Rarity.UNCOMMON, mage.cards.p.ProsperousInnkeeper.class, NON_FULL_USE_VARIOUS));
cards.add(new SetCardInfo("Prosperous Innkeeper", 402, Rarity.UNCOMMON, mage.cards.p.ProsperousInnkeeper.class, NON_FULL_USE_VARIOUS));
cards.add(new SetCardInfo("Purple Worm", 201, Rarity.UNCOMMON, mage.cards.p.PurpleWorm.class, NON_FULL_USE_VARIOUS));
cards.add(new SetCardInfo("Purple Worm", 332, Rarity.UNCOMMON, mage.cards.p.PurpleWorm.class, NON_FULL_USE_VARIOUS));
cards.add(new SetCardInfo("Rally Maneuver", 36, Rarity.UNCOMMON, mage.cards.r.RallyManeuver.class));
cards.add(new SetCardInfo("Ranger Class", 202, Rarity.RARE, mage.cards.r.RangerClass.class));
cards.add(new SetCardInfo("Ranger's Hawk", 37, Rarity.COMMON, mage.cards.r.RangersHawk.class));
@ -218,75 +312,114 @@ public final class AdventuresInTheForgottenRealms extends ExpansionSet {
cards.add(new SetCardInfo("Ray of Enfeeblement", 116, Rarity.UNCOMMON, mage.cards.r.RayOfEnfeeblement.class));
cards.add(new SetCardInfo("Ray of Frost", 68, Rarity.UNCOMMON, mage.cards.r.RayOfFrost.class));
cards.add(new SetCardInfo("Reaper's Talisman", 117, Rarity.UNCOMMON, mage.cards.r.ReapersTalisman.class));
cards.add(new SetCardInfo("Red Dragon", 160, Rarity.UNCOMMON, mage.cards.r.RedDragon.class));
cards.add(new SetCardInfo("Rimeshield Frost Giant", 69, Rarity.COMMON, mage.cards.r.RimeshieldFrostGiant.class));
cards.add(new SetCardInfo("Red Dragon", 160, Rarity.UNCOMMON, mage.cards.r.RedDragon.class, NON_FULL_USE_VARIOUS));
cards.add(new SetCardInfo("Red Dragon", 294, Rarity.UNCOMMON, mage.cards.r.RedDragon.class, NON_FULL_USE_VARIOUS));
cards.add(new SetCardInfo("Rimeshield Frost Giant", 310, Rarity.COMMON, mage.cards.r.RimeshieldFrostGiant.class, NON_FULL_USE_VARIOUS));
cards.add(new SetCardInfo("Rimeshield Frost Giant", 69, Rarity.COMMON, mage.cards.r.RimeshieldFrostGiant.class, NON_FULL_USE_VARIOUS));
cards.add(new SetCardInfo("Rogue Class", 230, Rarity.RARE, mage.cards.r.RogueClass.class));
cards.add(new SetCardInfo("Rust Monster", 161, Rarity.UNCOMMON, mage.cards.r.RustMonster.class));
cards.add(new SetCardInfo("Rust Monster", 161, Rarity.UNCOMMON, mage.cards.r.RustMonster.class, NON_FULL_USE_VARIOUS));
cards.add(new SetCardInfo("Rust Monster", 321, Rarity.UNCOMMON, mage.cards.r.RustMonster.class, NON_FULL_USE_VARIOUS));
cards.add(new SetCardInfo("Scaled Herbalist", 204, Rarity.COMMON, mage.cards.s.ScaledHerbalist.class));
cards.add(new SetCardInfo("Scion of Stygia", 70, Rarity.COMMON, mage.cards.s.ScionOfStygia.class));
cards.add(new SetCardInfo("Secret Door", 71, Rarity.COMMON, mage.cards.s.SecretDoor.class));
cards.add(new SetCardInfo("Sepulcher Ghoul", 118, Rarity.COMMON, mage.cards.s.SepulcherGhoul.class));
cards.add(new SetCardInfo("Shambling Ghast", 119, Rarity.COMMON, mage.cards.s.ShamblingGhast.class));
cards.add(new SetCardInfo("Shessra, Death's Whisper", 231, Rarity.UNCOMMON, mage.cards.s.ShessraDeathsWhisper.class));
cards.add(new SetCardInfo("Shessra, Death's Whisper", 231, Rarity.UNCOMMON, mage.cards.s.ShessraDeathsWhisper.class, NON_FULL_USE_VARIOUS));
cards.add(new SetCardInfo("Shessra, Death's Whisper", 345, Rarity.UNCOMMON, mage.cards.s.ShessraDeathsWhisper.class, NON_FULL_USE_VARIOUS));
cards.add(new SetCardInfo("Shocking Grasp", 72, Rarity.COMMON, mage.cards.s.ShockingGrasp.class));
cards.add(new SetCardInfo("Shortcut Seeker", 73, Rarity.COMMON, mage.cards.s.ShortcutSeeker.class));
cards.add(new SetCardInfo("Silver Raven", 74, Rarity.COMMON, mage.cards.s.SilverRaven.class));
cards.add(new SetCardInfo("Skeletal Swarming", 232, Rarity.RARE, mage.cards.s.SkeletalSwarming.class));
cards.add(new SetCardInfo("Skeletal Swarming", 232, Rarity.RARE, mage.cards.s.SkeletalSwarming.class, NON_FULL_USE_VARIOUS));
cards.add(new SetCardInfo("Skeletal Swarming", 389, Rarity.RARE, mage.cards.s.SkeletalSwarming.class, NON_FULL_USE_VARIOUS));
cards.add(new SetCardInfo("Skullport Merchant", 120, Rarity.UNCOMMON, mage.cards.s.SkullportMerchant.class));
cards.add(new SetCardInfo("Sorcerer Class", 233, Rarity.RARE, mage.cards.s.SorcererClass.class));
cards.add(new SetCardInfo("Soulknife Spy", 75, Rarity.COMMON, mage.cards.s.SoulknifeSpy.class));
cards.add(new SetCardInfo("Spare Dagger", 250, Rarity.COMMON, mage.cards.s.SpareDagger.class));
cards.add(new SetCardInfo("Sphere of Annihilation", 121, Rarity.RARE, mage.cards.s.SphereOfAnnihilation.class));
cards.add(new SetCardInfo("Sphere of Annihilation", 121, Rarity.RARE, mage.cards.s.SphereOfAnnihilation.class, NON_FULL_USE_VARIOUS));
cards.add(new SetCardInfo("Sphere of Annihilation", 376, Rarity.RARE, mage.cards.s.SphereOfAnnihilation.class, NON_FULL_USE_VARIOUS));
cards.add(new SetCardInfo("Spiked Pit Trap", 251, Rarity.COMMON, mage.cards.s.SpikedPitTrap.class));
cards.add(new SetCardInfo("Split the Party", 76, Rarity.UNCOMMON, mage.cards.s.SplitTheParty.class));
cards.add(new SetCardInfo("Spoils of the Hunt", 205, Rarity.COMMON, mage.cards.s.SpoilsOfTheHunt.class));
cards.add(new SetCardInfo("Steadfast Paladin", 38, Rarity.COMMON, mage.cards.s.SteadfastPaladin.class));
cards.add(new SetCardInfo("Sudden Insight", 77, Rarity.UNCOMMON, mage.cards.s.SuddenInsight.class));
cards.add(new SetCardInfo("Swamp", 270, Rarity.LAND, mage.cards.basiclands.Swamp.class, NON_FULL_USE_VARIOUS));
cards.add(new SetCardInfo("Swamp", 271, Rarity.LAND, mage.cards.basiclands.Swamp.class, NON_FULL_USE_VARIOUS));
cards.add(new SetCardInfo("Swamp", 272, Rarity.LAND, mage.cards.basiclands.Swamp.class, NON_FULL_USE_VARIOUS));
cards.add(new SetCardInfo("Swamp", 273, Rarity.LAND, mage.cards.basiclands.Swamp.class, NON_FULL_USE_VARIOUS));
cards.add(new SetCardInfo("Swarming Goblins", 162, Rarity.COMMON, mage.cards.s.SwarmingGoblins.class));
cards.add(new SetCardInfo("Sylvan Shepherd", 206, Rarity.COMMON, mage.cards.s.SylvanShepherd.class));
cards.add(new SetCardInfo("Targ Nar, Demon-Fang Gnoll", 234, Rarity.UNCOMMON, mage.cards.t.TargNarDemonFangGnoll.class));
cards.add(new SetCardInfo("Tasha's Hideous Laughter", 78, Rarity.RARE, mage.cards.t.TashasHideousLaughter.class));
cards.add(new SetCardInfo("Teleportation Circle", 39, Rarity.RARE, mage.cards.t.TeleportationCircle.class));
cards.add(new SetCardInfo("Temple of the Dragon Queen", 260, Rarity.UNCOMMON, mage.cards.t.TempleOfTheDragonQueen.class));
cards.add(new SetCardInfo("The Blackstaff of Waterdeep", 48, Rarity.RARE, mage.cards.t.TheBlackstaffOfWaterdeep.class));
cards.add(new SetCardInfo("The Book of Exalted Deeds", 4, Rarity.MYTHIC, mage.cards.t.TheBookOfExaltedDeeds.class));
cards.add(new SetCardInfo("The Book of Vile Darkness", 91, Rarity.MYTHIC, mage.cards.t.TheBookOfVileDarkness.class));
cards.add(new SetCardInfo("The Deck of Many Things", 241, Rarity.MYTHIC, mage.cards.t.TheDeckOfManyThings.class));
cards.add(new SetCardInfo("The Tarrasque", 207, Rarity.MYTHIC, mage.cards.t.TheTarrasque.class));
cards.add(new SetCardInfo("Tasha's Hideous Laughter", 368, Rarity.RARE, mage.cards.t.TashasHideousLaughter.class, NON_FULL_USE_VARIOUS));
cards.add(new SetCardInfo("Tasha's Hideous Laughter", 78, Rarity.RARE, mage.cards.t.TashasHideousLaughter.class, NON_FULL_USE_VARIOUS));
cards.add(new SetCardInfo("Teleportation Circle", 364, Rarity.RARE, mage.cards.t.TeleportationCircle.class, NON_FULL_USE_VARIOUS));
cards.add(new SetCardInfo("Teleportation Circle", 39, Rarity.RARE, mage.cards.t.TeleportationCircle.class, NON_FULL_USE_VARIOUS));
cards.add(new SetCardInfo("Temple of the Dragon Queen", 260, Rarity.UNCOMMON, mage.cards.t.TempleOfTheDragonQueen.class, NON_FULL_USE_VARIOUS));
cards.add(new SetCardInfo("Temple of the Dragon Queen", 357, Rarity.UNCOMMON, mage.cards.t.TempleOfTheDragonQueen.class, NON_FULL_USE_VARIOUS));
cards.add(new SetCardInfo("The Blackstaff of Waterdeep", 365, Rarity.RARE, mage.cards.t.TheBlackstaffOfWaterdeep.class, NON_FULL_USE_VARIOUS));
cards.add(new SetCardInfo("The Blackstaff of Waterdeep", 48, Rarity.RARE, mage.cards.t.TheBlackstaffOfWaterdeep.class, NON_FULL_USE_VARIOUS));
cards.add(new SetCardInfo("The Book of Exalted Deeds", 359, Rarity.MYTHIC, mage.cards.t.TheBookOfExaltedDeeds.class, NON_FULL_USE_VARIOUS));
cards.add(new SetCardInfo("The Book of Exalted Deeds", 4, Rarity.MYTHIC, mage.cards.t.TheBookOfExaltedDeeds.class, NON_FULL_USE_VARIOUS));
cards.add(new SetCardInfo("The Book of Vile Darkness", 374, Rarity.MYTHIC, mage.cards.t.TheBookOfVileDarkness.class, NON_FULL_USE_VARIOUS));
cards.add(new SetCardInfo("The Book of Vile Darkness", 91, Rarity.MYTHIC, mage.cards.t.TheBookOfVileDarkness.class, NON_FULL_USE_VARIOUS));
cards.add(new SetCardInfo("The Deck of Many Things", 241, Rarity.MYTHIC, mage.cards.t.TheDeckOfManyThings.class, NON_FULL_USE_VARIOUS));
cards.add(new SetCardInfo("The Deck of Many Things", 392, Rarity.MYTHIC, mage.cards.t.TheDeckOfManyThings.class, NON_FULL_USE_VARIOUS));
cards.add(new SetCardInfo("The Tarrasque", 207, Rarity.MYTHIC, mage.cards.t.TheTarrasque.class, NON_FULL_USE_VARIOUS));
cards.add(new SetCardInfo("The Tarrasque", 333, Rarity.MYTHIC, mage.cards.t.TheTarrasque.class, NON_FULL_USE_VARIOUS));
cards.add(new SetCardInfo("Thieves' Tools", 122, Rarity.COMMON, mage.cards.t.ThievesTools.class));
cards.add(new SetCardInfo("Tiamat", 235, Rarity.MYTHIC, mage.cards.t.Tiamat.class));
cards.add(new SetCardInfo("Tiamat", 235, Rarity.MYTHIC, mage.cards.t.Tiamat.class, NON_FULL_USE_VARIOUS));
cards.add(new SetCardInfo("Tiamat", 298, Rarity.MYTHIC, mage.cards.t.Tiamat.class, NON_FULL_USE_VARIOUS));
cards.add(new SetCardInfo("Tiger-Tribe Hunter", 163, Rarity.UNCOMMON, mage.cards.t.TigerTribeHunter.class));
cards.add(new SetCardInfo("Treasure Chest", 252, Rarity.RARE, mage.cards.t.TreasureChest.class));
cards.add(new SetCardInfo("Treasure Vault", 261, Rarity.RARE, mage.cards.t.TreasureVault.class));
cards.add(new SetCardInfo("Trelasarra, Moon Dancer", 236, Rarity.UNCOMMON, mage.cards.t.TrelasarraMoonDancer.class));
cards.add(new SetCardInfo("Treasure Chest", 252, Rarity.RARE, mage.cards.t.TreasureChest.class, NON_FULL_USE_VARIOUS));
cards.add(new SetCardInfo("Treasure Chest", 395, Rarity.RARE, mage.cards.t.TreasureChest.class, NON_FULL_USE_VARIOUS));
cards.add(new SetCardInfo("Treasure Chest", 397, Rarity.RARE, mage.cards.t.TreasureChest.class, NON_FULL_USE_VARIOUS));
cards.add(new SetCardInfo("Treasure Vault", 261, Rarity.RARE, mage.cards.t.TreasureVault.class, NON_FULL_USE_VARIOUS));
cards.add(new SetCardInfo("Treasure Vault", 358, Rarity.RARE, mage.cards.t.TreasureVault.class, NON_FULL_USE_VARIOUS));
cards.add(new SetCardInfo("Trelasarra, Moon Dancer", 236, Rarity.UNCOMMON, mage.cards.t.TrelasarraMoonDancer.class, NON_FULL_USE_VARIOUS));
cards.add(new SetCardInfo("Trelasarra, Moon Dancer", 346, Rarity.UNCOMMON, mage.cards.t.TrelasarraMoonDancer.class, NON_FULL_USE_VARIOUS));
cards.add(new SetCardInfo("Trickster's Talisman", 79, Rarity.UNCOMMON, mage.cards.t.TrickstersTalisman.class));
cards.add(new SetCardInfo("Triumphant Adventurer", 237, Rarity.RARE, mage.cards.t.TriumphantAdventurer.class));
cards.add(new SetCardInfo("True Polymorph", 80, Rarity.RARE, mage.cards.t.TruePolymorph.class));
cards.add(new SetCardInfo("Underdark Basilisk", 208, Rarity.COMMON, mage.cards.u.UnderdarkBasilisk.class));
cards.add(new SetCardInfo("Triumphant Adventurer", 237, Rarity.RARE, mage.cards.t.TriumphantAdventurer.class, NON_FULL_USE_VARIOUS));
cards.add(new SetCardInfo("Triumphant Adventurer", 390, Rarity.RARE, mage.cards.t.TriumphantAdventurer.class, NON_FULL_USE_VARIOUS));
cards.add(new SetCardInfo("True Polymorph", 369, Rarity.RARE, mage.cards.t.TruePolymorph.class, NON_FULL_USE_VARIOUS));
cards.add(new SetCardInfo("True Polymorph", 80, Rarity.RARE, mage.cards.t.TruePolymorph.class, NON_FULL_USE_VARIOUS));
cards.add(new SetCardInfo("Underdark Basilisk", 208, Rarity.COMMON, mage.cards.u.UnderdarkBasilisk.class, NON_FULL_USE_VARIOUS));
cards.add(new SetCardInfo("Underdark Basilisk", 334, Rarity.COMMON, mage.cards.u.UnderdarkBasilisk.class, NON_FULL_USE_VARIOUS));
cards.add(new SetCardInfo("Unexpected Windfall", 164, Rarity.COMMON, mage.cards.u.UnexpectedWindfall.class));
cards.add(new SetCardInfo("Valor Singer", 165, Rarity.COMMON, mage.cards.v.ValorSinger.class));
cards.add(new SetCardInfo("Vampire Spawn", 123, Rarity.COMMON, mage.cards.v.VampireSpawn.class));
cards.add(new SetCardInfo("Varis, Silverymoon Ranger", 209, Rarity.RARE, mage.cards.v.VarisSilverymoonRanger.class));
cards.add(new SetCardInfo("Varis, Silverymoon Ranger", 209, Rarity.RARE, mage.cards.v.VarisSilverymoonRanger.class, NON_FULL_USE_VARIOUS));
cards.add(new SetCardInfo("Varis, Silverymoon Ranger", 335, Rarity.RARE, mage.cards.v.VarisSilverymoonRanger.class, NON_FULL_USE_VARIOUS));
cards.add(new SetCardInfo("Veteran Dungeoneer", 40, Rarity.COMMON, mage.cards.v.VeteranDungeoneer.class));
cards.add(new SetCardInfo("Volo, Guide to Monsters", 238, Rarity.RARE, mage.cards.v.VoloGuideToMonsters.class));
cards.add(new SetCardInfo("Vorpal Sword", 124, Rarity.RARE, mage.cards.v.VorpalSword.class));
cards.add(new SetCardInfo("Volo, Guide to Monsters", 238, Rarity.RARE, mage.cards.v.VoloGuideToMonsters.class, NON_FULL_USE_VARIOUS));
cards.add(new SetCardInfo("Volo, Guide to Monsters", 347, Rarity.RARE, mage.cards.v.VoloGuideToMonsters.class, NON_FULL_USE_VARIOUS));
cards.add(new SetCardInfo("Vorpal Sword", 124, Rarity.RARE, mage.cards.v.VorpalSword.class, NON_FULL_USE_VARIOUS));
cards.add(new SetCardInfo("Vorpal Sword", 377, Rarity.RARE, mage.cards.v.VorpalSword.class, NON_FULL_USE_VARIOUS));
cards.add(new SetCardInfo("Vorpal Sword", 396, Rarity.RARE, mage.cards.v.VorpalSword.class, NON_FULL_USE_VARIOUS));
cards.add(new SetCardInfo("Wandering Troubadour", 210, Rarity.UNCOMMON, mage.cards.w.WanderingTroubadour.class));
cards.add(new SetCardInfo("Warlock Class", 125, Rarity.UNCOMMON, mage.cards.w.WarlockClass.class));
cards.add(new SetCardInfo("Werewolf Pack Leader", 211, Rarity.RARE, mage.cards.w.WerewolfPackLeader.class));
cards.add(new SetCardInfo("Westgate Regent", 126, Rarity.RARE, mage.cards.w.WestgateRegent.class));
cards.add(new SetCardInfo("White Dragon", 41, Rarity.UNCOMMON, mage.cards.w.WhiteDragon.class));
cards.add(new SetCardInfo("Wight", 127, Rarity.RARE, mage.cards.w.Wight.class));
cards.add(new SetCardInfo("Werewolf Pack Leader", 211, Rarity.RARE, mage.cards.w.WerewolfPackLeader.class, NON_FULL_USE_VARIOUS));
cards.add(new SetCardInfo("Werewolf Pack Leader", 387, Rarity.RARE, mage.cards.w.WerewolfPackLeader.class, NON_FULL_USE_VARIOUS));
cards.add(new SetCardInfo("Westgate Regent", 126, Rarity.RARE, mage.cards.w.WestgateRegent.class, NON_FULL_USE_VARIOUS));
cards.add(new SetCardInfo("Westgate Regent", 315, Rarity.RARE, mage.cards.w.WestgateRegent.class, NON_FULL_USE_VARIOUS));
cards.add(new SetCardInfo("White Dragon", 288, Rarity.UNCOMMON, mage.cards.w.WhiteDragon.class, NON_FULL_USE_VARIOUS));
cards.add(new SetCardInfo("White Dragon", 41, Rarity.UNCOMMON, mage.cards.w.WhiteDragon.class, NON_FULL_USE_VARIOUS));
cards.add(new SetCardInfo("Wight", 127, Rarity.RARE, mage.cards.w.Wight.class, NON_FULL_USE_VARIOUS));
cards.add(new SetCardInfo("Wight", 316, Rarity.RARE, mage.cards.w.Wight.class, NON_FULL_USE_VARIOUS));
cards.add(new SetCardInfo("Wild Shape", 212, Rarity.UNCOMMON, mage.cards.w.WildShape.class));
cards.add(new SetCardInfo("Wish", 166, Rarity.RARE, mage.cards.w.Wish.class));
cards.add(new SetCardInfo("Wish", 166, Rarity.RARE, mage.cards.w.Wish.class, NON_FULL_USE_VARIOUS));
cards.add(new SetCardInfo("Wish", 382, Rarity.RARE, mage.cards.w.Wish.class, NON_FULL_USE_VARIOUS));
cards.add(new SetCardInfo("Wizard Class", 81, Rarity.UNCOMMON, mage.cards.w.WizardClass.class));
cards.add(new SetCardInfo("Wizard's Spellbook", 82, Rarity.RARE, mage.cards.w.WizardsSpellbook.class));
cards.add(new SetCardInfo("Xorn", 167, Rarity.RARE, mage.cards.x.Xorn.class));
cards.add(new SetCardInfo("Wizard's Spellbook", 370, Rarity.RARE, mage.cards.w.WizardsSpellbook.class, NON_FULL_USE_VARIOUS));
cards.add(new SetCardInfo("Wizard's Spellbook", 82, Rarity.RARE, mage.cards.w.WizardsSpellbook.class, NON_FULL_USE_VARIOUS));
cards.add(new SetCardInfo("Xanathar, Guild Kingpin", 239, Rarity.MYTHIC, mage.cards.x.XanatharGuildKingpin.class, NON_FULL_USE_VARIOUS));
cards.add(new SetCardInfo("Xanathar, Guild Kingpin", 391, Rarity.MYTHIC, mage.cards.x.XanatharGuildKingpin.class, NON_FULL_USE_VARIOUS));
cards.add(new SetCardInfo("Xorn", 167, Rarity.RARE, mage.cards.x.Xorn.class, NON_FULL_USE_VARIOUS));
cards.add(new SetCardInfo("Xorn", 322, Rarity.RARE, mage.cards.x.Xorn.class, NON_FULL_USE_VARIOUS));
cards.add(new SetCardInfo("You Come to a River", 83, Rarity.COMMON, mage.cards.y.YouComeToARiver.class));
cards.add(new SetCardInfo("You Come to the Gnoll Camp", 168, Rarity.COMMON, mage.cards.y.YouComeToTheGnollCamp.class));
cards.add(new SetCardInfo("You Find Some Prisoners", 169, Rarity.UNCOMMON, mage.cards.y.YouFindSomePrisoners.class));
cards.add(new SetCardInfo("You Find a Cursed Idol", 213, Rarity.COMMON, mage.cards.y.YouFindACursedIdol.class));
cards.add(new SetCardInfo("You Find the Villains' Lair", 84, Rarity.COMMON, mage.cards.y.YouFindTheVillainsLair.class));
cards.add(new SetCardInfo("You Find the Villains' Lair", 399, Rarity.COMMON, mage.cards.y.YouFindTheVillainsLair.class, NON_FULL_USE_VARIOUS));
cards.add(new SetCardInfo("You Find the Villains' Lair", 84, Rarity.COMMON, mage.cards.y.YouFindTheVillainsLair.class, NON_FULL_USE_VARIOUS));
cards.add(new SetCardInfo("You Happen On a Glade", 214, Rarity.UNCOMMON, mage.cards.y.YouHappenOnAGlade.class));
cards.add(new SetCardInfo("You Hear Something on Watch", 42, Rarity.COMMON, mage.cards.y.YouHearSomethingOnWatch.class));
cards.add(new SetCardInfo("You Meet in a Tavern", 215, Rarity.UNCOMMON, mage.cards.y.YouMeetInATavern.class));
@ -294,9 +427,12 @@ public final class AdventuresInTheForgottenRealms extends ExpansionSet {
cards.add(new SetCardInfo("You See a Pair of Goblins", 170, Rarity.UNCOMMON, mage.cards.y.YouSeeAPairOfGoblins.class));
cards.add(new SetCardInfo("You're Ambushed on the Road", 43, Rarity.COMMON, mage.cards.y.YoureAmbushedOnTheRoad.class));
cards.add(new SetCardInfo("Yuan-Ti Fang-Blade", 128, Rarity.COMMON, mage.cards.y.YuanTiFangBlade.class));
cards.add(new SetCardInfo("Yuan-Ti Malison", 86, Rarity.RARE, mage.cards.y.YuanTiMalison.class));
cards.add(new SetCardInfo("Zalto, Fire Giant Duke", 171, Rarity.RARE, mage.cards.z.ZaltoFireGiantDuke.class));
cards.add(new SetCardInfo("Zariel, Archduke of Avernus", 172, Rarity.MYTHIC, mage.cards.z.ZarielArchdukeOfAvernus.class));
cards.add(new SetCardInfo("Yuan-Ti Malison", 371, Rarity.RARE, mage.cards.y.YuanTiMalison.class, NON_FULL_USE_VARIOUS));
cards.add(new SetCardInfo("Yuan-Ti Malison", 86, Rarity.RARE, mage.cards.y.YuanTiMalison.class, NON_FULL_USE_VARIOUS));
cards.add(new SetCardInfo("Zalto, Fire Giant Duke", 171, Rarity.RARE, mage.cards.z.ZaltoFireGiantDuke.class, NON_FULL_USE_VARIOUS));
cards.add(new SetCardInfo("Zalto, Fire Giant Duke", 323, Rarity.RARE, mage.cards.z.ZaltoFireGiantDuke.class, NON_FULL_USE_VARIOUS));
cards.add(new SetCardInfo("Zariel, Archduke of Avernus", 172, Rarity.MYTHIC, mage.cards.z.ZarielArchdukeOfAvernus.class, NON_FULL_USE_VARIOUS));
cards.add(new SetCardInfo("Zariel, Archduke of Avernus", 285, Rarity.MYTHIC, mage.cards.z.ZarielArchdukeOfAvernus.class, NON_FULL_USE_VARIOUS));
cards.add(new SetCardInfo("Zombie Ogre", 129, Rarity.COMMON, mage.cards.z.ZombieOgre.class));
}
}

View file

@ -23,8 +23,8 @@ public final class AlaraReborn extends ExpansionSet {
this.parentSet = ShardsOfAlara.getInstance();
this.hasBasicLands = false;
this.hasBoosters = true;
this.numBoosterLands = 0;
this.numBoosterCommon = 11;
this.numBoosterLands = 1;
this.numBoosterCommon = 10;
this.numBoosterUncommon = 3;
this.numBoosterRare = 1;
this.ratioBoosterMythic = 8;

View file

@ -23,8 +23,8 @@ public final class BornOfTheGods extends ExpansionSet {
this.parentSet = Theros.getInstance();
this.hasBasicLands = false;
this.hasBoosters = true;
this.numBoosterLands = 0;
this.numBoosterCommon = 11;
this.numBoosterLands = 1;
this.numBoosterCommon = 10;
this.numBoosterUncommon = 3;
this.numBoosterRare = 1;
this.ratioBoosterMythic = 8;

View file

@ -23,8 +23,8 @@ public final class Conflux extends ExpansionSet {
this.parentSet = ShardsOfAlara.getInstance();
this.hasBasicLands = false;
this.hasBoosters = true;
this.numBoosterLands = 0;
this.numBoosterCommon = 11;
this.numBoosterLands = 1;
this.numBoosterCommon = 10;
this.numBoosterUncommon = 3;
this.numBoosterRare = 1;
this.ratioBoosterMythic = 8;

View file

@ -22,8 +22,8 @@ public final class RivalsOfIxalan extends ExpansionSet {
this.parentSet = Ixalan.getInstance();
this.hasBoosters = true;
this.hasBasicLands = true;
this.numBoosterLands = 0;
this.numBoosterCommon = 11;
this.numBoosterLands = 1;
this.numBoosterCommon = 10;
this.numBoosterUncommon = 3;
this.numBoosterRare = 1;
this.ratioBoosterMythic = 8;

View file

@ -415,7 +415,7 @@ class TherosBeyondDeathCollator implements BoosterCollator {
}
private static class TherosBeyondDeathStructure extends BoosterStructure {
private static final TherosBeyondDeathStructure C1 = new TherosBeyondDeathStructure(
private static final TherosBeyondDeathStructure AABBC1C1C1C1C1C1 = new TherosBeyondDeathStructure(
TherosBeyondDeathRun.commonA,
TherosBeyondDeathRun.commonA,
TherosBeyondDeathRun.commonB,
@ -427,7 +427,7 @@ class TherosBeyondDeathCollator implements BoosterCollator {
TherosBeyondDeathRun.commonC1,
TherosBeyondDeathRun.commonC1
);
private static final TherosBeyondDeathStructure C2 = new TherosBeyondDeathStructure(
private static final TherosBeyondDeathStructure AAABBC1C1C1C1C1 = new TherosBeyondDeathStructure(
TherosBeyondDeathRun.commonA,
TherosBeyondDeathRun.commonA,
TherosBeyondDeathRun.commonA,
@ -439,7 +439,7 @@ class TherosBeyondDeathCollator implements BoosterCollator {
TherosBeyondDeathRun.commonC1,
TherosBeyondDeathRun.commonC1
);
private static final TherosBeyondDeathStructure C3 = new TherosBeyondDeathStructure(
private static final TherosBeyondDeathStructure AAAABBC2C2C2C2 = new TherosBeyondDeathStructure(
TherosBeyondDeathRun.commonA,
TherosBeyondDeathRun.commonA,
TherosBeyondDeathRun.commonA,
@ -451,7 +451,7 @@ class TherosBeyondDeathCollator implements BoosterCollator {
TherosBeyondDeathRun.commonC2,
TherosBeyondDeathRun.commonC2
);
private static final TherosBeyondDeathStructure C4 = new TherosBeyondDeathStructure(
private static final TherosBeyondDeathStructure AAAABBBC2C2C2 = new TherosBeyondDeathStructure(
TherosBeyondDeathRun.commonA,
TherosBeyondDeathRun.commonA,
TherosBeyondDeathRun.commonA,
@ -463,7 +463,7 @@ class TherosBeyondDeathCollator implements BoosterCollator {
TherosBeyondDeathRun.commonC2,
TherosBeyondDeathRun.commonC2
);
private static final TherosBeyondDeathStructure C5 = new TherosBeyondDeathStructure(
private static final TherosBeyondDeathStructure AAAABBBBC2C2 = new TherosBeyondDeathStructure(
TherosBeyondDeathRun.commonA,
TherosBeyondDeathRun.commonA,
TherosBeyondDeathRun.commonA,
@ -475,12 +475,12 @@ class TherosBeyondDeathCollator implements BoosterCollator {
TherosBeyondDeathRun.commonC2,
TherosBeyondDeathRun.commonC2
);
private static final TherosBeyondDeathStructure U1 = new TherosBeyondDeathStructure(
private static final TherosBeyondDeathStructure ABB = new TherosBeyondDeathStructure(
TherosBeyondDeathRun.uncommonA,
TherosBeyondDeathRun.uncommonB,
TherosBeyondDeathRun.uncommonB
);
private static final TherosBeyondDeathStructure U2 = new TherosBeyondDeathStructure(
private static final TherosBeyondDeathStructure AAB = new TherosBeyondDeathStructure(
TherosBeyondDeathRun.uncommonA,
TherosBeyondDeathRun.uncommonA,
TherosBeyondDeathRun.uncommonB
@ -500,24 +500,41 @@ class TherosBeyondDeathCollator implements BoosterCollator {
}
}
// In order for equal numbers of each common to exist, the average booster must contain:
// 3.28 A commons (36 / 11)
// 2.18 B commons (24 / 11)
// 2.72 C1 commons (30 / 11, or 60 / 11 in each C1 booster)
// 1.81 C2 commons (20 / 11, or 40 / 11 in each C2 booster)
// (these numbers are the same for all sets with 101 commons and 10 common slots per booster)
private final RarityConfiguration commonRuns = new RarityConfiguration(
false,
TherosBeyondDeathStructure.C1,
TherosBeyondDeathStructure.C2,
TherosBeyondDeathStructure.C3,
TherosBeyondDeathStructure.C4,
TherosBeyondDeathStructure.C5,
TherosBeyondDeathStructure.C1,
TherosBeyondDeathStructure.C2,
TherosBeyondDeathStructure.C3,
TherosBeyondDeathStructure.C4,
TherosBeyondDeathStructure.C5,
TherosBeyondDeathStructure.C4,
TherosBeyondDeathStructure.C5
TherosBeyondDeathStructure.AABBC1C1C1C1C1C1,
TherosBeyondDeathStructure.AABBC1C1C1C1C1C1,
TherosBeyondDeathStructure.AABBC1C1C1C1C1C1,
TherosBeyondDeathStructure.AABBC1C1C1C1C1C1,
TherosBeyondDeathStructure.AABBC1C1C1C1C1C1,
TherosBeyondDeathStructure.AAABBC1C1C1C1C1,
TherosBeyondDeathStructure.AAABBC1C1C1C1C1,
TherosBeyondDeathStructure.AAABBC1C1C1C1C1,
TherosBeyondDeathStructure.AAABBC1C1C1C1C1,
TherosBeyondDeathStructure.AAABBC1C1C1C1C1,
TherosBeyondDeathStructure.AAABBC1C1C1C1C1,
TherosBeyondDeathStructure.AAAABBC2C2C2C2,
TherosBeyondDeathStructure.AAAABBC2C2C2C2,
TherosBeyondDeathStructure.AAAABBC2C2C2C2,
TherosBeyondDeathStructure.AAAABBC2C2C2C2,
TherosBeyondDeathStructure.AAAABBC2C2C2C2,
TherosBeyondDeathStructure.AAAABBC2C2C2C2,
TherosBeyondDeathStructure.AAAABBC2C2C2C2,
TherosBeyondDeathStructure.AAAABBC2C2C2C2,
TherosBeyondDeathStructure.AAAABBBC2C2C2,
TherosBeyondDeathStructure.AAAABBBC2C2C2,
TherosBeyondDeathStructure.AAAABBBBC2C2
);
private final RarityConfiguration uncommonRuns = new RarityConfiguration(
TherosBeyondDeathStructure.U1,
TherosBeyondDeathStructure.U2
TherosBeyondDeathStructure.ABB,
TherosBeyondDeathStructure.AAB
);
private final RarityConfiguration rareRuns = new RarityConfiguration(
false,

View file

@ -23,8 +23,8 @@ public final class Worldwake extends ExpansionSet {
this.parentSet = Zendikar.getInstance();
this.hasBasicLands = false;
this.hasBoosters = true;
this.numBoosterLands = 0;
this.numBoosterCommon = 11;
this.numBoosterLands = 1;
this.numBoosterCommon = 10;
this.numBoosterUncommon = 3;
this.numBoosterRare = 1;
this.ratioBoosterMythic = 8;

View file

@ -6,7 +6,7 @@
<parent>
<groupId>org.mage</groupId>
<artifactId>mage-root</artifactId>
<version>1.4.49</version>
<version>1.4.50</version>
</parent>
<artifactId>mage-tests</artifactId>

View file

@ -0,0 +1,61 @@
package org.mage.test.cards.single.afr;
import mage.constants.PhaseStep;
import mage.constants.Zone;
import org.junit.Test;
import org.mage.test.serverside.base.CardTestPlayerBase;
/**
* @author JayDi85
*/
public class XanatharGuildKingpinTest extends CardTestPlayerBase {
@Test
public void test_Play() {
removeAllCardsFromLibrary(playerA);
removeAllCardsFromLibrary(playerB);
skipInitShuffling();
// At the beginning of your upkeep, choose target opponent.
// Until end of turn, that player cant cast spells, you may look at the top card of their library any time,
// you may play the top card of their library, and you may spend mana as though it were mana of any color
// to cast spells this way.
addCard(Zone.BATTLEFIELD, playerA, "Xanathar, Guild Kingpin");
//
addCard(Zone.BATTLEFIELD, playerA, "Mountain", 2);
addCard(Zone.BATTLEFIELD, playerA, "Swamp", 2);
//
addCard(Zone.HAND, playerA, "Thunderbolt");
//
addCard(Zone.HAND, playerB, "Lightning Bolt");
addCard(Zone.BATTLEFIELD, playerB, "Mountain", 2);
//
addCard(Zone.LIBRARY, playerB, "Mountain");
addCard(Zone.LIBRARY, playerB, "Lightning Bolt");
addCard(Zone.LIBRARY, playerB, "Grizzly Bears");
// activate on opponent
addTarget(playerA, playerB);
// B can't cast spells
checkPlayableAbility("B can't cast", 1, PhaseStep.PRECOMBAT_MAIN, playerB, "Cast Lightning Bolt", false);
// A can cast own and from B library
checkPlayableAbility("A can cast own", 1, PhaseStep.PRECOMBAT_MAIN, playerA, "Cast Thunderbolt", true);
checkPlayableAbility("A can cast from B", 1, PhaseStep.PRECOMBAT_MAIN, playerA, "Cast Grizzly Bears", true);
// cast from B and try another one with any color and full stack
activateManaAbility(1, PhaseStep.PRECOMBAT_MAIN, playerA, "{T}: Add {B}", 2); // pay for {G} as any
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Grizzly Bears");
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Lightning Bolt", null, "Grizzly Bears");
addTarget(playerA, playerB); // bolt
checkStackSize("multi cast", 1, PhaseStep.PRECOMBAT_MAIN, playerA, 2);
// B can cast again
checkPlayableAbility("B can cast", 2, PhaseStep.PRECOMBAT_MAIN, playerB, "Cast Lightning Bolt", true);
setStrictChooseMode(true);
setStopAt(2, PhaseStep.END_TURN);
execute();
assertAllCommandsUsed();
}
}

View file

@ -6,7 +6,7 @@
<parent>
<groupId>org.mage</groupId>
<artifactId>mage-root</artifactId>
<version>1.4.49</version>
<version>1.4.50</version>
</parent>
<artifactId>mage-verify</artifactId>

View file

@ -6,7 +6,7 @@
<parent>
<groupId>org.mage</groupId>
<artifactId>mage-root</artifactId>
<version>1.4.49</version>
<version>1.4.50</version>
</parent>
<artifactId>mage</artifactId>

View file

@ -7,18 +7,15 @@ import mage.filter.StaticFilters;
import mage.filter.common.FilterCreaturePermanent;
import mage.game.Game;
import mage.game.events.GameEvent;
import mage.game.permanent.Permanent;
import mage.util.CardUtil;
import java.util.UUID;
/**
* @author Styxo
*/
public class AttacksWithCreaturesTriggeredAbility extends TriggeredAbilityImpl {
private FilterCreaturePermanent filter;
private int minAttackers;
private final FilterCreaturePermanent filter;
private final int minAttackers;
public AttacksWithCreaturesTriggeredAbility(Effect effect, int minAttackers) {
this(effect, minAttackers, StaticFilters.FILTER_PERMANENT_CREATURES);
@ -52,28 +49,26 @@ public class AttacksWithCreaturesTriggeredAbility extends TriggeredAbilityImpl {
@Override
public boolean checkTrigger(GameEvent event, Game game) {
if (game.getCombat().getAttackingPlayerId().equals(getControllerId())) {
int attackerCount = 0;
for (UUID attackerId : game.getCombat().getAttackers()) {
Permanent attacker = game.getPermanent(attackerId);
if (filter.match(attacker, game)) {
attackerCount++;
}
}
return attackerCount >= minAttackers;
}
return false;
return isControlledBy(game.getCombat().getAttackingPlayerId())
&& game
.getCombat()
.getAttackers()
.stream()
.map(game::getPermanent)
.filter(permanent -> filter.match(permanent, sourceId, controllerId, game))
.mapToInt(x -> 1).sum() > minAttackers;
}
@Override
public String getTriggerPhrase() {
if (minAttackers == 0) {
if (minAttackers == 1) {
return "Whenever you attack, ";
}
StringBuilder sb = new StringBuilder("Whenever you attack with " + CardUtil.numberToText(minAttackers) + " or more ");
StringBuilder sb = new StringBuilder("Whenever you attack with ");
sb.append(CardUtil.numberToText(minAttackers));
sb.append(" or more ");
sb.append(filter.getMessage());
sb.append(", ");
return sb.toString();
}
}

View file

@ -241,7 +241,7 @@ public abstract class ManaCostImpl extends CostImpl implements ManaCost {
assignPayment(game, ability, player.getManaPool(), costToPay != null ? costToPay : this);
}
game.getState().getSpecialActions().removeManaActions();
while (!isPaid()) {
while (player.canRespond() && !isPaid()) {
ManaCost unpaid = this.getUnpaid();
String promptText = ManaUtil.addSpecialManaPayAbilities(ability, game, unpaid);
if (player.playMana(ability, unpaid, promptText, game)) {
@ -251,7 +251,7 @@ public abstract class ManaCostImpl extends CostImpl implements ManaCost {
}
game.getState().getSpecialActions().removeManaActions();
}
return true;
return isPaid();
}
@Override

View file

@ -128,7 +128,7 @@ public class ManaCostsImpl<T extends ManaCost> extends ArrayList<T> implements M
assignPayment(game, ability, player.getManaPool(), this);
}
game.getState().getSpecialActions().removeManaActions();
while (!isPaid()) {
while (player.canRespond() && !isPaid()) {
ManaCost unpaid = this.getUnpaid();
String promptText = ManaUtil.addSpecialManaPayAbilities(ability, game, unpaid);
if (player.playMana(ability, unpaid, promptText, game)) {
@ -138,7 +138,7 @@ public class ManaCostsImpl<T extends ManaCost> extends ArrayList<T> implements M
}
game.getState().getSpecialActions().removeManaActions();
}
return true;
return isPaid();
}
/**

View file

@ -4,25 +4,51 @@ import mage.MageObject;
import mage.abilities.Ability;
import mage.abilities.effects.ContinuousEffectImpl;
import mage.cards.Card;
import mage.constants.Duration;
import mage.constants.Layer;
import mage.constants.Outcome;
import mage.constants.SubLayer;
import mage.constants.*;
import mage.game.Game;
import mage.players.Player;
import mage.util.CardUtil;
import java.util.HashSet;
import java.util.Objects;
import java.util.Set;
import java.util.UUID;
/**
* @author TheElk801
*/
public class LookAtTopCardOfLibraryAnyTimeEffect extends ContinuousEffectImpl {
private final TargetController targetLibrary;
public LookAtTopCardOfLibraryAnyTimeEffect() {
super(Duration.WhileOnBattlefield, Layer.PlayerEffects, SubLayer.NA, Outcome.Benefit);
staticText = "You may look at the top card of your library any time.";
this(TargetController.YOU, Duration.WhileOnBattlefield);
}
private LookAtTopCardOfLibraryAnyTimeEffect(final LookAtTopCardOfLibraryAnyTimeEffect effect) {
public LookAtTopCardOfLibraryAnyTimeEffect(TargetController targetLibrary, Duration duration) {
super(duration, Layer.PlayerEffects, SubLayer.NA, Outcome.Benefit);
this.targetLibrary = targetLibrary;
String libInfo;
switch (this.targetLibrary) {
case YOU:
libInfo = "your library";
break;
case OPPONENT:
libInfo = "opponents libraries";
break;
case SOURCE_TARGETS:
libInfo = "target player's library";
break;
default:
throw new IllegalArgumentException("Unknown target library type: " + targetLibrary);
}
staticText = duration.toString().isEmpty() ? "" : duration + " you may look at the top card of " + libInfo + " any time.";
}
protected LookAtTopCardOfLibraryAnyTimeEffect(final LookAtTopCardOfLibraryAnyTimeEffect effect) {
super(effect);
this.targetLibrary = effect.targetLibrary;
}
@Override
@ -34,18 +60,46 @@ public class LookAtTopCardOfLibraryAnyTimeEffect extends ContinuousEffectImpl {
if (controller == null) {
return false;
}
Card topCard = controller.getLibrary().getFromTop(game);
if (topCard == null) {
if (!canLookAtNextTopLibraryCard(game)) {
return false;
}
MageObject obj = source.getSourceObject(game);
if (obj == null) {
return false;
}
if (!canLookAtNextTopLibraryCard(game)) {
Set<UUID> needPlayers = new HashSet<>();
switch (this.targetLibrary) {
case YOU: {
needPlayers.add(source.getControllerId());
break;
}
case OPPONENT: {
needPlayers.addAll(game.getOpponents(source.getControllerId()));
break;
}
case SOURCE_TARGETS: {
needPlayers.addAll(CardUtil.getAllSelectedTargets(source, game));
break;
}
}
Set<Card> needCards = new HashSet<>();
needPlayers.stream()
.map(game::getPlayer)
.filter(Objects::nonNull)
.map(player -> player.getLibrary().getFromTop(game))
.filter(Objects::nonNull)
.forEach(needCards::add);
if (needCards.isEmpty()) {
return false;
}
controller.lookAtCards("Top card of " + obj.getIdName() + " controller's library", topCard, game);
// all fine, can show top card
needCards.forEach(topCard -> {
Player owner = game.getPlayer(topCard.getOwnerId());
controller.lookAtCards(String.format("%s: top card of %s", obj.getName(), owner == null ? "error" : owner.getName()), topCard, game);
});
return true;
}

View file

@ -0,0 +1,23 @@
package mage.abilities.effects.common.continuous;
import mage.constants.Duration;
import mage.constants.TargetController;
/**
* @author JayDi85
*/
public class LookAtTopCardOfLibraryAnyTimeTargetEffect extends LookAtTopCardOfLibraryAnyTimeEffect {
public LookAtTopCardOfLibraryAnyTimeTargetEffect(Duration duration) {
super(TargetController.SOURCE_TARGETS, duration);
}
private LookAtTopCardOfLibraryAnyTimeTargetEffect(final LookAtTopCardOfLibraryAnyTimeTargetEffect effect) {
super(effect);
}
@Override
public LookAtTopCardOfLibraryAnyTimeTargetEffect copy() {
return new LookAtTopCardOfLibraryAnyTimeTargetEffect(this);
}
}

View file

@ -6,11 +6,14 @@ import mage.cards.Card;
import mage.constants.AsThoughEffectType;
import mage.constants.Duration;
import mage.constants.Outcome;
import mage.constants.TargetController;
import mage.filter.FilterCard;
import mage.game.Game;
import mage.players.Player;
import mage.util.CardUtil;
import java.util.Locale;
import java.util.Objects;
import java.util.UUID;
/**
@ -19,20 +22,44 @@ import java.util.UUID;
public class PlayTheTopCardEffect extends AsThoughEffectImpl {
private final FilterCard filter;
private final TargetController targetLibrary;
// can play card or can play lands/cast spells, see two modes below
private final boolean canPlayCardOnly;
/**
* Support targets, use TargetController.SOURCE_TARGETS
*/
public PlayTheTopCardEffect() {
this(new FilterCard("play lands and cast spells"), false);
this(TargetController.YOU);
}
public PlayTheTopCardEffect(FilterCard filter, boolean canPlayCardOnly) {
public PlayTheTopCardEffect(TargetController targetLibrary) {
this(targetLibrary, new FilterCard("play lands and cast spells"), false);
}
public PlayTheTopCardEffect(TargetController targetLibrary, FilterCard filter, boolean canPlayCardOnly) {
super(AsThoughEffectType.PLAY_FROM_NOT_OWN_HAND_ZONE, Duration.WhileOnBattlefield, Outcome.Benefit);
this.filter = filter;
this.targetLibrary = targetLibrary;
this.canPlayCardOnly = canPlayCardOnly;
this.staticText = "You may " + filter.getMessage() + " from the top of your library";
String libInfo;
switch (this.targetLibrary) {
case YOU:
libInfo = "your library";
break;
case OPPONENT:
libInfo = "opponents libraries";
break;
case SOURCE_TARGETS:
libInfo = "target player's library";
break;
default:
throw new IllegalArgumentException("Unknown target library type: " + targetLibrary);
}
this.staticText = "You may " + filter.getMessage() + " from the top of " + libInfo;
// verify check: if you see "card" text in the rules then use card mode
// (there aren't any real cards after oracle update, but can be added in the future)
@ -44,6 +71,7 @@ public class PlayTheTopCardEffect extends AsThoughEffectImpl {
public PlayTheTopCardEffect(final PlayTheTopCardEffect effect) {
super(effect);
this.filter = effect.filter;
this.targetLibrary = effect.targetLibrary;
this.canPlayCardOnly = effect.canPlayCardOnly;
}
@ -71,7 +99,7 @@ public class PlayTheTopCardEffect extends AsThoughEffectImpl {
}
if (this.canPlayCardOnly) {
// check whole card intead part
// check whole card instead part
cardToCheck = cardToCheck.getMainCard();
}
@ -80,16 +108,50 @@ public class PlayTheTopCardEffect extends AsThoughEffectImpl {
return false;
}
// must be your card
Player player = game.getPlayer(cardToCheck.getOwnerId());
if (player == null || !player.getId().equals(affectedControllerId)) {
Player cardOwner = game.getPlayer(cardToCheck.getOwnerId());
Player controller = game.getPlayer(source.getControllerId());
if (cardOwner == null || controller == null) {
return false;
}
// must be from your library
Card topCard = player.getLibrary().getFromTop(game);
if (topCard == null || !topCard.getId().equals(cardToCheck.getMainCard().getId())) {
return false;
// must be your or opponents library
switch (this.targetLibrary) {
case YOU: {
Card topCard = controller.getLibrary().getFromTop(game);
if (topCard == null || !topCard.getId().equals(cardToCheck.getMainCard().getId())) {
return false;
}
break;
}
case OPPONENT: {
if (!game.getOpponents(controller.getId()).contains(cardOwner.getId())) {
return false;
}
Card topCard = cardOwner.getLibrary().getFromTop(game);
if (topCard == null || !topCard.getId().equals(cardToCheck.getMainCard().getId())) {
return false;
}
break;
}
case SOURCE_TARGETS: {
UUID needCardId = cardToCheck.getMainCard().getId();
if (CardUtil.getAllSelectedTargets(source, game).stream()
.map(game::getPlayer)
.filter(Objects::nonNull)
.noneMatch(player -> {
Card topCard = player.getLibrary().getFromTop(game);
return topCard != null && topCard.getId().equals(needCardId);
})) {
return false;
}
break;
}
default: {
return false;
}
}
// can't cast without mana cost

View file

@ -0,0 +1,22 @@
package mage.abilities.effects.common.continuous;
import mage.constants.TargetController;
/**
* @author JayDi85
*/
public class PlayTheTopCardTargetEffect extends PlayTheTopCardEffect {
public PlayTheTopCardTargetEffect() {
super(TargetController.SOURCE_TARGETS);
}
public PlayTheTopCardTargetEffect(final PlayTheTopCardTargetEffect effect) {
super(effect);
}
@Override
public PlayTheTopCardTargetEffect copy() {
return new PlayTheTopCardTargetEffect(this);
}
}

View file

@ -18,6 +18,8 @@ public class HintUtils {
public static final String HINT_ICON_BAD = "ICON_BAD";
public static final String HINT_ICON_RESTRICT = "ICON_RESTRICT";
public static final String HINT_ICON_REQUIRE = "ICON_REQUIRE";
public static final String HINT_ICON_DUNGEON_ROOM_CURRENT = "ICON_DUNGEON_ROOM_CURRENT";
public static final String HINT_ICON_DUNGEON_ROOM_NEXT = "ICON_DUNGEON_ROOM_NEXT";
//
public static final String HINT_START_MARK = "<br/><hintstart/>"; // workaround to find hint text in rules list and shows it in html
@ -34,7 +36,7 @@ public class HintUtils {
String hex = colorToHtml(color);
res = String.format("<font color=%s>%s</font>", hex, text);
} else {
res = text;
res = (text == null ? "" : text);
}
// icon

View file

@ -747,11 +747,19 @@ public abstract class CardImpl extends MageObjectImpl implements Card {
break;
}
GameEvent event = GameEvent.getEvent(GameEvent.EventType.COUNTER_REMOVED, objectId, source, getControllerOrOwner());
if (source != null
&& source.getControllerId() != null) {
event.setPlayerId(source.getControllerId()); // player who controls the source ability that removed the counter
}
event.setData(name);
game.fireEvent(event);
finalAmount++;
}
GameEvent event = GameEvent.getEvent(GameEvent.EventType.COUNTERS_REMOVED, objectId, source, getControllerOrOwner());
if (source != null
&& source.getControllerId() != null) {
event.setPlayerId(source.getControllerId()); // player who controls the source ability that removed the counter
}
event.setData(name);
event.setAmount(finalAmount);
game.fireEvent(event);

View file

@ -36,7 +36,7 @@ public enum CardRepository {
// raise this if db structure was changed
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 = 239;
private static final long CARD_CONTENT_VERSION = 240;
private Dao<CardInfo, Object> cardDao;
private Set<String> classNames;
private final RepositoryEventSource eventSource = new RepositoryEventSource();

View file

@ -28,7 +28,7 @@ public enum Outcome {
PutManaInPool(true),
Regenerate(true),
PreventDamage(true), // TODO: check good or bad
PreventCast(false), // TODO: check good or bad
PreventCast(false),
RedirectDamage(true), // TODO: check good or bad
Tap(false),
Transform(true),

View file

@ -25,7 +25,8 @@ public enum TargetController {
OWNER,
CONTROLLER_ATTACHED_TO,
NEXT,
EACH_PLAYER;
EACH_PLAYER,
SOURCE_TARGETS;
private final OwnerPredicate ownerPredicate;
private final PlayerPredicate playerPredicate;

View file

@ -11,11 +11,24 @@ import mage.players.Player;
*/
public enum CardOnTopOfLibraryPredicate implements ObjectPlayerPredicate<ObjectPlayer<Card>> {
instance;
YOUR,
ANY;
@Override
public boolean apply(ObjectPlayer<Card> input, Game game) {
Player player = game.getPlayer(input.getObject().getOwnerId());
Player player;
switch (this) {
case YOUR:
player = game.getPlayer(input.getPlayerId());
break;
case ANY:
default:
player = game.getPlayer(input.getObject().getOwnerId());
break;
}
if (player == null) {
return false;
}

View file

@ -11,6 +11,7 @@ import mage.abilities.costs.mana.ManaCosts;
import mage.abilities.costs.mana.ManaCostsImpl;
import mage.abilities.effects.ContinuousEffect;
import mage.abilities.effects.Effect;
import mage.abilities.hint.HintUtils;
import mage.abilities.text.TextPart;
import mage.cards.FrameStyle;
import mage.choices.Choice;
@ -125,7 +126,19 @@ public class Dungeon implements CommandObject {
"Currently in " + currentRoom.getName() :
"Not currently in a room"
) + ")</i>");
dungeonRooms.stream().map(DungeonRoom::toString).forEach(rules::add);
dungeonRooms.stream()
.map(room -> {
// mark useful rooms by icons
String prefix = "";
if (room.equals(currentRoom)) {
prefix += HintUtils.prepareText(null, null, HintUtils.HINT_ICON_DUNGEON_ROOM_CURRENT);
}
if (currentRoom != null && currentRoom.getNextRooms().stream().anyMatch(room::equals)) {
prefix += HintUtils.prepareText(null, null, HintUtils.HINT_ICON_DUNGEON_ROOM_NEXT);
}
return prefix + room;
})
.forEach(rules::add);
return rules;
}

View file

@ -24,10 +24,11 @@ public class BoosterDraft extends DraftImpl {
cardNum = 1;
fireUpdatePlayersEvent();
while (!isAbort() && pickCards()) {
if ((boosterNum + 1) % 2 == 1) {
passLeft();
// pass booster order: left -> right -> left
if (boosterNum % 2 == 1) {
passBoosterToLeft();
} else {
passRight();
passBoosterToRight();
}
fireUpdatePlayersEvent();
}

Some files were not shown because too many files have changed in this diff Show more