From 75577cdbe977948cd2f681a1082098e322290f99 Mon Sep 17 00:00:00 2001 From: Evan Kranzler Date: Sun, 3 May 2020 14:35:26 -0400 Subject: [PATCH] Added new method for discarding cards to handle batch triggers (ready for review) (#6489) * added new discard method * started refactoring to use new discard method * refactored A through I * fixed some issues * separated balance effect into its own class * refactored J through R * refactored S through Z * applied requested changes --- Mage.Sets/src/mage/cards/a/Amnesia.java | 24 +-- Mage.Sets/src/mage/cards/a/Apocalypse.java | 73 +------- Mage.Sets/src/mage/cards/b/Balance.java | 153 +--------------- Mage.Sets/src/mage/cards/b/BalancingAct.java | 56 +++--- Mage.Sets/src/mage/cards/b/BarbedShocker.java | 28 ++- Mage.Sets/src/mage/cards/b/Breakthrough.java | 56 +++--- .../src/mage/cards/b/BrinkOfMadness.java | 67 +++---- .../src/mage/cards/b/BurningInquiry.java | 12 +- .../src/mage/cards/c/CabalTherapist.java | 22 ++- Mage.Sets/src/mage/cards/c/CabalTherapy.java | 40 +++-- .../src/mage/cards/c/ChandraFlamecaller.java | 16 +- .../src/mage/cards/c/CollectiveDefiance.java | 14 +- .../src/mage/cards/c/CompulsiveResearch.java | 41 ++--- .../src/mage/cards/c/CrosisThePurger.java | 64 +++---- .../src/mage/cards/d/DangerousWager.java | 50 +----- .../src/mage/cards/d/DarettiScrapSavant.java | 22 +-- .../src/mage/cards/d/DiscordantDirge.java | 48 +++-- .../src/mage/cards/d/DistendedMindbender.java | 53 +++--- .../src/mage/cards/d/DrasticRevelation.java | 23 +-- Mage.Sets/src/mage/cards/e/Extortion.java | 34 ++-- .../src/mage/cards/g/GruesomeDiscovery.java | 54 +++--- .../src/mage/cards/h/HintOfInsanity.java | 65 +++---- Mage.Sets/src/mage/cards/i/InfernalKirin.java | 60 +++---- Mage.Sets/src/mage/cards/j/JayaBallard.java | 30 ++-- Mage.Sets/src/mage/cards/l/LastRites.java | 53 +++--- Mage.Sets/src/mage/cards/l/LeaveChance.java | 49 +++-- .../src/mage/cards/m/MagusOfTheBalance.java | 156 +--------------- .../src/mage/cards/m/MinamosMeddling.java | 66 ++++--- Mage.Sets/src/mage/cards/m/MindBomb.java | 91 +++++----- .../src/mage/cards/m/MindExtraction.java | 4 +- Mage.Sets/src/mage/cards/m/MindMaggots.java | 47 +++-- Mage.Sets/src/mage/cards/m/MindWarp.java | 43 ++--- Mage.Sets/src/mage/cards/m/Monomania.java | 43 ++--- .../src/mage/cards/m/MyojinOfNightsReach.java | 21 +-- .../src/mage/cards/n/NantukoCultivator.java | 63 ++++--- .../src/mage/cards/n/Nebuchadnezzar.java | 42 +++-- .../mage/cards/n/NehebDreadhordeChampion.java | 17 +- Mage.Sets/src/mage/cards/n/Nightsnare.java | 45 +++-- Mage.Sets/src/mage/cards/n/NogginWhack.java | 86 ++++----- Mage.Sets/src/mage/cards/n/NoxiousVapors.java | 74 ++++---- Mage.Sets/src/mage/cards/r/RareBGone.java | 76 +++----- .../src/mage/cards/r/RestoreBalance.java | 156 +--------------- Mage.Sets/src/mage/cards/r/RiseFall.java | 104 ++++++----- Mage.Sets/src/mage/cards/r/RitesOfSpring.java | 47 ++--- Mage.Sets/src/mage/cards/s/SacredRites.java | 41 ++--- .../src/mage/cards/s/ShatterAssumptions.java | 11 +- Mage.Sets/src/mage/cards/s/Shocker.java | 30 ++-- .../src/mage/cards/s/SireOfInsanity.java | 32 ++-- Mage.Sets/src/mage/cards/s/SkullRend.java | 47 ++--- .../src/mage/cards/t/TrapfindersTrick.java | 41 ++--- Mage.Sets/src/mage/cards/t/TsabosDecree.java | 68 ++++--- Mage.Sets/src/mage/cards/t/Tyrannize.java | 5 +- Mage.Sets/src/mage/cards/v/Void.java | 72 ++++---- .../src/mage/cards/w/WhisperingMadness.java | 41 ++--- Mage.Sets/src/mage/cards/w/Windfall.java | 26 ++- Mage.Sets/src/mage/cards/w/WitsEnd.java | 27 ++- Mage.Sets/src/mage/cards/w/WrenchMind.java | 41 +++-- .../java/org/mage/test/player/TestPlayer.java | 5 + .../java/org/mage/test/stub/PlayerStub.java | 10 +- .../costs/common/DiscardHandCost.java | 19 +- .../costs/common/DiscardTargetCost.java | 23 ++- .../effects/common/BalanceEffect.java | 168 ++++++++++++++++++ .../DiscardCardYouChooseTargetEffect.java | 7 +- .../discard/DiscardControllerEffect.java | 22 +-- .../discard/DiscardEachPlayerEffect.java | 89 +++++----- .../common/discard/DiscardHandAllEffect.java | 10 +- Mage/src/main/java/mage/players/Player.java | 2 + .../main/java/mage/players/PlayerImpl.java | 18 ++ 68 files changed, 1290 insertions(+), 1953 deletions(-) create mode 100644 Mage/src/main/java/mage/abilities/effects/common/BalanceEffect.java diff --git a/Mage.Sets/src/mage/cards/a/Amnesia.java b/Mage.Sets/src/mage/cards/a/Amnesia.java index ae4eebaa75f..b452e933bc8 100644 --- a/Mage.Sets/src/mage/cards/a/Amnesia.java +++ b/Mage.Sets/src/mage/cards/a/Amnesia.java @@ -1,28 +1,25 @@ - package mage.cards.a; -import java.util.Set; -import java.util.UUID; +import mage.MageObject; import mage.abilities.Ability; import mage.abilities.effects.OneShotEffect; -import mage.cards.Card; -import mage.cards.CardImpl; -import mage.cards.CardSetInfo; -import mage.cards.Cards; +import mage.cards.*; import mage.constants.CardType; import mage.constants.Outcome; import mage.game.Game; import mage.players.Player; import mage.target.TargetPlayer; +import java.util.Set; +import java.util.UUID; + /** - * * @author fireshoes */ public final class Amnesia extends CardImpl { public Amnesia(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.SORCERY},"{3}{U}{U}{U}"); + super(ownerId, setInfo, new CardType[]{CardType.SORCERY}, "{3}{U}{U}{U}"); // Target player reveals their hand and discards all nonland cards. this.getSpellAbility().addEffect(new AmnesiaEffect()); @@ -60,13 +57,10 @@ class AmnesiaEffect extends OneShotEffect { Player player = game.getPlayer(source.getFirstTarget()); if (player != null) { Cards hand = player.getHand(); - player.revealCards("Amnesia", hand, game); + player.revealCards(source, hand, game); Set cards = hand.getCards(game); - for (Card card : cards) { - if (card != null && !card.isLand()) { - player.discard(card, source, game); - } - } + cards.removeIf(MageObject::isLand); + player.discard(new CardsImpl(cards), source, game); return true; } return false; diff --git a/Mage.Sets/src/mage/cards/a/Apocalypse.java b/Mage.Sets/src/mage/cards/a/Apocalypse.java index 09008dac712..073e15d3361 100644 --- a/Mage.Sets/src/mage/cards/a/Apocalypse.java +++ b/Mage.Sets/src/mage/cards/a/Apocalypse.java @@ -1,30 +1,25 @@ - package mage.cards.a; -import java.util.UUID; -import mage.abilities.Ability; -import mage.abilities.effects.OneShotEffect; -import mage.cards.Card; +import mage.abilities.effects.common.ExileAllEffect; +import mage.abilities.effects.common.discard.DiscardHandControllerEffect; import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.constants.CardType; -import mage.constants.Outcome; -import mage.game.Game; -import mage.game.permanent.Permanent; -import mage.players.Player; +import mage.filter.StaticFilters; + +import java.util.UUID; /** - * * @author markedagain */ public final class Apocalypse extends CardImpl { public Apocalypse(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.SORCERY},"{2}{R}{R}{R}"); + super(ownerId, setInfo, new CardType[]{CardType.SORCERY}, "{2}{R}{R}{R}"); // Exile all permanents. You discard your hand. - this.getSpellAbility().addEffect(new ApocalypseExileAllPermanentsEffect()); - this.getSpellAbility().addEffect(new ApocalypseDiscardEffect()); + this.getSpellAbility().addEffect(new ExileAllEffect(StaticFilters.FILTER_PERMANENTS)); + this.getSpellAbility().addEffect(new DiscardHandControllerEffect().setText("You discard your hand")); } public Apocalypse(final Apocalypse card) { @@ -36,55 +31,3 @@ public final class Apocalypse extends CardImpl { return new Apocalypse(this); } } -class ApocalypseDiscardEffect extends OneShotEffect { - - public ApocalypseDiscardEffect() { - super(Outcome.Discard); - this.staticText = "Discard your hand"; - } - - public ApocalypseDiscardEffect(final ApocalypseDiscardEffect effect) { - super(effect); - } - - @Override - public ApocalypseDiscardEffect copy() { - return new ApocalypseDiscardEffect(this); - } - - @Override - public boolean apply(Game game, Ability source) { - Player player = game.getPlayer(source.getControllerId()); - if (player != null) { - for (Card card : player.getHand().getCards(game)) { - player.discard(card, source, game); - } - return true; - } - return false; - } -} -class ApocalypseExileAllPermanentsEffect extends OneShotEffect { - - public ApocalypseExileAllPermanentsEffect() { - super(Outcome.Exile); - staticText = "Exile all permanents"; - } - - public ApocalypseExileAllPermanentsEffect(final ApocalypseExileAllPermanentsEffect effect) { - super(effect); - } - - @Override - public ApocalypseExileAllPermanentsEffect copy() { - return new ApocalypseExileAllPermanentsEffect(this); - } - - @Override - public boolean apply(Game game, Ability source) { - for (Permanent permanent : game.getBattlefield().getAllActivePermanents()) { - permanent.moveToExile(null, null, source.getSourceId(), game); - } - return true; - } -} \ No newline at end of file diff --git a/Mage.Sets/src/mage/cards/b/Balance.java b/Mage.Sets/src/mage/cards/b/Balance.java index 153b24ecc5c..2c7ea4d675e 100644 --- a/Mage.Sets/src/mage/cards/b/Balance.java +++ b/Mage.Sets/src/mage/cards/b/Balance.java @@ -1,21 +1,10 @@ package mage.cards.b; -import mage.abilities.Ability; -import mage.abilities.effects.OneShotEffect; -import mage.cards.*; +import mage.abilities.effects.common.BalanceEffect; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; import mage.constants.CardType; -import mage.constants.Outcome; -import mage.filter.FilterCard; -import mage.filter.common.FilterControlledCreaturePermanent; -import mage.filter.common.FilterControlledLandPermanent; -import mage.game.Game; -import mage.game.permanent.Permanent; -import mage.players.Player; -import mage.target.common.TargetCardInHand; -import mage.target.common.TargetControlledPermanent; -import java.util.HashMap; -import java.util.Map; import java.util.UUID; /** @@ -39,139 +28,3 @@ public final class Balance extends CardImpl { return new Balance(this); } } - -class BalanceEffect extends OneShotEffect { - - BalanceEffect() { - super(Outcome.Sacrifice); - staticText = "each player chooses a number of lands they control " - + "equal to the number of lands controlled by the player " - + "who controls the fewest, then sacrifices the rest. " - + "Players discard cards and sacrifice creatures the same way"; - } - - BalanceEffect(final BalanceEffect effect) { - super(effect); - } - - @Override - public BalanceEffect copy() { - return new BalanceEffect(this); - } - - @Override - public boolean apply(Game game, Ability source) { - Player controller = game.getPlayer(source.getControllerId()); - if (controller != null) { - //Lands - int minLand = Integer.MAX_VALUE; - Cards landsToSacrifice = new CardsImpl(); - for (UUID playerId : game.getState().getPlayersInRange(controller.getId(), game)) { - Player player = game.getPlayer(playerId); - if (player != null) { - int count = game.getBattlefield().countAll(new FilterControlledLandPermanent(), player.getId(), game); - if (count < minLand) { - minLand = count; - } - } - } - - for (UUID playerId : game.getState().getPlayersInRange(controller.getId(), game)) { - Player player = game.getPlayer(playerId); - if (player != null) { - TargetControlledPermanent target = new TargetControlledPermanent(minLand, minLand, new FilterControlledLandPermanent("lands to keep"), true); - if (target.choose(Outcome.Sacrifice, player.getId(), source.getSourceId(), game)) { - for (Permanent permanent : game.getBattlefield().getActivePermanents(new FilterControlledLandPermanent(), player.getId(), source.getSourceId(), game)) { - if (permanent != null && !target.getTargets().contains(permanent.getId())) { - landsToSacrifice.add(permanent); - } - } - } - } - } - - for (UUID cardId : landsToSacrifice) { - Permanent permanent = game.getPermanent(cardId); - if (permanent != null) { - permanent.sacrifice(source.getSourceId(), game); - } - } - - //Creatures - int minCreature = Integer.MAX_VALUE; - Cards creaturesToSacrifice = new CardsImpl(); - for (UUID playerId : game.getState().getPlayersInRange(controller.getId(), game)) { - Player player = game.getPlayer(playerId); - if (player != null) { - int count = game.getBattlefield().countAll(new FilterControlledCreaturePermanent(), player.getId(), game); - if (count < minCreature) { - minCreature = count; - } - } - } - - for (UUID playerId : game.getState().getPlayersInRange(controller.getId(), game)) { - Player player = game.getPlayer(playerId); - if (player != null) { - TargetControlledPermanent target = new TargetControlledPermanent(minCreature, minCreature, new FilterControlledCreaturePermanent("creatures to keep"), true); - if (target.choose(Outcome.Sacrifice, player.getId(), source.getSourceId(), game)) { - for (Permanent permanent : game.getBattlefield().getActivePermanents(new FilterControlledCreaturePermanent(), player.getId(), source.getSourceId(), game)) { - if (permanent != null && !target.getTargets().contains(permanent.getId())) { - creaturesToSacrifice.add(permanent); - } - } - } - } - } - - for (UUID cardId : creaturesToSacrifice) { - Permanent permanent = game.getPermanent(cardId); - if (permanent != null) { - permanent.sacrifice(source.getSourceId(), game); - } - } - - //Cards in hand - int minCard = Integer.MAX_VALUE; - Map cardsToDiscard = new HashMap<>(2); - for (UUID playerId : game.getState().getPlayersInRange(controller.getId(), game)) { - Player player = game.getPlayer(playerId); - if (player != null) { - int count = player.getHand().size(); - if (count < minCard) { - minCard = count; - } - } - } - - for (UUID playerId : game.getState().getPlayersInRange(controller.getId(), game)) { - Player player = game.getPlayer(playerId); - if (player != null) { - Cards cards = new CardsImpl(); - TargetCardInHand target = new TargetCardInHand(minCard, new FilterCard("cards to keep")); - if (target.choose(Outcome.Discard, player.getId(), source.getSourceId(), game)) { - for (Card card : player.getHand().getCards(game)) { - if (card != null && !target.getTargets().contains(card.getId())) { - cards.add(card); - } - } - cardsToDiscard.put(playerId, cards); - } - } - } - - for (UUID playerId : game.getState().getPlayersInRange(controller.getId(), game)) { - Player player = game.getPlayer(playerId); - if (player != null && cardsToDiscard.get(playerId) != null) { - for (UUID cardId : cardsToDiscard.get(playerId)) { - Card card = game.getCard(cardId); - player.discard(card, source, game); - - } - } - } - return true; - } - return false; - } -} diff --git a/Mage.Sets/src/mage/cards/b/BalancingAct.java b/Mage.Sets/src/mage/cards/b/BalancingAct.java index 2052ec14e87..d8cd45b70cd 100644 --- a/Mage.Sets/src/mage/cards/b/BalancingAct.java +++ b/Mage.Sets/src/mage/cards/b/BalancingAct.java @@ -1,10 +1,7 @@ - package mage.cards.b; -import java.util.UUID; import mage.abilities.Ability; import mage.abilities.effects.OneShotEffect; -import mage.cards.Card; import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.cards.Cards; @@ -18,21 +15,21 @@ import mage.players.Player; import mage.target.common.TargetCardInHand; import mage.target.common.TargetControlledPermanent; +import java.util.UUID; + /** - * * @author Plopman (Restore Balance), cbt33 */ public final class BalancingAct extends CardImpl { public BalancingAct(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.SORCERY},"{2}{W}{W}"); - + super(ownerId, setInfo, new CardType[]{CardType.SORCERY}, "{2}{W}{W}"); // Each player chooses a number of permanents they control equal to the number of permanents controlled by the player who controls the fewest, then sacrifices the rest. Each player discards cards the same way. this.getSpellAbility().addEffect(new BalancingActEffect()); } - public BalancingAct(final BalancingAct card) { + private BalancingAct(final BalancingAct card) { super(card); } @@ -44,13 +41,12 @@ public final class BalancingAct extends CardImpl { class BalancingActEffect extends OneShotEffect { - - public BalancingActEffect() { + BalancingActEffect() { super(Outcome.Sacrifice); staticText = "Each player chooses a number of permanents they control equal to the number of permanents controlled by the player who controls the fewest, then sacrifices the rest. Each player discards cards the same way"; } - public BalancingActEffect(final BalancingActEffect effect) { + private BalancingActEffect(final BalancingActEffect effect) { super(effect); } @@ -65,23 +61,23 @@ class BalancingActEffect extends OneShotEffect { if (controller != null) { int minPermanent = Integer.MAX_VALUE, minCard = Integer.MAX_VALUE; // count minimal permanents - for(UUID playerId : game.getState().getPlayersInRange(controller.getId(), game)){ + for (UUID playerId : game.getState().getPlayersInRange(controller.getId(), game)) { Player player = game.getPlayer(playerId); - if(player != null){ + if (player != null) { int count = game.getBattlefield().getActivePermanents(new FilterControlledPermanent(), player.getId(), source.getSourceId(), game).size(); - if(count < minPermanent){ + if (count < minPermanent) { minPermanent = count; } } } // sacrifice permanents over the minimum - for(UUID playerId : game.getState().getPlayersInRange(controller.getId(), game)){ + for (UUID playerId : game.getState().getPlayersInRange(controller.getId(), game)) { Player player = game.getPlayer(playerId); - if(player != null){ + if (player != null) { TargetControlledPermanent target = new TargetControlledPermanent(minPermanent, minPermanent, new FilterControlledPermanent(), true); - if(target.choose(Outcome.Benefit, player.getId(), source.getSourceId(), game)){ - for(Permanent permanent : game.getBattlefield().getActivePermanents(new FilterControlledPermanent(), player.getId(), source.getSourceId(), game)){ - if(permanent != null && !target.getTargets().contains(permanent.getId())){ + if (target.choose(Outcome.Benefit, player.getId(), source.getSourceId(), game)) { + for (Permanent permanent : game.getBattlefield().getActivePermanents(new FilterControlledPermanent(), player.getId(), source.getSourceId(), game)) { + if (permanent != null && !target.getTargets().contains(permanent.getId())) { permanent.sacrifice(source.getSourceId(), game); } } @@ -90,29 +86,25 @@ class BalancingActEffect extends OneShotEffect { } // count minimal cards in hand - for(UUID playerId : game.getState().getPlayersInRange(controller.getId(), game)){ + for (UUID playerId : game.getState().getPlayersInRange(controller.getId(), game)) { Player player = game.getPlayer(playerId); - if(player != null){ + if (player != null) { int count = player.getHand().size(); - if(count < minCard){ + if (count < minCard) { minCard = count; } } } - + // discard cards over the minimum - for(UUID playerId : game.getState().getPlayersInRange(controller.getId(), game)){ + for (UUID playerId : game.getState().getPlayersInRange(controller.getId(), game)) { Player player = game.getPlayer(playerId); - if(player != null){ + if (player != null) { TargetCardInHand target = new TargetCardInHand(minCard, new FilterCard()); - if(target.choose(Outcome.Benefit, player.getId(), source.getSourceId(), game)){ - Cards cards = player.getHand().copy(); - for(UUID cardUUID : cards){ - Card card = player.getHand().get(cardUUID, game); - if(!target.getTargets().contains(cardUUID)){ - player.discard(card, source, game); - } - } + if (target.choose(Outcome.Benefit, player.getId(), source.getSourceId(), game)) { + Cards cards = player.getHand().copy(); + cards.removeIf(target.getTargets()::contains); + player.discard(cards, source, game); } } } diff --git a/Mage.Sets/src/mage/cards/b/BarbedShocker.java b/Mage.Sets/src/mage/cards/b/BarbedShocker.java index 0ae806c0d07..48177c00ffe 100644 --- a/Mage.Sets/src/mage/cards/b/BarbedShocker.java +++ b/Mage.Sets/src/mage/cards/b/BarbedShocker.java @@ -1,14 +1,11 @@ - package mage.cards.b; -import java.util.UUID; import mage.MageInt; import mage.abilities.Ability; import mage.abilities.common.DealsDamageToAPlayerTriggeredAbility; import mage.abilities.effects.OneShotEffect; import mage.abilities.keyword.HasteAbility; import mage.abilities.keyword.TrampleAbility; -import mage.cards.Card; import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.constants.CardType; @@ -17,14 +14,15 @@ import mage.constants.SubType; import mage.game.Game; import mage.players.Player; +import java.util.UUID; + /** - * * @author markedagain */ public final class BarbedShocker extends CardImpl { public BarbedShocker(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{3}{R}"); + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{3}{R}"); this.subtype.add(SubType.INSECT); this.power = new MageInt(2); this.toughness = new MageInt(2); @@ -37,7 +35,7 @@ public final class BarbedShocker extends CardImpl { this.addAbility(new DealsDamageToAPlayerTriggeredAbility(new BarbedShockerEffect(), false, true)); } - public BarbedShocker(final BarbedShocker card) { + private BarbedShocker(final BarbedShocker card) { super(card); } @@ -46,14 +44,15 @@ public final class BarbedShocker extends CardImpl { return new BarbedShocker(this); } } + class BarbedShockerEffect extends OneShotEffect { - public BarbedShockerEffect() { + BarbedShockerEffect() { super(Outcome.Discard); this.staticText = " that player discards all the cards in their hand, then draws that many cards"; } - public BarbedShockerEffect(final BarbedShockerEffect effect) { + private BarbedShockerEffect(final BarbedShockerEffect effect) { super(effect); } @@ -65,14 +64,11 @@ class BarbedShockerEffect extends OneShotEffect { @Override public boolean apply(Game game, Ability source) { Player targetPlayer = game.getPlayer(targetPointer.getFirst(game, source)); - if (targetPlayer != null) { - int count = targetPlayer.getHand().size(); - for (Card card : targetPlayer.getHand().getCards(game)) { - targetPlayer.discard(card, source, game); - } - targetPlayer.drawCards(count, source.getSourceId(), game); - return false; - } + if (targetPlayer == null) { + return false; + } + int count = targetPlayer.discard(targetPlayer.getHand(), source, game).size(); + targetPlayer.drawCards(count, source.getSourceId(), game); return true; } } \ No newline at end of file diff --git a/Mage.Sets/src/mage/cards/b/Breakthrough.java b/Mage.Sets/src/mage/cards/b/Breakthrough.java index 15f6a890e9d..b2392375b4c 100644 --- a/Mage.Sets/src/mage/cards/b/Breakthrough.java +++ b/Mage.Sets/src/mage/cards/b/Breakthrough.java @@ -1,13 +1,11 @@ - package mage.cards.b; -import java.util.UUID; import mage.abilities.Ability; import mage.abilities.effects.OneShotEffect; import mage.abilities.effects.common.DrawCardSourceControllerEffect; -import mage.cards.Card; import mage.cards.CardImpl; import mage.cards.CardSetInfo; +import mage.cards.Cards; import mage.constants.CardType; import mage.constants.Outcome; import mage.filter.FilterCard; @@ -15,25 +13,24 @@ import mage.game.Game; import mage.players.Player; import mage.target.common.TargetCardInHand; +import java.util.UUID; + /** - * * @author emerald000 */ public final class Breakthrough extends CardImpl { public Breakthrough(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.SORCERY},"{X}{U}"); - + super(ownerId, setInfo, new CardType[]{CardType.SORCERY}, "{X}{U}"); // Draw four cards, this.getSpellAbility().addEffect(new DrawCardSourceControllerEffect(4)); - + //then choose X cards in your hand and discard the rest. this.getSpellAbility().addEffect(new BreakthroughEffect()); - } - public Breakthrough(final Breakthrough card) { + private Breakthrough(final Breakthrough card) { super(card); } @@ -44,41 +41,38 @@ public final class Breakthrough extends CardImpl { } class BreakthroughEffect extends OneShotEffect { - + BreakthroughEffect() { super(Outcome.Discard); this.staticText = ", then choose X cards in your hand and discard the rest."; } - - BreakthroughEffect(final BreakthroughEffect effect) { + + private BreakthroughEffect(final BreakthroughEffect effect) { super(effect); } - + @Override public BreakthroughEffect copy() { return new BreakthroughEffect(this); } - + @Override public boolean apply(Game game, Ability source) { Player player = game.getPlayer(source.getControllerId()); - if (player != null) { - int amountToKeep = source.getManaCostsToPay().getX(); - if (amountToKeep == 0) { - player.discard(player.getHand().size(), false, source, game); - } - else if (amountToKeep < player.getHand().size()) { - TargetCardInHand target = new TargetCardInHand(amountToKeep, new FilterCard()); - target.setTargetName("cards to keep"); - target.choose(Outcome.Benefit, player.getId(), source.getSourceId(), game); - for (Card card : player.getHand().getCards(game)) { - if (!target.getTargets().contains(card.getId())) { - player.discard(card, source, game); - } - } - } - return true; + if (player == null) { + return false; } - return false; + int amountToKeep = source.getManaCostsToPay().getX(); + if (amountToKeep == 0) { + player.discard(player.getHand(), source, game); + } else if (amountToKeep < player.getHand().size()) { + TargetCardInHand target = new TargetCardInHand(amountToKeep, new FilterCard()); + target.setTargetName("cards to keep"); + target.choose(Outcome.Benefit, player.getId(), source.getSourceId(), game); + Cards cards = player.getHand().copy(); + cards.removeIf(target.getTargets()::contains); + player.discard(cards, source, game); + } + return true; } } diff --git a/Mage.Sets/src/mage/cards/b/BrinkOfMadness.java b/Mage.Sets/src/mage/cards/b/BrinkOfMadness.java index fe17742f0b6..58a37d6967a 100644 --- a/Mage.Sets/src/mage/cards/b/BrinkOfMadness.java +++ b/Mage.Sets/src/mage/cards/b/BrinkOfMadness.java @@ -1,8 +1,5 @@ - package mage.cards.b; -import java.util.Set; -import java.util.UUID; import mage.abilities.Ability; import mage.abilities.TriggeredAbility; import mage.abilities.common.BeginningOfUpkeepTriggeredAbility; @@ -10,38 +7,33 @@ import mage.abilities.condition.common.CardsInHandCondition; import mage.abilities.decorator.ConditionalInterveningIfTriggeredAbility; import mage.abilities.effects.OneShotEffect; import mage.abilities.effects.common.SacrificeSourceEffect; -import mage.cards.Card; import mage.cards.CardImpl; import mage.cards.CardSetInfo; -import mage.constants.CardType; -import mage.constants.ComparisonType; -import mage.constants.Outcome; -import mage.constants.TargetController; -import mage.constants.Zone; +import mage.constants.*; import mage.game.Game; import mage.players.Player; import mage.target.common.TargetOpponent; +import java.util.UUID; + /** - * * @author Plopman */ public final class BrinkOfMadness extends CardImpl { public BrinkOfMadness(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.ENCHANTMENT},"{2}{B}{B}"); - + super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{2}{B}{B}"); // At the beginning of your upkeep, if you have no cards in hand, sacrifice Brink of Madness and target opponent discards their hand. - TriggeredAbility ability = new BeginningOfUpkeepTriggeredAbility(Zone.BATTLEFIELD, new SacrificeSourceEffect(), TargetController.YOU, false); + TriggeredAbility ability = new BeginningOfUpkeepTriggeredAbility(Zone.BATTLEFIELD, new SacrificeSourceEffect(), TargetController.YOU, false); ability.addEffect(new BrinkOfMadnessEffect()); ability.addTarget(new TargetOpponent()); CardsInHandCondition contition = new CardsInHandCondition(ComparisonType.EQUAL_TO, 0); this.addAbility(new ConditionalInterveningIfTriggeredAbility(ability, contition, "At the beginning of your upkeep, if you have no cards in hand, sacrifice {this} and target opponent discards their hand.")); - + } - public BrinkOfMadness(final BrinkOfMadness card) { + private BrinkOfMadness(final BrinkOfMadness card) { super(card); } @@ -49,34 +41,27 @@ public final class BrinkOfMadness extends CardImpl { public BrinkOfMadness copy() { return new BrinkOfMadness(this); } - + static class BrinkOfMadnessEffect extends OneShotEffect { - public BrinkOfMadnessEffect() { - super(Outcome.Benefit); - this.staticText = "Target player discards their hand"; - } - - public BrinkOfMadnessEffect(final BrinkOfMadnessEffect effect) { - super(effect); - } - - @Override - public BrinkOfMadnessEffect copy() { - return new BrinkOfMadnessEffect(this); - } - - @Override - public boolean apply(Game game, Ability source) { - Player player = game.getPlayer(source.getFirstTarget()); - if (player != null) { - Set cards = player.getHand().getCards(game); - for (Card card : cards) { - player.discard(card, source, game); - } - return true; + private BrinkOfMadnessEffect() { + super(Outcome.Benefit); + this.staticText = "Target player discards their hand"; + } + + private BrinkOfMadnessEffect(final BrinkOfMadnessEffect effect) { + super(effect); + } + + @Override + public BrinkOfMadnessEffect copy() { + return new BrinkOfMadnessEffect(this); + } + + @Override + public boolean apply(Game game, Ability source) { + Player player = game.getPlayer(source.getFirstTarget()); + return player != null && !player.discard(player.getHand(), source, game).isEmpty(); } - return false; } } -} diff --git a/Mage.Sets/src/mage/cards/b/BurningInquiry.java b/Mage.Sets/src/mage/cards/b/BurningInquiry.java index 6691d8323b3..b8f1670d93d 100644 --- a/Mage.Sets/src/mage/cards/b/BurningInquiry.java +++ b/Mage.Sets/src/mage/cards/b/BurningInquiry.java @@ -1,7 +1,5 @@ - package mage.cards.b; -import java.util.UUID; import mage.abilities.effects.Effect; import mage.abilities.effects.common.DrawCardAllEffect; import mage.abilities.effects.common.discard.DiscardEachPlayerEffect; @@ -9,24 +7,24 @@ import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.constants.CardType; +import java.util.UUID; + /** - * * @author North */ public final class BurningInquiry extends CardImpl { public BurningInquiry(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.SORCERY},"{R}"); - + super(ownerId, setInfo, new CardType[]{CardType.SORCERY}, "{R}"); // Each player draws three cards, then discards three cards at random. this.getSpellAbility().addEffect(new DrawCardAllEffect(3)); Effect effect = new DiscardEachPlayerEffect(3, true); - effect.setText("then discards three cards at random"); + effect.setText(", then discards three cards at random"); this.getSpellAbility().addEffect(effect); } - public BurningInquiry(final BurningInquiry card) { + private BurningInquiry(final BurningInquiry card) { super(card); } diff --git a/Mage.Sets/src/mage/cards/c/CabalTherapist.java b/Mage.Sets/src/mage/cards/c/CabalTherapist.java index 96978c84ee8..2a6a3ac881a 100644 --- a/Mage.Sets/src/mage/cards/c/CabalTherapist.java +++ b/Mage.Sets/src/mage/cards/c/CabalTherapist.java @@ -19,7 +19,6 @@ import mage.game.events.GameEvent; import mage.players.Player; import mage.target.TargetPlayer; import mage.target.common.TargetControlledPermanent; -import mage.target.common.TargetOpponent; import mage.util.CardUtil; import java.util.UUID; @@ -138,22 +137,27 @@ class CabalTherapistDiscardEffect extends OneShotEffect { return false; } String cardName = (String) game.getState().getValue(source.getSourceId().toString() + ChooseACardNameEffect.INFO_KEY); - Cards hand = targetPlayer.getHand(); - - for (Card card : hand.getCards(game)) { + Cards hand = targetPlayer.getHand().copy(); + targetPlayer.revealCards(source, hand, game); + hand.removeIf(uuid -> { + Card card = hand.get(uuid, game); + if (card == null) { + return true; + } if (card.isSplitCard()) { SplitCard splitCard = (SplitCard) card; if (CardUtil.haveSameNames(splitCard.getLeftHalfCard().getName(), cardName)) { - targetPlayer.discard(card, source, game); + return false; } else if (CardUtil.haveSameNames(splitCard.getRightHalfCard().getName(), cardName)) { - targetPlayer.discard(card, source, game); + return false; } } if (CardUtil.haveSameNames(card.getName(), cardName)) { - targetPlayer.discard(card, source, game); + return false; } - } - targetPlayer.revealCards("Cabal Therapist", hand, game); + return true; + }); + targetPlayer.discard(hand, source, game); return true; } diff --git a/Mage.Sets/src/mage/cards/c/CabalTherapy.java b/Mage.Sets/src/mage/cards/c/CabalTherapy.java index ba03643b0a7..6aad9ff861c 100644 --- a/Mage.Sets/src/mage/cards/c/CabalTherapy.java +++ b/Mage.Sets/src/mage/cards/c/CabalTherapy.java @@ -64,25 +64,31 @@ class CabalTherapyEffect extends OneShotEffect { Player targetPlayer = game.getPlayer(targetPointer.getFirst(game, source)); Player controller = game.getPlayer(source.getControllerId()); MageObject sourceObject = game.getObject(source.getSourceId()); - if (targetPlayer != null && controller != null && sourceObject != null) { - String cardName = (String) game.getState().getValue(source.getSourceId().toString() + ChooseACardNameEffect.INFO_KEY); - Cards hand = targetPlayer.getHand(); - - for (Card card : hand.getCards(game)) { - if (card.isSplitCard()) { - SplitCard splitCard = (SplitCard) card; - if (CardUtil.haveSameNames(splitCard.getLeftHalfCard().getName(), cardName)) { - targetPlayer.discard(card, source, game); - } else if (CardUtil.haveSameNames(splitCard.getRightHalfCard().getName(), cardName)) { - targetPlayer.discard(card, source, game); - } - } - if (CardUtil.haveSameNames(card.getName(), cardName)) { - targetPlayer.discard(card, source, game); + if (targetPlayer == null || controller == null || sourceObject == null) { + return false; + } + String cardName = (String) game.getState().getValue(source.getSourceId().toString() + ChooseACardNameEffect.INFO_KEY); + Cards hand = targetPlayer.getHand().copy(); + targetPlayer.revealCards(source, hand, game); + hand.removeIf(uuid -> { + Card card = hand.get(uuid, game); + if (card == null) { + return true; + } + if (card.isSplitCard()) { + SplitCard splitCard = (SplitCard) card; + if (CardUtil.haveSameNames(splitCard.getLeftHalfCard().getName(), cardName)) { + return false; + } else if (CardUtil.haveSameNames(splitCard.getRightHalfCard().getName(), cardName)) { + return false; } } - targetPlayer.revealCards("Cabal Therapy", hand, game); - } + if (CardUtil.haveSameNames(card.getName(), cardName)) { + return false; + } + return true; + }); + targetPlayer.discard(hand, source, game); return true; } diff --git a/Mage.Sets/src/mage/cards/c/ChandraFlamecaller.java b/Mage.Sets/src/mage/cards/c/ChandraFlamecaller.java index ce7de428f6a..2987b764e4b 100644 --- a/Mage.Sets/src/mage/cards/c/ChandraFlamecaller.java +++ b/Mage.Sets/src/mage/cards/c/ChandraFlamecaller.java @@ -10,7 +10,6 @@ import mage.abilities.effects.Effect; import mage.abilities.effects.OneShotEffect; import mage.abilities.effects.common.CreateTokenEffect; import mage.abilities.effects.common.DamageAllEffect; -import mage.cards.Card; import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.constants.CardType; @@ -22,7 +21,6 @@ import mage.game.Game; import mage.game.permanent.token.ElementalToken; import mage.players.Player; -import java.util.Set; import java.util.UUID; /** @@ -106,16 +104,12 @@ class ChandraDrawEffect extends OneShotEffect { @Override public boolean apply(Game game, Ability source) { Player player = game.getPlayer(source.getControllerId()); - if (player != null) { - Set cardsInHand = player.getHand().getCards(game); - int amount = cardsInHand.size(); - for (Card card : cardsInHand) { - player.discard(card, source, game); - } - player.drawCards(amount + 1, source.getSourceId(), game); - return true; + if (player == null) { + return false; } - return false; + int amount = player.discard(player.getHand(), source, game).size(); + player.drawCards(amount + 1, source.getSourceId(), game); + return true; } } diff --git a/Mage.Sets/src/mage/cards/c/CollectiveDefiance.java b/Mage.Sets/src/mage/cards/c/CollectiveDefiance.java index 553a8acec7e..81f3abefa9f 100644 --- a/Mage.Sets/src/mage/cards/c/CollectiveDefiance.java +++ b/Mage.Sets/src/mage/cards/c/CollectiveDefiance.java @@ -7,7 +7,6 @@ import mage.abilities.effects.Effect; import mage.abilities.effects.OneShotEffect; import mage.abilities.effects.common.DamageTargetEffect; import mage.abilities.keyword.EscalateAbility; -import mage.cards.Card; import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.constants.CardType; @@ -90,14 +89,11 @@ class CollectiveDefianceEffect extends OneShotEffect { @Override public boolean apply(Game game, Ability source) { Player targetPlayer = game.getPlayer(targetPointer.getFirst(game, source)); - if (targetPlayer != null) { - int count = targetPlayer.getHand().size(); - for (Card card : targetPlayer.getHand().getCards(game)) { - targetPlayer.discard(card, source, game); - } - targetPlayer.drawCards(count, source.getSourceId(), game); - return true; + if (targetPlayer == null) { + return false; } - return false; + int count = targetPlayer.discard(targetPlayer.getHand(), source, game).size(); + targetPlayer.drawCards(count, source.getSourceId(), game); + return true; } } diff --git a/Mage.Sets/src/mage/cards/c/CompulsiveResearch.java b/Mage.Sets/src/mage/cards/c/CompulsiveResearch.java index d132be25f8b..11e97e13c6c 100644 --- a/Mage.Sets/src/mage/cards/c/CompulsiveResearch.java +++ b/Mage.Sets/src/mage/cards/c/CompulsiveResearch.java @@ -1,7 +1,5 @@ - package mage.cards.c; -import java.util.UUID; import mage.abilities.Ability; import mage.abilities.effects.OneShotEffect; import mage.abilities.effects.common.DrawCardTargetEffect; @@ -10,20 +8,21 @@ import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.constants.CardType; import mage.constants.Outcome; +import mage.filter.StaticFilters; import mage.game.Game; import mage.players.Player; import mage.target.TargetPlayer; import mage.target.common.TargetDiscard; +import java.util.UUID; + /** - * * @author Plopman */ public final class CompulsiveResearch extends CardImpl { public CompulsiveResearch(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.SORCERY},"{2}{U}"); - + super(ownerId, setInfo, new CardType[]{CardType.SORCERY}, "{2}{U}"); // Target player draws three cards. Then that player discards two cards unless they discard a land card. this.getSpellAbility().addTarget(new TargetPlayer()); @@ -31,7 +30,7 @@ public final class CompulsiveResearch extends CardImpl { this.getSpellAbility().addEffect(new CompulsiveResearchDiscardEffect()); } - public CompulsiveResearch(final CompulsiveResearch card) { + private CompulsiveResearch(final CompulsiveResearch card) { super(card); } @@ -40,14 +39,15 @@ public final class CompulsiveResearch extends CardImpl { return new CompulsiveResearch(this); } } + class CompulsiveResearchDiscardEffect extends OneShotEffect { - public CompulsiveResearchDiscardEffect() { + CompulsiveResearchDiscardEffect() { super(Outcome.Discard); this.staticText = "Then that player discards two cards unless they discard a land card"; } - public CompulsiveResearchDiscardEffect(final CompulsiveResearchDiscardEffect effect) { + private CompulsiveResearchDiscardEffect(final CompulsiveResearchDiscardEffect effect) { super(effect); } @@ -59,18 +59,19 @@ class CompulsiveResearchDiscardEffect extends OneShotEffect { @Override public boolean apply(Game game, Ability source) { Player targetPlayer = game.getPlayer(this.getTargetPointer().getFirst(game, source)); - if (targetPlayer != null && !targetPlayer.getHand().isEmpty()) { - TargetDiscard target = new TargetDiscard(targetPlayer.getId()); - targetPlayer.choose(Outcome.Discard, target, source.getSourceId(), game); - Card card = targetPlayer.getHand().get(target.getFirstTarget(), game); - if (card != null) { - targetPlayer.discard(card, source, game); - if (!card.isLand() && !targetPlayer.getHand().isEmpty()) { - targetPlayer.discard(1, false, source, game); - } - return true; - } + if (targetPlayer == null || targetPlayer.getHand().isEmpty()) { + return false; } - return false; + if (targetPlayer.getHand().count(StaticFilters.FILTER_CARD_LAND, game) < 1 + || !targetPlayer.chooseUse(outcome, "Discard a land card?", source, game)) { + return !targetPlayer.discard(2, false, source, game).isEmpty(); + } + TargetDiscard target = new TargetDiscard(StaticFilters.FILTER_CARD_LAND_A, targetPlayer.getId()); + targetPlayer.choose(Outcome.Discard, target, source.getSourceId(), game); + Card card = targetPlayer.getHand().get(target.getFirstTarget(), game); + if (card != null && targetPlayer.discard(card, source, game)) { + return true; + } + return !targetPlayer.discard(2, false, source, game).isEmpty(); } } diff --git a/Mage.Sets/src/mage/cards/c/CrosisThePurger.java b/Mage.Sets/src/mage/cards/c/CrosisThePurger.java index b2f87e2d6a0..3646ea742d7 100644 --- a/Mage.Sets/src/mage/cards/c/CrosisThePurger.java +++ b/Mage.Sets/src/mage/cards/c/CrosisThePurger.java @@ -1,9 +1,5 @@ - package mage.cards.c; -import java.util.ArrayList; -import java.util.List; -import java.util.UUID; import mage.MageInt; import mage.abilities.Ability; import mage.abilities.common.DealsCombatDamageToAPlayerTriggeredAbility; @@ -11,23 +7,23 @@ import mage.abilities.costs.mana.ManaCostsImpl; import mage.abilities.effects.OneShotEffect; import mage.abilities.effects.common.DoIfCostPaid; import mage.abilities.keyword.FlyingAbility; -import mage.cards.Card; import mage.cards.CardImpl; import mage.cards.CardSetInfo; +import mage.cards.Cards; +import mage.cards.CardsImpl; import mage.choices.ChoiceColor; import mage.constants.CardType; import mage.constants.Outcome; import mage.constants.SubType; import mage.constants.SuperType; -import mage.filter.FilterCard; -import mage.filter.predicate.mageobject.ColorPredicate; import mage.game.Game; import mage.players.Player; +import java.util.UUID; +import java.util.stream.Collectors; + /** - * * @author LoneFox - * */ public final class CrosisThePurger extends CardImpl { @@ -45,7 +41,7 @@ public final class CrosisThePurger extends CardImpl { new ManaCostsImpl("{2}{B}")), false, true)); } - public CrosisThePurger(final CrosisThePurger card) { + private CrosisThePurger(final CrosisThePurger card) { super(card); } @@ -62,7 +58,7 @@ class CrosisThePurgerEffect extends OneShotEffect { this.staticText = "choose a color, then that player reveals their hand and discards all cards of that color."; } - CrosisThePurgerEffect(final CrosisThePurgerEffect effect) { + private CrosisThePurgerEffect(final CrosisThePurgerEffect effect) { super(effect); } @@ -74,30 +70,28 @@ class CrosisThePurgerEffect extends OneShotEffect { @Override public boolean apply(Game game, Ability source) { Player player = game.getPlayer(source.getControllerId()); - if (player != null) { - ChoiceColor choice = new ChoiceColor(); - player.choose(outcome, choice, game); - if (choice.isChosen()) { - game.informPlayers(player.getLogName() + " chooses " + choice.getColor()); - Player damagedPlayer = game.getPlayer(this.getTargetPointer().getFirst(game, source)); - if(damagedPlayer != null) { - damagedPlayer.revealCards("hand of " + damagedPlayer.getName(), damagedPlayer.getHand(), game); - FilterCard filter = new FilterCard(); - filter.add(new ColorPredicate(choice.getColor())); - List toDiscard = new ArrayList<>(); - for (UUID cardId : damagedPlayer.getHand()) { - Card card = game.getCard(cardId); - if (filter.match(card, game)) { - toDiscard.add(card); - } - } - for (Card card : toDiscard) { - damagedPlayer.discard(card, source, game); - } - return true; - } - } + if (player == null) { + return false; } - return false; + ChoiceColor choice = new ChoiceColor(); + player.choose(outcome, choice, game); + if (!choice.isChosen()) { + return false; + } + game.informPlayers(player.getLogName() + " chooses " + choice.getColor()); + Player damagedPlayer = game.getPlayer(this.getTargetPointer().getFirst(game, source)); + if (damagedPlayer == null) { + return false; + } + damagedPlayer.revealCards("hand of " + damagedPlayer.getName(), damagedPlayer.getHand(), game); + Cards cards = new CardsImpl( + player.getHand() + .getCards(game) + .stream() + .filter(card -> card.getColor(game).shares(choice.getColor())) + .collect(Collectors.toSet()) + ); + damagedPlayer.discard(cards, source, game); + return true; } } diff --git a/Mage.Sets/src/mage/cards/d/DangerousWager.java b/Mage.Sets/src/mage/cards/d/DangerousWager.java index 1d328c8c063..1e98390b3eb 100644 --- a/Mage.Sets/src/mage/cards/d/DangerousWager.java +++ b/Mage.Sets/src/mage/cards/d/DangerousWager.java @@ -1,34 +1,27 @@ - package mage.cards.d; -import java.util.UUID; -import mage.abilities.Ability; -import mage.abilities.effects.OneShotEffect; import mage.abilities.effects.common.DrawCardSourceControllerEffect; -import mage.cards.Card; +import mage.abilities.effects.common.discard.DiscardHandControllerEffect; import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.constants.CardType; -import mage.constants.Outcome; -import mage.game.Game; -import mage.players.Player; + +import java.util.UUID; /** - * * @author North */ public final class DangerousWager extends CardImpl { public DangerousWager(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.INSTANT},"{1}{R}"); - + super(ownerId, setInfo, new CardType[]{CardType.INSTANT}, "{1}{R}"); // Discard your hand, then draw two cards. - this.getSpellAbility().addEffect(new DangerousWagerEffect()); - this.getSpellAbility().addEffect(new DrawCardSourceControllerEffect(2)); + this.getSpellAbility().addEffect(new DiscardHandControllerEffect()); + this.getSpellAbility().addEffect(new DrawCardSourceControllerEffect(2).setText(", then draw two cards")); } - public DangerousWager(final DangerousWager card) { + private DangerousWager(final DangerousWager card) { super(card); } @@ -37,32 +30,3 @@ public final class DangerousWager extends CardImpl { return new DangerousWager(this); } } - -class DangerousWagerEffect extends OneShotEffect { - - public DangerousWagerEffect() { - super(Outcome.Discard); - this.staticText = "Discard your hand"; - } - - public DangerousWagerEffect(final DangerousWagerEffect effect) { - super(effect); - } - - @Override - public DangerousWagerEffect copy() { - return new DangerousWagerEffect(this); - } - - @Override - public boolean apply(Game game, Ability source) { - Player player = game.getPlayer(source.getControllerId()); - if (player != null) { - for (Card card : player.getHand().getCards(game)) { - player.discard(card, source, game); - } - return true; - } - return false; - } -} diff --git a/Mage.Sets/src/mage/cards/d/DarettiScrapSavant.java b/Mage.Sets/src/mage/cards/d/DarettiScrapSavant.java index 03bf92605cd..294589fc0c3 100644 --- a/Mage.Sets/src/mage/cards/d/DarettiScrapSavant.java +++ b/Mage.Sets/src/mage/cards/d/DarettiScrapSavant.java @@ -1,7 +1,5 @@ - package mage.cards.d; -import java.util.UUID; import mage.abilities.Ability; import mage.abilities.LoyaltyAbility; import mage.abilities.common.CanBeYourCommanderAbility; @@ -14,12 +12,8 @@ import mage.abilities.effects.common.ReturnFromGraveyardToBattlefieldTargetEffec import mage.cards.Card; import mage.cards.CardImpl; import mage.cards.CardSetInfo; -import mage.constants.CardType; -import mage.constants.SubType; -import mage.constants.Outcome; -import mage.constants.SuperType; -import mage.constants.TargetController; -import mage.constants.Zone; +import mage.cards.CardsImpl; +import mage.constants.*; import mage.filter.FilterCard; import mage.filter.common.FilterArtifactCard; import mage.filter.common.FilterControlledArtifactPermanent; @@ -33,8 +27,9 @@ import mage.target.common.TargetControlledPermanent; import mage.target.common.TargetDiscard; import mage.target.targetpointer.FixedTarget; +import java.util.UUID; + /** - * * @author LevelX2 */ public final class DarettiScrapSavant extends CardImpl { @@ -93,14 +88,7 @@ class DarettiDiscardDrawEffect extends OneShotEffect { if (controller != null) { TargetDiscard target = new TargetDiscard(0, 2, new FilterCard(), controller.getId()); target.choose(outcome, controller.getId(), source.getSourceId(), game); - int count = 0; - for (UUID cardId : target.getTargets()) { - Card card = game.getCard(cardId); - if (card != null) { - controller.discard(card, source, game); - count++; - } - } + int count = controller.discard(new CardsImpl(target.getTargets()), source, game).size(); controller.drawCards(count, source.getSourceId(), game); return true; } diff --git a/Mage.Sets/src/mage/cards/d/DiscordantDirge.java b/Mage.Sets/src/mage/cards/d/DiscordantDirge.java index 4d2c5f94052..f81f8fa141b 100644 --- a/Mage.Sets/src/mage/cards/d/DiscordantDirge.java +++ b/Mage.Sets/src/mage/cards/d/DiscordantDirge.java @@ -9,6 +9,7 @@ import mage.abilities.effects.OneShotEffect; import mage.abilities.effects.common.counter.AddCountersSourceEffect; import mage.cards.CardImpl; import mage.cards.CardSetInfo; +import mage.cards.CardsImpl; import mage.constants.CardType; import mage.constants.Outcome; import mage.constants.TargetController; @@ -21,7 +22,6 @@ import mage.players.Player; import mage.target.TargetCard; import mage.target.common.TargetOpponent; -import java.util.Objects; import java.util.UUID; /** @@ -29,8 +29,6 @@ import java.util.UUID; */ public final class DiscordantDirge extends CardImpl { - private static final String rule = "Look at target opponent's hand and choose up to X cards from it, where X is the number of verse counters on {this}. That player discards those cards.."; - public DiscordantDirge(UUID ownerId, CardSetInfo setInfo) { super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{3}{B}{B}"); @@ -47,7 +45,7 @@ public final class DiscordantDirge extends CardImpl { this.addAbility(ability); } - public DiscordantDirge(final DiscordantDirge card) { + private DiscordantDirge(final DiscordantDirge card) { super(card); } @@ -59,37 +57,37 @@ public final class DiscordantDirge extends CardImpl { class DiscordantDirgeEffect extends OneShotEffect { - public DiscordantDirgeEffect() { + DiscordantDirgeEffect() { super(Outcome.Benefit); - staticText = "Look at target opponent's hand and choose up to X cards from it, where X is the number of verse counters on {this}. That player discards those card."; + staticText = "Look at target opponent's hand and choose up to X cards from it, " + + "where X is the number of verse counters on {this}. That player discards those cards"; } - public DiscordantDirgeEffect(final DiscordantDirgeEffect effect) { + private DiscordantDirgeEffect(final DiscordantDirgeEffect effect) { super(effect); } @Override public boolean apply(Game game, Ability source) { Permanent discordantDirge = game.getPermanentOrLKIBattlefield(source.getSourceId()); - if (discordantDirge != null) { - int verseCounters = discordantDirge.getCounters(game).getCount(CounterType.VERSE); - Player targetOpponent = game.getPlayer(source.getFirstTarget()); - Player controller = game.getPlayer(source.getControllerId()); - if (targetOpponent != null - && controller != null) { - controller.lookAtCards(targetOpponent.getName() + " hand", targetOpponent.getHand(), game); - TargetCard target = new TargetCard(0, verseCounters, Zone.HAND, new FilterCard()); - target.setNotTarget(true); - if (controller.choose(Outcome.Benefit, targetOpponent.getHand(), target, game)) { - target.getTargets().stream().map(game::getCard).filter(Objects::nonNull).filter((card) -> (card != null - && targetOpponent.getHand().contains(card.getId()))).forEachOrdered((card) -> { - targetOpponent.discard(card, source, game); - }); - return true; - } - } + if (discordantDirge == null) { + return false; } - return false; + int verseCounters = discordantDirge.getCounters(game).getCount(CounterType.VERSE); + Player targetOpponent = game.getPlayer(source.getFirstTarget()); + Player controller = game.getPlayer(source.getControllerId()); + if (targetOpponent == null + || controller == null) { + return false; + } + controller.lookAtCards(targetOpponent.getName() + " hand", targetOpponent.getHand(), game); + TargetCard target = new TargetCard(0, verseCounters, Zone.HAND, new FilterCard()); + target.setNotTarget(true); + if (!controller.choose(Outcome.Benefit, targetOpponent.getHand(), target, game)) { + return false; + } + targetOpponent.discard(new CardsImpl(target.getTargets()), source, game); + return true; } @Override diff --git a/Mage.Sets/src/mage/cards/d/DistendedMindbender.java b/Mage.Sets/src/mage/cards/d/DistendedMindbender.java index 13500ac1449..cff8d820f64 100644 --- a/Mage.Sets/src/mage/cards/d/DistendedMindbender.java +++ b/Mage.Sets/src/mage/cards/d/DistendedMindbender.java @@ -1,38 +1,37 @@ - package mage.cards.d; -import java.util.List; -import java.util.UUID; import mage.MageInt; import mage.abilities.Ability; import mage.abilities.costs.mana.ManaCostsImpl; import mage.abilities.effects.OneShotEffect; import mage.abilities.effects.common.CastSourceTriggeredAbility; import mage.abilities.keyword.EmergeAbility; -import mage.cards.Card; import mage.cards.CardImpl; import mage.cards.CardSetInfo; +import mage.cards.Cards; +import mage.cards.CardsImpl; import mage.constants.CardType; -import mage.constants.SubType; import mage.constants.ComparisonType; import mage.constants.Outcome; -import mage.constants.Zone; +import mage.constants.SubType; import mage.filter.FilterCard; import mage.filter.predicate.Predicates; import mage.filter.predicate.mageobject.ConvertedManaCostPredicate; import mage.game.Game; import mage.players.Player; import mage.target.TargetCard; +import mage.target.common.TargetCardInHand; import mage.target.common.TargetOpponent; +import java.util.UUID; + /** - * * @author fireshoes */ public final class DistendedMindbender extends CardImpl { public DistendedMindbender(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{8}"); + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{8}"); this.subtype.add(SubType.ELDRAZI); this.subtype.add(SubType.INSECT); this.power = new MageInt(5); @@ -88,30 +87,20 @@ class DistendedMindbenderEffect extends OneShotEffect { public boolean apply(Game game, Ability source) { Player opponent = game.getPlayer(source.getFirstTarget()); Player controller = game.getPlayer(source.getControllerId()); - if (opponent != null && controller != null) { - opponent.revealCards("Distended Mindbender", opponent.getHand(), game); - TargetCard targetThreeOrLess = new TargetCard(1, Zone.HAND, filterThreeOrLess); - TargetCard targetFourOrGreater = new TargetCard(1, Zone.HAND, filterFourOrGreater); - if (controller.choose(Outcome.Benefit, opponent.getHand(), targetThreeOrLess, game)) { - List targets = targetThreeOrLess.getTargets(); - for (UUID targetId : targets) { - Card card = opponent.getHand().get(targetId, game); - if (card != null) { - opponent.discard(card, source, game); - } - } - } - if (controller.choose(Outcome.Benefit, opponent.getHand(), targetFourOrGreater, game)) { - List targets = targetFourOrGreater.getTargets(); - for (UUID targetId : targets) { - Card card = opponent.getHand().get(targetId, game); - if (card != null) { - opponent.discard(card, source, game); - } - } - } - return true; + if (opponent == null || controller == null) { + return false; } - return false; + opponent.revealCards(source, opponent.getHand(), game); + TargetCard targetThreeOrLess = new TargetCardInHand(1, filterThreeOrLess); + TargetCard targetFourOrGreater = new TargetCardInHand(1, filterFourOrGreater); + Cards toDiscard = new CardsImpl(); + if (controller.choose(Outcome.Benefit, opponent.getHand(), targetThreeOrLess, game)) { + toDiscard.addAll(targetThreeOrLess.getTargets()); + } + if (controller.choose(Outcome.Benefit, opponent.getHand(), targetFourOrGreater, game)) { + toDiscard.addAll(targetFourOrGreater.getTargets()); + } + opponent.discard(toDiscard, source, game); + return true; } } diff --git a/Mage.Sets/src/mage/cards/d/DrasticRevelation.java b/Mage.Sets/src/mage/cards/d/DrasticRevelation.java index d6391c7de8e..df6a334e9ae 100644 --- a/Mage.Sets/src/mage/cards/d/DrasticRevelation.java +++ b/Mage.Sets/src/mage/cards/d/DrasticRevelation.java @@ -2,10 +2,8 @@ package mage.cards.d; import mage.abilities.Ability; import mage.abilities.effects.OneShotEffect; -import mage.cards.Card; import mage.cards.CardImpl; import mage.cards.CardSetInfo; -import mage.cards.Cards; import mage.constants.CardType; import mage.constants.Outcome; import mage.game.Game; @@ -25,7 +23,7 @@ public final class DrasticRevelation extends CardImpl { this.getSpellAbility().addEffect(new DrasticRevelationEffect()); } - public DrasticRevelation(final DrasticRevelation card) { + private DrasticRevelation(final DrasticRevelation card) { super(card); } @@ -42,24 +40,19 @@ class DrasticRevelationEffect extends OneShotEffect { staticText = "Discard your hand. Draw seven cards, then discard three cards at random"; } - DrasticRevelationEffect(final DrasticRevelationEffect effect) { + private DrasticRevelationEffect(final DrasticRevelationEffect effect) { super(effect); } @Override public boolean apply(Game game, Ability source) { Player you = game.getPlayer(source.getControllerId()); - if (you != null) { - you.discard(you.getHand().size(), false, source, game); - you.drawCards(7, source.getSourceId(), game); - Cards hand = you.getHand(); - for (int i = 0; i < 3; i++) { - Card card = hand.getRandom(game); - if (card != null) { - you.discard(card, source, game); - } - } + if (you == null) { + return false; } + you.discard(you.getHand(), source, game); + you.drawCards(7, source.getSourceId(), game); + you.discard(3, true, source, game); return false; } @@ -67,4 +60,4 @@ class DrasticRevelationEffect extends OneShotEffect { public DrasticRevelationEffect copy() { return new DrasticRevelationEffect(this); } -} \ No newline at end of file +} diff --git a/Mage.Sets/src/mage/cards/e/Extortion.java b/Mage.Sets/src/mage/cards/e/Extortion.java index 46d5163ae06..86c210dc310 100644 --- a/Mage.Sets/src/mage/cards/e/Extortion.java +++ b/Mage.Sets/src/mage/cards/e/Extortion.java @@ -1,19 +1,18 @@ - package mage.cards.e; import mage.abilities.Ability; import mage.abilities.effects.OneShotEffect; -import mage.cards.Card; import mage.cards.CardImpl; import mage.cards.CardSetInfo; +import mage.cards.CardsImpl; import mage.constants.CardType; import mage.constants.Outcome; -import mage.constants.Zone; -import mage.filter.FilterCard; +import mage.filter.StaticFilters; import mage.game.Game; import mage.players.Player; import mage.target.TargetCard; import mage.target.TargetPlayer; +import mage.target.common.TargetCardInHand; import java.util.UUID; @@ -30,7 +29,7 @@ public final class Extortion extends CardImpl { this.getSpellAbility().addTarget(new TargetPlayer()); } - public Extortion(final Extortion card) { + private Extortion(final Extortion card) { super(card); } @@ -42,12 +41,12 @@ public final class Extortion extends CardImpl { class ExtortionEffect extends OneShotEffect { - public ExtortionEffect() { + ExtortionEffect() { super(Outcome.Discard); - staticText = "Look at target player's hand and choose up to two cards from it. That player discards that card."; + staticText = "Look at target player's hand and choose up to two cards from it. That player discards those cards."; } - public ExtortionEffect(final ExtortionEffect effect) { + private ExtortionEffect(final ExtortionEffect effect) { super(effect); } @@ -55,18 +54,15 @@ class ExtortionEffect extends OneShotEffect { public boolean apply(Game game, Ability source) { Player targetPlayer = game.getPlayer(source.getFirstTarget()); Player you = game.getPlayer(source.getControllerId()); - if (targetPlayer != null && you != null) { - you.lookAtCards("Discard", targetPlayer.getHand(), game); - TargetCard target = new TargetCard(0, 2, Zone.HAND, new FilterCard()); - target.setNotTarget(true); - if (you.choose(Outcome.Benefit, targetPlayer.getHand(), target, game)) { - Card card = targetPlayer.getHand().get(target.getFirstTarget(), game); - return targetPlayer.discard(card, source, game); - - } - + if (targetPlayer == null || you == null) { + return false; } - return false; + you.lookAtCards("Discard", targetPlayer.getHand(), game); + TargetCard target = new TargetCardInHand(0, 2, StaticFilters.FILTER_CARD_CARDS); + target.setNotTarget(true); + you.choose(Outcome.Discard, targetPlayer.getHand(), target, game); + targetPlayer.discard(new CardsImpl(target.getTargets()), source, game); + return true; } @Override diff --git a/Mage.Sets/src/mage/cards/g/GruesomeDiscovery.java b/Mage.Sets/src/mage/cards/g/GruesomeDiscovery.java index 7e996c5a251..9d33d69e3c8 100644 --- a/Mage.Sets/src/mage/cards/g/GruesomeDiscovery.java +++ b/Mage.Sets/src/mage/cards/g/GruesomeDiscovery.java @@ -1,4 +1,3 @@ - package mage.cards.g; import mage.abilities.Ability; @@ -6,19 +5,18 @@ import mage.abilities.condition.common.MorbidCondition; import mage.abilities.decorator.ConditionalOneShotEffect; import mage.abilities.effects.OneShotEffect; import mage.abilities.effects.common.discard.DiscardTargetEffect; -import mage.cards.Card; import mage.cards.CardImpl; import mage.cards.CardSetInfo; +import mage.cards.CardsImpl; import mage.constants.CardType; import mage.constants.Outcome; -import mage.constants.Zone; -import mage.filter.FilterCard; +import mage.filter.StaticFilters; import mage.game.Game; import mage.players.Player; import mage.target.TargetCard; import mage.target.TargetPlayer; +import mage.target.common.TargetCardInHand; -import java.util.List; import java.util.UUID; /** @@ -29,18 +27,18 @@ public final class GruesomeDiscovery extends CardImpl { public GruesomeDiscovery(UUID ownerId, CardSetInfo setInfo) { super(ownerId, setInfo, new CardType[]{CardType.SORCERY}, "{2}{B}{B}"); - // Target player discards two cards. // Morbid — If a creature died this turn, instead that player reveals their hand, you choose two cards from it, then that player discards those cards. this.getSpellAbility().addEffect(new ConditionalOneShotEffect( - new GruesomeDiscoveryEffect(), - new DiscardTargetEffect(2), - MorbidCondition.instance, - "Target player discards two cards. Morbid — If a creature died this turn, instead that player reveals their hand, you choose two cards from it, then that player discards those cards")); + new GruesomeDiscoveryEffect(), new DiscardTargetEffect(2), + MorbidCondition.instance, "Target player discards two cards. " + + "
Morbid — If a creature died this turn, instead that player reveals their hand, " + + "you choose two cards from it, then that player discards those cards" + )); this.getSpellAbility().addTarget(new TargetPlayer()); } - public GruesomeDiscovery(final GruesomeDiscovery card) { + private GruesomeDiscovery(final GruesomeDiscovery card) { super(card); } @@ -52,12 +50,11 @@ public final class GruesomeDiscovery extends CardImpl { class GruesomeDiscoveryEffect extends OneShotEffect { - public GruesomeDiscoveryEffect() { + GruesomeDiscoveryEffect() { super(Outcome.Discard); - this.staticText = "target player reveals their hand, you choose two cards from it, then that player discards those cards"; } - public GruesomeDiscoveryEffect(final GruesomeDiscoveryEffect effect) { + private GruesomeDiscoveryEffect(final GruesomeDiscoveryEffect effect) { super(effect); } @@ -70,25 +67,16 @@ class GruesomeDiscoveryEffect extends OneShotEffect { public boolean apply(Game game, Ability source) { Player player = game.getPlayer(source.getControllerId()); Player targetPlayer = game.getPlayer(source.getFirstTarget()); - - if (player != null && targetPlayer != null) { - targetPlayer.revealCards("Gruesome Discovery", targetPlayer.getHand(), game); - - if (targetPlayer.getHand().size() <= 2) { - targetPlayer.discard(2, false, source, game); - } - - TargetCard target = new TargetCard(2, Zone.HAND, new FilterCard()); - if (player.choose(Outcome.Benefit, targetPlayer.getHand(), target, game)) { - List targets = target.getTargets(); - for (UUID targetId : targets) { - Card card = targetPlayer.getHand().get(targetId, game); - targetPlayer.discard(card, source, game); - - } - } - return true; + if (player == null || targetPlayer == null) { + return false; } - return false; + targetPlayer.revealCards(source, targetPlayer.getHand(), game); + if (targetPlayer.getHand().size() <= 2) { + targetPlayer.discard(2, false, source, game); + } + TargetCard target = new TargetCardInHand(2, StaticFilters.FILTER_CARD_CARDS); + player.choose(Outcome.Discard, targetPlayer.getHand(), target, game); + targetPlayer.discard(new CardsImpl(target.getTargets()), source, game); + return true; } } diff --git a/Mage.Sets/src/mage/cards/h/HintOfInsanity.java b/Mage.Sets/src/mage/cards/h/HintOfInsanity.java index 1d299587214..d41189a633a 100644 --- a/Mage.Sets/src/mage/cards/h/HintOfInsanity.java +++ b/Mage.Sets/src/mage/cards/h/HintOfInsanity.java @@ -1,21 +1,26 @@ package mage.cards.h; +import mage.MageObject; import mage.abilities.Ability; import mage.abilities.effects.OneShotEffect; -import mage.cards.*; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.cards.Cards; +import mage.cards.CardsImpl; import mage.constants.CardType; import mage.constants.Outcome; -import mage.filter.FilterCard; import mage.game.Game; import mage.players.Player; import mage.target.TargetPlayer; -import mage.target.common.TargetCardInHand; -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 jeffwadsworth + * @author TheElk801 */ public final class HintOfInsanity extends CardImpl { @@ -25,10 +30,9 @@ public final class HintOfInsanity extends CardImpl { // Target player reveals their hand. That player discards all nonland cards with the same name as another card in their hand. this.getSpellAbility().addEffect(new HintOfInsanityEffect()); this.getSpellAbility().addTarget(new TargetPlayer()); - } - public HintOfInsanity(final HintOfInsanity card) { + private HintOfInsanity(final HintOfInsanity card) { super(card); } @@ -40,12 +44,13 @@ public final class HintOfInsanity extends CardImpl { class HintOfInsanityEffect extends OneShotEffect { - public HintOfInsanityEffect() { + HintOfInsanityEffect() { super(Outcome.Discard); - this.staticText = "Target player reveals their hand. That player discards all nonland cards with the same name as another card in their hand"; + this.staticText = "Target player reveals their hand. " + + "That player discards all nonland cards with the same name as another card in their hand"; } - public HintOfInsanityEffect(final HintOfInsanityEffect effect) { + private HintOfInsanityEffect(final HintOfInsanityEffect effect) { super(effect); } @@ -56,26 +61,26 @@ class HintOfInsanityEffect extends OneShotEffect { @Override public boolean apply(Game game, Ability source) { - FilterCard filter = new FilterCard("card from your hand"); - Player targetPlayer = game.getPlayer(source.getFirstTarget()); - Card chosenCard; - if (targetPlayer != null) { - TargetCardInHand targetCard = new TargetCardInHand(filter); - targetCard.setNotTarget(true); - Cards cardsInHand = new CardsImpl(); - cardsInHand.addAll(targetPlayer.getHand()); - targetPlayer.revealCards("Hint of Insanity Reveal", cardsInHand, game); - if (!cardsInHand.isEmpty() - && targetPlayer.choose(Outcome.Discard, targetCard, source.getSourceId(), game)) { - chosenCard = game.getCard(targetCard.getFirstTarget()); - for (Card card : cardsInHand.getCards(game)) { - if (CardUtil.haveSameNames(card, chosenCard) && !card.isLand()) { - targetPlayer.discard(card, source, game); - } - } - return true; - } + Player player = game.getPlayer(source.getFirstTarget()); + if (player == null) { + return false; } - return false; + Map nameCounts = new HashMap<>(); + player.getHand() + .getCards(game) + .stream() + .map(MageObject::getName) + .forEach(s -> nameCounts.compute(s, (u, i) -> i == null ? 1 : Integer.sum(i, 1))); + Cards cards = new CardsImpl( + player.getHand() + .getCards(game) + .stream() + .filter(Objects::nonNull) + .filter(card -> !card.isLand()) + .filter(card -> nameCounts.getOrDefault(card.getName(), 0) > 1) + .collect(Collectors.toSet()) + ); + player.discard(cards, source, game); + return true; } } diff --git a/Mage.Sets/src/mage/cards/i/InfernalKirin.java b/Mage.Sets/src/mage/cards/i/InfernalKirin.java index 38cdc8b4a79..eedc3483ba4 100644 --- a/Mage.Sets/src/mage/cards/i/InfernalKirin.java +++ b/Mage.Sets/src/mage/cards/i/InfernalKirin.java @@ -1,20 +1,14 @@ - package mage.cards.i; -import java.util.UUID; import mage.MageInt; import mage.abilities.Ability; import mage.abilities.common.SpellCastControllerTriggeredAbility; import mage.abilities.effects.OneShotEffect; import mage.abilities.keyword.FlyingAbility; -import mage.cards.Card; import mage.cards.CardImpl; import mage.cards.CardSetInfo; -import mage.constants.CardType; -import mage.constants.SubType; -import mage.constants.Outcome; -import mage.constants.SuperType; -import mage.constants.Zone; +import mage.cards.Cards; +import mage.constants.*; import mage.filter.StaticFilters; import mage.game.Game; import mage.game.stack.Spell; @@ -22,8 +16,9 @@ import mage.players.Player; import mage.target.Target; import mage.target.TargetPlayer; +import java.util.UUID; + /** - * * @author LevelX2 */ public final class InfernalKirin extends CardImpl { @@ -39,14 +34,14 @@ public final class InfernalKirin extends CardImpl { // Flying this.addAbility(FlyingAbility.getInstance()); + // Whenever you cast a Spirit or Arcane spell, target player reveals their hand and discards all cards with that spell's converted mana cost. Ability ability = new SpellCastControllerTriggeredAbility(Zone.BATTLEFIELD, new InfernalKirinEffect(), StaticFilters.SPIRIT_OR_ARCANE_CARD, false, true); ability.addTarget(new TargetPlayer()); this.addAbility(ability); - } - public InfernalKirin(final InfernalKirin card) { + private InfernalKirin(final InfernalKirin card) { super(card); } @@ -58,12 +53,12 @@ public final class InfernalKirin extends CardImpl { class InfernalKirinEffect extends OneShotEffect { - public InfernalKirinEffect() { + InfernalKirinEffect() { super(Outcome.Detriment); this.staticText = "target player reveals their hand and discards all cards with that spell's converted mana cost"; } - public InfernalKirinEffect(final InfernalKirinEffect effect) { + private InfernalKirinEffect(final InfernalKirinEffect effect) { super(effect); } @@ -75,27 +70,26 @@ class InfernalKirinEffect extends OneShotEffect { @Override public boolean apply(Game game, Ability source) { Spell spell = game.getSpellOrLKIStack(this.getTargetPointer().getFirst(game, source)); - if (spell != null) { - int cmc = spell.getConvertedManaCost(); - Player targetPlayer = null; - for (Target target : source.getTargets()) { - if (target instanceof TargetPlayer) { - targetPlayer = game.getPlayer(target.getFirstTarget()); - } - } - if (targetPlayer != null) { - if (!targetPlayer.getHand().isEmpty()) { - targetPlayer.revealCards("Infernal Kirin", targetPlayer.getHand(), game); - for (UUID uuid : targetPlayer.getHand().copy()) { - Card card = game.getCard(uuid); - if (card != null && card.getConvertedManaCost() == cmc) { - targetPlayer.discard(card, source, game); - } - } - } - return true; + if (spell == null) { + return false; + } + int cmc = spell.getConvertedManaCost(); + Player targetPlayer = null; + for (Target target : source.getTargets()) { + if (target instanceof TargetPlayer) { + targetPlayer = game.getPlayer(target.getFirstTarget()); } } - return false; + if (targetPlayer == null) { + return false; + } + if (targetPlayer.getHand().isEmpty()) { + return true; + } + targetPlayer.revealCards(source, targetPlayer.getHand(), game); + Cards cards = targetPlayer.getHand().copy(); + cards.removeIf(uuid -> game.getCard(uuid).getConvertedManaCost() != cmc); + targetPlayer.discard(cards, source, game); + return true; } } diff --git a/Mage.Sets/src/mage/cards/j/JayaBallard.java b/Mage.Sets/src/mage/cards/j/JayaBallard.java index 8af23864bfc..6b0e37e0755 100644 --- a/Mage.Sets/src/mage/cards/j/JayaBallard.java +++ b/Mage.Sets/src/mage/cards/j/JayaBallard.java @@ -1,18 +1,16 @@ - package mage.cards.j; -import java.util.UUID; import mage.Mana; import mage.abilities.Ability; import mage.abilities.LoyaltyAbility; import mage.abilities.common.PlaneswalkerEntersWithLoyaltyCountersAbility; import mage.abilities.effects.OneShotEffect; -import mage.abilities.effects.mana.AddConditionalManaEffect; import mage.abilities.effects.common.GetEmblemEffect; +import mage.abilities.effects.mana.AddConditionalManaEffect; import mage.abilities.mana.builder.common.InstantOrSorcerySpellManaBuilder; -import mage.cards.Card; import mage.cards.CardImpl; import mage.cards.CardSetInfo; +import mage.cards.CardsImpl; import mage.constants.CardType; import mage.constants.Outcome; import mage.constants.SubType; @@ -24,8 +22,9 @@ import mage.players.Player; import mage.target.common.TargetDiscard; import mage.watchers.common.CastFromGraveyardWatcher; +import java.util.UUID; + /** - * * @author LevelX2 */ public final class JayaBallard extends CardImpl { @@ -76,20 +75,13 @@ class JayaBallardDiscardDrawEffect extends OneShotEffect { @Override public boolean apply(Game game, Ability source) { Player controller = game.getPlayer(source.getControllerId()); - if (controller != null) { - TargetDiscard target = new TargetDiscard(0, 3, new FilterCard(), controller.getId()); - target.choose(outcome, controller.getId(), source.getSourceId(), game); - int count = 0; - for (UUID cardId : target.getTargets()) { - Card card = game.getCard(cardId); - if (card != null) { - controller.discard(card, source, game); - count++; - } - } - controller.drawCards(count, source.getSourceId(), game); - return true; + if (controller == null) { + return false; } - return false; + TargetDiscard target = new TargetDiscard(0, 3, new FilterCard(), controller.getId()); + target.choose(outcome, controller.getId(), source.getSourceId(), game); + int count = controller.discard(new CardsImpl(target.getTargets()), source, game).size(); + controller.drawCards(count, source.getSourceId(), game); + return true; } } diff --git a/Mage.Sets/src/mage/cards/l/LastRites.java b/Mage.Sets/src/mage/cards/l/LastRites.java index 7cb78edc19a..81d3dcb06b9 100644 --- a/Mage.Sets/src/mage/cards/l/LastRites.java +++ b/Mage.Sets/src/mage/cards/l/LastRites.java @@ -1,29 +1,30 @@ package mage.cards.l; -import java.util.UUID; import mage.abilities.Ability; import mage.abilities.dynamicvalue.common.StaticValue; import mage.abilities.effects.Effect; import mage.abilities.effects.OneShotEffect; import mage.abilities.effects.common.discard.DiscardCardYouChooseTargetEffect; -import mage.cards.Card; import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.cards.Cards; +import mage.cards.CardsImpl; import mage.constants.CardType; import mage.constants.Outcome; import mage.constants.TargetController; -import mage.constants.Zone; import mage.filter.FilterCard; +import mage.filter.StaticFilters; import mage.filter.predicate.Predicates; import mage.game.Game; import mage.players.Player; import mage.target.TargetCard; import mage.target.TargetPlayer; +import mage.target.common.TargetDiscard; import mage.target.targetpointer.FixedTarget; +import java.util.UUID; + /** - * * @author L_J */ public final class LastRites extends CardImpl { @@ -32,14 +33,13 @@ public final class LastRites extends CardImpl { super(ownerId, setInfo, new CardType[]{CardType.SORCERY}, "{2}{B}"); // Discard any number of cards. Target player reveals their hand, then - //you choose a nonland card from it for each card discarded + // you choose a nonland card from it for each card discarded // this way. That player discards those cards. this.getSpellAbility().addEffect(new LastRitesEffect()); this.getSpellAbility().addTarget(new TargetPlayer()); - } - public LastRites(final LastRites card) { + private LastRites(final LastRites card) { super(card); } @@ -58,7 +58,7 @@ class LastRitesEffect extends OneShotEffect { + "each card discarded this way. That player discards those cards"; } - LastRitesEffect(final LastRitesEffect effect) { + private LastRitesEffect(final LastRitesEffect effect) { super(effect); } @@ -71,28 +71,21 @@ class LastRitesEffect extends OneShotEffect { public boolean apply(Game game, Ability source) { Player controller = game.getPlayer(source.getControllerId()); Player targetPlayer = game.getPlayer(this.getTargetPointer().getFirst(game, source)); - if (controller != null && targetPlayer != null) { - Cards cardsInHand = controller.getHand().copy(); - TargetCard target = new TargetCard(0, Integer.MAX_VALUE, Zone.HAND, new FilterCard("cards to discard")); - controller.chooseTarget(Outcome.AIDontUseIt, cardsInHand, target, source, game); - int discardCount = target.getTargets().size(); - if (discardCount > 0) { - for (UUID cardId : target.getTargets()) { - Card card = game.getCard(cardId); - if (card != null) { - controller.discard(card, source, game); - } - } - FilterCard filter = new FilterCard((discardCount > 1 ? "" : "a") - + " nonland card" + (discardCount > 1 ? "s" : "")); - filter.add(Predicates.not(CardType.LAND.getPredicate())); - StaticValue discardValue = StaticValue.get(discardCount); - Effect effect = new DiscardCardYouChooseTargetEffect(discardValue, filter, TargetController.ANY); - effect.setTargetPointer(new FixedTarget(targetPlayer.getId())); - effect.apply(game, source); - } - return true; + if (controller == null || targetPlayer == null) { + return false; } - return false; + Cards cardsInHand = controller.getHand().copy(); + TargetCard target = new TargetDiscard( + 0, Integer.MAX_VALUE, StaticFilters.FILTER_CARD_CARDS, controller.getId() + ); + controller.chooseTarget(Outcome.AIDontUseIt, cardsInHand, target, source, game); + int discardCount = controller.discard(new CardsImpl(target.getTargets()), source, game).size(); + FilterCard filter = new FilterCard((discardCount > 1 ? "" : "a") + + " nonland card" + (discardCount > 1 ? "s" : "")); + filter.add(Predicates.not(CardType.LAND.getPredicate())); + Effect effect = new DiscardCardYouChooseTargetEffect(StaticValue.get(discardCount), filter, TargetController.ANY); + effect.setTargetPointer(new FixedTarget(targetPlayer.getId())); + effect.apply(game, source); + return true; } } diff --git a/Mage.Sets/src/mage/cards/l/LeaveChance.java b/Mage.Sets/src/mage/cards/l/LeaveChance.java index 4298a545403..00c6923f172 100644 --- a/Mage.Sets/src/mage/cards/l/LeaveChance.java +++ b/Mage.Sets/src/mage/cards/l/LeaveChance.java @@ -1,39 +1,41 @@ - package mage.cards.l; -import java.util.UUID; import mage.abilities.Ability; import mage.abilities.effects.OneShotEffect; import mage.abilities.effects.common.ReturnToHandTargetEffect; import mage.abilities.keyword.AftermathAbility; -import mage.cards.Card; import mage.cards.CardSetInfo; -import mage.cards.Cards; +import mage.cards.CardsImpl; import mage.cards.SplitCard; import mage.constants.CardType; import mage.constants.Outcome; import mage.constants.SpellAbilityType; import mage.constants.TargetController; -import mage.filter.FilterCard; import mage.filter.FilterPermanent; +import mage.filter.StaticFilters; import mage.game.Game; import mage.players.Player; import mage.target.TargetCard; import mage.target.TargetPermanent; -import mage.target.common.TargetCardInHand; +import mage.target.common.TargetDiscard; + +import java.util.UUID; /** - * * @author LevelX2 */ public final class LeaveChance extends SplitCard { + private static final FilterPermanent filter = new FilterPermanent("permanents you own"); + + static { + filter.add(TargetController.YOU.getOwnerPredicate()); + } + public LeaveChance(UUID ownerId, CardSetInfo setInfo) { super(ownerId, setInfo, new CardType[]{CardType.INSTANT}, new CardType[]{CardType.SORCERY}, "{1}{W}", "{3}{R}", SpellAbilityType.SPLIT_AFTERMATH); // Return any number of target permanents you own to your hand. - FilterPermanent filter = new FilterPermanent("permanents you own"); - filter.add(TargetController.YOU.getOwnerPredicate()); getLeftHalfCard().getSpellAbility().addEffect(new ReturnToHandTargetEffect()); getLeftHalfCard().getSpellAbility().addTarget(new TargetPermanent(0, Integer.MAX_VALUE, filter, false)); @@ -41,12 +43,12 @@ public final class LeaveChance extends SplitCard { // Sorcery // Aftermath getRightHalfCard().addAbility(new AftermathAbility().setRuleAtTheTop(true)); + // Discard any number of cards, then draw that many cards. getRightHalfCard().getSpellAbility().addEffect(new ChanceEffect()); - } - public LeaveChance(final LeaveChance card) { + private LeaveChance(final LeaveChance card) { super(card); } @@ -63,7 +65,7 @@ class ChanceEffect extends OneShotEffect { this.staticText = "Discard any number of cards, then draw that many cards"; } - ChanceEffect(final ChanceEffect effect) { + private ChanceEffect(final ChanceEffect effect) { super(effect); } @@ -75,22 +77,13 @@ class ChanceEffect extends OneShotEffect { @Override public boolean apply(Game game, Ability source) { Player controller = game.getPlayer(source.getControllerId()); - if (controller != null) { - Cards cardsInHand = controller.getHand().copy(); - TargetCard target = new TargetCardInHand(0, cardsInHand.size(), new FilterCard()); - controller.chooseTarget(outcome, cardsInHand, target, source, game); - if (!target.getTargets().isEmpty()) { - for (UUID cardId : target.getTargets()) { - Card card = game.getCard(cardId); - if (card != null) { - controller.discard(card, source, game); - } - } - game.applyEffects(); - controller.drawCards(target.getTargets().size(), source.getSourceId(), game); - } - return true; + if (controller == null) { + return false; } - return false; + TargetCard target = new TargetDiscard(0, controller.getHand().size(), StaticFilters.FILTER_CARD_CARDS, controller.getId()); + controller.chooseTarget(outcome, controller.getHand(), target, source, game); + int amount = controller.discard(new CardsImpl(target.getTargets()), source, game).size(); + controller.drawCards(amount, source.getSourceId(), game); + return true; } } diff --git a/Mage.Sets/src/mage/cards/m/MagusOfTheBalance.java b/Mage.Sets/src/mage/cards/m/MagusOfTheBalance.java index b5b386a5598..bea16480291 100644 --- a/Mage.Sets/src/mage/cards/m/MagusOfTheBalance.java +++ b/Mage.Sets/src/mage/cards/m/MagusOfTheBalance.java @@ -6,22 +6,12 @@ import mage.abilities.common.SimpleActivatedAbility; import mage.abilities.costs.common.SacrificeSourceCost; import mage.abilities.costs.common.TapSourceCost; import mage.abilities.costs.mana.ManaCostsImpl; -import mage.abilities.effects.OneShotEffect; -import mage.cards.*; +import mage.abilities.effects.common.BalanceEffect; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; import mage.constants.CardType; -import mage.constants.Outcome; import mage.constants.SubType; -import mage.filter.FilterCard; -import mage.filter.common.FilterControlledCreaturePermanent; -import mage.filter.common.FilterControlledLandPermanent; -import mage.game.Game; -import mage.game.permanent.Permanent; -import mage.players.Player; -import mage.target.common.TargetCardInHand; -import mage.target.common.TargetControlledPermanent; -import java.util.HashMap; -import java.util.Map; import java.util.UUID; /** @@ -39,7 +29,7 @@ public final class MagusOfTheBalance extends CardImpl { // {4}{W}, {T}, Sacrifice Magus of the Balance: Each player chooses a number of lands they control equal to the number of lands controlled by the player who controls the fewest, then sacrifices the rest. Players discard cards and sacrifice creatures the same way. Ability ability = new SimpleActivatedAbility( - new MagusOfTheBalanceEffect(), + new BalanceEffect(), new ManaCostsImpl("{4}{W}") ); ability.addCost(new TapSourceCost()); @@ -47,7 +37,7 @@ public final class MagusOfTheBalance extends CardImpl { this.addAbility(ability); } - public MagusOfTheBalance(final MagusOfTheBalance card) { + private MagusOfTheBalance(final MagusOfTheBalance card) { super(card); } @@ -56,139 +46,3 @@ public final class MagusOfTheBalance extends CardImpl { return new MagusOfTheBalance(this); } } - -class MagusOfTheBalanceEffect extends OneShotEffect { - - MagusOfTheBalanceEffect() { - super(Outcome.Sacrifice); - staticText = "each player chooses a number of lands they control " - + "equal to the number of lands controlled by the player " - + "who controls the fewest, then sacrifices the rest. " - + "Players discard cards and sacrifice creatures the same way"; - } - - MagusOfTheBalanceEffect(final MagusOfTheBalanceEffect effect) { - super(effect); - } - - @Override - public MagusOfTheBalanceEffect copy() { - return new MagusOfTheBalanceEffect(this); - } - - @Override - public boolean apply(Game game, Ability source) { - Player controller = game.getPlayer(source.getControllerId()); - if (controller != null) { - //Lands - int minLand = Integer.MAX_VALUE; - Cards landsToSacrifice = new CardsImpl(); - for (UUID playerId : game.getState().getPlayersInRange(controller.getId(), game)) { - Player player = game.getPlayer(playerId); - if (player != null) { - int count = game.getBattlefield().countAll(new FilterControlledLandPermanent(), player.getId(), game); - if (count < minLand) { - minLand = count; - } - } - } - - for (UUID playerId : game.getState().getPlayersInRange(controller.getId(), game)) { - Player player = game.getPlayer(playerId); - if (player != null) { - TargetControlledPermanent target = new TargetControlledPermanent(minLand, minLand, new FilterControlledLandPermanent("lands to keep"), true); - if (target.choose(Outcome.Sacrifice, player.getId(), source.getSourceId(), game)) { - for (Permanent permanent : game.getBattlefield().getActivePermanents(new FilterControlledLandPermanent(), player.getId(), source.getSourceId(), game)) { - if (permanent != null && !target.getTargets().contains(permanent.getId())) { - landsToSacrifice.add(permanent); - } - } - } - } - } - - for (UUID cardId : landsToSacrifice) { - Permanent permanent = game.getPermanent(cardId); - if (permanent != null) { - permanent.sacrifice(source.getSourceId(), game); - } - } - - //Creatures - int minCreature = Integer.MAX_VALUE; - Cards creaturesToSacrifice = new CardsImpl(); - for (UUID playerId : game.getState().getPlayersInRange(controller.getId(), game)) { - Player player = game.getPlayer(playerId); - if (player != null) { - int count = game.getBattlefield().countAll(new FilterControlledCreaturePermanent(), player.getId(), game); - if (count < minCreature) { - minCreature = count; - } - } - } - - for (UUID playerId : game.getState().getPlayersInRange(controller.getId(), game)) { - Player player = game.getPlayer(playerId); - if (player != null) { - TargetControlledPermanent target = new TargetControlledPermanent(minCreature, minCreature, new FilterControlledCreaturePermanent("creatures to keep"), true); - if (target.choose(Outcome.Sacrifice, player.getId(), source.getSourceId(), game)) { - for (Permanent permanent : game.getBattlefield().getActivePermanents(new FilterControlledCreaturePermanent(), player.getId(), source.getSourceId(), game)) { - if (permanent != null && !target.getTargets().contains(permanent.getId())) { - creaturesToSacrifice.add(permanent); - } - } - } - } - } - - for (UUID cardId : creaturesToSacrifice) { - Permanent permanent = game.getPermanent(cardId); - if (permanent != null) { - permanent.sacrifice(source.getSourceId(), game); - } - } - - //Cards in hand - int minCard = Integer.MAX_VALUE; - Map cardsToDiscard = new HashMap<>(2); - for (UUID playerId : game.getState().getPlayersInRange(controller.getId(), game)) { - Player player = game.getPlayer(playerId); - if (player != null) { - int count = player.getHand().size(); - if (count < minCard) { - minCard = count; - } - } - } - - for (UUID playerId : game.getState().getPlayersInRange(controller.getId(), game)) { - Player player = game.getPlayer(playerId); - if (player != null) { - Cards cards = new CardsImpl(); - TargetCardInHand target = new TargetCardInHand(minCard, new FilterCard("cards to keep")); - if (target.choose(Outcome.Discard, player.getId(), source.getSourceId(), game)) { - for (Card card : player.getHand().getCards(game)) { - if (card != null && !target.getTargets().contains(card.getId())) { - cards.add(card); - } - } - cardsToDiscard.put(playerId, cards); - } - } - } - - for (UUID playerId : game.getState().getPlayersInRange(controller.getId(), game)) { - Player player = game.getPlayer(playerId); - if (player != null && cardsToDiscard.get(playerId) != null) { - for (UUID cardId : cardsToDiscard.get(playerId)) { - Card card = game.getCard(cardId); - player.discard(card, source, game); - - } - } - } - return true; - } - return false; - } -} diff --git a/Mage.Sets/src/mage/cards/m/MinamosMeddling.java b/Mage.Sets/src/mage/cards/m/MinamosMeddling.java index bed01234fde..11887b5046f 100644 --- a/Mage.Sets/src/mage/cards/m/MinamosMeddling.java +++ b/Mage.Sets/src/mage/cards/m/MinamosMeddling.java @@ -1,7 +1,5 @@ - package mage.cards.m; -import java.util.UUID; import mage.MageObject; import mage.abilities.Ability; import mage.abilities.SpellAbility; @@ -10,29 +8,27 @@ import mage.cards.*; import mage.constants.CardType; import mage.constants.Outcome; import mage.constants.SpellAbilityType; -import mage.filter.StaticFilters; import mage.game.Game; import mage.game.stack.Spell; import mage.players.Player; import mage.target.TargetSpell; +import java.util.UUID; /** - * * @author LevelX2 */ public final class MinamosMeddling extends CardImpl { public MinamosMeddling(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.INSTANT},"{2}{U}{U}"); - + super(ownerId, setInfo, new CardType[]{CardType.INSTANT}, "{2}{U}{U}"); // Counter target spell. That spell's controller reveals their hand, then discards each card with the same name as a card spliced onto that spell. - this.getSpellAbility().addTarget(new TargetSpell(StaticFilters.FILTER_SPELL)); this.getSpellAbility().addEffect(new MinamosMeddlingCounterTargetEffect()); + this.getSpellAbility().addTarget(new TargetSpell()); } - public MinamosMeddling(final MinamosMeddling card) { + private MinamosMeddling(final MinamosMeddling card) { super(card); } @@ -44,12 +40,12 @@ public final class MinamosMeddling extends CardImpl { class MinamosMeddlingCounterTargetEffect extends OneShotEffect { - public MinamosMeddlingCounterTargetEffect() { + MinamosMeddlingCounterTargetEffect() { super(Outcome.Benefit); staticText = "Counter target spell. That spell's controller reveals their hand, then discards each card with the same name as a card spliced onto that spell"; } - public MinamosMeddlingCounterTargetEffect(final MinamosMeddlingCounterTargetEffect effect) { + private MinamosMeddlingCounterTargetEffect(final MinamosMeddlingCounterTargetEffect effect) { super(effect); } @@ -61,36 +57,34 @@ class MinamosMeddlingCounterTargetEffect extends OneShotEffect { @Override public boolean apply(Game game, Ability source) { MageObject sourceObject = game.getObject(source.getSourceId()); - if (sourceObject != null) { - for (UUID targetId : getTargetPointer().getTargets(game, source) ) { - Spell spell = game.getStack().getSpell(targetId); - if (spell != null) { - game.getStack().counter(targetId, source.getSourceId(), game); - Player spellController = game.getPlayer(spell.getControllerId()); - if (spellController != null) { - spellController.revealCards(sourceObject.getName(), spellController.getHand(), game); - Cards cardsToDiscard = new CardsImpl(); - for (SpellAbility spellAbility : spell.getSpellAbilities()) { - if (spellAbility.getSpellAbilityType() == SpellAbilityType.SPLICE) { - for (Card card: spellController.getHand().getCards(game)) { - if (card.getName().equals(spellAbility.getCardName())) { - cardsToDiscard.add(card); - } - } - } - } - if (!cardsToDiscard.isEmpty()) { - for (Card card :cardsToDiscard.getCards(game)) { - spellController.discard(card, source, game); - } + if (sourceObject == null) { + return false; + } + for (UUID targetId : getTargetPointer().getTargets(game, source)) { + Spell spell = game.getStack().getSpell(targetId); + if (spell == null) { + continue; + } + game.getStack().counter(targetId, source.getSourceId(), game); + Player spellController = game.getPlayer(spell.getControllerId()); + if (spellController == null) { + continue; + } + spellController.revealCards(sourceObject.getName(), spellController.getHand(), game); + Cards cardsToDiscard = new CardsImpl(); + for (SpellAbility spellAbility : spell.getSpellAbilities()) { + if (spellAbility.getSpellAbilityType() == SpellAbilityType.SPLICE) { + for (Card card : spellController.getHand().getCards(game)) { + if (card.getName().equals(spellAbility.getCardName())) { + cardsToDiscard.add(card); } } - } } - return true; + if (!cardsToDiscard.isEmpty()) { + spellController.discard(cardsToDiscard, source, game); + } } - return false; + return true; } - } diff --git a/Mage.Sets/src/mage/cards/m/MindBomb.java b/Mage.Sets/src/mage/cards/m/MindBomb.java index 16074428a2e..4fa1119c70c 100644 --- a/Mage.Sets/src/mage/cards/m/MindBomb.java +++ b/Mage.Sets/src/mage/cards/m/MindBomb.java @@ -3,7 +3,10 @@ package mage.cards.m; import mage.MageObject; import mage.abilities.Ability; import mage.abilities.effects.OneShotEffect; -import mage.cards.*; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.cards.Cards; +import mage.cards.CardsImpl; import mage.constants.CardType; import mage.constants.Outcome; import mage.filter.FilterCard; @@ -28,7 +31,7 @@ public final class MindBomb extends CardImpl { this.getSpellAbility().addEffect(new MindBombEffect()); } - public MindBomb(final MindBomb card) { + private MindBomb(final MindBomb card) { super(card); } @@ -40,13 +43,13 @@ public final class MindBomb extends CardImpl { class MindBombEffect extends OneShotEffect { - public MindBombEffect() { + MindBombEffect() { super(Outcome.Neutral); this.staticText = "Each player may discard up to three cards." + " {this} deals damage to each player equal to 3 minus the number of cards they discarded this way"; } - public MindBombEffect(final MindBombEffect effect) { + private MindBombEffect(final MindBombEffect effect) { super(effect); } @@ -59,48 +62,44 @@ class MindBombEffect extends OneShotEffect { public boolean apply(Game game, Ability source) { Player controller = game.getPlayer(source.getControllerId()); MageObject sourceObject = source.getSourceObject(game); - if (controller != null && sourceObject != null) { - Map cardsToDiscard = new HashMap<>(); - - // choose - for (UUID playerId : game.getState().getPlayersInRange(controller.getId(), game)) { - Player player = game.getPlayer(playerId); - if (player != null) { - Cards cards = new CardsImpl(); - Target target = new TargetDiscard(0, 3, new FilterCard(), playerId); - player.chooseTarget(outcome, target, source, game); - cards.addAll(target.getTargets()); - cardsToDiscard.put(playerId, cards); - } - } - - // discard - for (UUID playerId : game.getState().getPlayersInRange(controller.getId(), game)) { - Player player = game.getPlayer(playerId); - if (player != null) { - Cards cardsPlayer = cardsToDiscard.get(playerId); - if (cardsPlayer != null) { - for (UUID cardId : cardsPlayer) { - Card card = game.getCard(cardId); - player.discard(card, source, game); - - } - } - } - } - - // damage - for (UUID playerId : game.getState().getPlayersInRange(controller.getId(), game)) { - Player player = game.getPlayer(playerId); - if (player != null) { - Cards cardsPlayer = cardsToDiscard.get(playerId); - if (cardsPlayer != null) { - player.damage(3 - cardsPlayer.size(), source.getId(), game); - } - } - } - return true; + if (controller == null || sourceObject == null) { + return false; } - return false; + Map cardsToDiscard = new HashMap<>(); + + // choose + for (UUID playerId : game.getState().getPlayersInRange(controller.getId(), game)) { + Player player = game.getPlayer(playerId); + if (player == null) { + continue; + } + Cards cards = new CardsImpl(); + Target target = new TargetDiscard(0, 3, new FilterCard(), playerId); + player.chooseTarget(Outcome.Discard, target, source, game); + cards.addAll(target.getTargets()); + cardsToDiscard.put(playerId, cards); + } + + // discard + for (UUID playerId : game.getState().getPlayersInRange(controller.getId(), game)) { + Player player = game.getPlayer(playerId); + if (player != null) { + Cards cardsPlayer = cardsToDiscard.get(playerId); + cardsToDiscard.put(playerId, player.discard(cardsPlayer, source, game)); + } + } + + // damage + for (UUID playerId : game.getState().getPlayersInRange(controller.getId(), game)) { + Player player = game.getPlayer(playerId); + if (player == null) { + continue; + } + Cards cardsPlayer = cardsToDiscard.get(playerId); + if (cardsPlayer != null) { + player.damage(3 - cardsPlayer.size(), source.getId(), game); + } + } + return true; } } diff --git a/Mage.Sets/src/mage/cards/m/MindExtraction.java b/Mage.Sets/src/mage/cards/m/MindExtraction.java index 485c0fa3808..7a377321463 100644 --- a/Mage.Sets/src/mage/cards/m/MindExtraction.java +++ b/Mage.Sets/src/mage/cards/m/MindExtraction.java @@ -99,9 +99,7 @@ class MindExtractionEffect extends OneShotEffect { .stream() .filter(card -> card.getColor(game).shares(color)) .forEach(toDiscard::add); - toDiscard.getCards(game) - .stream() - .forEach(card -> player.discard(card, source, game)); + player.discard(toDiscard, source, game); return true; } } \ No newline at end of file diff --git a/Mage.Sets/src/mage/cards/m/MindMaggots.java b/Mage.Sets/src/mage/cards/m/MindMaggots.java index e98e414ce8b..c68088cb883 100644 --- a/Mage.Sets/src/mage/cards/m/MindMaggots.java +++ b/Mage.Sets/src/mage/cards/m/MindMaggots.java @@ -1,25 +1,26 @@ package mage.cards.m; -import java.util.UUID; import mage.MageInt; import mage.abilities.Ability; import mage.abilities.common.EntersBattlefieldTriggeredAbility; import mage.abilities.effects.OneShotEffect; -import mage.abilities.effects.common.counter.AddCountersSourceEffect; -import mage.cards.Card; -import mage.constants.SubType; import mage.cards.CardImpl; import mage.cards.CardSetInfo; +import mage.cards.CardsImpl; import mage.constants.CardType; import mage.constants.Outcome; +import mage.constants.SubType; import mage.counters.CounterType; import mage.filter.StaticFilters; import mage.game.Game; +import mage.game.permanent.Permanent; import mage.players.Player; -import mage.target.common.TargetCardInHand; +import mage.target.TargetCard; +import mage.target.common.TargetDiscard; + +import java.util.UUID; /** - * * @author jeffwadsworth */ public final class MindMaggots extends CardImpl { @@ -34,10 +35,9 @@ public final class MindMaggots extends CardImpl { // When Mind Maggots enters the battlefield, discard any number of creature cards. // For each card discarded this way, put two +1/+1 counters on Mind Maggots. this.addAbility(new EntersBattlefieldTriggeredAbility(new MindMaggotsEffect())); - } - public MindMaggots(final MindMaggots card) { + private MindMaggots(final MindMaggots card) { super(card); } @@ -51,10 +51,11 @@ class MindMaggotsEffect extends OneShotEffect { MindMaggotsEffect() { super(Outcome.BoostCreature); - this.staticText = "discard any number of creature cards. For each card discarded this way, put two +1/+1 counters on {this}"; + this.staticText = "discard any number of creature cards. " + + "For each card discarded this way, put two +1/+1 counters on {this}"; } - MindMaggotsEffect(final MindMaggotsEffect effect) { + private MindMaggotsEffect(final MindMaggotsEffect effect) { super(effect); } @@ -66,23 +67,17 @@ class MindMaggotsEffect extends OneShotEffect { @Override public boolean apply(Game game, Ability source) { Player controller = game.getPlayer(source.getControllerId()); - if (controller != null) { - int numToDiscard = controller.getAmount(0, - controller.getHand().getCards(StaticFilters.FILTER_CARD_CREATURE, game).size(), - "Discard how many creature cards?", - game); - TargetCardInHand target = new TargetCardInHand(numToDiscard, StaticFilters.FILTER_CARD_CREATURE); - if (controller.choose(Outcome.Benefit, target, source.getSourceId(), game)) { - for (UUID targetId : target.getTargets()) { - Card card = game.getCard(targetId); - if (card != null - && controller.discard(card, source, game)) { - new AddCountersSourceEffect(CounterType.P1P1.createInstance(2)).apply(game, source); - } - } - } + if (controller == null) { + return false; + } + TargetCard target = new TargetDiscard(0, Integer.MAX_VALUE, StaticFilters.FILTER_CARD_CREATURE, controller.getId()); + controller.choose(outcome, controller.getHand(), target, game); + int counters = controller.discard(new CardsImpl(target.getTargets()), source, game).size(); + Permanent permanent = game.getPermanent(source.getSourceId()); + if (permanent == null || counters < 1) { return true; } - return false; + permanent.addCounters(CounterType.P1P1.createInstance(counters), source, game); + return true; } } diff --git a/Mage.Sets/src/mage/cards/m/MindWarp.java b/Mage.Sets/src/mage/cards/m/MindWarp.java index afef657aebd..c7fd19c8580 100644 --- a/Mage.Sets/src/mage/cards/m/MindWarp.java +++ b/Mage.Sets/src/mage/cards/m/MindWarp.java @@ -1,21 +1,18 @@ - package mage.cards.m; import mage.abilities.Ability; -import mage.abilities.dynamicvalue.DynamicValue; -import mage.abilities.dynamicvalue.common.ManacostVariableValue; import mage.abilities.effects.OneShotEffect; -import mage.cards.Card; import mage.cards.CardImpl; import mage.cards.CardSetInfo; +import mage.cards.CardsImpl; import mage.constants.CardType; import mage.constants.Outcome; -import mage.constants.Zone; -import mage.filter.FilterCard; +import mage.filter.StaticFilters; import mage.game.Game; import mage.players.Player; import mage.target.TargetCard; import mage.target.TargetPlayer; +import mage.target.common.TargetCardInHand; import java.util.UUID; @@ -28,11 +25,11 @@ public final class MindWarp extends CardImpl { super(ownerId, setInfo, new CardType[]{CardType.SORCERY}, "{X}{3}{B}"); // Look at target player's hand and choose X cards from it. That player discards those cards. - this.getSpellAbility().addEffect(new MindWarpEffect(ManacostVariableValue.instance)); + this.getSpellAbility().addEffect(new MindWarpEffect()); this.getSpellAbility().addTarget(new TargetPlayer()); } - public MindWarp(final MindWarp card) { + private MindWarp(final MindWarp card) { super(card); } @@ -44,39 +41,27 @@ public final class MindWarp extends CardImpl { class MindWarpEffect extends OneShotEffect { - private final DynamicValue xValue; - - public MindWarpEffect(DynamicValue xValue) { + MindWarpEffect() { super(Outcome.Discard); - this.xValue = xValue; staticText = "Look at target player's hand and choose X cards from it. That player discards those card."; } - public MindWarpEffect(final MindWarpEffect effect) { + private MindWarpEffect(final MindWarpEffect effect) { super(effect); - this.xValue = effect.xValue; } @Override public boolean apply(Game game, Ability source) { Player targetPlayer = game.getPlayer(source.getFirstTarget()); Player you = game.getPlayer(source.getControllerId()); - if (targetPlayer != null && you != null) { - int amountToDiscard = Math.min( - xValue.calculate(game, source, this), - targetPlayer.getHand().size() - ); - you.lookAtCards("Discard", targetPlayer.getHand(), game); - TargetCard target = new TargetCard(amountToDiscard, Zone.HAND, new FilterCard()); - target.setNotTarget(true); - if (you.choose(Outcome.Benefit, targetPlayer.getHand(), target, game)) { - Card card = targetPlayer.getHand().get(target.getFirstTarget(), game); - return targetPlayer.discard(card, source, game); - - } - + if (targetPlayer == null || you == null) { + return false; } - return false; + int amountToDiscard = source.getManaCostsToPay().getX(); + TargetCard target = new TargetCardInHand(amountToDiscard, StaticFilters.FILTER_CARD_CARDS); + you.choose(outcome, targetPlayer.getHand(), target, game); + targetPlayer.discard(new CardsImpl(target.getTargets()), source, game); + return true; } @Override diff --git a/Mage.Sets/src/mage/cards/m/Monomania.java b/Mage.Sets/src/mage/cards/m/Monomania.java index 8e27d39857c..86f4ac069ff 100644 --- a/Mage.Sets/src/mage/cards/m/Monomania.java +++ b/Mage.Sets/src/mage/cards/m/Monomania.java @@ -1,37 +1,35 @@ - package mage.cards.m; -import java.util.UUID; import mage.abilities.Ability; import mage.abilities.effects.OneShotEffect; -import mage.cards.Card; import mage.cards.CardImpl; import mage.cards.CardSetInfo; +import mage.cards.Cards; import mage.constants.CardType; import mage.constants.Outcome; -import mage.constants.Zone; import mage.filter.FilterCard; import mage.game.Game; import mage.players.Player; import mage.target.TargetCard; import mage.target.TargetPlayer; +import mage.target.common.TargetDiscard; + +import java.util.UUID; /** - * * @author nantuko */ public final class Monomania extends CardImpl { public Monomania(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.SORCERY},"{3}{B}{B}"); - + super(ownerId, setInfo, new CardType[]{CardType.SORCERY}, "{3}{B}{B}"); // Target player chooses a card in their hand and discards the rest. this.getSpellAbility().addEffect(new MonomaniaEffect()); this.getSpellAbility().addTarget(new TargetPlayer()); } - public Monomania(final Monomania card) { + private Monomania(final Monomania card) { super(card); } @@ -45,41 +43,30 @@ class MonomaniaEffect extends OneShotEffect { private static final FilterCard filter = new FilterCard("a card"); - public MonomaniaEffect() { + MonomaniaEffect() { super(Outcome.Discard); staticText = "Target player chooses a card in their hand and discards the rest"; } - public MonomaniaEffect(final MonomaniaEffect effect) { + private MonomaniaEffect(final MonomaniaEffect effect) { super(effect); } @Override public boolean apply(Game game, Ability source) { Player player = game.getPlayer(source.getFirstTarget()); - if (player != null) { - TargetCard target = new TargetCard(Zone.HAND, filter); - if (player.choose(Outcome.Detriment, player.getHand(), target, game)) { - while (player.getHand().size() > 1) { - for (UUID uuid : player.getHand()) { - if (!uuid.equals(target.getFirstTarget())) { - Card card = player.getHand().get(uuid, game); - if (card != null) { - player.discard(card, source, game); - break; - } - } - } - } - return true; - } + if (player == null || player.getHand().isEmpty()) { + return false; } - return false; + TargetCard target = new TargetDiscard(player.getId()); + player.choose(Outcome.Benefit, player.getHand(), target, game); + Cards cards = player.getHand().copy(); + cards.removeIf(target.getTargets()::contains); + return !player.discard(cards, source, game).isEmpty(); } @Override public MonomaniaEffect copy() { return new MonomaniaEffect(this); } - } diff --git a/Mage.Sets/src/mage/cards/m/MyojinOfNightsReach.java b/Mage.Sets/src/mage/cards/m/MyojinOfNightsReach.java index 9f6f424fd3c..559c409e512 100644 --- a/Mage.Sets/src/mage/cards/m/MyojinOfNightsReach.java +++ b/Mage.Sets/src/mage/cards/m/MyojinOfNightsReach.java @@ -1,7 +1,5 @@ - package mage.cards.m; -import java.util.UUID; import mage.MageInt; import mage.abilities.Ability; import mage.abilities.common.EntersBattlefieldAbility; @@ -16,7 +14,6 @@ import mage.abilities.effects.OneShotEffect; import mage.abilities.effects.common.continuous.GainAbilitySourceEffect; import mage.abilities.effects.common.counter.AddCountersSourceEffect; import mage.abilities.keyword.IndestructibleAbility; -import mage.cards.Card; import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.constants.*; @@ -25,13 +22,15 @@ import mage.game.Game; import mage.players.Player; import mage.watchers.common.CastFromHandWatcher; +import java.util.UUID; + /** * @author LevelX */ public final class MyojinOfNightsReach extends CardImpl { public MyojinOfNightsReach(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{5}{B}{B}{B}"); + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{5}{B}{B}{B}"); addSuperType(SuperType.LEGENDARY); this.subtype.add(SubType.SPIRIT); @@ -50,7 +49,7 @@ public final class MyojinOfNightsReach extends CardImpl { this.addAbility(ability); } - public MyojinOfNightsReach(final MyojinOfNightsReach card) { + private MyojinOfNightsReach(final MyojinOfNightsReach card) { super(card); } @@ -61,12 +60,13 @@ public final class MyojinOfNightsReach extends CardImpl { } class MyojinOfNightsReachEffect extends OneShotEffect { - public MyojinOfNightsReachEffect() { + + MyojinOfNightsReachEffect() { super(Outcome.Discard); staticText = "Each opponent discards their hand"; } - public MyojinOfNightsReachEffect(final MyojinOfNightsReachEffect effect) { + private MyojinOfNightsReachEffect(final MyojinOfNightsReachEffect effect) { super(effect); } @@ -74,10 +74,8 @@ class MyojinOfNightsReachEffect extends OneShotEffect { public boolean apply(Game game, Ability source) { for (UUID opponentId : game.getOpponents(source.getControllerId())) { Player opponent = game.getPlayer(opponentId); - if(opponent != null) { - for (Card c : opponent.getHand().getCards(game)) { - opponent.discard(c, source, game); - } + if (opponent != null) { + opponent.discard(opponent.getHand(), source, game); } } return true; @@ -87,5 +85,4 @@ class MyojinOfNightsReachEffect extends OneShotEffect { public MyojinOfNightsReachEffect copy() { return new MyojinOfNightsReachEffect(this); } - } diff --git a/Mage.Sets/src/mage/cards/n/NantukoCultivator.java b/Mage.Sets/src/mage/cards/n/NantukoCultivator.java index f284e81d74a..1372acb7b24 100644 --- a/Mage.Sets/src/mage/cards/n/NantukoCultivator.java +++ b/Mage.Sets/src/mage/cards/n/NantukoCultivator.java @@ -1,42 +1,41 @@ - package mage.cards.n; -import java.util.UUID; import mage.MageInt; import mage.abilities.Ability; import mage.abilities.common.EntersBattlefieldTriggeredAbility; import mage.abilities.effects.OneShotEffect; import mage.cards.CardImpl; import mage.cards.CardSetInfo; +import mage.cards.CardsImpl; import mage.constants.CardType; -import mage.constants.SubType; import mage.constants.Outcome; +import mage.constants.SubType; import mage.counters.CounterType; -import mage.filter.common.FilterLandCard; +import mage.filter.StaticFilters; import mage.game.Game; import mage.game.permanent.Permanent; import mage.players.Player; import mage.target.common.TargetCardInHand; -/** - * - * @author LoneFox +import java.util.UUID; +/** + * @author LoneFox */ public final class NantukoCultivator extends CardImpl { public NantukoCultivator(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{3}{G}"); + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{3}{G}"); this.subtype.add(SubType.INSECT); this.subtype.add(SubType.DRUID); this.power = new MageInt(2); this.toughness = new MageInt(2); // When Nantuko Cultivator enters the battlefield, you may discard any number of land cards. Put that many +1/+1 counters on Nantuko Cultivator and draw that many cards. - this.addAbility(new EntersBattlefieldTriggeredAbility(new NantukoCultivatorEffect(), true)); + this.addAbility(new EntersBattlefieldTriggeredAbility(new NantukoCultivatorEffect())); } - public NantukoCultivator(final NantukoCultivator card) { + private NantukoCultivator(final NantukoCultivator card) { super(card); } @@ -48,40 +47,38 @@ public final class NantukoCultivator extends CardImpl { class NantukoCultivatorEffect extends OneShotEffect { - public NantukoCultivatorEffect() { + NantukoCultivatorEffect() { super(Outcome.BoostCreature); - staticText = "you may discard any number of land cards. Put that many +1/+1 counters on {this} and draw that many cards."; + staticText = "you may discard any number of land cards. " + + "Put that many +1/+1 counters on {this} and draw that many cards."; + } + + private NantukoCultivatorEffect(final NantukoCultivatorEffect effect) { + super(effect); } @Override public boolean apply(Game game, Ability source) { Player player = game.getPlayer(source.getControllerId()); - if(player != null) { - TargetCardInHand toDiscard = new TargetCardInHand(0, Integer.MAX_VALUE, new FilterLandCard()); - if(player.chooseTarget(Outcome.Discard, toDiscard, source, game)) { - int count = 0; - for(UUID targetId: toDiscard.getTargets()) { - player.discard(game.getCard(targetId), source, game); - count++; - } - Permanent permanent = game.getPermanent(source.getSourceId()); - if(permanent != null) { - permanent.addCounters(CounterType.P1P1.createInstance(count), source, game); - } - player.drawCards(count, source.getSourceId(), game); - } - return true; + if (player == null || player.getHand().count(StaticFilters.FILTER_CARD_LAND, game) < 1) { + return false; } - return false; - } - - public NantukoCultivatorEffect(final NantukoCultivatorEffect effect) { - super(effect); + TargetCardInHand toDiscard = new TargetCardInHand(0, Integer.MAX_VALUE, StaticFilters.FILTER_CARD_LAND); + player.chooseTarget(Outcome.AIDontUseIt, toDiscard, source, game); + int count = player.discard(new CardsImpl(toDiscard.getTargets()), source, game).size(); + if (count < 1) { + return false; + } + Permanent permanent = game.getPermanent(source.getSourceId()); + if (permanent != null) { + permanent.addCounters(CounterType.P1P1.createInstance(count), source, game); + } + player.drawCards(count, source.getSourceId(), game); + return true; } @Override public NantukoCultivatorEffect copy() { return new NantukoCultivatorEffect(this); } - } diff --git a/Mage.Sets/src/mage/cards/n/Nebuchadnezzar.java b/Mage.Sets/src/mage/cards/n/Nebuchadnezzar.java index e1ba7288f1c..7eee5eec448 100644 --- a/Mage.Sets/src/mage/cards/n/Nebuchadnezzar.java +++ b/Mage.Sets/src/mage/cards/n/Nebuchadnezzar.java @@ -66,30 +66,28 @@ class NebuchadnezzarEffect extends OneShotEffect { Player opponent = game.getPlayer(targetPointer.getFirst(game, source)); MageObject sourceObject = game.getObject(source.getSourceId()); String cardName = (String) game.getState().getValue(source.getSourceId().toString() + ChooseACardNameEffect.INFO_KEY); - if (opponent != null && sourceObject != null && !cardName.isEmpty()) { - int costX = source.getManaCostsToPay().getX(); - if (costX > 0 && !opponent.getHand().isEmpty()) { - Cards cards = new CardsImpl(); - while (costX > 0) { - Card card = opponent.getHand().getRandom(game); - if (!cards.contains(card.getId())) { - cards.add(card); - costX--; - } - if (opponent.getHand().size() <= cards.size()) { - break; - } - } - opponent.revealCards(sourceObject.getIdName(), cards, game); - for (Card cardToDiscard : cards.getCards(game)) { - if (cardToDiscard.getName().equals(cardName)) { - opponent.discard(cardToDiscard, source, game); - } - } - } + if (opponent == null || sourceObject == null || cardName.isEmpty()) { + return false; + } + int costX = source.getManaCostsToPay().getX(); + if (costX <= 0 || opponent.getHand().isEmpty()) { return true; } - return false; + Cards cards = new CardsImpl(); + while (costX > 0) { + Card card = opponent.getHand().getRandom(game); + if (!cards.contains(card.getId())) { + cards.add(card); + costX--; + } + if (opponent.getHand().size() <= cards.size()) { + break; + } + } + opponent.revealCards(sourceObject.getIdName(), cards, game); + cards.removeIf(uuid -> !cardName.equals(game.getCard(uuid).getName())); + opponent.discard(cards, source, game); + return true; } @Override diff --git a/Mage.Sets/src/mage/cards/n/NehebDreadhordeChampion.java b/Mage.Sets/src/mage/cards/n/NehebDreadhordeChampion.java index 338608ef223..535dcff7a90 100644 --- a/Mage.Sets/src/mage/cards/n/NehebDreadhordeChampion.java +++ b/Mage.Sets/src/mage/cards/n/NehebDreadhordeChampion.java @@ -6,7 +6,9 @@ import mage.abilities.Ability; import mage.abilities.common.DealsCombatDamageToAPlayerTriggeredAbility; import mage.abilities.effects.OneShotEffect; import mage.abilities.keyword.TrampleAbility; -import mage.cards.*; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.cards.CardsImpl; import mage.constants.CardType; import mage.constants.Outcome; import mage.constants.SubType; @@ -18,6 +20,7 @@ import mage.target.TargetCard; import mage.target.common.TargetCardInHand; import java.util.UUID; +import java.util.stream.IntStream; /** * @author TheElk801 @@ -80,18 +83,12 @@ class NehebDreadhordeChampionEffect extends OneShotEffect { if (!player.choose(outcome, target, source.getSourceId(), game)) { return false; } - Cards cards = new CardsImpl(target.getTargets()); - int counter = 0; + int counter = player.discard(new CardsImpl(target.getTargets()), source, game).size(); Mana mana = new Mana(); - for (Card card : cards.getCards(game)) { - if (player.discard(card, source, game)) { - counter++; - mana.increaseRed(); - } - } - if (counter == 0) { + if (counter < 1) { return true; } + IntStream.range(0, counter).forEach(x -> mana.increaseRed()); player.drawCards(counter, source.getSourceId(), game); player.getManaPool().addMana(mana, game, source, true); return true; diff --git a/Mage.Sets/src/mage/cards/n/Nightsnare.java b/Mage.Sets/src/mage/cards/n/Nightsnare.java index a0326c9f49f..e0535648e96 100644 --- a/Mage.Sets/src/mage/cards/n/Nightsnare.java +++ b/Mage.Sets/src/mage/cards/n/Nightsnare.java @@ -52,32 +52,27 @@ class NightsnareDiscardEffect extends OneShotEffect { public boolean apply(Game game, Ability source) { Player player = game.getPlayer(targetPointer.getFirst(game, source)); Player controller = game.getPlayer(source.getControllerId()); - if (player != null && controller != null) { - if (!player.getHand().isEmpty()) { - Cards revealedCards = new CardsImpl(); - revealedCards.addAll(player.getHand()); - Card sourceCard = game.getCard(source.getSourceId()); - player.revealCards(sourceCard != null ? sourceCard.getIdName() : "Discard", revealedCards, game); - // You may choose a nonland card from it. - if (controller.chooseUse(outcome, "Choose a a card to discard? (Otherwise " + player.getLogName() + " has to discard 2 cards).", source, game)) { - TargetCard target = new TargetCard(1, Zone.HAND, new FilterNonlandCard()); - if (controller.choose(Outcome.Benefit, revealedCards, target, game)) { - for (UUID targetId : target.getTargets()) { - Card card = revealedCards.get(targetId, game); - player.discard(card, source, game); - - } - } - - } else { - player.discard(2, false, source, game); - } - } - return true; - + if (player == null || controller == null) { + return false; } - return false; - + if (player.getHand().isEmpty()) { + return true; + } + Cards revealedCards = new CardsImpl(); + revealedCards.addAll(player.getHand()); + Card sourceCard = game.getCard(source.getSourceId()); + player.revealCards(sourceCard != null ? sourceCard.getIdName() : "Discard", revealedCards, game); + // You may choose a nonland card from it. + if (!controller.chooseUse(outcome, "Choose a card to discard? (Otherwise " + player.getLogName() + " has to discard 2 cards).", source, game)) { + player.discard(2, false, source, game); + return true; + } + TargetCard target = new TargetCard(1, Zone.HAND, new FilterNonlandCard()); + if (controller.choose(Outcome.Benefit, revealedCards, target, game)) { + Card card = revealedCards.get(target.getFirstTarget(), game); + player.discard(card, source, game); + } + return true; } @Override diff --git a/Mage.Sets/src/mage/cards/n/NogginWhack.java b/Mage.Sets/src/mage/cards/n/NogginWhack.java index 5aa88225c42..3eabce33e6d 100644 --- a/Mage.Sets/src/mage/cards/n/NogginWhack.java +++ b/Mage.Sets/src/mage/cards/n/NogginWhack.java @@ -1,19 +1,12 @@ - package mage.cards.n; -import java.util.List; -import java.util.UUID; import mage.abilities.Ability; import mage.abilities.effects.OneShotEffect; import mage.abilities.keyword.ProwlAbility; -import mage.cards.Card; -import mage.cards.CardImpl; -import mage.cards.CardSetInfo; -import mage.cards.Cards; -import mage.cards.CardsImpl; +import mage.cards.*; import mage.constants.CardType; -import mage.constants.SubType; import mage.constants.Outcome; +import mage.constants.SubType; import mage.constants.Zone; import mage.filter.FilterCard; import mage.game.Game; @@ -21,14 +14,16 @@ import mage.players.Player; import mage.target.TargetCard; import mage.target.TargetPlayer; +import java.util.List; +import java.util.UUID; + /** - * * @author LevelX2 */ public final class NogginWhack extends CardImpl { public NogginWhack(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.TRIBAL,CardType.SORCERY},"{2}{B}{B}"); + super(ownerId, setInfo, new CardType[]{CardType.TRIBAL, CardType.SORCERY}, "{2}{B}{B}"); this.subtype.add(SubType.ROGUE); @@ -40,7 +35,7 @@ public final class NogginWhack extends CardImpl { } - public NogginWhack(final NogginWhack card) { + private NogginWhack(final NogginWhack card) { super(card); } @@ -52,12 +47,12 @@ public final class NogginWhack extends CardImpl { class NogginWhackEffect extends OneShotEffect { - public NogginWhackEffect() { + NogginWhackEffect() { super(Outcome.Benefit); this.staticText = "Target player reveals three cards from their hand. You choose two of them. That player discards those cards"; } - public NogginWhackEffect(final NogginWhackEffect effect) { + private NogginWhackEffect(final NogginWhackEffect effect) { super(effect); } @@ -71,40 +66,35 @@ class NogginWhackEffect extends OneShotEffect { Player controller = game.getPlayer(source.getControllerId()); Player targetPlayer = game.getPlayer(source.getFirstTarget()); Card sourceCard = game.getCard(source.getSourceId()); - if (controller != null && targetPlayer != null && sourceCard != null) { - Cards cardsInHand = new CardsImpl(); - cardsInHand.addAll(targetPlayer.getHand()); - - int count = Math.min(cardsInHand.size(), 3); - - TargetCard target = new TargetCard(count, Zone.HAND, new FilterCard()); - Cards revealedCards = new CardsImpl(); - - if (targetPlayer.chooseTarget(Outcome.Discard, cardsInHand, target, source, game)) { - List targets = target.getTargets(); - for (UUID targetId : targets) { - Card card = game.getCard(targetId); - if (card != null) { - revealedCards.add(card); - } - } - } - - int cardsToDiscard = Math.min(revealedCards.size(), 2); - TargetCard targetInHand = new TargetCard(cardsToDiscard, cardsToDiscard, Zone.HAND, new FilterCard("card to discard")); - - if (!revealedCards.isEmpty()) { - targetPlayer.revealCards("Noggin Whack", revealedCards, game); - controller.chooseTarget(Outcome.Exile, revealedCards, targetInHand, source, game); - for (UUID cardId : targetInHand.getTargets()) { - Card card = game.getCard(cardId); - if (card != null) { - controller.discard(card, source, game); - } - } - } - return true; + if (controller == null || targetPlayer == null || sourceCard == null) { + return false; } - return false; + Cards cardsInHand = new CardsImpl(); + cardsInHand.addAll(targetPlayer.getHand()); + + int count = Math.min(cardsInHand.size(), 3); + + TargetCard target = new TargetCard(count, Zone.HAND, new FilterCard()); + Cards revealedCards = new CardsImpl(); + + if (targetPlayer.chooseTarget(Outcome.Discard, cardsInHand, target, source, game)) { + List targets = target.getTargets(); + for (UUID targetId : targets) { + Card card = game.getCard(targetId); + if (card != null) { + revealedCards.add(card); + } + } + } + + int cardsToDiscard = Math.min(revealedCards.size(), 2); + TargetCard targetInHand = new TargetCard(cardsToDiscard, cardsToDiscard, Zone.HAND, new FilterCard("card to discard")); + + if (!revealedCards.isEmpty()) { + targetPlayer.revealCards(source, revealedCards, game); + controller.chooseTarget(Outcome.Exile, revealedCards, targetInHand, source, game); + targetPlayer.discard(new CardsImpl(target.getTargets()), source, game); + } + return true; } } diff --git a/Mage.Sets/src/mage/cards/n/NoxiousVapors.java b/Mage.Sets/src/mage/cards/n/NoxiousVapors.java index 1e67b13521e..e550c4c05ef 100644 --- a/Mage.Sets/src/mage/cards/n/NoxiousVapors.java +++ b/Mage.Sets/src/mage/cards/n/NoxiousVapors.java @@ -1,26 +1,27 @@ - package mage.cards.n; -import java.util.HashSet; -import java.util.Set; -import java.util.UUID; import mage.ObjectColor; import mage.abilities.Ability; import mage.abilities.effects.OneShotEffect; import mage.cards.Card; import mage.cards.CardImpl; import mage.cards.CardSetInfo; +import mage.cards.Cards; import mage.constants.CardType; import mage.constants.Outcome; import mage.filter.FilterCard; +import mage.filter.StaticFilters; import mage.filter.common.FilterNonlandCard; import mage.filter.predicate.mageobject.ColorPredicate; import mage.game.Game; import mage.players.Player; import mage.target.common.TargetCardInHand; +import java.util.HashSet; +import java.util.Set; +import java.util.UUID; + /** - * * @author L_J */ public final class NoxiousVapors extends CardImpl { @@ -30,10 +31,9 @@ public final class NoxiousVapors extends CardImpl { // Each player reveals their hand, chooses one card of each color from it, then discards all other nonland cards. this.getSpellAbility().addEffect(new NoxiousVaporsEffect()); - } - public NoxiousVapors(final NoxiousVapors card) { + private NoxiousVapors(final NoxiousVapors card) { super(card); } @@ -47,12 +47,12 @@ class NoxiousVaporsEffect extends OneShotEffect { private static final FilterNonlandCard filter = new FilterNonlandCard(); - public NoxiousVaporsEffect() { + NoxiousVaporsEffect() { super(Outcome.Benefit); this.staticText = "Each player reveals their hand, chooses one card of each color from it, then discards all other nonland cards"; } - public NoxiousVaporsEffect(final NoxiousVaporsEffect effect) { + private NoxiousVaporsEffect(final NoxiousVaporsEffect effect) { super(effect); } @@ -64,37 +64,35 @@ class NoxiousVaporsEffect extends OneShotEffect { @Override public boolean apply(Game game, Ability source) { Player controller = game.getPlayer(source.getControllerId()); - if (controller != null) { - for (UUID playerId : game.getState().getPlayersInRange(controller.getId(), game)) { - Player player = game.getPlayer(playerId); - if (player != null) { - player.revealCards(player.getName() + "'s hand", player.getHand(), game); - } - } - - for (UUID playerId : game.getState().getPlayersInRange(controller.getId(), game)) { - Player player = game.getPlayer(playerId); - if (player != null) { - Set chosenCards = new HashSet<>(); - chooseCardForColor(ObjectColor.WHITE, chosenCards, player, game, source); - chooseCardForColor(ObjectColor.BLUE, chosenCards, player, game, source); - chooseCardForColor(ObjectColor.BLACK, chosenCards, player, game, source); - chooseCardForColor(ObjectColor.RED, chosenCards, player, game, source); - chooseCardForColor(ObjectColor.GREEN, chosenCards, player, game, source); - - Set cards = player.getHand().getCards(game); - for (Card card : cards) { - if (card != null && !chosenCards.contains(card) && filter.match(card, game)) { - player.discard(card, source, game); - } - } - } - } - return true; + if (controller == null) { + return false; } - return false; + for (UUID playerId : game.getState().getPlayersInRange(controller.getId(), game)) { + Player player = game.getPlayer(playerId); + if (player != null) { + player.revealCards(player.getName() + "'s hand", player.getHand(), game); + } + } + + for (UUID playerId : game.getState().getPlayersInRange(controller.getId(), game)) { + Player player = game.getPlayer(playerId); + if (player == null) { + continue; + } + Set chosenCards = new HashSet<>(); + chooseCardForColor(ObjectColor.WHITE, chosenCards, player, game, source); + chooseCardForColor(ObjectColor.BLUE, chosenCards, player, game, source); + chooseCardForColor(ObjectColor.BLACK, chosenCards, player, game, source); + chooseCardForColor(ObjectColor.RED, chosenCards, player, game, source); + chooseCardForColor(ObjectColor.GREEN, chosenCards, player, game, source); + chosenCards.addAll(player.getHand().getCards(StaticFilters.FILTER_CARD_LAND, game)); + Cards cards = player.getHand().copy(); + cards.removeIf(chosenCards::contains); + player.discard(cards, source, game); + } + return true; } - + private void chooseCardForColor(ObjectColor color, Set chosenCards, Player player, Game game, Ability source) { FilterCard filter = new FilterCard(); filter.add(new ColorPredicate(color)); diff --git a/Mage.Sets/src/mage/cards/r/RareBGone.java b/Mage.Sets/src/mage/cards/r/RareBGone.java index bb97dfceb0c..5440a478f84 100644 --- a/Mage.Sets/src/mage/cards/r/RareBGone.java +++ b/Mage.Sets/src/mage/cards/r/RareBGone.java @@ -2,23 +2,18 @@ package mage.cards.r; import mage.abilities.Ability; import mage.abilities.effects.OneShotEffect; -import mage.cards.Card; -import mage.cards.CardImpl; -import mage.cards.CardSetInfo; -import mage.cards.Cards; +import mage.cards.*; import mage.constants.CardType; import mage.constants.Outcome; import mage.constants.Rarity; import mage.filter.FilterCard; import mage.filter.FilterPermanent; import mage.filter.predicate.Predicate; -import mage.filter.predicate.Predicates; import mage.game.Game; import mage.game.permanent.Permanent; import mage.players.Player; import java.util.Objects; -import java.util.Set; import java.util.UUID; /** @@ -31,10 +26,9 @@ public final class RareBGone extends CardImpl { // Each player sacrifices all permanents that are rare or mythic rare, then each player reveals their hand and discards all cards that are rare or mythic rare. this.getSpellAbility().addEffect(new RareBGoneEffect()); - } - public RareBGone(final RareBGone card) { + private RareBGone(final RareBGone card) { super(card); } @@ -50,22 +44,17 @@ class RareBGoneEffect extends OneShotEffect { private static final FilterCard filterCard = new FilterCard(); static { - filterPermanent.add(Predicates.or( - new RarityPredicate(Rarity.RARE), - new RarityPredicate(Rarity.MYTHIC) - )); - filterCard.add(Predicates.or( - new RarityPredicate(Rarity.RARE), - new RarityPredicate(Rarity.MYTHIC) - )); + filterPermanent.add(RareBGonePredicate.instance); + filterCard.add(RareBGonePredicate.instance); } - public RareBGoneEffect() { + RareBGoneEffect() { super(Outcome.Benefit); - this.staticText = "Each player sacrifices all permanents that are rare or mythic rare, then each player reveals their hand and discards all cards that are rare or mythic rare"; + this.staticText = "Each player sacrifices all permanents that are rare or mythic rare, " + + "then each player reveals their hand and discards all cards that are rare or mythic rare"; } - public RareBGoneEffect(final RareBGoneEffect effect) { + private RareBGoneEffect(final RareBGoneEffect effect) { super(effect); } @@ -77,44 +66,29 @@ class RareBGoneEffect extends OneShotEffect { @Override public boolean apply(Game game, Ability source) { Player controller = game.getPlayer(source.getControllerId()); - if (controller != null) { - for (UUID playerId : game.getState().getPlayersInRange(controller.getId(), game)) { - Player player = game.getPlayer(playerId); - if (player != null) { - for (Permanent permanent : game.getBattlefield().getAllActivePermanents(filterPermanent, playerId, game)) { - permanent.sacrifice(source.getSourceId(), game); - } - Cards hand = player.getHand(); - player.revealCards("Rare-B-Gone", hand, game); - Set cards = hand.getCards(game); - for (Card card : cards) { - if (card != null && filterCard.match(card, game)) { - player.discard(card, source, game); - } - } - } - } - return true; + if (controller == null) { + return false; } - return false; + for (UUID playerId : game.getState().getPlayersInRange(controller.getId(), game)) { + Player player = game.getPlayer(playerId); + if (player == null) { + } + for (Permanent permanent : game.getBattlefield().getAllActivePermanents(filterPermanent, playerId, game)) { + permanent.sacrifice(source.getSourceId(), game); + } + Cards cards = player.getHand(); + player.revealCards(source, cards, game); + player.discard(new CardsImpl(cards.getCards(filterCard, game)), source, game); + } + return true; } } -class RarityPredicate implements Predicate { - - private final Rarity rarity; - - public RarityPredicate(Rarity rarity) { - this.rarity = rarity; - } +enum RareBGonePredicate implements Predicate { + instance; @Override public boolean apply(Card input, Game game) { - return Objects.equals(input.getRarity(), rarity); - } - - @Override - public String toString() { - return "Rarity(" + rarity + ')'; + return Objects.equals(input.getRarity(), Rarity.RARE) || Objects.equals(input.getRarity(), Rarity.MYTHIC); } } diff --git a/Mage.Sets/src/mage/cards/r/RestoreBalance.java b/Mage.Sets/src/mage/cards/r/RestoreBalance.java index dec27da79f1..18a8f979639 100644 --- a/Mage.Sets/src/mage/cards/r/RestoreBalance.java +++ b/Mage.Sets/src/mage/cards/r/RestoreBalance.java @@ -1,25 +1,13 @@ - package mage.cards.r; -import mage.abilities.Ability; import mage.abilities.costs.mana.ColoredManaCost; -import mage.abilities.effects.OneShotEffect; +import mage.abilities.effects.common.BalanceEffect; import mage.abilities.keyword.SuspendAbility; -import mage.cards.*; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; import mage.constants.CardType; import mage.constants.ColoredManaSymbol; -import mage.constants.Outcome; -import mage.filter.FilterCard; -import mage.filter.common.FilterControlledCreaturePermanent; -import mage.filter.common.FilterControlledLandPermanent; -import mage.game.Game; -import mage.game.permanent.Permanent; -import mage.players.Player; -import mage.target.common.TargetCardInHand; -import mage.target.common.TargetControlledPermanent; -import java.util.HashMap; -import java.util.Map; import java.util.UUID; /** @@ -35,10 +23,10 @@ public final class RestoreBalance extends CardImpl { // Suspend 6-{W} this.addAbility(new SuspendAbility(6, new ColoredManaCost(ColoredManaSymbol.W), this)); // Each player chooses a number of lands they control equal to the number of lands controlled by the player who controls the fewest, then sacrifices the rest. Players sacrifice creatures and discard cards the same way. - this.getSpellAbility().addEffect(new RestoreBalanceEffect()); + this.getSpellAbility().addEffect(new BalanceEffect()); } - public RestoreBalance(final RestoreBalance card) { + private RestoreBalance(final RestoreBalance card) { super(card); } @@ -47,137 +35,3 @@ public final class RestoreBalance extends CardImpl { return new RestoreBalance(this); } } - - -class RestoreBalanceEffect extends OneShotEffect { - - RestoreBalanceEffect() { - super(Outcome.Sacrifice); - staticText = "Each player chooses a number of lands they control equal to the number of lands controlled by the player who controls the fewest, then sacrifices the rest. Players sacrifice creatures and discard cards the same way"; - } - - RestoreBalanceEffect(final RestoreBalanceEffect effect) { - super(effect); - } - - @Override - public RestoreBalanceEffect copy() { - return new RestoreBalanceEffect(this); - } - - @Override - public boolean apply(Game game, Ability source) { - Player controller = game.getPlayer(source.getControllerId()); - if (controller != null) { - //Lands - int minLand = Integer.MAX_VALUE; - Cards landsToSacrifice = new CardsImpl(); - for (UUID playerId : game.getState().getPlayersInRange(controller.getId(), game)) { - Player player = game.getPlayer(playerId); - if (player != null) { - int count = game.getBattlefield().countAll(new FilterControlledLandPermanent(), player.getId(), game); - if (count < minLand) { - minLand = count; - } - } - } - - for (UUID playerId : game.getState().getPlayersInRange(controller.getId(), game)) { - Player player = game.getPlayer(playerId); - if (player != null) { - TargetControlledPermanent target = new TargetControlledPermanent(minLand, minLand, new FilterControlledLandPermanent(), true); - if (target.choose(Outcome.Sacrifice, player.getId(), source.getSourceId(), game)) { - for (Permanent permanent : game.getBattlefield().getActivePermanents(new FilterControlledLandPermanent(), player.getId(), source.getSourceId(), game)) { - if (permanent != null && !target.getTargets().contains(permanent.getId())) { - landsToSacrifice.add(permanent); - } - } - } - } - } - - for (UUID cardId : landsToSacrifice) { - Permanent permanent = game.getPermanent(cardId); - if (permanent != null) { - permanent.sacrifice(source.getSourceId(), game); - } - } - - //Creatures - int minCreature = Integer.MAX_VALUE; - Cards creaturesToSacrifice = new CardsImpl(); - for (UUID playerId : game.getState().getPlayersInRange(controller.getId(), game)) { - Player player = game.getPlayer(playerId); - if (player != null) { - int count = game.getBattlefield().countAll(new FilterControlledCreaturePermanent(), player.getId(), game); - if (count < minCreature) { - minCreature = count; - } - } - } - - for (UUID playerId : game.getState().getPlayersInRange(controller.getId(), game)) { - Player player = game.getPlayer(playerId); - if (player != null) { - TargetControlledPermanent target = new TargetControlledPermanent(minCreature, minCreature, new FilterControlledCreaturePermanent(), true); - if (target.choose(Outcome.Sacrifice, player.getId(), source.getSourceId(), game)) { - for (Permanent permanent : game.getBattlefield().getActivePermanents(new FilterControlledCreaturePermanent(), player.getId(), source.getSourceId(), game)) { - if (permanent != null && !target.getTargets().contains(permanent.getId())) { - creaturesToSacrifice.add(permanent); - } - } - } - } - } - - for (UUID cardId : creaturesToSacrifice) { - Permanent permanent = game.getPermanent(cardId); - if (permanent != null) { - permanent.sacrifice(source.getSourceId(), game); - } - } - - //Cards in hand - int minCard = Integer.MAX_VALUE; - Map cardsToDiscard = new HashMap<>(2); - for (UUID playerId : game.getState().getPlayersInRange(controller.getId(), game)) { - Player player = game.getPlayer(playerId); - if (player != null) { - int count = player.getHand().size(); - if (count < minCard) { - minCard = count; - } - } - } - - for (UUID playerId : game.getState().getPlayersInRange(controller.getId(), game)) { - Player player = game.getPlayer(playerId); - if (player != null) { - Cards cards = new CardsImpl(); - TargetCardInHand target = new TargetCardInHand(minCard, new FilterCard()); - if (target.choose(Outcome.Discard, player.getId(), source.getSourceId(), game)) { - for (Card card : player.getHand().getCards(game)) { - if (card != null && !target.getTargets().contains(card.getId())) { - cards.add(card); - } - } - cardsToDiscard.put(playerId, cards); - } - } - } - - for (UUID playerId : game.getState().getPlayersInRange(controller.getId(), game)) { - Player player = game.getPlayer(playerId); - if (player != null && cardsToDiscard.get(playerId) != null) { - for (UUID cardId : cardsToDiscard.get(playerId)) { - Card card = game.getCard(cardId); - player.discard(card, source, game); - - } - } - } - return true; - } - return false; - } -} diff --git a/Mage.Sets/src/mage/cards/r/RiseFall.java b/Mage.Sets/src/mage/cards/r/RiseFall.java index b3042b99025..e32809e2809 100644 --- a/Mage.Sets/src/mage/cards/r/RiseFall.java +++ b/Mage.Sets/src/mage/cards/r/RiseFall.java @@ -1,19 +1,14 @@ - package mage.cards.r; -import java.util.UUID; import mage.MageObject; import mage.abilities.Ability; import mage.abilities.effects.OneShotEffect; -import mage.cards.Card; -import mage.cards.CardSetInfo; -import mage.cards.Cards; -import mage.cards.CardsImpl; -import mage.cards.SplitCard; +import mage.cards.*; import mage.constants.CardType; import mage.constants.Outcome; import mage.constants.SpellAbilityType; import mage.constants.Zone; +import mage.filter.FilterCard; import mage.filter.common.FilterCreatureCard; import mage.game.Game; import mage.game.permanent.Permanent; @@ -22,19 +17,22 @@ import mage.target.TargetPlayer; import mage.target.common.TargetCardInGraveyard; import mage.target.common.TargetCreaturePermanent; +import java.util.UUID; + /** - * * @author LevelX2 */ public final class RiseFall extends SplitCard { + private static final FilterCard filter = new FilterCreatureCard("creature card from a graveyard"); + public RiseFall(UUID ownerId, CardSetInfo setInfo) { super(ownerId, setInfo, new CardType[]{CardType.SORCERY}, "{U}{B}", "{B}{R}", SpellAbilityType.SPLIT); // Rise // Return target creature card from a graveyard and target creature on the battlefield to their owners' hands. getLeftHalfCard().getSpellAbility().addEffect(new RiseEffect()); - getLeftHalfCard().getSpellAbility().addTarget(new TargetCardInGraveyard(new FilterCreatureCard("creature card from a graveyard"))); + getLeftHalfCard().getSpellAbility().addTarget(new TargetCardInGraveyard(filter)); getLeftHalfCard().getSpellAbility().addTarget(new TargetCreaturePermanent()); // Fall @@ -43,7 +41,7 @@ public final class RiseFall extends SplitCard { getRightHalfCard().getSpellAbility().addTarget(new TargetPlayer()); } - public RiseFall(final RiseFall card) { + private RiseFall(final RiseFall card) { super(card); } @@ -55,12 +53,12 @@ public final class RiseFall extends SplitCard { class RiseEffect extends OneShotEffect { - public RiseEffect() { + RiseEffect() { super(Outcome.ReturnToHand); this.staticText = "Return target creature card from a graveyard and target creature on the battlefield to their owners' hands"; } - public RiseEffect(final RiseEffect effect) { + private RiseEffect(final RiseEffect effect) { super(effect); } @@ -72,31 +70,31 @@ class RiseEffect extends OneShotEffect { @Override public boolean apply(Game game, Ability source) { Player controller = game.getPlayer(source.getControllerId()); - if (controller != null) { - Cards cardsToHand = new CardsImpl(); - Card cardInGraveyard = game.getCard(getTargetPointer().getFirst(game, source)); - if (cardInGraveyard != null) { - cardsToHand.add(cardInGraveyard); - } - Permanent permanent = game.getPermanent(source.getTargets().get(1).getFirstTarget()); - if (permanent != null) { - cardsToHand.add(permanent); - } - controller.moveCards(cardsToHand, Zone.HAND, source, game); - return true; + if (controller == null) { + return false; } - return false; + Cards cardsToHand = new CardsImpl(); + Card cardInGraveyard = game.getCard(getTargetPointer().getFirst(game, source)); + if (cardInGraveyard != null) { + cardsToHand.add(cardInGraveyard); + } + Permanent permanent = game.getPermanent(source.getTargets().get(1).getFirstTarget()); + if (permanent != null) { + cardsToHand.add(permanent); + } + controller.moveCards(cardsToHand, Zone.HAND, source, game); + return true; } } class FallEffect extends OneShotEffect { - public FallEffect() { + FallEffect() { super(Outcome.Discard); this.staticText = "Target player reveals two cards at random from their hand, then discards each nonland card revealed this way"; } - public FallEffect(final FallEffect effect) { + private FallEffect(final FallEffect effect) { super(effect); } @@ -109,34 +107,32 @@ class FallEffect extends OneShotEffect { public boolean apply(Game game, Ability source) { Player controller = game.getPlayer(source.getControllerId()); MageObject sourceObject = game.getObject(source.getSourceId()); - if (controller != null) { - Player targetPlayer = game.getPlayer(getTargetPointer().getFirst(game, source)); - if (targetPlayer != null) { - if (!targetPlayer.getHand().isEmpty()) { - Card card = targetPlayer.getHand().getRandom(game); - if (card == null) { - return false; - } - Cards cards = new CardsImpl(card); - if (targetPlayer.getHand().size() > 1) { - do { - card = targetPlayer.getHand().getRandom(game); - if (card == null) { - return false; - } - } while (cards.contains(card.getId())); - cards.add(card); - } - targetPlayer.revealCards(sourceObject.getIdName(), cards, game); - for (Card cardToDiscard : cards.getCards(game)) { - if (!cardToDiscard.isLand()) { - targetPlayer.discard(cardToDiscard, source, game); - } - } - } - } + if (controller == null) { + return false; + } + Player targetPlayer = game.getPlayer(getTargetPointer().getFirst(game, source)); + if (targetPlayer == null) { return true; } - return false; + if (targetPlayer.getHand().isEmpty()) { + return true; + } + Card card = targetPlayer.getHand().getRandom(game); + if (card == null) { + return false; + } + Cards cards = new CardsImpl(card); + if (targetPlayer.getHand().size() > 1) { + do { + card = targetPlayer.getHand().getRandom(game); + if (card == null) { + return false; + } + } while (cards.contains(card.getId())); + cards.add(card); + } + targetPlayer.revealCards(sourceObject.getIdName(), cards, game); + targetPlayer.discard(cards, source, game); + return true; } } diff --git a/Mage.Sets/src/mage/cards/r/RitesOfSpring.java b/Mage.Sets/src/mage/cards/r/RitesOfSpring.java index 76dfca48a10..3991d3acd3c 100644 --- a/Mage.Sets/src/mage/cards/r/RitesOfSpring.java +++ b/Mage.Sets/src/mage/cards/r/RitesOfSpring.java @@ -1,25 +1,23 @@ - package mage.cards.r; -import java.util.UUID; import mage.abilities.Ability; import mage.abilities.effects.OneShotEffect; import mage.abilities.effects.common.search.SearchLibraryPutInHandEffect; -import mage.cards.Card; import mage.cards.CardImpl; import mage.cards.CardSetInfo; +import mage.cards.CardsImpl; import mage.constants.CardType; import mage.constants.Outcome; -import mage.filter.FilterCard; import mage.filter.StaticFilters; import mage.game.Game; import mage.players.Player; -import mage.target.Target; -import mage.target.common.TargetCardInHand; +import mage.target.TargetCard; import mage.target.common.TargetCardInLibrary; +import mage.target.common.TargetDiscard; + +import java.util.UUID; /** - * * @author LevelX2 */ public final class RitesOfSpring extends CardImpl { @@ -31,7 +29,7 @@ public final class RitesOfSpring extends CardImpl { getSpellAbility().addEffect(new RitesOfSpringEffect()); } - public RitesOfSpring(final RitesOfSpring card) { + private RitesOfSpring(final RitesOfSpring card) { super(card); } @@ -43,12 +41,13 @@ public final class RitesOfSpring extends CardImpl { class RitesOfSpringEffect extends OneShotEffect { - public RitesOfSpringEffect() { + RitesOfSpringEffect() { super(Outcome.DrawCard); - this.staticText = "Discard any number of cards. Search your library for up to that many basic land cards, reveal those cards, and put them into your hand. Then shuffle your library."; + this.staticText = "Discard any number of cards. Search your library for up to that many basic land cards, " + + "reveal those cards, and put them into your hand. Then shuffle your library."; } - public RitesOfSpringEffect(final RitesOfSpringEffect effect) { + private RitesOfSpringEffect(final RitesOfSpringEffect effect) { super(effect); } @@ -60,23 +59,15 @@ class RitesOfSpringEffect extends OneShotEffect { @Override public boolean apply(Game game, Ability source) { Player controller = game.getPlayer(source.getControllerId()); - if (controller != null) { - Target target = new TargetCardInHand(0, Integer.MAX_VALUE, new FilterCard("cards to discard")); - while (controller.canRespond() && !target.isChosen()) { - target.choose(Outcome.BoostCreature, controller.getId(), source.getSourceId(), game); - } - int numDiscarded = 0; - for (UUID targetId : target.getTargets()) { - Card card = controller.getHand().get(targetId, game); - if (controller.discard(card, source, game)) { - numDiscarded++; - } - } - game.applyEffects(); - return new SearchLibraryPutInHandEffect( - new TargetCardInLibrary(0, numDiscarded, StaticFilters.FILTER_CARD_BASIC_LAND), true, true) - .apply(game, source); + if (controller == null) { + return false; } - return false; + TargetCard target = new TargetDiscard(0, Integer.MAX_VALUE, StaticFilters.FILTER_CARD, controller.getId()); + controller.choose(Outcome.AIDontUseIt, controller.getHand(), target, game); + int numDiscarded = controller.discard(new CardsImpl(target.getTargets()), source, game).size(); + new SearchLibraryPutInHandEffect(new TargetCardInLibrary( + 0, numDiscarded, StaticFilters.FILTER_CARD_BASIC_LAND + ), true, true).apply(game, source); + return true; } } diff --git a/Mage.Sets/src/mage/cards/s/SacredRites.java b/Mage.Sets/src/mage/cards/s/SacredRites.java index a1302c4ba34..3104c737bdc 100644 --- a/Mage.Sets/src/mage/cards/s/SacredRites.java +++ b/Mage.Sets/src/mage/cards/s/SacredRites.java @@ -1,24 +1,23 @@ - package mage.cards.s; -import java.util.UUID; import mage.abilities.Ability; import mage.abilities.effects.OneShotEffect; import mage.abilities.effects.common.continuous.BoostControlledEffect; -import mage.cards.Card; import mage.cards.CardImpl; import mage.cards.CardSetInfo; +import mage.cards.CardsImpl; import mage.constants.CardType; import mage.constants.Duration; import mage.constants.Outcome; -import mage.filter.FilterCard; +import mage.filter.StaticFilters; import mage.game.Game; import mage.players.Player; import mage.target.Target; -import mage.target.common.TargetCardInHand; +import mage.target.common.TargetDiscard; + +import java.util.UUID; /** - * * @author cbt33 */ public final class SacredRites extends CardImpl { @@ -30,7 +29,7 @@ public final class SacredRites extends CardImpl { this.getSpellAbility().addEffect(new SacredRitesEffect()); } - public SacredRites(final SacredRites card) { + private SacredRites(final SacredRites card) { super(card); } @@ -43,11 +42,11 @@ public final class SacredRites extends CardImpl { class SacredRitesEffect extends OneShotEffect { SacredRitesEffect() { - super(Outcome.Benefit); + super(Outcome.AIDontUseIt); this.staticText = "Discard any number of cards. Creatures you control get +0/+1 until end of turn for each card discarded this way."; } - SacredRitesEffect(final SacredRitesEffect effect) { + private SacredRitesEffect(final SacredRitesEffect effect) { super(effect); } @@ -59,21 +58,15 @@ class SacredRitesEffect extends OneShotEffect { @Override public boolean apply(Game game, Ability source) { Player controller = game.getPlayer(source.getControllerId()); - if (controller != null) { - Target target = new TargetCardInHand(0, Integer.MAX_VALUE, new FilterCard("cards to discard")); - while (controller.canRespond() && !target.isChosen()) { - target.choose(Outcome.BoostCreature, controller.getId(), source.getSourceId(), game); - } - int numDiscarded = 0; - for (UUID targetId : target.getTargets()) { - Card card = controller.getHand().get(targetId, game); - if (controller.discard(card, source, game)) { - numDiscarded++; - } - } - game.addEffect(new BoostControlledEffect(0, numDiscarded, Duration.EndOfTurn), source); - return true; + if (controller == null) { + return false; } - return false; + Target target = new TargetDiscard(0, Integer.MAX_VALUE, StaticFilters.FILTER_CARD, controller.getId()); + target.choose(outcome, controller.getId(), source.getSourceId(), game); + int numDiscarded = controller.discard(new CardsImpl(target.getTargets()), source, game).size(); + if (numDiscarded > 0) { + game.addEffect(new BoostControlledEffect(0, numDiscarded, Duration.EndOfTurn), source); + } + return true; } } diff --git a/Mage.Sets/src/mage/cards/s/ShatterAssumptions.java b/Mage.Sets/src/mage/cards/s/ShatterAssumptions.java index bea5cab22d0..09dc73af6fd 100644 --- a/Mage.Sets/src/mage/cards/s/ShatterAssumptions.java +++ b/Mage.Sets/src/mage/cards/s/ShatterAssumptions.java @@ -3,7 +3,9 @@ package mage.cards.s; import mage.abilities.Ability; import mage.abilities.Mode; import mage.abilities.effects.OneShotEffect; -import mage.cards.*; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.cards.CardsImpl; import mage.constants.CardType; import mage.constants.Outcome; import mage.filter.FilterCard; @@ -83,17 +85,14 @@ class ShatterAssumptionsEffect extends OneShotEffect { if (player == null) { return false; } - Cards cards = new CardsImpl(player.getHand()); - player.revealCards(source, cards, game); + player.revealCards(source, player.getHand(), game); FilterCard f; if (colorless) { f = filter; } else { f = filter2; } - for (Card card : cards.getCards(f, source.getSourceId(), source.getControllerId(), game)) { - player.discard(card, source, game); - } + player.discard(new CardsImpl(player.getHand().getCards(f, game)), source, game); return true; } } \ No newline at end of file diff --git a/Mage.Sets/src/mage/cards/s/Shocker.java b/Mage.Sets/src/mage/cards/s/Shocker.java index e988fd2caff..176afefbf0e 100644 --- a/Mage.Sets/src/mage/cards/s/Shocker.java +++ b/Mage.Sets/src/mage/cards/s/Shocker.java @@ -1,28 +1,26 @@ - package mage.cards.s; -import java.util.UUID; import mage.MageInt; import mage.abilities.Ability; import mage.abilities.common.DealsDamageToAPlayerTriggeredAbility; import mage.abilities.effects.OneShotEffect; -import mage.cards.Card; import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.constants.CardType; -import mage.constants.SubType; import mage.constants.Outcome; +import mage.constants.SubType; import mage.game.Game; import mage.players.Player; +import java.util.UUID; + /** - * * @author markedagain */ public final class Shocker extends CardImpl { public Shocker(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{1}{R}"); + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{1}{R}"); this.subtype.add(SubType.INSECT); this.power = new MageInt(1); this.toughness = new MageInt(1); @@ -40,14 +38,15 @@ public final class Shocker extends CardImpl { return new Shocker(this); } } + class ShockerEffect extends OneShotEffect { - public ShockerEffect() { + ShockerEffect() { super(Outcome.Discard); this.staticText = " that player discards all the cards in their hand, then draws that many cards"; } - public ShockerEffect(final ShockerEffect effect) { + private ShockerEffect(final ShockerEffect effect) { super(effect); } @@ -59,14 +58,11 @@ class ShockerEffect extends OneShotEffect { @Override public boolean apply(Game game, Ability source) { Player targetPlayer = game.getPlayer(targetPointer.getFirst(game, source)); - if (targetPlayer != null) { - int count = targetPlayer.getHand().size(); - for (Card card : targetPlayer.getHand().getCards(game)) { - targetPlayer.discard(card, source, game); - } - targetPlayer.drawCards(count, source.getSourceId(), game); - return false; - } + if (targetPlayer == null) { + return false; + } + int count = targetPlayer.discard(targetPlayer.getHand(), source, game).size(); + targetPlayer.drawCards(count, source.getSourceId(), game); return true; } -} \ No newline at end of file +} diff --git a/Mage.Sets/src/mage/cards/s/SireOfInsanity.java b/Mage.Sets/src/mage/cards/s/SireOfInsanity.java index 7a9f1af074e..90ece9fc954 100644 --- a/Mage.Sets/src/mage/cards/s/SireOfInsanity.java +++ b/Mage.Sets/src/mage/cards/s/SireOfInsanity.java @@ -1,43 +1,39 @@ - package mage.cards.s; -import java.util.UUID; import mage.MageInt; import mage.abilities.Ability; -import mage.abilities.common.OnEventTriggeredAbility; +import mage.abilities.common.BeginningOfEndStepTriggeredAbility; import mage.abilities.effects.OneShotEffect; -import mage.cards.Card; import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.constants.CardType; -import mage.constants.SubType; import mage.constants.Outcome; +import mage.constants.SubType; +import mage.constants.TargetController; import mage.game.Game; -import mage.game.events.GameEvent; import mage.players.Player; +import java.util.UUID; + /** - * * @author LevelX2 */ - - public final class SireOfInsanity extends CardImpl { - public SireOfInsanity (UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{4}{B}{R}"); + public SireOfInsanity(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{4}{B}{R}"); this.subtype.add(SubType.DEMON); - this.power = new MageInt(6); this.toughness = new MageInt(4); // At the beginning of each end step, each player discards their hand. - this.addAbility(new OnEventTriggeredAbility(GameEvent.EventType.END_TURN_STEP_PRE, "beginning of each end step", true, new SireOfInsanityEffect())); - + this.addAbility(new BeginningOfEndStepTriggeredAbility( + new SireOfInsanityEffect(), TargetController.ANY, false + )); } - public SireOfInsanity (final SireOfInsanity card) { + private SireOfInsanity(final SireOfInsanity card) { super(card); } @@ -54,7 +50,7 @@ class SireOfInsanityEffect extends OneShotEffect { staticText = "each player discards their hand"; } - SireOfInsanityEffect(final SireOfInsanityEffect effect) { + private SireOfInsanityEffect(final SireOfInsanityEffect effect) { super(effect); } @@ -67,9 +63,7 @@ class SireOfInsanityEffect extends OneShotEffect { for (UUID playerId : game.getState().getPlayersInRange(sourcePlayer.getId(), game)) { Player player = game.getPlayer(playerId); if (player != null) { - for (Card c : player.getHand().getCards(game)) { - player.discard(c, source, game); - } + player.discard(player.getHand(), source, game); } } return true; diff --git a/Mage.Sets/src/mage/cards/s/SkullRend.java b/Mage.Sets/src/mage/cards/s/SkullRend.java index 9b521c87947..e2a3f3ec399 100644 --- a/Mage.Sets/src/mage/cards/s/SkullRend.java +++ b/Mage.Sets/src/mage/cards/s/SkullRend.java @@ -2,7 +2,6 @@ package mage.cards.s; import mage.abilities.Ability; import mage.abilities.effects.OneShotEffect; -import mage.cards.Card; import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.constants.CardType; @@ -10,24 +9,24 @@ import mage.constants.Outcome; import mage.game.Game; import mage.players.Player; +import java.util.List; import java.util.Objects; import java.util.UUID; +import java.util.stream.Collectors; /** - * @author LevelX2 + * @author TheElk801 */ public final class SkullRend extends CardImpl { public SkullRend(UUID ownerId, CardSetInfo setInfo) { super(ownerId, setInfo, new CardType[]{CardType.SORCERY}, "{3}{B}{R}"); - // Skull Rend deals 2 damage to each opponent. Those players each discard two cards at random. this.getSpellAbility().addEffect(new SkullRendEffect()); - } - public SkullRend(final SkullRend card) { + private SkullRend(final SkullRend card) { super(card); } @@ -38,39 +37,29 @@ public final class SkullRend extends CardImpl { private static class SkullRendEffect extends OneShotEffect { - public SkullRendEffect() { + private SkullRendEffect() { super(Outcome.Damage); staticText = "{this} deals 2 damage to each opponent. Those players each discard two cards at random"; } - public SkullRendEffect(final SkullRendEffect effect) { + private SkullRendEffect(final SkullRendEffect effect) { super(effect); } @Override public boolean apply(Game game, Ability source) { - Player controller = game.getPlayer(source.getControllerId()); - if (controller != null) { - for (UUID playerId : game.getState().getPlayersInRange(controller.getId(), game)) { - if (!Objects.equals(playerId, source.getControllerId())) { - Player opponent = game.getPlayer(playerId); - if (opponent != null) { - // damage - opponent.damage(2, source.getSourceId(), game); - // discard 2 cards at random - int amount = Math.min(2, opponent.getHand().size()); - for (int i = 0; i < amount; i++) { - Card card = opponent.getHand().getRandom(game); - if (card != null) { - opponent.discard(card, source, game); - } - } - } - } - } - return true; + List opponents = game + .getOpponents(source.getControllerId()) + .stream().map(game::getPlayer) + .filter(Objects::nonNull) + .collect(Collectors.toList()); + for (Player opponent : opponents) { + opponent.damage(2, source.getSourceId(), game); } - return false; + for (Player opponent : opponents) { + opponent.discard(2, true, source, game); + } + return true; } @Override @@ -78,4 +67,4 @@ public final class SkullRend extends CardImpl { return new SkullRendEffect(this); } } -} \ No newline at end of file +} diff --git a/Mage.Sets/src/mage/cards/t/TrapfindersTrick.java b/Mage.Sets/src/mage/cards/t/TrapfindersTrick.java index 970b08a6f70..03c02e1b039 100644 --- a/Mage.Sets/src/mage/cards/t/TrapfindersTrick.java +++ b/Mage.Sets/src/mage/cards/t/TrapfindersTrick.java @@ -1,37 +1,34 @@ - package mage.cards.t; -import java.util.Set; -import java.util.UUID; import mage.abilities.Ability; import mage.abilities.effects.OneShotEffect; -import mage.cards.Card; import mage.cards.CardImpl; import mage.cards.CardSetInfo; -import mage.cards.Cards; +import mage.cards.CardsImpl; import mage.constants.CardType; import mage.constants.Outcome; import mage.constants.SubType; +import mage.filter.FilterCard; import mage.game.Game; import mage.players.Player; import mage.target.TargetPlayer; +import java.util.UUID; + /** - * * @author North */ public final class TrapfindersTrick extends CardImpl { public TrapfindersTrick(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.SORCERY},"{1}{U}"); - + super(ownerId, setInfo, new CardType[]{CardType.SORCERY}, "{1}{U}"); // Target player reveals their hand and discards all Trap cards. this.getSpellAbility().addEffect(new TrapfindersTrickEffect()); this.getSpellAbility().addTarget(new TargetPlayer()); } - public TrapfindersTrick(final TrapfindersTrick card) { + private TrapfindersTrick(final TrapfindersTrick card) { super(card); } @@ -43,12 +40,18 @@ public final class TrapfindersTrick extends CardImpl { class TrapfindersTrickEffect extends OneShotEffect { - public TrapfindersTrickEffect() { + private static final FilterCard filter = new FilterCard(); + + static { + filter.add(SubType.TRAP.getPredicate()); + } + + TrapfindersTrickEffect() { super(Outcome.Discard); this.staticText = "Target player reveals their hand and discards all Trap cards"; } - public TrapfindersTrickEffect(final TrapfindersTrickEffect effect) { + private TrapfindersTrickEffect(final TrapfindersTrickEffect effect) { super(effect); } @@ -60,17 +63,11 @@ class TrapfindersTrickEffect extends OneShotEffect { @Override public boolean apply(Game game, Ability source) { Player player = game.getPlayer(source.getFirstTarget()); - if (player != null) { - Cards hand = player.getHand(); - player.revealCards("Trapfinder's Trick", hand, game); - Set cards = hand.getCards(game); - for (Card card : cards) { - if (card != null && card.hasSubtype(SubType.TRAP, game)) { - player.discard(card, source, game); - } - } - return true; + if (player == null) { + return false; } - return false; + player.revealCards(source, player.getHand(), game); + player.discard(new CardsImpl(player.getHand().getCards(filter, game)), source, game); + return true; } } diff --git a/Mage.Sets/src/mage/cards/t/TsabosDecree.java b/Mage.Sets/src/mage/cards/t/TsabosDecree.java index 193105e8b1f..ab5b862b092 100644 --- a/Mage.Sets/src/mage/cards/t/TsabosDecree.java +++ b/Mage.Sets/src/mage/cards/t/TsabosDecree.java @@ -1,15 +1,11 @@ - package mage.cards.t; -import java.util.ArrayList; -import java.util.List; -import java.util.UUID; import mage.MageObject; import mage.abilities.Ability; import mage.abilities.effects.OneShotEffect; -import mage.cards.Card; import mage.cards.CardImpl; import mage.cards.CardSetInfo; +import mage.cards.CardsImpl; import mage.choices.Choice; import mage.choices.ChoiceCreatureType; import mage.constants.CardType; @@ -22,8 +18,9 @@ import mage.game.permanent.Permanent; import mage.players.Player; import mage.target.TargetPlayer; +import java.util.UUID; + /** - * * @author fireshoes */ public final class TsabosDecree extends CardImpl { @@ -36,7 +33,7 @@ public final class TsabosDecree extends CardImpl { this.getSpellAbility().addTarget(new TargetPlayer()); } - public TsabosDecree(final TsabosDecree card) { + private TsabosDecree(final TsabosDecree card) { super(card); } @@ -48,12 +45,14 @@ public final class TsabosDecree extends CardImpl { class TsabosDecreeEffect extends OneShotEffect { - public TsabosDecreeEffect() { + TsabosDecreeEffect() { super(Outcome.UnboostCreature); - staticText = "Choose a creature type. Target player reveals their hand and discards all creature cards of that type. Then destroy all creatures of that type that player controls. They can't be regenerated"; + staticText = "Choose a creature type. Target player reveals their hand and discards " + + "all creature cards of that type. Then destroy all creatures of that type that player controls. " + + "They can't be regenerated"; } - public TsabosDecreeEffect(final TsabosDecreeEffect effect) { + private TsabosDecreeEffect(final TsabosDecreeEffect effect) { super(effect); } @@ -62,36 +61,29 @@ class TsabosDecreeEffect extends OneShotEffect { Player player = game.getPlayer(source.getControllerId()); Player targetPlayer = game.getPlayer(targetPointer.getFirst(game, source)); MageObject sourceObject = game.getObject(source.getSourceId()); - if (player != null) { - if(sourceObject != null) { - Choice typeChoice = new ChoiceCreatureType(sourceObject); - if (!player.choose(outcome, typeChoice, game)) { - return false; - } - game.informPlayers(sourceObject.getLogName() + " chosen type: " + typeChoice.getChoice()); - targetPlayer.revealCards("hand of " + targetPlayer.getName(), targetPlayer.getHand(), game); - FilterCard filterCard = new FilterCard(); - filterCard.add(SubType.byDescription(typeChoice.getChoice()).getPredicate()); - List toDiscard = new ArrayList<>(); - for (Card card : targetPlayer.getHand().getCards(game)) { - if (filterCard.match(card, game)) { - toDiscard.add(card); - } - } - for (Card card : toDiscard) { - targetPlayer.discard(card, source, game); - } - FilterCreaturePermanent filterCreaturePermanent = new FilterCreaturePermanent(); - filterCreaturePermanent.add(SubType.byDescription(typeChoice.getChoice()).getPredicate()); - for (Permanent creature : game.getBattlefield().getActivePermanents(filterCreaturePermanent, source.getSourceId(), game)) { - if (creature.isControlledBy(targetPlayer.getId())) { - creature.destroy(source.getSourceId(), game, true); - } - } - return true; + if (player == null) { + return false; + } + if (sourceObject == null) { + return false; + } + Choice typeChoice = new ChoiceCreatureType(sourceObject); + if (!player.choose(outcome, typeChoice, game)) { + return false; + } + game.informPlayers(sourceObject.getLogName() + " chosen type: " + typeChoice.getChoice()); + targetPlayer.revealCards("hand of " + targetPlayer.getName(), targetPlayer.getHand(), game); + FilterCard filterCard = new FilterCard(); + filterCard.add(SubType.byDescription(typeChoice.getChoice()).getPredicate()); + targetPlayer.discard(new CardsImpl(targetPlayer.getHand().getCards(filterCard, game)), source, game); + FilterCreaturePermanent filterCreaturePermanent = new FilterCreaturePermanent(); + filterCreaturePermanent.add(SubType.byDescription(typeChoice.getChoice()).getPredicate()); + for (Permanent creature : game.getBattlefield().getActivePermanents(filterCreaturePermanent, source.getSourceId(), game)) { + if (creature.isControlledBy(targetPlayer.getId())) { + creature.destroy(source.getSourceId(), game, true); } } - return false; + return true; } @Override diff --git a/Mage.Sets/src/mage/cards/t/Tyrannize.java b/Mage.Sets/src/mage/cards/t/Tyrannize.java index c7055ae97ab..90c56333a09 100644 --- a/Mage.Sets/src/mage/cards/t/Tyrannize.java +++ b/Mage.Sets/src/mage/cards/t/Tyrannize.java @@ -29,7 +29,6 @@ public final class Tyrannize extends CardImpl { // Target player discards their hand unless they pay 7 life. this.getSpellAbility().addTarget(new TargetPlayer()); this.getSpellAbility().addEffect(new TyrannizeEffect()); - } public Tyrannize(final Tyrannize card) { @@ -66,9 +65,7 @@ class TyrannizeEffect extends OneShotEffect { if (!cost.canPay(source, source.getSourceId(), player.getId(), game) || !player.chooseUse(Outcome.LoseLife, "Pay 7 life?", source, game) || !cost.pay(source, game, source.getSourceId(), player.getId(), false, null)) { - for (Card card : player.getHand().getCards(game)) { - player.discard(card, source, game); - } + player.discard(player.getHand(),source,game); } return true; } diff --git a/Mage.Sets/src/mage/cards/v/Void.java b/Mage.Sets/src/mage/cards/v/Void.java index 2f11a512249..902f2a2b6ff 100644 --- a/Mage.Sets/src/mage/cards/v/Void.java +++ b/Mage.Sets/src/mage/cards/v/Void.java @@ -1,14 +1,10 @@ - package mage.cards.v; -import java.util.HashSet; -import java.util.Set; -import java.util.UUID; import mage.abilities.Ability; import mage.abilities.effects.OneShotEffect; -import mage.cards.Card; import mage.cards.CardImpl; import mage.cards.CardSetInfo; +import mage.cards.CardsImpl; import mage.choices.Choice; import mage.choices.ChoiceImpl; import mage.constants.CardType; @@ -22,6 +18,10 @@ import mage.game.permanent.Permanent; import mage.players.Player; import mage.target.TargetPlayer; +import java.util.HashSet; +import java.util.Set; +import java.util.UUID; + /** * @author LevelX2 */ @@ -33,7 +33,6 @@ public final class Void extends CardImpl { // Choose a number. Destroy all artifacts and creatures with converted mana cost equal to that number. Then target player reveals their hand and discards all nonland cards with converted mana cost equal to the number. this.getSpellAbility().addTarget(new TargetPlayer()); this.getSpellAbility().addEffect(new VoidEffect()); - } public Void(final Void card) { @@ -48,12 +47,12 @@ public final class Void extends CardImpl { class VoidEffect extends OneShotEffect { - public VoidEffect() { + VoidEffect() { super(Outcome.DestroyPermanent); this.staticText = "Choose a number. Destroy all artifacts and creatures with converted mana cost equal to that number. Then target player reveals their hand and discards all nonland cards with converted mana cost equal to the number"; } - public VoidEffect(final VoidEffect effect) { + private VoidEffect(final VoidEffect effect) { super(effect); } @@ -65,39 +64,36 @@ class VoidEffect extends OneShotEffect { @Override public boolean apply(Game game, Ability source) { Player controller = game.getPlayer(source.getControllerId()); - if (controller != null) { - Choice numberChoice = new ChoiceImpl(); - Set numbers = new HashSet<>(16); - for (int i = 0; i <= 15; i++) { - numbers.add(Integer.toString(i)); + if (controller == null) { + return false; + } + Choice numberChoice = new ChoiceImpl(); + Set numbers = new HashSet<>(16); + for (int i = 0; i <= 15; i++) { + numbers.add(Integer.toString(i)); + } + numberChoice.setChoices(numbers); + numberChoice.setMessage("Choose a number"); + if (!controller.choose(Outcome.DestroyPermanent, numberChoice, game)) { + return false; + } + int number = Integer.parseInt(numberChoice.getChoice()); + for (Permanent permanent : game.getBattlefield().getActivePermanents(source.getControllerId(), game)) { + if ((permanent.isArtifact() || permanent.isCreature()) + && permanent.getConvertedManaCost() == number) { + permanent.destroy(source.getSourceId(), game, false); } - numberChoice.setChoices(numbers); - numberChoice.setMessage("Choose a number"); - if (!controller.choose(Outcome.DestroyPermanent, numberChoice, game)) { - return false; - } - int number = Integer.parseInt(numberChoice.getChoice()); - for (Permanent permanent : game.getBattlefield().getActivePermanents(source.getControllerId(), game)) { - if ((permanent.isArtifact() || permanent.isCreature()) - && permanent.getConvertedManaCost() == number) { - permanent.destroy(source.getSourceId(), game, false); - } - } - FilterCard filterCard = new FilterCard(); - filterCard.add(new ConvertedManaCostPredicate(ComparisonType.EQUAL_TO, number)); - filterCard.add(Predicates.not(CardType.LAND.getPredicate())); + } + FilterCard filterCard = new FilterCard(); + filterCard.add(new ConvertedManaCostPredicate(ComparisonType.EQUAL_TO, number)); + filterCard.add(Predicates.not(CardType.LAND.getPredicate())); - Player targetPlayer = game.getPlayer(targetPointer.getFirst(game, source)); - if (targetPlayer != null) { - targetPlayer.revealCards("Void", targetPlayer.getHand(), game); - for (Card card : targetPlayer.getHand().getCards(game)) { - if (filterCard.match(card, game)) { - targetPlayer.discard(card, source, game); - } - } - } + Player targetPlayer = game.getPlayer(targetPointer.getFirst(game, source)); + if (targetPlayer == null) { return true; } - return false; + targetPlayer.revealCards(source, targetPlayer.getHand(), game); + targetPlayer.discard(new CardsImpl(targetPlayer.getHand().getCards(filterCard, game)), source, game); + return true; } } diff --git a/Mage.Sets/src/mage/cards/w/WhisperingMadness.java b/Mage.Sets/src/mage/cards/w/WhisperingMadness.java index be9b8b6bc93..eb04fd9fa22 100644 --- a/Mage.Sets/src/mage/cards/w/WhisperingMadness.java +++ b/Mage.Sets/src/mage/cards/w/WhisperingMadness.java @@ -1,11 +1,8 @@ - package mage.cards.w; -import java.util.UUID; import mage.abilities.Ability; import mage.abilities.effects.OneShotEffect; import mage.abilities.effects.common.CipherEffect; -import mage.cards.Card; import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.constants.CardType; @@ -13,23 +10,24 @@ import mage.constants.Outcome; import mage.game.Game; import mage.players.Player; +import java.util.UUID; + /** - * * @author LevelX2 */ public final class WhisperingMadness extends CardImpl { public WhisperingMadness(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.SORCERY},"{2}{U}{B}"); - + super(ownerId, setInfo, new CardType[]{CardType.SORCERY}, "{2}{U}{B}"); // Each player discards their hand, then draws cards equal to the greatest number of cards a player discarded this way. this.getSpellAbility().addEffect(new WhisperingMadnessEffect()); + // Cipher this.getSpellAbility().addEffect(new CipherEffect()); } - public WhisperingMadness(final WhisperingMadness card) { + private WhisperingMadness(final WhisperingMadness card) { super(card); } @@ -45,38 +43,33 @@ class WhisperingMadnessEffect extends OneShotEffect { staticText = "Each player discards their hand, then draws cards equal to the greatest number of cards a player discarded this way"; } - WhisperingMadnessEffect(final WhisperingMadnessEffect effect) { + private WhisperingMadnessEffect(final WhisperingMadnessEffect effect) { super(effect); } @Override public boolean apply(Game game, Ability source) { int maxDiscarded = 0; - Player sourcePlayer = game.getPlayer(source.getControllerId()); - if (sourcePlayer == null) { + Player controller = game.getPlayer(source.getControllerId()); + if (controller == null) { return false; } - for (UUID playerId : game.getState().getPlayersInRange(sourcePlayer.getId(), game)) { + for (UUID playerId : game.getState().getPlayersInRange(controller.getId(), game)) { Player player = game.getPlayer(playerId); - if (player != null) { - int discarded = 0; - for (Card c : player.getHand().getCards(game)) { - if (player.discard(c, source, game)) { - discarded++; - } - } - if (discarded > maxDiscarded) { - maxDiscarded = discarded; - } + if (player == null) { + continue; + } + int discarded = player.discard(player.getHand(), source, game).size(); + if (discarded > maxDiscarded) { + maxDiscarded = discarded; } } - for (UUID playerId : game.getState().getPlayersInRange(sourcePlayer.getId(), game)) { + for (UUID playerId : game.getState().getPlayersInRange(controller.getId(), game)) { Player player = game.getPlayer(playerId); if (player != null) { player.drawCards(maxDiscarded, source.getSourceId(), game); } } - return true; } @@ -84,4 +77,4 @@ class WhisperingMadnessEffect extends OneShotEffect { public WhisperingMadnessEffect copy() { return new WhisperingMadnessEffect(this); } -} \ No newline at end of file +} diff --git a/Mage.Sets/src/mage/cards/w/Windfall.java b/Mage.Sets/src/mage/cards/w/Windfall.java index 955883d9d86..b7c641a9a4e 100644 --- a/Mage.Sets/src/mage/cards/w/Windfall.java +++ b/Mage.Sets/src/mage/cards/w/Windfall.java @@ -1,10 +1,7 @@ - package mage.cards.w; -import java.util.UUID; import mage.abilities.Ability; import mage.abilities.effects.OneShotEffect; -import mage.cards.Card; import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.constants.CardType; @@ -12,14 +9,15 @@ import mage.constants.Outcome; import mage.game.Game; import mage.players.Player; +import java.util.UUID; + /** - * * @author emerald000 */ public final class Windfall extends CardImpl { public Windfall(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.SORCERY},"{2}{U}"); + super(ownerId, setInfo, new CardType[]{CardType.SORCERY}, "{2}{U}"); // Each player discards their hand, then draws cards equal to the greatest number of cards a player discarded this way. this.getSpellAbility().addEffect(new WindfallEffect()); @@ -42,7 +40,7 @@ class WindfallEffect extends OneShotEffect { staticText = "Each player discards their hand, then draws cards equal to the greatest number of cards a player discarded this way."; } - WindfallEffect(final WindfallEffect effect) { + private WindfallEffect(final WindfallEffect effect) { super(effect); } @@ -55,16 +53,12 @@ class WindfallEffect extends OneShotEffect { } for (UUID playerId : game.getState().getPlayersInRange(controller.getId(), game)) { Player player = game.getPlayer(playerId); - if (player != null) { - int discarded = 0; - for (Card c : player.getHand().getCards(game)) { - if (player.discard(c, source, game)) { - discarded++; - } - } - if (discarded > maxDiscarded) { - maxDiscarded = discarded; - } + if (player == null) { + continue; + } + int discarded = player.discard(player.getHand(), source, game).size(); + if (discarded > maxDiscarded) { + maxDiscarded = discarded; } } for (UUID playerId : game.getState().getPlayersInRange(controller.getId(), game)) { diff --git a/Mage.Sets/src/mage/cards/w/WitsEnd.java b/Mage.Sets/src/mage/cards/w/WitsEnd.java index 3bb57d18e8b..ff2e542b7d6 100644 --- a/Mage.Sets/src/mage/cards/w/WitsEnd.java +++ b/Mage.Sets/src/mage/cards/w/WitsEnd.java @@ -1,11 +1,7 @@ - package mage.cards.w; -import java.util.Set; -import java.util.UUID; import mage.abilities.Ability; import mage.abilities.effects.OneShotEffect; -import mage.cards.Card; import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.constants.CardType; @@ -14,22 +10,22 @@ import mage.game.Game; import mage.players.Player; import mage.target.TargetPlayer; +import java.util.UUID; + /** - * * @author North */ public final class WitsEnd extends CardImpl { public WitsEnd(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.SORCERY},"{5}{B}{B}"); - + super(ownerId, setInfo, new CardType[]{CardType.SORCERY}, "{5}{B}{B}"); // Target player discards their hand. this.getSpellAbility().addEffect(new WitsEndEffect()); this.getSpellAbility().addTarget(new TargetPlayer()); } - public WitsEnd(final WitsEnd card) { + private WitsEnd(final WitsEnd card) { super(card); } @@ -41,12 +37,12 @@ public final class WitsEnd extends CardImpl { class WitsEndEffect extends OneShotEffect { - public WitsEndEffect() { + WitsEndEffect() { super(Outcome.Benefit); this.staticText = "Target player discards their hand"; } - public WitsEndEffect(final WitsEndEffect effect) { + private WitsEndEffect(final WitsEndEffect effect) { super(effect); } @@ -58,13 +54,10 @@ class WitsEndEffect extends OneShotEffect { @Override public boolean apply(Game game, Ability source) { Player player = game.getPlayer(source.getFirstTarget()); - if (player != null) { - Set cards = player.getHand().getCards(game); - for (Card card : cards) { - player.discard(card, source, game); - } - return true; + if (player == null) { + return false; } - return false; + player.discard(player.getHand(), source, game); + return true; } } diff --git a/Mage.Sets/src/mage/cards/w/WrenchMind.java b/Mage.Sets/src/mage/cards/w/WrenchMind.java index ae5dbe64aae..552f2cfb161 100644 --- a/Mage.Sets/src/mage/cards/w/WrenchMind.java +++ b/Mage.Sets/src/mage/cards/w/WrenchMind.java @@ -1,7 +1,5 @@ - package mage.cards.w; -import java.util.UUID; import mage.abilities.Ability; import mage.abilities.effects.OneShotEffect; import mage.cards.Card; @@ -9,28 +7,28 @@ import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.constants.CardType; import mage.constants.Outcome; +import mage.filter.StaticFilters; import mage.game.Game; import mage.players.Player; import mage.target.TargetPlayer; import mage.target.common.TargetDiscard; +import java.util.UUID; + /** - * * @author LevelX2 */ public final class WrenchMind extends CardImpl { public WrenchMind(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.SORCERY},"{B}{B}"); - + super(ownerId, setInfo, new CardType[]{CardType.SORCERY}, "{B}{B}"); // Target player discards two cards unless they discard an artifact card. this.getSpellAbility().addTarget(new TargetPlayer()); this.getSpellAbility().addEffect(new WrenchMindEffect()); - } - public WrenchMind(final WrenchMind card) { + private WrenchMind(final WrenchMind card) { super(card); } @@ -42,12 +40,12 @@ public final class WrenchMind extends CardImpl { class WrenchMindEffect extends OneShotEffect { - public WrenchMindEffect() { + WrenchMindEffect() { super(Outcome.Discard); this.staticText = "Target player discards two cards unless they discard an artifact card"; } - public WrenchMindEffect(final WrenchMindEffect effect) { + private WrenchMindEffect(final WrenchMindEffect effect) { super(effect); } @@ -59,18 +57,19 @@ class WrenchMindEffect extends OneShotEffect { @Override public boolean apply(Game game, Ability source) { Player targetPlayer = game.getPlayer(this.getTargetPointer().getFirst(game, source)); - if (targetPlayer != null && !targetPlayer.getHand().isEmpty()) { - TargetDiscard target = new TargetDiscard(targetPlayer.getId()); - targetPlayer.choose(Outcome.Discard, target, source.getSourceId(), game); - Card card = targetPlayer.getHand().get(target.getFirstTarget(), game); - if (card != null) { - targetPlayer.discard(card, source, game); - if (!card.isArtifact() && !targetPlayer.getHand().isEmpty()) { - targetPlayer.discard(1, false, source, game); - } - return true; - } + if (targetPlayer == null || targetPlayer.getHand().isEmpty()) { + return false; } - return false; + if (targetPlayer.getHand().count(StaticFilters.FILTER_CARD_ARTIFACT, game) < 1 + || !targetPlayer.chooseUse(Outcome.Benefit, "Discard an artifact card?", source, game)) { + return !targetPlayer.discard(2, false, source, game).isEmpty(); + } + TargetDiscard target = new TargetDiscard(StaticFilters.FILTER_CARD_ARTIFACT_AN, targetPlayer.getId()); + targetPlayer.choose(Outcome.Discard, target, source.getSourceId(), game); + Card card = targetPlayer.getHand().get(target.getFirstTarget(), game); + if (card != null && targetPlayer.discard(card, source, game)) { + return true; + } + return !targetPlayer.discard(2, false, source, game).isEmpty(); } } diff --git a/Mage.Tests/src/test/java/org/mage/test/player/TestPlayer.java b/Mage.Tests/src/test/java/org/mage/test/player/TestPlayer.java index b7ac18de7b6..34f9dbdc1ac 100644 --- a/Mage.Tests/src/test/java/org/mage/test/player/TestPlayer.java +++ b/Mage.Tests/src/test/java/org/mage/test/player/TestPlayer.java @@ -2550,6 +2550,11 @@ public class TestPlayer implements Player { return computerPlayer.discard(amount, random, source, game); } + @Override + public Cards discard(Cards cards, Ability source, Game game) { + return computerPlayer.discard(cards, source, game); + } + @Override public boolean discard(Card card, Ability source, Game game) { return computerPlayer.discard(card, source, game); diff --git a/Mage.Tests/src/test/java/org/mage/test/stub/PlayerStub.java b/Mage.Tests/src/test/java/org/mage/test/stub/PlayerStub.java index c5bcdeb7ded..ed5e1adbbc1 100644 --- a/Mage.Tests/src/test/java/org/mage/test/stub/PlayerStub.java +++ b/Mage.Tests/src/test/java/org/mage/test/stub/PlayerStub.java @@ -1,7 +1,5 @@ package org.mage.test.stub; -import java.io.Serializable; -import java.util.*; import mage.MageObject; import mage.MageObjectReference; import mage.abilities.*; @@ -41,6 +39,9 @@ import mage.target.TargetAmount; import mage.target.TargetCard; import mage.target.common.TargetCardInLibrary; +import java.io.Serializable; +import java.util.*; + /** * @author Quercitron */ @@ -656,6 +657,11 @@ public class PlayerStub implements Player { return 1; } + @Override + public Cards discard(Cards cards, Ability source, Game game) { + return null; + } + @Override public Card discardOne(boolean random, Ability source, Game game) { return null; diff --git a/Mage/src/main/java/mage/abilities/costs/common/DiscardHandCost.java b/Mage/src/main/java/mage/abilities/costs/common/DiscardHandCost.java index 4023d942b47..32a76e3a797 100644 --- a/Mage/src/main/java/mage/abilities/costs/common/DiscardHandCost.java +++ b/Mage/src/main/java/mage/abilities/costs/common/DiscardHandCost.java @@ -1,27 +1,23 @@ - - package mage.abilities.costs.common; -import java.util.UUID; import mage.abilities.Ability; import mage.abilities.costs.Cost; import mage.abilities.costs.CostImpl; -import mage.cards.Card; import mage.game.Game; import mage.players.Player; +import java.util.UUID; + /** - * * @author LevelX2 */ public class DiscardHandCost extends CostImpl { public DiscardHandCost() { - } - public DiscardHandCost(final DiscardHandCost cost) { + private DiscardHandCost(final DiscardHandCost cost) { super(cost); } @@ -38,12 +34,11 @@ public class DiscardHandCost extends CostImpl { @Override public boolean pay(Ability ability, Game game, UUID sourceId, UUID controllerId, boolean noMana, Cost costToPay) { Player player = game.getPlayer(controllerId); - if (player != null) { - for (Card card : player.getHand().getCards(game)) { - player.discard(card, ability, game); - } - paid = true; + if (player == null) { + return paid; } + player.discard(player.getHand(), ability, game); + paid = true; return paid; } diff --git a/Mage/src/main/java/mage/abilities/costs/common/DiscardTargetCost.java b/Mage/src/main/java/mage/abilities/costs/common/DiscardTargetCost.java index ff190e15cbe..6c786f6ff1e 100644 --- a/Mage/src/main/java/mage/abilities/costs/common/DiscardTargetCost.java +++ b/Mage/src/main/java/mage/abilities/costs/common/DiscardTargetCost.java @@ -1,20 +1,21 @@ - package mage.abilities.costs.common; -import java.util.ArrayList; -import java.util.List; -import java.util.UUID; import mage.abilities.Ability; import mage.abilities.costs.Cost; import mage.abilities.costs.CostImpl; import mage.cards.Card; +import mage.cards.Cards; +import mage.cards.CardsImpl; import mage.constants.Outcome; import mage.game.Game; import mage.players.Player; import mage.target.common.TargetCardInHand; +import java.util.ArrayList; +import java.util.List; +import java.util.UUID; + /** - * * @author BetaSteward_at_googlemail.com */ public class DiscardTargetCost extends CostImpl { @@ -50,13 +51,11 @@ public class DiscardTargetCost extends CostImpl { if (randomDiscard) { this.cards.addAll(player.discard(amount, true, ability, game).getCards(game)); } else if (targets.choose(Outcome.Discard, controllerId, sourceId, game)) { - for (UUID targetId : targets.get(0).getTargets()) { - Card card = player.getHand().get(targetId, game); - if (card == null) { - return false; - } - player.discard(card, ability, game); - this.cards.add(card); + Cards toDiscard = new CardsImpl(); + toDiscard.addAll(targets.get(0).getTargets()); + Cards discarded = player.discard(toDiscard, ability, game); + if (!discarded.isEmpty()) { + cards.addAll(discarded.getCards(game)); } } paid = cards.size() >= amount; diff --git a/Mage/src/main/java/mage/abilities/effects/common/BalanceEffect.java b/Mage/src/main/java/mage/abilities/effects/common/BalanceEffect.java new file mode 100644 index 00000000000..c81187c4ad1 --- /dev/null +++ b/Mage/src/main/java/mage/abilities/effects/common/BalanceEffect.java @@ -0,0 +1,168 @@ +package mage.abilities.effects.common; + +import mage.abilities.Ability; +import mage.abilities.effects.OneShotEffect; +import mage.cards.Card; +import mage.cards.Cards; +import mage.cards.CardsImpl; +import mage.constants.Outcome; +import mage.filter.FilterCard; +import mage.filter.StaticFilters; +import mage.filter.common.FilterControlledCreaturePermanent; +import mage.filter.common.FilterControlledLandPermanent; +import mage.filter.common.FilterControlledPermanent; +import mage.game.Game; +import mage.game.permanent.Permanent; +import mage.players.Player; +import mage.target.common.TargetCardInHand; +import mage.target.common.TargetControlledPermanent; + +import java.util.HashMap; +import java.util.Map; +import java.util.UUID; + +/** + * @author emerald000 + */ +public class BalanceEffect extends OneShotEffect { + + private static final FilterControlledPermanent filter = new FilterControlledLandPermanent("lands to keep"); + private static final FilterControlledPermanent filter2 = new FilterControlledCreaturePermanent("creatures to keep"); + private static final FilterCard filter3 = new FilterCard("cards to keep"); + + public BalanceEffect() { + super(Outcome.Sacrifice); + staticText = "each player chooses a number of lands they control " + + "equal to the number of lands controlled by the player " + + "who controls the fewest, then sacrifices the rest. " + + "Players discard cards and sacrifice creatures the same way"; + } + + private BalanceEffect(final BalanceEffect effect) { + super(effect); + } + + @Override + public BalanceEffect copy() { + return new BalanceEffect(this); + } + + @Override + public boolean apply(Game game, Ability source) { + Player controller = game.getPlayer(source.getControllerId()); + if (controller == null) { + return false; + } + //Lands + int minLand = Integer.MAX_VALUE; + Cards landsToSacrifice = new CardsImpl(); + for (UUID playerId : game.getState().getPlayersInRange(controller.getId(), game)) { + Player player = game.getPlayer(playerId); + if (player == null) { + continue; + } + int count = game.getBattlefield().countAll(StaticFilters.FILTER_CONTROLLED_PERMANENT_LAND, player.getId(), game); + if (count < minLand) { + minLand = count; + } + } + + for (UUID playerId : game.getState().getPlayersInRange(controller.getId(), game)) { + Player player = game.getPlayer(playerId); + if (player == null) { + continue; + } + TargetControlledPermanent target = new TargetControlledPermanent(minLand, minLand, filter, true); + if (!target.choose(Outcome.Sacrifice, player.getId(), source.getSourceId(), game)) { + continue; + } + for (Permanent permanent : game.getBattlefield().getActivePermanents(StaticFilters.FILTER_CONTROLLED_PERMANENT_LAND, player.getId(), source.getSourceId(), game)) { + if (permanent != null && !target.getTargets().contains(permanent.getId())) { + landsToSacrifice.add(permanent); + } + } + } + + for (UUID cardId : landsToSacrifice) { + Permanent permanent = game.getPermanent(cardId); + if (permanent != null) { + permanent.sacrifice(source.getSourceId(), game); + } + } + + //Creatures + int minCreature = Integer.MAX_VALUE; + Cards creaturesToSacrifice = new CardsImpl(); + for (UUID playerId : game.getState().getPlayersInRange(controller.getId(), game)) { + Player player = game.getPlayer(playerId); + if (player == null) { + } + int count = game.getBattlefield().countAll(StaticFilters.FILTER_CONTROLLED_PERMANENT_LAND, player.getId(), game); + if (count < minCreature) { + minCreature = count; + } + } + + for (UUID playerId : game.getState().getPlayersInRange(controller.getId(), game)) { + Player player = game.getPlayer(playerId); + if (player == null) { + continue; + } + TargetControlledPermanent target = new TargetControlledPermanent(minCreature, minCreature, filter2, true); + if (!target.choose(Outcome.Sacrifice, player.getId(), source.getSourceId(), game)) { + continue; + } + for (Permanent permanent : game.getBattlefield().getActivePermanents(StaticFilters.FILTER_CONTROLLED_CREATURE, player.getId(), source.getSourceId(), game)) { + if (permanent != null && !target.getTargets().contains(permanent.getId())) { + creaturesToSacrifice.add(permanent); + } + } + } + + for (UUID cardId : creaturesToSacrifice) { + Permanent permanent = game.getPermanent(cardId); + if (permanent != null) { + permanent.sacrifice(source.getSourceId(), game); + } + } + + //Cards in hand + int minCard = Integer.MAX_VALUE; + Map cardsToDiscard = new HashMap<>(2); + for (UUID playerId : game.getState().getPlayersInRange(controller.getId(), game)) { + Player player = game.getPlayer(playerId); + if (player == null) { + } + int count = player.getHand().size(); + if (count < minCard) { + minCard = count; + } + } + + for (UUID playerId : game.getState().getPlayersInRange(controller.getId(), game)) { + Player player = game.getPlayer(playerId); + if (player == null) { + continue; + } + Cards cards = new CardsImpl(); + TargetCardInHand target = new TargetCardInHand(minCard, filter3); + if (!target.choose(Outcome.Discard, player.getId(), source.getSourceId(), game)) { + continue; + } + for (Card card : player.getHand().getCards(game)) { + if (card != null && !target.getTargets().contains(card.getId())) { + cards.add(card); + } + } + cardsToDiscard.put(playerId, cards); + } + + for (UUID playerId : game.getState().getPlayersInRange(controller.getId(), game)) { + Player player = game.getPlayer(playerId); + if (player != null && cardsToDiscard.get(playerId) != null) { + player.discard(cardsToDiscard.get(playerId), source, game); + } + } + return true; + } +} diff --git a/Mage/src/main/java/mage/abilities/effects/common/discard/DiscardCardYouChooseTargetEffect.java b/Mage/src/main/java/mage/abilities/effects/common/discard/DiscardCardYouChooseTargetEffect.java index d48b78dc8e4..403fde557ae 100644 --- a/Mage/src/main/java/mage/abilities/effects/common/discard/DiscardCardYouChooseTargetEffect.java +++ b/Mage/src/main/java/mage/abilities/effects/common/discard/DiscardCardYouChooseTargetEffect.java @@ -144,12 +144,7 @@ public class DiscardCardYouChooseTargetEffect extends OneShotEffect { if (!controller.choose(Outcome.Benefit, revealedCards, target, game)) { return result; } - for (UUID targetId : target.getTargets()) { - Card card = revealedCards.get(targetId, game); - if (!player.discard(card, source, game)) { - result = false; - } - } + result=!player.discard(new CardsImpl(target.getTargets()),source,game).isEmpty(); return result; } diff --git a/Mage/src/main/java/mage/abilities/effects/common/discard/DiscardControllerEffect.java b/Mage/src/main/java/mage/abilities/effects/common/discard/DiscardControllerEffect.java index 278a4747c83..88d1f95aded 100644 --- a/Mage/src/main/java/mage/abilities/effects/common/discard/DiscardControllerEffect.java +++ b/Mage/src/main/java/mage/abilities/effects/common/discard/DiscardControllerEffect.java @@ -1,11 +1,9 @@ - package mage.abilities.effects.common.discard; import mage.abilities.Ability; import mage.abilities.dynamicvalue.DynamicValue; import mage.abilities.dynamicvalue.common.StaticValue; import mage.abilities.effects.OneShotEffect; -import mage.cards.Card; import mage.constants.Outcome; import mage.game.Game; import mage.players.Player; @@ -16,8 +14,8 @@ import mage.util.CardUtil; */ public class DiscardControllerEffect extends OneShotEffect { - protected DynamicValue amount; - protected boolean randomDiscard; + protected final DynamicValue amount; + protected final boolean randomDiscard; public DiscardControllerEffect(int amount) { this(StaticValue.get(amount)); @@ -51,22 +49,8 @@ public class DiscardControllerEffect extends OneShotEffect { @Override public boolean apply(Game game, Ability source) { - boolean result = false; Player player = game.getPlayer(source.getControllerId()); - if (player != null) { - if (randomDiscard) { - int maxAmount = Math.min(amount.calculate(game, source, this), player.getHand().size()); - for (int i = 0; i < maxAmount; i++) { - Card card = player.getHand().getRandom(game); - result |= player.discard(card, source, game); - - } - } else { - player.discard(amount.calculate(game, source, this), false, source, game); - result = true; - } - } - return result; + return player != null && !player.discard(amount.calculate(game, source, this), randomDiscard, source, game).isEmpty(); } private void setText() { diff --git a/Mage/src/main/java/mage/abilities/effects/common/discard/DiscardEachPlayerEffect.java b/Mage/src/main/java/mage/abilities/effects/common/discard/DiscardEachPlayerEffect.java index fba1fef2f9c..92bf3876449 100644 --- a/Mage/src/main/java/mage/abilities/effects/common/discard/DiscardEachPlayerEffect.java +++ b/Mage/src/main/java/mage/abilities/effects/common/discard/DiscardEachPlayerEffect.java @@ -5,12 +5,11 @@ import mage.abilities.Mode; import mage.abilities.dynamicvalue.DynamicValue; import mage.abilities.dynamicvalue.common.StaticValue; import mage.abilities.effects.OneShotEffect; -import mage.cards.Card; import mage.cards.Cards; import mage.cards.CardsImpl; import mage.constants.Outcome; import mage.constants.TargetController; -import mage.filter.FilterCard; +import mage.filter.StaticFilters; import mage.game.Game; import mage.players.Player; import mage.target.Target; @@ -62,54 +61,50 @@ public class DiscardEachPlayerEffect extends OneShotEffect { Player controller = game.getPlayer(source.getControllerId()); // Store for each player the cards to discard, that's important because all discard shall happen at the same time Map cardsToDiscard = new HashMap<>(); - if (controller != null) { - // choose cards to discard - for (UUID playerId : game.getState().getPlayersInRange(controller.getId(), game)) { - Player player = game.getPlayer(playerId); - if (player != null) { - switch (targetController) { - case NOT_YOU: - if (playerId.equals(source.getControllerId())) { - continue; - } - break; - case OPPONENT: - if (!game.getOpponents(source.getControllerId()).contains(playerId)) { - continue; - } - break; - } - int numberOfCardsToDiscard = Math.min(amount.calculate(game, source, this), player.getHand().size()); - Cards cards = new CardsImpl(); - if (randomDiscard) { - while (player.isInGame() && cards.size() < numberOfCardsToDiscard) { - Card card = player.getHand().getRandom(game); - if (!cards.contains(card.getId())) { - cards.add(card); - } - } - } else { - Target target = new TargetDiscard(numberOfCardsToDiscard, numberOfCardsToDiscard, new FilterCard(), playerId); - player.chooseTarget(outcome, target, source, game); - cards.addAll(target.getTargets()); - } - cardsToDiscard.put(playerId, cards); - } + if (controller == null) { + return true; + } + int toDiscard = amount.calculate(game, source, this); + // choose cards to discard + for (UUID playerId : game.getState().getPlayersInRange(controller.getId(), game)) { + Player player = game.getPlayer(playerId); + if (player == null) { + continue; } - // discard all choosen cards - for (UUID playerId : game.getState().getPlayersInRange(controller.getId(), game)) { - Player player = game.getPlayer(playerId); - if (player != null) { - Cards cardsPlayer = cardsToDiscard.get(playerId); - if (cardsPlayer != null) { - for (UUID cardId : cardsPlayer) { - Card card = game.getCard(cardId); - player.discard(card, source, game); - - } + switch (targetController) { + case NOT_YOU: + if (playerId.equals(source.getControllerId())) { + continue; } - } + break; + case OPPONENT: + if (!game.getOpponents(source.getControllerId()).contains(playerId)) { + continue; + } + break; } + if (randomDiscard) { + player.discard(toDiscard, true, source, game); + continue; + } + int numberOfCardsToDiscard = Math.min(toDiscard, player.getHand().size()); + Cards cards = new CardsImpl(); + Target target = new TargetDiscard(numberOfCardsToDiscard, numberOfCardsToDiscard, StaticFilters.FILTER_CARD, playerId); + player.chooseTarget(outcome, target, source, game); + cards.addAll(target.getTargets()); + cardsToDiscard.put(playerId, cards); + } + if (randomDiscard) { + return true; + } + // discard all choosen cards + for (UUID playerId : game.getState().getPlayersInRange(controller.getId(), game)) { + Player player = game.getPlayer(playerId); + if (player == null) { + continue; + } + Cards cardsPlayer = cardsToDiscard.get(playerId); + player.discard(cardsPlayer, source, game); } return true; } diff --git a/Mage/src/main/java/mage/abilities/effects/common/discard/DiscardHandAllEffect.java b/Mage/src/main/java/mage/abilities/effects/common/discard/DiscardHandAllEffect.java index d6cb2f4eb78..60cc0bd3422 100644 --- a/Mage/src/main/java/mage/abilities/effects/common/discard/DiscardHandAllEffect.java +++ b/Mage/src/main/java/mage/abilities/effects/common/discard/DiscardHandAllEffect.java @@ -2,12 +2,10 @@ package mage.abilities.effects.common.discard; import mage.abilities.Ability; import mage.abilities.effects.OneShotEffect; -import mage.cards.Card; import mage.constants.Outcome; import mage.game.Game; import mage.players.Player; -import java.util.Set; import java.util.UUID; /** @@ -33,12 +31,10 @@ public class DiscardHandAllEffect extends OneShotEffect { public boolean apply(Game game, Ability source) { for (UUID playerId : game.getState().getPlayersInRange(source.getControllerId(), game)) { Player player = game.getPlayer(playerId); - if (player != null) { - Set cards = player.getHand().getCards(game); - for (Card card : cards) { - player.discard(card, source, game); - } + if (player == null) { + continue; } + player.discard(player.getHand(), source, game); } return true; } diff --git a/Mage/src/main/java/mage/players/Player.java b/Mage/src/main/java/mage/players/Player.java index 2128323f2cf..0e7c6109031 100644 --- a/Mage/src/main/java/mage/players/Player.java +++ b/Mage/src/main/java/mage/players/Player.java @@ -412,6 +412,8 @@ public interface Player extends MageItem, Copyable { Cards discard(int amount, boolean random, Ability source, Game game); + Cards discard(Cards cards, Ability source, Game game); + void discardToMax(Game game); boolean discard(Card card, Ability source, Game game); diff --git a/Mage/src/main/java/mage/players/PlayerImpl.java b/Mage/src/main/java/mage/players/PlayerImpl.java index 1bc9a3b339f..f7ff8422b18 100644 --- a/Mage/src/main/java/mage/players/PlayerImpl.java +++ b/Mage/src/main/java/mage/players/PlayerImpl.java @@ -718,6 +718,24 @@ public abstract class PlayerImpl implements Player, Serializable { return discardedCards; } + @Override + public Cards discard(Cards cards, Ability source, Game game) { + Cards discardedCards = new CardsImpl(); + for (Card card : cards.getCards(game)) { + if (doDiscard(card, source, game, false)) { + discardedCards.add(card); + } + } + if (!discardedCards.isEmpty()) { + UUID sourceId = source == null ? null : source.getSourceId(); + game.fireEvent(GameEvent.getEvent( + GameEvent.EventType.DISCARDED_CARDS, sourceId, + sourceId, playerId, discardedCards.size() + )); + } + return discardedCards; + } + private Cards doDiscard(int amount, boolean random, Ability source, Game game) { Cards discardedCards = new CardsImpl(); if (amount <= 0) {