From 7b298f84a7b154ffde0e91c84133741bf273c9e4 Mon Sep 17 00:00:00 2001 From: Oleg Agafonov Date: Sat, 28 Aug 2021 11:34:28 +0400 Subject: [PATCH 01/14] Fixed comment --- Mage.Sets/src/mage/cards/d/DivineIntervention.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Mage.Sets/src/mage/cards/d/DivineIntervention.java b/Mage.Sets/src/mage/cards/d/DivineIntervention.java index 1759e3a7cbe..4319c0230b5 100644 --- a/Mage.Sets/src/mage/cards/d/DivineIntervention.java +++ b/Mage.Sets/src/mage/cards/d/DivineIntervention.java @@ -41,7 +41,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()); } From 2efdb464fcbee66aba32fba42643078f73a0bf3c Mon Sep 17 00:00:00 2001 From: Oleg Agafonov Date: Sat, 28 Aug 2021 12:09:22 +0400 Subject: [PATCH 02/14] Little refactor, additional logs for CheckPlayableState error; --- .../src/mage/player/human/HumanPlayer.java | 4 ++++ Mage.Sets/src/mage/cards/f/FadeAway.java | 2 +- Mage.Sets/src/mage/cards/s/ShroudedLore.java | 7 +++---- .../main/java/mage/abilities/costs/mana/ManaCostImpl.java | 4 ++-- .../main/java/mage/abilities/costs/mana/ManaCostsImpl.java | 4 ++-- 5 files changed, 12 insertions(+), 9 deletions(-) diff --git a/Mage.Server.Plugins/Mage.Player.Human/src/mage/player/human/HumanPlayer.java b/Mage.Server.Plugins/Mage.Player.Human/src/mage/player/human/HumanPlayer.java index ba1cfdc9c76..c97996682a0 100644 --- a/Mage.Server.Plugins/Mage.Player.Human/src/mage/player/human/HumanPlayer.java +++ b/Mage.Server.Plugins/Mage.Player.Human/src/mage/player/human/HumanPlayer.java @@ -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; diff --git a/Mage.Sets/src/mage/cards/f/FadeAway.java b/Mage.Sets/src/mage/cards/f/FadeAway.java index a9e70c3bb62..94b255845ed 100644 --- a/Mage.Sets/src/mage/cards/f/FadeAway.java +++ b/Mage.Sets/src/mage/cards/f/FadeAway.java @@ -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)); diff --git a/Mage.Sets/src/mage/cards/s/ShroudedLore.java b/Mage.Sets/src/mage/cards/s/ShroudedLore.java index 1d74a8a34d5..029746b868a 100644 --- a/Mage.Sets/src/mage/cards/s/ShroudedLore.java +++ b/Mage.Sets/src/mage/cards/s/ShroudedLore.java @@ -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; } } diff --git a/Mage/src/main/java/mage/abilities/costs/mana/ManaCostImpl.java b/Mage/src/main/java/mage/abilities/costs/mana/ManaCostImpl.java index 421ce7baae9..d0503b870cb 100644 --- a/Mage/src/main/java/mage/abilities/costs/mana/ManaCostImpl.java +++ b/Mage/src/main/java/mage/abilities/costs/mana/ManaCostImpl.java @@ -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 diff --git a/Mage/src/main/java/mage/abilities/costs/mana/ManaCostsImpl.java b/Mage/src/main/java/mage/abilities/costs/mana/ManaCostsImpl.java index bb2580d96d6..59e2e9dbd72 100644 --- a/Mage/src/main/java/mage/abilities/costs/mana/ManaCostsImpl.java +++ b/Mage/src/main/java/mage/abilities/costs/mana/ManaCostsImpl.java @@ -128,7 +128,7 @@ public class ManaCostsImpl extends ArrayList 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 extends ArrayList implements M } game.getState().getSpecialActions().removeManaActions(); } - return true; + return isPaid(); } /** From 65761b085f9c72187e4b4b7eefe161e23c12cd98 Mon Sep 17 00:00:00 2001 From: Oleg Agafonov Date: Sat, 28 Aug 2021 13:17:57 +0400 Subject: [PATCH 03/14] * Game: fixed wrong booster pass order in drafts (#8075); --- .../src/main/java/mage/client/draft/DraftPanel.java | 2 +- Mage.Common/src/main/java/mage/view/DraftView.java | 4 ++-- Mage.Sets/src/mage/cards/c/ChaosMoon.java | 2 +- Mage/src/main/java/mage/game/draft/BoosterDraft.java | 7 ++++--- Mage/src/main/java/mage/game/draft/DraftImpl.java | 8 ++++---- .../main/java/mage/game/draft/RichManBoosterDraft.java | 5 +++-- .../java/mage/game/draft/RichManCubeBoosterDraft.java | 5 +++-- Mage/src/main/java/mage/players/PlayerList.java | 6 +++++- 8 files changed, 23 insertions(+), 16 deletions(-) diff --git a/Mage.Client/src/main/java/mage/client/draft/DraftPanel.java b/Mage.Client/src/main/java/mage/client/draft/DraftPanel.java index 390b7a04238..55c564ca7f4 100644 --- a/Mage.Client/src/main/java/mage/client/draft/DraftPanel.java +++ b/Mage.Client/src/main/java/mage/client/draft/DraftPanel.java @@ -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)); diff --git a/Mage.Common/src/main/java/mage/view/DraftView.java b/Mage.Common/src/main/java/mage/view/DraftView.java index b1f2b960a48..9b0100c74d5 100644 --- a/Mage.Common/src/main/java/mage/view/DraftView.java +++ b/Mage.Common/src/main/java/mage/view/DraftView.java @@ -19,8 +19,8 @@ public class DraftView implements Serializable { private final List sets = new ArrayList<>(); private final List 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 players = new ArrayList<>(); public DraftView(Draft draft) { diff --git a/Mage.Sets/src/mage/cards/c/ChaosMoon.java b/Mage.Sets/src/mage/cards/c/ChaosMoon.java index 262bebbf481..6741496ba70 100644 --- a/Mage.Sets/src/mage/cards/c/ChaosMoon.java +++ b/Mage.Sets/src/mage/cards/c/ChaosMoon.java @@ -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 diff --git a/Mage/src/main/java/mage/game/draft/BoosterDraft.java b/Mage/src/main/java/mage/game/draft/BoosterDraft.java index ee5901a05f9..152834226bd 100644 --- a/Mage/src/main/java/mage/game/draft/BoosterDraft.java +++ b/Mage/src/main/java/mage/game/draft/BoosterDraft.java @@ -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(); } diff --git a/Mage/src/main/java/mage/game/draft/DraftImpl.java b/Mage/src/main/java/mage/game/draft/DraftImpl.java index cadea09ddc8..9a78e7e98dd 100644 --- a/Mage/src/main/java/mage/game/draft/DraftImpl.java +++ b/Mage/src/main/java/mage/game/draft/DraftImpl.java @@ -149,11 +149,11 @@ public abstract class DraftImpl implements Draft { this.addPick(playerId, booster.get(booster.size()-1).getId(), null); } - protected void passLeft() { + protected void passBoosterToLeft() { synchronized (players) { UUID startId = table.get(0); UUID currentId = startId; - UUID nextId = table.getNext(); + UUID nextId = table.getNext(); // getNext return left player by default DraftPlayer current = players.get(currentId); DraftPlayer next = players.get(nextId); List currentBooster = current.booster; @@ -170,11 +170,11 @@ public abstract class DraftImpl implements Draft { } } - protected void passRight() { + protected void passBoosterToRight() { synchronized (players) { UUID startId = table.get(0); UUID currentId = startId; - UUID prevId = table.getPrevious(); + UUID prevId = table.getPrevious(); // getPrevious return right player by default DraftPlayer current = players.get(currentId); DraftPlayer prev = players.get(prevId); List currentBooster = current.booster; diff --git a/Mage/src/main/java/mage/game/draft/RichManBoosterDraft.java b/Mage/src/main/java/mage/game/draft/RichManBoosterDraft.java index b8b63f5e050..8f7e3ca70e6 100644 --- a/Mage/src/main/java/mage/game/draft/RichManBoosterDraft.java +++ b/Mage/src/main/java/mage/game/draft/RichManBoosterDraft.java @@ -32,7 +32,8 @@ public class RichManBoosterDraft extends DraftImpl { cardNum = 1; fireUpdatePlayersEvent(); while (!isAbort() && pickCards()) { - passLeft(); + // new booster each time, so order is irrelevant + passBoosterToLeft(); fireUpdatePlayersEvent(); } boosterNum++; @@ -42,7 +43,7 @@ public class RichManBoosterDraft extends DraftImpl { } @Override - protected void passLeft() { + protected void passBoosterToLeft() { synchronized (players) { UUID startId = table.get(0); UUID currentId = startId; diff --git a/Mage/src/main/java/mage/game/draft/RichManCubeBoosterDraft.java b/Mage/src/main/java/mage/game/draft/RichManCubeBoosterDraft.java index 7045e0b70b8..e2d9c02361e 100644 --- a/Mage/src/main/java/mage/game/draft/RichManCubeBoosterDraft.java +++ b/Mage/src/main/java/mage/game/draft/RichManCubeBoosterDraft.java @@ -30,7 +30,8 @@ public class RichManCubeBoosterDraft extends DraftImpl { cardNum = 1; fireUpdatePlayersEvent(); while (!isAbort() && pickCards()) { - passLeft(); + // new booster each time, so order is irrelevant + passBoosterToLeft(); fireUpdatePlayersEvent(); } boosterNum++; @@ -40,7 +41,7 @@ public class RichManCubeBoosterDraft extends DraftImpl { } @Override - protected void passLeft() { + protected void passBoosterToLeft() { synchronized (players) { UUID startId = table.get(0); UUID currentId = startId; diff --git a/Mage/src/main/java/mage/players/PlayerList.java b/Mage/src/main/java/mage/players/PlayerList.java index 11ae44c0577..3a884c16daf 100644 --- a/Mage/src/main/java/mage/players/PlayerList.java +++ b/Mage/src/main/java/mage/players/PlayerList.java @@ -6,6 +6,8 @@ import mage.util.CircularList; import java.util.UUID; /** + * Default players order: left (next player seated to the active player's left) + * * @author BetaSteward_at_googlemail.com */ public class PlayerList extends CircularList { @@ -34,7 +36,9 @@ public class PlayerList extends CircularList { } /** - * checkNextTurnReached - use it turns/priority code only to mark leaved player as "reached next turn end" (need for some continous effects) + * Find next player. Default order: next player from the left + * + * @checkNextTurnReached - use it turns/priority code only to mark leaved player as "reached next turn end" (need for some continous effects) */ public Player getNext(Game game, boolean checkNextTurnReached) { UUID start = this.get(); From f03a410b9e808e5aeeabea8ad6c18255fd865e10 Mon Sep 17 00:00:00 2001 From: Raphael-Schulz <72562197+Raphael-Schulz@users.noreply.github.com> Date: Sat, 28 Aug 2021 21:55:41 +0200 Subject: [PATCH 04/14] [AFR] Implemented Xanathar, Guild Kingpin (#8045) * [AFR] Implemented Xanathar, Guild Kingpin Co-authored-by: Oleg Agafonov --- .../src/mage/cards/c/ConspicuousSnoop.java | 3 +- .../src/mage/cards/c/CourserOfKruphix.java | 3 +- .../src/mage/cards/e/ElshaOfTheInfinite.java | 9 +- .../src/mage/cards/g/GaleaKindlerOfHope.java | 2 +- Mage.Sets/src/mage/cards/g/GarruksHorde.java | 3 +- .../src/mage/cards/m/MelekIzzetParagon.java | 7 +- Mage.Sets/src/mage/cards/m/MysticForge.java | 3 +- .../src/mage/cards/o/OracleOfMulDaya.java | 3 +- .../src/mage/cards/p/PrecognitionField.java | 3 +- .../src/mage/cards/r/RadhaHeartOfKeld.java | 7 +- Mage.Sets/src/mage/cards/r/RangerClass.java | 3 +- Mage.Sets/src/mage/cards/r/Realmwalker.java | 3 +- Mage.Sets/src/mage/cards/v/VergeRangers.java | 3 +- .../mage/cards/v/VivienMonstersAdvocate.java | 2 +- .../mage/cards/v/VizierOfTheMenagerie.java | 2 +- .../mage/cards/x/XanatharGuildKingpin.java | 185 ++++++++++++++++++ .../sets/AdventuresInTheForgottenRealms.java | 1 + .../single/afr/XanatharGuildKingpinTest.java | 61 ++++++ .../LookAtTopCardOfLibraryAnyTimeEffect.java | 78 ++++++-- ...AtTopCardOfLibraryAnyTimeTargetEffect.java | 23 +++ .../continuous/PlayTheTopCardEffect.java | 84 ++++++-- .../PlayTheTopCardTargetEffect.java | 22 +++ .../src/main/java/mage/constants/Outcome.java | 2 +- .../java/mage/constants/TargetController.java | 3 +- .../card/CardOnTopOfLibraryPredicate.java | 17 +- 25 files changed, 477 insertions(+), 55 deletions(-) create mode 100644 Mage.Sets/src/mage/cards/x/XanatharGuildKingpin.java create mode 100644 Mage.Tests/src/test/java/org/mage/test/cards/single/afr/XanatharGuildKingpinTest.java create mode 100644 Mage/src/main/java/mage/abilities/effects/common/continuous/LookAtTopCardOfLibraryAnyTimeTargetEffect.java create mode 100644 Mage/src/main/java/mage/abilities/effects/common/continuous/PlayTheTopCardTargetEffect.java diff --git a/Mage.Sets/src/mage/cards/c/ConspicuousSnoop.java b/Mage.Sets/src/mage/cards/c/ConspicuousSnoop.java index a3ef5dfbb94..a790c80537f 100644 --- a/Mage.Sets/src/mage/cards/c/ConspicuousSnoop.java +++ b/Mage.Sets/src/mage/cards/c/ConspicuousSnoop.java @@ -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")))); diff --git a/Mage.Sets/src/mage/cards/c/CourserOfKruphix.java b/Mage.Sets/src/mage/cards/c/CourserOfKruphix.java index 3dd49b34446..b24868717f0 100644 --- a/Mage.Sets/src/mage/cards/c/CourserOfKruphix.java +++ b/Mage.Sets/src/mage/cards/c/CourserOfKruphix.java @@ -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)); diff --git a/Mage.Sets/src/mage/cards/e/ElshaOfTheInfinite.java b/Mage.Sets/src/mage/cards/e/ElshaOfTheInfinite.java index c400fc2d8cc..3c9dde86ab1 100644 --- a/Mage.Sets/src/mage/cards/e/ElshaOfTheInfinite.java +++ b/Mage.Sets/src/mage/cards/e/ElshaOfTheInfinite.java @@ -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.")); diff --git a/Mage.Sets/src/mage/cards/g/GaleaKindlerOfHope.java b/Mage.Sets/src/mage/cards/g/GaleaKindlerOfHope.java index 7bf04c3d3fa..b5d449e8e7f 100644 --- a/Mage.Sets/src/mage/cards/g/GaleaKindlerOfHope.java +++ b/Mage.Sets/src/mage/cards/g/GaleaKindlerOfHope.java @@ -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); diff --git a/Mage.Sets/src/mage/cards/g/GarruksHorde.java b/Mage.Sets/src/mage/cards/g/GarruksHorde.java index 37cb6954913..7b00eca127f 100644 --- a/Mage.Sets/src/mage/cards/g/GarruksHorde.java +++ b/Mage.Sets/src/mage/cards/g/GarruksHorde.java @@ -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) { diff --git a/Mage.Sets/src/mage/cards/m/MelekIzzetParagon.java b/Mage.Sets/src/mage/cards/m/MelekIzzetParagon.java index c28d8337298..6cdd29c0064 100644 --- a/Mage.Sets/src/mage/cards/m/MelekIzzetParagon.java +++ b/Mage.Sets/src/mage/cards/m/MelekIzzetParagon.java @@ -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()); diff --git a/Mage.Sets/src/mage/cards/m/MysticForge.java b/Mage.Sets/src/mage/cards/m/MysticForge.java index 1975c5d34b5..09ad165fa8c 100644 --- a/Mage.Sets/src/mage/cards/m/MysticForge.java +++ b/Mage.Sets/src/mage/cards/m/MysticForge.java @@ -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()); diff --git a/Mage.Sets/src/mage/cards/o/OracleOfMulDaya.java b/Mage.Sets/src/mage/cards/o/OracleOfMulDaya.java index 3e077c7696a..a5a6bc5d02a 100644 --- a/Mage.Sets/src/mage/cards/o/OracleOfMulDaya.java +++ b/Mage.Sets/src/mage/cards/o/OracleOfMulDaya.java @@ -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) { diff --git a/Mage.Sets/src/mage/cards/p/PrecognitionField.java b/Mage.Sets/src/mage/cards/p/PrecognitionField.java index 3f9ac0ef0db..1b3e999ac91 100644 --- a/Mage.Sets/src/mage/cards/p/PrecognitionField.java +++ b/Mage.Sets/src/mage/cards/p/PrecognitionField.java @@ -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))); diff --git a/Mage.Sets/src/mage/cards/r/RadhaHeartOfKeld.java b/Mage.Sets/src/mage/cards/r/RadhaHeartOfKeld.java index 912e8e00233..f2e6fb023ff 100644 --- a/Mage.Sets/src/mage/cards/r/RadhaHeartOfKeld.java +++ b/Mage.Sets/src/mage/cards/r/RadhaHeartOfKeld.java @@ -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); diff --git a/Mage.Sets/src/mage/cards/r/RangerClass.java b/Mage.Sets/src/mage/cards/r/RangerClass.java index 19e83d42561..ee3fa766655 100644 --- a/Mage.Sets/src/mage/cards/r/RangerClass.java +++ b/Mage.Sets/src/mage/cards/r/RangerClass.java @@ -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; @@ -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 ))); } diff --git a/Mage.Sets/src/mage/cards/r/Realmwalker.java b/Mage.Sets/src/mage/cards/r/Realmwalker.java index 6f57551358f..75fc454b9a8 100644 --- a/Mage.Sets/src/mage/cards/r/Realmwalker.java +++ b/Mage.Sets/src/mage/cards/r/Realmwalker.java @@ -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) { diff --git a/Mage.Sets/src/mage/cards/v/VergeRangers.java b/Mage.Sets/src/mage/cards/v/VergeRangers.java index a3a8b11fecf..b1026649ec6 100644 --- a/Mage.Sets/src/mage/cards/v/VergeRangers.java +++ b/Mage.Sets/src/mage/cards/v/VergeRangers.java @@ -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"; } diff --git a/Mage.Sets/src/mage/cards/v/VivienMonstersAdvocate.java b/Mage.Sets/src/mage/cards/v/VivienMonstersAdvocate.java index cd715c19905..1985e62cf9a 100644 --- a/Mage.Sets/src/mage/cards/v/VivienMonstersAdvocate.java +++ b/Mage.Sets/src/mage/cards/v/VivienMonstersAdvocate.java @@ -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. diff --git a/Mage.Sets/src/mage/cards/v/VizierOfTheMenagerie.java b/Mage.Sets/src/mage/cards/v/VizierOfTheMenagerie.java index 05c575f9637..89dc665a906 100644 --- a/Mage.Sets/src/mage/cards/v/VizierOfTheMenagerie.java +++ b/Mage.Sets/src/mage/cards/v/VizierOfTheMenagerie.java @@ -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())); diff --git a/Mage.Sets/src/mage/cards/x/XanatharGuildKingpin.java b/Mage.Sets/src/mage/cards/x/XanatharGuildKingpin.java new file mode 100644 index 00000000000..5fe1b5ac9df --- /dev/null +++ b/Mage.Sets/src/mage/cards/x/XanatharGuildKingpin.java @@ -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 can’t 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(); + } +} diff --git a/Mage.Sets/src/mage/sets/AdventuresInTheForgottenRealms.java b/Mage.Sets/src/mage/sets/AdventuresInTheForgottenRealms.java index 78bc4fba4e2..f4a444f5b5d 100644 --- a/Mage.Sets/src/mage/sets/AdventuresInTheForgottenRealms.java +++ b/Mage.Sets/src/mage/sets/AdventuresInTheForgottenRealms.java @@ -281,6 +281,7 @@ public final class AdventuresInTheForgottenRealms extends ExpansionSet { cards.add(new SetCardInfo("Wish", 166, Rarity.RARE, mage.cards.w.Wish.class)); 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("Xanathar, Guild Kingpin", 239, Rarity.MYTHIC, mage.cards.x.XanatharGuildKingpin.class)); cards.add(new SetCardInfo("Xorn", 167, Rarity.RARE, mage.cards.x.Xorn.class)); 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)); diff --git a/Mage.Tests/src/test/java/org/mage/test/cards/single/afr/XanatharGuildKingpinTest.java b/Mage.Tests/src/test/java/org/mage/test/cards/single/afr/XanatharGuildKingpinTest.java new file mode 100644 index 00000000000..09701105b42 --- /dev/null +++ b/Mage.Tests/src/test/java/org/mage/test/cards/single/afr/XanatharGuildKingpinTest.java @@ -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 can’t 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(); + } +} diff --git a/Mage/src/main/java/mage/abilities/effects/common/continuous/LookAtTopCardOfLibraryAnyTimeEffect.java b/Mage/src/main/java/mage/abilities/effects/common/continuous/LookAtTopCardOfLibraryAnyTimeEffect.java index 3c1ae950d5a..281a6cead4c 100644 --- a/Mage/src/main/java/mage/abilities/effects/common/continuous/LookAtTopCardOfLibraryAnyTimeEffect.java +++ b/Mage/src/main/java/mage/abilities/effects/common/continuous/LookAtTopCardOfLibraryAnyTimeEffect.java @@ -4,48 +4,102 @@ 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 public boolean apply(Game game, Ability source) { if (game.inCheckPlayableState()) { // Ignored - see https://github.com/magefree/mage/issues/6994 return false; - } + } Player controller = game.getPlayer(source.getControllerId()); 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 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 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; } diff --git a/Mage/src/main/java/mage/abilities/effects/common/continuous/LookAtTopCardOfLibraryAnyTimeTargetEffect.java b/Mage/src/main/java/mage/abilities/effects/common/continuous/LookAtTopCardOfLibraryAnyTimeTargetEffect.java new file mode 100644 index 00000000000..4af3cf4d5d7 --- /dev/null +++ b/Mage/src/main/java/mage/abilities/effects/common/continuous/LookAtTopCardOfLibraryAnyTimeTargetEffect.java @@ -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); + } +} diff --git a/Mage/src/main/java/mage/abilities/effects/common/continuous/PlayTheTopCardEffect.java b/Mage/src/main/java/mage/abilities/effects/common/continuous/PlayTheTopCardEffect.java index a9719c54bb1..14049f882e8 100644 --- a/Mage/src/main/java/mage/abilities/effects/common/continuous/PlayTheTopCardEffect.java +++ b/Mage/src/main/java/mage/abilities/effects/common/continuous/PlayTheTopCardEffect.java @@ -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 diff --git a/Mage/src/main/java/mage/abilities/effects/common/continuous/PlayTheTopCardTargetEffect.java b/Mage/src/main/java/mage/abilities/effects/common/continuous/PlayTheTopCardTargetEffect.java new file mode 100644 index 00000000000..64be57feab9 --- /dev/null +++ b/Mage/src/main/java/mage/abilities/effects/common/continuous/PlayTheTopCardTargetEffect.java @@ -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); + } +} diff --git a/Mage/src/main/java/mage/constants/Outcome.java b/Mage/src/main/java/mage/constants/Outcome.java index 2fdba3d1ced..1f4e4681214 100644 --- a/Mage/src/main/java/mage/constants/Outcome.java +++ b/Mage/src/main/java/mage/constants/Outcome.java @@ -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), diff --git a/Mage/src/main/java/mage/constants/TargetController.java b/Mage/src/main/java/mage/constants/TargetController.java index ffe2b05a623..c827820bbdd 100644 --- a/Mage/src/main/java/mage/constants/TargetController.java +++ b/Mage/src/main/java/mage/constants/TargetController.java @@ -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; diff --git a/Mage/src/main/java/mage/filter/predicate/card/CardOnTopOfLibraryPredicate.java b/Mage/src/main/java/mage/filter/predicate/card/CardOnTopOfLibraryPredicate.java index 6024ed0c905..f21aa550852 100644 --- a/Mage/src/main/java/mage/filter/predicate/card/CardOnTopOfLibraryPredicate.java +++ b/Mage/src/main/java/mage/filter/predicate/card/CardOnTopOfLibraryPredicate.java @@ -11,11 +11,24 @@ import mage.players.Player; */ public enum CardOnTopOfLibraryPredicate implements ObjectPlayerPredicate> { - instance; + YOUR, + ANY; @Override public boolean apply(ObjectPlayer 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; } From 3ce3adfe1dcc602b6de420efbaa59593a40cbf09 Mon Sep 17 00:00:00 2001 From: Evan Kranzler Date: Sat, 28 Aug 2021 16:01:46 -0400 Subject: [PATCH 05/14] [AFR] added all printings --- .../sets/AdventuresInTheForgottenRealms.java | 376 ++++++++++++------ 1 file changed, 256 insertions(+), 120 deletions(-) diff --git a/Mage.Sets/src/mage/sets/AdventuresInTheForgottenRealms.java b/Mage.Sets/src/mage/sets/AdventuresInTheForgottenRealms.java index f4a444f5b5d..5ab67978dd4 100644 --- a/Mage.Sets/src/mage/sets/AdventuresInTheForgottenRealms.java +++ b/Mage.Sets/src/mage/sets/AdventuresInTheForgottenRealms.java @@ -35,182 +35,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,76 +313,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("Xanathar, Guild Kingpin", 239, Rarity.MYTHIC, mage.cards.x.XanatharGuildKingpin.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)); @@ -295,9 +428,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)); } } From 91e114e501f393b5c86727140c506ecd5760555d Mon Sep 17 00:00:00 2001 From: Evan Kranzler Date: Sat, 28 Aug 2021 16:02:23 -0400 Subject: [PATCH 06/14] [AFR] enabled collation --- Mage.Sets/src/mage/sets/AdventuresInTheForgottenRealms.java | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/Mage.Sets/src/mage/sets/AdventuresInTheForgottenRealms.java b/Mage.Sets/src/mage/sets/AdventuresInTheForgottenRealms.java index 5ab67978dd4..94bed009b6e 100644 --- a/Mage.Sets/src/mage/sets/AdventuresInTheForgottenRealms.java +++ b/Mage.Sets/src/mage/sets/AdventuresInTheForgottenRealms.java @@ -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; From 5a87664a55e4095b53df5e98e7d6322cd12f4e4c Mon Sep 17 00:00:00 2001 From: "jeff@delmarus.com" <> Date: Sat, 28 Aug 2021 15:40:46 -0500 Subject: [PATCH 07/14] - Fixed #8166 --- .../src/mage/cards/d/DivineIntervention.java | 43 ++++--------------- Mage/src/main/java/mage/cards/CardImpl.java | 8 ++++ 2 files changed, 17 insertions(+), 34 deletions(-) diff --git a/Mage.Sets/src/mage/cards/d/DivineIntervention.java b/Mage.Sets/src/mage/cards/d/DivineIntervention.java index 1759e3a7cbe..afc0629b4dc 100644 --- a/Mage.Sets/src/mage/cards/d/DivineIntervention.java +++ b/Mage.Sets/src/mage/cards/d/DivineIntervention.java @@ -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; /** @@ -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; diff --git a/Mage/src/main/java/mage/cards/CardImpl.java b/Mage/src/main/java/mage/cards/CardImpl.java index b7c491f4dd4..c3741f4a45f 100644 --- a/Mage/src/main/java/mage/cards/CardImpl.java +++ b/Mage/src/main/java/mage/cards/CardImpl.java @@ -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); From 1809fb516aeb913939b592683f59d4b4ff4e4d0f Mon Sep 17 00:00:00 2001 From: Oleg Agafonov Date: Sun, 29 Aug 2021 01:00:49 +0400 Subject: [PATCH 08/14] * GUI: added card hints with current and next rooms in card rules (#8012); --- .../java/org/mage/card/arcane/ManaSymbols.java | 6 ++++++ .../hint/arrow-down-right-square fill-yellow.png | Bin 0 -> 3577 bytes .../hint/arrow-right-square-fill-green.png | Bin 0 -> 4091 bytes .../main/java/mage/abilities/hint/HintUtils.java | 4 +++- .../src/main/java/mage/game/command/Dungeon.java | 15 ++++++++++++++- 5 files changed, 23 insertions(+), 2 deletions(-) create mode 100644 Mage.Client/src/main/resources/hint/arrow-down-right-square fill-yellow.png create mode 100644 Mage.Client/src/main/resources/hint/arrow-right-square-fill-green.png diff --git a/Mage.Client/src/main/java/org/mage/card/arcane/ManaSymbols.java b/Mage.Client/src/main/java/org/mage/card/arcane/ManaSymbols.java index 350d87fd3e8..071c252e6f4 100644 --- a/Mage.Client/src/main/java/org/mage/card/arcane/ManaSymbols.java +++ b/Mage.Client/src/main/java/org/mage/card/arcane/ManaSymbols.java @@ -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) + " "); } + 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) + " "); + } + 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) + " "); + } // ignored data restore replaced = replaced diff --git a/Mage.Client/src/main/resources/hint/arrow-down-right-square fill-yellow.png b/Mage.Client/src/main/resources/hint/arrow-down-right-square fill-yellow.png new file mode 100644 index 0000000000000000000000000000000000000000..528a795d8615d9a49e4dc4ddef0ba781383fd34f GIT binary patch literal 3577 zcmcgv4Nwzj8s6|z1EL0L)hd>4;QXm>b~pdKB?>0UPYob)74~2U(vb*kv5TqWl zUMaSYQae~}wd&loSF|cU$Fr7tz<9Mi?a^M@F)xub>g6G+KqV>KFA<_;OJKkMp zvh035-~02t&-?C|b%puaW8x>rLl873H^){4{s!f*@&Rx?I)^#|K?;-GYAwuUcn1p? zWzU0W-~?fw2|+VnY}nY6ceL=q=US#@y}#>8<=?x6=?e=zr`y)&E_)s>*<;TU3j1hX{3k7+ zHa>vIe6(}NQ>t;n#{9DeRY6AM%l%Ud9hZwkUq8s zYCTqP>*}Jp9|9)hgq$T31dUFTzY6G;ZIi&-AKb+yz7qQalIFb{O6FG+@CpD8LFsb? z0!5dzKG?yQxjBovx4A_PyBUjmvB8en1uN@v=d2RhMXU0Q=~d-4!KmlXfztydFyLi< z6ddq+IEf5c)FHbhxR;kvH5`KY$}Q@Ff|l3|VJk1Put8%)Xk4#_O@szFVuV&d8`fgD z3B^n(u0t@K#EhhlfWsd(@Fp@&vdA_+>SUiFiT)dB$T>M>3NB;c-2Y_0;J>p~7SiIhd3(1$| z2Wf-}85S)SR|zay#7caHNV8df5N7INHj=N1y~F1{YzOerW`VSdEal_HVxIR5R=IF6 zU)XAeXDoJe3|}eDlzoNatc~)q7PS`B;s|C&v_vt6k+_-EnPy>n62k_dcAjxNtA>Lb z^rTk*11L}%L;0u?!3<40dC^M&uH0U#j70^mObtgWKw5bZF9OFPI$bCVyPeGCBp=1m zY_83s1}SLVZiXaGT7so095G`?3NdT-;9?-0h|y`ljYgdbGccyX{WhMikVPTyALtK; zr-6+-UX4bl(`hi85i>zE2<_0D5r+=bB09`y)MHKxGZ7JM1)>|YDCHSyRgQ`Q7M(gm zZ`A9Z2yJGJ2%*zsh}pqnhy!Dtj6-KKQU<-;2qA5eIc^CQt}5JGi`bRnJC7R<$%&+B zxlJr;S}rlmsKd+dVfeTw&*A-*E*2R5iQ*4GQiyk(n9YVI?wr8aY*n2 zB~oBEv7%&AJ4N0LM`Qr|c$g9dkDI3Cv{66Dg!?~IDD_?aNRkP!x01|j}e2C|M>)ksi$2OSH^<5j^0NqG(}^2lNn5D z%Iri~Mo%CP+KeGU|0aXMftxTV=-`1E?~=-$?){&pLXTMe5ehDAA|jBxQ^v5Odr19< zYAg~098%kV$KQx*ySMT5e=ZR!zi$V|4Eo~s870i^72P%m&u--99Z%8o9II?WvzI_{rt-Q zYhRCUI`ggn)`gFI5AE$;cH-K~4Vvtlu3KN~{*utTCi%v{U-|fgsx}o$zBy@m PQ zvB9+|2c{{jO>4&1+%%TG6We;_Xp z@F4X<*W0yg!5p$>4GdN>i7_$HIwitIfbf_oD#yPHk*`9lRzw#}*t_-;}8A;)`RV zwq)7hV6#gZ(^NR?nRr!9)A+CY;uIcR1{~bJJ5`loZAer?zn*#aq07g2EZ;h&tFQmD z=++zKp>##-tmv)-6~qWby`_Y`*(`2)ry^OZu`Z4!P_kV PvdGQKx9yu(`pka-W6{(= literal 0 HcmV?d00001 diff --git a/Mage.Client/src/main/resources/hint/arrow-right-square-fill-green.png b/Mage.Client/src/main/resources/hint/arrow-right-square-fill-green.png new file mode 100644 index 0000000000000000000000000000000000000000..aad1afd64b6dd749fc1b793ac3d975c81a855031 GIT binary patch literal 4091 zcmcgv2~-nj9-nXsO(}w+rlmp}d==k1WO8Q)!fg?2ARJZDB1~o`kTuD~WH=ioyR8&k z3szUriWTei@W8TbrFfAR4_dl_T8mXIwCaLw6%nOXQTI!LllsG>+(O>vXsqPf8W6qV0_ zpx}4cmN(34RQbKx;6Lm5mU*7vbs488sdQ&QSsB0ZEpFQGnALmZW7euC7;1{|`ji=_ zzS^D1>ySV7LMgkg;dJ#lf!h~VoB!-H z-dde-UgDD&SzU3@U&S^(gywvH+v1aH{o1SuT#4GeOqr~?Q!^G@7p(UFGQBsoc^8#_ z`udAe)5<+Il(mTJ1K(URXX4pYNmH77U9$v%I@#3vc^~aLa=Z9}!neJjGHj0XjGU>M zk{(sCC8YQjPUxB+)F+M4diUZ*spKJNj<4d!8*0Ac(B+{hP%Aoh?PK$39c zjJYPA!#GLsDIKM!42&6I1x~Cnhh}JV4*dw#&d0wp0H{?eoi@hwMXz_7Ff+6AKp4Y> zjEOd<78)sjGG(T7O$0S754agL5{;Qjrheh`3B&>1A#B8AOcc)0rc|2NjbvFh5-&F< zh8sLzYar=-^9;MKVK^0wGn9fSM1%quk;6hX6+tk82$RVEgorT&8GLRc;p$?eJ{QUn*N5fNf<1V?RQv$bZBxWeJqN}-kvuXI|jqnt3D zu(yeVN7z$Lfp~_twPWz{M3#r;^K&Sm^f!_}WX4Qun0(wsMP&o-9#dNUN4icM@+i|N z=Z&}t2eXMXnH4;ZiPm$SWx!=%id;h1Q5Rc9NV-jw!31@*k znlh3yX-DOMbd5P(;5w@9zhm#Q)%IlL>HnM}zWseWG-mk!Ie~`mV~2Qr$=;WaR}wbX zta;M<1MesdOj_sc{asUX*gpM7r>%WrI07Ga@EF+wry2Xwd5i)#&Vv|b09|SV$E<0) zcFcw#w>|N(QKgY+LRSr-ctKj2YpOTnV$R*I{de@0Satz zd`5L$5i{@L8xhcqzE9_&UQ<_naE$HcwWZAOxmCQ3H{Vb4`sosS@A~^ETf6(u-&lUh ze`#mO@iNyaPKnQ=&T|2gKPE$${UFpm(y+aB4O8;TbJil??g_-!WkHoQi&kfSlg-+M zt6baM+uS~^@8Jq71lFa{k!3+)o4VcVT}vlNKp!ev1B17tZf!08(KY*6SYy@GU2Y4G zzI}jI85=6pSloNOUT0b7U9UY>0_1cXEmfx`MK)(*dvmfk2wh75X6#0RT1T%iM_^Ldlk6qPpe^LBl_O=Yx!R;$~Qf7_!Hutuf7O&dv z8yN1uWS=7k9wrv{m%4YJSlY|I%2x4n{c5)a{8V*x>f8j@s+8dnpK!^(u_U7q*huI|_NZn)xV zD_#>^JF8DFEeEUYlNps6WyujI zx;=YbKR$TWc4mI)e&03^$QV}z@%H!zTm3mfDkwAS?MT+KthXXr)3R1XvbJTFMzY8o z3K#b*Teqj5^@U7;L4W4_#ii-9I!`~_^A>>o;#n%6ZR^Xy1FLUl#rR{Auw2r z&e_+k9DszN!$1nUeUs&$bt{3i3qyN4cWn>&sSs$MedQi_V6EsKS6eQ!Ybm&67|;J^ zKojtqVo7h@$De<9d1LhMf$qMLMTf6lZCHs9Jh;T^jVRNXC!u#2LZR-FPgp^Yh631^ z*;%Pqe3Dlrb-Z57y5;|^8`K#(?Y^We@9x_D3vJ70Y%P7}UcAR?m!3)CCFf4RjIH8C zHu%2pBAahyx}0BL#*^+p_U?FUfkbsAM$wvUthSc1>rzB zlSFG$$$g!k7t#aCThS`!gCp)9tH0;KflYmLvY6pF{-8NA3~R_qdLDTRMgr3TgJ~yh^>jv`s=>|4UE)G literal 0 HcmV?d00001 diff --git a/Mage/src/main/java/mage/abilities/hint/HintUtils.java b/Mage/src/main/java/mage/abilities/hint/HintUtils.java index 372b4208a4d..e7b7452107a 100644 --- a/Mage/src/main/java/mage/abilities/hint/HintUtils.java +++ b/Mage/src/main/java/mage/abilities/hint/HintUtils.java @@ -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 = "
"; // 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("%s", hex, text); } else { - res = text; + res = (text == null ? "" : text); } // icon diff --git a/Mage/src/main/java/mage/game/command/Dungeon.java b/Mage/src/main/java/mage/game/command/Dungeon.java index 96c7fe0a9a3..7b0841f9220 100644 --- a/Mage/src/main/java/mage/game/command/Dungeon.java +++ b/Mage/src/main/java/mage/game/command/Dungeon.java @@ -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" ) + ")"); - 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; } From 8bd1a9cde5c763d83c334fe0fca3c6ff4bdbb040 Mon Sep 17 00:00:00 2001 From: Oleg Agafonov Date: Mon, 30 Aug 2021 10:10:26 +0400 Subject: [PATCH 09/14] GUI: fixed that dungeon card hint doesn't hide after choose dialog, fixed working card hint on empty space in choose dialog (#8012); --- .../java/mage/client/dialog/PickChoiceDialog.java | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/Mage.Client/src/main/java/mage/client/dialog/PickChoiceDialog.java b/Mage.Client/src/main/java/mage/client/dialog/PickChoiceDialog.java index 3ecb24adfd1..344cfff3030 100644 --- a/Mage.Client/src/main/java/mage/client/dialog/PickChoiceDialog.java +++ b/Mage.Client/src/main/java/mage/client/dialog/PickChoiceDialog.java @@ -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; From 2158d682cc1b89b245f81123fbede06f76f14065 Mon Sep 17 00:00:00 2001 From: Oleg Agafonov Date: Mon, 30 Aug 2021 14:44:03 +0400 Subject: [PATCH 10/14] Prepare new release --- Mage.Client/pom.xml | 2 +- Mage.Common/pom.xml | 2 +- Mage.Common/src/main/java/mage/utils/MageVersion.java | 4 ++-- Mage.Plugins/Mage.Counter.Plugin/pom.xml | 2 +- Mage.Plugins/pom.xml | 2 +- Mage.Server.Console/pom.xml | 2 +- Mage.Server.Plugins/Mage.Deck.Constructed/pom.xml | 2 +- Mage.Server.Plugins/Mage.Deck.Limited/pom.xml | 2 +- Mage.Server.Plugins/Mage.Game.BrawlDuel/pom.xml | 2 +- Mage.Server.Plugins/Mage.Game.BrawlFreeForAll/pom.xml | 2 +- Mage.Server.Plugins/Mage.Game.CanadianHighlanderDuel/pom.xml | 2 +- Mage.Server.Plugins/Mage.Game.CommanderDuel/pom.xml | 2 +- Mage.Server.Plugins/Mage.Game.CommanderFreeForAll/pom.xml | 2 +- Mage.Server.Plugins/Mage.Game.FreeForAll/pom.xml | 2 +- Mage.Server.Plugins/Mage.Game.FreeformCommanderDuel/pom.xml | 2 +- .../Mage.Game.FreeformCommanderFreeForAll/pom.xml | 2 +- .../Mage.Game.FreeformUnlimitedCommander/pom.xml | 4 ++-- Mage.Server.Plugins/Mage.Game.MomirDuel/pom.xml | 2 +- Mage.Server.Plugins/Mage.Game.MomirGame/pom.xml | 2 +- Mage.Server.Plugins/Mage.Game.OathbreakerDuel/pom.xml | 4 ++-- Mage.Server.Plugins/Mage.Game.OathbreakerFreeForAll/pom.xml | 2 +- .../Mage.Game.PennyDreadfulCommanderFreeForAll/pom.xml | 2 +- Mage.Server.Plugins/Mage.Game.TinyLeadersDuel/pom.xml | 2 +- Mage.Server.Plugins/Mage.Game.TwoPlayerDuel/pom.xml | 2 +- Mage.Server.Plugins/Mage.Player.AI.DraftBot/pom.xml | 2 +- Mage.Server.Plugins/Mage.Player.AI.MA/pom.xml | 2 +- Mage.Server.Plugins/Mage.Player.AI/pom.xml | 2 +- Mage.Server.Plugins/Mage.Player.AIMCTS/pom.xml | 2 +- Mage.Server.Plugins/Mage.Player.AIMinimax/pom.xml | 2 +- Mage.Server.Plugins/Mage.Player.Human/pom.xml | 2 +- Mage.Server.Plugins/Mage.Tournament.BoosterDraft/pom.xml | 2 +- Mage.Server.Plugins/Mage.Tournament.Constructed/pom.xml | 2 +- Mage.Server.Plugins/Mage.Tournament.Sealed/pom.xml | 2 +- Mage.Server.Plugins/pom.xml | 2 +- Mage.Server/pom.xml | 2 +- Mage.Sets/pom.xml | 2 +- Mage.Tests/pom.xml | 2 +- Mage.Verify/pom.xml | 2 +- Mage/pom.xml | 2 +- Mage/src/main/java/mage/cards/repository/CardRepository.java | 2 +- pom.xml | 4 ++-- 41 files changed, 45 insertions(+), 45 deletions(-) diff --git a/Mage.Client/pom.xml b/Mage.Client/pom.xml index 79867c89069..0ff115a1879 100644 --- a/Mage.Client/pom.xml +++ b/Mage.Client/pom.xml @@ -6,7 +6,7 @@ org.mage mage-root - 1.4.49 + 1.4.50 mage-client diff --git a/Mage.Common/pom.xml b/Mage.Common/pom.xml index 3af8ebed3aa..c6d83d8238f 100644 --- a/Mage.Common/pom.xml +++ b/Mage.Common/pom.xml @@ -7,7 +7,7 @@ org.mage mage-root - 1.4.49 + 1.4.50 mage-common diff --git a/Mage.Common/src/main/java/mage/utils/MageVersion.java b/Mage.Common/src/main/java/mage/utils/MageVersion.java index 11faceb3aa7..9e1e82c6407 100644 --- a/Mage.Common/src/main/java/mage/utils/MageVersion.java +++ b/Mage.Common/src/main/java/mage/utils/MageVersion.java @@ -17,8 +17,8 @@ public class MageVersion implements Serializable, Comparable { // * 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 diff --git a/Mage.Plugins/Mage.Counter.Plugin/pom.xml b/Mage.Plugins/Mage.Counter.Plugin/pom.xml index 2485467ea13..483cdf4e6a0 100644 --- a/Mage.Plugins/Mage.Counter.Plugin/pom.xml +++ b/Mage.Plugins/Mage.Counter.Plugin/pom.xml @@ -7,7 +7,7 @@ org.mage mage-plugins - 1.4.49 + 1.4.50 mage-counter-plugin diff --git a/Mage.Plugins/pom.xml b/Mage.Plugins/pom.xml index 78a037fbc26..2bcf6c49a71 100644 --- a/Mage.Plugins/pom.xml +++ b/Mage.Plugins/pom.xml @@ -7,7 +7,7 @@ org.mage mage-root - 1.4.49 + 1.4.50 mage-plugins diff --git a/Mage.Server.Console/pom.xml b/Mage.Server.Console/pom.xml index 16efe50e2c4..dfe03c7fe4b 100644 --- a/Mage.Server.Console/pom.xml +++ b/Mage.Server.Console/pom.xml @@ -6,7 +6,7 @@ org.mage mage-root - 1.4.49 + 1.4.50 mage.server.console diff --git a/Mage.Server.Plugins/Mage.Deck.Constructed/pom.xml b/Mage.Server.Plugins/Mage.Deck.Constructed/pom.xml index 7363e86cba3..59f3c8d770b 100644 --- a/Mage.Server.Plugins/Mage.Deck.Constructed/pom.xml +++ b/Mage.Server.Plugins/Mage.Deck.Constructed/pom.xml @@ -7,7 +7,7 @@ org.mage mage-server-plugins - 1.4.49 + 1.4.50 mage-deck-constructed diff --git a/Mage.Server.Plugins/Mage.Deck.Limited/pom.xml b/Mage.Server.Plugins/Mage.Deck.Limited/pom.xml index 4b56efc52c4..10b7dc182d2 100644 --- a/Mage.Server.Plugins/Mage.Deck.Limited/pom.xml +++ b/Mage.Server.Plugins/Mage.Deck.Limited/pom.xml @@ -7,7 +7,7 @@ org.mage mage-server-plugins - 1.4.49 + 1.4.50 mage-deck-limited diff --git a/Mage.Server.Plugins/Mage.Game.BrawlDuel/pom.xml b/Mage.Server.Plugins/Mage.Game.BrawlDuel/pom.xml index 11ed22fc2ff..efaa8bf89c4 100644 --- a/Mage.Server.Plugins/Mage.Game.BrawlDuel/pom.xml +++ b/Mage.Server.Plugins/Mage.Game.BrawlDuel/pom.xml @@ -7,7 +7,7 @@ org.mage mage-server-plugins - 1.4.49 + 1.4.50 mage-game-brawlduel diff --git a/Mage.Server.Plugins/Mage.Game.BrawlFreeForAll/pom.xml b/Mage.Server.Plugins/Mage.Game.BrawlFreeForAll/pom.xml index cd7ee8aa0b3..28114185066 100644 --- a/Mage.Server.Plugins/Mage.Game.BrawlFreeForAll/pom.xml +++ b/Mage.Server.Plugins/Mage.Game.BrawlFreeForAll/pom.xml @@ -6,7 +6,7 @@ org.mage mage-server-plugins - 1.4.49 + 1.4.50 mage-game-brawlfreeforall diff --git a/Mage.Server.Plugins/Mage.Game.CanadianHighlanderDuel/pom.xml b/Mage.Server.Plugins/Mage.Game.CanadianHighlanderDuel/pom.xml index 4d62047aa92..19db8c09758 100644 --- a/Mage.Server.Plugins/Mage.Game.CanadianHighlanderDuel/pom.xml +++ b/Mage.Server.Plugins/Mage.Game.CanadianHighlanderDuel/pom.xml @@ -7,7 +7,7 @@ org.mage mage-server-plugins - 1.4.49 + 1.4.50 mage-game-canadianhighlanderduel diff --git a/Mage.Server.Plugins/Mage.Game.CommanderDuel/pom.xml b/Mage.Server.Plugins/Mage.Game.CommanderDuel/pom.xml index 9aa42c44b8e..4f40f8c1100 100644 --- a/Mage.Server.Plugins/Mage.Game.CommanderDuel/pom.xml +++ b/Mage.Server.Plugins/Mage.Game.CommanderDuel/pom.xml @@ -7,7 +7,7 @@ org.mage mage-server-plugins - 1.4.49 + 1.4.50 mage-game-commanderduel diff --git a/Mage.Server.Plugins/Mage.Game.CommanderFreeForAll/pom.xml b/Mage.Server.Plugins/Mage.Game.CommanderFreeForAll/pom.xml index c1b72b17d24..aad226db0b5 100644 --- a/Mage.Server.Plugins/Mage.Game.CommanderFreeForAll/pom.xml +++ b/Mage.Server.Plugins/Mage.Game.CommanderFreeForAll/pom.xml @@ -6,7 +6,7 @@ org.mage mage-server-plugins - 1.4.49 + 1.4.50 mage-game-commanderfreeforall diff --git a/Mage.Server.Plugins/Mage.Game.FreeForAll/pom.xml b/Mage.Server.Plugins/Mage.Game.FreeForAll/pom.xml index a82c320bd79..34622e8fc30 100644 --- a/Mage.Server.Plugins/Mage.Game.FreeForAll/pom.xml +++ b/Mage.Server.Plugins/Mage.Game.FreeForAll/pom.xml @@ -7,7 +7,7 @@ org.mage mage-server-plugins - 1.4.49 + 1.4.50 mage-game-freeforall diff --git a/Mage.Server.Plugins/Mage.Game.FreeformCommanderDuel/pom.xml b/Mage.Server.Plugins/Mage.Game.FreeformCommanderDuel/pom.xml index 1ae8eb24f43..58217aaa7da 100644 --- a/Mage.Server.Plugins/Mage.Game.FreeformCommanderDuel/pom.xml +++ b/Mage.Server.Plugins/Mage.Game.FreeformCommanderDuel/pom.xml @@ -7,7 +7,7 @@ org.mage mage-server-plugins - 1.4.49 + 1.4.50 mage-game-freeformcommanderduel diff --git a/Mage.Server.Plugins/Mage.Game.FreeformCommanderFreeForAll/pom.xml b/Mage.Server.Plugins/Mage.Game.FreeformCommanderFreeForAll/pom.xml index 228456f86c0..9115301dac7 100644 --- a/Mage.Server.Plugins/Mage.Game.FreeformCommanderFreeForAll/pom.xml +++ b/Mage.Server.Plugins/Mage.Game.FreeformCommanderFreeForAll/pom.xml @@ -6,7 +6,7 @@ org.mage mage-server-plugins - 1.4.49 + 1.4.50 mage-game-freeformcommanderfreeforall diff --git a/Mage.Server.Plugins/Mage.Game.FreeformUnlimitedCommander/pom.xml b/Mage.Server.Plugins/Mage.Game.FreeformUnlimitedCommander/pom.xml index 36fb471f9b6..7606ed21ae0 100644 --- a/Mage.Server.Plugins/Mage.Game.FreeformUnlimitedCommander/pom.xml +++ b/Mage.Server.Plugins/Mage.Game.FreeformUnlimitedCommander/pom.xml @@ -7,7 +7,7 @@ org.mage mage-server-plugins - 1.4.49 + 1.4.50 mage-game-freeformunlimitedcommander @@ -23,7 +23,7 @@ org.mage mage-game-freeformcommanderfreeforall - 1.4.49 + 1.4.50 compile diff --git a/Mage.Server.Plugins/Mage.Game.MomirDuel/pom.xml b/Mage.Server.Plugins/Mage.Game.MomirDuel/pom.xml index e3f38288c0b..979428bfd8c 100644 --- a/Mage.Server.Plugins/Mage.Game.MomirDuel/pom.xml +++ b/Mage.Server.Plugins/Mage.Game.MomirDuel/pom.xml @@ -7,7 +7,7 @@ org.mage mage-server-plugins - 1.4.49 + 1.4.50 mage-game-momirduel diff --git a/Mage.Server.Plugins/Mage.Game.MomirGame/pom.xml b/Mage.Server.Plugins/Mage.Game.MomirGame/pom.xml index 1fe96beedbf..8b76b45d119 100644 --- a/Mage.Server.Plugins/Mage.Game.MomirGame/pom.xml +++ b/Mage.Server.Plugins/Mage.Game.MomirGame/pom.xml @@ -7,7 +7,7 @@ org.mage mage-server-plugins - 1.4.49 + 1.4.50 mage-game-momirfreeforall diff --git a/Mage.Server.Plugins/Mage.Game.OathbreakerDuel/pom.xml b/Mage.Server.Plugins/Mage.Game.OathbreakerDuel/pom.xml index 8c35a194979..45bacb58e08 100644 --- a/Mage.Server.Plugins/Mage.Game.OathbreakerDuel/pom.xml +++ b/Mage.Server.Plugins/Mage.Game.OathbreakerDuel/pom.xml @@ -6,7 +6,7 @@ org.mage mage-server-plugins - 1.4.49 + 1.4.50 mage-game-oathbreakerduel @@ -22,7 +22,7 @@ org.mage mage-game-oathbreakerfreeforall - 1.4.49 + 1.4.50 compile diff --git a/Mage.Server.Plugins/Mage.Game.OathbreakerFreeForAll/pom.xml b/Mage.Server.Plugins/Mage.Game.OathbreakerFreeForAll/pom.xml index ebff6f3180a..eeed2f86639 100644 --- a/Mage.Server.Plugins/Mage.Game.OathbreakerFreeForAll/pom.xml +++ b/Mage.Server.Plugins/Mage.Game.OathbreakerFreeForAll/pom.xml @@ -7,7 +7,7 @@ org.mage mage-server-plugins - 1.4.49 + 1.4.50 mage-game-oathbreakerfreeforall diff --git a/Mage.Server.Plugins/Mage.Game.PennyDreadfulCommanderFreeForAll/pom.xml b/Mage.Server.Plugins/Mage.Game.PennyDreadfulCommanderFreeForAll/pom.xml index 97ea4fa016c..e9b29f52581 100644 --- a/Mage.Server.Plugins/Mage.Game.PennyDreadfulCommanderFreeForAll/pom.xml +++ b/Mage.Server.Plugins/Mage.Game.PennyDreadfulCommanderFreeForAll/pom.xml @@ -6,7 +6,7 @@ org.mage mage-server-plugins - 1.4.49 + 1.4.50 mage-game-pennydreadfulcommanderfreeforall diff --git a/Mage.Server.Plugins/Mage.Game.TinyLeadersDuel/pom.xml b/Mage.Server.Plugins/Mage.Game.TinyLeadersDuel/pom.xml index 3e9443091a8..8cee445bb8a 100644 --- a/Mage.Server.Plugins/Mage.Game.TinyLeadersDuel/pom.xml +++ b/Mage.Server.Plugins/Mage.Game.TinyLeadersDuel/pom.xml @@ -7,7 +7,7 @@ org.mage mage-server-plugins - 1.4.49 + 1.4.50 mage-game-tinyleadersduel diff --git a/Mage.Server.Plugins/Mage.Game.TwoPlayerDuel/pom.xml b/Mage.Server.Plugins/Mage.Game.TwoPlayerDuel/pom.xml index 920734f68dc..6ebf570c7bb 100644 --- a/Mage.Server.Plugins/Mage.Game.TwoPlayerDuel/pom.xml +++ b/Mage.Server.Plugins/Mage.Game.TwoPlayerDuel/pom.xml @@ -7,7 +7,7 @@ org.mage mage-server-plugins - 1.4.49 + 1.4.50 mage-game-twoplayerduel diff --git a/Mage.Server.Plugins/Mage.Player.AI.DraftBot/pom.xml b/Mage.Server.Plugins/Mage.Player.AI.DraftBot/pom.xml index 9f0e0691931..8030802e125 100644 --- a/Mage.Server.Plugins/Mage.Player.AI.DraftBot/pom.xml +++ b/Mage.Server.Plugins/Mage.Player.AI.DraftBot/pom.xml @@ -7,7 +7,7 @@ org.mage mage-server-plugins - 1.4.49 + 1.4.50 mage-player-ai-draftbot diff --git a/Mage.Server.Plugins/Mage.Player.AI.MA/pom.xml b/Mage.Server.Plugins/Mage.Player.AI.MA/pom.xml index f87d9c663c4..58e7b32695d 100644 --- a/Mage.Server.Plugins/Mage.Player.AI.MA/pom.xml +++ b/Mage.Server.Plugins/Mage.Player.AI.MA/pom.xml @@ -7,7 +7,7 @@ org.mage mage-server-plugins - 1.4.49 + 1.4.50 mage-player-ai-ma diff --git a/Mage.Server.Plugins/Mage.Player.AI/pom.xml b/Mage.Server.Plugins/Mage.Player.AI/pom.xml index c1e87317260..b6b558e6e81 100644 --- a/Mage.Server.Plugins/Mage.Player.AI/pom.xml +++ b/Mage.Server.Plugins/Mage.Player.AI/pom.xml @@ -7,7 +7,7 @@ org.mage mage-server-plugins - 1.4.49 + 1.4.50 mage-player-ai diff --git a/Mage.Server.Plugins/Mage.Player.AIMCTS/pom.xml b/Mage.Server.Plugins/Mage.Player.AIMCTS/pom.xml index f574ae0cdc8..8435f3ea3ed 100644 --- a/Mage.Server.Plugins/Mage.Player.AIMCTS/pom.xml +++ b/Mage.Server.Plugins/Mage.Player.AIMCTS/pom.xml @@ -7,7 +7,7 @@ org.mage mage-server-plugins - 1.4.49 + 1.4.50 mage-player-ai-mcts diff --git a/Mage.Server.Plugins/Mage.Player.AIMinimax/pom.xml b/Mage.Server.Plugins/Mage.Player.AIMinimax/pom.xml index 199ac52705a..3b773ba2ea1 100644 --- a/Mage.Server.Plugins/Mage.Player.AIMinimax/pom.xml +++ b/Mage.Server.Plugins/Mage.Player.AIMinimax/pom.xml @@ -7,7 +7,7 @@ org.mage mage-server-plugins - 1.4.49 + 1.4.50 mage-player-aiminimax diff --git a/Mage.Server.Plugins/Mage.Player.Human/pom.xml b/Mage.Server.Plugins/Mage.Player.Human/pom.xml index 229a04baa08..c4d102c8920 100644 --- a/Mage.Server.Plugins/Mage.Player.Human/pom.xml +++ b/Mage.Server.Plugins/Mage.Player.Human/pom.xml @@ -7,7 +7,7 @@ org.mage mage-server-plugins - 1.4.49 + 1.4.50 mage-player-human diff --git a/Mage.Server.Plugins/Mage.Tournament.BoosterDraft/pom.xml b/Mage.Server.Plugins/Mage.Tournament.BoosterDraft/pom.xml index 578554ff211..dda8b802153 100644 --- a/Mage.Server.Plugins/Mage.Tournament.BoosterDraft/pom.xml +++ b/Mage.Server.Plugins/Mage.Tournament.BoosterDraft/pom.xml @@ -7,7 +7,7 @@ org.mage mage-server-plugins - 1.4.49 + 1.4.50 mage-tournament-boosterdraft diff --git a/Mage.Server.Plugins/Mage.Tournament.Constructed/pom.xml b/Mage.Server.Plugins/Mage.Tournament.Constructed/pom.xml index 234586405d2..1326691219b 100644 --- a/Mage.Server.Plugins/Mage.Tournament.Constructed/pom.xml +++ b/Mage.Server.Plugins/Mage.Tournament.Constructed/pom.xml @@ -7,7 +7,7 @@ org.mage mage-server-plugins - 1.4.49 + 1.4.50 mage-tournament-constructed diff --git a/Mage.Server.Plugins/Mage.Tournament.Sealed/pom.xml b/Mage.Server.Plugins/Mage.Tournament.Sealed/pom.xml index 17b488f24ae..fcc84cc9c3a 100644 --- a/Mage.Server.Plugins/Mage.Tournament.Sealed/pom.xml +++ b/Mage.Server.Plugins/Mage.Tournament.Sealed/pom.xml @@ -7,7 +7,7 @@ org.mage mage-server-plugins - 1.4.49 + 1.4.50 mage-tournament-sealed diff --git a/Mage.Server.Plugins/pom.xml b/Mage.Server.Plugins/pom.xml index 55c5d8567f4..dc254573434 100644 --- a/Mage.Server.Plugins/pom.xml +++ b/Mage.Server.Plugins/pom.xml @@ -7,7 +7,7 @@ org.mage mage-root - 1.4.49 + 1.4.50 mage-server-plugins diff --git a/Mage.Server/pom.xml b/Mage.Server/pom.xml index 63e4fdfdcaf..2a635552f30 100644 --- a/Mage.Server/pom.xml +++ b/Mage.Server/pom.xml @@ -6,7 +6,7 @@ org.mage mage-root - 1.4.49 + 1.4.50 mage-server diff --git a/Mage.Sets/pom.xml b/Mage.Sets/pom.xml index 16094c7cac9..4dac5f304e8 100644 --- a/Mage.Sets/pom.xml +++ b/Mage.Sets/pom.xml @@ -7,7 +7,7 @@ org.mage mage-root - 1.4.49 + 1.4.50 mage-sets diff --git a/Mage.Tests/pom.xml b/Mage.Tests/pom.xml index 55f495d7659..90eaf920f39 100644 --- a/Mage.Tests/pom.xml +++ b/Mage.Tests/pom.xml @@ -6,7 +6,7 @@ org.mage mage-root - 1.4.49 + 1.4.50 mage-tests diff --git a/Mage.Verify/pom.xml b/Mage.Verify/pom.xml index 91263f642d1..df584fd29b9 100644 --- a/Mage.Verify/pom.xml +++ b/Mage.Verify/pom.xml @@ -6,7 +6,7 @@ org.mage mage-root - 1.4.49 + 1.4.50 mage-verify diff --git a/Mage/pom.xml b/Mage/pom.xml index 7e78757283c..261fa2208f6 100644 --- a/Mage/pom.xml +++ b/Mage/pom.xml @@ -6,7 +6,7 @@ org.mage mage-root - 1.4.49 + 1.4.50 mage diff --git a/Mage/src/main/java/mage/cards/repository/CardRepository.java b/Mage/src/main/java/mage/cards/repository/CardRepository.java index cca6bc97b0e..63aee9a1176 100644 --- a/Mage/src/main/java/mage/cards/repository/CardRepository.java +++ b/Mage/src/main/java/mage/cards/repository/CardRepository.java @@ -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 cardDao; private Set classNames; private final RepositoryEventSource eventSource = new RepositoryEventSource(); diff --git a/pom.xml b/pom.xml index 91c1340a6ce..ffa1aff2100 100644 --- a/pom.xml +++ b/pom.xml @@ -6,7 +6,7 @@ org.mage mage-root - 1.4.49 + 1.4.50 pom Mage Root Mage Root POM @@ -134,7 +134,7 @@ - 1.4.49 + 1.4.50 -Dfile.encoding=UTF-8 UTF-8 yyyy-MM-dd'T'HH:mm:ss'Z' From d0ddd8e7f08590cc99296431e9630fef97826a45 Mon Sep 17 00:00:00 2001 From: "Alex W. Jackson" Date: Mon, 30 Aug 2021 07:25:12 -0400 Subject: [PATCH 11/14] Fix some post-Alara small set boosters not having a basic land slot --- Mage.Sets/src/mage/sets/AlaraReborn.java | 4 ++-- Mage.Sets/src/mage/sets/BornOfTheGods.java | 4 ++-- Mage.Sets/src/mage/sets/Conflux.java | 4 ++-- Mage.Sets/src/mage/sets/RivalsOfIxalan.java | 4 ++-- Mage.Sets/src/mage/sets/Worldwake.java | 4 ++-- 5 files changed, 10 insertions(+), 10 deletions(-) diff --git a/Mage.Sets/src/mage/sets/AlaraReborn.java b/Mage.Sets/src/mage/sets/AlaraReborn.java index c1656977ea4..5e8c9b528b8 100644 --- a/Mage.Sets/src/mage/sets/AlaraReborn.java +++ b/Mage.Sets/src/mage/sets/AlaraReborn.java @@ -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; diff --git a/Mage.Sets/src/mage/sets/BornOfTheGods.java b/Mage.Sets/src/mage/sets/BornOfTheGods.java index 0401d9f67a1..5bcb1357669 100644 --- a/Mage.Sets/src/mage/sets/BornOfTheGods.java +++ b/Mage.Sets/src/mage/sets/BornOfTheGods.java @@ -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; diff --git a/Mage.Sets/src/mage/sets/Conflux.java b/Mage.Sets/src/mage/sets/Conflux.java index 35bb0ed36b1..82a42d710f9 100644 --- a/Mage.Sets/src/mage/sets/Conflux.java +++ b/Mage.Sets/src/mage/sets/Conflux.java @@ -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; diff --git a/Mage.Sets/src/mage/sets/RivalsOfIxalan.java b/Mage.Sets/src/mage/sets/RivalsOfIxalan.java index d1955c54eed..02af3eb5614 100644 --- a/Mage.Sets/src/mage/sets/RivalsOfIxalan.java +++ b/Mage.Sets/src/mage/sets/RivalsOfIxalan.java @@ -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; diff --git a/Mage.Sets/src/mage/sets/Worldwake.java b/Mage.Sets/src/mage/sets/Worldwake.java index 5c98f9848ad..590a8c01aa5 100644 --- a/Mage.Sets/src/mage/sets/Worldwake.java +++ b/Mage.Sets/src/mage/sets/Worldwake.java @@ -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; From 600b4fe1109c23a02def079a6d4cef258843db6d Mon Sep 17 00:00:00 2001 From: Evan Kranzler Date: Mon, 30 Aug 2021 19:51:46 -0400 Subject: [PATCH 12/14] reworked AttacksWithCreaturesTriggeredAbility implementation and text generation, fixed issues where it could trigger when nothing attacked --- .../mage/cards/a/AlibouAncientWitness.java | 2 +- .../src/mage/cards/a/AncestorDragon.java | 10 ++-- .../src/mage/cards/a/AngelicGuardian.java | 4 +- .../src/mage/cards/k/KrydleOfBaldursGate.java | 2 +- Mage.Sets/src/mage/cards/p/PaladinClass.java | 2 +- Mage.Sets/src/mage/cards/p/PathOfBravery.java | 51 +++++-------------- .../src/mage/cards/p/PlarggDeanOfChaos.java | 2 +- Mage.Sets/src/mage/cards/r/RagingRiver.java | 15 +++--- Mage.Sets/src/mage/cards/r/RangerClass.java | 2 +- .../src/mage/cards/s/SparringRegimen.java | 2 +- .../mage/cards/t/ThoroughInvestigation.java | 2 +- .../AttacksWithCreaturesTriggeredAbility.java | 33 +++++------- 12 files changed, 49 insertions(+), 78 deletions(-) diff --git a/Mage.Sets/src/mage/cards/a/AlibouAncientWitness.java b/Mage.Sets/src/mage/cards/a/AlibouAncientWitness.java index 1472c6cade6..3fc6f9f0f98 100644 --- a/Mage.Sets/src/mage/cards/a/AlibouAncientWitness.java +++ b/Mage.Sets/src/mage/cards/a/AlibouAncientWitness.java @@ -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())); } diff --git a/Mage.Sets/src/mage/cards/a/AncestorDragon.java b/Mage.Sets/src/mage/cards/a/AncestorDragon.java index 04857e8c10d..90820cb6a70 100644 --- a/Mage.Sets/src/mage/cards/a/AncestorDragon.java +++ b/Mage.Sets/src/mage/cards/a/AncestorDragon.java @@ -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) { diff --git a/Mage.Sets/src/mage/cards/a/AngelicGuardian.java b/Mage.Sets/src/mage/cards/a/AngelicGuardian.java index 19b7df8c97c..58cc6759579 100644 --- a/Mage.Sets/src/mage/cards/a/AngelicGuardian.java +++ b/Mage.Sets/src/mage/cards/a/AngelicGuardian.java @@ -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) { diff --git a/Mage.Sets/src/mage/cards/k/KrydleOfBaldursGate.java b/Mage.Sets/src/mage/cards/k/KrydleOfBaldursGate.java index 3c281503479..20b9bbf634a 100644 --- a/Mage.Sets/src/mage/cards/k/KrydleOfBaldursGate.java +++ b/Mage.Sets/src/mage/cards/k/KrydleOfBaldursGate.java @@ -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); } diff --git a/Mage.Sets/src/mage/cards/p/PaladinClass.java b/Mage.Sets/src/mage/cards/p/PaladinClass.java index 0339e5a6ca5..15c0b70713b 100644 --- a/Mage.Sets/src/mage/cards/p/PaladinClass.java +++ b/Mage.Sets/src/mage/cards/p/PaladinClass.java @@ -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 diff --git a/Mage.Sets/src/mage/cards/p/PathOfBravery.java b/Mage.Sets/src/mage/cards/p/PathOfBravery.java index 5c11488da34..f1fbd0ba7bc 100644 --- a/Mage.Sets/src/mage/cards/p/PathOfBravery.java +++ b/Mage.Sets/src/mage/cards/p/PathOfBravery.java @@ -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; - } -} diff --git a/Mage.Sets/src/mage/cards/p/PlarggDeanOfChaos.java b/Mage.Sets/src/mage/cards/p/PlarggDeanOfChaos.java index e13e052308d..482dadd310a 100644 --- a/Mage.Sets/src/mage/cards/p/PlarggDeanOfChaos.java +++ b/Mage.Sets/src/mage/cards/p/PlarggDeanOfChaos.java @@ -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); } diff --git a/Mage.Sets/src/mage/cards/r/RagingRiver.java b/Mage.Sets/src/mage/cards/r/RagingRiver.java index 0d342b57088..9fb3086d78b 100644 --- a/Mage.Sets/src/mage/cards/r/RagingRiver.java +++ b/Mage.Sets/src/mage/cards/r/RagingRiver.java @@ -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,20 +92,19 @@ 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); } } } - + // it could be nice to invoke some graphic indicator of which creature is Left or Right in this spot StringBuilder sb = new StringBuilder("Left pile of ").append(defender.getLogName()).append(": "); sb.append(leftLog.stream().map(MageObject::getLogName).collect(Collectors.joining(", "))); game.informPlayers(sb.toString()); - + sb = new StringBuilder("Right pile of ").append(defender.getLogName()).append(": "); sb.append(rightLog.stream().map(MageObject::getLogName).collect(Collectors.joining(", "))); @@ -135,7 +134,7 @@ class RagingRiverEffect extends OneShotEffect { .filter(permanent -> permanent.isControlledBy(defender.getId())) .collect(Collectors.toList()); - + if (controller.choosePile(outcome, attacker.getName() + ": attacking " + defender.getName(), leftLog, rightLog, game)) { filter.add(Predicates.not(Predicates.or(new AbilityPredicate(FlyingAbility.class), new PermanentInListPredicate(left)))); game.informPlayers(attacker.getLogName() + ": attacks left (" + defender.getLogName() + ")"); diff --git a/Mage.Sets/src/mage/cards/r/RangerClass.java b/Mage.Sets/src/mage/cards/r/RangerClass.java index ee3fa766655..b570eb499b8 100644 --- a/Mage.Sets/src/mage/cards/r/RangerClass.java +++ b/Mage.Sets/src/mage/cards/r/RangerClass.java @@ -47,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))); diff --git a/Mage.Sets/src/mage/cards/s/SparringRegimen.java b/Mage.Sets/src/mage/cards/s/SparringRegimen.java index ef7ef8a13e5..1132d415d9d 100644 --- a/Mage.Sets/src/mage/cards/s/SparringRegimen.java +++ b/Mage.Sets/src/mage/cards/s/SparringRegimen.java @@ -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()); diff --git a/Mage.Sets/src/mage/cards/t/ThoroughInvestigation.java b/Mage.Sets/src/mage/cards/t/ThoroughInvestigation.java index c1cbdd18371..bed81742c95 100644 --- a/Mage.Sets/src/mage/cards/t/ThoroughInvestigation.java +++ b/Mage.Sets/src/mage/cards/t/ThoroughInvestigation.java @@ -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)); diff --git a/Mage/src/main/java/mage/abilities/common/AttacksWithCreaturesTriggeredAbility.java b/Mage/src/main/java/mage/abilities/common/AttacksWithCreaturesTriggeredAbility.java index c1e48bd0199..70c7b35367c 100644 --- a/Mage/src/main/java/mage/abilities/common/AttacksWithCreaturesTriggeredAbility.java +++ b/Mage/src/main/java/mage/abilities/common/AttacksWithCreaturesTriggeredAbility.java @@ -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(); } - } From 126c76ce100ad62926b5168bacc913251d9a25f5 Mon Sep 17 00:00:00 2001 From: Evan Kranzler Date: Mon, 30 Aug 2021 21:10:48 -0400 Subject: [PATCH 13/14] [WAR] reworked Niv-Mizzet Reborn to simplify card choices --- .../src/mage/cards/n/NivMizzetReborn.java | 153 ++++++++---------- 1 file changed, 68 insertions(+), 85 deletions(-) diff --git a/Mage.Sets/src/mage/cards/n/NivMizzetReborn.java b/Mage.Sets/src/mage/cards/n/NivMizzetReborn.java index ef7707ab9e2..b39ee01e093 100644 --- a/Mage.Sets/src/mage/cards/n/NivMizzetReborn.java +++ b/Mage.Sets/src/mage/cards/n/NivMizzetReborn.java @@ -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 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 { + 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); + } +} From 7a8321b1fcc37d152e9ae2dc1c512a2122d8e86b Mon Sep 17 00:00:00 2001 From: "Alex W. Jackson" Date: Tue, 31 Aug 2021 08:28:51 -0400 Subject: [PATCH 14/14] Fix Theros Beyond Death collator common print run ratios (#8180) --- .../src/mage/sets/TherosBeyondDeath.java | 59 ++++++++++++------- 1 file changed, 38 insertions(+), 21 deletions(-) diff --git a/Mage.Sets/src/mage/sets/TherosBeyondDeath.java b/Mage.Sets/src/mage/sets/TherosBeyondDeath.java index 1f31df9ea33..8cd2998fd34 100644 --- a/Mage.Sets/src/mage/sets/TherosBeyondDeath.java +++ b/Mage.Sets/src/mage/sets/TherosBeyondDeath.java @@ -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,