diff --git a/Mage.Sets/src/mage/cards/a/AzorsGateway.java b/Mage.Sets/src/mage/cards/a/AzorsGateway.java index 6ac44610cf8..4a6f94a4a39 100644 --- a/Mage.Sets/src/mage/cards/a/AzorsGateway.java +++ b/Mage.Sets/src/mage/cards/a/AzorsGateway.java @@ -1,12 +1,15 @@ - package mage.cards.a; import mage.MageObject; import mage.abilities.Ability; import mage.abilities.common.SimpleActivatedAbility; +import mage.abilities.condition.Condition; import mage.abilities.costs.common.TapSourceCost; import mage.abilities.costs.mana.GenericManaCost; +import mage.abilities.decorator.ConditionalOneShotEffect; import mage.abilities.effects.OneShotEffect; +import mage.abilities.effects.common.DrawCardSourceControllerEffect; +import mage.abilities.effects.common.GainLifeEffect; import mage.abilities.effects.common.TransformSourceEffect; import mage.abilities.effects.common.UntapSourceEffect; import mage.abilities.keyword.TransformAbility; @@ -19,11 +22,10 @@ import mage.constants.SuperType; import mage.game.ExileZone; import mage.game.Game; import mage.players.Player; +import mage.target.TargetCard; import mage.target.common.TargetCardInHand; import mage.util.CardUtil; -import java.util.HashSet; -import java.util.Set; import java.util.UUID; /** @@ -41,8 +43,13 @@ public final class AzorsGateway extends CardImpl { // If cards with five or more different converted mana costs are exiled with Azor's Gateway, // you gain 5 life, untap Azor's Gateway, and transform it. this.addAbility(new TransformAbility()); - Ability ability = new SimpleActivatedAbility(new AzorsGatewayEffect(), new GenericManaCost(1)); + Ability ability = new SimpleActivatedAbility(new DrawCardSourceControllerEffect(1), new GenericManaCost(1)); ability.addCost(new TapSourceCost()); + ability.addEffect(new AzorsGatewayEffect()); + ability.addEffect(new ConditionalOneShotEffect( + new GainLifeEffect(5), AzorsGatewayCondition.instance, "If cards with five or more " + + "different mana values are exiled with {this}, you gain 5 life, untap {this}, and transform it." + ).addEffect(new UntapSourceEffect()).addEffect(new TransformSourceEffect())); this.addAbility(ability); } @@ -56,13 +63,28 @@ public final class AzorsGateway extends CardImpl { } } +enum AzorsGatewayCondition implements Condition { + instance; + + @Override + public boolean apply(Game game, Ability source) { + ExileZone exileZone = game.getExile().getExileZone(CardUtil.getExileZoneId(game, source)); + return exileZone != null + && exileZone + .getCards(game) + .stream() + .map(MageObject::getManaValue) + .distinct() + .mapToInt(x -> 1) + .sum() >= 5; + } +} + class AzorsGatewayEffect extends OneShotEffect { AzorsGatewayEffect() { super(Outcome.Benefit); - this.staticText = "Draw a card, then exile a card from your hand. " + - "If cards with five or more different mana values are exiled with {this}, " + - "you gain 5 life, untap {this}, and transform it"; + this.staticText = ", then exile a card from your hand"; } private AzorsGatewayEffect(final AzorsGatewayEffect effect) { @@ -76,37 +98,18 @@ class AzorsGatewayEffect extends OneShotEffect { @Override public boolean apply(Game game, Ability source) { - Player controller = game.getPlayer(source.getControllerId()); - if (controller == null) { + Player player = game.getPlayer(source.getControllerId()); + if (player == null || player.getHand().isEmpty()) { return false; } - - MageObject sourceObject = source.getSourceObject(game); - if (sourceObject == null) { - return false; - } - - UUID exileId = CardUtil.getCardExileZoneId(game, source); - - controller.drawCards(1, source, game); - TargetCardInHand target = new TargetCardInHand(); - controller.choose(outcome, target, source, game); - Card cardToExile = game.getCard(target.getFirstTarget()); - if (cardToExile != null) { - controller.moveCardsToExile(cardToExile, source, game, true, exileId, sourceObject.getIdName()); - } - Set usedCMC = new HashSet<>(); - ExileZone exileZone = game.getExile().getExileZone(exileId); - if (exileZone != null) { - for (Card card : exileZone.getCards(game)) { - usedCMC.add(card.getManaValue()); - } - if (usedCMC.size() > 4) { - controller.gainLife(4, game, source); - new UntapSourceEffect().apply(game, source); - new TransformSourceEffect().apply(game, source); - } - } - return true; + TargetCard target = new TargetCardInHand(); + target.withChooseHint("to exile"); + player.choose(outcome, player.getHand(), target, source, game); + Card card = game.getCard(target.getFirstTarget()); + return card != null && player.moveCardsToExile( + card, source, game, true, + CardUtil.getExileZoneId(game, source), + CardUtil.getSourceLogName(game, source) + ); } } diff --git a/Mage.Sets/src/mage/cards/g/GoldenGuardian.java b/Mage.Sets/src/mage/cards/g/GoldenGuardian.java index af1a5657715..d30b0a5cf7a 100644 --- a/Mage.Sets/src/mage/cards/g/GoldenGuardian.java +++ b/Mage.Sets/src/mage/cards/g/GoldenGuardian.java @@ -104,17 +104,11 @@ class GoldenGuardianReturnTransformedEffect extends OneShotEffect { @Override public boolean apply(Game game, Ability source) { Player controller = game.getPlayer(source.getControllerId()); - if (controller != null) { - if (game.getState().getZone(source.getSourceId()) == Zone.GRAVEYARD) { - game.getState().setValue(TransformAbility.VALUE_KEY_ENTER_TRANSFORMED + source.getSourceId(), Boolean.TRUE); - Card card = game.getCard(source.getSourceId()); - if (card != null) { - controller.moveCards(card, Zone.BATTLEFIELD, source, game); - } - } - return true; + if (controller == null || game.getState().getZone(source.getSourceId()) != Zone.GRAVEYARD) { + return false; } - return false; + game.getState().setValue(TransformAbility.VALUE_KEY_ENTER_TRANSFORMED + source.getSourceId(), Boolean.TRUE); + Card card = game.getCard(source.getSourceId()); + return card != null && controller.moveCards(card, Zone.BATTLEFIELD, source, game); } - } diff --git a/Mage.Sets/src/mage/cards/j/JourneyToEternity.java b/Mage.Sets/src/mage/cards/j/JourneyToEternity.java index ef16a392044..f3759a3341d 100644 --- a/Mage.Sets/src/mage/cards/j/JourneyToEternity.java +++ b/Mage.Sets/src/mage/cards/j/JourneyToEternity.java @@ -1,8 +1,6 @@ package mage.cards.j; -import java.util.UUID; - import mage.abilities.Ability; import mage.abilities.common.DiesAttachedTriggeredAbility; import mage.abilities.effects.OneShotEffect; @@ -13,16 +11,14 @@ import mage.abilities.keyword.TransformAbility; import mage.cards.Card; import mage.cards.CardImpl; import mage.cards.CardSetInfo; -import mage.constants.CardType; -import mage.constants.Outcome; -import mage.constants.SubType; -import mage.constants.SuperType; -import mage.constants.Zone; +import mage.constants.*; import mage.filter.StaticFilters; import mage.game.Game; import mage.players.Player; import mage.target.TargetPermanent; +import java.util.UUID; + /** * @author LevelX2 */ @@ -40,12 +36,11 @@ public final class JourneyToEternity extends CardImpl { TargetPermanent auraTarget = new TargetPermanent(StaticFilters.FILTER_PERMANENT_CREATURE_CONTROLLED); this.getSpellAbility().addTarget(auraTarget); this.getSpellAbility().addEffect(new AttachEffect(Outcome.BoostCreature)); - Ability ability = new EnchantAbility(auraTarget); - this.addAbility(ability); + this.addAbility(new EnchantAbility(auraTarget)); // When enchanted creature dies, return it to the battlefield under your control, then return Journey to Eternity to the battlefield transformed under your control. this.addAbility(new TransformAbility()); - ability = new DiesAttachedTriggeredAbility(new ReturnToBattlefieldUnderYourControlAttachedEffect("it"), "enchanted creature"); + Ability ability = new DiesAttachedTriggeredAbility(new ReturnToBattlefieldUnderYourControlAttachedEffect("it"), "enchanted creature"); ability.addEffect(new JourneyToEternityReturnTransformedSourceEffect()); this.addAbility(ability); diff --git a/Mage.Sets/src/mage/cards/m/MetzaliTowerOfTriumph.java b/Mage.Sets/src/mage/cards/m/MetzaliTowerOfTriumph.java index 0581ccc1d20..8ff50743a8a 100644 --- a/Mage.Sets/src/mage/cards/m/MetzaliTowerOfTriumph.java +++ b/Mage.Sets/src/mage/cards/m/MetzaliTowerOfTriumph.java @@ -1,10 +1,5 @@ package mage.cards.m; -import java.util.ArrayList; -import java.util.List; -import java.util.Set; -import java.util.UUID; -import mage.MageObjectReference; import mage.abilities.Ability; import mage.abilities.common.SimpleActivatedAbility; import mage.abilities.costs.common.TapSourceCost; @@ -18,15 +13,16 @@ import mage.constants.CardType; import mage.constants.Outcome; import mage.constants.SuperType; import mage.constants.TargetController; -import mage.constants.Zone; import mage.game.Game; import mage.game.permanent.Permanent; import mage.util.RandomUtil; -import mage.watchers.Watcher; import mage.watchers.common.AttackedThisTurnWatcher; +import java.util.Objects; +import java.util.UUID; +import java.util.stream.Collectors; + /** - * * @author LevelX2 */ public final class MetzaliTowerOfTriumph extends CardImpl { @@ -51,7 +47,6 @@ public final class MetzaliTowerOfTriumph extends CardImpl { ability = new SimpleActivatedAbility(new MetzaliTowerOfTriumphEffect(), new ManaCostsImpl<>("{2}{W}")); ability.addCost(new TapSourceCost()); this.addAbility(ability); - } private MetzaliTowerOfTriumph(final MetzaliTowerOfTriumph card) { @@ -69,7 +64,7 @@ class MetzaliTowerOfTriumphEffect extends OneShotEffect { MetzaliTowerOfTriumphEffect() { super(Outcome.DestroyPermanent); - this.staticText = "Choose a creature at random that attacked this turn. Destroy that creature"; + this.staticText = "choose a creature at random that attacked this turn. Destroy that creature"; } private MetzaliTowerOfTriumphEffect(final MetzaliTowerOfTriumphEffect effect) { @@ -83,24 +78,15 @@ class MetzaliTowerOfTriumphEffect extends OneShotEffect { @Override public boolean apply(Game game, Ability source) { - Watcher watcher = game.getState().getWatcher(AttackedThisTurnWatcher.class); - if (watcher instanceof AttackedThisTurnWatcher) { - Set attackedThisTurn = ((AttackedThisTurnWatcher) watcher).getAttackedThisTurnCreatures(); - List available = new ArrayList<>(); - for (MageObjectReference mor : attackedThisTurn) { - Permanent permanent = mor.getPermanent(game); - if (permanent != null && permanent.isCreature(game)) { - available.add(permanent); - } - } - if (!available.isEmpty()) { - Permanent permanent = available.get(RandomUtil.nextInt(available.size())); - if (permanent != null) { - permanent.destroy(source, game, false); - } - } - return true; - } - return false; + Permanent permanent = RandomUtil.randomFromCollection( + game.getState() + .getWatcher(AttackedThisTurnWatcher.class) + .getAttackedThisTurnCreatures() + .stream() + .map(mor -> mor.getPermanent(game)) + .filter(Objects::nonNull) + .collect(Collectors.toSet()) + ); + return permanent != null && permanent.destroy(source, game); } } diff --git a/Mage.Sets/src/mage/cards/p/ProfaneProcession.java b/Mage.Sets/src/mage/cards/p/ProfaneProcession.java index ae78c26a88a..881bab6e555 100644 --- a/Mage.Sets/src/mage/cards/p/ProfaneProcession.java +++ b/Mage.Sets/src/mage/cards/p/ProfaneProcession.java @@ -1,28 +1,25 @@ package mage.cards.p; -import java.util.UUID; - -import mage.MageObject; import mage.abilities.Ability; import mage.abilities.common.SimpleActivatedAbility; +import mage.abilities.condition.Condition; import mage.abilities.costs.mana.ManaCostsImpl; -import mage.abilities.effects.OneShotEffect; -import mage.abilities.effects.common.ExileTargetEffect; +import mage.abilities.decorator.ConditionalOneShotEffect; +import mage.abilities.effects.common.ExileTargetForSourceEffect; import mage.abilities.effects.common.TransformSourceEffect; import mage.abilities.keyword.TransformAbility; import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.constants.CardType; -import mage.constants.Outcome; import mage.constants.SuperType; -import mage.constants.Zone; -import mage.game.ExileZone; import mage.game.Game; -import mage.players.Player; import mage.target.common.TargetCreaturePermanent; import mage.util.CardUtil; +import java.util.Optional; +import java.util.UUID; + /** * @author LevelX2 */ @@ -37,7 +34,11 @@ public final class ProfaneProcession extends CardImpl { // {3}{W}{B}: Exile target creature. Then if there are three or more cards exiled with Profane Procession, transform it. this.addAbility(new TransformAbility()); - Ability ability = new SimpleActivatedAbility(new ProfaneProcessionEffect(), new ManaCostsImpl<>("{3}{W}{B}")); + Ability ability = new SimpleActivatedAbility(new ExileTargetForSourceEffect(), new ManaCostsImpl<>("{3}{W}{B}")); + ability.addEffect(new ConditionalOneShotEffect( + new TransformSourceEffect(), ProfaneProcessionCondition.instance, + "Then if there are three or more cards exiled with {this}, transform it" + )); ability.addTarget(new TargetCreaturePermanent()); this.addAbility(ability); } @@ -52,36 +53,14 @@ public final class ProfaneProcession extends CardImpl { } } -class ProfaneProcessionEffect extends OneShotEffect { - - ProfaneProcessionEffect() { - super(Outcome.Exile); - this.staticText = "Exile target creature. Then if there are three or more cards exiled with {this}, transform it."; - } - - private ProfaneProcessionEffect(final ProfaneProcessionEffect effect) { - super(effect); - } - - @Override - public ProfaneProcessionEffect copy() { - return new ProfaneProcessionEffect(this); - } +enum ProfaneProcessionCondition implements Condition { + instance; @Override public boolean apply(Game game, Ability source) { - Player controller = game.getPlayer(source.getControllerId()); - UUID exileId = CardUtil.getCardExileZoneId(game, source); - MageObject sourceObject = source.getSourceObject(game); - if (controller != null && exileId != null && sourceObject != null) { - new ExileTargetEffect(exileId, sourceObject.getIdName()).setTargetPointer(this.getTargetPointer().copy()).apply(game, source); - game.processAction(); - ExileZone exileZone = game.getExile().getExileZone(exileId); - if (exileZone != null && exileZone.size() > 2) { - new TransformSourceEffect().apply(game, source); - } - return true; - } - return false; + return Optional + .ofNullable(game.getExile().getExileZone(CardUtil.getExileZoneId(game, source))) + .filter(cards -> cards.size() >= 3) + .isPresent(); } } diff --git a/Mage.Sets/src/mage/cards/t/TombOfTheDuskRose.java b/Mage.Sets/src/mage/cards/t/TombOfTheDuskRose.java index 35cffef463a..46a7ecf9733 100644 --- a/Mage.Sets/src/mage/cards/t/TombOfTheDuskRose.java +++ b/Mage.Sets/src/mage/cards/t/TombOfTheDuskRose.java @@ -1,7 +1,5 @@ package mage.cards.t; -import java.util.UUID; -import mage.MageObject; import mage.abilities.Ability; import mage.abilities.common.SimpleActivatedAbility; import mage.abilities.costs.common.TapSourceCost; @@ -20,10 +18,12 @@ import mage.game.ExileZone; import mage.game.Game; import mage.players.Player; import mage.target.TargetCard; +import mage.target.common.TargetCardInExile; import mage.util.CardUtil; +import java.util.UUID; + /** - * * @author LevelX2 */ public final class TombOfTheDuskRose extends CardImpl { @@ -60,7 +60,7 @@ class TombOfTheDuskRoseEffect extends OneShotEffect { TombOfTheDuskRoseEffect() { super(Outcome.PutCardInPlay); - this.staticText = "Put a creature card exiled with this permanent onto the battlefield under your control"; + this.staticText = "put a creature card exiled with this permanent onto the battlefield under your control"; } private TombOfTheDuskRoseEffect(final TombOfTheDuskRoseEffect effect) { @@ -75,20 +75,17 @@ class TombOfTheDuskRoseEffect extends OneShotEffect { @Override public boolean apply(Game game, Ability source) { Player controller = game.getPlayer(source.getControllerId()); - UUID exileId = CardUtil.getCardExileZoneId(game, source); - MageObject sourceObject = source.getSourceObject(game); - if (controller != null && exileId != null && sourceObject != null) { - ExileZone exileZone = game.getExile().getExileZone(exileId); - if (exileZone != null) { - TargetCard targetCard = new TargetCard(Zone.EXILED, StaticFilters.FILTER_CARD_CREATURE); - controller.chooseTarget(outcome, exileZone, targetCard, source, game); - Card card = game.getCard(targetCard.getFirstTarget()); - if (card != null) { - controller.moveCards(card, Zone.BATTLEFIELD, source, game); - } - } - return true; + if (controller == null) { + return false; } - return false; + ExileZone exileZone = game.getExile().getExileZone(CardUtil.getExileZoneId(game, source)); + if (exileZone == null || exileZone.count(StaticFilters.FILTER_CARD_CREATURE, game) < 1) { + return false; + } + TargetCard targetCard = new TargetCardInExile(StaticFilters.FILTER_CARD_CREATURE, exileZone.getId()); + targetCard.withNotTarget(true); + controller.choose(outcome, targetCard, source, game); + Card card = game.getCard(targetCard.getFirstTarget()); + return card != null && controller.moveCards(card, Zone.BATTLEFIELD, source, game); } }