From 8369184cac23fc7cfa3c05718fb34dd62d480907 Mon Sep 17 00:00:00 2001 From: htrajan Date: Sun, 7 Jun 2020 13:02:07 -0700 Subject: [PATCH] Implement more m21 cards (#6612) * init commit * AdherentOfHope init commit * BasrisAegis init commit * don't change test * FungalRebirth init commit * GarruksWarsteed init commit * KeralKeepDisciples init commit * ChromaticOrrery init commit * add back filter names * fix GolgariFindbroker text * address comments Co-authored-by: Evan Kranzler --- .../src/mage/cards/a/AdherentOfHope.java | 54 ++++++++++++ Mage.Sets/src/mage/cards/b/BasrisAegis.java | 46 ++++++++++ .../src/mage/cards/c/ChandrasRegulator.java | 54 +----------- .../src/mage/cards/c/ChromaticOrrery.java | 84 +++++++++++++++++++ Mage.Sets/src/mage/cards/f/FungalRebirth.java | 46 ++++++++++ .../src/mage/cards/g/GarruksWarsteed.java | 50 +++++++++++ .../src/mage/cards/g/GolgariFindbroker.java | 16 ++-- .../src/mage/cards/k/KeralKeepDisciples.java | 40 +++++++++ Mage.Sets/src/mage/cards/s/SoulOfRavnica.java | 58 +------------ Mage.Sets/src/mage/sets/CoreSet2021.java | 6 ++ ...swalkerLoyaltyAbilityTriggeredAbility.java | 61 ++++++++++++++ ...hColorAmongControlledPermanentsEffect.java | 57 +++++++++++++ .../main/java/mage/filter/StaticFilters.java | 6 ++ 13 files changed, 464 insertions(+), 114 deletions(-) create mode 100644 Mage.Sets/src/mage/cards/a/AdherentOfHope.java create mode 100644 Mage.Sets/src/mage/cards/b/BasrisAegis.java create mode 100644 Mage.Sets/src/mage/cards/c/ChromaticOrrery.java create mode 100644 Mage.Sets/src/mage/cards/f/FungalRebirth.java create mode 100644 Mage.Sets/src/mage/cards/g/GarruksWarsteed.java create mode 100644 Mage.Sets/src/mage/cards/k/KeralKeepDisciples.java create mode 100644 Mage/src/main/java/mage/abilities/common/ActivatePlaneswalkerLoyaltyAbilityTriggeredAbility.java create mode 100644 Mage/src/main/java/mage/abilities/effects/common/DrawCardForEachColorAmongControlledPermanentsEffect.java diff --git a/Mage.Sets/src/mage/cards/a/AdherentOfHope.java b/Mage.Sets/src/mage/cards/a/AdherentOfHope.java new file mode 100644 index 0000000000..be05c2aaaf --- /dev/null +++ b/Mage.Sets/src/mage/cards/a/AdherentOfHope.java @@ -0,0 +1,54 @@ +package mage.cards.a; + +import mage.MageInt; +import mage.abilities.common.BeginningOfCombatTriggeredAbility; +import mage.abilities.condition.common.PermanentsOnTheBattlefieldCondition; +import mage.abilities.decorator.ConditionalInterveningIfTriggeredAbility; +import mage.abilities.effects.common.counter.AddCountersSourceEffect; +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.common.FilterControlledPermanent; + +import java.util.UUID; + +/** + * + * @author htrajan + */ +public final class AdherentOfHope extends CardImpl { + + private static final FilterControlledPermanent filter = new FilterControlledPermanent(); + + static { + filter.add(CardType.PLANESWALKER.getPredicate()); + filter.add(SubType.BASRI.getPredicate()); + } + + public AdherentOfHope(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{1}{W}"); + + this.subtype.add(SubType.HUMAN); + this.subtype.add(SubType.SOLDIER); + this.power = new MageInt(2); + this.toughness = new MageInt(1); + + // At the beginning of combat on your turn, if you control a Basri planeswalker, put a +1/+1 counter on Adherent of Hope. + this.addAbility(new ConditionalInterveningIfTriggeredAbility( + new BeginningOfCombatTriggeredAbility(new AddCountersSourceEffect(CounterType.P1P1.createInstance()), TargetController.YOU, false), + new PermanentsOnTheBattlefieldCondition(filter), + "At the beginning of combat on your turn, if you control a Basri planeswalker, put a +1/+1 counter on {this}.")); + } + + private AdherentOfHope(final AdherentOfHope card) { + super(card); + } + + @Override + public AdherentOfHope copy() { + return new AdherentOfHope(this); + } +} diff --git a/Mage.Sets/src/mage/cards/b/BasrisAegis.java b/Mage.Sets/src/mage/cards/b/BasrisAegis.java new file mode 100644 index 0000000000..e0dbee48d2 --- /dev/null +++ b/Mage.Sets/src/mage/cards/b/BasrisAegis.java @@ -0,0 +1,46 @@ +package mage.cards.b; + +import mage.abilities.effects.common.counter.AddCountersTargetEffect; +import mage.abilities.effects.common.search.SearchLibraryGraveyardPutInHandEffect; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.counters.CounterType; +import mage.filter.FilterCard; +import mage.filter.predicate.mageobject.NamePredicate; +import mage.target.common.TargetCreaturePermanent; + +import java.util.UUID; + +/** + * + * @author htrajan + */ +public final class BasrisAegis extends CardImpl { + + private static final FilterCard filter = new FilterCard("Basri, Devoted Paladin"); + + static { + filter.add(new NamePredicate("Basri, Devoted Paladin")); + } + + public BasrisAegis(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.SORCERY}, "{2}{W}{W}"); + + // Put a +1/+1 counter on each of up to two target creatures. You may search your library and/or graveyard for a card named Basri, Devoted Paladin, reveal it, and put it into your hand. If you search your library this way, shuffle it. + this.getSpellAbility().addEffect(new AddCountersTargetEffect( + CounterType.P1P1.createInstance() + ).setText("Put a +1/+1 counter on each of up to two target creatures")); + this.getSpellAbility().addEffect(new SearchLibraryGraveyardPutInHandEffect(filter, false, true)); + this.getSpellAbility().addTarget(new TargetCreaturePermanent(0, 2)); + } + + private BasrisAegis(final BasrisAegis card) { + super(card); + } + + @Override + public BasrisAegis copy() { + return new BasrisAegis(this); + } +} diff --git a/Mage.Sets/src/mage/cards/c/ChandrasRegulator.java b/Mage.Sets/src/mage/cards/c/ChandrasRegulator.java index 29a5a4b730..53010c2af0 100644 --- a/Mage.Sets/src/mage/cards/c/ChandrasRegulator.java +++ b/Mage.Sets/src/mage/cards/c/ChandrasRegulator.java @@ -2,14 +2,12 @@ package mage.cards.c; import mage.ObjectColor; import mage.abilities.Ability; -import mage.abilities.LoyaltyAbility; -import mage.abilities.TriggeredAbilityImpl; +import mage.abilities.common.ActivatePlaneswalkerLoyaltyAbilityTriggeredAbility; import mage.abilities.common.SimpleActivatedAbility; import mage.abilities.costs.common.DiscardTargetCost; import mage.abilities.costs.common.TapSourceCost; import mage.abilities.costs.mana.GenericManaCost; import mage.abilities.costs.mana.ManaCostsImpl; -import mage.abilities.effects.Effect; import mage.abilities.effects.OneShotEffect; import mage.abilities.effects.common.DrawCardSourceControllerEffect; import mage.cards.CardImpl; @@ -19,7 +17,6 @@ import mage.filter.FilterCard; import mage.filter.predicate.Predicates; import mage.filter.predicate.mageobject.ColorPredicate; import mage.game.Game; -import mage.game.events.GameEvent; import mage.game.permanent.Permanent; import mage.game.stack.StackAbility; import mage.players.Player; @@ -47,7 +44,7 @@ public final class ChandrasRegulator extends CardImpl { this.addSuperType(SuperType.LEGENDARY); // Whenever you activate a loyalty ability of a Chandra planeswalker, you may pay {1}. If you do, copy that ability. You may choose new targets for the copy. - this.addAbility(new ChandrasRegulatorTriggeredAbility()); + this.addAbility(new ActivatePlaneswalkerLoyaltyAbilityTriggeredAbility(new ChandrasRegulatorEffect(), SubType.CHANDRA)); // {1}, {T}, Discard a Mountain card or a red card: Draw a card. Ability ability = new SimpleActivatedAbility( @@ -68,56 +65,11 @@ public final class ChandrasRegulator extends CardImpl { } } -class ChandrasRegulatorTriggeredAbility extends TriggeredAbilityImpl { - - ChandrasRegulatorTriggeredAbility() { - super(Zone.BATTLEFIELD, new ChandrasRegulatorEffect(), false); - } - - private ChandrasRegulatorTriggeredAbility(final ChandrasRegulatorTriggeredAbility ability) { - super(ability); - } - - @Override - public ChandrasRegulatorTriggeredAbility copy() { - return new ChandrasRegulatorTriggeredAbility(this); - } - - @Override - public boolean checkEventType(GameEvent event, Game game) { - return event.getType() == GameEvent.EventType.ACTIVATED_ABILITY; - } - - @Override - public boolean checkTrigger(GameEvent event, Game game) { - if (!event.getPlayerId().equals(getControllerId())) { - return false; - } - StackAbility stackAbility = (StackAbility) game.getStack().getStackObject(event.getSourceId()); - if (stackAbility == null || !(stackAbility.getStackAbility() instanceof LoyaltyAbility)) { - return false; - } - Permanent permanent = stackAbility.getSourcePermanentOrLKI(game); - if (permanent == null || !permanent.isPlaneswalker() - || !permanent.hasSubtype(SubType.CHANDRA, game)) { - return false; - } - Effect effect = this.getEffects().get(0); - effect.setValue("stackAbility", stackAbility); - return true; - } - - @Override - public String getRule() { - return "Whenever you activate a loyalty ability of a Chandra planeswalker, you may pay {1}. " + - "If you do, copy that ability. You may choose new targets for the copy."; - } -} - class ChandrasRegulatorEffect extends OneShotEffect { ChandrasRegulatorEffect() { super(Outcome.Benefit); + staticText = "you may pay {1}. If you do, copy that ability. You may choose new targets for the copy"; } private ChandrasRegulatorEffect(final ChandrasRegulatorEffect effect) { diff --git a/Mage.Sets/src/mage/cards/c/ChromaticOrrery.java b/Mage.Sets/src/mage/cards/c/ChromaticOrrery.java new file mode 100644 index 0000000000..d69cbdcdff --- /dev/null +++ b/Mage.Sets/src/mage/cards/c/ChromaticOrrery.java @@ -0,0 +1,84 @@ +package mage.cards.c; + +import mage.Mana; +import mage.abilities.Ability; +import mage.abilities.common.SimpleActivatedAbility; +import mage.abilities.common.SimpleStaticAbility; +import mage.abilities.costs.common.TapSourceCost; +import mage.abilities.costs.mana.GenericManaCost; +import mage.abilities.effects.AsThoughEffectImpl; +import mage.abilities.effects.AsThoughManaEffect; +import mage.abilities.effects.common.DrawCardForEachColorAmongControlledPermanentsEffect; +import mage.abilities.mana.SimpleManaAbility; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.*; +import mage.game.Game; +import mage.players.ManaPoolItem; + +import java.util.UUID; + +/** + * + * @author htrajan + */ +public final class ChromaticOrrery extends CardImpl { + + public ChromaticOrrery(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.ARTIFACT}, "{7}"); + + this.addSuperType(SuperType.LEGENDARY); + + // You may spend mana as though it were mana of any color. + this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new ChromaticOrreryEffect())); + + // {T}: Add {C}{C}{C}{C}{C}. + this.addAbility(new SimpleManaAbility(Zone.BATTLEFIELD, Mana.ColorlessMana(5), new TapSourceCost())); + + // {5}, {T}: Draw a card for each color among permanents you control. + Ability ability = new SimpleActivatedAbility(new DrawCardForEachColorAmongControlledPermanentsEffect(), new GenericManaCost(5)); + ability.addCost(new TapSourceCost()); + this.addAbility(ability); + } + + private ChromaticOrrery(final ChromaticOrrery card) { + super(card); + } + + @Override + public ChromaticOrrery copy() { + return new ChromaticOrrery(this); + } +} + +class ChromaticOrreryEffect extends AsThoughEffectImpl implements AsThoughManaEffect { + + ChromaticOrreryEffect() { + super(AsThoughEffectType.SPEND_OTHER_MANA, Duration.WhileOnBattlefield, Outcome.Benefit); + staticText = "You may spend mana as though it were mana of any color"; + } + + private ChromaticOrreryEffect(ChromaticOrreryEffect effect) { + super(effect); + } + + @Override + public ChromaticOrreryEffect copy() { + return new ChromaticOrreryEffect(this); + } + + @Override + public boolean applies(UUID sourceId, Ability source, UUID affectedControllerId, Game game) { + return true; + } + + @Override + public boolean apply(Game game, Ability source) { + return true; + } + + @Override + public ManaType getAsThoughManaType(ManaType manaType, ManaPoolItem mana, UUID affectedControllerId, Ability source, Game game) { + return mana.getFirstAvailable(); + } +} \ No newline at end of file diff --git a/Mage.Sets/src/mage/cards/f/FungalRebirth.java b/Mage.Sets/src/mage/cards/f/FungalRebirth.java new file mode 100644 index 0000000000..801d277449 --- /dev/null +++ b/Mage.Sets/src/mage/cards/f/FungalRebirth.java @@ -0,0 +1,46 @@ +package mage.cards.f; + +import mage.abilities.condition.common.MorbidCondition; +import mage.abilities.decorator.ConditionalOneShotEffect; +import mage.abilities.effects.common.CreateTokenEffect; +import mage.abilities.effects.common.ReturnFromGraveyardToHandTargetEffect; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.filter.StaticFilters; +import mage.game.permanent.token.SaprolingToken; +import mage.target.common.TargetCardInYourGraveyard; +import mage.watchers.common.MorbidWatcher; + +import java.util.UUID; + +/** + * + * @author htrajan + */ +public final class FungalRebirth extends CardImpl { + + public FungalRebirth(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.INSTANT}, "{2}{G}"); + + // Return target permanent card from your graveyard to your hand. If a creature died this turn, create two 1/1 green Saproling creature tokens. + getSpellAbility().addEffect( + new ReturnFromGraveyardToHandTargetEffect().setText("Return target permanent card from your graveyard to your hand") + ); + getSpellAbility().addWatcher(new MorbidWatcher()); + getSpellAbility().addEffect(new ConditionalOneShotEffect( + new CreateTokenEffect(new SaprolingToken(), 2), + MorbidCondition.instance, + "If a creature died this turn, create two 1/1 green Saproling creature tokens")); + getSpellAbility().addTarget(new TargetCardInYourGraveyard(StaticFilters.FILTER_CARD_PERMANENT)); + } + + private FungalRebirth(final FungalRebirth card) { + super(card); + } + + @Override + public FungalRebirth copy() { + return new FungalRebirth(this); + } +} diff --git a/Mage.Sets/src/mage/cards/g/GarruksWarsteed.java b/Mage.Sets/src/mage/cards/g/GarruksWarsteed.java new file mode 100644 index 0000000000..8652a4ad3b --- /dev/null +++ b/Mage.Sets/src/mage/cards/g/GarruksWarsteed.java @@ -0,0 +1,50 @@ +package mage.cards.g; + +import mage.MageInt; +import mage.abilities.common.EntersBattlefieldTriggeredAbility; +import mage.abilities.effects.common.search.SearchLibraryGraveyardPutInHandEffect; +import mage.abilities.keyword.VigilanceAbility; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.SubType; +import mage.filter.FilterCard; +import mage.filter.predicate.mageobject.NamePredicate; + +import java.util.UUID; + +/** + * + * @author htrajan + */ +public final class GarruksWarsteed extends CardImpl { + + private static final FilterCard filter = new FilterCard("Garruk, Savage Herald"); + + static { + filter.add(new NamePredicate("Garruk, Savage Herald")); + } + + public GarruksWarsteed(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{3}{G}{G}"); + + this.subtype.add(SubType.RHINO); + this.power = new MageInt(3); + this.toughness = new MageInt(5); + + // Vigilance + this.addAbility(VigilanceAbility.getInstance()); + + // When Garruk's Warsteed enters the battlefield, you may search your library and/or graveyard for a card named Garruk, Savage Herald, reveal it, and put it into your hand. If you search your library this way, shuffle it. + this.addAbility(new EntersBattlefieldTriggeredAbility(new SearchLibraryGraveyardPutInHandEffect(filter, false, true))); + } + + private GarruksWarsteed(final GarruksWarsteed card) { + super(card); + } + + @Override + public GarruksWarsteed copy() { + return new GarruksWarsteed(this); + } +} diff --git a/Mage.Sets/src/mage/cards/g/GolgariFindbroker.java b/Mage.Sets/src/mage/cards/g/GolgariFindbroker.java index e95d580c61..06ee57f2aa 100644 --- a/Mage.Sets/src/mage/cards/g/GolgariFindbroker.java +++ b/Mage.Sets/src/mage/cards/g/GolgariFindbroker.java @@ -1,27 +1,24 @@ package mage.cards.g; -import java.util.UUID; import mage.MageInt; import mage.abilities.Ability; import mage.abilities.common.EntersBattlefieldTriggeredAbility; import mage.abilities.effects.common.ReturnFromGraveyardToHandTargetEffect; -import mage.constants.SubType; import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.constants.CardType; -import mage.filter.FilterCard; -import mage.filter.common.FilterPermanentCard; +import mage.constants.SubType; +import mage.filter.StaticFilters; import mage.target.common.TargetCardInYourGraveyard; +import java.util.UUID; + /** * * @author TheElk801 */ public final class GolgariFindbroker extends CardImpl { - private static final FilterCard filter - = new FilterPermanentCard("permanent card from your graveyard"); - public GolgariFindbroker(UUID ownerId, CardSetInfo setInfo) { super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{B}{B}{G}{G}"); @@ -32,9 +29,10 @@ public final class GolgariFindbroker extends CardImpl { // When Golgari Findbroker enters the battlefield, return target permanent card from your graveyard to your hand. Ability ability = new EntersBattlefieldTriggeredAbility( - new ReturnFromGraveyardToHandTargetEffect(), false + new ReturnFromGraveyardToHandTargetEffect().setText("return target permanent card from your graveyard to your hand"), + false ); - ability.addTarget(new TargetCardInYourGraveyard(filter)); + ability.addTarget(new TargetCardInYourGraveyard(StaticFilters.FILTER_CARD_PERMANENT)); this.addAbility(ability); } diff --git a/Mage.Sets/src/mage/cards/k/KeralKeepDisciples.java b/Mage.Sets/src/mage/cards/k/KeralKeepDisciples.java new file mode 100644 index 0000000000..83fbcf75b1 --- /dev/null +++ b/Mage.Sets/src/mage/cards/k/KeralKeepDisciples.java @@ -0,0 +1,40 @@ +package mage.cards.k; + +import mage.MageInt; +import mage.abilities.common.ActivatePlaneswalkerLoyaltyAbilityTriggeredAbility; +import mage.abilities.effects.common.DamagePlayersEffect; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.SubType; +import mage.constants.TargetController; + +import java.util.UUID; + +/** + * + * @author htrajan + */ +public final class KeralKeepDisciples extends CardImpl { + + public KeralKeepDisciples(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{2}{R}{R}"); + + this.subtype.add(SubType.HUMAN); + this.subtype.add(SubType.MONK); + this.power = new MageInt(4); + this.toughness = new MageInt(3); + + // Whenever you activate a loyalty ability of a Chandra planeswalker, Keral Keep Disciples deals 1 damage to each opponent. + this.addAbility(new ActivatePlaneswalkerLoyaltyAbilityTriggeredAbility(new DamagePlayersEffect(1, TargetController.OPPONENT), SubType.CHANDRA)); + } + + private KeralKeepDisciples(final KeralKeepDisciples card) { + super(card); + } + + @Override + public KeralKeepDisciples copy() { + return new KeralKeepDisciples(this); + } +} diff --git a/Mage.Sets/src/mage/cards/s/SoulOfRavnica.java b/Mage.Sets/src/mage/cards/s/SoulOfRavnica.java index 070cac316f..e0ae6486e0 100644 --- a/Mage.Sets/src/mage/cards/s/SoulOfRavnica.java +++ b/Mage.Sets/src/mage/cards/s/SoulOfRavnica.java @@ -2,25 +2,18 @@ package mage.cards.s; import mage.MageInt; -import mage.ObjectColor; import mage.abilities.Ability; import mage.abilities.common.SimpleActivatedAbility; import mage.abilities.costs.common.ExileSourceFromGraveCost; import mage.abilities.costs.mana.ManaCostsImpl; -import mage.abilities.effects.OneShotEffect; +import mage.abilities.effects.common.DrawCardForEachColorAmongControlledPermanentsEffect; import mage.abilities.keyword.FlyingAbility; import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.constants.CardType; import mage.constants.SubType; -import mage.constants.Outcome; import mage.constants.Zone; -import mage.game.Game; -import mage.game.permanent.Permanent; -import mage.players.Player; -import java.util.HashSet; -import java.util.Set; import java.util.UUID; /** @@ -38,11 +31,12 @@ public final class SoulOfRavnica extends CardImpl { // Flying this.addAbility(FlyingAbility.getInstance()); + // {5}{U}{U}: Draw a card for each color among permanents you control. - this.addAbility(new SimpleActivatedAbility(Zone.BATTLEFIELD, new SoulOfRavnicaEffect(), new ManaCostsImpl("{5}{U}{U}"))); + this.addAbility(new SimpleActivatedAbility(Zone.BATTLEFIELD, new DrawCardForEachColorAmongControlledPermanentsEffect(), new ManaCostsImpl("{5}{U}{U}"))); // {5}{U}{U}, Exile Soul of Ravnica from your graveyard: Draw a card for each color among permanents you control. - Ability ability = new SimpleActivatedAbility(Zone.GRAVEYARD, new SoulOfRavnicaEffect(), new ManaCostsImpl("{5}{U}{U}")); + Ability ability = new SimpleActivatedAbility(Zone.GRAVEYARD, new DrawCardForEachColorAmongControlledPermanentsEffect(), new ManaCostsImpl("{5}{U}{U}")); ability.addCost(new ExileSourceFromGraveCost()); this.addAbility(ability); } @@ -57,47 +51,3 @@ public final class SoulOfRavnica extends CardImpl { } } -class SoulOfRavnicaEffect extends OneShotEffect { - - public SoulOfRavnicaEffect() { - super(Outcome.DrawCard); - this.staticText = "Draw a card for each color among permanents you control"; - } - - public SoulOfRavnicaEffect(final SoulOfRavnicaEffect effect) { - super(effect); - } - - @Override - public SoulOfRavnicaEffect copy() { - return new SoulOfRavnicaEffect(this); - } - - @Override - public boolean apply(Game game, Ability source) { - Player controller = game.getPlayer(source.getControllerId()); - if (controller != null) { - Set colors = new HashSet<>(); - for (Permanent permanent : game.getBattlefield().getAllActivePermanents(controller.getId())) { - if (permanent.getColor(game).isBlack()) { - colors.add(ObjectColor.BLACK); - } - if (permanent.getColor(game).isBlue()) { - colors.add(ObjectColor.BLUE); - } - if (permanent.getColor(game).isRed()) { - colors.add(ObjectColor.RED); - } - if (permanent.getColor(game).isGreen()) { - colors.add(ObjectColor.GREEN); - } - if (permanent.getColor(game).isWhite()) { - colors.add(ObjectColor.WHITE); - } - } - controller.drawCards(colors.size(), source.getSourceId(), game); - return true; - } - return false; - } -} diff --git a/Mage.Sets/src/mage/sets/CoreSet2021.java b/Mage.Sets/src/mage/sets/CoreSet2021.java index edf23bc174..b310e7e8c4 100644 --- a/Mage.Sets/src/mage/sets/CoreSet2021.java +++ b/Mage.Sets/src/mage/sets/CoreSet2021.java @@ -33,22 +33,28 @@ public final class CoreSet2021 extends ExpansionSet { this.ratioBoosterMythic = 8; this.maxCardNumberInBooster = 274; + cards.add(new SetCardInfo("Adherent of Hope", 321, Rarity.COMMON, mage.cards.a.AdherentOfHope.class)); cards.add(new SetCardInfo("Azusa, Lost but Seeking", 173, Rarity.RARE, mage.cards.a.AzusaLostButSeeking.class)); cards.add(new SetCardInfo("Bad Deal", 89, Rarity.UNCOMMON, mage.cards.b.BadDeal.class)); cards.add(new SetCardInfo("Baneslayer Angel", 4, Rarity.MYTHIC, mage.cards.b.BaneslayerAngel.class)); + cards.add(new SetCardInfo("Basri's Aegis", 322, Rarity.RARE, mage.cards.b.BasrisAegis.class)); cards.add(new SetCardInfo("Basri, Devoted Paladin", 320, Rarity.MYTHIC, mage.cards.b.BasriDevotedPaladin.class)); cards.add(new SetCardInfo("Chandra's Firemaw", 333, Rarity.RARE, mage.cards.c.ChandrasFiremaw.class)); cards.add(new SetCardInfo("Chandra, Flame's Catalyst", 332, Rarity.MYTHIC, mage.cards.c.ChandraFlamesCatalyst.class)); + cards.add(new SetCardInfo("Chromatic Orrery", 228, Rarity.MYTHIC, mage.cards.c.ChromaticOrrery.class)); cards.add(new SetCardInfo("Containment Priest", 314, Rarity.RARE, mage.cards.c.ContainmentPriest.class)); cards.add(new SetCardInfo("Double Vision", 142, Rarity.RARE, mage.cards.d.DoubleVision.class)); cards.add(new SetCardInfo("Fierce Empath", 181, Rarity.UNCOMMON, mage.cards.f.FierceEmpath.class)); + cards.add(new SetCardInfo("Fungal Rebirth", 182, Rarity.UNCOMMON, mage.cards.f.FungalRebirth.class)); cards.add(new SetCardInfo("Gadrak, the Crown-Scourge", 146, Rarity.RARE, mage.cards.g.GadrakTheCrownScourge.class)); + cards.add(new SetCardInfo("Garruk's Warsteed", 337, Rarity.RARE, mage.cards.g.GarruksWarsteed.class)); cards.add(new SetCardInfo("Garruk, Savage Herald", 336, Rarity.MYTHIC, mage.cards.g.GarrukSavageHerald.class)); cards.add(new SetCardInfo("Grim Tutor", 103, Rarity.MYTHIC, mage.cards.g.GrimTutor.class)); cards.add(new SetCardInfo("Historian of Zhalfir", 325, Rarity.UNCOMMON, mage.cards.h.HistorianOfZhalfir.class)); cards.add(new SetCardInfo("Indulging Patrician", 219, Rarity.UNCOMMON, mage.cards.i.IndulgingPatrician.class)); cards.add(new SetCardInfo("Island", 310, Rarity.LAND, mage.cards.basiclands.Island.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Jeskai Elder", 53, Rarity.UNCOMMON, mage.cards.j.JeskaiElder.class)); + cards.add(new SetCardInfo("Keral Keep Disciples", 334, Rarity.UNCOMMON, mage.cards.k.KeralKeepDisciples.class)); cards.add(new SetCardInfo("Liliana's Scorn", 329, Rarity.RARE, mage.cards.l.LilianasScorn.class)); cards.add(new SetCardInfo("Liliana's Scrounger", 330, Rarity.UNCOMMON, mage.cards.l.LilianasScrounger.class)); cards.add(new SetCardInfo("Liliana, Death Mage", 328, Rarity.MYTHIC, mage.cards.l.LilianaDeathMage.class)); diff --git a/Mage/src/main/java/mage/abilities/common/ActivatePlaneswalkerLoyaltyAbilityTriggeredAbility.java b/Mage/src/main/java/mage/abilities/common/ActivatePlaneswalkerLoyaltyAbilityTriggeredAbility.java new file mode 100644 index 0000000000..ba4bd5c48b --- /dev/null +++ b/Mage/src/main/java/mage/abilities/common/ActivatePlaneswalkerLoyaltyAbilityTriggeredAbility.java @@ -0,0 +1,61 @@ +package mage.abilities.common; + +import mage.abilities.LoyaltyAbility; +import mage.abilities.TriggeredAbilityImpl; +import mage.abilities.effects.Effect; +import mage.constants.SubType; +import mage.constants.Zone; +import mage.game.Game; +import mage.game.events.GameEvent; +import mage.game.permanent.Permanent; +import mage.game.stack.StackAbility; + +public class ActivatePlaneswalkerLoyaltyAbilityTriggeredAbility extends TriggeredAbilityImpl { + + private final SubType planeswalkerSubType; + + public ActivatePlaneswalkerLoyaltyAbilityTriggeredAbility(Effect effect, SubType planeswalkerSubType) { + super(Zone.BATTLEFIELD, effect, false); + this.planeswalkerSubType = planeswalkerSubType; + } + + private ActivatePlaneswalkerLoyaltyAbilityTriggeredAbility(final ActivatePlaneswalkerLoyaltyAbilityTriggeredAbility ability) { + super(ability); + this.planeswalkerSubType = ability.planeswalkerSubType; + } + + @Override + public ActivatePlaneswalkerLoyaltyAbilityTriggeredAbility copy() { + return new ActivatePlaneswalkerLoyaltyAbilityTriggeredAbility(this); + } + + @Override + public boolean checkEventType(GameEvent event, Game game) { + return event.getType() == GameEvent.EventType.ACTIVATED_ABILITY; + } + + @Override + public boolean checkTrigger(GameEvent event, Game game) { + if (!event.getPlayerId().equals(getControllerId())) { + return false; + } + StackAbility stackAbility = (StackAbility) game.getStack().getStackObject(event.getSourceId()); + if (stackAbility == null || !(stackAbility.getStackAbility() instanceof LoyaltyAbility)) { + return false; + } + Permanent permanent = stackAbility.getSourcePermanentOrLKI(game); + if (permanent == null || !permanent.isPlaneswalker() + || !permanent.hasSubtype(planeswalkerSubType, game)) { + return false; + } + Effect effect = this.getEffects().get(0); + effect.setValue("stackAbility", stackAbility); + return true; + } + + @Override + public String getRule() { + return "Whenever you activate a loyalty ability of a " + planeswalkerSubType.getDescription() + " planeswalker, " + + this.getEffects().get(0).getText(getModes().getMode()) + "."; + } +} diff --git a/Mage/src/main/java/mage/abilities/effects/common/DrawCardForEachColorAmongControlledPermanentsEffect.java b/Mage/src/main/java/mage/abilities/effects/common/DrawCardForEachColorAmongControlledPermanentsEffect.java new file mode 100644 index 0000000000..951d788acb --- /dev/null +++ b/Mage/src/main/java/mage/abilities/effects/common/DrawCardForEachColorAmongControlledPermanentsEffect.java @@ -0,0 +1,57 @@ +package mage.abilities.effects.common; + +import mage.ObjectColor; +import mage.abilities.Ability; +import mage.abilities.effects.OneShotEffect; +import mage.constants.Outcome; +import mage.game.Game; +import mage.game.permanent.Permanent; +import mage.players.Player; + +import java.util.HashSet; +import java.util.Set; + +public class DrawCardForEachColorAmongControlledPermanentsEffect extends OneShotEffect { + + public DrawCardForEachColorAmongControlledPermanentsEffect() { + super(Outcome.DrawCard); + this.staticText = "Draw a card for each color among permanents you control"; + } + + public DrawCardForEachColorAmongControlledPermanentsEffect(final DrawCardForEachColorAmongControlledPermanentsEffect effect) { + super(effect); + } + + @Override + public DrawCardForEachColorAmongControlledPermanentsEffect copy() { + return new DrawCardForEachColorAmongControlledPermanentsEffect(this); + } + + @Override + public boolean apply(Game game, Ability source) { + Player controller = game.getPlayer(source.getControllerId()); + if (controller != null) { + Set colors = new HashSet<>(); + for (Permanent permanent : game.getBattlefield().getAllActivePermanents(controller.getId())) { + if (permanent.getColor(game).isBlack()) { + colors.add(ObjectColor.BLACK); + } + if (permanent.getColor(game).isBlue()) { + colors.add(ObjectColor.BLUE); + } + if (permanent.getColor(game).isRed()) { + colors.add(ObjectColor.RED); + } + if (permanent.getColor(game).isGreen()) { + colors.add(ObjectColor.GREEN); + } + if (permanent.getColor(game).isWhite()) { + colors.add(ObjectColor.WHITE); + } + } + controller.drawCards(colors.size(), source.getSourceId(), game); + return true; + } + return false; + } +} diff --git a/Mage/src/main/java/mage/filter/StaticFilters.java b/Mage/src/main/java/mage/filter/StaticFilters.java index 2e10475094..2a0dc193e1 100644 --- a/Mage/src/main/java/mage/filter/StaticFilters.java +++ b/Mage/src/main/java/mage/filter/StaticFilters.java @@ -191,6 +191,12 @@ public final class StaticFilters { FILTER_CARD_INSTANT_AND_SORCERY.setLockedFilter(true); } + public static final FilterPermanentCard FILTER_CARD_PERMANENT = new FilterPermanentCard("permanent card"); + + static { + FILTER_CARD_PERMANENT.setLockedFilter(true); + } + public static final FilterPermanent FILTER_PERMANENT = new FilterPermanent(); static {